From 0e004c696b0e68b2cff37a4c3315b022a35eaf43 Mon Sep 17 00:00:00 2001 From: Perberos Date: Thu, 1 Dec 2011 22:24:23 -0300 Subject: moving from https://github.com/perberos/mate-desktop-environment --- AUTHORS | 60 + COPYING | 351 + COPYING-DOCS | 355 + COPYING.EXTENSIONS | 10 + COPYING.LIB | 482 + ChangeLog | 0 HACKING | 57 + INSTALL | 365 + MAINTAINERS | 23 + Makefile.am | 44 + Makefile.shared | 1 + NEWS | 1713 +++ README | 31 + README.commits | 68 + THANKS | 621 + TODO | 19 + acconfig.h | 27 + aclocal.m4 | 1812 +++ add-include-prefix | 1 + autogen.sh | 25 + config.guess | 1501 ++ config.h.in | 185 + config.sub | 1705 +++ configure.in | 483 + cut-n-paste-code/Makefile.am | 2 + cut-n-paste-code/Makefile.in | 646 + cut-n-paste-code/README | 21 + cut-n-paste-code/libegg/Makefile.am | 46 + cut-n-paste-code/libegg/Makefile.in | 657 + cut-n-paste-code/libegg/eggdesktopfile.c | 1477 ++ cut-n-paste-code/libegg/eggdesktopfile.h | 166 + cut-n-paste-code/libegg/eggsmclient-private.h | 57 + cut-n-paste-code/libegg/eggsmclient-xsmp.c | 1371 ++ cut-n-paste-code/libegg/eggsmclient.c | 602 + cut-n-paste-code/libegg/eggsmclient.h | 123 + cut-n-paste-code/libegg/eggtreemultidnd.c | 415 + cut-n-paste-code/libegg/eggtreemultidnd.h | 78 + cut-n-paste-code/libegg/update-from-egg.sh | 25 + data/Makefile.am | 54 + data/browser.xml | 76 + data/caja-autorun-software.desktop.in.in | 14 + data/caja-browser.desktop.in.in | 15 + data/caja-computer.desktop.in.in | 15 + data/caja-extras.placeholder | 2 + data/caja-file-management-properties.desktop.in.in | 14 + data/caja-folder-handler.desktop.in.in | 15 + data/caja-home.desktop.in.in | 14 + data/caja-suggested.placeholder | 2 + data/caja.desktop.in.in | 17 + data/caja.xml.in | 8 + data/icons/Makefile.am | 86 + data/icons/hicolor_apps_16x16_caja.png | Bin 0 -> 874 bytes data/icons/hicolor_apps_16x16_caja.svg | 262 + data/icons/hicolor_apps_22x22_caja.png | Bin 0 -> 1270 bytes data/icons/hicolor_apps_22x22_caja.svg | 323 + data/icons/hicolor_apps_24x24_caja.png | Bin 0 -> 1310 bytes data/icons/hicolor_apps_32x32_caja.png | Bin 0 -> 2345 bytes data/icons/hicolor_apps_32x32_caja.svg | 314 + data/icons/hicolor_apps_scalable_caja.svg | 275 + data/icons/hicolor_emblems_16x16_emblem-note.png | Bin 0 -> 534 bytes data/icons/hicolor_emblems_24x24_emblem-note.png | Bin 0 -> 913 bytes data/icons/hicolor_emblems_48x48_emblem-note.png | Bin 0 -> 2454 bytes data/patterns/Makefile.am | 39 + data/patterns/blue_gray_rough.png | Bin 0 -> 22418 bytes data/patterns/blue_ridge.png | Bin 0 -> 263 bytes data/patterns/blue_type.png | Bin 0 -> 11060 bytes data/patterns/brushed_metal.png | Bin 0 -> 29181 bytes data/patterns/burlap.jpg | Bin 0 -> 1611 bytes data/patterns/camouflage.png | Bin 0 -> 29561 bytes data/patterns/chalk.jpg | Bin 0 -> 821 bytes data/patterns/cork.png | Bin 0 -> 20928 bytes data/patterns/countertop.png | Bin 0 -> 4787 bytes data/patterns/dark-mate.jpg | Bin 0 -> 9877 bytes data/patterns/dots.png | Bin 0 -> 922 bytes data/patterns/fibers.png | Bin 0 -> 28188 bytes data/patterns/fleur_de_lis.png | Bin 0 -> 28890 bytes data/patterns/floral.png | Bin 0 -> 73080 bytes data/patterns/fossil.png | Bin 0 -> 14478 bytes data/patterns/green_weave.png | Bin 0 -> 8088 bytes data/patterns/ice.png | Bin 0 -> 19562 bytes data/patterns/manila_paper.png | Bin 0 -> 21751 bytes data/patterns/mate.jpg | Bin 0 -> 8316 bytes data/patterns/moss_ridge.png | Bin 0 -> 274 bytes data/patterns/numbers.png | Bin 0 -> 8993 bytes data/patterns/ocean_stripes.png | Bin 0 -> 274 bytes data/patterns/purple_marble.png | Bin 0 -> 12288 bytes data/patterns/reset.png | Bin 0 -> 441 bytes data/patterns/ridged_paper.png | Bin 0 -> 10353 bytes data/patterns/rough_paper.png | Bin 0 -> 3955 bytes data/patterns/sky_ridge.png | Bin 0 -> 264 bytes data/patterns/snow_ridge.png | Bin 0 -> 274 bytes data/patterns/stucco.jpg | Bin 0 -> 2499 bytes data/patterns/terracotta.png | Bin 0 -> 32001 bytes data/patterns/wavy_white.png | Bin 0 -> 1522 bytes depcomp | 630 + distro/archlinux/PKGBUILD | 41 + distro/archlinux/mate-file-manager.install | 28 + distro/ubuntu/build | 36 + distro/ubuntu/postinst | 15 + distro/ubuntu/postrm | 10 + distro/ubuntu/preinst | 8 + distro/ubuntu/prerm | 11 + docs/Makefile.am | 25 + docs/architecture.txt | 160 + docs/caja-connect-server.1 | 50 + docs/caja-file-management-properties.1 | 49 + docs/caja-internals.pdf | Bin 0 -> 307912 bytes docs/caja-internals.sxw | Bin 0 -> 59282 bytes docs/caja-io.txt | 255 + docs/caja.1 | 77 + docs/caja.faq | 7 + docs/dnd.txt | 92 + docs/key_mouse_navigation.txt | 112 + docs/load-states.dia | Bin 0 -> 2026 bytes docs/recommended-books.html | 167 + docs/reference/Makefile.am | 1 + docs/reference/Makefile.in | 646 + docs/reference/libcaja-extension/Makefile.am | 84 + docs/reference/libcaja-extension/Makefile.in | 797 + docs/reference/libcaja-extension/html/ch01.html | 63 + docs/reference/libcaja-extension/html/home.png | Bin 0 -> 654 bytes docs/reference/libcaja-extension/html/index.html | 66 + docs/reference/libcaja-extension/html/index.sgml | 170 + docs/reference/libcaja-extension/html/ix01.html | 224 + docs/reference/libcaja-extension/html/left.png | Bin 0 -> 459 bytes .../libcaja-extension-caja-column-provider.html | 117 + .../html/libcaja-extension-caja-column.html | 182 + .../libcaja-extension-caja-extension-types.html | 158 + .../html/libcaja-extension-caja-file-info.html | 643 + .../html/libcaja-extension-caja-info-provider.html | 252 + ...ja-extension-caja-location-widget-provider.html | 133 + .../html/libcaja-extension-caja-menu-provider.html | 267 + .../html/libcaja-extension-caja-menu.html | 473 + ...caja-extension-caja-property-page-provider.html | 131 + .../html/libcaja-extension-caja-property-page.html | 148 + .../html/libcaja-extension.devhelp | 118 + .../html/libcaja-extension.devhelp2 | 118 + docs/reference/libcaja-extension/html/pt01.html | 68 + docs/reference/libcaja-extension/html/right.png | Bin 0 -> 472 bytes docs/reference/libcaja-extension/html/style.css | 265 + docs/reference/libcaja-extension/html/up.png | Bin 0 -> 406 bytes .../libcaja-extension/libcaja-extension-docs.xml | 36 + .../libcaja-extension-overrides.txt | 0 .../libcaja-extension-sections.txt | 185 + .../libcaja-extension/libcaja-extension.types | 11 + .../tmpl/caja-column-provider.sgml | 45 + .../libcaja-extension/tmpl/caja-column.sgml | 76 + .../tmpl/caja-extension-types.sgml | 78 + .../libcaja-extension/tmpl/caja-file-info.sgml | 257 + .../libcaja-extension/tmpl/caja-info-provider.sgml | 80 + .../tmpl/caja-location-widget-provider.sgml | 47 + .../libcaja-extension/tmpl/caja-menu-item.sgml | 22 + .../libcaja-extension/tmpl/caja-menu-provider.sgml | 86 + .../libcaja-extension/tmpl/caja-menu.sgml | 208 + .../tmpl/caja-property-page-provider.sgml | 46 + .../libcaja-extension/tmpl/caja-property-page.sgml | 60 + .../tmpl/libcaja-extension-unused.sgml | 0 docs/reference/libcaja-extension/version.xml.in | 1 + docs/smoketests.html | 555 + docs/state-machines.txt | 77 + docs/style-guide.html | 137 + eel/ChangeLog | 9642 ++++++++++++ eel/Makefile.am | 186 + eel/README | 4 + eel/check-eel | 3 + eel/check-program.c | 60 + eel/eel-accessibility.c | 432 + eel/eel-accessibility.h | 153 + eel/eel-alert-dialog.c | 490 + eel/eel-alert-dialog.h | 60 + eel/eel-art-extensions.c | 321 + eel/eel-art-extensions.h | 120 + eel/eel-art-gtk-extensions.c | 346 + eel/eel-art-gtk-extensions.h | 74 + eel/eel-background-box.c | 70 + eel/eel-background-box.h | 71 + eel/eel-background.c | 1273 ++ eel/eel-background.h | 162 + eel/eel-canvas-rect-ellipse.c | 1550 ++ eel/eel-canvas-rect-ellipse.h | 184 + eel/eel-canvas-util.c | 426 + eel/eel-canvas-util.h | 110 + eel/eel-canvas.c | 4213 ++++++ eel/eel-canvas.h | 545 + eel/eel-debug-drawing.c | 566 + eel/eel-debug-drawing.h | 72 + eel/eel-debug.c | 135 + eel/eel-debug.h | 52 + eel/eel-editable-label.c | 4402 ++++++ eel/eel-editable-label.h | 145 + eel/eel-enumeration.c | 555 + eel/eel-enumeration.h | 63 + eel/eel-gdk-extensions.c | 971 ++ eel/eel-gdk-extensions.h | 164 + eel/eel-gdk-pixbuf-extensions.c | 1510 ++ eel/eel-gdk-pixbuf-extensions.h | 162 + eel/eel-glib-extensions.c | 1231 ++ eel/eel-glib-extensions.h | 128 + eel/eel-graphic-effects.c | 421 + eel/eel-graphic-effects.h | 66 + eel/eel-gtk-container.c | 225 + eel/eel-gtk-container.h | 47 + eel/eel-gtk-extensions.c | 1247 ++ eel/eel-gtk-extensions.h | 141 + eel/eel-gtk-macros.h | 178 + eel/eel-i18n.c | 52 + eel/eel-i18n.h | 55 + eel/eel-image-table.c | 601 + eel/eel-image-table.h | 99 + eel/eel-labeled-image.c | 2493 ++++ eel/eel-labeled-image.h | 166 + eel/eel-lib-self-check-functions.c | 38 + eel/eel-lib-self-check-functions.h | 53 + eel/eel-mate-extensions.c | 221 + eel/eel-mate-extensions.h | 44 + eel/eel-mateconf-extensions.c | 687 + eel/eel-mateconf-extensions.h | 78 + eel/eel-pango-extensions.c | 615 + eel/eel-pango-extensions.h | 55 + eel/eel-preferences-builder.c | 646 + eel/eel-preferences.c | 1764 +++ eel/eel-preferences.h | 165 + eel/eel-self-checks.c | 237 + eel/eel-self-checks.h | 101 + eel/eel-stock-dialogs.c | 588 + eel/eel-stock-dialogs.h | 91 + eel/eel-string.c | 1275 ++ eel/eel-string.h | 122 + eel/eel-types.c | 82 + eel/eel-types.h | 32 + eel/eel-vfs-extensions.c | 187 + eel/eel-vfs-extensions.h | 59 + eel/eel-wrap-table.c | 1108 ++ eel/eel-wrap-table.h | 108 + eel/eel-xml-extensions.c | 199 + eel/eel-xml-extensions.h | 49 + eel/eel.h | 53 + eel/eelmarshal.list | 13 + eel/makeenums.pl | 220 + eel/maketypes.awk | 155 + gtk-doc.make | 280 + icons/Makefile.am | 16 + icons/audio.svg | 43 + icons/backgrounds.png | Bin 0 -> 3735 bytes icons/chit_frame.png | Bin 0 -> 751 bytes icons/colors.png | Bin 0 -> 3115 bytes icons/emblems.png | Bin 0 -> 3122 bytes icons/erase.png | Bin 0 -> 3441 bytes icons/knob.png | Bin 0 -> 206 bytes icons/thumbnail_frame.png | Bin 0 -> 482 bytes install-sh | 520 + intltool-extract.in | 0 intltool-merge.in | 0 intltool-update.in | 0 libcaja-extension/Makefile.am | 89 + libcaja-extension/caja-column-provider.c | 74 + libcaja-extension/caja-column-provider.h | 65 + libcaja-extension/caja-column.c | 240 + libcaja-extension/caja-column.h | 77 + libcaja-extension/caja-extension-i18n.h | 24 + libcaja-extension/caja-extension-private.h | 39 + libcaja-extension/caja-extension-types.c | 59 + libcaja-extension/caja-extension-types.h | 72 + libcaja-extension/caja-file-info.c | 308 + libcaja-extension/caja-file-info.h | 140 + libcaja-extension/caja-info-provider.c | 122 + libcaja-extension/caja-info-provider.h | 87 + libcaja-extension/caja-location-widget-provider.c | 74 + libcaja-extension/caja-location-widget-provider.h | 69 + libcaja-extension/caja-menu-item.c | 342 + libcaja-extension/caja-menu-item.h | 30 + libcaja-extension/caja-menu-provider.c | 143 + libcaja-extension/caja-menu-provider.h | 85 + libcaja-extension/caja-menu.c | 112 + libcaja-extension/caja-menu.h | 125 + libcaja-extension/caja-property-page-provider.c | 89 + libcaja-extension/caja-property-page-provider.h | 68 + libcaja-extension/caja-property-page.c | 246 + libcaja-extension/caja-property-page.h | 74 + .../libcaja-extension-uninstalled.pc.in | 12 + libcaja-extension/libcaja-extension.pc.in | 12 + libcaja-private/Makefile.am | 246 + libcaja-private/README | 13 + libcaja-private/apps_caja_preferences.schemas.in | 1205 ++ libcaja-private/caja-autorun.c | 1434 ++ libcaja-private/caja-autorun.h | 81 + libcaja-private/caja-bookmark.c | 672 + libcaja-private/caja-bookmark.h | 100 + libcaja-private/caja-cell-renderer-pixbuf-emblem.c | 519 + libcaja-private/caja-cell-renderer-pixbuf-emblem.h | 68 + .../caja-cell-renderer-text-ellipsized.c | 80 + .../caja-cell-renderer-text-ellipsized.h | 61 + libcaja-private/caja-clipboard-monitor.c | 338 + libcaja-private/caja-clipboard-monitor.h | 85 + libcaja-private/caja-clipboard.c | 692 + libcaja-private/caja-clipboard.h | 54 + libcaja-private/caja-column-chooser.c | 670 + libcaja-private/caja-column-chooser.h | 69 + libcaja-private/caja-column-utilities.c | 327 + libcaja-private/caja-column-utilities.h | 41 + libcaja-private/caja-customization-data.c | 498 + libcaja-private/caja-customization-data.h | 68 + libcaja-private/caja-debug-log.c | 760 + libcaja-private/caja-debug-log.h | 58 + libcaja-private/caja-default-file-icon.c | 537 + libcaja-private/caja-default-file-icon.h | 32 + libcaja-private/caja-desktop-directory-file.c | 731 + libcaja-private/caja-desktop-directory-file.h | 68 + libcaja-private/caja-desktop-directory.c | 560 + libcaja-private/caja-desktop-directory.h | 61 + libcaja-private/caja-desktop-icon-file.c | 410 + libcaja-private/caja-desktop-icon-file.h | 64 + libcaja-private/caja-desktop-link-monitor.c | 575 + libcaja-private/caja-desktop-link-monitor.h | 67 + libcaja-private/caja-desktop-link.c | 479 + libcaja-private/caja-desktop-link.h | 84 + libcaja-private/caja-directory-async.c | 5410 +++++++ libcaja-private/caja-directory-background.c | 731 + libcaja-private/caja-directory-background.h | 36 + libcaja-private/caja-directory-notify.h | 74 + libcaja-private/caja-directory-private.h | 249 + libcaja-private/caja-directory.c | 2004 +++ libcaja-private/caja-directory.h | 244 + libcaja-private/caja-dnd.c | 1446 ++ libcaja-private/caja-dnd.h | 200 + libcaja-private/caja-emblem-utils.c | 511 + libcaja-private/caja-emblem-utils.h | 53 + libcaja-private/caja-entry.c | 442 + libcaja-private/caja-entry.h | 78 + libcaja-private/caja-file-attributes.h | 47 + libcaja-private/caja-file-changes-queue.c | 475 + libcaja-private/caja-file-changes-queue.h | 42 + libcaja-private/caja-file-conflict-dialog.c | 670 + libcaja-private/caja-file-conflict-dialog.h | 80 + libcaja-private/caja-file-dnd.c | 186 + libcaja-private/caja-file-dnd.h | 44 + libcaja-private/caja-file-operations.c | 6469 +++++++++ libcaja-private/caja-file-operations.h | 142 + libcaja-private/caja-file-private.h | 316 + libcaja-private/caja-file-queue.c | 133 + libcaja-private/caja-file-queue.h | 52 + libcaja-private/caja-file-utilities.c | 1449 ++ libcaja-private/caja-file-utilities.h | 111 + libcaja-private/caja-file.c | 8411 +++++++++++ libcaja-private/caja-file.h | 590 + libcaja-private/caja-global-preferences.c | 954 ++ libcaja-private/caja-global-preferences.h | 242 + libcaja-private/caja-horizontal-splitter.c | 307 + libcaja-private/caja-horizontal-splitter.h | 76 + libcaja-private/caja-icon-canvas-item.c | 3874 +++++ libcaja-private/caja-icon-canvas-item.h | 123 + libcaja-private/caja-icon-container.c | 10612 ++++++++++++++ libcaja-private/caja-icon-container.h | 371 + libcaja-private/caja-icon-dnd.c | 2123 +++ libcaja-private/caja-icon-dnd.h | 63 + libcaja-private/caja-icon-info.c | 751 + libcaja-private/caja-icon-info.h | 99 + libcaja-private/caja-icon-names.h | 30 + libcaja-private/caja-icon-private.h | 336 + libcaja-private/caja-idle-queue.c | 156 + libcaja-private/caja-idle-queue.h | 49 + libcaja-private/caja-iso9660.h | 110 + libcaja-private/caja-keep-last-vertical-box.c | 166 + libcaja-private/caja-keep-last-vertical-box.h | 59 + libcaja-private/caja-lib-self-check-functions.c | 38 + libcaja-private/caja-lib-self-check-functions.h | 50 + libcaja-private/caja-link.c | 642 + libcaja-private/caja-link.h | 54 + libcaja-private/caja-marshal.c | 2 + libcaja-private/caja-marshal.list | 23 + libcaja-private/caja-merged-directory.c | 735 + libcaja-private/caja-merged-directory.h | 69 + libcaja-private/caja-metadata.c | 80 + libcaja-private/caja-metadata.h | 82 + libcaja-private/caja-mime-actions.c | 2597 ++++ libcaja-private/caja-mime-actions.h | 62 + libcaja-private/caja-mime-application-chooser.c | 746 + libcaja-private/caja-mime-application-chooser.h | 57 + libcaja-private/caja-module.c | 293 + libcaja-private/caja-module.h | 46 + libcaja-private/caja-monitor.c | 157 + libcaja-private/caja-monitor.h | 38 + libcaja-private/caja-open-with-dialog.c | 1183 ++ libcaja-private/caja-open-with-dialog.h | 66 + libcaja-private/caja-program-choosing.c | 509 + libcaja-private/caja-program-choosing.h | 57 + libcaja-private/caja-progress-info.c | 930 ++ libcaja-private/caja-progress-info.h | 85 + libcaja-private/caja-query.c | 395 + libcaja-private/caja-query.h | 68 + libcaja-private/caja-recent.c | 80 + libcaja-private/caja-recent.h | 13 + libcaja-private/caja-saved-search-file.c | 49 + libcaja-private/caja-saved-search-file.h | 58 + libcaja-private/caja-search-directory-file.c | 260 + libcaja-private/caja-search-directory-file.h | 59 + libcaja-private/caja-search-directory.c | 934 ++ libcaja-private/caja-search-directory.h | 73 + libcaja-private/caja-search-engine-beagle.c | 443 + libcaja-private/caja-search-engine-beagle.h | 53 + libcaja-private/caja-search-engine-simple.c | 464 + libcaja-private/caja-search-engine-simple.h | 53 + libcaja-private/caja-search-engine-tracker.c | 580 + libcaja-private/caja-search-engine-tracker.h | 53 + libcaja-private/caja-search-engine.c | 216 + libcaja-private/caja-search-engine.h | 77 + libcaja-private/caja-sidebar-provider.c | 74 + libcaja-private/caja-sidebar-provider.h | 61 + libcaja-private/caja-sidebar.c | 128 + libcaja-private/caja-sidebar.h | 84 + libcaja-private/caja-signaller.c | 115 + libcaja-private/caja-signaller.h | 46 + libcaja-private/caja-thumbnails.c | 1084 ++ libcaja-private/caja-thumbnails.h | 80 + libcaja-private/caja-trash-monitor.c | 250 + libcaja-private/caja-trash-monitor.h | 70 + libcaja-private/caja-tree-view-drag-dest.c | 1306 ++ libcaja-private/caja-tree-view-drag-dest.h | 106 + libcaja-private/caja-ui-utilities.c | 256 + libcaja-private/caja-ui-utilities.h | 43 + libcaja-private/caja-undo-manager.c | 320 + libcaja-private/caja-undo-manager.h | 82 + libcaja-private/caja-undo-private.h | 36 + libcaja-private/caja-undo-signal-handlers.c | 345 + libcaja-private/caja-undo-signal-handlers.h | 37 + libcaja-private/caja-undo-transaction.c | 343 + libcaja-private/caja-undo-transaction.h | 80 + libcaja-private/caja-undo.c | 218 + libcaja-private/caja-undo.h | 77 + libcaja-private/caja-users-groups-cache.c | 295 + libcaja-private/caja-users-groups-cache.h | 34 + libcaja-private/caja-vfs-directory.c | 170 + libcaja-private/caja-vfs-directory.h | 57 + libcaja-private/caja-vfs-file.c | 781 + libcaja-private/caja-vfs-file.h | 57 + libcaja-private/caja-view-factory.c | 126 + libcaja-private/caja-view-factory.h | 75 + libcaja-private/caja-view.c | 330 + libcaja-private/caja-view.h | 193 + libcaja-private/caja-window-info.c | 291 + libcaja-private/caja-window-info.h | 189 + libcaja-private/caja-window-slot-info.c | 157 + libcaja-private/caja-window-slot-info.h | 97 + ltmain.sh | 9655 ++++++++++++ m4/gtk-doc.m4 | 67 + m4/intltool.m4 | 216 + m4/libtool.m4 | 7982 ++++++++++ m4/ltoptions.m4 | 384 + m4/ltsugar.m4 | 123 + m4/ltversion.m4 | 23 + m4/lt~obsolete.m4 | 98 + missing | 376 + mkinstalldirs | 162 + po/ChangeLog | 14540 +++++++++++++++++++ po/LINGUAS | 111 + po/POTFILES.in | 116 + po/POTFILES.skip | 10 + po/af.po | 9108 ++++++++++++ po/am.po | 6957 +++++++++ po/ar.po | 7816 ++++++++++ po/as.po | 7860 ++++++++++ po/ast.po | 7372 ++++++++++ po/az.po | 6869 +++++++++ po/be.po | 7584 ++++++++++ po/be@latin.po | 6875 +++++++++ po/bg.po | 7634 ++++++++++ po/bn.po | 7490 ++++++++++ po/bn_IN.po | 7456 ++++++++++ po/br.po | 6898 +++++++++ po/bs.po | 7124 +++++++++ po/ca.po | 8182 +++++++++++ po/ca@valencia.po | 7992 ++++++++++ po/crh.po | 9240 ++++++++++++ po/cs.po | 7499 ++++++++++ po/cy.po | 8976 ++++++++++++ po/da.po | 7982 ++++++++++ po/de.po | 8137 +++++++++++ po/dz.po | 6901 +++++++++ po/el.po | 7334 ++++++++++ po/en@shaw.po | 7478 ++++++++++ po/en_CA.po | 6248 ++++++++ po/en_GB.po | 8484 +++++++++++ po/eo.po | 7520 ++++++++++ po/es.po | 8824 +++++++++++ po/et.po | 5838 ++++++++ po/eu.po | 7729 ++++++++++ po/fa.po | 8218 +++++++++++ po/fi.po | 7706 ++++++++++ po/fr.po | 7733 ++++++++++ po/fur.po | 6349 ++++++++ po/fy.po | 6980 +++++++++ po/ga.po | 7167 +++++++++ po/gl.po | 7732 ++++++++++ po/gu.po | 7335 ++++++++++ po/gv.po | 7811 ++++++++++ po/ha.po | 8321 +++++++++++ po/he.po | 9223 ++++++++++++ po/hi.po | 7304 ++++++++++ po/hr.po | 7061 +++++++++ po/hu.po | 7616 ++++++++++ po/hy.po | 5520 +++++++ po/id.po | 7621 ++++++++++ po/ig.po | 8168 +++++++++++ po/io.po | 5852 ++++++++ po/is.po | 7393 ++++++++++ po/it.po | 7905 ++++++++++ po/ja.po | 7627 ++++++++++ po/ka.po | 6894 +++++++++ po/kk.po | 7335 ++++++++++ po/km.po | 5533 +++++++ po/kn.po | 7606 ++++++++++ po/ko.po | 7418 ++++++++++ po/ku.po | 6232 ++++++++ po/li.po | 8928 ++++++++++++ po/lt.po | 7826 ++++++++++ po/lv.po | 7695 ++++++++++ po/mai.po | 6627 +++++++++ po/mg.po | 5752 ++++++++ po/mi.po | 6017 ++++++++ po/mk.po | 7830 ++++++++++ po/ml.po | 7351 ++++++++++ po/mn.po | 7140 +++++++++ po/mr.po | 7321 ++++++++++ po/ms.po | 8896 ++++++++++++ po/nb.po | 7519 ++++++++++ po/nds.po | 6746 +++++++++ po/ne.po | 6235 ++++++++ po/nl.po | 8497 +++++++++++ po/nn.po | 8891 ++++++++++++ po/nso.po | 9291 ++++++++++++ po/oc.po | 7903 ++++++++++ po/or.po | 7378 ++++++++++ po/pa.po | 7988 ++++++++++ po/pl.po | 7675 ++++++++++ po/ps.po | 6634 +++++++++ po/pt.po | 10496 +++++++++++++ po/pt_BR.po | 8162 +++++++++++ po/ro.po | 7815 ++++++++++ po/ru.po | 7688 ++++++++++ po/rw.po | 7205 +++++++++ po/si.po | 5962 ++++++++ po/sk.po | 6909 +++++++++ po/sl.po | 7512 ++++++++++ po/sq.po | 7075 +++++++++ po/sr.po | 8059 ++++++++++ po/sr@ije.po | 7459 ++++++++++ po/sr@latin.po | 8059 ++++++++++ po/sv.po | 7095 +++++++++ po/ta.po | 6616 +++++++++ po/te.po | 7137 +++++++++ po/th.po | 7388 ++++++++++ po/tk.po | 6623 +++++++++ po/tr.po | 8164 +++++++++++ po/ug.po | 7378 ++++++++++ po/uk.po | 7488 ++++++++++ po/uz.po | 6214 ++++++++ po/uz@cyrillic.po | 6214 ++++++++ po/vi.po | 6265 ++++++++ po/wa.po | 7277 ++++++++++ po/xh.po | 6776 +++++++++ po/yi.po | 5857 ++++++++ po/yo.po | 8147 +++++++++++ po/zh_CN.po | 7439 ++++++++++ po/zh_HK.po | 8114 +++++++++++ po/zh_TW.po | 8240 +++++++++++ po/zu.po | 6638 +++++++++ src/Makefile.am | 197 + src/caja-actions.h | 56 + src/caja-application.c | 2338 +++ src/caja-application.h | 117 + src/caja-autorun-software.c | 316 + src/caja-bookmark-list.c | 775 + src/caja-bookmark-list.h | 87 + src/caja-bookmarks-window.c | 1112 ++ src/caja-bookmarks-window.h | 39 + src/caja-bookmarks-window.ui | 370 + src/caja-connect-server-dialog-main.c | 235 + src/caja-connect-server-dialog-nonmain.c | 59 + src/caja-connect-server-dialog.c | 1075 ++ src/caja-connect-server-dialog.h | 61 + src/caja-convert-metadata.c | 492 + src/caja-desktop-window.c | 277 + src/caja-desktop-window.h | 66 + src/caja-emblem-sidebar.c | 1174 ++ src/caja-emblem-sidebar.h | 63 + src/caja-file-management-properties-main.c | 64 + src/caja-file-management-properties.c | 891 ++ src/caja-file-management-properties.h | 41 + src/caja-file-management-properties.ui | 3080 ++++ src/caja-history-sidebar.c | 423 + src/caja-history-sidebar.h | 50 + src/caja-image-properties-page.c | 745 + src/caja-image-properties-page.h | 57 + src/caja-information-panel.c | 1271 ++ src/caja-information-panel.h | 66 + src/caja-location-bar.c | 617 + src/caja-location-bar.h | 70 + src/caja-location-dialog.c | 275 + src/caja-location-dialog.h | 55 + src/caja-location-entry.c | 485 + src/caja-location-entry.h | 72 + src/caja-main.c | 590 + src/caja-main.h | 37 + src/caja-navigation-action.c | 381 + src/caja-navigation-action.h | 68 + src/caja-navigation-bar.c | 170 + src/caja-navigation-bar.h | 77 + src/caja-navigation-window-menus.c | 1099 ++ src/caja-navigation-window-pane.c | 946 ++ src/caja-navigation-window-pane.h | 92 + src/caja-navigation-window-slot.c | 241 + src/caja-navigation-window-slot.h | 78 + src/caja-navigation-window-ui.xml | 77 + src/caja-navigation-window.c | 1426 ++ src/caja-navigation-window.h | 119 + src/caja-notebook.c | 570 + src/caja-notebook.h | 99 + src/caja-notes-viewer.c | 535 + src/caja-notes-viewer.h | 50 + src/caja-pathbar.c | 2165 +++ src/caja-pathbar.h | 90 + src/caja-places-sidebar.c | 3092 ++++ src/caja-places-sidebar.h | 49 + src/caja-property-browser.c | 2492 ++++ src/caja-property-browser.h | 71 + src/caja-query-editor.c | 1397 ++ src/caja-query-editor.h | 81 + src/caja-search-bar.c | 256 + src/caja-search-bar.h | 68 + src/caja-self-check-functions.c | 40 + src/caja-self-check-functions.h | 47 + src/caja-shell-ui.xml | 87 + src/caja-side-pane.c | 675 + src/caja-side-pane.h | 82 + src/caja-sidebar-title.c | 732 + src/caja-sidebar-title.h | 76 + src/caja-spatial-window-ui.xml | 29 + src/caja-spatial-window.c | 1209 ++ src/caja-spatial-window.h | 71 + src/caja-trash-bar.c | 236 + src/caja-trash-bar.h | 64 + src/caja-view-as-action.c | 288 + src/caja-view-as-action.h | 57 + src/caja-window-bookmarks.c | 295 + src/caja-window-bookmarks.h | 37 + src/caja-window-manage-views.c | 2337 +++ src/caja-window-manage-views.h | 49 + src/caja-window-menus.c | 1163 ++ src/caja-window-pane.c | 305 + src/caja-window-pane.h | 97 + src/caja-window-private.h | 250 + src/caja-window-slot.c | 710 + src/caja-window-slot.h | 186 + src/caja-window-toolbars.c | 204 + src/caja-window.c | 2164 +++ src/caja-window.h | 164 + src/caja-x-content-bar.c | 331 + src/caja-x-content-bar.h | 71 + src/caja-zoom-action.c | 211 + src/caja-zoom-action.h | 57 + src/caja-zoom-control.c | 996 ++ src/caja-zoom-control.h | 91 + src/check-caja | 2 + src/file-manager/Makefile.am | 61 + src/file-manager/caja-audio-mime-types.h | 46 + src/file-manager/caja-desktop-icon-view-ui.xml | 21 + src/file-manager/caja-directory-view-ui.xml | 231 + src/file-manager/caja-icon-view-ui.xml | 56 + src/file-manager/caja-list-view-ui.xml | 9 + src/file-manager/fm-actions.h | 110 + src/file-manager/fm-desktop-icon-view.c | 881 ++ src/file-manager/fm-desktop-icon-view.h | 60 + src/file-manager/fm-directory-view.c | 10936 ++++++++++++++ src/file-manager/fm-directory-view.h | 495 + src/file-manager/fm-ditem-page.c | 563 + src/file-manager/fm-ditem-page.h | 51 + src/file-manager/fm-empty-view.c | 412 + src/file-manager/fm-empty-view.h | 60 + src/file-manager/fm-error-reporting.c | 380 + src/file-manager/fm-error-reporting.h | 55 + src/file-manager/fm-icon-container.c | 625 + src/file-manager/fm-icon-container.h | 68 + src/file-manager/fm-icon-view.c | 3439 +++++ src/file-manager/fm-icon-view.h | 135 + src/file-manager/fm-list-model.c | 1882 +++ src/file-manager/fm-list-model.h | 148 + src/file-manager/fm-list-view-private.h | 43 + src/file-manager/fm-list-view.c | 3415 +++++ src/file-manager/fm-list-view.h | 63 + src/file-manager/fm-properties-window.c | 5835 ++++++++ src/file-manager/fm-properties-window.h | 69 + src/file-manager/fm-tree-model.c | 2152 +++ src/file-manager/fm-tree-model.h | 104 + src/file-manager/fm-tree-view.c | 1814 +++ src/file-manager/fm-tree-view.h | 65 + src/mate-network-scheme.desktop.in | 11 + test/Makefile.am | 46 + test/test-caja-directory-async.c | 104 + test/test-caja-search-engine.c | 58 + test/test-caja-wrap-table.c | 96 + test/test-copy.c | 93 + test/test-eel-background.c | 38 + test/test-eel-editable-label.c | 58 + test/test-eel-image-scrolled.c | 187 + test/test-eel-image-table.c | 304 + test/test-eel-labeled-image.c | 79 + test/test-eel-pixbuf-scale.c | 83 + test/test.c | 152 + test/test.h | 38 + 709 files changed, 1088094 insertions(+) create mode 100644 AUTHORS create mode 100644 COPYING create mode 100644 COPYING-DOCS create mode 100644 COPYING.EXTENSIONS create mode 100644 COPYING.LIB create mode 100644 ChangeLog create mode 100644 HACKING create mode 100644 INSTALL create mode 100644 MAINTAINERS create mode 100644 Makefile.am create mode 100644 Makefile.shared create mode 100644 NEWS create mode 100644 README create mode 100644 README.commits create mode 100644 THANKS create mode 100644 TODO create mode 100644 acconfig.h create mode 100644 aclocal.m4 create mode 100755 add-include-prefix create mode 100755 autogen.sh create mode 100755 config.guess create mode 100644 config.h.in create mode 100755 config.sub create mode 100644 configure.in create mode 100644 cut-n-paste-code/Makefile.am create mode 100644 cut-n-paste-code/Makefile.in create mode 100644 cut-n-paste-code/README create mode 100644 cut-n-paste-code/libegg/Makefile.am create mode 100644 cut-n-paste-code/libegg/Makefile.in create mode 100644 cut-n-paste-code/libegg/eggdesktopfile.c create mode 100644 cut-n-paste-code/libegg/eggdesktopfile.h create mode 100644 cut-n-paste-code/libegg/eggsmclient-private.h create mode 100644 cut-n-paste-code/libegg/eggsmclient-xsmp.c create mode 100644 cut-n-paste-code/libegg/eggsmclient.c create mode 100644 cut-n-paste-code/libegg/eggsmclient.h create mode 100644 cut-n-paste-code/libegg/eggtreemultidnd.c create mode 100644 cut-n-paste-code/libegg/eggtreemultidnd.h create mode 100755 cut-n-paste-code/libegg/update-from-egg.sh create mode 100644 data/Makefile.am create mode 100644 data/browser.xml create mode 100644 data/caja-autorun-software.desktop.in.in create mode 100644 data/caja-browser.desktop.in.in create mode 100644 data/caja-computer.desktop.in.in create mode 100644 data/caja-extras.placeholder create mode 100644 data/caja-file-management-properties.desktop.in.in create mode 100644 data/caja-folder-handler.desktop.in.in create mode 100644 data/caja-home.desktop.in.in create mode 100644 data/caja-suggested.placeholder create mode 100644 data/caja.desktop.in.in create mode 100644 data/caja.xml.in create mode 100644 data/icons/Makefile.am create mode 100644 data/icons/hicolor_apps_16x16_caja.png create mode 100644 data/icons/hicolor_apps_16x16_caja.svg create mode 100644 data/icons/hicolor_apps_22x22_caja.png create mode 100644 data/icons/hicolor_apps_22x22_caja.svg create mode 100644 data/icons/hicolor_apps_24x24_caja.png create mode 100644 data/icons/hicolor_apps_32x32_caja.png create mode 100644 data/icons/hicolor_apps_32x32_caja.svg create mode 100644 data/icons/hicolor_apps_scalable_caja.svg create mode 100644 data/icons/hicolor_emblems_16x16_emblem-note.png create mode 100644 data/icons/hicolor_emblems_24x24_emblem-note.png create mode 100644 data/icons/hicolor_emblems_48x48_emblem-note.png create mode 100644 data/patterns/Makefile.am create mode 100644 data/patterns/blue_gray_rough.png create mode 100644 data/patterns/blue_ridge.png create mode 100644 data/patterns/blue_type.png create mode 100644 data/patterns/brushed_metal.png create mode 100644 data/patterns/burlap.jpg create mode 100644 data/patterns/camouflage.png create mode 100644 data/patterns/chalk.jpg create mode 100644 data/patterns/cork.png create mode 100644 data/patterns/countertop.png create mode 100644 data/patterns/dark-mate.jpg create mode 100644 data/patterns/dots.png create mode 100644 data/patterns/fibers.png create mode 100644 data/patterns/fleur_de_lis.png create mode 100644 data/patterns/floral.png create mode 100644 data/patterns/fossil.png create mode 100644 data/patterns/green_weave.png create mode 100644 data/patterns/ice.png create mode 100644 data/patterns/manila_paper.png create mode 100644 data/patterns/mate.jpg create mode 100644 data/patterns/moss_ridge.png create mode 100644 data/patterns/numbers.png create mode 100644 data/patterns/ocean_stripes.png create mode 100644 data/patterns/purple_marble.png create mode 100644 data/patterns/reset.png create mode 100644 data/patterns/ridged_paper.png create mode 100644 data/patterns/rough_paper.png create mode 100644 data/patterns/sky_ridge.png create mode 100644 data/patterns/snow_ridge.png create mode 100644 data/patterns/stucco.jpg create mode 100644 data/patterns/terracotta.png create mode 100644 data/patterns/wavy_white.png create mode 100755 depcomp create mode 100644 distro/archlinux/PKGBUILD create mode 100644 distro/archlinux/mate-file-manager.install create mode 100755 distro/ubuntu/build create mode 100755 distro/ubuntu/postinst create mode 100755 distro/ubuntu/postrm create mode 100755 distro/ubuntu/preinst create mode 100755 distro/ubuntu/prerm create mode 100644 docs/Makefile.am create mode 100644 docs/architecture.txt create mode 100644 docs/caja-connect-server.1 create mode 100644 docs/caja-file-management-properties.1 create mode 100644 docs/caja-internals.pdf create mode 100644 docs/caja-internals.sxw create mode 100644 docs/caja-io.txt create mode 100644 docs/caja.1 create mode 100644 docs/caja.faq create mode 100644 docs/dnd.txt create mode 100644 docs/key_mouse_navigation.txt create mode 100644 docs/load-states.dia create mode 100644 docs/recommended-books.html create mode 100644 docs/reference/Makefile.am create mode 100644 docs/reference/Makefile.in create mode 100644 docs/reference/libcaja-extension/Makefile.am create mode 100644 docs/reference/libcaja-extension/Makefile.in create mode 100644 docs/reference/libcaja-extension/html/ch01.html create mode 100644 docs/reference/libcaja-extension/html/home.png create mode 100644 docs/reference/libcaja-extension/html/index.html create mode 100644 docs/reference/libcaja-extension/html/index.sgml create mode 100644 docs/reference/libcaja-extension/html/ix01.html create mode 100644 docs/reference/libcaja-extension/html/left.png create mode 100644 docs/reference/libcaja-extension/html/libcaja-extension-caja-column-provider.html create mode 100644 docs/reference/libcaja-extension/html/libcaja-extension-caja-column.html create mode 100644 docs/reference/libcaja-extension/html/libcaja-extension-caja-extension-types.html create mode 100644 docs/reference/libcaja-extension/html/libcaja-extension-caja-file-info.html create mode 100644 docs/reference/libcaja-extension/html/libcaja-extension-caja-info-provider.html create mode 100644 docs/reference/libcaja-extension/html/libcaja-extension-caja-location-widget-provider.html create mode 100644 docs/reference/libcaja-extension/html/libcaja-extension-caja-menu-provider.html create mode 100644 docs/reference/libcaja-extension/html/libcaja-extension-caja-menu.html create mode 100644 docs/reference/libcaja-extension/html/libcaja-extension-caja-property-page-provider.html create mode 100644 docs/reference/libcaja-extension/html/libcaja-extension-caja-property-page.html create mode 100644 docs/reference/libcaja-extension/html/libcaja-extension.devhelp create mode 100644 docs/reference/libcaja-extension/html/libcaja-extension.devhelp2 create mode 100644 docs/reference/libcaja-extension/html/pt01.html create mode 100644 docs/reference/libcaja-extension/html/right.png create mode 100644 docs/reference/libcaja-extension/html/style.css create mode 100644 docs/reference/libcaja-extension/html/up.png create mode 100644 docs/reference/libcaja-extension/libcaja-extension-docs.xml create mode 100644 docs/reference/libcaja-extension/libcaja-extension-overrides.txt create mode 100644 docs/reference/libcaja-extension/libcaja-extension-sections.txt create mode 100644 docs/reference/libcaja-extension/libcaja-extension.types create mode 100644 docs/reference/libcaja-extension/tmpl/caja-column-provider.sgml create mode 100644 docs/reference/libcaja-extension/tmpl/caja-column.sgml create mode 100644 docs/reference/libcaja-extension/tmpl/caja-extension-types.sgml create mode 100644 docs/reference/libcaja-extension/tmpl/caja-file-info.sgml create mode 100644 docs/reference/libcaja-extension/tmpl/caja-info-provider.sgml create mode 100644 docs/reference/libcaja-extension/tmpl/caja-location-widget-provider.sgml create mode 100644 docs/reference/libcaja-extension/tmpl/caja-menu-item.sgml create mode 100644 docs/reference/libcaja-extension/tmpl/caja-menu-provider.sgml create mode 100644 docs/reference/libcaja-extension/tmpl/caja-menu.sgml create mode 100644 docs/reference/libcaja-extension/tmpl/caja-property-page-provider.sgml create mode 100644 docs/reference/libcaja-extension/tmpl/caja-property-page.sgml create mode 100644 docs/reference/libcaja-extension/tmpl/libcaja-extension-unused.sgml create mode 100644 docs/reference/libcaja-extension/version.xml.in create mode 100644 docs/smoketests.html create mode 100644 docs/state-machines.txt create mode 100644 docs/style-guide.html create mode 100644 eel/ChangeLog create mode 100644 eel/Makefile.am create mode 100644 eel/README create mode 100755 eel/check-eel create mode 100644 eel/check-program.c create mode 100644 eel/eel-accessibility.c create mode 100644 eel/eel-accessibility.h create mode 100644 eel/eel-alert-dialog.c create mode 100644 eel/eel-alert-dialog.h create mode 100644 eel/eel-art-extensions.c create mode 100644 eel/eel-art-extensions.h create mode 100644 eel/eel-art-gtk-extensions.c create mode 100644 eel/eel-art-gtk-extensions.h create mode 100644 eel/eel-background-box.c create mode 100644 eel/eel-background-box.h create mode 100644 eel/eel-background.c create mode 100644 eel/eel-background.h create mode 100644 eel/eel-canvas-rect-ellipse.c create mode 100644 eel/eel-canvas-rect-ellipse.h create mode 100644 eel/eel-canvas-util.c create mode 100644 eel/eel-canvas-util.h create mode 100644 eel/eel-canvas.c create mode 100644 eel/eel-canvas.h create mode 100644 eel/eel-debug-drawing.c create mode 100644 eel/eel-debug-drawing.h create mode 100644 eel/eel-debug.c create mode 100644 eel/eel-debug.h create mode 100644 eel/eel-editable-label.c create mode 100644 eel/eel-editable-label.h create mode 100644 eel/eel-enumeration.c create mode 100644 eel/eel-enumeration.h create mode 100644 eel/eel-gdk-extensions.c create mode 100644 eel/eel-gdk-extensions.h create mode 100644 eel/eel-gdk-pixbuf-extensions.c create mode 100644 eel/eel-gdk-pixbuf-extensions.h create mode 100644 eel/eel-glib-extensions.c create mode 100644 eel/eel-glib-extensions.h create mode 100644 eel/eel-graphic-effects.c create mode 100644 eel/eel-graphic-effects.h create mode 100644 eel/eel-gtk-container.c create mode 100644 eel/eel-gtk-container.h create mode 100644 eel/eel-gtk-extensions.c create mode 100644 eel/eel-gtk-extensions.h create mode 100644 eel/eel-gtk-macros.h create mode 100644 eel/eel-i18n.c create mode 100644 eel/eel-i18n.h create mode 100644 eel/eel-image-table.c create mode 100644 eel/eel-image-table.h create mode 100644 eel/eel-labeled-image.c create mode 100644 eel/eel-labeled-image.h create mode 100644 eel/eel-lib-self-check-functions.c create mode 100644 eel/eel-lib-self-check-functions.h create mode 100644 eel/eel-mate-extensions.c create mode 100644 eel/eel-mate-extensions.h create mode 100644 eel/eel-mateconf-extensions.c create mode 100644 eel/eel-mateconf-extensions.h create mode 100644 eel/eel-pango-extensions.c create mode 100644 eel/eel-pango-extensions.h create mode 100644 eel/eel-preferences-builder.c create mode 100644 eel/eel-preferences.c create mode 100644 eel/eel-preferences.h create mode 100644 eel/eel-self-checks.c create mode 100644 eel/eel-self-checks.h create mode 100644 eel/eel-stock-dialogs.c create mode 100644 eel/eel-stock-dialogs.h create mode 100644 eel/eel-string.c create mode 100644 eel/eel-string.h create mode 100644 eel/eel-types.c create mode 100644 eel/eel-types.h create mode 100644 eel/eel-vfs-extensions.c create mode 100644 eel/eel-vfs-extensions.h create mode 100644 eel/eel-wrap-table.c create mode 100644 eel/eel-wrap-table.h create mode 100644 eel/eel-xml-extensions.c create mode 100644 eel/eel-xml-extensions.h create mode 100644 eel/eel.h create mode 100644 eel/eelmarshal.list create mode 100755 eel/makeenums.pl create mode 100755 eel/maketypes.awk create mode 100644 gtk-doc.make create mode 100644 icons/Makefile.am create mode 100644 icons/audio.svg create mode 100644 icons/backgrounds.png create mode 100644 icons/chit_frame.png create mode 100644 icons/colors.png create mode 100644 icons/emblems.png create mode 100644 icons/erase.png create mode 100644 icons/knob.png create mode 100644 icons/thumbnail_frame.png create mode 100755 install-sh create mode 100644 intltool-extract.in create mode 100644 intltool-merge.in create mode 100644 intltool-update.in create mode 100644 libcaja-extension/Makefile.am create mode 100644 libcaja-extension/caja-column-provider.c create mode 100644 libcaja-extension/caja-column-provider.h create mode 100644 libcaja-extension/caja-column.c create mode 100644 libcaja-extension/caja-column.h create mode 100644 libcaja-extension/caja-extension-i18n.h create mode 100644 libcaja-extension/caja-extension-private.h create mode 100644 libcaja-extension/caja-extension-types.c create mode 100644 libcaja-extension/caja-extension-types.h create mode 100644 libcaja-extension/caja-file-info.c create mode 100644 libcaja-extension/caja-file-info.h create mode 100644 libcaja-extension/caja-info-provider.c create mode 100644 libcaja-extension/caja-info-provider.h create mode 100644 libcaja-extension/caja-location-widget-provider.c create mode 100644 libcaja-extension/caja-location-widget-provider.h create mode 100644 libcaja-extension/caja-menu-item.c create mode 100644 libcaja-extension/caja-menu-item.h create mode 100644 libcaja-extension/caja-menu-provider.c create mode 100644 libcaja-extension/caja-menu-provider.h create mode 100644 libcaja-extension/caja-menu.c create mode 100644 libcaja-extension/caja-menu.h create mode 100644 libcaja-extension/caja-property-page-provider.c create mode 100644 libcaja-extension/caja-property-page-provider.h create mode 100644 libcaja-extension/caja-property-page.c create mode 100644 libcaja-extension/caja-property-page.h create mode 100644 libcaja-extension/libcaja-extension-uninstalled.pc.in create mode 100644 libcaja-extension/libcaja-extension.pc.in create mode 100644 libcaja-private/Makefile.am create mode 100644 libcaja-private/README create mode 100644 libcaja-private/apps_caja_preferences.schemas.in create mode 100644 libcaja-private/caja-autorun.c create mode 100644 libcaja-private/caja-autorun.h create mode 100644 libcaja-private/caja-bookmark.c create mode 100644 libcaja-private/caja-bookmark.h create mode 100644 libcaja-private/caja-cell-renderer-pixbuf-emblem.c create mode 100644 libcaja-private/caja-cell-renderer-pixbuf-emblem.h create mode 100644 libcaja-private/caja-cell-renderer-text-ellipsized.c create mode 100644 libcaja-private/caja-cell-renderer-text-ellipsized.h create mode 100644 libcaja-private/caja-clipboard-monitor.c create mode 100644 libcaja-private/caja-clipboard-monitor.h create mode 100644 libcaja-private/caja-clipboard.c create mode 100644 libcaja-private/caja-clipboard.h create mode 100644 libcaja-private/caja-column-chooser.c create mode 100644 libcaja-private/caja-column-chooser.h create mode 100644 libcaja-private/caja-column-utilities.c create mode 100644 libcaja-private/caja-column-utilities.h create mode 100644 libcaja-private/caja-customization-data.c create mode 100644 libcaja-private/caja-customization-data.h create mode 100644 libcaja-private/caja-debug-log.c create mode 100644 libcaja-private/caja-debug-log.h create mode 100644 libcaja-private/caja-default-file-icon.c create mode 100644 libcaja-private/caja-default-file-icon.h create mode 100644 libcaja-private/caja-desktop-directory-file.c create mode 100644 libcaja-private/caja-desktop-directory-file.h create mode 100644 libcaja-private/caja-desktop-directory.c create mode 100644 libcaja-private/caja-desktop-directory.h create mode 100644 libcaja-private/caja-desktop-icon-file.c create mode 100644 libcaja-private/caja-desktop-icon-file.h create mode 100644 libcaja-private/caja-desktop-link-monitor.c create mode 100644 libcaja-private/caja-desktop-link-monitor.h create mode 100644 libcaja-private/caja-desktop-link.c create mode 100644 libcaja-private/caja-desktop-link.h create mode 100644 libcaja-private/caja-directory-async.c create mode 100644 libcaja-private/caja-directory-background.c create mode 100644 libcaja-private/caja-directory-background.h create mode 100644 libcaja-private/caja-directory-notify.h create mode 100644 libcaja-private/caja-directory-private.h create mode 100644 libcaja-private/caja-directory.c create mode 100644 libcaja-private/caja-directory.h create mode 100644 libcaja-private/caja-dnd.c create mode 100644 libcaja-private/caja-dnd.h create mode 100644 libcaja-private/caja-emblem-utils.c create mode 100644 libcaja-private/caja-emblem-utils.h create mode 100644 libcaja-private/caja-entry.c create mode 100644 libcaja-private/caja-entry.h create mode 100644 libcaja-private/caja-file-attributes.h create mode 100644 libcaja-private/caja-file-changes-queue.c create mode 100644 libcaja-private/caja-file-changes-queue.h create mode 100644 libcaja-private/caja-file-conflict-dialog.c create mode 100644 libcaja-private/caja-file-conflict-dialog.h create mode 100644 libcaja-private/caja-file-dnd.c create mode 100644 libcaja-private/caja-file-dnd.h create mode 100644 libcaja-private/caja-file-operations.c create mode 100644 libcaja-private/caja-file-operations.h create mode 100644 libcaja-private/caja-file-private.h create mode 100644 libcaja-private/caja-file-queue.c create mode 100644 libcaja-private/caja-file-queue.h create mode 100644 libcaja-private/caja-file-utilities.c create mode 100644 libcaja-private/caja-file-utilities.h create mode 100644 libcaja-private/caja-file.c create mode 100644 libcaja-private/caja-file.h create mode 100644 libcaja-private/caja-global-preferences.c create mode 100644 libcaja-private/caja-global-preferences.h create mode 100644 libcaja-private/caja-horizontal-splitter.c create mode 100644 libcaja-private/caja-horizontal-splitter.h create mode 100644 libcaja-private/caja-icon-canvas-item.c create mode 100644 libcaja-private/caja-icon-canvas-item.h create mode 100644 libcaja-private/caja-icon-container.c create mode 100644 libcaja-private/caja-icon-container.h create mode 100644 libcaja-private/caja-icon-dnd.c create mode 100644 libcaja-private/caja-icon-dnd.h create mode 100644 libcaja-private/caja-icon-info.c create mode 100644 libcaja-private/caja-icon-info.h create mode 100644 libcaja-private/caja-icon-names.h create mode 100644 libcaja-private/caja-icon-private.h create mode 100644 libcaja-private/caja-idle-queue.c create mode 100644 libcaja-private/caja-idle-queue.h create mode 100644 libcaja-private/caja-iso9660.h create mode 100644 libcaja-private/caja-keep-last-vertical-box.c create mode 100644 libcaja-private/caja-keep-last-vertical-box.h create mode 100644 libcaja-private/caja-lib-self-check-functions.c create mode 100644 libcaja-private/caja-lib-self-check-functions.h create mode 100644 libcaja-private/caja-link.c create mode 100644 libcaja-private/caja-link.h create mode 100644 libcaja-private/caja-marshal.c create mode 100644 libcaja-private/caja-marshal.list create mode 100644 libcaja-private/caja-merged-directory.c create mode 100644 libcaja-private/caja-merged-directory.h create mode 100644 libcaja-private/caja-metadata.c create mode 100644 libcaja-private/caja-metadata.h create mode 100644 libcaja-private/caja-mime-actions.c create mode 100644 libcaja-private/caja-mime-actions.h create mode 100644 libcaja-private/caja-mime-application-chooser.c create mode 100644 libcaja-private/caja-mime-application-chooser.h create mode 100644 libcaja-private/caja-module.c create mode 100644 libcaja-private/caja-module.h create mode 100644 libcaja-private/caja-monitor.c create mode 100644 libcaja-private/caja-monitor.h create mode 100644 libcaja-private/caja-open-with-dialog.c create mode 100644 libcaja-private/caja-open-with-dialog.h create mode 100644 libcaja-private/caja-program-choosing.c create mode 100644 libcaja-private/caja-program-choosing.h create mode 100644 libcaja-private/caja-progress-info.c create mode 100644 libcaja-private/caja-progress-info.h create mode 100644 libcaja-private/caja-query.c create mode 100644 libcaja-private/caja-query.h create mode 100644 libcaja-private/caja-recent.c create mode 100644 libcaja-private/caja-recent.h create mode 100644 libcaja-private/caja-saved-search-file.c create mode 100644 libcaja-private/caja-saved-search-file.h create mode 100644 libcaja-private/caja-search-directory-file.c create mode 100644 libcaja-private/caja-search-directory-file.h create mode 100644 libcaja-private/caja-search-directory.c create mode 100644 libcaja-private/caja-search-directory.h create mode 100644 libcaja-private/caja-search-engine-beagle.c create mode 100644 libcaja-private/caja-search-engine-beagle.h create mode 100644 libcaja-private/caja-search-engine-simple.c create mode 100644 libcaja-private/caja-search-engine-simple.h create mode 100644 libcaja-private/caja-search-engine-tracker.c create mode 100644 libcaja-private/caja-search-engine-tracker.h create mode 100644 libcaja-private/caja-search-engine.c create mode 100644 libcaja-private/caja-search-engine.h create mode 100644 libcaja-private/caja-sidebar-provider.c create mode 100644 libcaja-private/caja-sidebar-provider.h create mode 100644 libcaja-private/caja-sidebar.c create mode 100644 libcaja-private/caja-sidebar.h create mode 100644 libcaja-private/caja-signaller.c create mode 100644 libcaja-private/caja-signaller.h create mode 100644 libcaja-private/caja-thumbnails.c create mode 100644 libcaja-private/caja-thumbnails.h create mode 100644 libcaja-private/caja-trash-monitor.c create mode 100644 libcaja-private/caja-trash-monitor.h create mode 100644 libcaja-private/caja-tree-view-drag-dest.c create mode 100644 libcaja-private/caja-tree-view-drag-dest.h create mode 100644 libcaja-private/caja-ui-utilities.c create mode 100644 libcaja-private/caja-ui-utilities.h create mode 100644 libcaja-private/caja-undo-manager.c create mode 100644 libcaja-private/caja-undo-manager.h create mode 100644 libcaja-private/caja-undo-private.h create mode 100644 libcaja-private/caja-undo-signal-handlers.c create mode 100644 libcaja-private/caja-undo-signal-handlers.h create mode 100644 libcaja-private/caja-undo-transaction.c create mode 100644 libcaja-private/caja-undo-transaction.h create mode 100644 libcaja-private/caja-undo.c create mode 100644 libcaja-private/caja-undo.h create mode 100644 libcaja-private/caja-users-groups-cache.c create mode 100644 libcaja-private/caja-users-groups-cache.h create mode 100644 libcaja-private/caja-vfs-directory.c create mode 100644 libcaja-private/caja-vfs-directory.h create mode 100644 libcaja-private/caja-vfs-file.c create mode 100644 libcaja-private/caja-vfs-file.h create mode 100644 libcaja-private/caja-view-factory.c create mode 100644 libcaja-private/caja-view-factory.h create mode 100644 libcaja-private/caja-view.c create mode 100644 libcaja-private/caja-view.h create mode 100644 libcaja-private/caja-window-info.c create mode 100644 libcaja-private/caja-window-info.h create mode 100644 libcaja-private/caja-window-slot-info.c create mode 100644 libcaja-private/caja-window-slot-info.h create mode 100644 ltmain.sh create mode 100644 m4/gtk-doc.m4 create mode 100644 m4/intltool.m4 create mode 100644 m4/libtool.m4 create mode 100644 m4/ltoptions.m4 create mode 100644 m4/ltsugar.m4 create mode 100644 m4/ltversion.m4 create mode 100644 m4/lt~obsolete.m4 create mode 100755 missing create mode 100755 mkinstalldirs create mode 100644 po/ChangeLog create mode 100644 po/LINGUAS create mode 100644 po/POTFILES.in create mode 100644 po/POTFILES.skip create mode 100644 po/af.po create mode 100644 po/am.po create mode 100644 po/ar.po create mode 100644 po/as.po create mode 100644 po/ast.po create mode 100644 po/az.po create mode 100644 po/be.po create mode 100644 po/be@latin.po create mode 100644 po/bg.po create mode 100644 po/bn.po create mode 100644 po/bn_IN.po create mode 100644 po/br.po create mode 100644 po/bs.po create mode 100644 po/ca.po create mode 100644 po/ca@valencia.po create mode 100644 po/crh.po create mode 100644 po/cs.po create mode 100644 po/cy.po create mode 100644 po/da.po create mode 100644 po/de.po create mode 100644 po/dz.po create mode 100644 po/el.po create mode 100644 po/en@shaw.po create mode 100644 po/en_CA.po create mode 100644 po/en_GB.po create mode 100644 po/eo.po create mode 100644 po/es.po create mode 100644 po/et.po create mode 100644 po/eu.po create mode 100644 po/fa.po create mode 100644 po/fi.po create mode 100644 po/fr.po create mode 100644 po/fur.po create mode 100644 po/fy.po create mode 100644 po/ga.po create mode 100644 po/gl.po create mode 100644 po/gu.po create mode 100644 po/gv.po create mode 100644 po/ha.po create mode 100644 po/he.po create mode 100644 po/hi.po create mode 100644 po/hr.po create mode 100644 po/hu.po create mode 100644 po/hy.po create mode 100644 po/id.po create mode 100644 po/ig.po create mode 100644 po/io.po create mode 100644 po/is.po create mode 100644 po/it.po create mode 100644 po/ja.po create mode 100644 po/ka.po create mode 100644 po/kk.po create mode 100644 po/km.po create mode 100644 po/kn.po create mode 100644 po/ko.po create mode 100644 po/ku.po create mode 100644 po/li.po create mode 100644 po/lt.po create mode 100644 po/lv.po create mode 100644 po/mai.po create mode 100644 po/mg.po create mode 100644 po/mi.po create mode 100644 po/mk.po create mode 100644 po/ml.po create mode 100644 po/mn.po create mode 100644 po/mr.po create mode 100644 po/ms.po create mode 100644 po/nb.po create mode 100644 po/nds.po create mode 100644 po/ne.po create mode 100644 po/nl.po create mode 100644 po/nn.po create mode 100644 po/nso.po create mode 100644 po/oc.po create mode 100644 po/or.po create mode 100644 po/pa.po create mode 100644 po/pl.po create mode 100644 po/ps.po create mode 100644 po/pt.po create mode 100644 po/pt_BR.po create mode 100644 po/ro.po create mode 100644 po/ru.po create mode 100644 po/rw.po create mode 100644 po/si.po create mode 100644 po/sk.po create mode 100644 po/sl.po create mode 100644 po/sq.po create mode 100644 po/sr.po create mode 100644 po/sr@ije.po create mode 100644 po/sr@latin.po create mode 100644 po/sv.po create mode 100644 po/ta.po create mode 100644 po/te.po create mode 100644 po/th.po create mode 100644 po/tk.po create mode 100644 po/tr.po create mode 100644 po/ug.po create mode 100644 po/uk.po create mode 100644 po/uz.po create mode 100644 po/uz@cyrillic.po create mode 100644 po/vi.po create mode 100644 po/wa.po create mode 100644 po/xh.po create mode 100644 po/yi.po create mode 100644 po/yo.po create mode 100644 po/zh_CN.po create mode 100644 po/zh_HK.po create mode 100644 po/zh_TW.po create mode 100644 po/zu.po create mode 100644 src/Makefile.am create mode 100644 src/caja-actions.h create mode 100644 src/caja-application.c create mode 100644 src/caja-application.h create mode 100644 src/caja-autorun-software.c create mode 100644 src/caja-bookmark-list.c create mode 100644 src/caja-bookmark-list.h create mode 100644 src/caja-bookmarks-window.c create mode 100644 src/caja-bookmarks-window.h create mode 100644 src/caja-bookmarks-window.ui create mode 100644 src/caja-connect-server-dialog-main.c create mode 100644 src/caja-connect-server-dialog-nonmain.c create mode 100644 src/caja-connect-server-dialog.c create mode 100644 src/caja-connect-server-dialog.h create mode 100644 src/caja-convert-metadata.c create mode 100644 src/caja-desktop-window.c create mode 100644 src/caja-desktop-window.h create mode 100644 src/caja-emblem-sidebar.c create mode 100644 src/caja-emblem-sidebar.h create mode 100644 src/caja-file-management-properties-main.c create mode 100644 src/caja-file-management-properties.c create mode 100644 src/caja-file-management-properties.h create mode 100644 src/caja-file-management-properties.ui create mode 100644 src/caja-history-sidebar.c create mode 100644 src/caja-history-sidebar.h create mode 100644 src/caja-image-properties-page.c create mode 100644 src/caja-image-properties-page.h create mode 100644 src/caja-information-panel.c create mode 100644 src/caja-information-panel.h create mode 100644 src/caja-location-bar.c create mode 100644 src/caja-location-bar.h create mode 100644 src/caja-location-dialog.c create mode 100644 src/caja-location-dialog.h create mode 100644 src/caja-location-entry.c create mode 100644 src/caja-location-entry.h create mode 100644 src/caja-main.c create mode 100644 src/caja-main.h create mode 100644 src/caja-navigation-action.c create mode 100644 src/caja-navigation-action.h create mode 100644 src/caja-navigation-bar.c create mode 100644 src/caja-navigation-bar.h create mode 100644 src/caja-navigation-window-menus.c create mode 100644 src/caja-navigation-window-pane.c create mode 100644 src/caja-navigation-window-pane.h create mode 100644 src/caja-navigation-window-slot.c create mode 100644 src/caja-navigation-window-slot.h create mode 100644 src/caja-navigation-window-ui.xml create mode 100644 src/caja-navigation-window.c create mode 100644 src/caja-navigation-window.h create mode 100644 src/caja-notebook.c create mode 100644 src/caja-notebook.h create mode 100644 src/caja-notes-viewer.c create mode 100644 src/caja-notes-viewer.h create mode 100644 src/caja-pathbar.c create mode 100644 src/caja-pathbar.h create mode 100644 src/caja-places-sidebar.c create mode 100644 src/caja-places-sidebar.h create mode 100644 src/caja-property-browser.c create mode 100644 src/caja-property-browser.h create mode 100644 src/caja-query-editor.c create mode 100644 src/caja-query-editor.h create mode 100644 src/caja-search-bar.c create mode 100644 src/caja-search-bar.h create mode 100644 src/caja-self-check-functions.c create mode 100644 src/caja-self-check-functions.h create mode 100644 src/caja-shell-ui.xml create mode 100644 src/caja-side-pane.c create mode 100644 src/caja-side-pane.h create mode 100644 src/caja-sidebar-title.c create mode 100644 src/caja-sidebar-title.h create mode 100644 src/caja-spatial-window-ui.xml create mode 100644 src/caja-spatial-window.c create mode 100644 src/caja-spatial-window.h create mode 100644 src/caja-trash-bar.c create mode 100644 src/caja-trash-bar.h create mode 100644 src/caja-view-as-action.c create mode 100644 src/caja-view-as-action.h create mode 100644 src/caja-window-bookmarks.c create mode 100644 src/caja-window-bookmarks.h create mode 100644 src/caja-window-manage-views.c create mode 100644 src/caja-window-manage-views.h create mode 100644 src/caja-window-menus.c create mode 100644 src/caja-window-pane.c create mode 100644 src/caja-window-pane.h create mode 100644 src/caja-window-private.h create mode 100644 src/caja-window-slot.c create mode 100644 src/caja-window-slot.h create mode 100644 src/caja-window-toolbars.c create mode 100644 src/caja-window.c create mode 100644 src/caja-window.h create mode 100644 src/caja-x-content-bar.c create mode 100644 src/caja-x-content-bar.h create mode 100644 src/caja-zoom-action.c create mode 100644 src/caja-zoom-action.h create mode 100644 src/caja-zoom-control.c create mode 100644 src/caja-zoom-control.h create mode 100755 src/check-caja create mode 100644 src/file-manager/Makefile.am create mode 100644 src/file-manager/caja-audio-mime-types.h create mode 100644 src/file-manager/caja-desktop-icon-view-ui.xml create mode 100644 src/file-manager/caja-directory-view-ui.xml create mode 100644 src/file-manager/caja-icon-view-ui.xml create mode 100644 src/file-manager/caja-list-view-ui.xml create mode 100644 src/file-manager/fm-actions.h create mode 100644 src/file-manager/fm-desktop-icon-view.c create mode 100644 src/file-manager/fm-desktop-icon-view.h create mode 100644 src/file-manager/fm-directory-view.c create mode 100644 src/file-manager/fm-directory-view.h create mode 100644 src/file-manager/fm-ditem-page.c create mode 100644 src/file-manager/fm-ditem-page.h create mode 100644 src/file-manager/fm-empty-view.c create mode 100644 src/file-manager/fm-empty-view.h create mode 100644 src/file-manager/fm-error-reporting.c create mode 100644 src/file-manager/fm-error-reporting.h create mode 100644 src/file-manager/fm-icon-container.c create mode 100644 src/file-manager/fm-icon-container.h create mode 100644 src/file-manager/fm-icon-view.c create mode 100644 src/file-manager/fm-icon-view.h create mode 100644 src/file-manager/fm-list-model.c create mode 100644 src/file-manager/fm-list-model.h create mode 100644 src/file-manager/fm-list-view-private.h create mode 100644 src/file-manager/fm-list-view.c create mode 100644 src/file-manager/fm-list-view.h create mode 100644 src/file-manager/fm-properties-window.c create mode 100644 src/file-manager/fm-properties-window.h create mode 100644 src/file-manager/fm-tree-model.c create mode 100644 src/file-manager/fm-tree-model.h create mode 100644 src/file-manager/fm-tree-view.c create mode 100644 src/file-manager/fm-tree-view.h create mode 100644 src/mate-network-scheme.desktop.in create mode 100644 test/Makefile.am create mode 100644 test/test-caja-directory-async.c create mode 100644 test/test-caja-search-engine.c create mode 100644 test/test-caja-wrap-table.c create mode 100644 test/test-copy.c create mode 100644 test/test-eel-background.c create mode 100644 test/test-eel-editable-label.c create mode 100644 test/test-eel-image-scrolled.c create mode 100644 test/test-eel-image-table.c create mode 100644 test/test-eel-labeled-image.c create mode 100644 test/test-eel-pixbuf-scale.c create mode 100644 test/test.c create mode 100644 test/test.h diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 00000000..65ae3e0d --- /dev/null +++ b/AUTHORS @@ -0,0 +1,60 @@ +Caja 2.22 version by: +Martin Wehner +Alex Larsson +Cosimo Cecchi +David Zeuthen + +Caja 2.4 version by: + +Alex Larsson +Dave Camp +Soren Sandmann +Jürg Billeter + +Caja 2.2 version by: + +Alex Larsson +Dave Camp +James Willcox +Jan Arne Petersen +Mark McLoughlin + +Mate 2 conversion by: + +Darin Adler +Anders Carlsson +Michael Meeks +Alex Larsson +Jacob Berkman +*** need to decide who else to add here *** + +Original version by the Caja 1.0 team: + +Ali Abdin +Andy Hertzfeld +Arlo Rose +Darin Adler +Eli Goldberg +Elliot Lee +Eskil Heyn Olsen +Ettore Perazzoli +Gene Z. Ragan +George Lebl +Ian McKellar +John Harper +John Sullivan +Josh Barrow +J Shane Culpepper +Maciej Stachowiak +Mathieu Lacage +Mike Engber +Mike Fleming +Pavel Cisler +Ramiro Estrugo +Raph Levien +Rebecca Schulman +Robey Pointer +Robin * Slomkowski +Seth Nickell +Susan Kare diff --git a/COPYING b/COPYING new file mode 100644 index 00000000..5838501c --- /dev/null +++ b/COPYING @@ -0,0 +1,351 @@ +********************************************************************** +The following license applies to the Caja software but does not +apply to the Eazel Trademarks. Please read the TRADEMARK_NOTICE file +for licensing information about the Eazel Trademarks. +********************************************************************** + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) 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 +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. 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. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the 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 a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE 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. + + 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 +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This 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 2 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, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision 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, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This 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 Library General +Public License instead of this License. diff --git a/COPYING-DOCS b/COPYING-DOCS new file mode 100644 index 00000000..b42936be --- /dev/null +++ b/COPYING-DOCS @@ -0,0 +1,355 @@ + GNU Free Documentation License + Version 1.1, March 2000 + + Copyright (C) 2000 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + +0. PREAMBLE + +The purpose of this License is to make a manual, textbook, or other +written document "free" in the sense of freedom: to assure everyone +the effective freedom to copy and redistribute it, with or without +modifying it, either commercially or noncommercially. Secondarily, +this License preserves for the author and publisher a way to get +credit for their work, while not being considered responsible for +modifications made by others. + +This License is a kind of "copyleft", which means that derivative +works of the document must themselves be free in the same sense. It +complements the GNU General Public License, which is a copyleft +license designed for free software. + +We have designed this License in order to use it for manuals for free +software, because free software needs free documentation: a free +program should come with manuals providing the same freedoms that the +software does. But this License is not limited to software manuals; +it can be used for any textual work, regardless of subject matter or +whether it is published as a printed book. We recommend this License +principally for works whose purpose is instruction or reference. + + +1. APPLICABILITY AND DEFINITIONS + +This License applies to any manual or other work that contains a +notice placed by the copyright holder saying it can be distributed +under the terms of this License. The "Document", below, refers to any +such manual or work. Any member of the public is a licensee, and is +addressed as "you". + +A "Modified Version" of the Document means any work containing the +Document or a portion of it, either copied verbatim, or with +modifications and/or translated into another language. + +A "Secondary Section" is a named appendix or a front-matter section of +the Document that deals exclusively with the relationship of the +publishers or authors of the Document to the Document's overall subject +(or to related matters) and contains nothing that could fall directly +within that overall subject. (For example, if the Document is in part a +textbook of mathematics, a Secondary Section may not explain any +mathematics.) The relationship could be a matter of historical +connection with the subject or with related matters, or of legal, +commercial, philosophical, ethical or political position regarding +them. + +The "Invariant Sections" are certain Secondary Sections whose titles +are designated, as being those of Invariant Sections, in the notice +that says that the Document is released under this License. + +The "Cover Texts" are certain short passages of text that are listed, +as Front-Cover Texts or Back-Cover Texts, in the notice that says that +the Document is released under this License. + +A "Transparent" copy of the Document means a machine-readable copy, +represented in a format whose specification is available to the +general public, whose contents can be viewed and edited directly and +straightforwardly with generic text editors or (for images composed of +pixels) generic paint programs or (for drawings) some widely available +drawing editor, and that is suitable for input to text formatters or +for automatic translation to a variety of formats suitable for input +to text formatters. A copy made in an otherwise Transparent file +format whose markup has been designed to thwart or discourage +subsequent modification by readers is not Transparent. A copy that is +not "Transparent" is called "Opaque". + +Examples of suitable formats for Transparent copies include plain +ASCII without markup, Texinfo input format, LaTeX input format, SGML +or XML using a publicly available DTD, and standard-conforming simple +HTML designed for human modification. Opaque formats include +PostScript, PDF, proprietary formats that can be read and edited only +by proprietary word processors, SGML or XML for which the DTD and/or +processing tools are not generally available, and the +machine-generated HTML produced by some word processors for output +purposes only. + +The "Title Page" means, for a printed book, the title page itself, +plus such following pages as are needed to hold, legibly, the material +this License requires to appear in the title page. For works in +formats which do not have any title page as such, "Title Page" means +the text near the most prominent appearance of the work's title, +preceding the beginning of the body of the text. + + +2. VERBATIM COPYING + +You may copy and distribute the Document in any medium, either +commercially or noncommercially, provided that this License, the +copyright notices, and the license notice saying this License applies +to the Document are reproduced in all copies, and that you add no other +conditions whatsoever to those of this License. You may not use +technical measures to obstruct or control the reading or further +copying of the copies you make or distribute. However, you may accept +compensation in exchange for copies. If you distribute a large enough +number of copies you must also follow the conditions in section 3. + +You may also lend copies, under the same conditions stated above, and +you may publicly display copies. + + +3. COPYING IN QUANTITY + +If you publish printed copies of the Document numbering more than 100, +and the Document's license notice requires Cover Texts, you must enclose +the copies in covers that carry, clearly and legibly, all these Cover +Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on +the back cover. Both covers must also clearly and legibly identify +you as the publisher of these copies. The front cover must present +the full title with all words of the title equally prominent and +visible. You may add other material on the covers in addition. +Copying with changes limited to the covers, as long as they preserve +the title of the Document and satisfy these conditions, can be treated +as verbatim copying in other respects. + +If the required texts for either cover are too voluminous to fit +legibly, you should put the first ones listed (as many as fit +reasonably) on the actual cover, and continue the rest onto adjacent +pages. + +If you publish or distribute Opaque copies of the Document numbering +more than 100, you must either include a machine-readable Transparent +copy along with each Opaque copy, or state in or with each Opaque copy +a publicly-accessible computer-network location containing a complete +Transparent copy of the Document, free of added material, which the +general network-using public has access to download anonymously at no +charge using public-standard network protocols. If you use the latter +option, you must take reasonably prudent steps, when you begin +distribution of Opaque copies in quantity, to ensure that this +Transparent copy will remain thus accessible at the stated location +until at least one year after the last time you distribute an Opaque +copy (directly or through your agents or retailers) of that edition to +the public. + +It is requested, but not required, that you contact the authors of the +Document well before redistributing any large number of copies, to give +them a chance to provide you with an updated version of the Document. + + +4. MODIFICATIONS + +You may copy and distribute a Modified Version of the Document under +the conditions of sections 2 and 3 above, provided that you release +the Modified Version under precisely this License, with the Modified +Version filling the role of the Document, thus licensing distribution +and modification of the Modified Version to whoever possesses a copy +of it. In addition, you must do these things in the Modified Version: + +A. Use in the Title Page (and on the covers, if any) a title distinct + from that of the Document, and from those of previous versions + (which should, if there were any, be listed in the History section + of the Document). You may use the same title as a previous version + if the original publisher of that version gives permission. +B. List on the Title Page, as authors, one or more persons or entities + responsible for authorship of the modifications in the Modified + Version, together with at least five of the principal authors of the + Document (all of its principal authors, if it has less than five). +C. State on the Title page the name of the publisher of the + Modified Version, as the publisher. +D. Preserve all the copyright notices of the Document. +E. Add an appropriate copyright notice for your modifications + adjacent to the other copyright notices. +F. Include, immediately after the copyright notices, a license notice + giving the public permission to use the Modified Version under the + terms of this License, in the form shown in the Addendum below. +G. Preserve in that license notice the full lists of Invariant Sections + and required Cover Texts given in the Document's license notice. +H. Include an unaltered copy of this License. +I. Preserve the section entitled "History", and its title, and add to + it an item stating at least the title, year, new authors, and + publisher of the Modified Version as given on the Title Page. If + there is no section entitled "History" in the Document, create one + stating the title, year, authors, and publisher of the Document as + given on its Title Page, then add an item describing the Modified + Version as stated in the previous sentence. +J. Preserve the network location, if any, given in the Document for + public access to a Transparent copy of the Document, and likewise + the network locations given in the Document for previous versions + it was based on. These may be placed in the "History" section. + You may omit a network location for a work that was published at + least four years before the Document itself, or if the original + publisher of the version it refers to gives permission. +K. In any section entitled "Acknowledgements" or "Dedications", + preserve the section's title, and preserve in the section all the + substance and tone of each of the contributor acknowledgements + and/or dedications given therein. +L. Preserve all the Invariant Sections of the Document, + unaltered in their text and in their titles. Section numbers + or the equivalent are not considered part of the section titles. +M. Delete any section entitled "Endorsements". Such a section + may not be included in the Modified Version. +N. Do not retitle any existing section as "Endorsements" + or to conflict in title with any Invariant Section. + +If the Modified Version includes new front-matter sections or +appendices that qualify as Secondary Sections and contain no material +copied from the Document, you may at your option designate some or all +of these sections as invariant. To do this, add their titles to the +list of Invariant Sections in the Modified Version's license notice. +These titles must be distinct from any other section titles. + +You may add a section entitled "Endorsements", provided it contains +nothing but endorsements of your Modified Version by various +parties--for example, statements of peer review or that the text has +been approved by an organization as the authoritative definition of a +standard. + +You may add a passage of up to five words as a Front-Cover Text, and a +passage of up to 25 words as a Back-Cover Text, to the end of the list +of Cover Texts in the Modified Version. Only one passage of +Front-Cover Text and one of Back-Cover Text may be added by (or +through arrangements made by) any one entity. If the Document already +includes a cover text for the same cover, previously added by you or +by arrangement made by the same entity you are acting on behalf of, +you may not add another; but you may replace the old one, on explicit +permission from the previous publisher that added the old one. + +The author(s) and publisher(s) of the Document do not by this License +give permission to use their names for publicity for or to assert or +imply endorsement of any Modified Version. + + +5. COMBINING DOCUMENTS + +You may combine the Document with other documents released under this +License, under the terms defined in section 4 above for modified +versions, provided that you include in the combination all of the +Invariant Sections of all of the original documents, unmodified, and +list them all as Invariant Sections of your combined work in its +license notice. + +The combined work need only contain one copy of this License, and +multiple identical Invariant Sections may be replaced with a single +copy. If there are multiple Invariant Sections with the same name but +different contents, make the title of each such section unique by +adding at the end of it, in parentheses, the name of the original +author or publisher of that section if known, or else a unique number. +Make the same adjustment to the section titles in the list of +Invariant Sections in the license notice of the combined work. + +In the combination, you must combine any sections entitled "History" +in the various original documents, forming one section entitled +"History"; likewise combine any sections entitled "Acknowledgements", +and any sections entitled "Dedications". You must delete all sections +entitled "Endorsements." + + +6. COLLECTIONS OF DOCUMENTS + +You may make a collection consisting of the Document and other documents +released under this License, and replace the individual copies of this +License in the various documents with a single copy that is included in +the collection, provided that you follow the rules of this License for +verbatim copying of each of the documents in all other respects. + +You may extract a single document from such a collection, and distribute +it individually under this License, provided you insert a copy of this +License into the extracted document, and follow this License in all +other respects regarding verbatim copying of that document. + + +7. AGGREGATION WITH INDEPENDENT WORKS + +A compilation of the Document or its derivatives with other separate +and independent documents or works, in or on a volume of a storage or +distribution medium, does not as a whole count as a Modified Version +of the Document, provided no compilation copyright is claimed for the +compilation. Such a compilation is called an "aggregate", and this +License does not apply to the other self-contained works thus compiled +with the Document, on account of their being thus compiled, if they +are not themselves derivative works of the Document. + +If the Cover Text requirement of section 3 is applicable to these +copies of the Document, then if the Document is less than one quarter +of the entire aggregate, the Document's Cover Texts may be placed on +covers that surround only the Document within the aggregate. +Otherwise they must appear on covers around the whole aggregate. + + +8. TRANSLATION + +Translation is considered a kind of modification, so you may +distribute translations of the Document under the terms of section 4. +Replacing Invariant Sections with translations requires special +permission from their copyright holders, but you may include +translations of some or all Invariant Sections in addition to the +original versions of these Invariant Sections. You may include a +translation of this License provided that you also include the +original English version of this License. In case of a disagreement +between the translation and the original English version of this +License, the original English version will prevail. + + +9. TERMINATION + +You may not copy, modify, sublicense, or distribute the Document except +as expressly provided for under this License. Any other attempt to +copy, modify, sublicense or distribute the Document is void, and will +automatically terminate your rights under this License. However, +parties who have received copies, or rights, from you under this +License will not have their licenses terminated so long as such +parties remain in full compliance. + + +10. FUTURE REVISIONS OF THIS LICENSE + +The Free Software Foundation may publish new, revised versions +of the GNU Free Documentation 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. See +http://www.gnu.org/copyleft/. + +Each version of the License is given a distinguishing version number. +If the Document specifies that a particular numbered version of this +License "or any later version" applies to it, you have the option of +following the terms and conditions either of that specified version or +of any later version that has been published (not as a draft) by the +Free Software Foundation. If the Document does not specify a version +number of this License, you may choose any version ever published (not +as a draft) by the Free Software Foundation. + + +ADDENDUM: How to use this License for your documents + +To use this License in a document you have written, include a copy of +the License in the document and put the following copyright and +license notices just after the title page: + + Copyright (c) YEAR YOUR NAME. + Permission is granted to copy, distribute and/or modify this document + under the terms of the GNU Free Documentation License, Version 1.1 + or any later version published by the Free Software Foundation; + with the Invariant Sections being LIST THEIR TITLES, with the + Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST. + A copy of the license is included in the section entitled "GNU + Free Documentation License". + +If you have no Invariant Sections, write "with no Invariant Sections" +instead of saying which ones are invariant. If you have no +Front-Cover Texts, write "no Front-Cover Texts" instead of +"Front-Cover Texts being LIST"; likewise for Back-Cover Texts. + +If your document contains nontrivial examples of program code, we +recommend releasing these examples in parallel under your choice of +free software license, such as the GNU General Public License, +to permit their use in free software. diff --git a/COPYING.EXTENSIONS b/COPYING.EXTENSIONS new file mode 100644 index 00000000..d4ba7d8a --- /dev/null +++ b/COPYING.EXTENSIONS @@ -0,0 +1,10 @@ +Caja extensions link against the libcaja-extenstions library which is +is under the LGPL license. However, they also get loaded into the main +caja program which is licensed under the GPL. So, extensions should not +be incompatible with the LGPL or GPL. + +Some extensions are GPL but use some IPC mechanism like dbus to talk to a +potentially non-GPL application. This is actually not such a bad design in +general if your extension is doing a lot of work, as running as a caja +extension with all its issues (no synchronous i/o, can't control of the +context your code runs in, etc) can be kind of a pain. diff --git a/COPYING.LIB b/COPYING.LIB new file mode 100644 index 00000000..161a3d1d --- /dev/null +++ b/COPYING.LIB @@ -0,0 +1,482 @@ + GNU LIBRARY GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1991 Free Software Foundation, Inc. + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the library GPL. It is + numbered 2 because it goes with version 2 of the ordinary GPL.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Library General Public License, applies to some +specially designated Free Software Foundation software, and to any +other libraries whose authors decide to use it. You can use it for +your libraries, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if +you distribute copies of the library, or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link a program with the library, you must provide +complete object files to the recipients so that they can relink them +with the library, after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + Our method of protecting your rights has two steps: (1) copyright +the library, and (2) offer you this license which gives you legal +permission to copy, distribute and/or modify the library. + + Also, for each distributor's protection, we want to make certain +that everyone understands that there is no warranty for this free +library. If the library is modified by someone else and passed on, we +want its recipients to know that what they have is not the original +version, so that any problems introduced by others will not reflect on +the original authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that companies distributing free +software will individually obtain patent licenses, thus in effect +transforming the program into proprietary software. To prevent this, +we have made it clear that any patent must be licensed for everyone's +free use or not licensed at all. + + Most GNU software, including some libraries, is covered by the ordinary +GNU General Public License, which was designed for utility programs. This +license, the GNU Library General Public License, applies to certain +designated libraries. This license is quite different from the ordinary +one; be sure to read it in full, and don't assume that anything in it is +the same as in the ordinary license. + + The reason we have a separate public license for some libraries is that +they blur the distinction we usually make between modifying or adding to a +program and simply using it. Linking a program with a library, without +changing the library, is in some sense simply using the library, and is +analogous to running a utility program or application program. However, in +a textual and legal sense, the linked executable is a combined work, a +derivative of the original library, and the ordinary General Public License +treats it as such. + + Because of this blurred distinction, using the ordinary General +Public License for libraries did not effectively promote software +sharing, because most developers did not use the libraries. We +concluded that weaker conditions might promote sharing better. + + However, unrestricted linking of non-free programs would deprive the +users of those programs of all benefit from the free status of the +libraries themselves. This Library General Public License is intended to +permit developers of non-free programs to use free libraries, while +preserving your freedom as a user of such programs to change the free +libraries that are incorporated in them. (We have not seen how to achieve +this as regards changes in header files, but we have achieved it as regards +changes in the actual functions of the Library.) The hope is that this +will lead to faster development of free libraries. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, while the latter only +works together with the library. + + Note that it is possible for a library to be covered by the ordinary +General Public License rather than by this special one. + + GNU LIBRARY GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library which +contains a notice placed by the copyright holder or other authorized +party saying it may be distributed under the terms of this Library +General Public License (also called "this License"). Each licensee is +addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also compile or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + c) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + d) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the source code distributed need not include anything that is normally +distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Library General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 00000000..e69de29b diff --git a/HACKING b/HACKING new file mode 100644 index 00000000..734ac49a --- /dev/null +++ b/HACKING @@ -0,0 +1,57 @@ +Hacking on Caja +------------------- + +The Caja source tree is available from MATE git (git.gnome.org) and +in releases on the MATE FTP site +(http://ftp.gnome.org/pub/MATE/sources/caja/). + +If you plan to hack on Caja, please make sure you work from the +Git version. The Git version can be checked from the MATE git server. +See http://live.gnome.org/Git for details on how to get started with +MATE Git. For details on how Caja uses git, see the README.commits +file. + +If you want to contribute in development discussions, please send mail +to the caja mailing list: . Archives and +subscription information are available at +http://mail.gnome.org/mailman/listinfo/caja-list + + +Submitting Patches +------------------ + +If you've been working on a change to Caja and want to propose it +for inclusion, you have to generate a patch and submit it for review +by the maintainers. + +Patches should be made with 'git format-patch -M' +and should conform to Caja coding style as described in +docs/style-guide.html. We are pretty strict about coding style, so +please make sure you follow the style guide to avoid unnecessary +work on both sides when reviewing the patch. + +The best way to submit a patch for review is to post it on the mailing +list. That way everyone sees it and can take part in the following +discussion about it. Sometimes people also attach patches to bugs in +bugzilla (http://bugzilla.gnome.org, product 'caja'). If you do +this, please send a mail to the list saying you did so, because it is +very easy for the bugzilla email to get lost in all the bugzilla +reports, and only the people CCd on the bug can partake in the +discussion. When attaching bugs to bugzilla from git the git-bz +command can be helpful, see: +http://blog.fishsoup.net/2008/11/16/git-bz-bugzilla-subcommand-for-git/ + +The Caja maintainers do their best to review patches and help +developers that want to work on something, however we are often +swamped in work and can miss an email or just forget to answer +it. Don't be afraid of reposting your patches after a while, or poking +us about the status of them. + +Also, if you're planning to do large changes, please take them up for +discussion on the list first. If you get feedback early it is much +easier to integrate it into your work. + +If your patch adds non-trivial strings, please ask for a string review +from the i18n team before committing the changes. Strings should avoid +contractions, and stay consistent with other strings already in Caja. +Please reuse strings within Caja where it makes sense to do so. diff --git a/INSTALL b/INSTALL new file mode 100644 index 00000000..7d1c323b --- /dev/null +++ b/INSTALL @@ -0,0 +1,365 @@ +Installation Instructions +************************* + +Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, +2006, 2007, 2008, 2009 Free Software Foundation, Inc. + + Copying and distribution of this file, with or without modification, +are permitted in any medium without royalty provided the copyright +notice and this notice are preserved. This file is offered as-is, +without warranty of any kind. + +Basic Installation +================== + + Briefly, the shell commands `./configure; make; make install' should +configure, build, and install this package. The following +more-detailed instructions are generic; see the `README' file for +instructions specific to this package. Some packages provide this +`INSTALL' file but do not implement all of the features documented +below. The lack of an optional feature in a given package is not +necessarily a bug. More recommendations for GNU packages can be found +in *note Makefile Conventions: (standards)Makefile Conventions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, and a +file `config.log' containing compiler output (useful mainly for +debugging `configure'). + + It can also use an optional file (typically called `config.cache' +and enabled with `--cache-file=config.cache' or simply `-C') that saves +the results of its tests to speed up reconfiguring. Caching is +disabled by default to prevent problems with accidental use of stale +cache files. + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If you are using the cache, and at +some point `config.cache' contains results you don't want to keep, you +may remove or edit it. + + The file `configure.ac' (or `configure.in') is used to create +`configure' by a program called `autoconf'. You need `configure.ac' if +you want to change it or regenerate `configure' using a newer version +of `autoconf'. + + The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. + + Running `configure' might take a while. While running, it prints + some messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package, generally using the just-built uninstalled binaries. + + 4. Type `make install' to install the programs and any data files and + documentation. When installing into a prefix owned by root, it is + recommended that the package be configured and built as a regular + user, and only the `make install' phase executed with root + privileges. + + 5. Optionally, type `make installcheck' to repeat any self-tests, but + this time using the binaries in their final installed location. + This target does not install anything. Running this target as a + regular user, particularly if the prior `make install' required + root privileges, verifies that the installation completed + correctly. + + 6. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + + 7. Often, you can also type `make uninstall' to remove the installed + files again. In practice, not all packages have tested that + uninstallation works correctly, even though it is required by the + GNU Coding Standards. + + 8. Some packages, particularly those that use Automake, provide `make + distcheck', which can by used by developers to test that all other + targets like `make install' and `make uninstall' work correctly. + This target is generally not run by end users. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. Run `./configure --help' +for details on some of the pertinent environment variables. + + You can give `configure' initial values for configuration parameters +by setting variables in the command line or in the environment. Here +is an example: + + ./configure CC=c99 CFLAGS=-g LIBS=-lposix + + *Note Defining Variables::, for more details. + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you can use GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. This +is known as a "VPATH" build. + + With a non-GNU `make', it is safer to compile the package for one +architecture at a time in the source code directory. After you have +installed the package for one architecture, use `make distclean' before +reconfiguring for another architecture. + + On MacOS X 10.5 and later systems, you can create libraries and +executables that work on multiple system types--known as "fat" or +"universal" binaries--by specifying multiple `-arch' options to the +compiler but only a single `-arch' option to the preprocessor. Like +this: + + ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ + CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ + CPP="gcc -E" CXXCPP="g++ -E" + + This is not guaranteed to produce working output in all cases, you +may have to build one architecture at a time and combine the results +using the `lipo' tool if you have problems. + +Installation Names +================== + + By default, `make install' installs the package's commands under +`/usr/local/bin', include files under `/usr/local/include', etc. You +can specify an installation prefix other than `/usr/local' by giving +`configure' the option `--prefix=PREFIX', where PREFIX must be an +absolute file name. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +pass the option `--exec-prefix=PREFIX' to `configure', the package uses +PREFIX as the prefix for installing programs and libraries. +Documentation and other data files still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=DIR' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. In general, the +default for these options is expressed in terms of `${prefix}', so that +specifying just `--prefix' will affect all of the other directory +specifications that were not explicitly provided. + + The most portable way to affect installation locations is to pass the +correct locations to `configure'; however, many packages provide one or +both of the following shortcuts of passing variable assignments to the +`make install' command line to change installation locations without +having to reconfigure or recompile. + + The first method involves providing an override variable for each +affected directory. For example, `make install +prefix=/alternate/directory' will choose an alternate location for all +directory configuration variables that were expressed in terms of +`${prefix}'. Any directories that were specified during `configure', +but not in terms of `${prefix}', must each be overridden at install +time for the entire installation to be relocated. The approach of +makefile variable overrides for each directory variable is required by +the GNU Coding Standards, and ideally causes no recompilation. +However, some platforms have known limitations with the semantics of +shared libraries that end up requiring recompilation when using this +method, particularly noticeable in packages that use GNU Libtool. + + The second method involves providing the `DESTDIR' variable. For +example, `make install DESTDIR=/alternate/directory' will prepend +`/alternate/directory' before all installation names. The approach of +`DESTDIR' overrides is not required by the GNU Coding Standards, and +does not work on platforms that have drive letters. On the other hand, +it does better at avoiding recompilation issues, and works well even +when some directory options were not specified in terms of `${prefix}' +at `configure' time. + +Optional Features +================= + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + + Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + + Some packages offer the ability to configure how verbose the +execution of `make' will be. For these packages, running `./configure +--enable-silent-rules' sets the default to minimal output, which can be +overridden with `make V=1'; while running `./configure +--disable-silent-rules' sets the default to verbose, which can be +overridden with `make V=0'. + +Particular systems +================== + + On HP-UX, the default C compiler is not ANSI C compatible. If GNU +CC is not installed, it is recommended to use the following options in +order to use an ANSI C compiler: + + ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" + +and if that doesn't work, install pre-built binaries of GCC for HP-UX. + + On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot +parse its `' header file. The option `-nodtk' can be used as +a workaround. If GNU CC is not installed, it is therefore recommended +to try + + ./configure CC="cc" + +and if that doesn't work, try + + ./configure CC="cc -nodtk" + + On Solaris, don't put `/usr/ucb' early in your `PATH'. This +directory contains several dysfunctional programs; working variants of +these programs are available in `/usr/bin'. So, if you need `/usr/ucb' +in your `PATH', put it _after_ `/usr/bin'. + + On Haiku, software installed for all users goes in `/boot/common', +not `/usr/local'. It is recommended to use the following options: + + ./configure --prefix=/boot/common + +Specifying the System Type +========================== + + There may be some features `configure' cannot figure out +automatically, but needs to determine by the type of machine the package +will run on. Usually, assuming the package is built to be run on the +_same_ architectures, `configure' can figure that out, but if it prints +a message saying it cannot guess the machine type, give it the +`--build=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name which has the form: + + CPU-COMPANY-SYSTEM + +where SYSTEM can have one of these forms: + + OS + KERNEL-OS + + See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the machine type. + + If you are _building_ compiler tools for cross-compiling, you should +use the option `--target=TYPE' to select the type of system they will +produce code for. + + If you want to _use_ a cross compiler, that generates code for a +platform different from the build platform, you should specify the +"host" platform (i.e., that on which the generated programs will +eventually be run) with `--host=TYPE'. + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Defining Variables +================== + + Variables not defined in a site shell script can be set in the +environment passed to `configure'. However, some packages may run +configure again during the build, and the customized values of these +variables may be lost. In order to avoid this problem, you should set +them in the `configure' command line, using `VAR=value'. For example: + + ./configure CC=/usr/local2/bin/gcc + +causes the specified `gcc' to be used as the C compiler (unless it is +overridden in the site shell script). + +Unfortunately, this technique does not work for `CONFIG_SHELL' due to +an Autoconf bug. Until the bug is fixed you can use this workaround: + + CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash + +`configure' Invocation +====================== + + `configure' recognizes the following options to control how it +operates. + +`--help' +`-h' + Print a summary of all of the options to `configure', and exit. + +`--help=short' +`--help=recursive' + Print a summary of the options unique to this package's + `configure', and exit. The `short' variant lists options used + only in the top level, while the `recursive' variant lists options + also present in any nested packages. + +`--version' +`-V' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`--cache-file=FILE' + Enable the cache: use and save the results of the tests in FILE, + traditionally `config.cache'. FILE defaults to `/dev/null' to + disable caching. + +`--config-cache' +`-C' + Alias for `--cache-file=config.cache'. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`--prefix=DIR' + Use DIR as the installation prefix. *note Installation Names:: + for more details, including other options available for fine-tuning + the installation locations. + +`--no-create' +`-n' + Run the configure checks, but stop before creating any output + files. + +`configure' also accepts some other, not widely useful, options. Run +`configure --help' for more details. + diff --git a/MAINTAINERS b/MAINTAINERS new file mode 100644 index 00000000..a628ebec --- /dev/null +++ b/MAINTAINERS @@ -0,0 +1,23 @@ +Alex Larsson +E-mail: alexl@redhat.com +Userid: alexl + +Dave Camp +E-mail: dave@novell.com +Userid: campd + +Martin Wehner +E-mail: martin.wehner@gmail.com +Userid: mwehner + +Christian Neumair +E-mail: cneumair@gnome.org +Userid: cneumair + +Andrew Walton +E-mail: awalton@gnome.org +Userid: awalton + +Cosimo Cecchi +E-mail: cosimoc@gnome.org +Userid: cosimoc diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 00000000..67339feb --- /dev/null +++ b/Makefile.am @@ -0,0 +1,44 @@ +include $(top_srcdir)/Makefile.shared + +SUBDIRS = \ + eel \ + libcaja-extension \ + cut-n-paste-code \ + libcaja-private \ + src \ + test \ + po \ + data \ + icons \ + docs \ + $(NULL) + +EXTRA_DIST= \ + COPYING.LIB \ + COPYING.EXTENSIONS \ + COPYING-DOCS \ + HACKING \ + MAINTAINERS \ + README.commits \ + intltool-extract.in \ + intltool-merge.in \ + intltool-update.in \ + Makefile.shared \ + add-include-prefix \ + $(NULL) + +DISTCLEANFILES = \ + intltool-extract \ + intltool-merge \ + intltool-update + +DISTCHECK_CONFIGURE_FLAGS = --disable-update-mimedb --enable-gtk-doc + +ACLOCAL_AMFLAGS = -I m4 + +distclean-local: + if test "$(srcdir)" = "."; then :; else \ + rm -f ChangeLog; \ + fi + +.PHONY: ChangeLog diff --git a/Makefile.shared b/Makefile.shared new file mode 100644 index 00000000..86f0b1c0 --- /dev/null +++ b/Makefile.shared @@ -0,0 +1 @@ +NULL = diff --git a/NEWS b/NEWS new file mode 100644 index 00000000..31444339 --- /dev/null +++ b/NEWS @@ -0,0 +1,1713 @@ +Major changes in 2.32.0 are: +* Fix places sidebar sometimes not changing location + when clicking on a place +* Fix various crashers +* Translation updates + +Major changes in 2.31.92 are: +* String fixes for the file conflict dialog +* Add a border around infobars +* Fix a regression when copy/pasting in list view +* Re-use libunique instead of GApplication +* Drop GDK_DISABLE_DEPRECATED cflag, as we don't want to cope with + recent GDK 2.22 deprecations for the 2.32 branch + +Major changes in 2.31.90 are: +* Don't make pathbar buttons disappear when deleting a folder +* Remove useless unique-1.0 dependency +* Don't use deprecated GtkNotebookPage +* Translation updates + +Major changes in 2.31.6 are: +* This release is based on 2.30.1 +* A long list of fixes have been backported from the master branch, + including: + * Expand and collapse folders with +/- in list view + * Rename .desktop files also change their name on disk + * Support overriding .mate2 directory + * Save passwords for the session by default + * Remove deleted folders from the pathbar + * Replace libunique with GApplication + * Don't show 'File Browser' anymore in the window title + * Port to GDBus + * Change the default order for files in special directories + * Support relative paths in the location entry/dialog. + * Use folder icons as window icons in browser and spatial mode + * Add 'Trashed On' and 'Original Location' columns in the trash + * Implement transparent icons for cut files + * Change default thumbnail size + * Fix a number of bugs related to bookmarks + * New dialog to handle conflicts within file copy/move operations + * New button in the trashbar to restore selected items + * Use async I/O to save .gtk-bookmarks + * Fix a number of issues related to DnD in the places sidebar + * New icon for audio preview + * Don't show Unmount when showing Eject/Safe Removal + * Bump libcaja-extension API version + * Fix a number of UI glitches +* Translation updates + +Major changes in 2.30.1 are: +* Translation updates +* Support for tracker 0.8.0 +* Fix crashes +* Fix emblem scaling in zoomed view +* Fix sensitivity of split-view related menu items +* Control-L closes the extra view first, not the window + +Major changes in 2.30.0 are: +* By default, don't exit with last window even if desktop is + not visible. This way we still run to handle e.g. volume + monitoring. If you don't want this, change + /apps/caja/preferences/exit_with_last_window + to True in mateconf +* Don't show weird border around desktop +* Correctly put focus on view for new windows +* Extra view does not get focus when created +* Add nicer thumbnail border +* Fix crash when hiding search bar +* Fix build on sun compiler +* Support AIFF for audio preview +* Translation updates + +Major changes in 2.29.92.1 are: +* Fix compilation due to deprecated GTK_WIDGET_STATE symbol +* Fix libm linking +* Updated Portuguese translation + +Major changes in 2.29.92 are: +* Make view default focus in new windows +* Put tabs at the top again +* Don't use deprecated gtk widgets +* Allow Alt- to switch tabs +* Dynamically load tracker support +* Don't auto-close the window you initiated an unmount in + +Major changes in 2.29.91 are: +* Make it possible to have backgrounds spanning multiple monitors. +* Better handling of closing windows when device is unmounted +* Use GtkSpinner instead of custom widget +* Translation updates + +Major changes in 2.29.90 are: +* Fix copy-pasted tooltip string +* Translation updates + +Major changes in 2.29.2 are: +* Align sidebar header and location bar +* Remove tabs menu +* Update translations + +Major changes in 2.29.1 are: +* Make browser mode the default +* Add split view mode +* Browser UI reorganization +* Better background support on multi-monitor setups +* Support new "default location" on mounts (supported by ftp and sftp) +* Add extension api to lookup CajaFileInfo objects +* Make the search toolbar button a toggle button +* Ctrl+shift does multiple range selection in list view + +Major changes in 2.28.0 are: +* Translation updates +* Don't load non-images for thumbnailing when zoomed +* Made desktop window a native X window for nicer redrawing +* Fix leaks + +Major changes in 2.27.92 are: +* Fix crash on logout +* Translation updates +* Always show app icon in open with popup menu +* fix duplicate id in ui file +* Fix warning in new power manager inhibiting + +Major changes in 2.27.91 are: +* Migrate old-style caja metadata to gvfs metadata +* Fix viewing of very small image files +* Respect disable_command_line option +* Reverse mouse button used for back/forward to same as firefox +* Always show menu icons for menu items representing files +* Inhibit suspend during file operations +* Cancel audio preview when deleting the previewed file + +Major changes in 2.27.4 are: +* Add support for starting and stopping drives +* Use the new GVfs metadata framework +* Support new style unmount operations; this will provide a nice dialog when + unmounting a busy drive mount +* Add application icons to the Open With context menu +* Reload xdg-user-dirs according to the user preferences + +Major changes in 2.27.2 are: +* Support ctrl-drop in list view +* Allow user defined keyboard shortcuts for extension items +* Fix crash on click on toolbar +* Fix crash on entering empty location +* Added daemon-mode (don't exit with last window) +* Display info about the selected item in the information sidebar +* Sort applications in open with + +Major changes in 2.27.1 are: +* Drop GTK+ deprecated symbols +* Display the application icon in the popup menu +* Fix autorun hints for Win32 software media +* Allow shift+return during typeahead find +* Update desktop icons according to DPI changes +* Use the correct folder icon fallbacks +* Autogenerate ChangeLog and use shave to display the build output + +Major changes in 2.26.2 are: +* Fix issue with default dnd type when dragging to a parent directory +* Fix icon view RTL layout in compact view +* Make sure spatial geometry is always saved when closing windows +* Save and load custom accelerator maps +* Check for PackageKit before showing dialog using it +* Add "location" column +* Show both unmount and eject in menus for mounts that support both + +Major changes in 2.26.1 are: +* Better handling of thumbnail scaling +* Support XDS in list view +* Make session loading work +* Start Caja on requested screen +* Fix crashes +* Fix possible infinite layout loop in compact mode +* Update fallback icon to not look like mate 1.x +* Fix some cases of sync i/o +* Handle non-gvfs uris like e.g. mailto and http links with queries in links + +Major changes in 2.26.0 are: +* Stable release +* Fix crash due to broken gdk-pixbuf tga loader +* make sure thumbnails are updated even when zoomed up +* fix crash in media settings preferences + +Major changes in 2.25.93 are: +* Use ConsoleKit to make sure we only autorun on active sessions +* Never show unmount if we show an eject menu item +* Show the gvfs reported owner/group names +* Don't allow changing default app for folders +* Fix "can't unmount same location twice" bug + +Major changes in 2.25.92 are: +* Set mmap limit to avoid desktop background memory not being returned to the os +* Warn when source overwrites destination in move +* Don't put "link to ..." in front of symlinks unless there are name conflicts +* Fix desktop flicker on theme change +* Require desktop file app launchers to be executable +* Support making symlinks on remote locations (if supported by backend) + +Major changes in 2.25.91 are: +* Use G_DEFINE_TYPE_* instead of hand-written types +* fix: opening a new window restores minimised ones +* fix renaming of desktop files +* Handle new kinds of GIcons +* Don't display shadowed mounts + +Major changes in 2.25.4 are: +* Don't show desktop files from other desktops than Mate on the desktop +* Support crossfades of desktop backgrounds +* Don't snap desktop icons outside right margin +* Fix crashes and leaks + +Major changes in 2.25.3 are: +* Remove CD/DVD creator from places menu and sidebar +* Allow deleting custom emblems +* Fix crashes +* Don't show read-only emblems in trash +* Trash performance fixes +* General performance fixes +* Update to new PackageKit API + +Major changes in 2.25.2 are: +* Merged eel into caja +* Use single glib/gtk includes +* Support PackageKit application search +* Fix new windows not appearing after successful mount +* Remove support for old KDE trash dirs + +Major changes in 2.25.1 are: +* Remove depencency on libmate & mate-vfs +* Fix crashes +* Chop trailing space characters when moving to FAT file system +* When DnD'ing, COPY instead of MOVE, when the source is not deletable +* Don't set default when opening with other app, just add to open with list. +* Don't make copies of files from readonly source (e.g. CDROM) readonly +* Don't show cancel dialog when showing the "run or display" dialog + +Major changes in 2.24.0 are: +* Icon/compact view: + * Follow run-time changes to set of icon text attributes to be displayed + * Invalidate icon label when changing zoom level or “text besides icon” +* List view: + * Properly offer textual drag target +* Request centered autorun dialog +* Always sort folders before files, even if sort criterion is reversed +* Always assume that trash directories are local +* Fix Small leaks and thinkos + +Major changes in 2.23.92 are: +* Icon/compact view: + * Allow to select range in addition to current selection, when pressing ctrl + and shift at once [not yet doable in list view] + * Fix layout timestamp storage when moving items around on desktop +* List view: + Default to reverse sort order for date columns (i.e. recent to old) +* Improve “Clear History” confirmation dialog +* Use GdkAppLaunchContext instead of EelAppLaunchContext +* Fix small leaks + +Major changes in 2.23.91 are: +* Make autorun work for blank media +* No more pixelated SVGs displayed for desktop items with absolute icon SVG paths +* Use consistent labels, mnemonics and icons for trash and delete actions +* Icon container (i.e. icon view and compact view) + * RTL support for vertical layout + * Always reveal entire rows or columns of icons + * Nicer icon container bounds + * (Again) vastly improved keyboard navigation, especially in RTL mode + * No more overlapping desktop icons, when files are added or volumes mounted + while Caja is not running. This is implemented with metadata timestamps when + the desktop icons are laid out. + * Rewrite large chunks of icon canvas text size handling + * Clear underlying items if hovered or selected item overlaps them +* List View + * Make scripts work when items in nested list view subdirectories are selected +* Usual minor fix & polish galore + +Major changes in 2.23.90 are: +* Truncate long item labels in the icon view and on the desktop + + icon_view/text_ellipsis_limit and desktop/text_ellipsis_limit MateConf + preferences added (defaults to three lines) + + expand when hovering, or when selecting a file +* Support restoring of multiple items from trash at once +* Handle scroll events on the path bar +* Fix “same file system” (i.e. copy vs. move) DND check for desktop +* Fix search for content type in simple search backend +* Fix running of scripts on the desktop +* Use more archive file types for file-roller integration for remote locations +* Consolidate zoom handling internals +* Show file name instead of URI in the bookmark editor window for local files +* Polish “Visible Columns“ list view dialog + +Major changes in 2.23.6.1 are: +* Fix display name of computer:// icons + +Major changes in 2.23.6 are: +* Support transferring files with reserved FAT characters to a FAT file system + Replace them with an underscore if neccessary +* Use x-content/* MIME type to associate applications with hotpluggable media +* Path bar + * enable control-left click and middle-click interaction for path bar buttons + * dynamically handle hierarchy changes in the path bar +* Icon view keyboard navigation + * Use linear selection instead of rectangle selection in when pressing shift + * Still offer rectangular selection when pressing ctrl and shift + * Only wrap around horizontally in horizontal layout mode, + * Only wrap around vertically in vertical layout mode + * Never wrap around when in rectangle selection +* Icon view now remembers last position when reloading in vertical layout +* List view: Do not request mass redraw when dragging +* Clear display name when changing file name +* Only show "... All" actions ("Skip All", ...) in file operation dialogs if more + than one file is transferred +* Identify to MATE session as file manager, not as generic desktop application + +Major changes in 2.23.5.1 are: +* Fix crasher in spatial mode when closing window with ctrl-w +* Work around GTK+ tree view bug for sidebar eject button click area +* Some popup menu fixes +* Do not use C_() due to intltool bug + +Major changes in 2.23.5 are: +* Add tab support to browser mode +* Add "restore from trash" functionality (only per item) +* Path bar and notebooks can be used as fully functional URI drop targets +* Places sidebar + * Add eject buttons to volumes + * Fix bookmark reordering + * Make DND indication consistent with GTK+ file chooser +* Async I/O + * Use CajaFile instead of GFile for path bar display name + * Use CajaFile for DND "same FS" check +* Fix navigation where window was inconsistently "stuck" between two + directories, i.e. the view was not completely changed. +* Fix huge leak - status bar messages were never popped from the stack +* Always grab focus on location change, even if view is reused +* Icon view fixes + * If no icon is selected, but an icon has the keyboard focus, select it when + pressing space. + * Move keyboard focus after a file has been removed + * Fix double-clicking of half-shown items +* Thumbnailing changes + * Never scale up any thumbnails + * Compose and scale thumbnails on the fly + * Speed up loading of large image files used as their own thumbnails +* Display emblems for small icon sizes +* Offer clipboard contents as text/uri-list +* Use UTF-8 dash for properties window instead of "--" +* Misc + * Allow to build without XMP + * Require beagle 0.2.4 + * Require intltool 0.36.3. + +Major changes in 2.23.4 are: +* Fix background extension submenus for background context menus +* Fix thumbnailing + * Always re-thumbnail if a file without any thumbnail changes + * Always re-thumbnail if a failed thumbnail is not up to date +* Make zoom level specifications consistent (33% vs. 25%), round to 66% rather than 67%. +* Never hide hidden or backup files in trash +* Always copy file entire metadata when copying. Fixes timestamp preservation. +* Remove desktop emblem from desktop directory, since the folder now uses a desktop icon + +Major changes in 2.23.3 are: +* Use bilinear interpolation instead of hyperbolic. Massively speeds up thumbnailing. +* Fix thumbnail frame size calculation +* Rework properties dialog + * Remove "Launcher" tab, and move all the launcher properties to "Basic" + * Hide useless file info widgets from "Basic" tab for special locations like "computer:///". +* Support adding files to archives via file-roller +* Add location popup context menu to all path bar buttons +* Fix location popup context menu separators +* Add "Paste Into" item to location popup context menu +* Do not count the same inode twice when calculating directory sizes +* Never copy to "trash:///", never move to "burn:///" +* Never maximize windows opened from shell if a custom geometry has been specified +* Properly close windows displaying the media root location when ejecting a medium +* Empty the clipboard when copying/moving with DND to a container +* Remove libbackground +* Require eel 2.23.2 due to directory background API changes. + +Major changes in 2.23.2 are: +* Increase default thumbnailing size limit +* Various fixes to keyboard handling in icon and list view +* Use description from gio as window title +* Fix double click behaviour in list view +* Remember windows size when closed while maximized +* Always use single click policy in the places sidebar +* Fix selection handling after canceling delete operation +* Improve autorun behaviour +* Improve internal error handling +* Fix adding emblems +* Fix mateconf preferences description +* Improve list column page indentation +* Prevent recursive move/copy into itself +* Show mount dialog for already mounted shares too +* Prevent autogenerated file names from overflowing the max filename length +* Use ellipsis as per HIG +* Fix leaks +* Fix crashes +* Build fixes +* Translation updates + +Major changes in 2.23.1 are: +* Support new mate-session autostart semantics. +* Unify session save/restore routines with "--restart" and "--load-session" +* Allow to invert selection +* Do not automount mount points inside hidden hierarchies +* Add CajaFileInfo APIs: can_write(), get_mount(), get_parent_info() +* Add initial Gtk-doc support. +* Remove some dead code. + +Major changes in 2.22.1 are: +* Fix crashes and leaks +* Fix emblem display in property page +* Fix mime choosing to not always create application/x-ext- type +* Actually mount location in external connect to server dialog +* Fix thumbnail size limit checks +* Fix "show hidden" to also show backup files + (was broken in some situations) +* Verify that tracker is running before using it +* Fix desktop file icon handling with absolute filenames +* Use GDesktopAppInfos to launch desktop files +* Don't follow symlinks for deep file count +* Fix audio preview with later gstreamer +* Make "move file over directory" overwrite case work +* Sometimes we failed to ask for overwrite when move + operations falled back to copy + delete +* Make sure we correctly transcode filenames when merging + directories if the directory is on another filesystem. +* Some moves were reported as copies, not moves in the ui + which could cause not up-to-date directory displays +* Don't center file progress dialog if its already displayed + +Major changes in 2.22.0 are: +* Fix typo in strings +* Fix crashes +* Use a better icon for the progress dialog +* Have a mount menu for mountable files, not an unmount one +* Handle broken bookmark files bette +* Sniff x-content type asynchronously +* Don't look for autorun stuff on non-local files +* Allow setting permissions on remote shares +* Fix "delete all" button in delete dialog +* Show custom icons at right size +* Fix some performance issues on nonlocal mounts + +Major changes in 2.21.92 are: +* Build fixes +* Fix crashes and leaks +* Fix handling of desktop file launchers +* Better handling of desktop file icons +* Semitransparent DnD icon support (when composited) +* Avoid showing progress info when dialogs are shown +* Allow minimize of progress window +* Handle beagle >= 0.3.0 +* Close properties dialog on escape +* Make custom icons work again +* Fix fuzzy icons +* Duplicate file if copies to the source directory +* Support open with dialog for multiple selected files +* Ressurect connect to server dialog +* Allow theming of free diskspace chart colors + +Major changes in 2.21.91 are: +* String cleanups +* Inhibit autorun for things we mount ourselves +* Fix crashes and leaks +* Only show selinux context if selinux detected +* Default to move, not copy when dragging from trash +* Don't autorun/automount non-local mounts +* Fix case where we could run out of file descriptors +* Handle drop of files on the desktop +* Fix sensitiveness of delete from trash menu item +* Fix open with context menu in always-use-browser mode + +Major changes in 2.21.90 are: +* Use thousand separators in all numbers (if used by locale) +* Fix leaks +* Performance improvements +* Update to latest glib APIs +* Fix bug that lost metadata from older versions +* Fix crashes +* Enable paste into folder for desktop icons +* Better finding of autorun files on case sensitive media + +Major changes in 2.21.6 are: +* Regenerate thumbnails when files change +* Fix crashes +* New autorun and automount support +* Allow unmount of current location if its a mountpoint + +Major changes in 2.21.5 are: +* Add autorun/automount feature +* Better handling of sensitivity of delete menu items +* Better handling of mount/unmount/eject in many places +* Fix for extensions with submenus +* Fix crashes +* Updated some icons to the Tango look +* Fix some portability issues + +Major changes in 2.21.2 are: +* Update pkg-config files with new extensions dir +* Add some gio features to extension API +* Handle dnd of desktop icons +* Update to latest gvfs/gio API +* Implement some missing unmount/eject operations + +Major changes in 2.21.1 are: +* Totally replaced mate-vfs use with gio +* New implementation of file operations like copy/move with + a shared progress dialog +* Lots of cleanup + +Major changes in 2.20.0 are: +* Load thumbnails asynchronously +* Support direct save DnD (XDS) +* Fix up octal permission display +* Store window keep-above and stickines state across sessions + +Major changes in 2.19.91 are: +* Be more robust against broken extensions +* Set current working directory right on desktop when running scripts +* Fix crash on file:///# +* Update to cope with the new size of emblem icons + +Major changes in 2.19.90 are: +* Auto-size list view filename column again +* New message for service unavailable error +* UI terminology consistency fix +* Build fix + +Major changes in 2.19.6 are: +* Fixes to UI manager usage +* Better string ellipsation +* Consistent focus behaviour for toolbar buttons +* Support for XMP image metadata +* Improved keyboard handling in connect to server dialog +* I18n fixes and string clarifications +* Add more tooltips and use new gtk+ tootips API +* Better handling of unreadable directories during search +* Fix various crashes +* Translation updates + +Major changes in 2.19.5 are: +* Build fixes +* Fix leaks +* Fix crash +* Improved JPEG metadata handling +* Fix information sidebar layout +* Translation updates + +Major changes in 2.19.4 are: +* Allow activating the zoom context menu by keyboard +* Allow renaming of the network servers icons +* Use new desktop capplet +* Better handling of unicode search terms +* Fix program name in about dialog +* Fix keyboard shortcuts in preferences dialog +* Fix leak in zoom context menu +* Fix typos in error and warning messages +* Fix crash in properties dialog + +Major changes in 2.19.3 are: +* Added support for xdg-user-dirs +* A11y fix in the file properties dialog +* Build fix +* Don't show folder handler in menu editor +* Added alpha support for icon frames +* Updated thumbnail frame + +Major changes in 2.19.2 are: +* Fix crashes and leaks +* Add open in place sidebar context menu +* Make default icon sizes match xdg icon sizes better +* Fix hang with recursive symlinks +* Make name column wider +* Add trash to places sidebar +* Support for thumbnail icon size preference +* Disk free pie chart in properties dialog + +Major changes in 2.18.0.1 are: +* Reverted accidental commit + +Major changes in 2.18.0 are: +* Fix up desktop file categories +* Some sparse code cleanups +* Don't make filename column expand + +Major changes in 2.17.92 are: +* Don't display homedir as "desktop" in pathbar when in home-as-desktop mode +* Use GtkLabel ellipsizing +* Ellipsize filename column in list view +* Don't show unsupported methods in connect-to-server dialog +* Fix crashes + +Major changes in 2.17.91 are: +* Change file management capplet category +* Avoid showing "empty" in the tree while loading directory +* Prompt for empty trash on unmount +* Capitalize lin" in "Link to ..." names +* Fix crashes and memory leaks + +Major changes in 2.17.90 are: +* Add caja_file_info_get_activation_uri for extensions +* Zero-pad seconds in progress display +* Fix permissions of files created from templates +* Support multimedia keys +* Fix leaks +* Fix crashes + +Major changes in 2.17.1 are: +* Empty trash button in trash +* New menu icons for new document/folder/window +* Ring buffer for debugging +* Fix spinner size +* Open location dialog on desktop defaults to home +* Remove metadata on external delete events +* Draw text selection rectangle using cairo +* Jump to selection on sort order change +* Fix gsequence crash +* Freeze icon view while renaming +* New theming features for icon view +* New icon in about dialog +* Handle scroll button while rubberbanding +* Ellipsize menu button at 16 chars + +Major changes in 2.16.3 are: +* Revert a patch that caused icons to move around +* Fix crash introduced in 2.16.2 + +Major changes in 2.16.2 are: +* Fix a lot of crashes +* Handle throbbers with different sizes +* Don't add a newline when pasting filenames +* Better a11y relationships betweeen widgets +* Make caja --quit not be restarted by session +* Fix occasional stuck grabs when rubberband selecting +* Don't timeout typeahead when scrolling with mouse wheel +* Add X-MATE-Bugzilla-Version to desktop files +* Fix desktop icon overlap problem + +Major changes in 2.16.1 are: +* Default to search in current directory for non-indexed search +* Fix clash with symbol names in gtk+ + +Major changes in 2.16.0 are: +* Handle enter activation when using typeahead search +* Avoid using mate_vfs_is_local in wrong places +* Translations + +Major changes in 2.15.92.1 are: +* Fix crash on startup + +Major changes in 2.15.92 are: +* Fix crash on changing owner/group of file +* Fix double free +* Make sure all strings are displayed translated + +Major changes in 2.15.91 are: +* Use gtk recent files code +* Fix file change notification regression +* Don't display raw form of selinux contexts +* Import lates EggSequence with bugfixes +* DnD fixes +* Read .hidden symlinks +* Fix down navigation in last column, next to last row + +Major changes in 2.15.90 are: +* Submenu support for extensions +* Improved beagle daemon detection +* Enable D'n'D reordering in the places sidebar +* New icons for trash operations +* Add a button/text toggle button to the location bar +* Fix leak + +Major changes in 2.15.4 are: +* New permission dialog with recursion and selinx support +* Improve extension interface +* Add complete session management +* Handle removal of the displayed location more elegantly +* Use proper caja-cd-burner icon +* Support dropping uris, urls and text to subfolders +* Fix leaks and warnings + +Major changes in 2.15.2 are: +* Don't allow formating of mounted floppies +* Perfomance fixes +* Don't use deprecated eel features +* Use less memory when thumbnailing + +Major changes in 2.15.1 are: +* Improve startup performance +* Use GOption +* Fix selection box width calculation +* Improve file permission handling +* Add volume operations to the file menu, tree and places sidebar +* New po/LINGUAS handling +* Smarter date handling for images +* HIG fixes +* Fix various typos +* Fix about dialog to work with current gtk+ +* Fix crashes +* Show network volumes in the places sidebar +* Fix progress dialog showing the wrong file +* Code cleanups + +Major changes in 2.14.1 are: +* Translation updates +* Code cleanups +* Use --no-desktop option for all desktop files +* Startup performance improvements +* Make files copied from read-only source writeable +* Don't allow bookmarking x-desktop:/// +* Add help buttons to several dialogs +* Fix SVG file identification +* Properly break down URIs for connect to server ui +* Don't reposition icons on reload +* Show unmounted but user-visible drives in the places sidebar +* Display more info in the progress dialog when preparing +* Smarter DnD target selection +* Smaller close icon in the sidebar title +* MateGoals: Use po/LINGUAS + +Major changes in 2.14.0 are: +* Fix deadlock when dragging over list view in some conditions +* Fix keynav details in text beside icon mode +* Don't show folder count for smb shares +* Fix crash on middle click of file +* Fix a crash when leaving a directory +* Close window when folder moves to trash +* Fix deep count in properties dialog in some cases +* Avoid calculating mime lists for activation +* Fix text drawing in RTL mode when using text besides icons +* Remove blank error dialog on mount when using mate-mount + +Major changes in 2.13.92 are: +* Better filename linebreaking at punctuation marks. +* List view: If a rename moves the file in the view, scroll to the new position +* Better handling of broken filename encoding for link targets +* Some desktop icon positioning fixes +* Browser mode: don't close window on up if current directory has been removed +* Pass original files, not target files to property page providers. + This allows property page extensions to look at desktop files and symlinks. +* Various small optimizations +* Leak fixes +* Build fixes + +Major changes in 2.13.91 are: +* Fix a desktop icon positioning bug +* Fix opening saved searches file from outside caja + +Major changes in 2.13.90 are: +* Add option to always use the location bar to the preferences dialog +* Enable the icons in the places sidebar as drop targets +* Fix for desktop volume icon positioning +* Show detailed file size in the properties dialog +* HIG fix for the delete from trash dialog +* Fix icon scaling for images with extreme ratios +* Fix leaks & crashes + +Major changes in 2.13.4 are: +* Open modules with BIND_LOCAL +* Disable network icon on desktop by default +* Add Network to places menu +* Fix sort by atime +* Some HIG fixes +* Add support for searching for custom mime type +* store custom icons for folders as relative patch if in folder +* Much better activation of multiple files +* Bumped the default image size thumbnailing limit +* Handle new background image zooming mode +* Add optional support for Tracker indexer +* Fix leaks & crashes + +Major changes in 2.13.3 are: +* Added initial support for search +* Fixed memleaks +* Don't frame thumbnails with alpha channel +* Better handling of opening multiple files +* New resize knob icon +* View update optimizations +* No titles for alert dialogs +* Add network desktop icon +* Use access() to determine permissions + +Major changes in 2.13.2 are: +* Fix mime list problem introduced with sort change +* Build fixes +* Keyboard support for icon stretching +* Finally fix tree sidebar crash +* ctrl-shift-g goes backwards in typeahead +* Add Skip all button in copy/move conflict dialog +* Position new files/folders correctly in manual layout mode +* Nicer UI for setting custom file icons +* Fix CD icon positioning on desktop +* Fix desktop redraw issues on non-100% zoom levels +* Use the same home icon always + +Major changes in 2.13.1 are: +* Adds volume/drive api for modules +* Better sizes of stock icons in many places +* GtkTreeView style typeahead +* '/' opens location dialog/entry +* middle click in browser mode opens new window +* Handle cancellation of authentication better +* Add format menu item for floppy drives + +Major changes in 2.12.1 are: +* Pass all selected files to menu extensions, not only one per mimetype +* Use much fewer file monitors +* Fix text size on startup with non-standard default zoom size +* Some fixes to trash handling and unmount +* Fix some desktop icon positioning details +* Copy thumbnails when copying files +* Autofill connect to server dialog when possible +* Always show deep counts in properties page +* Fix leaks and crashes +* Correctly escape filenames for display in progress dialog + +Major changes in 2.12.0 are: +* Fix icon layout in text-beside-icons mode in some cases +* Fix template creation on volumes other than the same as /tmp +* Expand file uris correctly on desktop when passing to scripts +* Workaround crash on audio preview in burn: +* Fix handling of global show hidden files preference +* Fix crash caused by earlier memleak fix +* Don't redraw windows/desktop on focus in/out + +Major changes in 2.11.92 are: +* Enable emblem dropping to the list view +* Disallow deleting special locations from the location button popup +* Don't show "Open Folder" as application option in context menus +* Disallow custom icons for the trash +* Cleanups & Leak fixed + +Major changes in 2.11.91 are: +* Don't allow renaming of the desktop folder +* Make moves within burn:// possible +* Fixes to property browser drag and drop code +* Add Explorer-style keybindings +* Add timestamps to metafiles +* Make ESC switch back to the pathbar +* Use saner check for mime mismatching +* Make progress dialog minimizable +* UI fixes + +Major changes in 2.11.90 are: +* Handle dnd more efficently +* Use file-manager icon for browser windows +* Use hover underline and cursor for single click mode +* Make labels selectable in the sidebar +* Improve sound preview process handling +* UI fixes to path- and sidebar + +Major changes in 2.11.4 are: +* Allow dnd of text on view to create a new file +* show hostname in progress dialogs +* use pathbar in location toolbar +* busy curson when loading folder in browser mode too + +Major changes in 2.11.3 are: +* Turn the list view into a tree +* No dnd drop rect on the desktop +* Use gtk bookmars as bookmark source +* Add bookmarks to spatial mode +* New places sidebar +* better sort order for filenames with numbers in them + (needs glib 2.7.x) +* Better handling of font sizes wrt zoom in icon view +* Fix leaks + +Major changes in 2.11.2 are: +* Fix sort order for size/count/time +* ctrl+scrollwheel changes zoom, ctrl-= zooms in +* better handling of cut and paste in notes text view +* Add smb domain field in connect to server dialog +* nicer handling of drops from mozilla +* no properties menu item for desktop context menu +* shift-f2 renames with the whole name initially selected +* sort by emblem only looks at user-set emblems +* scroll to icon when selected and partially visible + +Major changes in 2.11.1 are: +* Use authentication in external connect to server app +* UI polish +* Allow DnD of location button icon. +* Context menus on location button and location label in browser +* Fix memory leaks +* Fix crashes +* Speed up delete in list view +* Fix rename in list view breaking when there was a file change +* Removed "new terminal" from desktop context menu + If you want this, install the caja-open-terminal extension, + its much better than this feature ever was. +* Don't thumbnail files constantly if they're changing +* Fixed a loop that could happen on remote locations when removing + a directory. +* Add properties of the current folder menu item to background + context menu +* Use --no-desktop in default folder handler to avoid taking over + the desktop if you don't run mate. + +Major changes in 2.10.1 are: +* Use less memory for desktop background +* Make authentication work for the external connect-to-server dialog +* Fix leaks +* Redraw less in the list view when deleting + +Major changes in 2.10.0 are: +* Some fixes for startup notification to avoid focus-stealing +* Center the file management prefs dialog + +Major changes in 2.9.92 are: +* Avoid doing i/o to tree root nodes before they are used. + This means we don't get authentication callbacks. +* Correct handling of startup notification +* Fix crashers in desktop icon context menus when unmounting volumes +* Make property page for home icon on desktop show the right size +* Prevent the progress dialog from displaying strange ETAs +* Make backspace key open parent folder in list view + +Major changes in 2.9.91 are: +* Fix some crashes +* Don't pop up mozilla dnd ask dialog under windows +* Change the look of the path button to make it easier to find +* Some changes to the look/text of the progress dialog +* Fix panel size detection on 64bit machines +* Allow open with menu on folders + +Major changes in 2.9.90 are: +* Better window titles for browser windows +* Better icons for burn: & computer: in the ui +* Allow eject of unmounted devices +* Better handling of DnD from mozilla +* Make connect to server dialog available as separate app +* Use GtkAboutDialog + +Major changes in 2.9.2 are: +* Use the new mime API +* Fixed bug in finding empty spots on the desktop +* Handle drags to special desktop icons (trash...) +* Fix crash in clipboard code +* Fix crash with non-unique volume filenames +* Better handling of sizes for image-file-as-icon +* Fill in ctrl-l dialog correctly for desktop +* Fix crash in bookmark dialog if parent window goes away + +Major changes since 2.8.2 are: +* MateComponent not used for caja views +* GtkUIManager used for the ui, not MateComponentUI + +Major changes since 2.8.1 are: +* On mime mismatch, allow open with default app as open with +* On dnd of mozilla link, create desktop file with .desktop ending +* Delay activation when keyboard navigating in tree sidebar +* Add open new window menu item in browser mode +* Fix race condition that made up not alway select the folder +* Better error message when there is no handler for a file +* Fix throbber right-alignment with latest matecomponentui +* Alt-up selects the directory you came from +* Display a frame on DnD hover if accepting +* Fix off-by-one bug in icon positioning on DnD +* Make creating new files in list view auto-rename +* Add the icon text to the DnD icon +* Add eject to volumes in free sidebar +* Don't close browser window when the showed path is unmounted +* Save browser window geometry +* Handle the new env vars for filesystem charset + +Major changes since 2.8.0 are: +* Update to latest egg-recent +* Fix memory leaks +* Clear clipboard after a cut file is pasted +* Properly escape uris created by connect to server dialog +* Better alignment of icon labels +* Allow move (not copy) of a file to another filesystem +* Fix reordering of selection when a listview is resorted +* Allow keynav on desktop +* Fix crash in sort-by-emblems mode +* Performance fixes when selecting files +* Performance increase in folder load +* Allow pasting files as text +* Fix caja extensions such as file-roller menus +* Made select by pattern work in trash +* Fixed cut/paste of text when renaming in listview +* Always use homedir icon for homedir + +Major changes since 2.7.92 are: +* Destroy metadata hashtable in right way, fixes crash +* Fix crash in list view when changing views +* Translation updates + +Major changes since 2.7.4 are: +* Fix crash when transfer rate near zero +* Fix crash when renaming in list view and changing directory +* Fix double call of eel_preferences_remove_callback on shutdown +* Use default folder view from mateconf instead of now broken mate-vfs mime setting +* Some fixes to the handling of open with +* Faster way to get the group list for a user +* Don't make progress dialog on copy to desktop appear on all workspaces +* Fix sort by size in computer view + +Major changes since 2.7.2 are: + +* Fix remaining time reporting in progress dialog +* Nicer connect to server dialog +* Various bugfixes and memleak fixes + +Major changes since 2.7.1 are: + +* Added spatial/browser pref to the prefs dialog +* Use ctrl+q to add all windows +* On shift-double-click on a non-folder, close the window after. +* Bug fixes +* Show estimated time remaining in the progress dialog. +* per-window show hidden files setting +* Don't warn about mime-type mismatches if the handler is the same + for both mime-types. +* Date formatting improvements +* Killed start-here +* Changed to use the new mime spec and UI + +Major changes since 2.6.2 are: +* Desktop file editior property page +* Display server name in window title for remote URIs +* Add setting to not show volumes on desktop +* Prevents read-only emblem from being shown on desktop icons + when user is in root group +* Fix dnd start coordinates when zoomed +* Start apps in the directory they are launched from +* Add close all windows to spatial window menu + +Major changes since 2.6.1 are: +* Accessibility/keynav/theming fixes +* Leak fixes +* .desktop file updates +* Fixed help buttons in the preferences dialog +* Portability fix +* Use initial click position to anchor icon dnd +* Crash fix in the file properties dialog +* Don't overlap the close icon and text label when the sidepane + is very small. + +Major changes since 2.6.0 are: +* Fix various crashes and leaks +* Use correct icon for filesystem in treeview +* Place unplaced windows over the parent window +* Fix non-ascii typeahead +* Faster property dialog for operations on many files +* Faster list view +* Fill open location dialog with initial path +* Add down arrow to location button +* Make shift close window behind in more places +* Allow smaller spatial windows +* Allow svg backgrounds +* Fix ignore kde trash directory hack +* By default set per-folder background in spatial mode + +Major changes since 2.5.91 are: +* Translation updates + +Major changes since 2.5.90 are: +* Handle failures when opening new window better (don't loop) +* visiting and accept modifiers were reversed in list view +* Build fixes + +Major changes since 2.5.8 are: +* Beter typeahead in list view +* "browse" context menu item in more places +* Added go -> cd burner in browser mode +* Fallback to normal icon view if there is a problem launching another view +* Close windows on unmounted directories +* Fix crashes +* Longer delay until cancel open dialog opens + +Major changes since 2.5.7 are: +* Fix crash +* Nicer names for toplevel uris +* Browse folder works in more places +* Added preference to always use browser windows +* Warn when sniffed/extension-matched mime type disagrees +* Show applications for both sniffed and extension-matched + mimetype in the open with menu + +Major changes since 2.5.6 are: +* Fix icon lookup crash +* Fix property page crash +* Some a11y fixes +* Use new background capplet name +* Fix rename keyfocus issue +* Scroll to icon after rename +* Fix ogg previewing +* Some HIG rephrasing of strings +* Fix crash on rename of empty selection +* Update help userguide links +* Paste menu sensitivity fix +* Rename selection keynav now behaves better from the start + +Major changes since 2.5.5 are: +* hig/ui tweaks +* ngettext support +* distribute caja-list-view-ui.xml +* New mimetype detection approach +* performance fixes +* non-modal open with other dialog +* Don't show small svgs as themseleves (always thumbnail) +* update egg-recent + +Major changes since 2.5.4 are: +* Extension system for emblem, property page, menu item, and + list view column plugins. +* Editable list view columns +* Don't expand symlinks when following them. +* Busy cursor in loading spatial windows +* Icon-view style typeahead in the list view. +* Emblems in the list view +* Added a location button to spatial windows +* Removed tab icon nav from the icon view +* Add a context menu to the tree side pane. +* Pop up folder menu in list view background +* Turn on home icon on the desktop by default +* Added status bar info when no files are selected +* Got rid of unnecessary EelGenerousBin/EelInputEventBox usage +* HIG fixes +* Bugfixes + +Major changes since 2.5.3 are: +* Use GtkIconTheme instead of MateIconTheme +* Show visited folders differently +* Better mouse/keynav in icon and list view +* Save window geometry on window close +* HIG message dialogs +* File templates support + +Major changes since 2.5.2 are: +* Accessibility fixes +* Better initial size of navigation window +* Close all parents closes all parents +* Focus the next item after delete in list view + +Major changes since 2.5.1.1 are: +* Don't do unnecessary i/o on remote locations +* handle broken symlinks that go unbroken +* various bug fixes +* some accessibility fixes + +Major changes since 2.5.1 are: + +* Fixed a CajaFile leak +* DISABLE_DEPRECATED fixes. + +Major changes since 2.5.0 are: + +* Start of new volume handling system +* deprecaton clean +* fixed leaks +* performance fixes + +Major changes since 2.4.0 are: + +* Spatial / Navigational split + +* Themed icon for desktop window + +* Exif image properties + +* Fixes for query-drags + +* Don't allow renames to "" in list view + +* Expand treeview rows on double click + +* Change desktop grid size + +* Don't disable deprecated API + +* Pattern selection + +* No incremental display of files + +* Various bug fixes + +Major changes since 2.3.90 are: + +* don't migrate .mate-desktop if it is a symlink + +* Fix messed up home/trash icons for new users + +* Handle xpm icons correctly in desktop files + +* Handle non-utf8 user names + +Major changes since 2.3.9 are: + +* Fix warning on theme changes + +* Sometimes the home and trash icons became blank and unusable + +* Auto-hide KDE trash directory in desktop directory. + +Major changes since 2.3.8 are: + +* Fix history sidepane crash + +* Add keynav rectangle selection + +* Better error string for missing proxy hostnames + +* Handle arrow keys on numerical keypad + +Major changes since 2.3.7 are: + +* Handle write protected mateconf keys better + +* Make "Write to CD" button higher priority + +* Small bugfixes + +Major changes since 2.3.6 are: + +* Fixed zoom-to-fit in the zoom control. + +* Selected files are colorized with the selection color. + +* Doesn't create new windows when mounting CD-ROMS. + +* Improved the gutter-on-the-right problem. + +* Updates the disks menu when fstab changes + +* Performance enhancements for icon layout. + +* Added support for total size and total count for multi-file property dialogs. + +* String fixes + +* Added documentation on caja internals + +* Various fixes + +Major changes since 2.3.5 are: + +* .hidden file support + +* Improved context menus + +* Speed improvements in the list and tree views + +* Multi-rooted tree view + +* Update emblems list after adding custom emblems + +* Prefer existing windows from the command line in open-in-new-window + mode + +Major changes since 2.3.4 are: + +* Startup notification support when launching files. + +* Selection fixes + +* Crash fix in the properties dialog + +* Icon theme changes in the tree view fixed + +* gcc 3.3 build fixes + +* Desktop icon bug fixes + +* Panel transparency fix + +Major changes since 2.3.3 are: + +* Added a "text beside icons" pref to the icon view + +* Use the authentication manager in the adapter component + +* MateComponent context menus can supply an icon + +* Zoom control uses stock widgets + +* The property dialog can edit multiple files + +* HIG-compliance improvements + +Major changes since 2.3.2 are: + +* Made the throbber themable using icon themes + (requires mate-icon-theme 1.0.4) + +* Get manager selection for desktop + +* Fix some bugs in new desktop code + +* fixed icon position for DnD in the listview + +* Fixed spacing in dialogs to comply better with the HIG + +* Use the authentication manager from libmateui instead + of our own. + +* Fix keynav bug with space in listview + + +Major changes since 2.3.1 are: + +* Disabled the limit on the number of files in a directory. + +* Change desktop directory to ~/Desktop + +* Major change to how desktop icons are handled + +* Some accessibility fixes + +Major changes since 2.2.3 are: + +* Performance increases on directory loads. + +* Integrate caja-cd-burner + +* "Keep Aligned" mode on desktop + +* Cygwin & AIX port + +* Uses new mate_vfs_show_url API to activate files + +* Better bookmarks UI + +* Change in how attributes are stored internally. + +Major changes since 2.2.2 are: + +* Lots of fixes to the list view keyboard and mouse handling + +* Lots of fixes to the icon view keyboard and mouse handling + +* Automatic notes emblem (requires mate-icon-theme 1.0.2) + +* Correctly scale icons in list view + +* No more tearing when zooming the icon view + +* Don't select the extension for rename in the list view + +* Easier to trigger auto scrolling during drag and drop in the icon + view + +* Much better thumbnail queue handling. Visible thumbnails are + prioritized. + +* Scroll to previous position on directory reload + +* Show volume and free space in the property dialog for directories + +* Clean up by name doesn't leave icons outside the screen anymore + +* Fix show backup/hidden files and some default view preferences + +* Set the Caja application name used when grouping in the task + list. + +* Converted CajaFile to a GObject + +* Make the thumbnail size prefs not affect external thumbnailers, as + it makes little sense for e.g. videos. + +* Allow you to exit caja-file-management-properties + +* Fix crash when droping from other app to Caja + +* Use startup notification when launching Caja + +* Don't save window geometry when maximized + +* Added code to migrate Caja 1.0.x scripts + +* Added some docs about keyboard and mouse navigation in caja views. + +* Better accessibility support in the icon view + +* Some other small bugfixes and polish + +Major changes since 2.2.1 are: + +* Going back/forwards scrolls to the position you left + +* Better support for Gtk+ themes on the toolbar and location bar + +* Disable the "switch to manual layout" dialog + +* Ctrl-dragging on a selected file doesn't de-select it + +* Save the current active side pane + +* Now easier to hit icons, since you can also click on the transparent + parts. + +* Select the directory name for renaming when creating a new directory + +* Select the base name (not extension) when renaming a file + +* List view smaller zoomlevel by default + +* Text view has copy to clipboard functionallity + +* Padding and alignment changes in the preferences dialog + +* Performance enhancement for embedded text + +* The delete key now works on the desktop + +* Added back the "erase" emblem to the Backgrounds & emblems dialog + +* Better accessibility support for the icon view + +* Refresh listview when icon theme changes + +* Correct font size when renaming and not 100% zoomed view + +* Remove all usage of deprecated APIs + +* Use monospace font in text view + +* Added 1 gigabyte pref tor max thumbnailing size + +* Handle floppies and cdroms mounted outside /mnt + +* Fix duplicated entries in context menu. + +* Don't session manage CajaViews + +* Multi-head fixes for the preference dialog + +* Leak fixes + +* Fix matecomponent-activation forkbomb + + +Major changes since 2.2.0.2 are: + +* Fix name collisions in trash + +* fix image properties crash + +* multihead fixes + +* allow .svgz rendering + +* correct icons dor zip disks + +* fix button ordering for transfer error dialogs + +* memory leaks fixed + +* "slow context menu" fixed + +* Fixed smb passwords getting "stuck". + +Major changes since 2.2.0.1 are: + +* Background crash fix + +* Embedded text fix + +Major changes since 2.2.0 are: + +* CajaView refcounting fix + +* New translations + +Major changes since 2.1.91 are: + +* i18n fixes + +* List view fixes + +* Reverted the symlink change. Now resolves symlinks when following + them. + +* Context menu corba usage fix + +* Reload thumbnails when files changes + +* Small fixes + +Major changes since 2.1.6 are: + +* No flicker on startup. + +* Faster expose of the desktop + +* Don't resolve symlinks when follow them + +* Small bugfixes + +Major changes since 2.1.6 are: + +* Multihead fixes + +* Fixed delete-in-rename-deletes-file bug + +* UI review improvements + +* Resolved the conflict between Edit and Empty Trash that was causing + the desktop to be badly stuck. + +* Small bugfixes + +Major changes since 2.1.5 are: + +* Don't depend on libmatecanvas + +* Don't put icons under panel + +* Use new icons for start-here + +* Better window titles for e.g. fonts:/// + +* Handle thumbnail preferences + + +Major changes since 2.1.4 are: + +* Handle icon theme changes better + +* Query drag with middle button instead of right-click. + This allows faster context menus. + +* Bugfixes + +Major changes since 2.1.2 are: + +* Remove unused code. + +* Lots of smalll bugfixes. + +* Make matecomponent property pages regular controls instead of CajaViews. + +* Mimetype-sensitive context menu plugins + +* Restructure the cut-and-paste code. + +Major changes since 2.1.1 are: + +* New preferences dialog and capplet. + +* Pluggable file property pages. + +* New Image properties page. + +* Emblem sidebar work. + +* Handle rootwindow drops. + +* Background drag and drop changes + +* The music view has been removed. + +Major changes since 2.1.0 are: + +* Multihead support + +* Emblem sidebar + +* Emblems handled with icon themes + +* Uses new pango wrap mode in icon view + +* Work on exterminating Caja themes + +* Recent files support + +Major changes since 2.0.7 are: + +* Caja now uses the system icon theme. + +* The sidebar tabs have been replaced with a new widget. + +* The icon container uses the new eel canvas. + +* UI cleanups. + +* Various bugfixes. + +Major changes since 2.0.6 are: + +* Fixed the assertion failure on startup + +* CD handling updates + +Major changes since 2.0.5 are: + +* Fixed volume handling bug with thrash that made it impossible + to unmount removable media while using fam. + +Major changes since 2.0.4 are: + +* Follow thumbnailing prefs for svgs too + +* Correctly handle old non-utf8 trash and home links + +* Fix the "icons stacked in top left corner" bug + +* Various small bugfixes. + +Major changes since 2.0.3 are: + +* Don't show progress dialog for fast operations + +* Mime handling fixes + +* crux theme tweak + +* small performance enhancements + +* Various bugfixes. + + +Major changes since 2.0.2 are: + +* Drag and drop has been implemented in the list view. + +* Performance enhancements in the icon factory. + +* Various bugfixes. + + +Major changes since 2.0.1 are: + +* List view doesn't hang anymore. + +* Reflect changes in the eel background api. + +* Fix for crash when invoking "caja -q". + + +Major changes since 2.0.0 are: + +* Various UI cleanups from the ui review + +* Various bugfixes + +* The Mate Caja theme now follows the gtk+ theme better + +* Window geometry is stored even in open-directories-in-same-window mode + +* All executable matecomponent components moved into libexec. + +* Some performance improvements + +* Accessibility fixes + +* Add support for kernel supermount patch + +* Read desktop file icons according to the icon theme specification + +* New throbber for the mate theme + +* large version of trash icon + +* Better handling of disk ejecting + +* Proper handling of launching desktop files according to the spec + + + +Major changes since 1.0.x are: + +* Port to Gtk+ 2 and the Mate 2 platform. + +* Major performance improvements. + +* Userlevels are removed. + +* Lots of small UI changes in order to comply with the Mate 2 Human + Interface Guidelines. + +* Preferences dialog has been trimmed down. + +* Anti-aliased mode has been removed. If you want anti-aliased text, + you need to use the Gtk+ 2 anti-aliased text mode. + +* New emblems added to the default set of emblems. + +* Support for editing vfolder menus using caja. + +* Made most normal component in-process. + +* Accessibility support. + +* Drop support for public metadata. + +* The news was sidebar disabled/removed + +* Image view component removed, we now use Eye of Mate. + +* Bugfixes + + +Minor new features: + +* Drop-shadow for text on the desktop + +* Alt-drag image and pick set-as-background + +* New progress dialog window-icon shows progress visually. + +* You can use Alt-left/right/up/down to navigate the icon view using + the keyboard. + +* Ability to easily create launchers on the desktop. + diff --git a/README b/README new file mode 100644 index 00000000..471a3a57 --- /dev/null +++ b/README @@ -0,0 +1,31 @@ +This is Caja, the file manager for the MATE desktop. + +Installation +============ + +See the 'INSTALL' file for installation instructions. You will need a +complete and up-to-date MATE development environment to build caja. +You can also find some building and installation tips at +http://live.gnome.org/Caja/Development/Caja + +Hacking on Caja +=================== + +Please see the HACKING file for information about hacking on caja. + +Mailing List +============ + +The caja mailing list is caja-list@gnome.org. Subscription +information is available at +http://mail.gnome.org/mailman/listinfo/caja-list + +How to report bugs +================== + +Bugs should be reported to the MATE bug tracking system +(http://bugzilla.gnome.org), in the "caja" product. + +Please read the following page on how to prepare a useful bug report: +http://bugzilla.gnome.org/bug-HOWTO.html + diff --git a/README.commits b/README.commits new file mode 100644 index 00000000..2a2f019b --- /dev/null +++ b/README.commits @@ -0,0 +1,68 @@ +Caja is part of the MATE git repository. At the current time, any +person with write access to the MATE repository, can make changes to +Caja. This is a good thing, in that it encourages many people to work +on Caja, and progress can be made quickly. However, we'd like to ask +people committing to Caja to follow a few rules: + +0) Ask first. If your changes are major, or could possibly break existing + code, you should always ask. If your change is minor and you've + been working on Caja for a while it probably isn't necessary + to ask. But when in doubt, ask. Even if your change is correct, + somebody may know a better way to do things. + + If you are making changes to Caja, you should be subscribed + to caja-list@gnome.org. (Subscription address: + caja-list-request@gnome.org.) This is a good place to ask + about intended changes. + + #caja on GIMPNet (irc.gimp.org, irc.us.gimp.org, irc.eu.gimp.org, ...) + is also a good place to find Caja developers to discuss changes with. + +1) Ask _first_. + +2) With git, we no longer maintain a ChangeLog file, but you are expected + to produce a meaningful commit message. Changes without a sufficient + commit message will be reverted. See below for the expected format + of commit messages. + +3) Try to separate each change into multiple small commits that are + independent ("micro commits" in git speak). This way its easier to + see what each change does, making it easier to review, to cherry pick + to other branches, to revert, and to bisect. + +Notes: + +* When developing larger features or complicated bug fixes, it is + advisable to work in a branch in your own cloned Caja repository. + You may even consider making your repository publically available + so that others can easily test and review your changes. + +* The expected format for git commit messages is as follows: + +=== begin example commit === +Short explanation of the commit + +Longer explanation explaining exactly what's changed, whether any +external or private interfaces changed, what bugs were fixed (with bug +tracker reference if applicable) and so forth. Be concise but not too brief. +=== end example commit === + + - Always add a brief description of the commit to the _first_ line of + the commit and terminate by two newlines (it will work without the + second newline, but that is not nice for the interfaces). + + - First line (the brief description) must only be one sentence and + should start with a capital letter unless it starts with a lowercase + symbol or identifier. Don't use a trailing period either. Don't exceed + 72 characters. + + - The main description (the body) is normal prose and should use normal + punctuation and capital letters where appropriate. Normally, for patches + sent to a mailing list it's copied from there. + + - When committing code on behalf of others use the --author option, e.g. + git commit -a --author "Joe Coder " and --signoff. + + +Alexander Larsson +17 Apr 2009 diff --git a/THANKS b/THANKS new file mode 100644 index 00000000..ac66b683 --- /dev/null +++ b/THANKS @@ -0,0 +1,621 @@ +The Caja team would like to thank the following contributors: + +Caja 2.12 - 2.22 +==================== + +A. Walton +Abel Cheung +Adi Attar +Ahmad Riza H Nst +Alastair McKinstry +Alexis Robert +Amitakhya Phukan +Anders Carlsson +Andre Klapper +Andrea Cimitan +Ani Peter +Ankit Patel +Arangel Angov +Artur Flinta +Benjamin Berg +Benoît Dejean +Brian Cameron +Brian Pepple +Chao-Hsiung Liao +Choe Hwanjin +Chris Lahey +Chris Lyttle +Christian Kellner +Christian Kirbach +Christian Persch +Christophe Fergeau +Christophe Merlet +Christopher Lahey +Chrustian Neumair +Claude Paroz +Clytie Siddall +Cosimo Cecchi +Dafydd Harries +Damien Carbery +Damon Chaplin +Dan Winship +Daniel Drake +Daniel Godas +Daniel Nylander +Danilo Šegan +Danishka Navin +Dave Ahlswede +Dave Bordoley +Dave Camp +David Bordoley +David Emory Watson +David Sainty +David Zeuthen +Denis Jacquerye +Denis Washington +Diego Gonzalez +Djihed Afifi +Dom Lachowicz +Elizabeth Green +Emmanuele Bassi +Erdal Ronahi +Eric Baudais +Fabio Bonelli +Farzaneh Sarafraz +Federico Mena Quintero +Florian Steinel +Francisco Javier F. Serrador +Frank Worsley +Frederic Crozat +Funda Wang +Gabor Kelemen +Ganesan Sethuraman +Gaute Lindkvist +Gautier Portet +Gediminas Paulauskas +German Poo-Caaman~o +Gil "Dolfin" Osher +Gil Forcada +Gintautas Miliauskas +Glen Gray +Glynn Foster +Goran Rakić +Gregory Leblanc +Gregory Merchan +Guilherme de S. Pastore +Guillaume Desmottes +Guillaume Savaton +Gustavo Giráldez +Gustavo Maciel Dias Vieira +Hasbullah Bin Pit +Hendrik Richter +Hubert Figuiere +I. Felix +Iain +Ignacio Casal Quinteiro +Ihar Hrachyshka +Ilkka Tuohela +Inaki Larranaga Murgoitio +Jacob Berkman +Jakub Friedl +James Henstridge +Jamie McCracken +Jan Arne Petersen +Jan de Groot +Javier F. Serrador +Jens Finke +Jens Granseuer +Jens Seidel +Jesse Stockall +Jody Goldberg +Joe Shaw +Johan Dahlin +John Harper +Jonh Wendell +Jordi Mas +Jorge Gonzalez +Jorn Baayen +Josep Puigdemont Casamajó +Josh Barrow +Jovan Naumovski +Juerg Billeter +Justin Fitzsimmons +Jérémy Ar Floc'h +Keith Conger +Kenneth Nielsen +Kenneth Rohde Christiansen +Kevin Kubasik +Kostas Papadimas +Lasse Bang Mikkelsen +Laszlo Dvornik +Laszlo Peter +Lauris Kaplinski +Leonardo Ferreira Fontenelle +Louise Miller +Lucas Rocha +Luis Medinas +Lukas Novotny +Lukasz Stelmach +MArk Finlay +Marinus Schraal +Mark Gordon +Marten Ter Borgh +Matej Urbančič +Matic Žgur +Matthias Clasen +Maxim Dziumanenko +Michael Terry +Michiel Sikkes +Mohammad DAMT +Mugurel Tudor +Mətin Əmirov +Nate Nielsen +Nelson Benítez +Nguyễn Thái Ngọc Duy +Nickolay V. Shmyrev +Nikos Charonitakis +Olav Vitters +Paisa Seeluangsawat +Pasupathi Duraisamy +Pat Suwalski +Paul Duffy +Pawan Chitrakar +Pema Geyleg +Peteris Krisjanis +Petr Kovar +Philip Withnall +Pramod Raghavendra +Priit Laes +RUAUDEL Frédéric +Rachel Hestilow +Raffaele Sandrini +Rahul Bhalerao +Raivis Dejus +Raj +Rajeev Karale +Rajesh Ranjan +Raphael Higino +Reinout van Schouwen +Remi Cohen-Scali +Richard Hoelscher +Rodney Dawes +Rodrigo Moya +Rodriguez Perez +Rohit R +Roozbeh Pournader +Runa Bhattacharjee +Ryan Lortie +Samuel Jan Gunnarsson +Sanlig Badral +Satoru SATOH +Satyajit Kanungo +Sean Atkinson +Sebastian Dröge +Sebastien Bacher +Sergey Udaltsov +Seán de Búrca +Shivram U +Sigurd Gartmann +Simos Xenitellis +Siviah Nallagatla +Slobodan D. Sredojevic +Soeren Sandmann +Stephen Browne +Stephen Cook +Steve Murphy +Stuart MacLean +Stéphane Raimbault +Subhransu Behera +Sunil Mohan Adapa +Takeshi AIHANA +Taneem Ahmed +Terance Sola +Theppitak Karoonboonyanan +Thierry Randrianiriana +Thomas Canty +Thomas Meeks +Thomas Vander Stichele +Tom Parker +Tomas Bzatek +Tomasz Kloczko +Trevor Davenport +Tõivo Leedjärv +Urbančič Matej +Vasiliy Faronov +Vinay M R +Vincent Noel +Vincent Untz +Vincent van Adrighem +Vladimer Sichinava +Wadim Dziedzic +William Jon McCann +Willie Walker +Wouter Bolsterlee +Xavier Claessens +Yair Hershkovitz +Yang Hong +Yannig Marchegay +Yuriy Syrota +Zbigniew Chyla +christian neumair +jacob berkman +marten ter borgh +Åsmund Skjæveland +Øivind Hoel +Žygimantas Beručka + + +Caja 2.4 - 2.10 +=================== + +Alan Swanson +Alex Duggan +Alex Graveley +Alexander Winston +Anders Carlsson +Arjan van de Ven +Arvind Samptur +Balamurali Viswanathan +Baris Cicek +Bastien Nocera +Bradford Hovinen +Chris Lahey +Christian Neumair +Christian Rose +Christophe Fergeau +Colin Leroy +David Bordoley +David Malcolm +Dennis Cranston +Dinoop Thomas +Elijah Newren +Federico Mena Quintero +Fernando Herrera +Francisco Javier F. Serrador +Grahame Bowland +Gustavo Giraldez +Hugo +Iain +Ian Wienand +J. Christopher Six +Jaap Haitsma +James Henstridge +James Willcox +Jamie +Jason Leach +Jimmy Do +Jonathan Blandford +Jorn Baayen +Jürg Billeter +Kaushal Kumar +Luca Ferretti +Magnus Damm +Marco Pesenti Gritti +Mark McLoughlin +Matthew Gatto +Mattias Eriksson +Michael Gossard +Michael Henson +Murray Cumming +Nickolay V. Shmyrev +Padraig O'Briain +Paolo Borelli +Rached Ben Mustapha +Richard Hoelscher +Sebastien Bacher +Shaun McCance +Sivaiah Nallagatla +Soeren Sandmann +Srinivasa Ragavan +Stephane Wirtel +Sven Herzberg +Takao Fujiwar +Thierry Moisan +Thomas Cataldo +Tim Savannah +Victor I. +Vijaykumar Patwari +Vincent Noel +Vincent Untz +William Lachance +Xan Lopez + +Caja 2.4 +============ + +Alex Duggan - bug fixes +Anders Carlsson - bug fixes, Made CajaFileAttributes a bitmask +Arvind Samptur - multihead work +Bastien Nocera - bug fixes +Chris Altmann - bug fixes +Christian Neumair - HIG fixes +Christian Rose - string fixes +Christophe Fergeau - bug fixes +David Bordoley - UI and HIG work +Dennis Cranston - file management capplet icon +Dom Lachowicz - bug fixes +Frank Worsley - Use new mate-vfs show_url API +Frederic Crozat - bug fixes +Fredrik Jösson - bug fixes +Gaute Lindkvist - bug fixes, Show volume name and free space +George Lebl - handle non-writable mateconf keys +Glynn Foster - nicer bookmarks dialog +Greg Merchan - HIG fixes +Hidetoshi Tajima - bug fixes +Iain Holmes - new zoom widget, don't use deprecated gtk+ API +James Willcox - bug fixes +Jody Goldberg - foocanvas fixes +Johan Dahlin - total size and count for multi-file property dialogs +Jordi Mallach - bug fixes +Keith Conger - bug fixes +Laurent Vivier - AIX port +Luca Ferretti - bug fixes +Luca Ferretti - string fixes +Marco Pesenti Gritti - throbber theamable using icon theme +Mark McLoughlin - bug fixes +Marten ter Borgh - bug fixes +Masahiro Sakai - cygwin port +Michael Meeks - bug fixes +Miguel Ibarra - build fix +Morten Welinder - foocanvas fixes +Muktha Narayan - bug fixes +Padraig O'Briain - a11y work +Pasupathi Duraisamy - bug fixes +Reinout van Schouwen - string fixes +Stephen Browne - bug fixes +Wolfgang Pichler - initial work on multirooted tree + +Caja 2.0 and 2.2 +==================== + +Alex Duggan - bug fixes +Anders Carlsson - bug fixes, porting work +Arvind Samptur - bug fixes +Damon Chaplin - bug fixes +Dave Bordoley - bug fixes, user interface improvement +David Emory Watson - hierarchical scripts menu, bug fixes +Dennis M. Cranston - bug fixes +Diego González - Code cleanups +Federico Mena Quintero +Frank Worsley - Transfer dialog improvements. +Havoc Pennington - bug fixes, advice +Jody Goldberg - porting work, bug fixes. +John Fleck - help browser work, cleanups +Jonathan Blandford - bug fixes, tree view help +Kjartan Maraas - bug fixes, i18n code +Laszlo Peter - build fixes +Michael Meeks - matecomponent fixes, porting work +Narayana Pattipati - bug fixes +Owen Taylor - bug fixes +Padraig O'Briain - bug fixes + +The following people who helped manage the bug database: + +Alex Duggan +Aschwin van der Woude +Benedikt Roth +Christian Schaller +Dave Bordoley +Dave Fallon +David Kennedy +Elijah Newren +Heath Harrelson +John Fleck +Luis Villa + +Caja 1.x +============ + +Alex Larsson - faster thumbnailing for JPEGs, bug fixes +Anders Carlsson - background drawing optimizations +Arik Devens - bug fixes +Bart Decrem - fixes to default news channels, gathering feedback, founding Eazel :-) +Brian Frank - fixes to default bookmarks, product marketing +Bud Tribble - Management, moral support, design help +Christopher Blizzard - mozilla component fixes +Christopher James Lahey - bug fixes +Cody Russell - bug fixes +Dan Mueth - documentation, help system design +David Emory Watson - hierarchical scripts menu +Don Melton - Management, moral support, design help +Eric Fischer - bug fixes +Fabrice Bellet - eog image view component work +Fatih Demir - bug fixes +Frank Belew - Mozilla component build fixes +Gregory S. Hayes - bug fixes +Havoc Pennington - desktop file support, start here menu, bug fixes, advice +JP Rosevear - bug fixes +Jason Leach - Solaris fix +Jens Finke - URL fix +Jim Garrison - bug fixes +Joe Shaw - installer code, bug fixes +John Fleck - help browser work +John Gotts - bug fix +Jon K Hellan - bug fixes +Jonathan Blandford - desktop file support, help system, bug fixes +Kenneth Christiansen - icons, internationalization tools +Kjartan Maraas - bug fixes, i18n code +Laszlo Kovacs - help system hacking +Martin Baulig - added PersistFile support +Matt Bissiri - list widget improvements +Michael Meeks - matecomponent fixes +Morten Welinder - check-fixme suggestions +Owen Taylor - bug fixes +Philip Langdale - help system galeon mode +Richard Boulton - build fixes +Richard Hult - bug reporting +Robert Brady - bug fixes +Shane Butlers - IDE in hardware view patch for showing IDE +Stanislav Brabec - bug fixes +Vera Horiuchi - documentation +Victor Lecha - build fixes +Yanko Kaneti - i18n fix +Yoann Vandoorselaere - performance work + +The following people who did significant amounts of testing: + +Albert Wang +Brad Moore +Brett Neely +Christian Rose +James Farwell +John Fleck +Jon Allen +Kenneth Christiansen +Kenny Graunke +Peter Foley +Tim Tan +Victor Lecha +Will LaShell + +As well as the following people who contributed translations: + +Abel Cheung +Adam Weinberger +Akagic Amila +Akira TAGOH +Alastair McKinstry +Ales Nyakhaychyk +Alessio Frusciante +Alexander Shopov +Alexander Winston +Almer S. Tigelaar +Andras Timar +Andraz Tori +Andreas Hyden +Andrew V. Samoilov +Ankit Patel +Arafat Medini +Artis Trops +Artur Flinta +Asmund Skjaeveland +Baris Cicek +Benedikt Roth +Carlos Perelló Marín +Changwoo Ryu +Christian Meyer +Christian Neumair +Christian Rose +Christophe Merlet +Christopher R. Gabriel +Dafydd Harries +Daniel Yacob +Danilo Segan +David Lodge +Dennis Smit +Dirk-Jan C. Binnema +Dmitry G. Mastrukov +Duarte Loreto +Dwayne Bailey +Egle Girinaite +Emese Kovacs +Eric Brayeur +Evandro Fernandes Giovanini +Fatih Demir +Francisco Javier F. Serrador +Francisco Javier Fernandez +Frank Arnold +Frederic Crozat +Funda Wang +Gareth Owen +Gaute Hvoslef Kvalnes +Gediminas Paulauskas +George Lebl +German Poo Caamano +Gil Osher +Gong Yi LIAO +Guntupalli Karunakar +Gustavo Maciel Dias Vieira +Gustavo Noronha Silva +Görkem Cetin +Hasbullah Bin Pit +He Qiangqiang +Hendrik Richter +Inaki Larranaga +Ivan Stojmirov +Jarkko Ranta +Jayaradna +Jean-Michel Ardantz +Jesús Bravo Álvarez +John C Barstow +Jordi Mallach - bug fixes +Jorge Carrasquilla Soares +KAMAGASAKO Masatoshi +Kang Jeong-Hee +Keld Simonsen +Kenneth Christiansen +Kim Schulz +Kjartan Maraas +Kjenneth Christiansen +Kostas Papadimas +Laszlo Dvornik +Laurent Dhima +Leonid Kanter +Luca Ferretti +Mantas Kriauciunas +Manuel Borchers +Manuel de Vega Barreiro +Marcel Telka +Marius Andreiana +Martin Norbäck +Martin Willemoes Hansen +Mathieu van Woerkom +Matthias Warkus +Maxim Dziumanenko +Meelad Zakaria +Mendel Mobach +Metin Amiroff +Michal Bukovjan +Miloslav Trmac +Mohammad DAMT +Mugurel Tudor +Naba Kumar +Nam SungHyun +Nikos Charonitakis +Ole Laursen +Pablo G. del Campo +Pablo Gonzalo del Campo +Pablo Saratxaga +Paisa Seeluangsawat +Paul Duffy +Pauli Virtanen +Pawan Chitrakar +Peteris Krisjanis +Priit Laes +Raphael Higino +Rhys Jones +Richard Hult +Robert Brady +Robert Sedak +Roozbeh Pournader +Ross Golder +Roy-Magne Mo +Runa Bhattacharjee +Sami Pesonen +Samuel Jon Gunnarsson +Sanlig Badral +Satoru Sato +Sayamindu Dasgupta +Sebastien Bacher +Simos Xenitellis +Stanislav Brabec +Stanislav Visnovsky +Szabolcs Ban +Takeshi AIHANA +Takuo Kitame +Taneem Ahmed +Telsa Gwynne +Tommi Vainikainen +Töivo Leedjärv +Valek Filippov +Valentín Trilles +Vasif Ismailoglu MD +Veeravanallore Madhavan +Vincent van Adrighem +Vlad Harchev +Wang Jian +Young-ho, Cha +Yukihiro Nakai +Yuri Syrota +Zbigniew Chyla +Zygimantas Berucka diff --git a/TODO b/TODO new file mode 100644 index 00000000..f8c02181 --- /dev/null +++ b/TODO @@ -0,0 +1,19 @@ +For tasks outside the porting effort, we track them as bugs in +http://bugzilla.gnome.org. For the porting effort, please let +darin@bentspoon.com know what you are working on. + +- Visit all the MATE2_CONVERSION_COMPLETE and fix each issue + (details forthcoming) + +- Visit all the destroy and move things into finalize or dispose + and make them callable twice as appropriate. +- Change things that use destroy handlers to use weak references + instead. + +- Figure out why we get NULL font problems in Pango when the progress + dialog comes up. + +- Split themes into a separate tarball/package? + +- Add mnemonics for all preferences, so you can use the keyboard to + drive the preferences dialog. diff --git a/acconfig.h b/acconfig.h new file mode 100644 index 00000000..86dbe12d --- /dev/null +++ b/acconfig.h @@ -0,0 +1,27 @@ +#undef ENABLE_INSTALLER +#undef ENABLE_NLS +#undef ENABLE_PROFILER +#undef GETTEXT_PACKAGE +#undef HAVE_CATGETS +#undef HAVE_GETTEXT +#undef HAVE_LC_MESSAGES +#undef HAVE_LIBBZ2 +#undef HAVE_LIBJPEG +#undef HAVE_MEDUSA +#undef HAVE_STPCPY +#undef bzclose +#undef bzCompress +#undef bzCompressInit +#undef bzDecompress +#undef bzDecompressInit +#undef bzdopen +#undef bzerror +#undef bzflush +#undef bzopen +#undef bzread +#undef bzwrite +#define HAVE_GTK_MULTIHEAD /* needed for egg-screen-exec functions */ +#undef HAVE_STARTUP_NOTIFICATION +#undef HAVE_EXIF +#undef HAVE_OLD_EXIF +#undef HAVE_RENDER diff --git a/aclocal.m4 b/aclocal.m4 new file mode 100644 index 00000000..c600402b --- /dev/null +++ b/aclocal.m4 @@ -0,0 +1,1812 @@ +# generated automatically by aclocal 1.11.1 -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.68],, +[m4_warning([this file was generated for autoconf 2.68. +You have another version of autoconf. It may work, but is not guaranteed to. +If you have problems, you may need to regenerate the build system entirely. +To do so, use the procedure documented by the package, typically `autoreconf'.])]) + +# Copyright (C) 1995-2002 Free Software Foundation, Inc. +# Copyright (C) 2001-2003,2004 Red Hat, Inc. +# +# This file is free software, distributed under the terms of the GNU +# General Public License. As a special exception to the GNU General +# Public License, this file may be distributed as part of a program +# that contains a configuration script generated by Autoconf, under +# the same distribution terms as the rest of that program. +# +# This file can be copied and used freely without restrictions. It can +# be used in projects which are not available under the GNU Public License +# but which still want to provide support for the GNU gettext functionality. +# +# Macro to add for using GNU gettext. +# Ulrich Drepper , 1995, 1996 +# +# Modified to never use included libintl. +# Owen Taylor , 12/15/1998 +# +# Major rework to remove unused code +# Owen Taylor , 12/11/2002 +# +# Added better handling of ALL_LINGUAS from GNU gettext version +# written by Bruno Haible, Owen Taylor 5/30/3002 +# +# Modified to require ngettext +# Matthias Clasen 08/06/2004 +# +# We need this here as well, since someone might use autoconf-2.5x +# to configure GLib then an older version to configure a package +# using AM_GLIB_GNU_GETTEXT +AC_PREREQ(2.53) + +dnl +dnl We go to great lengths to make sure that aclocal won't +dnl try to pull in the installed version of these macros +dnl when running aclocal in the glib directory. +dnl +m4_copy([AC_DEFUN],[glib_DEFUN]) +m4_copy([AC_REQUIRE],[glib_REQUIRE]) +dnl +dnl At the end, if we're not within glib, we'll define the public +dnl definitions in terms of our private definitions. +dnl + +# GLIB_LC_MESSAGES +#-------------------- +glib_DEFUN([GLIB_LC_MESSAGES], + [AC_CHECK_HEADERS([locale.h]) + if test $ac_cv_header_locale_h = yes; then + AC_CACHE_CHECK([for LC_MESSAGES], am_cv_val_LC_MESSAGES, + [AC_TRY_LINK([#include ], [return LC_MESSAGES], + am_cv_val_LC_MESSAGES=yes, am_cv_val_LC_MESSAGES=no)]) + if test $am_cv_val_LC_MESSAGES = yes; then + AC_DEFINE(HAVE_LC_MESSAGES, 1, + [Define if your file defines LC_MESSAGES.]) + fi + fi]) + +# GLIB_PATH_PROG_WITH_TEST +#---------------------------- +dnl GLIB_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR, +dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]]) +glib_DEFUN([GLIB_PATH_PROG_WITH_TEST], +[# Extract the first word of "$2", so it can be a program name with args. +set dummy $2; ac_word=[$]2 +AC_MSG_CHECKING([for $ac_word]) +AC_CACHE_VAL(ac_cv_path_$1, +[case "[$]$1" in + /*) + ac_cv_path_$1="[$]$1" # Let the user override the test with a path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in ifelse([$5], , $PATH, [$5]); do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if [$3]; then + ac_cv_path_$1="$ac_dir/$ac_word" + break + fi + fi + done + IFS="$ac_save_ifs" +dnl If no 4th arg is given, leave the cache variable unset, +dnl so AC_PATH_PROGS will keep looking. +ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4" +])dnl + ;; +esac])dnl +$1="$ac_cv_path_$1" +if test ifelse([$4], , [-n "[$]$1"], ["[$]$1" != "$4"]); then + AC_MSG_RESULT([$]$1) +else + AC_MSG_RESULT(no) +fi +AC_SUBST($1)dnl +]) + +# GLIB_WITH_NLS +#----------------- +glib_DEFUN([GLIB_WITH_NLS], + dnl NLS is obligatory + [USE_NLS=yes + AC_SUBST(USE_NLS) + + gt_cv_have_gettext=no + + CATOBJEXT=NONE + XGETTEXT=: + INTLLIBS= + + AC_CHECK_HEADER(libintl.h, + [gt_cv_func_dgettext_libintl="no" + libintl_extra_libs="" + + # + # First check in libc + # + AC_CACHE_CHECK([for ngettext in libc], gt_cv_func_ngettext_libc, + [AC_TRY_LINK([ +#include +], + [return !ngettext ("","", 1)], + gt_cv_func_ngettext_libc=yes, + gt_cv_func_ngettext_libc=no) + ]) + + if test "$gt_cv_func_ngettext_libc" = "yes" ; then + AC_CACHE_CHECK([for dgettext in libc], gt_cv_func_dgettext_libc, + [AC_TRY_LINK([ +#include +], + [return !dgettext ("","")], + gt_cv_func_dgettext_libc=yes, + gt_cv_func_dgettext_libc=no) + ]) + fi + + if test "$gt_cv_func_ngettext_libc" = "yes" ; then + AC_CHECK_FUNCS(bind_textdomain_codeset) + fi + + # + # If we don't have everything we want, check in libintl + # + if test "$gt_cv_func_dgettext_libc" != "yes" \ + || test "$gt_cv_func_ngettext_libc" != "yes" \ + || test "$ac_cv_func_bind_textdomain_codeset" != "yes" ; then + + AC_CHECK_LIB(intl, bindtextdomain, + [AC_CHECK_LIB(intl, ngettext, + [AC_CHECK_LIB(intl, dgettext, + gt_cv_func_dgettext_libintl=yes)])]) + + if test "$gt_cv_func_dgettext_libintl" != "yes" ; then + AC_MSG_CHECKING([if -liconv is needed to use gettext]) + AC_MSG_RESULT([]) + AC_CHECK_LIB(intl, ngettext, + [AC_CHECK_LIB(intl, dcgettext, + [gt_cv_func_dgettext_libintl=yes + libintl_extra_libs=-liconv], + :,-liconv)], + :,-liconv) + fi + + # + # If we found libintl, then check in it for bind_textdomain_codeset(); + # we'll prefer libc if neither have bind_textdomain_codeset(), + # and both have dgettext and ngettext + # + if test "$gt_cv_func_dgettext_libintl" = "yes" ; then + glib_save_LIBS="$LIBS" + LIBS="$LIBS -lintl $libintl_extra_libs" + unset ac_cv_func_bind_textdomain_codeset + AC_CHECK_FUNCS(bind_textdomain_codeset) + LIBS="$glib_save_LIBS" + + if test "$ac_cv_func_bind_textdomain_codeset" = "yes" ; then + gt_cv_func_dgettext_libc=no + else + if test "$gt_cv_func_dgettext_libc" = "yes" \ + && test "$gt_cv_func_ngettext_libc" = "yes"; then + gt_cv_func_dgettext_libintl=no + fi + fi + fi + fi + + if test "$gt_cv_func_dgettext_libc" = "yes" \ + || test "$gt_cv_func_dgettext_libintl" = "yes"; then + gt_cv_have_gettext=yes + fi + + if test "$gt_cv_func_dgettext_libintl" = "yes"; then + INTLLIBS="-lintl $libintl_extra_libs" + fi + + if test "$gt_cv_have_gettext" = "yes"; then + AC_DEFINE(HAVE_GETTEXT,1, + [Define if the GNU gettext() function is already present or preinstalled.]) + GLIB_PATH_PROG_WITH_TEST(MSGFMT, msgfmt, + [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], no)dnl + if test "$MSGFMT" != "no"; then + glib_save_LIBS="$LIBS" + LIBS="$LIBS $INTLLIBS" + AC_CHECK_FUNCS(dcgettext) + MSGFMT_OPTS= + AC_MSG_CHECKING([if msgfmt accepts -c]) + GLIB_RUN_PROG([$MSGFMT -c -o /dev/null],[ +msgid "" +msgstr "" +"Content-Type: text/plain; charset=UTF-8\n" +"Project-Id-Version: test 1.0\n" +"PO-Revision-Date: 2007-02-15 12:01+0100\n" +"Last-Translator: test \n" +"Language-Team: C \n" +"MIME-Version: 1.0\n" +"Content-Transfer-Encoding: 8bit\n" +], [MSGFMT_OPTS=-c; AC_MSG_RESULT([yes])], [AC_MSG_RESULT([no])]) + AC_SUBST(MSGFMT_OPTS) + AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT) + GLIB_PATH_PROG_WITH_TEST(XGETTEXT, xgettext, + [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :) + AC_TRY_LINK(, [extern int _nl_msg_cat_cntr; + return _nl_msg_cat_cntr], + [CATOBJEXT=.gmo + DATADIRNAME=share], + [case $host in + *-*-solaris*) + dnl On Solaris, if bind_textdomain_codeset is in libc, + dnl GNU format message catalog is always supported, + dnl since both are added to the libc all together. + dnl Hence, we'd like to go with DATADIRNAME=share and + dnl and CATOBJEXT=.gmo in this case. + AC_CHECK_FUNC(bind_textdomain_codeset, + [CATOBJEXT=.gmo + DATADIRNAME=share], + [CATOBJEXT=.mo + DATADIRNAME=lib]) + ;; + *-*-openbsd*) + CATOBJEXT=.mo + DATADIRNAME=share + ;; + *) + CATOBJEXT=.mo + DATADIRNAME=lib + ;; + esac]) + LIBS="$glib_save_LIBS" + INSTOBJEXT=.mo + else + gt_cv_have_gettext=no + fi + fi + ]) + + if test "$gt_cv_have_gettext" = "yes" ; then + AC_DEFINE(ENABLE_NLS, 1, + [always defined to indicate that i18n is enabled]) + fi + + dnl Test whether we really found GNU xgettext. + if test "$XGETTEXT" != ":"; then + dnl If it is not GNU xgettext we define it as : so that the + dnl Makefiles still can work. + if $XGETTEXT --omit-header /dev/null 2> /dev/null; then + : ; + else + AC_MSG_RESULT( + [found xgettext program is not GNU xgettext; ignore it]) + XGETTEXT=":" + fi + fi + + # We need to process the po/ directory. + POSUB=po + + AC_OUTPUT_COMMANDS( + [case "$CONFIG_FILES" in *po/Makefile.in*) + sed -e "/POTFILES =/r po/POTFILES" po/Makefile.in > po/Makefile + esac]) + + dnl These rules are solely for the distribution goal. While doing this + dnl we only have to keep exactly one list of the available catalogs + dnl in configure.ac. + for lang in $ALL_LINGUAS; do + GMOFILES="$GMOFILES $lang.gmo" + POFILES="$POFILES $lang.po" + done + + dnl Make all variables we use known to autoconf. + AC_SUBST(CATALOGS) + AC_SUBST(CATOBJEXT) + AC_SUBST(DATADIRNAME) + AC_SUBST(GMOFILES) + AC_SUBST(INSTOBJEXT) + AC_SUBST(INTLLIBS) + AC_SUBST(PO_IN_DATADIR_TRUE) + AC_SUBST(PO_IN_DATADIR_FALSE) + AC_SUBST(POFILES) + AC_SUBST(POSUB) + ]) + +# AM_GLIB_GNU_GETTEXT +# ------------------- +# Do checks necessary for use of gettext. If a suitable implementation +# of gettext is found in either in libintl or in the C library, +# it will set INTLLIBS to the libraries needed for use of gettext +# and AC_DEFINE() HAVE_GETTEXT and ENABLE_NLS. (The shell variable +# gt_cv_have_gettext will be set to "yes".) It will also call AC_SUBST() +# on various variables needed by the Makefile.in.in installed by +# glib-gettextize. +dnl +glib_DEFUN([GLIB_GNU_GETTEXT], + [AC_REQUIRE([AC_PROG_CC])dnl + AC_REQUIRE([AC_HEADER_STDC])dnl + + GLIB_LC_MESSAGES + GLIB_WITH_NLS + + if test "$gt_cv_have_gettext" = "yes"; then + if test "x$ALL_LINGUAS" = "x"; then + LINGUAS= + else + AC_MSG_CHECKING(for catalogs to be installed) + NEW_LINGUAS= + for presentlang in $ALL_LINGUAS; do + useit=no + if test "%UNSET%" != "${LINGUAS-%UNSET%}"; then + desiredlanguages="$LINGUAS" + else + desiredlanguages="$ALL_LINGUAS" + fi + for desiredlang in $desiredlanguages; do + # Use the presentlang catalog if desiredlang is + # a. equal to presentlang, or + # b. a variant of presentlang (because in this case, + # presentlang can be used as a fallback for messages + # which are not translated in the desiredlang catalog). + case "$desiredlang" in + "$presentlang"*) useit=yes;; + esac + done + if test $useit = yes; then + NEW_LINGUAS="$NEW_LINGUAS $presentlang" + fi + done + LINGUAS=$NEW_LINGUAS + AC_MSG_RESULT($LINGUAS) + fi + + dnl Construct list of names of catalog files to be constructed. + if test -n "$LINGUAS"; then + for lang in $LINGUAS; do CATALOGS="$CATALOGS $lang$CATOBJEXT"; done + fi + fi + + dnl If the AC_CONFIG_AUX_DIR macro for autoconf is used we possibly + dnl find the mkinstalldirs script in another subdir but ($top_srcdir). + dnl Try to locate is. + MKINSTALLDIRS= + if test -n "$ac_aux_dir"; then + MKINSTALLDIRS="$ac_aux_dir/mkinstalldirs" + fi + if test -z "$MKINSTALLDIRS"; then + MKINSTALLDIRS="\$(top_srcdir)/mkinstalldirs" + fi + AC_SUBST(MKINSTALLDIRS) + + dnl Generate list of files to be processed by xgettext which will + dnl be included in po/Makefile. + test -d po || mkdir po + if test "x$srcdir" != "x."; then + if test "x`echo $srcdir | sed 's@/.*@@'`" = "x"; then + posrcprefix="$srcdir/" + else + posrcprefix="../$srcdir/" + fi + else + posrcprefix="../" + fi + rm -f po/POTFILES + sed -e "/^#/d" -e "/^\$/d" -e "s,.*, $posrcprefix& \\\\," -e "\$s/\(.*\) \\\\/\1/" \ + < $srcdir/po/POTFILES.in > po/POTFILES + ]) + +# AM_GLIB_DEFINE_LOCALEDIR(VARIABLE) +# ------------------------------- +# Define VARIABLE to the location where catalog files will +# be installed by po/Makefile. +glib_DEFUN([GLIB_DEFINE_LOCALEDIR], +[glib_REQUIRE([GLIB_GNU_GETTEXT])dnl +glib_save_prefix="$prefix" +glib_save_exec_prefix="$exec_prefix" +glib_save_datarootdir="$datarootdir" +test "x$prefix" = xNONE && prefix=$ac_default_prefix +test "x$exec_prefix" = xNONE && exec_prefix=$prefix +datarootdir=`eval echo "${datarootdir}"` +if test "x$CATOBJEXT" = "x.mo" ; then + localedir=`eval echo "${libdir}/locale"` +else + localedir=`eval echo "${datadir}/locale"` +fi +prefix="$glib_save_prefix" +exec_prefix="$glib_save_exec_prefix" +datarootdir="$glib_save_datarootdir" +AC_DEFINE_UNQUOTED($1, "$localedir", + [Define the location where the catalogs will be installed]) +]) + +dnl +dnl Now the definitions that aclocal will find +dnl +ifdef(glib_configure_ac,[],[ +AC_DEFUN([AM_GLIB_GNU_GETTEXT],[GLIB_GNU_GETTEXT($@)]) +AC_DEFUN([AM_GLIB_DEFINE_LOCALEDIR],[GLIB_DEFINE_LOCALEDIR($@)]) +])dnl + +# GLIB_RUN_PROG(PROGRAM, TEST-FILE, [ACTION-IF-PASS], [ACTION-IF-FAIL]) +# +# Create a temporary file with TEST-FILE as its contents and pass the +# file name to PROGRAM. Perform ACTION-IF-PASS if PROGRAM exits with +# 0 and perform ACTION-IF-FAIL for any other exit status. +AC_DEFUN([GLIB_RUN_PROG], +[cat >conftest.foo <<_ACEOF +$2 +_ACEOF +if AC_RUN_LOG([$1 conftest.foo]); then + m4_ifval([$3], [$3], [:]) +m4_ifvaln([$4], [else $4])dnl +echo "$as_me: failed input was:" >&AS_MESSAGE_LOG_FD +sed 's/^/| /' conftest.foo >&AS_MESSAGE_LOG_FD +fi]) + + +dnl -*- mode: autoconf -*- +dnl Copyright 2009 Johan Dahlin +dnl +dnl This file is free software; the author(s) gives unlimited +dnl permission to copy and/or distribute it, with or without +dnl modifications, as long as this notice is preserved. +dnl + +# serial 1 + +m4_define([_GOBJECT_INTROSPECTION_CHECK_INTERNAL], +[ + AC_BEFORE([AC_PROG_LIBTOOL],[$0])dnl setup libtool first + AC_BEFORE([AM_PROG_LIBTOOL],[$0])dnl setup libtool first + AC_BEFORE([LT_INIT],[$0])dnl setup libtool first + + dnl enable/disable introspection + m4_if([$2], [require], + [dnl + enable_introspection=yes + ],[dnl + AC_ARG_ENABLE(introspection, + AS_HELP_STRING([--enable-introspection[=@<:@no/auto/yes@:>@]], + [Enable introspection for this build]),, + [enable_introspection=auto]) + ])dnl + + AC_MSG_CHECKING([for gobject-introspection]) + + dnl presence/version checking + AS_CASE([$enable_introspection], + [no], [dnl + found_introspection="no (disabled, use --enable-introspection to enable)" + ],dnl + [yes],[dnl + PKG_CHECK_EXISTS([gobject-introspection-1.0],, + AC_MSG_ERROR([gobject-introspection-1.0 is not installed])) + PKG_CHECK_EXISTS([gobject-introspection-1.0 >= $1], + found_introspection=yes, + AC_MSG_ERROR([You need to have gobject-introspection >= $1 installed to build AC_PACKAGE_NAME])) + ],dnl + [auto],[dnl + PKG_CHECK_EXISTS([gobject-introspection-1.0 >= $1], found_introspection=yes, found_introspection=no) + ],dnl + [dnl + AC_MSG_ERROR([invalid argument passed to --enable-introspection, should be one of @<:@no/auto/yes@:>@]) + ])dnl + + AC_MSG_RESULT([$found_introspection]) + + INTROSPECTION_SCANNER= + INTROSPECTION_COMPILER= + INTROSPECTION_GENERATE= + INTROSPECTION_GIRDIR= + INTROSPECTION_TYPELIBDIR= + if test "x$found_introspection" = "xyes"; then + INTROSPECTION_SCANNER=`$PKG_CONFIG --variable=g_ir_scanner gobject-introspection-1.0` + INTROSPECTION_COMPILER=`$PKG_CONFIG --variable=g_ir_compiler gobject-introspection-1.0` + INTROSPECTION_GENERATE=`$PKG_CONFIG --variable=g_ir_generate gobject-introspection-1.0` + INTROSPECTION_GIRDIR=`$PKG_CONFIG --variable=girdir gobject-introspection-1.0` + INTROSPECTION_TYPELIBDIR="$($PKG_CONFIG --variable=typelibdir gobject-introspection-1.0)" + INTROSPECTION_CFLAGS=`$PKG_CONFIG --cflags gobject-introspection-1.0` + INTROSPECTION_LIBS=`$PKG_CONFIG --libs gobject-introspection-1.0` + INTROSPECTION_MAKEFILE=`$PKG_CONFIG --variable=datadir gobject-introspection-1.0`/gobject-introspection-1.0/Makefile.introspection + fi + AC_SUBST(INTROSPECTION_SCANNER) + AC_SUBST(INTROSPECTION_COMPILER) + AC_SUBST(INTROSPECTION_GENERATE) + AC_SUBST(INTROSPECTION_GIRDIR) + AC_SUBST(INTROSPECTION_TYPELIBDIR) + AC_SUBST(INTROSPECTION_CFLAGS) + AC_SUBST(INTROSPECTION_LIBS) + AC_SUBST(INTROSPECTION_MAKEFILE) + + AM_CONDITIONAL(HAVE_INTROSPECTION, test "x$found_introspection" = "xyes") +]) + + +dnl Usage: +dnl GOBJECT_INTROSPECTION_CHECK([minimum-g-i-version]) + +AC_DEFUN([GOBJECT_INTROSPECTION_CHECK], +[ + _GOBJECT_INTROSPECTION_CHECK_INTERNAL([$1]) +]) + +dnl Usage: +dnl GOBJECT_INTROSPECTION_REQUIRE([minimum-g-i-version]) + + +AC_DEFUN([GOBJECT_INTROSPECTION_REQUIRE], +[ + _GOBJECT_INTROSPECTION_CHECK_INTERNAL([$1], [require]) +]) + +dnl AM_MATECONF_SOURCE_2 +dnl Defines MATECONF_SCHEMA_CONFIG_SOURCE which is where you should install schemas +dnl (i.e. pass to mateconftool-2 +dnl Defines MATECONF_SCHEMA_FILE_DIR which is a filesystem directory where +dnl you should install foo.schemas files +dnl + +AC_DEFUN([AM_MATECONF_SOURCE_2], +[ + if test "x$MATECONF_SCHEMA_INSTALL_SOURCE" = "x"; then + MATECONF_SCHEMA_CONFIG_SOURCE=`mateconftool-2 --get-default-source` + else + MATECONF_SCHEMA_CONFIG_SOURCE=$MATECONF_SCHEMA_INSTALL_SOURCE + fi + + AC_ARG_WITH([mateconf-source], + AC_HELP_STRING([--with-mateconf-source=sourceaddress], + [Config database for installing schema files.]), + [MATECONF_SCHEMA_CONFIG_SOURCE="$withval"],) + + AC_SUBST(MATECONF_SCHEMA_CONFIG_SOURCE) + AC_MSG_RESULT([Using config source $MATECONF_SCHEMA_CONFIG_SOURCE for schema installation]) + + if test "x$MATECONF_SCHEMA_FILE_DIR" = "x"; then + MATECONF_SCHEMA_FILE_DIR='$(sysconfdir)/mateconf/schemas' + fi + + AC_ARG_WITH([mateconf-schema-file-dir], + AC_HELP_STRING([--with-mateconf-schema-file-dir=dir], + [Directory for installing schema files.]), + [MATECONF_SCHEMA_FILE_DIR="$withval"],) + + AC_SUBST(MATECONF_SCHEMA_FILE_DIR) + AC_MSG_RESULT([Using $MATECONF_SCHEMA_FILE_DIR as install directory for schema files]) + + AC_ARG_ENABLE(schemas-install, + AC_HELP_STRING([--disable-schemas-install], + [Disable the schemas installation]), + [case ${enableval} in + yes|no) ;; + *) AC_MSG_ERROR([bad value ${enableval} for --enable-schemas-install]) ;; + esac]) + AM_CONDITIONAL([MATECONF_SCHEMAS_INSTALL], [test "$enable_schemas_install" != no]) +]) + +# nls.m4 serial 5 (gettext-0.18) +dnl Copyright (C) 1995-2003, 2005-2006, 2008-2010 Free Software Foundation, +dnl Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. +dnl +dnl This file can can be used in projects which are not available under +dnl the GNU General Public License or the GNU Library General Public +dnl License but which still want to provide support for the GNU gettext +dnl functionality. +dnl Please note that the actual code of the GNU gettext library is covered +dnl by the GNU Library General Public License, and the rest of the GNU +dnl gettext package package is covered by the GNU General Public License. +dnl They are *not* in the public domain. + +dnl Authors: +dnl Ulrich Drepper , 1995-2000. +dnl Bruno Haible , 2000-2003. + +AC_PREREQ([2.50]) + +AC_DEFUN([AM_NLS], +[ + AC_MSG_CHECKING([whether NLS is requested]) + dnl Default is enabled NLS + AC_ARG_ENABLE([nls], + [ --disable-nls do not use Native Language Support], + USE_NLS=$enableval, USE_NLS=yes) + AC_MSG_RESULT([$USE_NLS]) + AC_SUBST([USE_NLS]) +]) + +# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- +# serial 1 (pkg-config-0.24) +# +# Copyright © 2004 Scott James Remnant . +# +# 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 2 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, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# PKG_PROG_PKG_CONFIG([MIN-VERSION]) +# ---------------------------------- +AC_DEFUN([PKG_PROG_PKG_CONFIG], +[m4_pattern_forbid([^_?PKG_[A-Z_]+$]) +m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$]) +m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$]) +AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility]) +AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path]) +AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path]) + +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then + AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) +fi +if test -n "$PKG_CONFIG"; then + _pkg_min_version=m4_default([$1], [0.9.0]) + AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + PKG_CONFIG="" + fi +fi[]dnl +])# PKG_PROG_PKG_CONFIG + +# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +# +# Check to see whether a particular set of modules exists. Similar +# to PKG_CHECK_MODULES(), but does not set variables or print errors. +# +# Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) +# only at the first occurence in configure.ac, so if the first place +# it's called might be skipped (such as if it is within an "if", you +# have to call PKG_CHECK_EXISTS manually +# -------------------------------------------------------------- +AC_DEFUN([PKG_CHECK_EXISTS], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +if test -n "$PKG_CONFIG" && \ + AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then + m4_default([$2], [:]) +m4_ifvaln([$3], [else + $3])dnl +fi]) + +# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) +# --------------------------------------------- +m4_define([_PKG_CONFIG], +[if test -n "$$1"; then + pkg_cv_[]$1="$$1" + elif test -n "$PKG_CONFIG"; then + PKG_CHECK_EXISTS([$3], + [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes ], + [pkg_failed=yes]) + else + pkg_failed=untried +fi[]dnl +])# _PKG_CONFIG + +# _PKG_SHORT_ERRORS_SUPPORTED +# ----------------------------- +AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG]) +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi[]dnl +])# _PKG_SHORT_ERRORS_SUPPORTED + + +# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], +# [ACTION-IF-NOT-FOUND]) +# +# +# Note that if there is a possibility the first call to +# PKG_CHECK_MODULES might not happen, you should be sure to include an +# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac +# +# +# -------------------------------------------------------------- +AC_DEFUN([PKG_CHECK_MODULES], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl +AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl + +pkg_failed=no +AC_MSG_CHECKING([for $1]) + +_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) +_PKG_CONFIG([$1][_LIBS], [libs], [$2]) + +m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS +and $1[]_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details.]) + +if test $pkg_failed = yes; then + AC_MSG_RESULT([no]) + _PKG_SHORT_ERRORS_SUPPORTED + if test $_pkg_short_errors_supported = yes; then + $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1` + else + $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD + + m4_default([$4], [AC_MSG_ERROR( +[Package requirements ($2) were not met: + +$$1_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +_PKG_TEXT])[]dnl + ]) +elif test $pkg_failed = untried; then + AC_MSG_RESULT([no]) + m4_default([$4], [AC_MSG_FAILURE( +[The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +_PKG_TEXT + +To get pkg-config, see .])[]dnl + ]) +else + $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS + $1[]_LIBS=$pkg_cv_[]$1[]_LIBS + AC_MSG_RESULT([yes]) + $3 +fi[]dnl +])# PKG_CHECK_MODULES + +# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_AUTOMAKE_VERSION(VERSION) +# ---------------------------- +# Automake X.Y traces this macro to ensure aclocal.m4 has been +# generated from the m4 files accompanying Automake X.Y. +# (This private macro should not be called outside this file.) +AC_DEFUN([AM_AUTOMAKE_VERSION], +[am__api_version='1.11' +dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to +dnl require some minimum version. Point them to the right macro. +m4_if([$1], [1.11.1], [], + [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl +]) + +# _AM_AUTOCONF_VERSION(VERSION) +# ----------------------------- +# aclocal traces this macro to find the Autoconf version. +# This is a private macro too. Using m4_define simplifies +# the logic in aclocal, which can simply ignore this definition. +m4_define([_AM_AUTOCONF_VERSION], []) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. +# This function is AC_REQUIREd by AM_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], +[AM_AUTOMAKE_VERSION([1.11.1])dnl +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) + +# AM_AUX_DIR_EXPAND -*- Autoconf -*- + +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets +# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to +# `$srcdir', `$srcdir/..', or `$srcdir/../..'. +# +# Of course, Automake must honor this variable whenever it calls a +# tool from the auxiliary directory. The problem is that $srcdir (and +# therefore $ac_aux_dir as well) can be either absolute or relative, +# depending on how configure is run. This is pretty annoying, since +# it makes $ac_aux_dir quite unusable in subdirectories: in the top +# source directory, any form will work fine, but in subdirectories a +# relative path needs to be adjusted first. +# +# $ac_aux_dir/missing +# fails when called from a subdirectory if $ac_aux_dir is relative +# $top_srcdir/$ac_aux_dir/missing +# fails if $ac_aux_dir is absolute, +# fails when called from a subdirectory in a VPATH build with +# a relative $ac_aux_dir +# +# The reason of the latter failure is that $top_srcdir and $ac_aux_dir +# are both prefixed by $srcdir. In an in-source build this is usually +# harmless because $srcdir is `.', but things will broke when you +# start a VPATH build or use an absolute $srcdir. +# +# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, +# iff we strip the leading $srcdir from $ac_aux_dir. That would be: +# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` +# and then we would define $MISSING as +# MISSING="\${SHELL} $am_aux_dir/missing" +# This will work as long as MISSING is not called from configure, because +# unfortunately $(top_srcdir) has no meaning in configure. +# However there are other variables, like CC, which are often used in +# configure, and could therefore not use this "fixed" $ac_aux_dir. +# +# Another solution, used here, is to always expand $ac_aux_dir to an +# absolute PATH. The drawback is that using absolute paths prevent a +# configured tree to be moved without reconfiguration. + +AC_DEFUN([AM_AUX_DIR_EXPAND], +[dnl Rely on autoconf to set up CDPATH properly. +AC_PREREQ([2.50])dnl +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 9 + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[AC_PREREQ(2.52)dnl + ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE])dnl +AC_SUBST([$1_FALSE])dnl +_AM_SUBST_NOTMAKE([$1_TRUE])dnl +_AM_SUBST_NOTMAKE([$1_FALSE])dnl +m4_define([_AM_COND_VALUE_$1], [$2])dnl +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([[conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]]) +fi])]) + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 10 + +# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be +# written in clear, in which case automake, when reading aclocal.m4, +# will think it sees a *use*, and therefore will trigger all it's +# C support machinery. Also note that it means that autoscan, seeing +# CC etc. in the Makefile, will ask for an AC_PROG_CC use... + + +# _AM_DEPENDENCIES(NAME) +# ---------------------- +# See how the compiler implements dependency checking. +# NAME is "CC", "CXX", "GCJ", or "OBJC". +# We try a few techniques and use that to set a single cache variable. +# +# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was +# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular +# dependency, and given that the user is not expected to run this macro, +# just rely on AC_PROG_CC. +AC_DEFUN([_AM_DEPENDENCIES], +[AC_REQUIRE([AM_SET_DEPDIR])dnl +AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl +AC_REQUIRE([AM_MAKE_INCLUDE])dnl +AC_REQUIRE([AM_DEP_TRACK])dnl + +ifelse([$1], CC, [depcc="$CC" am_compiler_list=], + [$1], CXX, [depcc="$CXX" am_compiler_list=], + [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], UPC, [depcc="$UPC" am_compiler_list=], + [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) + +AC_CACHE_CHECK([dependency style of $depcc], + [am_cv_$1_dependencies_compiler_type], +[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_$1_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` + fi + am__universal=false + m4_case([$1], [CC], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac], + [CXX], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac]) + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvisualcpp | msvcmsys) + # This compiler won't grok `-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_$1_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_$1_dependencies_compiler_type=none +fi +]) +AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +AM_CONDITIONAL([am__fastdep$1], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) +]) + + +# AM_SET_DEPDIR +# ------------- +# Choose a directory name for dependency files. +# This macro is AC_REQUIREd in _AM_DEPENDENCIES +AC_DEFUN([AM_SET_DEPDIR], +[AC_REQUIRE([AM_SET_LEADING_DOT])dnl +AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl +]) + + +# AM_DEP_TRACK +# ------------ +AC_DEFUN([AM_DEP_TRACK], +[AC_ARG_ENABLE(dependency-tracking, +[ --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors]) +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' +fi +AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +AC_SUBST([AMDEPBACKSLASH])dnl +_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl +]) + +# Generate code to set up dependency tracking. -*- Autoconf -*- + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +#serial 5 + +# _AM_OUTPUT_DEPENDENCY_COMMANDS +# ------------------------------ +AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +[{ + # Autoconf 2.62 quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`AS_DIRNAME("$mf")` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`AS_DIRNAME(["$file"])` + AS_MKDIR_P([$dirpart/$fdir]) + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} +])# _AM_OUTPUT_DEPENDENCY_COMMANDS + + +# AM_OUTPUT_DEPENDENCY_COMMANDS +# ----------------------------- +# This macro should only be invoked once -- use via AC_REQUIRE. +# +# This code is only required when automatic dependency tracking +# is enabled. FIXME. This creates each `.P' file that we will +# need in order to bootstrap the dependency handling code. +AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], +[AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], + [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) +]) + +# Do all the work for Automake. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005, 2006, 2008, 2009 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 16 + +# This macro actually does too much. Some checks are only needed if +# your package does certain things. But this isn't really a big deal. + +# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +# AM_INIT_AUTOMAKE([OPTIONS]) +# ----------------------------------------------- +# The call with PACKAGE and VERSION arguments is the old style +# call (pre autoconf-2.50), which is being phased out. PACKAGE +# and VERSION should now be passed to AC_INIT and removed from +# the call to AM_INIT_AUTOMAKE. +# We support both call styles for the transition. After +# the next Automake release, Autoconf can make the AC_INIT +# arguments mandatory, and then we can depend on a new Autoconf +# release and drop the old call support. +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_PREREQ([2.62])dnl +dnl Autoconf wants to disallow AM_ names. We explicitly allow +dnl the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL])dnl +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl +dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. +m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,, + [m4_fatal([AC_INIT should be called with package and version arguments])])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl + AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) + AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) +AM_MISSING_PROG(AUTOCONF, autoconf) +AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) +AM_MISSING_PROG(AUTOHEADER, autoheader) +AM_MISSING_PROG(MAKEINFO, makeinfo) +AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl +AC_REQUIRE([AM_PROG_MKDIR_P])dnl +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl +AC_REQUIRE([AM_SET_LEADING_DOT])dnl +_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], + [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES(CC)], + [define([AC_PROG_CC], + defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES(CXX)], + [define([AC_PROG_CXX], + defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJC], + [_AM_DEPENDENCIES(OBJC)], + [define([AC_PROG_OBJC], + defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl +]) +_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl +dnl The `parallel-tests' driver may need to know about EXEEXT, so add the +dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro +dnl is hooked onto _AC_COMPILER_EXEEXT early, see below. +AC_CONFIG_COMMANDS_PRE(dnl +[m4_provide_if([_AM_COMPILER_EXEEXT], + [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl +]) + +dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not +dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further +dnl mangled by Autoconf and run in a shell conditional statement. +m4_define([_AC_COMPILER_EXEEXT], +m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) + + +# When config.status generates a header, we must update the stamp-h file. +# This file resides in the same directory as the config header +# that is generated. The stamp files are numbered to have different names. + +# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +# loop where config.status creates the headers, so we can generate +# our stamp files there. +AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +[# Compute $1's index in $config_headers. +_am_arg=$1 +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) + +# Copyright (C) 2001, 2003, 2005, 2008 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +if test x"${install_sh}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi +AC_SUBST(install_sh)]) + +# Copyright (C) 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# Check whether the underlying file-system supports filenames +# with a leading dot. For instance MS-DOS doesn't. +AC_DEFUN([AM_SET_LEADING_DOT], +[rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null +AC_SUBST([am__leading_dot])]) + +# Add --enable-maintainer-mode option to configure. -*- Autoconf -*- +# From Jim Meyering + +# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 5 + +# AM_MAINTAINER_MODE([DEFAULT-MODE]) +# ---------------------------------- +# Control maintainer-specific portions of Makefiles. +# Default is to disable them, unless `enable' is passed literally. +# For symmetry, `disable' may be passed as well. Anyway, the user +# can override the default with the --enable/--disable switch. +AC_DEFUN([AM_MAINTAINER_MODE], +[m4_case(m4_default([$1], [disable]), + [enable], [m4_define([am_maintainer_other], [disable])], + [disable], [m4_define([am_maintainer_other], [enable])], + [m4_define([am_maintainer_other], [enable]) + m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])]) +AC_MSG_CHECKING([whether to am_maintainer_other maintainer-specific portions of Makefiles]) + dnl maintainer-mode's default is 'disable' unless 'enable' is passed + AC_ARG_ENABLE([maintainer-mode], +[ --][am_maintainer_other][-maintainer-mode am_maintainer_other make rules and dependencies not useful + (and sometimes confusing) to the casual installer], + [USE_MAINTAINER_MODE=$enableval], + [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes])) + AC_MSG_RESULT([$USE_MAINTAINER_MODE]) + AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes]) + MAINT=$MAINTAINER_MODE_TRUE + AC_SUBST([MAINT])dnl +] +) + +AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE]) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005, 2009 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 4 + +# AM_MAKE_INCLUDE() +# ----------------- +# Check to see how make treats includes. +AC_DEFUN([AM_MAKE_INCLUDE], +[am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +AC_MSG_CHECKING([for style of include used by $am_make]) +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from `make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi +AC_SUBST([am__include]) +AC_SUBST([am__quote]) +AC_MSG_RESULT([$_am_result]) +rm -f confinc confmf +]) + +# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- + +# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 6 + +# AM_MISSING_PROG(NAME, PROGRAM) +# ------------------------------ +AC_DEFUN([AM_MISSING_PROG], +[AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) + + +# AM_MISSING_HAS_RUN +# ------------------ +# Define MISSING if not defined so far and test if it supports --run. +# If it does, set am_missing_run to use it, otherwise, to nothing. +AC_DEFUN([AM_MISSING_HAS_RUN], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([missing])dnl +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + AC_MSG_WARN([`missing' script is too old or missing]) +fi +]) + +# Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_MKDIR_P +# --------------- +# Check for `mkdir -p'. +AC_DEFUN([AM_PROG_MKDIR_P], +[AC_PREREQ([2.60])dnl +AC_REQUIRE([AC_PROG_MKDIR_P])dnl +dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P, +dnl while keeping a definition of mkdir_p for backward compatibility. +dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile. +dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of +dnl Makefile.ins that do not define MKDIR_P, so we do our own +dnl adjustment using top_builddir (which is defined more often than +dnl MKDIR_P). +AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl +case $mkdir_p in + [[\\/$]]* | ?:[[\\/]]*) ;; + */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; +esac +]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005, 2008 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 4 + +# _AM_MANGLE_OPTION(NAME) +# ----------------------- +AC_DEFUN([_AM_MANGLE_OPTION], +[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) + +# _AM_SET_OPTION(NAME) +# ------------------------------ +# Set option NAME. Presently that only means defining a flag for this option. +AC_DEFUN([_AM_SET_OPTION], +[m4_define(_AM_MANGLE_OPTION([$1]), 1)]) + +# _AM_SET_OPTIONS(OPTIONS) +# ---------------------------------- +# OPTIONS is a space-separated list of Automake options. +AC_DEFUN([_AM_SET_OPTIONS], +[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) + +# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +# ------------------------------------------- +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +AC_DEFUN([_AM_IF_OPTION], +[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_RUN_LOG(COMMAND) +# ------------------- +# Run COMMAND, save the exit status in ac_status, and log it. +# (This has been adapted from Autoconf's _AC_RUN_LOG macro.) +AC_DEFUN([AM_RUN_LOG], +[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD + ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + (exit $ac_status); }]) + +# Check to make sure that the build environment is sane. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 5 + +# AM_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftest.file +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[[\\\"\#\$\&\'\`$am_lf]]*) + AC_MSG_ERROR([unsafe absolute working directory name]);; +esac +case $srcdir in + *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) + AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);; +esac + +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + rm -f conftest.file + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken +alias in your environment]) + fi + + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT(yes)]) + +# Copyright (C) 2009 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 1 + +# AM_SILENT_RULES([DEFAULT]) +# -------------------------- +# Enable less verbose build rules; with the default set to DEFAULT +# (`yes' being less verbose, `no' or empty being verbose). +AC_DEFUN([AM_SILENT_RULES], +[AC_ARG_ENABLE([silent-rules], +[ --enable-silent-rules less verbose build output (undo: `make V=1') + --disable-silent-rules verbose build output (undo: `make V=0')]) +case $enable_silent_rules in +yes) AM_DEFAULT_VERBOSITY=0;; +no) AM_DEFAULT_VERBOSITY=1;; +*) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; +esac +AC_SUBST([AM_DEFAULT_VERBOSITY])dnl +AM_BACKSLASH='\' +AC_SUBST([AM_BACKSLASH])dnl +_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl +]) + +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_STRIP +# --------------------- +# One issue with vendor `install' (even GNU) is that you can't +# specify the program used to strip binaries. This is especially +# annoying in cross-compiling environments, where the build's strip +# is unlikely to handle the host's binaries. +# Fortunately install-sh will honor a STRIPPROG variable, so we +# always use install-sh in `make install-strip', and initialize +# STRIPPROG with the value of the STRIP variable (set by the user). +AC_DEFUN([AM_PROG_INSTALL_STRIP], +[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be `maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# Copyright (C) 2006, 2008 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# _AM_SUBST_NOTMAKE(VARIABLE) +# --------------------------- +# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. +# This macro is traced by Automake. +AC_DEFUN([_AM_SUBST_NOTMAKE]) + +# AM_SUBST_NOTMAKE(VARIABLE) +# --------------------------- +# Public sister of _AM_SUBST_NOTMAKE. +AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) + +# Check how to create a tarball. -*- Autoconf -*- + +# Copyright (C) 2004, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# _AM_PROG_TAR(FORMAT) +# -------------------- +# Check how to create a tarball in format FORMAT. +# FORMAT should be one of `v7', `ustar', or `pax'. +# +# Substitute a variable $(am__tar) that is a command +# writing to stdout a FORMAT-tarball containing the directory +# $tardir. +# tardir=directory && $(am__tar) > result.tar +# +# Substitute a variable $(am__untar) that extract such +# a tarball read from stdin. +# $(am__untar) < result.tar +AC_DEFUN([_AM_PROG_TAR], +[# Always define AMTAR for backward compatibility. +AM_MISSING_PROG([AMTAR], [tar]) +m4_if([$1], [v7], + [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'], + [m4_case([$1], [ustar],, [pax],, + [m4_fatal([Unknown tar format])]) +AC_MSG_CHECKING([how to create a $1 tar archive]) +# Loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' +_am_tools=${am_cv_prog_tar_$1-$_am_tools} +# Do not fold the above two line into one, because Tru64 sh and +# Solaris sh will not grok spaces in the rhs of `-'. +for _am_tool in $_am_tools +do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; + do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar /dev/null 2>&1 && break + fi +done +rm -rf conftest.dir + +AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) +AC_MSG_RESULT([$am_cv_prog_tar_$1])]) +AC_SUBST([am__tar]) +AC_SUBST([am__untar]) +]) # _AM_PROG_TAR + +m4_include([m4/gtk-doc.m4]) +m4_include([m4/intltool.m4]) +m4_include([m4/libtool.m4]) +m4_include([m4/ltoptions.m4]) +m4_include([m4/ltsugar.m4]) +m4_include([m4/ltversion.m4]) +m4_include([m4/lt~obsolete.m4]) diff --git a/add-include-prefix b/add-include-prefix new file mode 100755 index 00000000..45e48769 --- /dev/null +++ b/add-include-prefix @@ -0,0 +1 @@ +sed -e 's/^/ /' -e 's/ */ /g' -e 's/ / -I /g' -e 's/ -I $//' diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 00000000..84b4f264 --- /dev/null +++ b/autogen.sh @@ -0,0 +1,25 @@ +#!/bin/sh +# Run this to generate all the initial makefiles, etc. + +srcdir=`dirname $0` +test -z "$srcdir" && srcdir=. + +PKG_NAME="mate-file-manager" + +(test -f $srcdir/configure.in) || { + echo -n "**Error**: Directory "\`$srcdir\'" does not look like the" + echo " top-level $PKG_NAME directory" + exit 1 +} + +which mate-autogen.sh || { + echo "You need to install mate-common from the MATE Git" + exit 1 +} + +REQUIRED_AUTOMAKE_VERSION=1.9 +USE_MATE2_MACROS=1 +USE_COMMON_DOC_BUILD=yes + +. mate-autogen.sh + diff --git a/config.guess b/config.guess new file mode 100755 index 00000000..dc84c68e --- /dev/null +++ b/config.guess @@ -0,0 +1,1501 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 +# Free Software Foundation, Inc. + +timestamp='2009-11-20' + +# This file 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 2 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, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA +# 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Originally written by Per Bothner. Please send patches (context +# diff format) to and include a ChangeLog +# entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, +2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ; set_cc_for_build= ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ELF__ + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + exit ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit ;; + *:SolidBSD:*:*) + echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + exit ;; + macppc:MirBSD:*:*) + echo powerpc-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit ;; + arm:riscos:*:*|arm:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + s390x:SunOS:*:*) + echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) + echo i386-pc-auroraux${UNAME_RELEASE} + exit ;; + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + eval $set_cc_for_build + SUN_ARCH="i386" + # If there is a compiler, see if it is configured for 64-bit objects. + # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. + # This test works for both compilers. + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + SUN_ARCH="x86_64" + fi + fi + echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && + dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`$dummy $dummyarg` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos${UNAME_RELEASE} + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit ;; + *:AIX:*:[456]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + eval $set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + grep -q __LP64__ + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:FreeBSD:*:*) + case ${UNAME_MACHINE} in + pc98) + echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + amd64) + echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + *) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + esac + exit ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit ;; + *:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit ;; + i*:windows32*:*) + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 + exit ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit ;; + *:Interix*:*) + case ${UNAME_MACHINE} in + x86) + echo i586-pc-interix${UNAME_RELEASE} + exit ;; + authenticamd | genuineintel | EM64T) + echo x86_64-unknown-interix${UNAME_RELEASE} + exit ;; + IA64) + echo ia64-unknown-interix${UNAME_RELEASE} + exit ;; + esac ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit ;; + 8664:Windows_NT:*) + echo x86_64-pc-mks + exit ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu + exit ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep -q ld.so.1 + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit ;; + arm*:Linux:*:*) + eval $set_cc_for_build + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then + echo ${UNAME_MACHINE}-unknown-linux-gnu + else + echo ${UNAME_MACHINE}-unknown-linux-gnueabi + fi + exit ;; + avr32*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + cris:Linux:*:*) + echo cris-axis-linux-gnu + exit ;; + crisv32:Linux:*:*) + echo crisv32-axis-linux-gnu + exit ;; + frv:Linux:*:*) + echo frv-unknown-linux-gnu + exit ;; + i*86:Linux:*:*) + LIBC=gnu + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #ifdef __dietlibc__ + LIBC=dietlibc + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` + echo "${UNAME_MACHINE}-pc-linux-${LIBC}" + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + mips:Linux:*:* | mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef ${UNAME_MACHINE} + #undef ${UNAME_MACHINE}el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=${UNAME_MACHINE}el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=${UNAME_MACHINE} + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + or32:Linux:*:*) + echo or32-unknown-linux-gnu + exit ;; + padre:Linux:*:*) + echo sparc-unknown-linux-gnu + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + vax:Linux:*:*) + echo ${UNAME_MACHINE}-dec-linux-gnu + exit ;; + x86_64:Linux:*:*) + echo x86_64-unknown-linux-gnu + exit ;; + xtensa*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i586. + # Note: whatever this is, it MUST be the same as what config.sub + # prints for the "djgpp" host, or else GDB configury will decide that + # this is a cross-build. + echo i586-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + NCR*:*:4.2:* | MPRAS*:*:4.2:*) + OS_REL='.3' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo ${UNAME_MACHINE}-stratus-vos + exit ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + BePC:Haiku:*:*) # Haiku running on Intel PC compatible. + echo i586-pc-haiku + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux${UNAME_RELEASE} + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux${UNAME_RELEASE} + exit ;; + SX-8R:SUPER-UX:*:*) + echo sx8r-nec-superux${UNAME_RELEASE} + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + case $UNAME_PROCESSOR in + i386) + eval $set_cc_for_build + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + UNAME_PROCESSOR="x86_64" + fi + fi ;; + unknown) UNAME_PROCESSOR=powerpc ;; + esac + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NSE-?:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk${UNAME_RELEASE} + exit ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + exit ;; + i*86:rdos:*:*) + echo ${UNAME_MACHINE}-pc-rdos + exit ;; + i*86:AROS:*:*) + echo ${UNAME_MACHINE}-pc-aros + exit ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix\n"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + c34*) + echo c34-convex-bsd + exit ;; + c38*) + echo c38-convex-bsd + exit ;; + c4*) + echo c4-convex-bsd + exit ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/config.h.in b/config.h.in new file mode 100644 index 00000000..cddf8aea --- /dev/null +++ b/config.h.in @@ -0,0 +1,185 @@ +/* config.h.in. Generated from configure.in by autoheader. */ +#undef ENABLE_INSTALLER +#undef ENABLE_NLS +#undef ENABLE_PROFILER +#undef GETTEXT_PACKAGE +#undef HAVE_CATGETS +#undef HAVE_GETTEXT +#undef HAVE_LC_MESSAGES +#undef HAVE_LIBBZ2 +#undef HAVE_LIBJPEG +#undef HAVE_MEDUSA +#undef HAVE_STPCPY +#undef bzclose +#undef bzCompress +#undef bzCompressInit +#undef bzDecompress +#undef bzDecompressInit +#undef bzdopen +#undef bzerror +#undef bzflush +#undef bzopen +#undef bzread +#undef bzwrite +#define HAVE_GTK_MULTIHEAD /* needed for egg-screen-exec functions */ +#undef HAVE_STARTUP_NOTIFICATION +#undef HAVE_EXIF +#undef HAVE_OLD_EXIF +#undef HAVE_RENDER + +/* Define if building universal (internal helper macro) */ +#undef AC_APPLE_UNIVERSAL_BUILD + +/* define to enable the empty view that is used for performance measurement */ +#undef ENABLE_EMPTY_VIEW + +/* always defined to indicate that i18n is enabled */ +#undef ENABLE_NLS + +/* define to enable PackageKit mimetype installer */ +#undef ENABLE_PACKAGEKIT + +/* define to enable the profiler */ +#undef ENABLE_PROFILER + +/* the gettext translation domain */ +#undef GETTEXT_PACKAGE + +/* Define to 1 if you have the `bind_textdomain_codeset' function. */ +#undef HAVE_BIND_TEXTDOMAIN_CODESET + +/* Define to 1 if you have the `dcgettext' function. */ +#undef HAVE_DCGETTEXT + +/* Define to 1 if you have the header file. */ +#undef HAVE_DLFCN_H + +/* Define to enable xmp support */ +#undef HAVE_EXEMPI + +/* Define if we have exempi with the new API */ +#undef HAVE_EXEMPI_NEW_API + +/* Define to enable EXIF support */ +#undef HAVE_EXIF + +/* Define if the GNU gettext() function is already present or preinstalled. */ +#undef HAVE_GETTEXT + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define if your file defines LC_MESSAGES. */ +#undef HAVE_LC_MESSAGES + +/* Define to 1 if you have the `m' library (-lm). */ +#undef HAVE_LIBM + +/* Define to 1 if you have the header file. */ +#undef HAVE_LOCALE_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_MALLOC_H + +/* Define to 1 if you have the `mallopt' function. */ +#undef HAVE_MALLOPT + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define if your EXIF library has old API */ +#undef HAVE_OLD_EXIF + +/* Define to 1 if libselinux is available */ +#undef HAVE_SELINUX + +/* Define to 1 if you have the header file. */ +#undef HAVE_SELINUX_SELINUX_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define if strftime supports %E and %O modifiers. */ +#undef HAVE_STRFTIME_EXTENSION + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_MOUNT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_PARAM_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_VFS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_X11_XF86KEYSYM_H + +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#undef LT_OBJDIR + +/* Define the location where the catalogs will be installed */ +#undef MATELOCALEDIR + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Version number of package */ +#undef VERSION + +/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most + significant byte first (like Motorola and SPARC, unlike Intel). */ +#if defined AC_APPLE_UNIVERSAL_BUILD +# if defined __BIG_ENDIAN__ +# define WORDS_BIGENDIAN 1 +# endif +#else +# ifndef WORDS_BIGENDIAN +# undef WORDS_BIGENDIAN +# endif +#endif + +/* Define to 1 if the X Window System is missing or not being used. */ +#undef X_DISPLAY_MISSING + +/* Define to empty if `const' does not conform to ANSI C. */ +#undef const diff --git a/config.sub b/config.sub new file mode 100755 index 00000000..2a55a507 --- /dev/null +++ b/config.sub @@ -0,0 +1,1705 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 +# Free Software Foundation, Inc. + +timestamp='2009-11-20' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file 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 2 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, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA +# 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Please send patches to . Submit a context +# diff and a properly formatted GNU ChangeLog entry. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, +2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \ + uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \ + kopensolaris*-gnu* | \ + storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis | -knuth | -cray | -microblaze) + os= + basic_machine=$1 + ;; + -bluegene*) + os=-cnk + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco6) + os=-sco5v6 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ + | bfin \ + | c4x | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | fido | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | lm32 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | mcore | mep | metag \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64octeon | mips64octeonel \ + | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | moxie \ + | mt \ + | msp430 \ + | nios | nios2 \ + | ns16k | ns32k \ + | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | pyramid \ + | rx \ + | score \ + | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu | strongarm \ + | tahoe | thumb | tic4x | tic80 | tron \ + | ubicom32 \ + | v850 | v850e \ + | we32k \ + | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \ + | z8k | z80) + basic_machine=$basic_machine-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12 | picochip) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + ms1) + basic_machine=mt-unknown + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* | avr32-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ + | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | lm32-* \ + | m32c-* | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64octeon-* | mips64octeonel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64r5900-* | mips64r5900el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ + | nios-* | nios2-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | pyramid-* \ + | romp-* | rs6000-* | rx-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \ + | tahoe-* | thumb-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* | tile-* \ + | tron-* \ + | ubicom32-* \ + | v850-* | v850e-* | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \ + | xstormy16-* | xtensa*-* \ + | ymp-* \ + | z8k-* | z80-*) + ;; + # Recognize the basic CPU types without company name, with glob match. + xtensa*) + basic_machine=$basic_machine-unknown + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aros) + basic_machine=i386-pc + os=-aros + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + blackfin) + basic_machine=bfin-unknown + os=-linux + ;; + blackfin-*) + basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + bluegene*) + basic_machine=powerpc-ibm + os=-cnk + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + cegcc) + basic_machine=arm-unknown + os=-cegcc + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16) + basic_machine=cr16-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dicos) + basic_machine=i686-pc + os=-dicos + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m68knommu) + basic_machine=m68k-unknown + os=-linux + ;; + m68knommu-*) + basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + microblaze) + basic_machine=microblaze-xilinx + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + os=-mingw32ce + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + ms1-*) + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + parisc) + basic_machine=hppa-unknown + os=-linux + ;; + parisc-*) + basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rdos) + basic_machine=i386-pc + os=-rdos + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh5el) + basic_machine=sh5le-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tic54x | c54x*) + basic_machine=tic54x-unknown + os=-coff + ;; + tic55x | c55x*) + basic_machine=tic55x-unknown + os=-coff + ;; + tic6x | c6x*) + basic_machine=tic6x-unknown + os=-coff + ;; + tile*) + basic_machine=tile-unknown + os=-linux-gnu + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + z80-*-coff) + basic_machine=z80-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -auroraux) + os=-auroraux + ;; + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ + | -sym* | -kopensolaris* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* | -aros* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -openbsd* | -solidbsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* | -cegcc* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -kaos*) + os=-kaos + ;; + -zvmoe) + os=-zvmoe + ;; + -dicos*) + os=-dicos + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + m68*-cisco) + os=-aout + ;; + mep-*) + os=-elf + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-haiku) + os=-haiku + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -cnk*|-aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/configure.in b/configure.in new file mode 100644 index 00000000..8b9fa2c6 --- /dev/null +++ b/configure.in @@ -0,0 +1,483 @@ +AC_PREREQ(2.54) + +dnl =========================================================================== + +m4_define(glib_minver, 2.25.9) +m4_define(mate_desktop_minver, 2.29.91) +m4_define(pango_minver, 1.1.2) +m4_define(gtk_minver, 2.22.0) +m4_define(xml_minver, 2.4.7) +m4_define(exif_minver, 0.5.12) +m4_define(exempi_minver, 1.99.2) +m4_define(exempi_minver_newapi, 1.99.5) +m4_define(gail_minver, 0.16) + + +dnl 1. If the library code has changed at all since last release, then increment revision. +dnl 2. If any interfaces have been added, then increment current and set revision to 0. +dnl Interface break is not allowed. +m4_define(caja_extension_current, 3) +m4_define(caja_extension_revision, 0) + +AC_INIT([caja], [2011.11.23], [https://github.com/perberos/mate-desktop-environment]) + +dnl --------------------------------------------------------------------------- +dnl GTK library version +dnl --------------------------------------------------------------------------- +GTK_API_VERSION=2.0 +GTK_REQUIRED=2.22.0 + +AC_MSG_CHECKING([which gtk+ version to compile against]) +AC_ARG_WITH([gtk], + [AS_HELP_STRING([--with-gtk=2.0|3.0],[which gtk+ version to compile against (default: 2.0)])], + [ + case "$with_gtk" in + 2.0|3.0) ;; + *) AC_MSG_ERROR([invalid gtk version specified]) ;; + esac + ], + [with_gtk=2.0]) +AC_MSG_RESULT([$with_gtk]) + +case "$with_gtk" in + 2.0) GTK_API_VERSION=2.0 + GTK_REQUIRED=2.18.0 + ;; + 3.0) GTK_API_VERSION=3.0 + GTK_REQUIRED=3.0.0 + ;; +esac + +dnl =========================================================================== + +AC_CONFIG_SRCDIR(src) +AC_CONFIG_HEADERS(config.h) +AC_CONFIG_MACRO_DIR([m4]) + +AM_INIT_AUTOMAKE([1.9 tar-ustar]) +m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) +AM_MAINTAINER_MODE +AC_SUBST([ACLOCAL_AMFLAGS], ["\${ACLOCAL_FLAGS}"]) + +AC_SUBST(GLIB_REQUIRED, [glib_minver]) +AC_SUBST(MATE_DESKTOP_REQUIRED, [mate_desktop_minver]) +AC_SUBST(PANGO_REQUIRED, [pango_minver]) +AC_SUBST(GTK_REQUIRED, [$GTK_REQUIRED]) +AC_SUBST(XML_REQUIRED, [xml_minver]) +AC_SUBST(GAIL_REQUIRED) + +dnl We need to decrement current by one in the calculation of the age because +dnl the library was started with version "1:0:0" instead of "0:0:0" +AC_SUBST(CAJA_EXTENSION_VERSION_INFO, [caja_extension_current]:[caja_extension_revision]:`expr [caja_extension_current] - 1`) + +AC_C_BIGENDIAN +AC_C_CONST +AC_PROG_CC +AC_PROG_CPP +AC_PROG_INSTALL +AC_PROG_LN_S +AC_PROG_MAKE_SET +AM_DISABLE_STATIC +AC_LIBTOOL_WIN32_DLL +AM_PROG_LIBTOOL +AC_PATH_PROG(PKG_CONFIG, pkg-config, no) + +AC_CHECK_LIB(m, floor) + +PKG_CHECK_MODULES(ALL, [ + glib-2.0 >= glib_minver + mate-desktop-2.0 >= mate_desktop_minver + gthread-2.0 + gio-unix-2.0 + gio-2.0 + pango >= pango_minver + gtk+-$GTK_API_VERSION >= $GTK_REQUIRED + libxml-2.0 >= xml_minver + gail >= gail_minver +]) +dnl ========================================================================== + +GETTEXT_PACKAGE=caja +AC_SUBST(GETTEXT_PACKAGE) +AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE,"$GETTEXT_PACKAGE", + [the gettext translation domain]) + +AM_GLIB_GNU_GETTEXT +GLIB_DEFINE_LOCALEDIR(MATELOCALEDIR) + +IT_PROG_INTLTOOL([0.40.1]) + +dnl ========================================================================== + +GTK_DOC_CHECK([1.4]) + +dnl ========================================================================== + +ENABLE_PROFILER= +AC_ARG_ENABLE(profiler, + AC_HELP_STRING([--enable-profiler], [Enable profiler]), + [ENABLE_PROFILER=1 + AC_DEFINE(ENABLE_PROFILER, 1, [define to enable the profiler])]) + +profiling_support=off +if test "x$ENABLE_PROFILER" = "x1" +then + CFLAGS="-g -O -gdwarf-2 -finstrument-functions -D__NO_STRING_INLINES $CFLAGS" + LDFLAGS="/mate/MATE2/lib/libprofiler.so -lpthread $LDFLAGS" + profiling_support=on +fi + +AC_SUBST(ENABLE_PROFILER) +AM_CONDITIONAL(ENABLE_PROFILER, test "x$ENABLE_PROFILER" = "x1") + +dnl ========================================================================== + +AC_CHECK_PROGS(PERL, perl5 perl) +AC_PATH_PROG(GLIB_GENMARSHAL, glib-genmarshal) + +dnl ========================================================================== + +AC_CHECK_HEADERS(sys/mount.h sys/vfs.h sys/param.h malloc.h) +AC_CHECK_FUNCS(mallopt) + +dnl X + +x_libs="`$PKG_CONFIG --libs pangox`" +case x_libs in + *-lX11*) pango_omitted_x_deps=no ;; + *) pango_omitted_x_deps=yes ;; +esac + +x_cflags="`$PKG_CONFIG --cflags pangox`" +x_extra_libs= + +if test $pango_omitted_x_deps = yes ; then + AC_PATH_XTRA + + if test x$no_x = xyes ; then + AC_MSG_ERROR([X development libraries not found]) + fi + + x_libs="$X_LIBS -lX11 $X_EXTRA_LIBS" +fi + +## Strip the .la files + +x_libs_for_checks=$x_libs +#for I in $x_libs ; do +# case $I in +# *.la) ;; +# *) x_libs_for_checks="$x_libs_for_checks $I" ;; +# esac +#done + +AC_CHECK_LIB(X11, XOpenDisplay, :, + AC_MSG_ERROR([*** libX11 not found. Check 'config.log' for more details.]), + $x_libs_for_checks) + +dnl ========================================================================== + +AM_CONDITIONAL(HAVE_EXIF, false) + +dnl libexif checking + +PKG_CHECK_MODULES(EXIF, libexif > exif_minver, + [AM_CONDITIONAL(HAVE_EXIF, true) + AC_DEFINE(HAVE_EXIF, 1, [Define to enable EXIF support]) + ], + [PKG_CHECK_MODULES(EXIF, libexif = exif_minver, + [AM_CONDITIONAL(HAVE_EXIF, true) + AC_DEFINE(HAVE_OLD_EXIF, 1, [Define if your EXIF library has old API]) + ], [AM_CONDITIONAL(HAVE_EXIF, false)]) + ]) + +AC_SUBST(EXIF_CFLAGS) +AC_SUBST(EXIF_LIBS) + +dnl ========================================================================== + +dnl exempi checking + +AM_CONDITIONAL(HAVE_EXEMPI, false) + +AC_ARG_ENABLE(xmp, + AC_HELP_STRING([--disable-xmp], + [build without xmp support])) +msg_xmp=no +if test "x$enable_xmp" != "xno"; then + PKG_CHECK_MODULES(EXEMPI, exempi-2.0 >= exempi_minver, + [AM_CONDITIONAL(HAVE_EXEMPI, true) + AC_DEFINE(HAVE_EXEMPI, 1, [Define to enable xmp support])] + msg_xmp=yes, + [AM_CONDITIONAL(HAVE_EXEMPI, false)]) + + PKG_CHECK_MODULES(EXEMPI_NEW_API, exempi-2.0 >= exempi_minver_newapi, + AC_DEFINE(HAVE_EXEMPI_NEW_API, 1, + [Define if we have exempi with the new API]), true) + + AC_SUBST(EXEMPI_CFLAGS) + AC_SUBST(EXEMPI_LIBS) +fi + +dnl ========================================================================== + +dnl **************************** +dnl *** Check for libselinux *** +dnl **************************** + +SELINUX_LIBS= +msg_selinux=no +AC_CHECK_LIB(selinux, is_selinux_enabled, + [AC_CHECK_HEADERS(selinux/selinux.h, + [AC_SEARCH_LIBS(selinux_raw_to_trans_context, selinux, + [AC_DEFINE(HAVE_SELINUX, 1, [Define to 1 if libselinux is available]) + SELINUX_LIBS="-lselinux" + msg_selinux=yes]) + ]) + ]) +AC_SUBST(SELINUX_LIBS) + + +AC_ARG_ENABLE(empty_view, + AC_HELP_STRING([--enable-empty-view], [Enable empty view]), + [ENABLE_EMPTY_VIEW=1 + AC_DEFINE(ENABLE_EMPTY_VIEW, 1, [define to enable the empty view that is used for performance measurement])]) + +AC_SUBST(ENABLE_EMPTY_VIEW) +AM_CONDITIONAL(ENABLE_EMPTY_VIEW, test "x$ENABLE_EMPTY_VIEW" = "x1") + +dnl ========================================================================== + +AC_ARG_ENABLE(packagekit, + AC_HELP_STRING([--disable-packagekit], + [build without PackageKit support])) +msg_packagekit=no +if test "x$enable_packagekit" != "xno"; then + msg_packagekit=yes + AC_DEFINE(ENABLE_PACKAGEKIT, 1, [define to enable PackageKit mimetype installer]) +fi + + +dnl ============================================================================ +dnl | se comprueba unique +dnl | de lo contrario, se intenta utilizar libunique +dnl ============================================================================ +case "$with_gtk" in + 2.0) LIBUNIQUE_VERSION=1.0 + ;; + 3.0) LIBUNIQUE_VERSION=3.0 + ;; +esac + +PKG_CHECK_MODULES(UNIQUE, unique-$LIBUNIQUE_VERSION, enable_libunique=yes, enable_libunique=no) + +AC_SUBST([UNIQUE_CFLAGS]) +AC_SUBST([UNIQUE_LIBS]) + +AC_ARG_ENABLE(unique, [ --enable-unique enable the use of libunique instead of g_application or gtk_application], enable_libunique=yes,) + +if test "x$enable_libunique" = "xyes"; then + UNIQUE_CFLAGS="$UNIQUE_CFLAGS -DUSE_UNIQUE=1" + # fix for deprecated on 2.26 + # unique en la version 1.0, contiene simbolos no definidos a partir de + # glib 2.26, pero puede ser obviado si se utiliza -DG_CONST_RETURN=const + if $PKG_CONFIG --atleast-version 2.26 glib-2.0; then + UNIQUE_CFLAGS="$UNIQUE_CFLAGS -DG_CONST_RETURN=const" + fi + + EXTRA_CORE_MODULES="$EXTRA_CORE_MODULES unique-$LIBUNIQUE_VERSION" +fi + + +dnl ========================================================================== + +dnl Turn on the additional warnings last, so -Werror doesn't affect other tests. + +WARNING_CFLAGS="" + +AC_ARG_ENABLE(more-warnings, +AC_HELP_STRING([--enable-more-warnings], [Maximum compiler warnings]), +set_more_warnings="$enableval",[ +if test -f $srcdir/CVSVERSION; then + is_cvs_version=true + set_more_warnings=yes +else + set_more_warnings=no +fi +]) +AC_MSG_CHECKING(for more warnings, including -Werror) +if test "$GCC" = "yes" -a "$set_more_warnings" != "no"; then + AC_MSG_RESULT(yes) + WARNING_CFLAGS="\ + -Wall \ + -Wmissing-declarations -Wmissing-prototypes \ + -Wnested-externs -Wpointer-arith \ + -Wcast-align \ + -Werror" + + for option in -Wstrict-aliasing=0 -Wno-pointer-sign; do + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $option" + AC_MSG_CHECKING([whether gcc understands $option]) + AC_TRY_COMPILE([], [], + has_option=yes, + has_option=no,) + if test $has_option = yes; then + WARNING_CFLAGS="$WARNING_CFLAGS $option" + fi + AC_MSG_RESULT($has_option) + CFLAGS="$SAVE_CFLAGS" + unset has_option + unset SAVE_CFLAGS + done + unset option +else + AC_MSG_RESULT(no) +fi + +AC_SUBST(WARNING_CFLAGS) + +dnl =========================================================================== + +dnl strftime checks + +AC_TRY_RUN([#include + int main () + { + char buf[100]; + struct tm tm = {0}; + tm.tm_year = 99; + if (strftime(buf, 100, "%EY", &tm) == 4 && + strcmp (buf, "1999")==0) + return 0; + return 1; + } + ], + AC_DEFINE(HAVE_STRFTIME_EXTENSION, 1, [Define if strftime supports %E and %O modifiers.]) +) + +dnl =========================================================================== + +# +# Checks for Xft/XRender +# +have_render=false +RENDER_LIBS="" + +AC_CHECK_LIB(Xrender, XRenderFindFormat, + have_render=true,:,-lXext) + +if $have_render ; then + RENDER_LIBS="-lXrender -lXext" + AC_DEFINE(HAVE_RENDER) +fi + +AC_SUBST(RENDER_LIBS) + + + +dnl ========================================================================== + +dnl libegg +LIBEGG_MODULES="gtk+-$GTK_API_VERSION" +LIBEGG_CFLAGS="`$PKG_CONFIG --cflags $LIBEGG_MODULES`" +AC_SUBST(LIBEGG_CFLAGS) +LIBEGG_LIBS="`$PKG_CONFIG --libs $LIBEGG_MODULES`" +AC_SUBST(LIBEGG_LIBS) + +dnl libcaja-extension +LIBCAJA_EXTENSION_MODULES="glib-2.0 gtk+-$GTK_API_VERSION" +LIBCAJA_EXTENSION_CFLAGS="`$PKG_CONFIG --cflags $LIBCAJA_EXTENSION_MODULES`" +AC_SUBST(LIBCAJA_EXTENSION_CFLAGS) +LIBCAJA_EXTENSION_LIBS="`$PKG_CONFIG --libs $LIBCAJA_EXTENSION_MODULES`" +AC_SUBST(LIBCAJA_EXTENSION_LIBS) + +dnl core caja +CORE_MODULES="glib-2.0 mate-desktop-2.0 gthread-2.0 gio-2.0 gio-unix-2.0 gail mateconf-2.0 libxml-2.0 $EXTRA_CORE_MODULES gtk+-$GTK_API_VERSION" +CORE_CFLAGS="`$PKG_CONFIG --cflags $CORE_MODULES` $x_cflags" +AC_SUBST(CORE_CFLAGS) +CORE_LIBS="`$PKG_CONFIG --libs $CORE_MODULES` $x_libs" +AC_SUBST(CORE_LIBS) + +DISABLE_DEPRECATED_CFLAGS="-DG_DISABLE_DEPRECATED -DGDK_PIXBUF_DISABLE_DEPRECATED" +AC_SUBST(DISABLE_DEPRECATED_CFLAGS) + +dnl Multimedia keys +AC_CHECK_HEADERS([X11/XF86keysym.h]) + +dnl ============================================== +dnl Special MateConf section +dnl ============================================== + +AC_PATH_PROG(MATECONFTOOL, mateconftool-2, no) + +if test x"$MATECONFTOOL" = xno; then + AC_MSG_ERROR([mateconftool-2 executable not found in your path - should be installed with MateConf]) +fi + +AM_MATECONF_SOURCE_2 + +################################################## +# Check for introspection +################################################## +GOBJECT_INTROSPECTION_CHECK([0.6.4]) + +dnl ========================================================================== + +AC_PATH_PROG(UPDATE_MIME_DATABASE, update-mime-database, no) + +AC_ARG_ENABLE(update-mimedb, + AC_HELP_STRING([--disable-update-mimedb], + [disable the update-mime-database after install [default=no]]),, + enable_update_mimedb=yes) +AM_CONDITIONAL(ENABLE_UPDATE_MIMEDB, test x$enable_update_mimedb = xyes) + +AC_CONFIG_FILES([ +Makefile +cut-n-paste-code/Makefile +cut-n-paste-code/libegg/Makefile +data/Makefile +data/icons/Makefile +data/patterns/Makefile +data/caja-computer.desktop.in +data/caja-file-management-properties.desktop.in +data/caja-home.desktop.in +data/caja.desktop.in +data/caja-folder-handler.desktop.in +data/caja-browser.desktop.in +data/caja-autorun-software.desktop.in +docs/Makefile +docs/reference/Makefile +docs/reference/libcaja-extension/Makefile +docs/reference/libcaja-extension/version.xml +eel/Makefile +icons/Makefile +libcaja-private/Makefile +libcaja-extension/Makefile +libcaja-extension/libcaja-extension.pc +libcaja-extension/libcaja-extension-uninstalled.pc +po/Makefile.in +src/Makefile +src/file-manager/Makefile +test/Makefile +]) + +AC_OUTPUT + +dnl ========================================================================== + +echo " +caja-$VERSION: + + prefix: ${prefix} + source code location: ${srcdir} + compiler: ${CC} + xmp support: $msg_xmp + Use libunique: ${enable_libunique} + Gtk+ version: ${GTK_API_VERSION} + PackageKit support: $msg_packagekit + + profiling support: ${profiling_support} + caja-extension documentation: ${enable_gtk_doc} + caja-extension introspection: ${found_introspection} +" diff --git a/cut-n-paste-code/Makefile.am b/cut-n-paste-code/Makefile.am new file mode 100644 index 00000000..80f6abb0 --- /dev/null +++ b/cut-n-paste-code/Makefile.am @@ -0,0 +1,2 @@ +SUBDIRS = libegg + diff --git a/cut-n-paste-code/Makefile.in b/cut-n-paste-code/Makefile.in new file mode 100644 index 00000000..abdf5846 --- /dev/null +++ b/cut-n-paste-code/Makefile.in @@ -0,0 +1,646 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = cut-n-paste-code +DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/gtk-doc.m4 \ + $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_GEN = $(am__v_GEN_$(V)) +am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) +am__v_GEN_0 = @echo " GEN " $@; +AM_V_at = $(am__v_at_$(V)) +am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) +am__v_at_0 = @ +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ + html-recursive info-recursive install-data-recursive \ + install-dvi-recursive install-exec-recursive \ + install-html-recursive install-info-recursive \ + install-pdf-recursive install-ps-recursive install-recursive \ + installcheck-recursive installdirs-recursive pdf-recursive \ + ps-recursive uninstall-recursive +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ + $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ + distdir +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +ACLOCAL = @ACLOCAL@ +ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@ +ALL_CFLAGS = @ALL_CFLAGS@ +ALL_LIBS = @ALL_LIBS@ +ALL_LINGUAS = @ALL_LINGUAS@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CAJA_EXTENSION_VERSION_INFO = @CAJA_EXTENSION_VERSION_INFO@ +CATALOGS = @CATALOGS@ +CATOBJEXT = @CATOBJEXT@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CORE_CFLAGS = @CORE_CFLAGS@ +CORE_LIBS = @CORE_LIBS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIRNAME = @DATADIRNAME@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DISABLE_DEPRECATED_CFLAGS = @DISABLE_DEPRECATED_CFLAGS@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ENABLE_EMPTY_VIEW = @ENABLE_EMPTY_VIEW@ +ENABLE_PROFILER = @ENABLE_PROFILER@ +EXEEXT = @EXEEXT@ +EXEMPI_CFLAGS = @EXEMPI_CFLAGS@ +EXEMPI_LIBS = @EXEMPI_LIBS@ +EXEMPI_NEW_API_CFLAGS = @EXEMPI_NEW_API_CFLAGS@ +EXEMPI_NEW_API_LIBS = @EXEMPI_NEW_API_LIBS@ +EXIF_CFLAGS = @EXIF_CFLAGS@ +EXIF_LIBS = @EXIF_LIBS@ +FGREP = @FGREP@ +GAIL_REQUIRED = @GAIL_REQUIRED@ +GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ +GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ +GLIB_REQUIRED = @GLIB_REQUIRED@ +GMOFILES = @GMOFILES@ +GMSGFMT = @GMSGFMT@ +GREP = @GREP@ +GTKDOC_CHECK = @GTKDOC_CHECK@ +GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@ +GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ +GTKDOC_MKPDF = @GTKDOC_MKPDF@ +GTKDOC_REBASE = @GTKDOC_REBASE@ +GTK_REQUIRED = @GTK_REQUIRED@ +HTML_DIR = @HTML_DIR@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INSTOBJEXT = @INSTOBJEXT@ +INTLLIBS = @INTLLIBS@ +INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ +INTLTOOL_MERGE = @INTLTOOL_MERGE@ +INTLTOOL_PERL = @INTLTOOL_PERL@ +INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ +INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@ +INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@ +INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@ +INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@ +INTROSPECTION_LIBS = @INTROSPECTION_LIBS@ +INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ +INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ +INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBCAJA_EXTENSION_CFLAGS = @LIBCAJA_EXTENSION_CFLAGS@ +LIBCAJA_EXTENSION_LIBS = @LIBCAJA_EXTENSION_LIBS@ +LIBEGG_CFLAGS = @LIBEGG_CFLAGS@ +LIBEGG_LIBS = @LIBEGG_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MATECONFTOOL = @MATECONFTOOL@ +MATECONF_SCHEMA_CONFIG_SOURCE = @MATECONF_SCHEMA_CONFIG_SOURCE@ +MATECONF_SCHEMA_FILE_DIR = @MATECONF_SCHEMA_FILE_DIR@ +MATE_DESKTOP_REQUIRED = @MATE_DESKTOP_REQUIRED@ +MKDIR_P = @MKDIR_P@ +MKINSTALLDIRS = @MKINSTALLDIRS@ +MSGFMT = @MSGFMT@ +MSGFMT_OPTS = @MSGFMT_OPTS@ +MSGMERGE = @MSGMERGE@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PANGO_REQUIRED = @PANGO_REQUIRED@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POFILES = @POFILES@ +POSUB = @POSUB@ +PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@ +PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@ +RANLIB = @RANLIB@ +RENDER_LIBS = @RENDER_LIBS@ +SED = @SED@ +SELINUX_LIBS = @SELINUX_LIBS@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +UNIQUE_CFLAGS = @UNIQUE_CFLAGS@ +UNIQUE_LIBS = @UNIQUE_LIBS@ +UPDATE_MIME_DATABASE = @UPDATE_MIME_DATABASE@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +WARNING_CFLAGS = @WARNING_CFLAGS@ +XGETTEXT = @XGETTEXT@ +XMKMF = @XMKMF@ +XML_REQUIRED = @XML_REQUIRED@ +X_CFLAGS = @X_CFLAGS@ +X_EXTRA_LIBS = @X_EXTRA_LIBS@ +X_LIBS = @X_LIBS@ +X_PRE_LIBS = @X_PRE_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +SUBDIRS = libegg +all: all-recursive + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu cut-n-paste-code/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu cut-n-paste-code/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. +$(RECURSIVE_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +$(RECURSIVE_CLEAN_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-recursive +all-am: Makefile +installdirs: installdirs-recursive +installdirs-am: +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-recursive + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: + +.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \ + install-am install-strip tags-recursive + +.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ + all all-am check check-am clean clean-generic clean-libtool \ + ctags ctags-recursive distclean distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs installdirs-am maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \ + uninstall uninstall-am + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/cut-n-paste-code/README b/cut-n-paste-code/README new file mode 100644 index 00000000..b8f4406f --- /dev/null +++ b/cut-n-paste-code/README @@ -0,0 +1,21 @@ +README for caja/cut-n-paste-code + +The code in this directory hierarchy was cut-n-pasted from +somewhere else. + +In the soon to come, Star Trek future, this code will be available +as part of standard libraries. + +For example, the code in libegg will be one day available as part +of Gtk+. + +Until that happens, DON'T HACK the code, unless you are updating +from the original cut-n-paste source. + +Instead of hacking the code in cut-n-paste-code, create subclasses +and put them in libcaja-extensions. + +If you have any specific questions, comments or complaints about this +setup, send mail to the caja mailing list at: + +caja-list@gnome.org diff --git a/cut-n-paste-code/libegg/Makefile.am b/cut-n-paste-code/libegg/Makefile.am new file mode 100644 index 00000000..1ee4585d --- /dev/null +++ b/cut-n-paste-code/libegg/Makefile.am @@ -0,0 +1,46 @@ +NULL= + +noinst_LTLIBRARIES = libegg.la + +INCLUDES = $(LIBEGG_CFLAGS) + +EGG_TREE_DND_FILES = \ + eggtreemultidnd.c \ + eggtreemultidnd.h \ + $(NULL) + +EGG_SMCLIENT_FILES = \ + eggdesktopfile.c \ + eggdesktopfile.h \ + eggsmclient.c \ + eggsmclient.h \ + eggsmclient-private.h \ + eggsmclient-xsmp.c \ + $(NULL) + +libegg_la_SOURCES = \ + $(EGG_TREE_DND_FILES) \ + $(EGG_SMCLIENT_FILES) \ + $(NULL) + +libegg_la_CFLAGS = \ + -DEGG_SM_CLIENT_BACKEND_XSMP \ + -DG_LOG_DOMAIN=\""EggSMClient"\" \ + $(LIBEGG_CFLAGS) \ + $(WARNING_CFLAGS) \ + $(DISABLE_DEPRECATED) + +libegg_la_LIBADD = \ + $(LIBEGG_LIBS) \ + -lSM -lICE + +EXTRA_DIST = \ + update-from-egg.sh \ + $(NULL) + +EGG_TREE_DND_DIR = $(srcdir)/../../../libegg/libegg/treeviewutils +EGG_SMCLIENT_DIR = $(srcdir)/../../../libegg/libegg/smclient + +regenerate-built-sources: + EGGFILES="$(EGG_TREE_DND_FILES)" EGGDIR="$(EGG_TREE_DND_DIR)" $(srcdir)/update-from-egg.sh + EGGFILES="$(EGG_SMCLIENT_FILES)" EGGDIR="$(EGG_SMCLIENT_DIR)" $(srcdir)/update-from-egg.sh diff --git a/cut-n-paste-code/libegg/Makefile.in b/cut-n-paste-code/libegg/Makefile.in new file mode 100644 index 00000000..f9fea4a5 --- /dev/null +++ b/cut-n-paste-code/libegg/Makefile.in @@ -0,0 +1,657 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = cut-n-paste-code/libegg +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/gtk-doc.m4 \ + $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) +am__DEPENDENCIES_1 = +libegg_la_DEPENDENCIES = $(am__DEPENDENCIES_1) +am__objects_1 = +am__objects_2 = libegg_la-eggtreemultidnd.lo $(am__objects_1) +am__objects_3 = libegg_la-eggdesktopfile.lo libegg_la-eggsmclient.lo \ + libegg_la-eggsmclient-xsmp.lo $(am__objects_1) +am_libegg_la_OBJECTS = $(am__objects_2) $(am__objects_3) \ + $(am__objects_1) +libegg_la_OBJECTS = $(am_libegg_la_OBJECTS) +AM_V_lt = $(am__v_lt_$(V)) +am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY)) +am__v_lt_0 = --silent +libegg_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libegg_la_CFLAGS) \ + $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_$(V)) +am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY)) +am__v_CC_0 = @echo " CC " $@; +AM_V_at = $(am__v_at_$(V)) +am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) +am__v_at_0 = @ +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_$(V)) +am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY)) +am__v_CCLD_0 = @echo " CCLD " $@; +AM_V_GEN = $(am__v_GEN_$(V)) +am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) +am__v_GEN_0 = @echo " GEN " $@; +SOURCES = $(libegg_la_SOURCES) +DIST_SOURCES = $(libegg_la_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@ +ALL_CFLAGS = @ALL_CFLAGS@ +ALL_LIBS = @ALL_LIBS@ +ALL_LINGUAS = @ALL_LINGUAS@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CAJA_EXTENSION_VERSION_INFO = @CAJA_EXTENSION_VERSION_INFO@ +CATALOGS = @CATALOGS@ +CATOBJEXT = @CATOBJEXT@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CORE_CFLAGS = @CORE_CFLAGS@ +CORE_LIBS = @CORE_LIBS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIRNAME = @DATADIRNAME@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DISABLE_DEPRECATED_CFLAGS = @DISABLE_DEPRECATED_CFLAGS@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ENABLE_EMPTY_VIEW = @ENABLE_EMPTY_VIEW@ +ENABLE_PROFILER = @ENABLE_PROFILER@ +EXEEXT = @EXEEXT@ +EXEMPI_CFLAGS = @EXEMPI_CFLAGS@ +EXEMPI_LIBS = @EXEMPI_LIBS@ +EXEMPI_NEW_API_CFLAGS = @EXEMPI_NEW_API_CFLAGS@ +EXEMPI_NEW_API_LIBS = @EXEMPI_NEW_API_LIBS@ +EXIF_CFLAGS = @EXIF_CFLAGS@ +EXIF_LIBS = @EXIF_LIBS@ +FGREP = @FGREP@ +GAIL_REQUIRED = @GAIL_REQUIRED@ +GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ +GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ +GLIB_REQUIRED = @GLIB_REQUIRED@ +GMOFILES = @GMOFILES@ +GMSGFMT = @GMSGFMT@ +GREP = @GREP@ +GTKDOC_CHECK = @GTKDOC_CHECK@ +GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@ +GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ +GTKDOC_MKPDF = @GTKDOC_MKPDF@ +GTKDOC_REBASE = @GTKDOC_REBASE@ +GTK_REQUIRED = @GTK_REQUIRED@ +HTML_DIR = @HTML_DIR@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INSTOBJEXT = @INSTOBJEXT@ +INTLLIBS = @INTLLIBS@ +INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ +INTLTOOL_MERGE = @INTLTOOL_MERGE@ +INTLTOOL_PERL = @INTLTOOL_PERL@ +INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ +INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@ +INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@ +INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@ +INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@ +INTROSPECTION_LIBS = @INTROSPECTION_LIBS@ +INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ +INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ +INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBCAJA_EXTENSION_CFLAGS = @LIBCAJA_EXTENSION_CFLAGS@ +LIBCAJA_EXTENSION_LIBS = @LIBCAJA_EXTENSION_LIBS@ +LIBEGG_CFLAGS = @LIBEGG_CFLAGS@ +LIBEGG_LIBS = @LIBEGG_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MATECONFTOOL = @MATECONFTOOL@ +MATECONF_SCHEMA_CONFIG_SOURCE = @MATECONF_SCHEMA_CONFIG_SOURCE@ +MATECONF_SCHEMA_FILE_DIR = @MATECONF_SCHEMA_FILE_DIR@ +MATE_DESKTOP_REQUIRED = @MATE_DESKTOP_REQUIRED@ +MKDIR_P = @MKDIR_P@ +MKINSTALLDIRS = @MKINSTALLDIRS@ +MSGFMT = @MSGFMT@ +MSGFMT_OPTS = @MSGFMT_OPTS@ +MSGMERGE = @MSGMERGE@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PANGO_REQUIRED = @PANGO_REQUIRED@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POFILES = @POFILES@ +POSUB = @POSUB@ +PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@ +PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@ +RANLIB = @RANLIB@ +RENDER_LIBS = @RENDER_LIBS@ +SED = @SED@ +SELINUX_LIBS = @SELINUX_LIBS@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +UNIQUE_CFLAGS = @UNIQUE_CFLAGS@ +UNIQUE_LIBS = @UNIQUE_LIBS@ +UPDATE_MIME_DATABASE = @UPDATE_MIME_DATABASE@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +WARNING_CFLAGS = @WARNING_CFLAGS@ +XGETTEXT = @XGETTEXT@ +XMKMF = @XMKMF@ +XML_REQUIRED = @XML_REQUIRED@ +X_CFLAGS = @X_CFLAGS@ +X_EXTRA_LIBS = @X_EXTRA_LIBS@ +X_LIBS = @X_LIBS@ +X_PRE_LIBS = @X_PRE_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +NULL = +noinst_LTLIBRARIES = libegg.la +INCLUDES = $(LIBEGG_CFLAGS) +EGG_TREE_DND_FILES = \ + eggtreemultidnd.c \ + eggtreemultidnd.h \ + $(NULL) + +EGG_SMCLIENT_FILES = \ + eggdesktopfile.c \ + eggdesktopfile.h \ + eggsmclient.c \ + eggsmclient.h \ + eggsmclient-private.h \ + eggsmclient-xsmp.c \ + $(NULL) + +libegg_la_SOURCES = \ + $(EGG_TREE_DND_FILES) \ + $(EGG_SMCLIENT_FILES) \ + $(NULL) + +libegg_la_CFLAGS = \ + -DEGG_SM_CLIENT_BACKEND_XSMP \ + -DG_LOG_DOMAIN=\""EggSMClient"\" \ + $(LIBEGG_CFLAGS) \ + $(WARNING_CFLAGS) \ + $(DISABLE_DEPRECATED) + +libegg_la_LIBADD = \ + $(LIBEGG_LIBS) \ + -lSM -lICE + +EXTRA_DIST = \ + update-from-egg.sh \ + $(NULL) + +EGG_TREE_DND_DIR = $(srcdir)/../../../libegg/libegg/treeviewutils +EGG_SMCLIENT_DIR = $(srcdir)/../../../libegg/libegg/smclient +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu cut-n-paste-code/libegg/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu cut-n-paste-code/libegg/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; for p in $$list; do \ + dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ + test "$$dir" != "$$p" || dir=.; \ + echo "rm -f \"$${dir}/so_locations\""; \ + rm -f "$${dir}/so_locations"; \ + done +libegg.la: $(libegg_la_OBJECTS) $(libegg_la_DEPENDENCIES) + $(AM_V_CCLD)$(libegg_la_LINK) $(libegg_la_OBJECTS) $(libegg_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libegg_la-eggdesktopfile.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libegg_la-eggsmclient-xsmp.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libegg_la-eggsmclient.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libegg_la-eggtreemultidnd.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +libegg_la-eggtreemultidnd.lo: eggtreemultidnd.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libegg_la_CFLAGS) $(CFLAGS) -MT libegg_la-eggtreemultidnd.lo -MD -MP -MF $(DEPDIR)/libegg_la-eggtreemultidnd.Tpo -c -o libegg_la-eggtreemultidnd.lo `test -f 'eggtreemultidnd.c' || echo '$(srcdir)/'`eggtreemultidnd.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libegg_la-eggtreemultidnd.Tpo $(DEPDIR)/libegg_la-eggtreemultidnd.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='eggtreemultidnd.c' object='libegg_la-eggtreemultidnd.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libegg_la_CFLAGS) $(CFLAGS) -c -o libegg_la-eggtreemultidnd.lo `test -f 'eggtreemultidnd.c' || echo '$(srcdir)/'`eggtreemultidnd.c + +libegg_la-eggdesktopfile.lo: eggdesktopfile.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libegg_la_CFLAGS) $(CFLAGS) -MT libegg_la-eggdesktopfile.lo -MD -MP -MF $(DEPDIR)/libegg_la-eggdesktopfile.Tpo -c -o libegg_la-eggdesktopfile.lo `test -f 'eggdesktopfile.c' || echo '$(srcdir)/'`eggdesktopfile.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libegg_la-eggdesktopfile.Tpo $(DEPDIR)/libegg_la-eggdesktopfile.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='eggdesktopfile.c' object='libegg_la-eggdesktopfile.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libegg_la_CFLAGS) $(CFLAGS) -c -o libegg_la-eggdesktopfile.lo `test -f 'eggdesktopfile.c' || echo '$(srcdir)/'`eggdesktopfile.c + +libegg_la-eggsmclient.lo: eggsmclient.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libegg_la_CFLAGS) $(CFLAGS) -MT libegg_la-eggsmclient.lo -MD -MP -MF $(DEPDIR)/libegg_la-eggsmclient.Tpo -c -o libegg_la-eggsmclient.lo `test -f 'eggsmclient.c' || echo '$(srcdir)/'`eggsmclient.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libegg_la-eggsmclient.Tpo $(DEPDIR)/libegg_la-eggsmclient.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='eggsmclient.c' object='libegg_la-eggsmclient.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libegg_la_CFLAGS) $(CFLAGS) -c -o libegg_la-eggsmclient.lo `test -f 'eggsmclient.c' || echo '$(srcdir)/'`eggsmclient.c + +libegg_la-eggsmclient-xsmp.lo: eggsmclient-xsmp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libegg_la_CFLAGS) $(CFLAGS) -MT libegg_la-eggsmclient-xsmp.lo -MD -MP -MF $(DEPDIR)/libegg_la-eggsmclient-xsmp.Tpo -c -o libegg_la-eggsmclient-xsmp.lo `test -f 'eggsmclient-xsmp.c' || echo '$(srcdir)/'`eggsmclient-xsmp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libegg_la-eggsmclient-xsmp.Tpo $(DEPDIR)/libegg_la-eggsmclient-xsmp.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='eggsmclient-xsmp.c' object='libegg_la-eggsmclient-xsmp.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libegg_la_CFLAGS) $(CFLAGS) -c -o libegg_la-eggsmclient-xsmp.lo `test -f 'eggsmclient-xsmp.c' || echo '$(srcdir)/'`eggsmclient-xsmp.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-noinstLTLIBRARIES ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am + + +regenerate-built-sources: + EGGFILES="$(EGG_TREE_DND_FILES)" EGGDIR="$(EGG_TREE_DND_DIR)" $(srcdir)/update-from-egg.sh + EGGFILES="$(EGG_SMCLIENT_FILES)" EGGDIR="$(EGG_SMCLIENT_DIR)" $(srcdir)/update-from-egg.sh + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/cut-n-paste-code/libegg/eggdesktopfile.c b/cut-n-paste-code/libegg/eggdesktopfile.c new file mode 100644 index 00000000..6e9cf44d --- /dev/null +++ b/cut-n-paste-code/libegg/eggdesktopfile.c @@ -0,0 +1,1477 @@ +/* eggdesktopfile.c - Freedesktop.Org Desktop Files + * Copyright (C) 2007 Novell, Inc. + * + * Based on mate-desktop-item.c + * Copyright (C) 1999, 2000 Red Hat Inc. + * Copyright (C) 2001 George Lebl + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; see the file COPYING.LIB. If not, + * write to the Free Software Foundation, Inc., 59 Temple Place - + * Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "eggdesktopfile.h" + +#include +#include + +#include +#include +#include + +struct EggDesktopFile +{ + GKeyFile *key_file; + char *source; + + char *name, *icon; + EggDesktopFileType type; + char document_code; +}; + +/** + * egg_desktop_file_new: + * @desktop_file_path: path to a Freedesktop-style Desktop file + * @error: error pointer + * + * Creates a new #EggDesktopFile for @desktop_file. + * + * Return value: the new #EggDesktopFile, or %NULL on error. + **/ +EggDesktopFile * +egg_desktop_file_new (const char *desktop_file_path, GError **error) +{ + GKeyFile *key_file; + + key_file = g_key_file_new (); + if (!g_key_file_load_from_file (key_file, desktop_file_path, 0, error)) + { + g_key_file_free (key_file); + return NULL; + } + + return egg_desktop_file_new_from_key_file (key_file, desktop_file_path, + error); +} + +/** + * egg_desktop_file_new_from_data_dirs: + * @desktop_file_path: relative path to a Freedesktop-style Desktop file + * @error: error pointer + * + * Looks for @desktop_file_path in the paths returned from + * g_get_user_data_dir() and g_get_system_data_dirs(), and creates + * a new #EggDesktopFile from it. + * + * Return value: the new #EggDesktopFile, or %NULL on error. + **/ +EggDesktopFile * +egg_desktop_file_new_from_data_dirs (const char *desktop_file_path, + GError **error) +{ + EggDesktopFile *desktop_file; + GKeyFile *key_file; + char *full_path; + + key_file = g_key_file_new (); + if (!g_key_file_load_from_data_dirs (key_file, desktop_file_path, + &full_path, 0, error)) + { + g_key_file_free (key_file); + return NULL; + } + + desktop_file = egg_desktop_file_new_from_key_file (key_file, + full_path, + error); + g_free (full_path); + return desktop_file; +} + +/** + * egg_desktop_file_new_from_dirs: + * @desktop_file_path: relative path to a Freedesktop-style Desktop file + * @search_dirs: NULL-terminated array of directories to search + * @error: error pointer + * + * Looks for @desktop_file_path in the paths returned from + * g_get_user_data_dir() and g_get_system_data_dirs(), and creates + * a new #EggDesktopFile from it. + * + * Return value: the new #EggDesktopFile, or %NULL on error. + **/ +EggDesktopFile * +egg_desktop_file_new_from_dirs (const char *desktop_file_path, + const char **search_dirs, + GError **error) +{ + EggDesktopFile *desktop_file; + GKeyFile *key_file; + char *full_path; + + key_file = g_key_file_new (); + if (!g_key_file_load_from_dirs (key_file, desktop_file_path, search_dirs, + &full_path, 0, error)) + { + g_key_file_free (key_file); + return NULL; + } + + desktop_file = egg_desktop_file_new_from_key_file (key_file, + full_path, + error); + g_free (full_path); + return desktop_file; +} + +/** + * egg_desktop_file_new_from_key_file: + * @key_file: a #GKeyFile representing a desktop file + * @source: the path or URI that @key_file was loaded from, or %NULL + * @error: error pointer + * + * Creates a new #EggDesktopFile for @key_file. Assumes ownership of + * @key_file (on success or failure); you should consider @key_file to + * be freed after calling this function. + * + * Return value: the new #EggDesktopFile, or %NULL on error. + **/ +EggDesktopFile * +egg_desktop_file_new_from_key_file (GKeyFile *key_file, + const char *source, + GError **error) +{ + EggDesktopFile *desktop_file; + char *version, *type; + + if (!g_key_file_has_group (key_file, EGG_DESKTOP_FILE_GROUP)) + { + g_set_error (error, EGG_DESKTOP_FILE_ERROR, + EGG_DESKTOP_FILE_ERROR_INVALID, + _("File is not a valid .desktop file")); + g_key_file_free (key_file); + return NULL; + } + + version = g_key_file_get_value (key_file, EGG_DESKTOP_FILE_GROUP, + EGG_DESKTOP_FILE_KEY_VERSION, + NULL); + if (version) + { + double version_num; + char *end; + + version_num = g_ascii_strtod (version, &end); + if (*end) + { + g_warning ("Invalid Version string '%s' in %s", + version, source ? source : "(unknown)"); + } + else if (version_num > 1.0) + { + g_set_error (error, EGG_DESKTOP_FILE_ERROR, + EGG_DESKTOP_FILE_ERROR_INVALID, + _("Unrecognized desktop file Version '%s'"), version); + g_free (version); + g_key_file_free (key_file); + return NULL; + } + g_free (version); + } + + desktop_file = g_new0 (EggDesktopFile, 1); + desktop_file->key_file = key_file; + + if (g_path_is_absolute (source)) + desktop_file->source = g_filename_to_uri (source, NULL, NULL); + else + desktop_file->source = g_strdup (source); + + desktop_file->name = g_key_file_get_string (key_file, EGG_DESKTOP_FILE_GROUP, + EGG_DESKTOP_FILE_KEY_NAME, error); + if (!desktop_file->name) + { + egg_desktop_file_free (desktop_file); + return NULL; + } + + type = g_key_file_get_string (key_file, EGG_DESKTOP_FILE_GROUP, + EGG_DESKTOP_FILE_KEY_TYPE, error); + if (!type) + { + egg_desktop_file_free (desktop_file); + return NULL; + } + + if (!strcmp (type, "Application")) + { + char *exec, *p; + + desktop_file->type = EGG_DESKTOP_FILE_TYPE_APPLICATION; + + exec = g_key_file_get_string (key_file, + EGG_DESKTOP_FILE_GROUP, + EGG_DESKTOP_FILE_KEY_EXEC, + error); + if (!exec) + { + egg_desktop_file_free (desktop_file); + g_free (type); + return NULL; + } + + /* See if it takes paths or URIs or neither */ + for (p = exec; *p; p++) + { + if (*p == '%') + { + if (p[1] == '\0' || strchr ("FfUu", p[1])) + { + desktop_file->document_code = p[1]; + break; + } + p++; + } + } + + g_free (exec); + } + else if (!strcmp (type, "Link")) + { + char *url; + + desktop_file->type = EGG_DESKTOP_FILE_TYPE_LINK; + + url = g_key_file_get_string (key_file, + EGG_DESKTOP_FILE_GROUP, + EGG_DESKTOP_FILE_KEY_URL, + error); + if (!url) + { + egg_desktop_file_free (desktop_file); + g_free (type); + return NULL; + } + g_free (url); + } + else if (!strcmp (type, "Directory")) + desktop_file->type = EGG_DESKTOP_FILE_TYPE_DIRECTORY; + else + desktop_file->type = EGG_DESKTOP_FILE_TYPE_UNRECOGNIZED; + + g_free (type); + + /* Check the Icon key */ + desktop_file->icon = g_key_file_get_string (key_file, + EGG_DESKTOP_FILE_GROUP, + EGG_DESKTOP_FILE_KEY_ICON, + NULL); + if (desktop_file->icon && !g_path_is_absolute (desktop_file->icon)) + { + char *ext; + + /* Lots of .desktop files still get this wrong */ + ext = strrchr (desktop_file->icon, '.'); + if (ext && (!strcmp (ext, ".png") || + !strcmp (ext, ".xpm") || + !strcmp (ext, ".svg"))) + { + g_warning ("Desktop file '%s' has malformed Icon key '%s'" + "(should not include extension)", + source ? source : "(unknown)", + desktop_file->icon); + *ext = '\0'; + } + } + + return desktop_file; +} + +/** + * egg_desktop_file_free: + * @desktop_file: an #EggDesktopFile + * + * Frees @desktop_file. + **/ +void +egg_desktop_file_free (EggDesktopFile *desktop_file) +{ + g_key_file_free (desktop_file->key_file); + g_free (desktop_file->source); + g_free (desktop_file->name); + g_free (desktop_file->icon); + g_free (desktop_file); +} + +/** + * egg_desktop_file_get_source: + * @desktop_file: an #EggDesktopFile + * + * Gets the URI that @desktop_file was loaded from. + * + * Return value: @desktop_file's source URI + **/ +const char * +egg_desktop_file_get_source (EggDesktopFile *desktop_file) +{ + return desktop_file->source; +} + +/** + * egg_desktop_file_get_desktop_file_type: + * @desktop_file: an #EggDesktopFile + * + * Gets the desktop file type of @desktop_file. + * + * Return value: @desktop_file's type + **/ +EggDesktopFileType +egg_desktop_file_get_desktop_file_type (EggDesktopFile *desktop_file) +{ + return desktop_file->type; +} + +/** + * egg_desktop_file_get_name: + * @desktop_file: an #EggDesktopFile + * + * Gets the (localized) value of @desktop_file's "Name" key. + * + * Return value: the application/link name + **/ +const char * +egg_desktop_file_get_name (EggDesktopFile *desktop_file) +{ + return desktop_file->name; +} + +/** + * egg_desktop_file_get_icon: + * @desktop_file: an #EggDesktopFile + * + * Gets the value of @desktop_file's "Icon" key. + * + * If the icon string is a full path (that is, if g_path_is_absolute() + * returns %TRUE when called on it), it points to a file containing an + * unthemed icon. If the icon string is not a full path, it is the + * name of a themed icon, which can be looked up with %GtkIconTheme, + * or passed directly to a theme-aware widget like %GtkImage or + * %GtkCellRendererPixbuf. + * + * Return value: the icon path or name + **/ +const char * +egg_desktop_file_get_icon (EggDesktopFile *desktop_file) +{ + return desktop_file->icon; +} + +gboolean +egg_desktop_file_has_key (EggDesktopFile *desktop_file, + const char *key, + GError **error) +{ + return g_key_file_has_key (desktop_file->key_file, + EGG_DESKTOP_FILE_GROUP, key, + error); +} + +char * +egg_desktop_file_get_string (EggDesktopFile *desktop_file, + const char *key, + GError **error) +{ + return g_key_file_get_string (desktop_file->key_file, + EGG_DESKTOP_FILE_GROUP, key, + error); +} + +char * +egg_desktop_file_get_locale_string (EggDesktopFile *desktop_file, + const char *key, + const char *locale, + GError **error) +{ + return g_key_file_get_locale_string (desktop_file->key_file, + EGG_DESKTOP_FILE_GROUP, key, locale, + error); +} + +gboolean +egg_desktop_file_get_boolean (EggDesktopFile *desktop_file, + const char *key, + GError **error) +{ + return g_key_file_get_boolean (desktop_file->key_file, + EGG_DESKTOP_FILE_GROUP, key, + error); +} + +double +egg_desktop_file_get_numeric (EggDesktopFile *desktop_file, + const char *key, + GError **error) +{ + return g_key_file_get_double (desktop_file->key_file, + EGG_DESKTOP_FILE_GROUP, key, + error); +} + +char ** +egg_desktop_file_get_string_list (EggDesktopFile *desktop_file, + const char *key, + gsize *length, + GError **error) +{ + return g_key_file_get_string_list (desktop_file->key_file, + EGG_DESKTOP_FILE_GROUP, key, length, + error); +} + +char ** +egg_desktop_file_get_locale_string_list (EggDesktopFile *desktop_file, + const char *key, + const char *locale, + gsize *length, + GError **error) +{ + return g_key_file_get_locale_string_list (desktop_file->key_file, + EGG_DESKTOP_FILE_GROUP, key, + locale, length, + error); +} + +/** + * egg_desktop_file_can_launch: + * @desktop_file: an #EggDesktopFile + * @desktop_environment: the name of the running desktop environment, + * or %NULL + * + * Tests if @desktop_file can/should be launched in the current + * environment. If @desktop_environment is non-%NULL, @desktop_file's + * "OnlyShowIn" and "NotShowIn" keys are checked to make sure that + * this desktop_file is appropriate for the named environment. + * + * Furthermore, if @desktop_file has type + * %EGG_DESKTOP_FILE_TYPE_APPLICATION, its "TryExec" key (if any) is + * also checked, to make sure the binary it points to exists. + * + * egg_desktop_file_can_launch() does NOT check the value of the + * "Hidden" key. + * + * Return value: %TRUE if @desktop_file can be launched + **/ +gboolean +egg_desktop_file_can_launch (EggDesktopFile *desktop_file, + const char *desktop_environment) +{ + char *try_exec, *found_program; + char **only_show_in, **not_show_in; + gboolean found; + int i; + + if (desktop_file->type != EGG_DESKTOP_FILE_TYPE_APPLICATION && + desktop_file->type != EGG_DESKTOP_FILE_TYPE_LINK) + return FALSE; + + if (desktop_environment) + { + only_show_in = g_key_file_get_string_list (desktop_file->key_file, + EGG_DESKTOP_FILE_GROUP, + EGG_DESKTOP_FILE_KEY_ONLY_SHOW_IN, + NULL, NULL); + if (only_show_in) + { + for (i = 0, found = FALSE; only_show_in[i] && !found; i++) + { + if (!strcmp (only_show_in[i], desktop_environment)) + found = TRUE; + } + + g_strfreev (only_show_in); + + if (!found) + return FALSE; + } + + not_show_in = g_key_file_get_string_list (desktop_file->key_file, + EGG_DESKTOP_FILE_GROUP, + EGG_DESKTOP_FILE_KEY_NOT_SHOW_IN, + NULL, NULL); + if (not_show_in) + { + for (i = 0, found = FALSE; not_show_in[i] && !found; i++) + { + if (!strcmp (not_show_in[i], desktop_environment)) + found = TRUE; + } + + g_strfreev (not_show_in); + + if (found) + return FALSE; + } + } + + if (desktop_file->type == EGG_DESKTOP_FILE_TYPE_APPLICATION) + { + try_exec = g_key_file_get_string (desktop_file->key_file, + EGG_DESKTOP_FILE_GROUP, + EGG_DESKTOP_FILE_KEY_TRY_EXEC, + NULL); + if (try_exec) + { + found_program = g_find_program_in_path (try_exec); + g_free (try_exec); + + if (!found_program) + return FALSE; + g_free (found_program); + } + } + + return TRUE; +} + +/** + * egg_desktop_file_accepts_documents: + * @desktop_file: an #EggDesktopFile + * + * Tests if @desktop_file represents an application that can accept + * documents on the command line. + * + * Return value: %TRUE or %FALSE + **/ +gboolean +egg_desktop_file_accepts_documents (EggDesktopFile *desktop_file) +{ + return desktop_file->document_code != 0; +} + +/** + * egg_desktop_file_accepts_multiple: + * @desktop_file: an #EggDesktopFile + * + * Tests if @desktop_file can accept multiple documents at once. + * + * If this returns %FALSE, you can still pass multiple documents to + * egg_desktop_file_launch(), but that will result in multiple copies + * of the application being launched. See egg_desktop_file_launch() + * for more details. + * + * Return value: %TRUE or %FALSE + **/ +gboolean +egg_desktop_file_accepts_multiple (EggDesktopFile *desktop_file) +{ + return (desktop_file->document_code == 'F' || + desktop_file->document_code == 'U'); +} + +/** + * egg_desktop_file_accepts_uris: + * @desktop_file: an #EggDesktopFile + * + * Tests if @desktop_file can accept (non-"file:") URIs as documents to + * open. + * + * Return value: %TRUE or %FALSE + **/ +gboolean +egg_desktop_file_accepts_uris (EggDesktopFile *desktop_file) +{ + return (desktop_file->document_code == 'U' || + desktop_file->document_code == 'u'); +} + +static void +append_quoted_word (GString *str, + const char *s, + gboolean in_single_quotes, + gboolean in_double_quotes) +{ + const char *p; + + if (!in_single_quotes && !in_double_quotes) + g_string_append_c (str, '\''); + else if (!in_single_quotes && in_double_quotes) + g_string_append (str, "\"'"); + + if (!strchr (s, '\'')) + g_string_append (str, s); + else + { + for (p = s; *p != '\0'; p++) + { + if (*p == '\'') + g_string_append (str, "'\\''"); + else + g_string_append_c (str, *p); + } + } + + if (!in_single_quotes && !in_double_quotes) + g_string_append_c (str, '\''); + else if (!in_single_quotes && in_double_quotes) + g_string_append (str, "'\""); +} + +static void +do_percent_subst (EggDesktopFile *desktop_file, + char code, + GString *str, + GSList **documents, + gboolean in_single_quotes, + gboolean in_double_quotes) +{ + GSList *d; + char *doc; + + switch (code) + { + case '%': + g_string_append_c (str, '%'); + break; + + case 'F': + case 'U': + for (d = *documents; d; d = d->next) + { + doc = d->data; + g_string_append (str, " "); + append_quoted_word (str, doc, in_single_quotes, in_double_quotes); + } + *documents = NULL; + break; + + case 'f': + case 'u': + if (*documents) + { + doc = (*documents)->data; + g_string_append (str, " "); + append_quoted_word (str, doc, in_single_quotes, in_double_quotes); + *documents = (*documents)->next; + } + break; + + case 'i': + if (desktop_file->icon) + { + g_string_append (str, "--icon "); + append_quoted_word (str, desktop_file->icon, + in_single_quotes, in_double_quotes); + } + break; + + case 'c': + if (desktop_file->name) + { + append_quoted_word (str, desktop_file->name, + in_single_quotes, in_double_quotes); + } + break; + + case 'k': + if (desktop_file->source) + { + append_quoted_word (str, desktop_file->source, + in_single_quotes, in_double_quotes); + } + break; + + case 'D': + case 'N': + case 'd': + case 'n': + case 'v': + case 'm': + /* Deprecated; skip */ + break; + + default: + g_warning ("Unrecognized %%-code '%%%c' in Exec", code); + break; + } +} + +static char * +parse_exec (EggDesktopFile *desktop_file, + GSList **documents, + GError **error) +{ + char *exec, *p, *command; + gboolean escape, single_quot, double_quot; + GString *gs; + + exec = g_key_file_get_string (desktop_file->key_file, + EGG_DESKTOP_FILE_GROUP, + EGG_DESKTOP_FILE_KEY_EXEC, + error); + if (!exec) + return NULL; + + /* Build the command */ + gs = g_string_new (NULL); + escape = single_quot = double_quot = FALSE; + + for (p = exec; *p != '\0'; p++) + { + if (escape) + { + escape = FALSE; + g_string_append_c (gs, *p); + } + else if (*p == '\\') + { + if (!single_quot) + escape = TRUE; + g_string_append_c (gs, *p); + } + else if (*p == '\'') + { + g_string_append_c (gs, *p); + if (!single_quot && !double_quot) + single_quot = TRUE; + else if (single_quot) + single_quot = FALSE; + } + else if (*p == '"') + { + g_string_append_c (gs, *p); + if (!single_quot && !double_quot) + double_quot = TRUE; + else if (double_quot) + double_quot = FALSE; + } + else if (*p == '%' && p[1]) + { + do_percent_subst (desktop_file, p[1], gs, documents, + single_quot, double_quot); + p++; + } + else + g_string_append_c (gs, *p); + } + + g_free (exec); + command = g_string_free (gs, FALSE); + + /* Prepend "xdg-terminal " if needed (FIXME: use gvfs) */ + if (g_key_file_has_key (desktop_file->key_file, + EGG_DESKTOP_FILE_GROUP, + EGG_DESKTOP_FILE_KEY_TERMINAL, + NULL)) + { + GError *terminal_error = NULL; + gboolean use_terminal = + g_key_file_get_boolean (desktop_file->key_file, + EGG_DESKTOP_FILE_GROUP, + EGG_DESKTOP_FILE_KEY_TERMINAL, + &terminal_error); + if (terminal_error) + { + g_free (command); + g_propagate_error (error, terminal_error); + return NULL; + } + + if (use_terminal) + { + gs = g_string_new ("xdg-terminal "); + append_quoted_word (gs, command, FALSE, FALSE); + g_free (command); + command = g_string_free (gs, FALSE); + } + } + + return command; +} + +static GSList * +translate_document_list (EggDesktopFile *desktop_file, GSList *documents) +{ + gboolean accepts_uris = egg_desktop_file_accepts_uris (desktop_file); + GSList *ret, *d; + + for (d = documents, ret = NULL; d; d = d->next) + { + const char *document = d->data; + gboolean is_uri = !g_path_is_absolute (document); + char *translated; + + if (accepts_uris) + { + if (is_uri) + translated = g_strdup (document); + else + translated = g_filename_to_uri (document, NULL, NULL); + } + else + { + if (is_uri) + translated = g_filename_from_uri (document, NULL, NULL); + else + translated = g_strdup (document); + } + + if (translated) + ret = g_slist_prepend (ret, translated); + } + + return g_slist_reverse (ret); +} + +static void +free_document_list (GSList *documents) +{ + GSList *d; + + for (d = documents; d; d = d->next) + g_free (d->data); + g_slist_free (documents); +} + +/** + * egg_desktop_file_parse_exec: + * @desktop_file: a #EggDesktopFile + * @documents: a list of document paths or URIs + * @error: error pointer + * + * Parses @desktop_file's Exec key, inserting @documents into it, and + * returns the result. + * + * If @documents contains non-file: URIs and @desktop_file does not + * accept URIs, those URIs will be ignored. Likewise, if @documents + * contains more elements than @desktop_file accepts, the extra + * documents will be ignored. + * + * Return value: the parsed Exec string + **/ +char * +egg_desktop_file_parse_exec (EggDesktopFile *desktop_file, + GSList *documents, + GError **error) +{ + GSList *translated, *docs; + char *command; + + docs = translated = translate_document_list (desktop_file, documents); + command = parse_exec (desktop_file, &docs, error); + free_document_list (translated); + + return command; +} + +static gboolean +parse_link (EggDesktopFile *desktop_file, + EggDesktopFile **app_desktop_file, + GSList **documents, + GError **error) +{ + char *url; + GKeyFile *key_file; + + url = g_key_file_get_string (desktop_file->key_file, + EGG_DESKTOP_FILE_GROUP, + EGG_DESKTOP_FILE_KEY_URL, + error); + if (!url) + return FALSE; + *documents = g_slist_prepend (NULL, url); + + /* FIXME: use gvfs */ + key_file = g_key_file_new (); + g_key_file_set_string (key_file, EGG_DESKTOP_FILE_GROUP, + EGG_DESKTOP_FILE_KEY_NAME, + "xdg-open"); + g_key_file_set_string (key_file, EGG_DESKTOP_FILE_GROUP, + EGG_DESKTOP_FILE_KEY_TYPE, + "Application"); + g_key_file_set_string (key_file, EGG_DESKTOP_FILE_GROUP, + EGG_DESKTOP_FILE_KEY_EXEC, + "xdg-open %u"); + *app_desktop_file = egg_desktop_file_new_from_key_file (key_file, NULL, NULL); + return TRUE; +} + +#if GTK_CHECK_VERSION (2, 12, 0) +static char * +start_startup_notification (GdkDisplay *display, + EggDesktopFile *desktop_file, + const char *argv0, + int screen, + int workspace, + guint32 launch_time) +{ + static int sequence = 0; + char *startup_id; + char *description, *wmclass; + char *screen_str, *workspace_str; + + if (g_key_file_has_key (desktop_file->key_file, + EGG_DESKTOP_FILE_GROUP, + EGG_DESKTOP_FILE_KEY_STARTUP_NOTIFY, + NULL)) + { + if (!g_key_file_get_boolean (desktop_file->key_file, + EGG_DESKTOP_FILE_GROUP, + EGG_DESKTOP_FILE_KEY_STARTUP_NOTIFY, + NULL)) + return NULL; + wmclass = NULL; + } + else + { + wmclass = g_key_file_get_string (desktop_file->key_file, + EGG_DESKTOP_FILE_GROUP, + EGG_DESKTOP_FILE_KEY_STARTUP_WM_CLASS, + NULL); + if (!wmclass) + return NULL; + } + + if (launch_time == (guint32)-1) + launch_time = gdk_x11_display_get_user_time (display); + startup_id = g_strdup_printf ("%s-%lu-%s-%s-%d_TIME%lu", + g_get_prgname (), + (unsigned long)getpid (), + g_get_host_name (), + argv0, + sequence++, + (unsigned long)launch_time); + + description = g_strdup_printf (_("Starting %s"), desktop_file->name); + screen_str = g_strdup_printf ("%d", screen); + workspace_str = workspace == -1 ? NULL : g_strdup_printf ("%d", workspace); + + gdk_x11_display_broadcast_startup_message (display, "new", + "ID", startup_id, + "NAME", desktop_file->name, + "SCREEN", screen_str, + "BIN", argv0, + "ICON", desktop_file->icon, + "DESKTOP", workspace_str, + "DESCRIPTION", description, + "WMCLASS", wmclass, + NULL); + + g_free (description); + g_free (wmclass); + g_free (screen_str); + g_free (workspace_str); + + return startup_id; +} + +static void +end_startup_notification (GdkDisplay *display, + const char *startup_id) +{ + gdk_x11_display_broadcast_startup_message (display, "remove", + "ID", startup_id, + NULL); +} + +#define EGG_DESKTOP_FILE_SN_TIMEOUT_LENGTH (30 /* seconds */ * 1000) + +typedef struct +{ + GdkDisplay *display; + char *startup_id; +} StartupNotificationData; + +static gboolean +startup_notification_timeout (gpointer data) +{ + StartupNotificationData *sn_data = data; + + end_startup_notification (sn_data->display, sn_data->startup_id); + g_object_unref (sn_data->display); + g_free (sn_data->startup_id); + g_free (sn_data); + + return FALSE; +} + +static void +set_startup_notification_timeout (GdkDisplay *display, + const char *startup_id) +{ + StartupNotificationData *sn_data; + + sn_data = g_new (StartupNotificationData, 1); + sn_data->display = g_object_ref (display); + sn_data->startup_id = g_strdup (startup_id); + + g_timeout_add (EGG_DESKTOP_FILE_SN_TIMEOUT_LENGTH, + startup_notification_timeout, sn_data); +} +#endif /* GTK 2.12 */ + +static GPtrArray * +array_putenv (GPtrArray *env, char *variable) +{ + int i, keylen; + + if (!env) + { + char **envp; + + env = g_ptr_array_new (); + + envp = g_listenv (); + for (i = 0; envp[i]; i++) + { + const char *value; + + value = g_getenv (envp[i]); + g_ptr_array_add (env, g_strdup_printf ("%s=%s", envp[i], + value ? value : "")); + } + g_strfreev (envp); + } + + keylen = strcspn (variable, "="); + + /* Remove old value of key */ + for (i = 0; i < env->len; i++) + { + char *envvar = env->pdata[i]; + + if (!strncmp (envvar, variable, keylen) && envvar[keylen] == '=') + { + g_free (envvar); + g_ptr_array_remove_index_fast (env, i); + break; + } + } + + /* Add new value */ + g_ptr_array_add (env, g_strdup (variable)); + + return env; +} + +static gboolean +egg_desktop_file_launchv (EggDesktopFile *desktop_file, + GSList *documents, va_list args, + GError **error) +{ + EggDesktopFileLaunchOption option; + GSList *translated_documents = NULL, *docs; + char *command, **argv; + int argc, i, screen_num; + gboolean success, current_success; + GdkDisplay *display; + char *startup_id; + + GPtrArray *env = NULL; + char **variables = NULL; + GdkScreen *screen = NULL; + int workspace = -1; + const char *directory = NULL; + guint32 launch_time = (guint32)-1; + GSpawnFlags flags = G_SPAWN_SEARCH_PATH; + GSpawnChildSetupFunc setup_func = NULL; + gpointer setup_data = NULL; + + GPid *ret_pid = NULL; + int *ret_stdin = NULL, *ret_stdout = NULL, *ret_stderr = NULL; + char **ret_startup_id = NULL; + + if (documents && desktop_file->document_code == 0) + { + g_set_error (error, EGG_DESKTOP_FILE_ERROR, + EGG_DESKTOP_FILE_ERROR_NOT_LAUNCHABLE, + _("Application does not accept documents on command line")); + return FALSE; + } + + /* Read the options: technically it's incorrect for the caller to + * NULL-terminate the list of options (rather than 0-terminating + * it), but NULL-terminating lets us use G_GNUC_NULL_TERMINATED, + * it's more consistent with other glib/gtk methods, and it will + * work as long as sizeof (int) <= sizeof (NULL), and NULL is + * represented as 0. (Which is true everywhere we care about.) + */ + while ((option = va_arg (args, EggDesktopFileLaunchOption))) + { + switch (option) + { + case EGG_DESKTOP_FILE_LAUNCH_CLEARENV: + if (env) + g_ptr_array_free (env, TRUE); + env = g_ptr_array_new (); + break; + case EGG_DESKTOP_FILE_LAUNCH_PUTENV: + variables = va_arg (args, char **); + for (i = 0; variables[i]; i++) + env = array_putenv (env, variables[i]); + break; + + case EGG_DESKTOP_FILE_LAUNCH_SCREEN: + screen = va_arg (args, GdkScreen *); + break; + case EGG_DESKTOP_FILE_LAUNCH_WORKSPACE: + workspace = va_arg (args, int); + break; + + case EGG_DESKTOP_FILE_LAUNCH_DIRECTORY: + directory = va_arg (args, const char *); + break; + case EGG_DESKTOP_FILE_LAUNCH_TIME: + launch_time = va_arg (args, guint32); + break; + case EGG_DESKTOP_FILE_LAUNCH_FLAGS: + flags |= va_arg (args, GSpawnFlags); + /* Make sure they didn't set any flags that don't make sense. */ + flags &= ~G_SPAWN_FILE_AND_ARGV_ZERO; + break; + case EGG_DESKTOP_FILE_LAUNCH_SETUP_FUNC: + setup_func = va_arg (args, GSpawnChildSetupFunc); + setup_data = va_arg (args, gpointer); + break; + + case EGG_DESKTOP_FILE_LAUNCH_RETURN_PID: + ret_pid = va_arg (args, GPid *); + break; + case EGG_DESKTOP_FILE_LAUNCH_RETURN_STDIN_PIPE: + ret_stdin = va_arg (args, int *); + break; + case EGG_DESKTOP_FILE_LAUNCH_RETURN_STDOUT_PIPE: + ret_stdout = va_arg (args, int *); + break; + case EGG_DESKTOP_FILE_LAUNCH_RETURN_STDERR_PIPE: + ret_stderr = va_arg (args, int *); + break; + case EGG_DESKTOP_FILE_LAUNCH_RETURN_STARTUP_ID: + ret_startup_id = va_arg (args, char **); + break; + + default: + g_set_error (error, EGG_DESKTOP_FILE_ERROR, + EGG_DESKTOP_FILE_ERROR_UNRECOGNIZED_OPTION, + _("Unrecognized launch option: %d"), + GPOINTER_TO_INT (option)); + success = FALSE; + goto out; + } + } + + if (screen) + { + char *display_name = gdk_screen_make_display_name (screen); + char *display_env = g_strdup_printf ("DISPLAY=%s", display_name); + env = array_putenv (env, display_env); + g_free (display_name); + g_free (display_env); + + display = gdk_screen_get_display (screen); + } + else + { + display = gdk_display_get_default (); + screen = gdk_display_get_default_screen (display); + } + screen_num = gdk_screen_get_number (screen); + + translated_documents = translate_document_list (desktop_file, documents); + docs = translated_documents; + + success = FALSE; + + do + { + command = parse_exec (desktop_file, &docs, error); + if (!command) + goto out; + + if (!g_shell_parse_argv (command, &argc, &argv, error)) + { + g_free (command); + goto out; + } + g_free (command); + +#if GTK_CHECK_VERSION (2, 12, 0) + startup_id = start_startup_notification (display, desktop_file, + argv[0], screen_num, + workspace, launch_time); + if (startup_id) + { + char *startup_id_env = g_strdup_printf ("DESKTOP_STARTUP_ID=%s", + startup_id); + env = array_putenv (env, startup_id_env); + g_free (startup_id_env); + } +#else + startup_id = NULL; +#endif /* GTK 2.12 */ + + if (env != NULL) + g_ptr_array_add (env, NULL); + + current_success = + g_spawn_async_with_pipes (directory, + argv, + env ? (char **)(env->pdata) : NULL, + flags, + setup_func, setup_data, + ret_pid, + ret_stdin, ret_stdout, ret_stderr, + error); + g_strfreev (argv); + + if (startup_id) + { +#if GTK_CHECK_VERSION (2, 12, 0) + if (current_success) + { + set_startup_notification_timeout (display, startup_id); + + if (ret_startup_id) + *ret_startup_id = startup_id; + else + g_free (startup_id); + } + else +#endif /* GTK 2.12 */ + g_free (startup_id); + } + else if (ret_startup_id) + *ret_startup_id = NULL; + + if (current_success) + { + /* If we successfully launch any instances of the app, make + * sure we return TRUE and don't set @error. + */ + success = TRUE; + error = NULL; + + /* Also, only set the output params on the first one */ + ret_pid = NULL; + ret_stdin = ret_stdout = ret_stderr = NULL; + ret_startup_id = NULL; + } + } + while (docs && current_success); + +out: + if (env) + { + g_strfreev ((char **)env->pdata); + g_ptr_array_free (env, FALSE); + } + free_document_list (translated_documents); + + return success; +} + +/** + * egg_desktop_file_launch: + * @desktop_file: an #EggDesktopFile + * @documents: a list of URIs or paths to documents to open + * @error: error pointer + * @...: additional options + * + * Launches @desktop_file with the given arguments. Additional options + * can be specified as follows: + * + * %EGG_DESKTOP_FILE_LAUNCH_CLEARENV: (no arguments) + * clears the environment in the child process + * %EGG_DESKTOP_FILE_LAUNCH_PUTENV: (char **variables) + * adds the NAME=VALUE strings in the given %NULL-terminated + * array to the child process's environment + * %EGG_DESKTOP_FILE_LAUNCH_SCREEN: (GdkScreen *screen) + * causes the application to be launched on the given screen + * %EGG_DESKTOP_FILE_LAUNCH_WORKSPACE: (int workspace) + * causes the application to be launched on the given workspace + * %EGG_DESKTOP_FILE_LAUNCH_DIRECTORY: (char *dir) + * causes the application to be launched in the given directory + * %EGG_DESKTOP_FILE_LAUNCH_TIME: (guint32 launch_time) + * sets the "launch time" for the application. If the user + * interacts with another window after @launch_time but before + * the launched application creates its first window, the window + * manager may choose to not give focus to the new application. + * Passing 0 for @launch_time will explicitly request that the + * application not receive focus. + * %EGG_DESKTOP_FILE_LAUNCH_FLAGS (GSpawnFlags flags) + * Sets additional #GSpawnFlags to use. See g_spawn_async() for + * more details. + * %EGG_DESKTOP_FILE_LAUNCH_SETUP_FUNC (GSpawnChildSetupFunc, gpointer) + * Sets the child setup callback and the data to pass to it. + * (See g_spawn_async() for more details.) + * + * %EGG_DESKTOP_FILE_LAUNCH_RETURN_PID (GPid **pid) + * On a successful launch, sets *@pid to the PID of the launched + * application. + * %EGG_DESKTOP_FILE_LAUNCH_RETURN_STARTUP_ID (char **startup_id) + * On a successful launch, sets *@startup_id to the Startup + * Notification "startup id" of the launched application. + * %EGG_DESKTOP_FILE_LAUNCH_RETURN_STDIN_PIPE (int *fd) + * On a successful launch, sets *@fd to the file descriptor of + * a pipe connected to the application's stdin. + * %EGG_DESKTOP_FILE_LAUNCH_RETURN_STDOUT_PIPE (int *fd) + * On a successful launch, sets *@fd to the file descriptor of + * a pipe connected to the application's stdout. + * %EGG_DESKTOP_FILE_LAUNCH_RETURN_STDERR_PIPE (int *fd) + * On a successful launch, sets *@fd to the file descriptor of + * a pipe connected to the application's stderr. + * + * The options should be terminated with a single %NULL. + * + * If @documents contains multiple documents, but + * egg_desktop_file_accepts_multiple() returns %FALSE for + * @desktop_file, then egg_desktop_file_launch() will actually launch + * multiple instances of the application. In that case, the return + * value (as well as any values passed via + * %EGG_DESKTOP_FILE_LAUNCH_RETURN_PID, etc) will only reflect the + * first instance of the application that was launched (but the + * %EGG_DESKTOP_FILE_LAUNCH_SETUP_FUNC will be called for each + * instance). + * + * Return value: %TRUE if the application was successfully launched. + **/ +gboolean +egg_desktop_file_launch (EggDesktopFile *desktop_file, + GSList *documents, GError **error, + ...) +{ + va_list args; + gboolean success; + EggDesktopFile *app_desktop_file; + + switch (desktop_file->type) + { + case EGG_DESKTOP_FILE_TYPE_APPLICATION: + va_start (args, error); + success = egg_desktop_file_launchv (desktop_file, documents, + args, error); + va_end (args); + break; + + case EGG_DESKTOP_FILE_TYPE_LINK: + if (documents) + { + g_set_error (error, EGG_DESKTOP_FILE_ERROR, + EGG_DESKTOP_FILE_ERROR_NOT_LAUNCHABLE, + _("Can't pass document URIs to a 'Type=Link' desktop entry")); + return FALSE; + } + + if (!parse_link (desktop_file, &app_desktop_file, &documents, error)) + return FALSE; + + va_start (args, error); + success = egg_desktop_file_launchv (app_desktop_file, documents, + args, error); + va_end (args); + + egg_desktop_file_free (app_desktop_file); + free_document_list (documents); + break; + + default: + g_set_error (error, EGG_DESKTOP_FILE_ERROR, + EGG_DESKTOP_FILE_ERROR_NOT_LAUNCHABLE, + _("Not a launchable item")); + success = FALSE; + break; + } + + return success; +} + + +GQuark +egg_desktop_file_error_quark (void) +{ + return g_quark_from_static_string ("egg-desktop_file-error-quark"); +} + + +G_LOCK_DEFINE_STATIC (egg_desktop_file); +static EggDesktopFile *egg_desktop_file; + +/** + * egg_set_desktop_file: + * @desktop_file_path: path to the application's desktop file + * + * Creates an #EggDesktopFile for the application from the data at + * @desktop_file_path. This will also call g_set_application_name() + * with the localized application name from the desktop file, and + * gtk_window_set_default_icon_name() or + * gtk_window_set_default_icon_from_file() with the application's + * icon. Other code may use additional information from the desktop + * file. + * + * Note that for thread safety reasons, this function can only + * be called once. + **/ +void +egg_set_desktop_file (const char *desktop_file_path) +{ + GError *error = NULL; + + G_LOCK (egg_desktop_file); + if (egg_desktop_file) + egg_desktop_file_free (egg_desktop_file); + + egg_desktop_file = egg_desktop_file_new (desktop_file_path, &error); + if (error) + { + g_warning ("Could not load desktop file '%s': %s", + desktop_file_path, error->message); + g_error_free (error); + } + + /* Set localized application name and default window icon */ + if (egg_desktop_file->name) + g_set_application_name (egg_desktop_file->name); + if (egg_desktop_file->icon) + { + if (g_path_is_absolute (egg_desktop_file->icon)) + gtk_window_set_default_icon_from_file (egg_desktop_file->icon, NULL); + else + gtk_window_set_default_icon_name (egg_desktop_file->icon); + } + + G_UNLOCK (egg_desktop_file); +} + +/** + * egg_get_desktop_file: + * + * Gets the application's #EggDesktopFile, as set by + * egg_set_desktop_file(). + * + * Return value: the #EggDesktopFile, or %NULL if it hasn't been set. + **/ +EggDesktopFile * +egg_get_desktop_file (void) +{ + EggDesktopFile *retval; + + G_LOCK (egg_desktop_file); + retval = egg_desktop_file; + G_UNLOCK (egg_desktop_file); + + return retval; +} diff --git a/cut-n-paste-code/libegg/eggdesktopfile.h b/cut-n-paste-code/libegg/eggdesktopfile.h new file mode 100644 index 00000000..6a6d580a --- /dev/null +++ b/cut-n-paste-code/libegg/eggdesktopfile.h @@ -0,0 +1,166 @@ +/* eggdesktopfile.h - Freedesktop.Org Desktop Files + * Copyright (C) 2007 Novell, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; see the file COPYING.LIB. If not, + * write to the Free Software Foundation, Inc., 59 Temple Place - + * Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __EGG_DESKTOP_FILE_H__ +#define __EGG_DESKTOP_FILE_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + typedef struct EggDesktopFile EggDesktopFile; + + typedef enum + { + EGG_DESKTOP_FILE_TYPE_UNRECOGNIZED, + + EGG_DESKTOP_FILE_TYPE_APPLICATION, + EGG_DESKTOP_FILE_TYPE_LINK, + EGG_DESKTOP_FILE_TYPE_DIRECTORY + } EggDesktopFileType; + + EggDesktopFile *egg_desktop_file_new (const char *desktop_file_path, + GError **error); + + EggDesktopFile *egg_desktop_file_new_from_data_dirs (const char *desktop_file_path, + GError **error); + EggDesktopFile *egg_desktop_file_new_from_dirs (const char *desktop_file_path, + const char **search_dirs, + GError **error); + EggDesktopFile *egg_desktop_file_new_from_key_file (GKeyFile *key_file, + const char *source, + GError **error); + + void egg_desktop_file_free (EggDesktopFile *desktop_file); + + const char *egg_desktop_file_get_source (EggDesktopFile *desktop_file); + + EggDesktopFileType egg_desktop_file_get_desktop_file_type (EggDesktopFile *desktop_file); + + const char *egg_desktop_file_get_name (EggDesktopFile *desktop_file); + const char *egg_desktop_file_get_icon (EggDesktopFile *desktop_file); + + gboolean egg_desktop_file_can_launch (EggDesktopFile *desktop_file, + const char *desktop_environment); + + gboolean egg_desktop_file_accepts_documents (EggDesktopFile *desktop_file); + gboolean egg_desktop_file_accepts_multiple (EggDesktopFile *desktop_file); + gboolean egg_desktop_file_accepts_uris (EggDesktopFile *desktop_file); + + char *egg_desktop_file_parse_exec (EggDesktopFile *desktop_file, + GSList *documents, + GError **error); + + gboolean egg_desktop_file_launch (EggDesktopFile *desktop_file, + GSList *documents, + GError **error, + ...) G_GNUC_NULL_TERMINATED; + + typedef enum + { + EGG_DESKTOP_FILE_LAUNCH_CLEARENV = 1, + EGG_DESKTOP_FILE_LAUNCH_PUTENV, + EGG_DESKTOP_FILE_LAUNCH_SCREEN, + EGG_DESKTOP_FILE_LAUNCH_WORKSPACE, + EGG_DESKTOP_FILE_LAUNCH_DIRECTORY, + EGG_DESKTOP_FILE_LAUNCH_TIME, + EGG_DESKTOP_FILE_LAUNCH_FLAGS, + EGG_DESKTOP_FILE_LAUNCH_SETUP_FUNC, + EGG_DESKTOP_FILE_LAUNCH_RETURN_PID, + EGG_DESKTOP_FILE_LAUNCH_RETURN_STDIN_PIPE, + EGG_DESKTOP_FILE_LAUNCH_RETURN_STDOUT_PIPE, + EGG_DESKTOP_FILE_LAUNCH_RETURN_STDERR_PIPE, + EGG_DESKTOP_FILE_LAUNCH_RETURN_STARTUP_ID + } EggDesktopFileLaunchOption; + + /* Standard Keys */ +#define EGG_DESKTOP_FILE_GROUP "Desktop Entry" + +#define EGG_DESKTOP_FILE_KEY_TYPE "Type" +#define EGG_DESKTOP_FILE_KEY_VERSION "Version" +#define EGG_DESKTOP_FILE_KEY_NAME "Name" +#define EGG_DESKTOP_FILE_KEY_GENERIC_NAME "GenericName" +#define EGG_DESKTOP_FILE_KEY_NO_DISPLAY "NoDisplay" +#define EGG_DESKTOP_FILE_KEY_COMMENT "Comment" +#define EGG_DESKTOP_FILE_KEY_ICON "Icon" +#define EGG_DESKTOP_FILE_KEY_HIDDEN "Hidden" +#define EGG_DESKTOP_FILE_KEY_ONLY_SHOW_IN "OnlyShowIn" +#define EGG_DESKTOP_FILE_KEY_NOT_SHOW_IN "NotShowIn" +#define EGG_DESKTOP_FILE_KEY_TRY_EXEC "TryExec" +#define EGG_DESKTOP_FILE_KEY_EXEC "Exec" +#define EGG_DESKTOP_FILE_KEY_PATH "Path" +#define EGG_DESKTOP_FILE_KEY_TERMINAL "Terminal" +#define EGG_DESKTOP_FILE_KEY_MIME_TYPE "MimeType" +#define EGG_DESKTOP_FILE_KEY_CATEGORIES "Categories" +#define EGG_DESKTOP_FILE_KEY_STARTUP_NOTIFY "StartupNotify" +#define EGG_DESKTOP_FILE_KEY_STARTUP_WM_CLASS "StartupWMClass" +#define EGG_DESKTOP_FILE_KEY_URL "URL" + + /* Accessors */ + gboolean egg_desktop_file_has_key (EggDesktopFile *desktop_file, + const char *key, + GError **error); + char *egg_desktop_file_get_string (EggDesktopFile *desktop_file, + const char *key, + GError **error) G_GNUC_MALLOC; + char *egg_desktop_file_get_locale_string (EggDesktopFile *desktop_file, + const char *key, + const char *locale, + GError **error) G_GNUC_MALLOC; + gboolean egg_desktop_file_get_boolean (EggDesktopFile *desktop_file, + const char *key, + GError **error); + double egg_desktop_file_get_numeric (EggDesktopFile *desktop_file, + const char *key, + GError **error); + char **egg_desktop_file_get_string_list (EggDesktopFile *desktop_file, + const char *key, + gsize *length, + GError **error) G_GNUC_MALLOC; + char **egg_desktop_file_get_locale_string_list (EggDesktopFile *desktop_file, + const char *key, + const char *locale, + gsize *length, + GError **error) G_GNUC_MALLOC; + + + /* Errors */ +#define EGG_DESKTOP_FILE_ERROR egg_desktop_file_error_quark() + + GQuark egg_desktop_file_error_quark (void); + + typedef enum + { + EGG_DESKTOP_FILE_ERROR_INVALID, + EGG_DESKTOP_FILE_ERROR_NOT_LAUNCHABLE, + EGG_DESKTOP_FILE_ERROR_UNRECOGNIZED_OPTION + } EggDesktopFileError; + + /* Global application desktop file */ + void egg_set_desktop_file (const char *desktop_file_path); + EggDesktopFile *egg_get_desktop_file (void); + + +#ifdef __cplusplus +} +#endif + +#endif /* __EGG_DESKTOP_FILE_H__ */ diff --git a/cut-n-paste-code/libegg/eggsmclient-private.h b/cut-n-paste-code/libegg/eggsmclient-private.h new file mode 100644 index 00000000..68f1c9ea --- /dev/null +++ b/cut-n-paste-code/libegg/eggsmclient-private.h @@ -0,0 +1,57 @@ +/* eggsmclient-private.h + * Copyright (C) 2007 Novell, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __EGG_SM_CLIENT_PRIVATE_H__ +#define __EGG_SM_CLIENT_PRIVATE_H__ + +#include +#include "eggsmclient.h" + +#ifdef __cplusplus +extern "C" { +#endif + + GKeyFile *egg_sm_client_save_state (EggSMClient *client); + void egg_sm_client_quit_requested (EggSMClient *client); + void egg_sm_client_quit_cancelled (EggSMClient *client); + void egg_sm_client_quit (EggSMClient *client); + +#if defined (GDK_WINDOWING_X11) +# ifdef EGG_SM_CLIENT_BACKEND_XSMP + GType egg_sm_client_xsmp_get_type (void); + EggSMClient *egg_sm_client_xsmp_new (void); +# endif +# ifdef EGG_SM_CLIENT_BACKEND_DBUS + GType egg_sm_client_dbus_get_type (void); + EggSMClient *egg_sm_client_dbus_new (void); +# endif +#elif defined (GDK_WINDOWING_WIN32) + GType egg_sm_client_win32_get_type (void); + EggSMClient *egg_sm_client_win32_new (void); +#elif defined (GDK_WINDOWING_QUARTZ) + GType egg_sm_client_osx_get_type (void); + EggSMClient *egg_sm_client_osx_new (void); +#endif + +#ifdef __cplusplus +} +#endif + + +#endif /* __EGG_SM_CLIENT_PRIVATE_H__ */ diff --git a/cut-n-paste-code/libegg/eggsmclient-xsmp.c b/cut-n-paste-code/libegg/eggsmclient-xsmp.c new file mode 100644 index 00000000..40d8c270 --- /dev/null +++ b/cut-n-paste-code/libegg/eggsmclient-xsmp.c @@ -0,0 +1,1371 @@ +/* + * Copyright (C) 2007 Novell, Inc. + * + * Inspired by various other pieces of code including GsmClient (C) + * 2001 Havoc Pennington, MateClient (C) 1998 Carsten Schaar, and twm + * session code (C) 1998 The Open Group. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include "eggsmclient.h" +#include "eggsmclient-private.h" + +#include "eggdesktopfile.h" + +#include +#include +#include +#include +#include +#include + +#include + +#define EGG_TYPE_SM_CLIENT_XSMP (egg_sm_client_xsmp_get_type ()) +#define EGG_SM_CLIENT_XSMP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EGG_TYPE_SM_CLIENT_XSMP, EggSMClientXSMP)) +#define EGG_SM_CLIENT_XSMP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EGG_TYPE_SM_CLIENT_XSMP, EggSMClientXSMPClass)) +#define EGG_IS_SM_CLIENT_XSMP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EGG_TYPE_SM_CLIENT_XSMP)) +#define EGG_IS_SM_CLIENT_XSMP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EGG_TYPE_SM_CLIENT_XSMP)) +#define EGG_SM_CLIENT_XSMP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EGG_TYPE_SM_CLIENT_XSMP, EggSMClientXSMPClass)) + +typedef struct _EggSMClientXSMP EggSMClientXSMP; +typedef struct _EggSMClientXSMPClass EggSMClientXSMPClass; + +/* These mostly correspond to the similarly-named states in section + * 9.1 of the XSMP spec. Some of the states there aren't represented + * here, because we don't need them. SHUTDOWN_CANCELLED is slightly + * different from the spec; we use it when the client is IDLE after a + * ShutdownCancelled message, but the application is still interacting + * and doesn't know the shutdown has been cancelled yet. + */ +typedef enum +{ + XSMP_STATE_IDLE, + XSMP_STATE_SAVE_YOURSELF, + XSMP_STATE_INTERACT_REQUEST, + XSMP_STATE_INTERACT, + XSMP_STATE_SAVE_YOURSELF_DONE, + XSMP_STATE_SHUTDOWN_CANCELLED, + XSMP_STATE_CONNECTION_CLOSED +} EggSMClientXSMPState; + +static const char *state_names[] = +{ + "idle", + "save-yourself", + "interact-request", + "interact", + "save-yourself-done", + "shutdown-cancelled", + "connection-closed" +}; + +#define EGG_SM_CLIENT_XSMP_STATE(xsmp) (state_names[(xsmp)->state]) + +struct _EggSMClientXSMP +{ + EggSMClient parent; + + SmcConn connection; + char *client_id; + + EggSMClientXSMPState state; + char **restart_command; + gboolean set_restart_command; + int restart_style; + + guint idle; + + /* Current SaveYourself state */ + guint expecting_initial_save_yourself : 1; + guint need_save_state : 1; + guint need_quit_requested : 1; + guint interact_errors : 1; + guint shutting_down : 1; + + /* Todo list */ + guint waiting_to_set_initial_properties : 1; + guint waiting_to_emit_quit : 1; + guint waiting_to_emit_quit_cancelled : 1; + guint waiting_to_save_myself : 1; + +}; + +struct _EggSMClientXSMPClass +{ + EggSMClientClass parent_class; + +}; + +static void sm_client_xsmp_startup (EggSMClient *client, + const char *client_id); +static void sm_client_xsmp_set_restart_command (EggSMClient *client, + int argc, + const char **argv); +static void sm_client_xsmp_will_quit (EggSMClient *client, + gboolean will_quit); +static gboolean sm_client_xsmp_end_session (EggSMClient *client, + EggSMClientEndStyle style, + gboolean request_confirmation); + +static void xsmp_save_yourself (SmcConn smc_conn, + SmPointer client_data, + int save_style, + Bool shutdown, + int interact_style, + Bool fast); +static void xsmp_die (SmcConn smc_conn, + SmPointer client_data); +static void xsmp_save_complete (SmcConn smc_conn, + SmPointer client_data); +static void xsmp_shutdown_cancelled (SmcConn smc_conn, + SmPointer client_data); +static void xsmp_interact (SmcConn smc_conn, + SmPointer client_data); + +static SmProp *array_prop (const char *name, + ...); +static SmProp *ptrarray_prop (const char *name, + GPtrArray *values); +static SmProp *string_prop (const char *name, + const char *value); +static SmProp *card8_prop (const char *name, + unsigned char value); + +static void set_properties (EggSMClientXSMP *xsmp, ...); +static void delete_properties (EggSMClientXSMP *xsmp, ...); + +static GPtrArray *generate_command (char **restart_command, + const char *client_id, + const char *state_file); + +static void save_state (EggSMClientXSMP *xsmp); +static void do_save_yourself (EggSMClientXSMP *xsmp); +static void update_pending_events (EggSMClientXSMP *xsmp); + +static void ice_init (void); +static gboolean process_ice_messages (IceConn ice_conn); +static void smc_error_handler (SmcConn smc_conn, + Bool swap, + int offending_minor_opcode, + unsigned long offending_sequence, + int error_class, + int severity, + SmPointer values); + +G_DEFINE_TYPE (EggSMClientXSMP, egg_sm_client_xsmp, EGG_TYPE_SM_CLIENT) + +static void +egg_sm_client_xsmp_init (EggSMClientXSMP *xsmp) +{ + xsmp->state = XSMP_STATE_CONNECTION_CLOSED; + xsmp->connection = NULL; + xsmp->restart_style = SmRestartIfRunning; +} + +static void +egg_sm_client_xsmp_class_init (EggSMClientXSMPClass *klass) +{ + EggSMClientClass *sm_client_class = EGG_SM_CLIENT_CLASS (klass); + + sm_client_class->startup = sm_client_xsmp_startup; + sm_client_class->set_restart_command = sm_client_xsmp_set_restart_command; + sm_client_class->will_quit = sm_client_xsmp_will_quit; + sm_client_class->end_session = sm_client_xsmp_end_session; +} + +EggSMClient * +egg_sm_client_xsmp_new (void) +{ + if (!g_getenv ("SESSION_MANAGER")) + return NULL; + + return g_object_new (EGG_TYPE_SM_CLIENT_XSMP, NULL); +} + +static gboolean +sm_client_xsmp_set_initial_properties (gpointer user_data) +{ + EggSMClientXSMP *xsmp = user_data; + EggDesktopFile *desktop_file; + GPtrArray *clone, *restart; + char pid_str[64]; + + if (xsmp->idle) + { + g_source_remove (xsmp->idle); + xsmp->idle = 0; + } + xsmp->waiting_to_set_initial_properties = FALSE; + + if (egg_sm_client_get_mode () == EGG_SM_CLIENT_MODE_NO_RESTART) + xsmp->restart_style = SmRestartNever; + + /* Parse info out of desktop file */ + desktop_file = egg_get_desktop_file (); + if (desktop_file) + { + GError *err = NULL; + char *cmdline, **argv; + int argc; + + if (xsmp->restart_style == SmRestartIfRunning) + { + if (egg_desktop_file_get_boolean (desktop_file, + "X-MATE-AutoRestart", NULL)) + xsmp->restart_style = SmRestartImmediately; + } + + if (!xsmp->set_restart_command) + { + cmdline = egg_desktop_file_parse_exec (desktop_file, NULL, &err); + if (cmdline && g_shell_parse_argv (cmdline, &argc, &argv, &err)) + { + egg_sm_client_set_restart_command (EGG_SM_CLIENT (xsmp), + argc, (const char **)argv); + g_strfreev (argv); + } + else + { + g_warning ("Could not parse Exec line in desktop file: %s", + err->message); + g_error_free (err); + } + g_free (cmdline); + } + } + + if (!xsmp->set_restart_command) + xsmp->restart_command = g_strsplit (g_get_prgname (), " ", -1); + + clone = generate_command (xsmp->restart_command, NULL, NULL); + restart = generate_command (xsmp->restart_command, xsmp->client_id, NULL); + + g_debug ("Setting initial properties"); + + /* Program, CloneCommand, RestartCommand, and UserID are required. + * ProcessID isn't required, but the SM may be able to do something + * useful with it. + */ + g_snprintf (pid_str, sizeof (pid_str), "%lu", (gulong) getpid ()); + set_properties (xsmp, + string_prop (SmProgram, g_get_prgname ()), + ptrarray_prop (SmCloneCommand, clone), + ptrarray_prop (SmRestartCommand, restart), + string_prop (SmUserID, g_get_user_name ()), + string_prop (SmProcessID, pid_str), + card8_prop (SmRestartStyleHint, xsmp->restart_style), + NULL); + g_ptr_array_free (clone, TRUE); + g_ptr_array_free (restart, TRUE); + + if (desktop_file) + { + set_properties (xsmp, + string_prop ("_GSM_DesktopFile", egg_desktop_file_get_source (desktop_file)), + NULL); + } + + update_pending_events (xsmp); + return FALSE; +} + +/* This gets called from two different places: xsmp_die() (when the + * server asks us to disconnect) and process_ice_messages() (when the + * server disconnects unexpectedly). + */ +static void +sm_client_xsmp_disconnect (EggSMClientXSMP *xsmp) +{ + SmcConn connection; + + if (!xsmp->connection) + return; + + g_debug ("Disconnecting"); + + connection = xsmp->connection; + xsmp->connection = NULL; + SmcCloseConnection (connection, 0, NULL); + xsmp->state = XSMP_STATE_CONNECTION_CLOSED; + + xsmp->waiting_to_save_myself = FALSE; + update_pending_events (xsmp); +} + +static void +sm_client_xsmp_startup (EggSMClient *client, + const char *client_id) +{ + EggSMClientXSMP *xsmp = (EggSMClientXSMP *)client; + SmcCallbacks callbacks; + char *ret_client_id; + char error_string_ret[256]; + + xsmp->client_id = g_strdup (client_id); + + ice_init (); + SmcSetErrorHandler (smc_error_handler); + + callbacks.save_yourself.callback = xsmp_save_yourself; + callbacks.die.callback = xsmp_die; + callbacks.save_complete.callback = xsmp_save_complete; + callbacks.shutdown_cancelled.callback = xsmp_shutdown_cancelled; + + callbacks.save_yourself.client_data = xsmp; + callbacks.die.client_data = xsmp; + callbacks.save_complete.client_data = xsmp; + callbacks.shutdown_cancelled.client_data = xsmp; + + client_id = NULL; + error_string_ret[0] = '\0'; + xsmp->connection = + SmcOpenConnection (NULL, xsmp, SmProtoMajor, SmProtoMinor, + SmcSaveYourselfProcMask | SmcDieProcMask | + SmcSaveCompleteProcMask | + SmcShutdownCancelledProcMask, + &callbacks, + xsmp->client_id, &ret_client_id, + sizeof (error_string_ret), error_string_ret); + + if (!xsmp->connection) + { + g_warning ("Failed to connect to the session manager: %s\n", + error_string_ret[0] ? + error_string_ret : "no error message given"); + xsmp->state = XSMP_STATE_CONNECTION_CLOSED; + return; + } + + /* We expect a pointless initial SaveYourself if either (a) we + * didn't have an initial client ID, or (b) we DID have an initial + * client ID, but the server rejected it and gave us a new one. + */ + if (!xsmp->client_id || + (ret_client_id && strcmp (xsmp->client_id, ret_client_id) != 0)) + xsmp->expecting_initial_save_yourself = TRUE; + + if (ret_client_id) + { + g_free (xsmp->client_id); + xsmp->client_id = g_strdup (ret_client_id); + free (ret_client_id); + + gdk_threads_enter (); + gdk_set_sm_client_id (xsmp->client_id); + gdk_threads_leave (); + + g_debug ("Got client ID \"%s\"", xsmp->client_id); + } + + xsmp->state = XSMP_STATE_IDLE; + + /* Do not set the initial properties until we reach the main loop, + * so that the application has a chance to call + * egg_set_desktop_file(). (This may also help the session manager + * have a better idea of when the application is fully up and + * running.) + */ + xsmp->waiting_to_set_initial_properties = TRUE; + xsmp->idle = g_idle_add (sm_client_xsmp_set_initial_properties, client); +} + +static void +sm_client_xsmp_set_restart_command (EggSMClient *client, + int argc, + const char **argv) +{ + EggSMClientXSMP *xsmp = (EggSMClientXSMP *)client; + int i; + + g_strfreev (xsmp->restart_command); + + xsmp->restart_command = g_new (char *, argc + 1); + for (i = 0; i < argc; i++) + xsmp->restart_command[i] = g_strdup (argv[i]); + xsmp->restart_command[i] = NULL; + + xsmp->set_restart_command = TRUE; +} + +static void +sm_client_xsmp_will_quit (EggSMClient *client, + gboolean will_quit) +{ + EggSMClientXSMP *xsmp = (EggSMClientXSMP *)client; + + if (xsmp->state == XSMP_STATE_CONNECTION_CLOSED) + { + /* The session manager has already exited! Schedule a quit + * signal. + */ + xsmp->waiting_to_emit_quit = TRUE; + update_pending_events (xsmp); + return; + } + else if (xsmp->state == XSMP_STATE_SHUTDOWN_CANCELLED) + { + /* We received a ShutdownCancelled message while the application + * was interacting; Schedule a quit_cancelled signal. + */ + xsmp->waiting_to_emit_quit_cancelled = TRUE; + update_pending_events (xsmp); + return; + } + + g_return_if_fail (xsmp->state == XSMP_STATE_INTERACT); + + g_debug ("Sending InteractDone(%s)", will_quit ? "False" : "True"); + SmcInteractDone (xsmp->connection, !will_quit); + + if (will_quit && xsmp->need_save_state) + save_state (xsmp); + + g_debug ("Sending SaveYourselfDone(%s)", will_quit ? "True" : "False"); + SmcSaveYourselfDone (xsmp->connection, will_quit); + xsmp->state = XSMP_STATE_SAVE_YOURSELF_DONE; +} + +static gboolean +sm_client_xsmp_end_session (EggSMClient *client, + EggSMClientEndStyle style, + gboolean request_confirmation) +{ + EggSMClientXSMP *xsmp = (EggSMClientXSMP *)client; + int save_type; + + /* To end the session via XSMP, we have to send a + * SaveYourselfRequest. We aren't allowed to do that if anything + * else is going on, but we don't want to expose this fact to the + * application. So we do our best to patch things up here... + * + * In the worst case, this method might block for some length of + * time in process_ice_messages, but the only time that code path is + * honestly likely to get hit is if the application tries to end the + * session as the very first thing it does, in which case it + * probably won't actually block anyway. It's not worth gunking up + * the API to try to deal nicely with the other 0.01% of cases where + * this happens. + */ + + while (xsmp->state != XSMP_STATE_IDLE || + xsmp->expecting_initial_save_yourself) + { + /* If we're already shutting down, we don't need to do anything. */ + if (xsmp->shutting_down) + return TRUE; + + switch (xsmp->state) + { + case XSMP_STATE_CONNECTION_CLOSED: + return FALSE; + + case XSMP_STATE_SAVE_YOURSELF: + /* Trying to log out from the save_state callback? Whatever. + * Abort the save_state. + */ + SmcSaveYourselfDone (xsmp->connection, FALSE); + xsmp->state = XSMP_STATE_SAVE_YOURSELF_DONE; + break; + + case XSMP_STATE_INTERACT_REQUEST: + case XSMP_STATE_INTERACT: + case XSMP_STATE_SHUTDOWN_CANCELLED: + /* Already in a shutdown-related state, just ignore + * the new shutdown request... + */ + return TRUE; + + case XSMP_STATE_IDLE: + if (xsmp->waiting_to_set_initial_properties) + sm_client_xsmp_set_initial_properties (xsmp); + + if (!xsmp->expecting_initial_save_yourself) + break; + /* else fall through */ + + case XSMP_STATE_SAVE_YOURSELF_DONE: + /* We need to wait for some response from the server.*/ + process_ice_messages (SmcGetIceConnection (xsmp->connection)); + break; + + default: + /* Hm... shouldn't happen */ + return FALSE; + } + } + + /* xfce4-session will do the wrong thing if we pass SmSaveGlobal and + * the user chooses to save the session. But mate-session will do + * the wrong thing if we pass SmSaveBoth and the user chooses NOT to + * save the session... Sigh. + */ + if (!strcmp (SmcVendor (xsmp->connection), "xfce4-session")) + save_type = SmSaveBoth; + else + save_type = SmSaveGlobal; + + g_debug ("Sending SaveYourselfRequest(SmSaveGlobal, Shutdown, SmInteractStyleAny, %sFast)", request_confirmation ? "!" : ""); + SmcRequestSaveYourself (xsmp->connection, + save_type, + True, /* shutdown */ + SmInteractStyleAny, + !request_confirmation, /* fast */ + True /* global */); + return TRUE; +} + +static gboolean +idle_do_pending_events (gpointer data) +{ + EggSMClientXSMP *xsmp = data; + EggSMClient *client = data; + + gdk_threads_enter (); + + xsmp->idle = 0; + + if (xsmp->waiting_to_emit_quit) + { + xsmp->waiting_to_emit_quit = FALSE; + egg_sm_client_quit (client); + goto out; + } + + if (xsmp->waiting_to_emit_quit_cancelled) + { + xsmp->waiting_to_emit_quit_cancelled = FALSE; + egg_sm_client_quit_cancelled (client); + xsmp->state = XSMP_STATE_IDLE; + } + + if (xsmp->waiting_to_save_myself) + { + xsmp->waiting_to_save_myself = FALSE; + do_save_yourself (xsmp); + } + +out: + gdk_threads_leave (); + return FALSE; +} + +static void +update_pending_events (EggSMClientXSMP *xsmp) +{ + gboolean want_idle = + xsmp->waiting_to_emit_quit || + xsmp->waiting_to_emit_quit_cancelled || + xsmp->waiting_to_save_myself; + + if (want_idle) + { + if (xsmp->idle == 0) + xsmp->idle = g_idle_add (idle_do_pending_events, xsmp); + } + else + { + if (xsmp->idle != 0) + g_source_remove (xsmp->idle); + xsmp->idle = 0; + } +} + +static void +fix_broken_state (EggSMClientXSMP *xsmp, const char *message, + gboolean send_interact_done, + gboolean send_save_yourself_done) +{ + g_warning ("Received XSMP %s message in state %s: client or server error", + message, EGG_SM_CLIENT_XSMP_STATE (xsmp)); + + /* Forget any pending SaveYourself plans we had */ + xsmp->waiting_to_save_myself = FALSE; + update_pending_events (xsmp); + + if (send_interact_done) + SmcInteractDone (xsmp->connection, False); + if (send_save_yourself_done) + SmcSaveYourselfDone (xsmp->connection, True); + + xsmp->state = send_save_yourself_done ? XSMP_STATE_SAVE_YOURSELF_DONE : XSMP_STATE_IDLE; +} + +/* SM callbacks */ + +static void +xsmp_save_yourself (SmcConn smc_conn, + SmPointer client_data, + int save_type, + Bool shutdown, + int interact_style, + Bool fast) +{ + EggSMClientXSMP *xsmp = client_data; + gboolean wants_quit_requested; + + g_debug ("Received SaveYourself(%s, %s, %s, %s) in state %s", + save_type == SmSaveLocal ? "SmSaveLocal" : + save_type == SmSaveGlobal ? "SmSaveGlobal" : "SmSaveBoth", + shutdown ? "Shutdown" : "!Shutdown", + interact_style == SmInteractStyleAny ? "SmInteractStyleAny" : + interact_style == SmInteractStyleErrors ? "SmInteractStyleErrors" : + "SmInteractStyleNone", fast ? "Fast" : "!Fast", + EGG_SM_CLIENT_XSMP_STATE (xsmp)); + + if (xsmp->state != XSMP_STATE_IDLE && + xsmp->state != XSMP_STATE_SHUTDOWN_CANCELLED) + { + fix_broken_state (xsmp, "SaveYourself", FALSE, TRUE); + return; + } + + if (xsmp->waiting_to_set_initial_properties) + sm_client_xsmp_set_initial_properties (xsmp); + + /* If this is the initial SaveYourself, ignore it; we've already set + * properties and there's no reason to actually save state too. + */ + if (xsmp->expecting_initial_save_yourself) + { + xsmp->expecting_initial_save_yourself = FALSE; + + if (save_type == SmSaveLocal && + interact_style == SmInteractStyleNone && + !shutdown && !fast) + { + g_debug ("Sending SaveYourselfDone(True) for initial SaveYourself"); + SmcSaveYourselfDone (xsmp->connection, True); + /* As explained in the comment at the end of + * do_save_yourself(), SAVE_YOURSELF_DONE is the correct + * state here, not IDLE. + */ + xsmp->state = XSMP_STATE_SAVE_YOURSELF_DONE; + return; + } + else + g_warning ("First SaveYourself was not the expected one!"); + } + + /* Even ignoring the "fast" flag completely, there are still 18 + * different combinations of save_type, shutdown and interact_style. + * We interpret them as follows: + * + * Type Shutdown Interact Interpretation + * G F A/E/N do nothing (1) + * G T N do nothing (1)* + * G T A/E quit_requested (2) + * L/B F A/E/N save_state (3) + * L/B T N save_state (3)* + * L/B T A/E quit_requested, then save_state (4) + * + * 1. Do nothing, because the SM asked us to do something + * uninteresting (save open files, but then don't quit + * afterward) or rude (save open files without asking the user + * for confirmation). + * + * 2. Request interaction and then emit ::quit_requested. This + * perhaps isn't quite correct for the SmInteractStyleErrors + * case, but we don't care. + * + * 3. Emit ::save_state. The SmSaveBoth SaveYourselfs in these + * rows essentially get demoted to SmSaveLocal, because their + * Global halves correspond to "do nothing". + * + * 4. Request interaction, emit ::quit_requested, and then emit + * ::save_state after interacting. This is the SmSaveBoth + * equivalent of #2, but we also promote SmSaveLocal shutdown + * SaveYourselfs to SmSaveBoth here, because we want to give + * the user a chance to save open files before quitting. + * + * (* It would be nice if we could do something useful when the + * session manager sends a SaveYourself with shutdown True and + * SmInteractStyleNone. But we can't, so we just pretend it didn't + * even tell us it was shutting down. The docs for ::quit mention + * that it might not always be preceded by ::quit_requested.) + */ + + /* As an optimization, we don't actually request interaction and + * emit ::quit_requested if the application isn't listening to the + * signal. + */ + wants_quit_requested = g_signal_has_handler_pending (xsmp, g_signal_lookup ("quit_requested", EGG_TYPE_SM_CLIENT), 0, FALSE); + + xsmp->need_save_state = (save_type != SmSaveGlobal); + xsmp->need_quit_requested = (shutdown && wants_quit_requested && + interact_style != SmInteractStyleNone); + xsmp->interact_errors = (interact_style == SmInteractStyleErrors); + + xsmp->shutting_down = shutdown; + + do_save_yourself (xsmp); +} + +static void +do_save_yourself (EggSMClientXSMP *xsmp) +{ + if (xsmp->state == XSMP_STATE_SHUTDOWN_CANCELLED) + { + /* The SM cancelled a previous SaveYourself, but we haven't yet + * had a chance to tell the application, so we can't start + * processing this SaveYourself yet. + */ + xsmp->waiting_to_save_myself = TRUE; + update_pending_events (xsmp); + return; + } + + if (xsmp->need_quit_requested) + { + xsmp->state = XSMP_STATE_INTERACT_REQUEST; + + g_debug ("Sending InteractRequest(%s)", + xsmp->interact_errors ? "Error" : "Normal"); + SmcInteractRequest (xsmp->connection, + xsmp->interact_errors ? SmDialogError : SmDialogNormal, + xsmp_interact, + xsmp); + return; + } + + if (xsmp->need_save_state) + { + save_state (xsmp); + + /* Though unlikely, the client could have been disconnected + * while the application was saving its state. + */ + if (!xsmp->connection) + return; + } + + g_debug ("Sending SaveYourselfDone(True)"); + SmcSaveYourselfDone (xsmp->connection, True); + + /* The client state diagram in the XSMP spec says that after a + * non-shutdown SaveYourself, we go directly back to "idle". But + * everything else in both the XSMP spec and the libSM docs + * disagrees. + */ + xsmp->state = XSMP_STATE_SAVE_YOURSELF_DONE; +} + +static void +save_state (EggSMClientXSMP *xsmp) +{ + GKeyFile *state_file; + char *state_file_path, *data; + EggDesktopFile *desktop_file; + GPtrArray *restart; + int offset, fd; + + /* We set xsmp->state before emitting save_state, but our caller is + * responsible for setting it back afterward. + */ + xsmp->state = XSMP_STATE_SAVE_YOURSELF; + + state_file = egg_sm_client_save_state ((EggSMClient *)xsmp); + if (!state_file) + { + restart = generate_command (xsmp->restart_command, xsmp->client_id, NULL); + set_properties (xsmp, + ptrarray_prop (SmRestartCommand, restart), + NULL); + g_ptr_array_free (restart, TRUE); + delete_properties (xsmp, SmDiscardCommand, NULL); + return; + } + + desktop_file = egg_get_desktop_file (); + if (desktop_file) + { + GKeyFile *merged_file; + char *desktop_file_path; + + merged_file = g_key_file_new (); + desktop_file_path = + g_filename_from_uri (egg_desktop_file_get_source (desktop_file), + NULL, NULL); + if (desktop_file_path && + g_key_file_load_from_file (merged_file, desktop_file_path, + G_KEY_FILE_KEEP_COMMENTS | + G_KEY_FILE_KEEP_TRANSLATIONS, NULL)) + { + guint g, k, i; + char **groups, **keys, *value, *exec; + + groups = g_key_file_get_groups (state_file, NULL); + for (g = 0; groups[g]; g++) + { + keys = g_key_file_get_keys (state_file, groups[g], NULL, NULL); + for (k = 0; keys[k]; k++) + { + value = g_key_file_get_value (state_file, groups[g], + keys[k], NULL); + if (value) + { + g_key_file_set_value (merged_file, groups[g], + keys[k], value); + g_free (value); + } + } + g_strfreev (keys); + } + g_strfreev (groups); + + g_key_file_free (state_file); + state_file = merged_file; + + /* Update Exec key using "--sm-client-state-file %k" */ + restart = generate_command (xsmp->restart_command, + NULL, "%k"); + for (i = 0; i < restart->len; i++) + restart->pdata[i] = g_shell_quote (restart->pdata[i]); + g_ptr_array_add (restart, NULL); + exec = g_strjoinv (" ", (char **)restart->pdata); + g_strfreev ((char **)restart->pdata); + g_ptr_array_free (restart, FALSE); + + g_key_file_set_string (state_file, EGG_DESKTOP_FILE_GROUP, + EGG_DESKTOP_FILE_KEY_EXEC, + exec); + g_free (exec); + } + else + desktop_file = NULL; + + g_free (desktop_file_path); + } + + /* Now write state_file to disk. (We can't use mktemp(), because + * that requires the filename to end with "XXXXXX", and we want + * it to end with ".desktop".) + */ + + data = g_key_file_to_data (state_file, NULL, NULL); + g_key_file_free (state_file); + + offset = 0; + while (1) + { + state_file_path = g_strdup_printf ("%s%csession-state%c%s-%ld.%s", + g_get_user_config_dir (), + G_DIR_SEPARATOR, G_DIR_SEPARATOR, + g_get_prgname (), + (long)time (NULL) + offset, + desktop_file ? "desktop" : "state"); + + fd = open (state_file_path, O_WRONLY | O_CREAT | O_EXCL, 0644); + if (fd == -1) + { + if (errno == EEXIST) + { + offset++; + g_free (state_file_path); + continue; + } + else if (errno == ENOTDIR || errno == ENOENT) + { + char *sep = strrchr (state_file_path, G_DIR_SEPARATOR); + + *sep = '\0'; + if (g_mkdir_with_parents (state_file_path, 0755) != 0) + { + g_warning ("Could not create directory '%s'", + state_file_path); + g_free (state_file_path); + state_file_path = NULL; + break; + } + + continue; + } + + g_warning ("Could not create file '%s': %s", + state_file_path, g_strerror (errno)); + g_free (state_file_path); + state_file_path = NULL; + break; + } + + close (fd); + g_file_set_contents (state_file_path, data, -1, NULL); + break; + } + g_free (data); + + restart = generate_command (xsmp->restart_command, xsmp->client_id, + state_file_path); + set_properties (xsmp, + ptrarray_prop (SmRestartCommand, restart), + NULL); + g_ptr_array_free (restart, TRUE); + + if (state_file_path) + { + set_properties (xsmp, + array_prop (SmDiscardCommand, + "/bin/rm", "-rf", state_file_path, + NULL), + NULL); + g_free (state_file_path); + } +} + +static void +xsmp_interact (SmcConn smc_conn, + SmPointer client_data) +{ + EggSMClientXSMP *xsmp = client_data; + EggSMClient *client = client_data; + + g_debug ("Received Interact message in state %s", + EGG_SM_CLIENT_XSMP_STATE (xsmp)); + + if (xsmp->state != XSMP_STATE_INTERACT_REQUEST) + { + fix_broken_state (xsmp, "Interact", TRUE, TRUE); + return; + } + + xsmp->state = XSMP_STATE_INTERACT; + egg_sm_client_quit_requested (client); +} + +static void +xsmp_die (SmcConn smc_conn, + SmPointer client_data) +{ + EggSMClientXSMP *xsmp = client_data; + EggSMClient *client = client_data; + + g_debug ("Received Die message in state %s", + EGG_SM_CLIENT_XSMP_STATE (xsmp)); + + sm_client_xsmp_disconnect (xsmp); + egg_sm_client_quit (client); +} + +static void +xsmp_save_complete (SmcConn smc_conn, + SmPointer client_data) +{ + EggSMClientXSMP *xsmp = client_data; + + g_debug ("Received SaveComplete message in state %s", + EGG_SM_CLIENT_XSMP_STATE (xsmp)); + + if (xsmp->state == XSMP_STATE_SAVE_YOURSELF_DONE) + xsmp->state = XSMP_STATE_IDLE; + else + fix_broken_state (xsmp, "SaveComplete", FALSE, FALSE); +} + +static void +xsmp_shutdown_cancelled (SmcConn smc_conn, + SmPointer client_data) +{ + EggSMClientXSMP *xsmp = client_data; + EggSMClient *client = client_data; + + g_debug ("Received ShutdownCancelled message in state %s", + EGG_SM_CLIENT_XSMP_STATE (xsmp)); + + xsmp->shutting_down = FALSE; + + if (xsmp->state == XSMP_STATE_SAVE_YOURSELF_DONE) + { + /* We've finished interacting and now the SM has agreed to + * cancel the shutdown. + */ + xsmp->state = XSMP_STATE_IDLE; + egg_sm_client_quit_cancelled (client); + } + else if (xsmp->state == XSMP_STATE_SHUTDOWN_CANCELLED) + { + /* Hm... ok, so we got a shutdown SaveYourself, which got + * cancelled, but the application was still interacting, so we + * didn't tell it yet, and then *another* SaveYourself arrived, + * which we must still be waiting to tell the app about, except + * that now that SaveYourself has been cancelled too! Dizzy yet? + */ + xsmp->waiting_to_save_myself = FALSE; + update_pending_events (xsmp); + } + else + { + g_debug ("Sending SaveYourselfDone(False)"); + SmcSaveYourselfDone (xsmp->connection, False); + + if (xsmp->state == XSMP_STATE_INTERACT) + { + /* The application is currently interacting, so we can't + * tell it about the cancellation yet; we will wait until + * after it calls egg_sm_client_will_quit(). + */ + xsmp->state = XSMP_STATE_SHUTDOWN_CANCELLED; + } + else + { + /* The shutdown was cancelled before the application got a + * chance to interact. + */ + xsmp->state = XSMP_STATE_IDLE; + } + } +} + +/* Utilities */ + +/* Create a restart/clone/Exec command based on @restart_command. + * If @client_id is non-%NULL, add "--sm-client-id @client_id". + * If @state_file is non-%NULL, add "--sm-client-state-file @state_file". + * + * None of the input strings are g_strdup()ed; the caller must keep + * them around until it is done with the returned GPtrArray, and must + * then free the array, but not its contents. + */ +static GPtrArray * +generate_command (char **restart_command, const char *client_id, + const char *state_file) +{ + GPtrArray *cmd; + int i; + + cmd = g_ptr_array_new (); + g_ptr_array_add (cmd, restart_command[0]); + + if (client_id) + { + g_ptr_array_add (cmd, "--sm-client-id"); + g_ptr_array_add (cmd, (char *)client_id); + } + + if (state_file) + { + g_ptr_array_add (cmd, "--sm-client-state-file"); + g_ptr_array_add (cmd, (char *)state_file); + } + + for (i = 1; restart_command[i]; i++) + g_ptr_array_add (cmd, restart_command[i]); + + return cmd; +} + +/* Takes a NULL-terminated list of SmProp * values, created by + * array_prop, ptrarray_prop, string_prop, card8_prop, sets them, and + * frees them. + */ +static void +set_properties (EggSMClientXSMP *xsmp, ...) +{ + GPtrArray *props; + SmProp *prop; + va_list ap; + guint i; + + props = g_ptr_array_new (); + + va_start (ap, xsmp); + while ((prop = va_arg (ap, SmProp *))) + g_ptr_array_add (props, prop); + va_end (ap); + + if (xsmp->connection) + { + SmcSetProperties (xsmp->connection, props->len, + (SmProp **)props->pdata); + } + + for (i = 0; i < props->len; i++) + { + prop = props->pdata[i]; + g_free (prop->vals); + g_free (prop); + } + g_ptr_array_free (props, TRUE); +} + +/* Takes a NULL-terminated list of property names and deletes them. */ +static void +delete_properties (EggSMClientXSMP *xsmp, ...) +{ + GPtrArray *props; + char *prop; + va_list ap; + + if (!xsmp->connection) + return; + + props = g_ptr_array_new (); + + va_start (ap, xsmp); + while ((prop = va_arg (ap, char *))) + g_ptr_array_add (props, prop); + va_end (ap); + + SmcDeleteProperties (xsmp->connection, props->len, + (char **)props->pdata); + + g_ptr_array_free (props, TRUE); +} + +/* Takes an array of strings and creates a LISTofARRAY8 property. The + * strings are neither dupped nor freed; they need to remain valid + * until you're done with the SmProp. + */ +static SmProp * +array_prop (const char *name, ...) +{ + SmProp *prop; + SmPropValue pv; + GArray *vals; + char *value; + va_list ap; + + prop = g_new (SmProp, 1); + prop->name = (char *)name; + prop->type = SmLISTofARRAY8; + + vals = g_array_new (FALSE, FALSE, sizeof (SmPropValue)); + + va_start (ap, name); + while ((value = va_arg (ap, char *))) + { + pv.length = strlen (value); + pv.value = value; + g_array_append_val (vals, pv); + } + + prop->num_vals = vals->len; + prop->vals = (SmPropValue *)vals->data; + + g_array_free (vals, FALSE); + + return prop; +} + +/* Takes a GPtrArray of strings and creates a LISTofARRAY8 property. + * The array contents are neither dupped nor freed; they need to + * remain valid until you're done with the SmProp. + */ +static SmProp * +ptrarray_prop (const char *name, GPtrArray *values) +{ + SmProp *prop; + SmPropValue pv; + GArray *vals; + guint i; + + prop = g_new (SmProp, 1); + prop->name = (char *)name; + prop->type = SmLISTofARRAY8; + + vals = g_array_new (FALSE, FALSE, sizeof (SmPropValue)); + + for (i = 0; i < values->len; i++) + { + pv.length = strlen (values->pdata[i]); + pv.value = values->pdata[i]; + g_array_append_val (vals, pv); + } + + prop->num_vals = vals->len; + prop->vals = (SmPropValue *)vals->data; + + g_array_free (vals, FALSE); + + return prop; +} + +/* Takes a string and creates an ARRAY8 property. The string is + * neither dupped nor freed; it needs to remain valid until you're + * done with the SmProp. + */ +static SmProp * +string_prop (const char *name, const char *value) +{ + SmProp *prop; + + prop = g_new (SmProp, 1); + prop->name = (char *)name; + prop->type = SmARRAY8; + + prop->num_vals = 1; + prop->vals = g_new (SmPropValue, 1); + + prop->vals[0].length = strlen (value); + prop->vals[0].value = (char *)value; + + return prop; +} + +/* Takes a char and creates a CARD8 property. */ +static SmProp * +card8_prop (const char *name, unsigned char value) +{ + SmProp *prop; + char *card8val; + + /* To avoid having to allocate and free prop->vals[0], we cheat and + * make vals a 2-element-long array and then use the second element + * to store value. + */ + + prop = g_new (SmProp, 1); + prop->name = (char *)name; + prop->type = SmCARD8; + + prop->num_vals = 1; + prop->vals = g_new (SmPropValue, 2); + card8val = (char *)(&prop->vals[1]); + card8val[0] = value; + + prop->vals[0].length = 1; + prop->vals[0].value = card8val; + + return prop; +} + +/* ICE code. This makes no effort to play nice with anyone else trying + * to use libICE. Fortunately, no one uses libICE for anything other + * than SM. (DCOP uses ICE, but it has its own private copy of + * libICE.) + * + * When this moves to gtk, it will need to be cleverer, to avoid + * tripping over old apps that use MateClient or that use libSM + * directly. + */ + +#include +#include + +static void ice_error_handler (IceConn ice_conn, + Bool swap, + int offending_minor_opcode, + unsigned long offending_sequence, + int error_class, + int severity, + IcePointer values); +static void ice_io_error_handler (IceConn ice_conn); +static void ice_connection_watch (IceConn ice_conn, + IcePointer client_data, + Bool opening, + IcePointer *watch_data); + +static void +ice_init (void) +{ + IceSetIOErrorHandler (ice_io_error_handler); + IceSetErrorHandler (ice_error_handler); + IceAddConnectionWatch (ice_connection_watch, NULL); +} + +static gboolean +process_ice_messages (IceConn ice_conn) +{ + IceProcessMessagesStatus status; + + gdk_threads_enter (); + status = IceProcessMessages (ice_conn, NULL, NULL); + gdk_threads_leave (); + + switch (status) + { + case IceProcessMessagesSuccess: + return TRUE; + + case IceProcessMessagesIOError: + sm_client_xsmp_disconnect (IceGetConnectionContext (ice_conn)); + return FALSE; + + case IceProcessMessagesConnectionClosed: + return FALSE; + + default: + g_assert_not_reached (); + } +} + +static gboolean +ice_iochannel_watch (GIOChannel *channel, + GIOCondition condition, + gpointer client_data) +{ + return process_ice_messages (client_data); +} + +static void +ice_connection_watch (IceConn ice_conn, + IcePointer client_data, + Bool opening, + IcePointer *watch_data) +{ + guint watch_id; + + if (opening) + { + GIOChannel *channel; + int fd = IceConnectionNumber (ice_conn); + + fcntl (fd, F_SETFD, fcntl (fd, F_GETFD, 0) | FD_CLOEXEC); + channel = g_io_channel_unix_new (fd); + watch_id = g_io_add_watch (channel, G_IO_IN | G_IO_ERR, + ice_iochannel_watch, ice_conn); + g_io_channel_unref (channel); + + *watch_data = GUINT_TO_POINTER (watch_id); + } + else + { + watch_id = GPOINTER_TO_UINT (*watch_data); + g_source_remove (watch_id); + } +} + +static void +ice_error_handler (IceConn ice_conn, + Bool swap, + int offending_minor_opcode, + unsigned long offending_sequence, + int error_class, + int severity, + IcePointer values) +{ + /* Do nothing */ +} + +static void +ice_io_error_handler (IceConn ice_conn) +{ + /* Do nothing */ +} + +static void +smc_error_handler (SmcConn smc_conn, + Bool swap, + int offending_minor_opcode, + unsigned long offending_sequence, + int error_class, + int severity, + SmPointer values) +{ + /* Do nothing */ +} diff --git a/cut-n-paste-code/libegg/eggsmclient.c b/cut-n-paste-code/libegg/eggsmclient.c new file mode 100644 index 00000000..280c7ded --- /dev/null +++ b/cut-n-paste-code/libegg/eggsmclient.c @@ -0,0 +1,602 @@ +/* + * Copyright (C) 2007 Novell, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include +#include + +#include "eggsmclient.h" +#include "eggsmclient-private.h" + +static void egg_sm_client_debug_handler (const char *log_domain, + GLogLevelFlags log_level, + const char *message, + gpointer user_data); + +enum +{ + SAVE_STATE, + QUIT_REQUESTED, + QUIT_CANCELLED, + QUIT, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL]; + +struct _EggSMClientPrivate +{ + GKeyFile *state_file; +}; + +#define EGG_SM_CLIENT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), EGG_TYPE_SM_CLIENT, EggSMClientPrivate)) + +G_DEFINE_TYPE (EggSMClient, egg_sm_client, G_TYPE_OBJECT) + +static EggSMClient *global_client; +static EggSMClientMode global_client_mode = EGG_SM_CLIENT_MODE_NORMAL; + +static void +egg_sm_client_init (EggSMClient *client) +{ + ; +} + +static void +egg_sm_client_class_init (EggSMClientClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private (klass, sizeof (EggSMClientPrivate)); + + /** + * EggSMClient::save_state: + * @client: the client + * @state_file: a #GKeyFile to save state information into + * + * Emitted when the session manager has requested that the + * application save information about its current state. The + * application should save its state into @state_file, and then the + * session manager may then restart the application in a future + * session and tell it to initialize itself from that state. + * + * You should not save any data into @state_file's "start group" + * (ie, the %NULL group). Instead, applications should save their + * data into groups with names that start with the application name, + * and libraries that connect to this signal should save their data + * into groups with names that start with the library name. + * + * Alternatively, rather than (or in addition to) using @state_file, + * the application can save its state by calling + * egg_sm_client_set_restart_command() during the processing of this + * signal (eg, to include a list of files to open). + **/ + signals[SAVE_STATE] = + g_signal_new ("save_state", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (EggSMClientClass, save_state), + NULL, NULL, + g_cclosure_marshal_VOID__POINTER, + G_TYPE_NONE, + 1, G_TYPE_POINTER); + + /** + * EggSMClient::quit_requested: + * @client: the client + * + * Emitted when the session manager requests that the application + * exit (generally because the user is logging out). The application + * should decide whether or not it is willing to quit (perhaps after + * asking the user what to do with documents that have unsaved + * changes) and then call egg_sm_client_will_quit(), passing %TRUE + * or %FALSE to give its answer to the session manager. (It does not + * need to give an answer before returning from the signal handler; + * it can interact with the user asynchronously and then give its + * answer later on.) If the application does not connect to this + * signal, then #EggSMClient will automatically return %TRUE on its + * behalf. + * + * The application should not save its session state as part of + * handling this signal; if the user has requested that the session + * be saved when logging out, then ::save_state will be emitted + * separately. + * + * If the application agrees to quit, it should then wait for either + * the ::quit_cancelled or ::quit signals to be emitted. + **/ + signals[QUIT_REQUESTED] = + g_signal_new ("quit_requested", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (EggSMClientClass, quit_requested), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); + + /** + * EggSMClient::quit_cancelled: + * @client: the client + * + * Emitted when the session manager decides to cancel a logout after + * the application has already agreed to quit. After receiving this + * signal, the application can go back to what it was doing before + * receiving the ::quit_requested signal. + **/ + signals[QUIT_CANCELLED] = + g_signal_new ("quit_cancelled", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (EggSMClientClass, quit_cancelled), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); + + /** + * EggSMClient::quit: + * @client: the client + * + * Emitted when the session manager wants the application to quit + * (generally because the user is logging out). The application + * should exit as soon as possible after receiving this signal; if + * it does not, the session manager may choose to forcibly kill it. + * + * Normally a GUI application would only be sent a ::quit if it + * agreed to quit in response to a ::quit_requested signal. However, + * this is not guaranteed; in some situations the session manager + * may decide to end the session without giving applications a + * chance to object. + **/ + signals[QUIT] = + g_signal_new ("quit", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (EggSMClientClass, quit), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); +} + +static gboolean sm_client_disable = FALSE; +static char *sm_client_state_file = NULL; +static char *sm_client_id = NULL; +static char *sm_config_prefix = NULL; + +static gboolean +sm_client_post_parse_func (GOptionContext *context, + GOptionGroup *group, + gpointer data, + GError **error) +{ + EggSMClient *client = egg_sm_client_get (); + + if (sm_client_id == NULL) + { + const gchar *desktop_autostart_id; + + desktop_autostart_id = g_getenv ("DESKTOP_AUTOSTART_ID"); + + if (desktop_autostart_id != NULL) + sm_client_id = g_strdup (desktop_autostart_id); + } + + /* Unset DESKTOP_AUTOSTART_ID in order to avoid child processes to + * use the same client id. */ + g_unsetenv ("DESKTOP_AUTOSTART_ID"); + + if (EGG_SM_CLIENT_GET_CLASS (client)->startup) + EGG_SM_CLIENT_GET_CLASS (client)->startup (client, sm_client_id); + return TRUE; +} + +/** + * egg_sm_client_get_option_group: + * + * Creates a %GOptionGroup containing the session-management-related + * options. You should add this group to the application's + * %GOptionContext if you want to use #EggSMClient. + * + * Return value: the %GOptionGroup + **/ +GOptionGroup * +egg_sm_client_get_option_group (void) +{ + const GOptionEntry entries[] = + { + { + "sm-client-disable", 0, 0, + G_OPTION_ARG_NONE, &sm_client_disable, + N_("Disable connection to session manager"), NULL + }, + { + "sm-client-state-file", 0, 0, + G_OPTION_ARG_FILENAME, &sm_client_state_file, + N_("Specify file containing saved configuration"), N_("FILE") + }, + { + "sm-client-id", 0, 0, + G_OPTION_ARG_STRING, &sm_client_id, + N_("Specify session management ID"), N_("ID") + }, + /* MateClient compatibility option */ + { + "sm-disable", 0, G_OPTION_FLAG_HIDDEN, + G_OPTION_ARG_NONE, &sm_client_disable, + NULL, NULL + }, + /* MateClient compatibility option. This is a dummy option that only + * exists so that sessions saved by apps with MateClient can be restored + * later when they've switched to EggSMClient. See bug #575308. + */ + { + "sm-config-prefix", 0, G_OPTION_FLAG_HIDDEN, + G_OPTION_ARG_STRING, &sm_config_prefix, + NULL, NULL + }, + { NULL } + }; + GOptionGroup *group; + + /* Use our own debug handler for the "EggSMClient" domain. */ + g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, + egg_sm_client_debug_handler, NULL); + + group = g_option_group_new ("sm-client", + _("Session management options:"), + _("Show session management options"), + NULL, NULL); + g_option_group_add_entries (group, entries); + g_option_group_set_parse_hooks (group, NULL, sm_client_post_parse_func); + + return group; +} + +/** + * egg_sm_client_set_mode: + * @mode: an #EggSMClient mode + * + * Sets the "mode" of #EggSMClient as follows: + * + * %EGG_SM_CLIENT_MODE_DISABLED: Session management is completely + * disabled. The application will not even connect to the session + * manager. (egg_sm_client_get() will still return an #EggSMClient, + * but it will just be a dummy object.) + * + * %EGG_SM_CLIENT_MODE_NO_RESTART: The application will connect to + * the session manager (and thus will receive notification when the + * user is logging out, etc), but will request to not be + * automatically restarted with saved state in future sessions. + * + * %EGG_SM_CLIENT_MODE_NORMAL: The default. #EggSMCLient will + * function normally. + * + * This must be called before the application's main loop begins. + **/ +void +egg_sm_client_set_mode (EggSMClientMode mode) +{ + global_client_mode = mode; +} + +/** + * egg_sm_client_get_mode: + * + * Gets the global #EggSMClientMode. See egg_sm_client_set_mode() + * for details. + * + * Return value: the global #EggSMClientMode + **/ +EggSMClientMode +egg_sm_client_get_mode (void) +{ + return global_client_mode; +} + +/** + * egg_sm_client_get: + * + * Returns the master #EggSMClient for the application. + * + * On platforms that support saved sessions (ie, POSIX/X11), the + * application will only request to be restarted by the session + * manager if you call egg_set_desktop_file() to set an application + * desktop file. In particular, if the desktop file contains the key + * "X + * + * Return value: the master #EggSMClient. + **/ +EggSMClient * +egg_sm_client_get (void) +{ + if (!global_client) + { + if (global_client_mode != EGG_SM_CLIENT_MODE_DISABLED && + !sm_client_disable) + { +#if defined (GDK_WINDOWING_WIN32) + global_client = egg_sm_client_win32_new (); +#elif defined (GDK_WINDOWING_QUARTZ) + global_client = egg_sm_client_osx_new (); +#else + /* If both D-Bus and XSMP are compiled in, try XSMP first + * (since it supports state saving) and fall back to D-Bus + * if XSMP isn't available. + */ +# ifdef EGG_SM_CLIENT_BACKEND_XSMP + global_client = egg_sm_client_xsmp_new (); +# endif +# ifdef EGG_SM_CLIENT_BACKEND_DBUS + if (!global_client) + global_client = egg_sm_client_dbus_new (); +# endif +#endif + } + + /* Fallback: create a dummy client, so that callers don't have + * to worry about a %NULL return value. + */ + if (!global_client) + global_client = g_object_new (EGG_TYPE_SM_CLIENT, NULL); + } + + return global_client; +} + +/** + * egg_sm_client_is_resumed: + * @client: the client + * + * Checks whether or not the current session has been resumed from + * a previous saved session. If so, the application should call + * egg_sm_client_get_state_file() and restore its state from the + * returned #GKeyFile. + * + * Return value: %TRUE if the session has been resumed + **/ +gboolean +egg_sm_client_is_resumed (EggSMClient *client) +{ + g_return_val_if_fail (client == global_client, FALSE); + + return sm_client_state_file != NULL; +} + +/** + * egg_sm_client_get_state_file: + * @client: the client + * + * If the application was resumed by the session manager, this will + * return the #GKeyFile containing its state from the previous + * session. + * + * Note that other libraries and #EggSMClient itself may also store + * state in the key file, so if you call egg_sm_client_get_groups(), + * on it, the return value will likely include groups that you did not + * put there yourself. (It is also not guaranteed that the first + * group created by the application will still be the "start group" + * when it is resumed.) + * + * Return value: the #GKeyFile containing the application's earlier + * state, or %NULL on error. You should not free this key file; it + * is owned by @client. + **/ +GKeyFile * +egg_sm_client_get_state_file (EggSMClient *client) +{ + EggSMClientPrivate *priv = EGG_SM_CLIENT_GET_PRIVATE (client); + char *state_file_path; + GError *err = NULL; + + g_return_val_if_fail (client == global_client, NULL); + + if (!sm_client_state_file) + return NULL; + if (priv->state_file) + return priv->state_file; + + if (!strncmp (sm_client_state_file, "file://", 7)) + state_file_path = g_filename_from_uri (sm_client_state_file, NULL, NULL); + else + state_file_path = g_strdup (sm_client_state_file); + + priv->state_file = g_key_file_new (); + if (!g_key_file_load_from_file (priv->state_file, state_file_path, 0, &err)) + { + g_warning ("Could not load SM state file '%s': %s", + sm_client_state_file, err->message); + g_clear_error (&err); + g_key_file_free (priv->state_file); + priv->state_file = NULL; + } + + g_free (state_file_path); + return priv->state_file; +} + +/** + * egg_sm_client_set_restart_command: + * @client: the client + * @argc: the length of @argv + * @argv: argument vector + * + * Sets the command used to restart @client if it does not have a + * .desktop file that can be used to find its restart command. + * + * This can also be used when handling the ::save_state signal, to + * save the current state via an updated command line. (Eg, providing + * a list of filenames to open when the application is resumed.) + **/ +void +egg_sm_client_set_restart_command (EggSMClient *client, + int argc, + const char **argv) +{ + g_return_if_fail (EGG_IS_SM_CLIENT (client)); + + if (EGG_SM_CLIENT_GET_CLASS (client)->set_restart_command) + EGG_SM_CLIENT_GET_CLASS (client)->set_restart_command (client, argc, argv); +} + +/** + * egg_sm_client_will_quit: + * @client: the client + * @will_quit: whether or not the application is willing to quit + * + * This MUST be called in response to the ::quit_requested signal, to + * indicate whether or not the application is willing to quit. The + * application may call it either directly from the signal handler, or + * at some later point (eg, after asynchronously interacting with the + * user). + * + * If the application does not connect to ::quit_requested, + * #EggSMClient will call this method on its behalf (passing %TRUE + * for @will_quit). + * + * After calling this method, the application should wait to receive + * either ::quit_cancelled or ::quit. + **/ +void +egg_sm_client_will_quit (EggSMClient *client, + gboolean will_quit) +{ + g_return_if_fail (EGG_IS_SM_CLIENT (client)); + + if (EGG_SM_CLIENT_GET_CLASS (client)->will_quit) + EGG_SM_CLIENT_GET_CLASS (client)->will_quit (client, will_quit); +} + +/** + * egg_sm_client_end_session: + * @style: a hint at how to end the session + * @request_confirmation: whether or not the user should get a chance + * to confirm the action + * + * Requests that the session manager end the current session. @style + * indicates how the session should be ended, and + * @request_confirmation indicates whether or not the user should be + * given a chance to confirm the logout/reboot/shutdown. Both of these + * flags are merely hints though; the session manager may choose to + * ignore them. + * + * Return value: %TRUE if the request was sent; %FALSE if it could not + * be (eg, because it could not connect to the session manager). + **/ +gboolean +egg_sm_client_end_session (EggSMClientEndStyle style, + gboolean request_confirmation) +{ + EggSMClient *client = egg_sm_client_get (); + + g_return_val_if_fail (EGG_IS_SM_CLIENT (client), FALSE); + + if (EGG_SM_CLIENT_GET_CLASS (client)->end_session) + { + return EGG_SM_CLIENT_GET_CLASS (client)->end_session (client, style, + request_confirmation); + } + else + return FALSE; +} + +/* Signal-emitting callbacks from platform-specific code */ + +GKeyFile * +egg_sm_client_save_state (EggSMClient *client) +{ + GKeyFile *state_file; + char *group; + + g_return_val_if_fail (client == global_client, NULL); + + state_file = g_key_file_new (); + + g_debug ("Emitting save_state"); + g_signal_emit (client, signals[SAVE_STATE], 0, state_file); + g_debug ("Done emitting save_state"); + + group = g_key_file_get_start_group (state_file); + if (group) + { + g_free (group); + return state_file; + } + else + { + g_key_file_free (state_file); + return NULL; + } +} + +void +egg_sm_client_quit_requested (EggSMClient *client) +{ + g_return_if_fail (client == global_client); + + if (!g_signal_has_handler_pending (client, signals[QUIT_REQUESTED], 0, FALSE)) + { + g_debug ("Not emitting quit_requested because no one is listening"); + egg_sm_client_will_quit (client, TRUE); + return; + } + + g_debug ("Emitting quit_requested"); + g_signal_emit (client, signals[QUIT_REQUESTED], 0); + g_debug ("Done emitting quit_requested"); +} + +void +egg_sm_client_quit_cancelled (EggSMClient *client) +{ + g_return_if_fail (client == global_client); + + g_debug ("Emitting quit_cancelled"); + g_signal_emit (client, signals[QUIT_CANCELLED], 0); + g_debug ("Done emitting quit_cancelled"); +} + +void +egg_sm_client_quit (EggSMClient *client) +{ + g_return_if_fail (client == global_client); + + g_debug ("Emitting quit"); + g_signal_emit (client, signals[QUIT], 0); + g_debug ("Done emitting quit"); + + /* FIXME: should we just call gtk_main_quit() here? */ +} + +static void +egg_sm_client_debug_handler (const char *log_domain, + GLogLevelFlags log_level, + const char *message, + gpointer user_data) +{ + static int debug = -1; + + if (debug < 0) + debug = (g_getenv ("EGG_SM_CLIENT_DEBUG") != NULL); + + if (debug) + g_log_default_handler (log_domain, log_level, message, NULL); +} diff --git a/cut-n-paste-code/libegg/eggsmclient.h b/cut-n-paste-code/libegg/eggsmclient.h new file mode 100644 index 00000000..f025bb50 --- /dev/null +++ b/cut-n-paste-code/libegg/eggsmclient.h @@ -0,0 +1,123 @@ +/* eggsmclient.h + * Copyright (C) 2007 Novell, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __EGG_SM_CLIENT_H__ +#define __EGG_SM_CLIENT_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define EGG_TYPE_SM_CLIENT (egg_sm_client_get_type ()) +#define EGG_SM_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EGG_TYPE_SM_CLIENT, EggSMClient)) +#define EGG_SM_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EGG_TYPE_SM_CLIENT, EggSMClientClass)) +#define EGG_IS_SM_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EGG_TYPE_SM_CLIENT)) +#define EGG_IS_SM_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EGG_TYPE_SM_CLIENT)) +#define EGG_SM_CLIENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EGG_TYPE_SM_CLIENT, EggSMClientClass)) + + typedef struct _EggSMClient EggSMClient; + typedef struct _EggSMClientClass EggSMClientClass; + typedef struct _EggSMClientPrivate EggSMClientPrivate; + + typedef enum + { + EGG_SM_CLIENT_END_SESSION_DEFAULT, + EGG_SM_CLIENT_LOGOUT, + EGG_SM_CLIENT_REBOOT, + EGG_SM_CLIENT_SHUTDOWN + } EggSMClientEndStyle; + + typedef enum + { + EGG_SM_CLIENT_MODE_DISABLED, + EGG_SM_CLIENT_MODE_NO_RESTART, + EGG_SM_CLIENT_MODE_NORMAL + } EggSMClientMode; + + struct _EggSMClient + { + GObject parent; + + }; + + struct _EggSMClientClass + { + GObjectClass parent_class; + + /* signals */ + void (*save_state) (EggSMClient *client, + GKeyFile *state_file); + + void (*quit_requested) (EggSMClient *client); + void (*quit_cancelled) (EggSMClient *client); + void (*quit) (EggSMClient *client); + + /* virtual methods */ + void (*startup) (EggSMClient *client, + const char *client_id); + void (*set_restart_command) (EggSMClient *client, + int argc, + const char **argv); + void (*will_quit) (EggSMClient *client, + gboolean will_quit); + gboolean (*end_session) (EggSMClient *client, + EggSMClientEndStyle style, + gboolean request_confirmation); + + /* Padding for future expansion */ + void (*_egg_reserved1) (void); + void (*_egg_reserved2) (void); + void (*_egg_reserved3) (void); + void (*_egg_reserved4) (void); + }; + + GType egg_sm_client_get_type (void) G_GNUC_CONST; + + GOptionGroup *egg_sm_client_get_option_group (void); + + /* Initialization */ + void egg_sm_client_set_mode (EggSMClientMode mode); + EggSMClientMode egg_sm_client_get_mode (void); + EggSMClient *egg_sm_client_get (void); + + /* Resuming a saved session */ + gboolean egg_sm_client_is_resumed (EggSMClient *client); + GKeyFile *egg_sm_client_get_state_file (EggSMClient *client); + + /* Alternate means of saving state */ + void egg_sm_client_set_restart_command (EggSMClient *client, + int argc, + const char **argv); + + /* Handling "quit_requested" signal */ + void egg_sm_client_will_quit (EggSMClient *client, + gboolean will_quit); + + /* Initiate a logout/reboot/shutdown */ + gboolean egg_sm_client_end_session (EggSMClientEndStyle style, + gboolean request_confirmation); + +#ifdef __cplusplus +} +#endif + + +#endif /* __EGG_SM_CLIENT_H__ */ diff --git a/cut-n-paste-code/libegg/eggtreemultidnd.c b/cut-n-paste-code/libegg/eggtreemultidnd.c new file mode 100644 index 00000000..ff62b9dd --- /dev/null +++ b/cut-n-paste-code/libegg/eggtreemultidnd.c @@ -0,0 +1,415 @@ +/* eggtreemultidnd.c + * Copyright (C) 2001 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include "eggtreemultidnd.h" + +#define EGG_TREE_MULTI_DND_STRING "EggTreeMultiDndString" + +typedef struct +{ + guint pressed_button; + gint x; + gint y; + guint motion_notify_handler; + guint button_release_handler; + guint drag_data_get_handler; + GSList *event_list; +} EggTreeMultiDndData; + +/* CUT-N-PASTE from gtktreeview.c */ +typedef struct _TreeViewDragInfo TreeViewDragInfo; +struct _TreeViewDragInfo +{ + GdkModifierType start_button_mask; + GtkTargetList *source_target_list; + GdkDragAction source_actions; + + GtkTargetList *dest_target_list; + + guint source_set : 1; + guint dest_set : 1; +}; + + +GType +egg_tree_multi_drag_source_get_type (void) +{ + static GType our_type = 0; + + if (!our_type) + { + const GTypeInfo our_info = + { + sizeof (EggTreeMultiDragSourceIface), /* class_size */ + NULL, /* base_init */ + NULL, /* base_finalize */ + NULL, + NULL, /* class_finalize */ + NULL, /* class_data */ + 0, + 0, /* n_preallocs */ + NULL + }; + + our_type = g_type_register_static (G_TYPE_INTERFACE, "EggTreeMultiDragSource", &our_info, 0); + } + + return our_type; +} + + +/** + * egg_tree_multi_drag_source_row_draggable: + * @drag_source: a #EggTreeMultiDragSource + * @path: row on which user is initiating a drag + * + * Asks the #EggTreeMultiDragSource whether a particular row can be used as + * the source of a DND operation. If the source doesn't implement + * this interface, the row is assumed draggable. + * + * Return value: %TRUE if the row can be dragged + **/ +gboolean +egg_tree_multi_drag_source_row_draggable (EggTreeMultiDragSource *drag_source, + GList *path_list) +{ + EggTreeMultiDragSourceIface *iface = EGG_TREE_MULTI_DRAG_SOURCE_GET_IFACE (drag_source); + + g_return_val_if_fail (EGG_IS_TREE_MULTI_DRAG_SOURCE (drag_source), FALSE); + g_return_val_if_fail (iface->row_draggable != NULL, FALSE); + g_return_val_if_fail (path_list != NULL, FALSE); + + if (iface->row_draggable) + return (* iface->row_draggable) (drag_source, path_list); + else + return TRUE; +} + + +/** + * egg_tree_multi_drag_source_drag_data_delete: + * @drag_source: a #EggTreeMultiDragSource + * @path: row that was being dragged + * + * Asks the #EggTreeMultiDragSource to delete the row at @path, because + * it was moved somewhere else via drag-and-drop. Returns %FALSE + * if the deletion fails because @path no longer exists, or for + * some model-specific reason. Should robustly handle a @path no + * longer found in the model! + * + * Return value: %TRUE if the row was successfully deleted + **/ +gboolean +egg_tree_multi_drag_source_drag_data_delete (EggTreeMultiDragSource *drag_source, + GList *path_list) +{ + EggTreeMultiDragSourceIface *iface = EGG_TREE_MULTI_DRAG_SOURCE_GET_IFACE (drag_source); + + g_return_val_if_fail (EGG_IS_TREE_MULTI_DRAG_SOURCE (drag_source), FALSE); + g_return_val_if_fail (iface->drag_data_delete != NULL, FALSE); + g_return_val_if_fail (path_list != NULL, FALSE); + + return (* iface->drag_data_delete) (drag_source, path_list); +} + +/** + * egg_tree_multi_drag_source_drag_data_get: + * @drag_source: a #EggTreeMultiDragSource + * @path: row that was dragged + * @selection_data: a #EggSelectionData to fill with data from the dragged row + * + * Asks the #EggTreeMultiDragSource to fill in @selection_data with a + * representation of the row at @path. @selection_data->target gives + * the required type of the data. Should robustly handle a @path no + * longer found in the model! + * + * Return value: %TRUE if data of the required type was provided + **/ +gboolean +egg_tree_multi_drag_source_drag_data_get (EggTreeMultiDragSource *drag_source, + GList *path_list, + GtkSelectionData *selection_data) +{ + EggTreeMultiDragSourceIface *iface = EGG_TREE_MULTI_DRAG_SOURCE_GET_IFACE (drag_source); + + g_return_val_if_fail (EGG_IS_TREE_MULTI_DRAG_SOURCE (drag_source), FALSE); + g_return_val_if_fail (iface->drag_data_get != NULL, FALSE); + g_return_val_if_fail (path_list != NULL, FALSE); + g_return_val_if_fail (selection_data != NULL, FALSE); + + return (* iface->drag_data_get) (drag_source, path_list, selection_data); +} + +static void +stop_drag_check (GtkWidget *widget) +{ + EggTreeMultiDndData *priv_data; + GSList *l; + + priv_data = g_object_get_data (G_OBJECT (widget), EGG_TREE_MULTI_DND_STRING); + + for (l = priv_data->event_list; l != NULL; l = l->next) + gdk_event_free (l->data); + + g_slist_free (priv_data->event_list); + priv_data->event_list = NULL; + g_signal_handler_disconnect (widget, priv_data->motion_notify_handler); + g_signal_handler_disconnect (widget, priv_data->button_release_handler); +} + +static gboolean +egg_tree_multi_drag_button_release_event (GtkWidget *widget, + GdkEventButton *event, + gpointer data) +{ + EggTreeMultiDndData *priv_data; + GSList *l; + + priv_data = g_object_get_data (G_OBJECT (widget), EGG_TREE_MULTI_DND_STRING); + + for (l = priv_data->event_list; l != NULL; l = l->next) + gtk_propagate_event (widget, l->data); + + stop_drag_check (widget); + + return FALSE; +} + +static void +selection_foreach (GtkTreeModel *model, + GtkTreePath *path, + GtkTreeIter *iter, + gpointer data) +{ + GList **list_ptr; + + list_ptr = (GList **) data; + + *list_ptr = g_list_prepend (*list_ptr, gtk_tree_row_reference_new (model, path)); +} + +static void +path_list_free (GList *path_list) +{ + g_list_foreach (path_list, (GFunc) gtk_tree_row_reference_free, NULL); + g_list_free (path_list); +} + +static void +set_context_data (GdkDragContext *context, + GList *path_list) +{ + g_object_set_data_full (G_OBJECT (context), + "egg-tree-view-multi-source-row", + path_list, + (GDestroyNotify) path_list_free); +} + +static GList * +get_context_data (GdkDragContext *context) +{ + return g_object_get_data (G_OBJECT (context), + "egg-tree-view-multi-source-row"); +} + +/* CUT-N-PASTE from gtktreeview.c */ +static TreeViewDragInfo* +get_info (GtkTreeView *tree_view) +{ + return g_object_get_data (G_OBJECT (tree_view), "gtk-tree-view-drag-info"); +} + + +static void +egg_tree_multi_drag_drag_data_get (GtkWidget *widget, + GdkDragContext *context, + GtkSelectionData *selection_data, + guint info, + guint time) +{ + GtkTreeView *tree_view; + GtkTreeModel *model; + TreeViewDragInfo *di; + GList *path_list; + + tree_view = GTK_TREE_VIEW (widget); + + model = gtk_tree_view_get_model (tree_view); + + if (model == NULL) + return; + + di = get_info (GTK_TREE_VIEW (widget)); + + if (di == NULL) + return; + + path_list = get_context_data (context); + + if (path_list == NULL) + return; + + /* We can implement the GTK_TREE_MODEL_ROW target generically for + * any model; for DragSource models there are some other targets + * we also support. + */ + + if (EGG_IS_TREE_MULTI_DRAG_SOURCE (model)) + { + egg_tree_multi_drag_source_drag_data_get (EGG_TREE_MULTI_DRAG_SOURCE (model), + path_list, + selection_data); + } +} + +static gboolean +egg_tree_multi_drag_motion_event (GtkWidget *widget, + GdkEventMotion *event, + gpointer data) +{ + EggTreeMultiDndData *priv_data; + + priv_data = g_object_get_data (G_OBJECT (widget), EGG_TREE_MULTI_DND_STRING); + + if (gtk_drag_check_threshold (widget, + priv_data->x, + priv_data->y, + event->x, + event->y)) + { + GList *path_list = NULL; + GtkTreeSelection *selection; + GtkTreeModel *model; + GdkDragContext *context; + TreeViewDragInfo *di; + + di = get_info (GTK_TREE_VIEW (widget)); + + if (di == NULL) + return FALSE; + + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget)); + stop_drag_check (widget); + gtk_tree_selection_selected_foreach (selection, selection_foreach, &path_list); + path_list = g_list_reverse (path_list); + model = gtk_tree_view_get_model (GTK_TREE_VIEW (widget)); + if (egg_tree_multi_drag_source_row_draggable (EGG_TREE_MULTI_DRAG_SOURCE (model), path_list)) + { + + context = gtk_drag_begin (widget, + gtk_drag_source_get_target_list (widget), + di->source_actions, + priv_data->pressed_button, + (GdkEvent*)event); + set_context_data (context, path_list); + gtk_drag_set_icon_default (context); + + } + else + { + path_list_free (path_list); + } + } + + return TRUE; +} + +static gboolean +egg_tree_multi_drag_button_press_event (GtkWidget *widget, + GdkEventButton *event, + gpointer data) +{ + GtkTreeView *tree_view; + GtkTreePath *path = NULL; + GtkTreeViewColumn *column = NULL; + gint cell_x, cell_y; + GtkTreeSelection *selection; + EggTreeMultiDndData *priv_data; + + tree_view = GTK_TREE_VIEW (widget); + priv_data = g_object_get_data (G_OBJECT (tree_view), EGG_TREE_MULTI_DND_STRING); + if (priv_data == NULL) + { + priv_data = g_new0 (EggTreeMultiDndData, 1); + g_object_set_data (G_OBJECT (tree_view), EGG_TREE_MULTI_DND_STRING, priv_data); + } + + if (g_slist_find (priv_data->event_list, event)) + return FALSE; + + if (priv_data->event_list) + { + /* save the event to be propagated in order */ + priv_data->event_list = g_slist_append (priv_data->event_list, gdk_event_copy ((GdkEvent*)event)); + return TRUE; + } + + if (event->type == GDK_2BUTTON_PRESS) + return FALSE; + + gtk_tree_view_get_path_at_pos (tree_view, + event->x, event->y, + &path, &column, + &cell_x, &cell_y); + + selection = gtk_tree_view_get_selection (tree_view); + + if (path && gtk_tree_selection_path_is_selected (selection, path)) + { + priv_data->pressed_button = event->button; + priv_data->x = event->x; + priv_data->y = event->y; + priv_data->event_list = g_slist_append (priv_data->event_list, gdk_event_copy ((GdkEvent*)event)); + priv_data->motion_notify_handler = + g_signal_connect (G_OBJECT (tree_view), "motion_notify_event", G_CALLBACK (egg_tree_multi_drag_motion_event), NULL); + priv_data->button_release_handler = + g_signal_connect (G_OBJECT (tree_view), "button_release_event", G_CALLBACK (egg_tree_multi_drag_button_release_event), NULL); + + if (priv_data->drag_data_get_handler == 0) + { + priv_data->drag_data_get_handler = + g_signal_connect (G_OBJECT (tree_view), "drag_data_get", G_CALLBACK (egg_tree_multi_drag_drag_data_get), NULL); + } + + gtk_tree_path_free (path); + + return TRUE; + } + + if (path) + { + gtk_tree_path_free (path); + } + + return FALSE; +} + +void +egg_tree_multi_drag_add_drag_support (GtkTreeView *tree_view) +{ + g_return_if_fail (GTK_IS_TREE_VIEW (tree_view)); + g_signal_connect (G_OBJECT (tree_view), "button_press_event", G_CALLBACK (egg_tree_multi_drag_button_press_event), NULL); +} + diff --git a/cut-n-paste-code/libegg/eggtreemultidnd.h b/cut-n-paste-code/libegg/eggtreemultidnd.h new file mode 100644 index 00000000..f7b98e51 --- /dev/null +++ b/cut-n-paste-code/libegg/eggtreemultidnd.h @@ -0,0 +1,78 @@ +/* eggtreednd.h + * Copyright (C) 2001 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __EGG_TREE_MULTI_DND_H__ +#define __EGG_TREE_MULTI_DND_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define EGG_TYPE_TREE_MULTI_DRAG_SOURCE (egg_tree_multi_drag_source_get_type ()) +#define EGG_TREE_MULTI_DRAG_SOURCE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EGG_TYPE_TREE_MULTI_DRAG_SOURCE, EggTreeMultiDragSource)) +#define EGG_IS_TREE_MULTI_DRAG_SOURCE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EGG_TYPE_TREE_MULTI_DRAG_SOURCE)) +#define EGG_TREE_MULTI_DRAG_SOURCE_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), EGG_TYPE_TREE_MULTI_DRAG_SOURCE, EggTreeMultiDragSourceIface)) + + typedef struct _EggTreeMultiDragSource EggTreeMultiDragSource; /* Dummy typedef */ + typedef struct _EggTreeMultiDragSourceIface EggTreeMultiDragSourceIface; + + struct _EggTreeMultiDragSourceIface + { + GTypeInterface g_iface; + + /* VTable - not signals */ + gboolean (* row_draggable) (EggTreeMultiDragSource *drag_source, + GList *path_list); + + gboolean (* drag_data_get) (EggTreeMultiDragSource *drag_source, + GList *path_list, + GtkSelectionData *selection_data); + + gboolean (* drag_data_delete) (EggTreeMultiDragSource *drag_source, + GList *path_list); + }; + + GType egg_tree_multi_drag_source_get_type (void) G_GNUC_CONST; + + /* Returns whether the given row can be dragged */ + gboolean egg_tree_multi_drag_source_row_draggable (EggTreeMultiDragSource *drag_source, + GList *path_list); + + /* Deletes the given row, or returns FALSE if it can't */ + gboolean egg_tree_multi_drag_source_drag_data_delete (EggTreeMultiDragSource *drag_source, + GList *path_list); + + + /* Fills in selection_data with type selection_data->target based on the row + * denoted by path, returns TRUE if it does anything + */ + gboolean egg_tree_multi_drag_source_drag_data_get (EggTreeMultiDragSource *drag_source, + GList *path_list, + GtkSelectionData *selection_data); + void egg_tree_multi_drag_add_drag_support (GtkTreeView *tree_view); + + + +#ifdef __cplusplus +} +#endif + +#endif /* __EGG_TREE_MULTI_DND_H__ */ diff --git a/cut-n-paste-code/libegg/update-from-egg.sh b/cut-n-paste-code/libegg/update-from-egg.sh new file mode 100755 index 00000000..9be68a9b --- /dev/null +++ b/cut-n-paste-code/libegg/update-from-egg.sh @@ -0,0 +1,25 @@ +#!/bin/sh + +function die() { + echo $* + exit 1 +} + +if test -z "$EGGDIR"; then + echo "Must set EGGDIR" + exit 1 +fi + +if test -z "$EGGFILES"; then + echo "Must set EGGFILES" + exit 1 +fi + +for FILE in $EGGFILES; do + if cmp -s $EGGDIR/$FILE $FILE; then + echo "File $FILE is unchanged" + else + cp $EGGDIR/$FILE $FILE || die "Could not move $EGGDIR/$FILE to $FILE" + echo "Updated $FILE" + fi +done diff --git a/data/Makefile.am b/data/Makefile.am new file mode 100644 index 00000000..0e8fb977 --- /dev/null +++ b/data/Makefile.am @@ -0,0 +1,54 @@ +NULL = + +xml_in_files = caja.xml.in +xml_files = $(xml_in_files:.xml.in=.xml) +@INTLTOOL_XML_RULE@ + +desktopdir = $(datadir)/applications +desktop_DATA = $(desktop_in_files:.desktop.in=.desktop) +desktop_in_files = \ + caja.desktop.in \ + caja-home.desktop.in \ + caja-computer.desktop.in \ + caja-folder-handler.desktop.in \ + caja-file-management-properties.desktop.in \ + caja-browser.desktop.in \ + caja-autorun-software.desktop.in +@INTLTOOL_DESKTOP_RULE@ + +mimedir = $(datadir)/mime/packages +mime_DATA = $(xml_files) + +cajadatadir = $(datadir)/caja + +cajadata_DATA = \ + browser.xml \ + caja-extras.placeholder \ + caja-suggested.placeholder \ + $(NULL) + +EXTRA_DIST = $(cajadata_DATA) \ + caja.desktop \ + caja.desktop.in \ + $(xml_in_files) \ + $(desktop_in_files) \ + $(NULL) + +CLEANFILES = $(xml_files) \ + $(desktop_DATA) \ + $(NULL) + +SUBDIRS = \ + icons \ + patterns \ + $(NULL) + +install-data-hook: +if ENABLE_UPDATE_MIMEDB + $(UPDATE_MIME_DATABASE) "$(DESTDIR)$(datadir)/mime" +endif + +uninstall-hook: +if ENABLE_UPDATE_MIMEDB + $(UPDATE_MIME_DATABASE) "$(DESTDIR)$(datadir)/mime" +endif diff --git a/data/browser.xml b/data/browser.xml new file mode 100644 index 00000000..a62d1035 --- /dev/null +++ b/data/browser.xml @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + #E0D656 + #D2AB50 + #C6864B + #BB6247 + #AD3841 + #5BA7CF + #3978A7 + #184A7F + #3E4985 + #65498C + #CCFFCC + #66CC66 + #457263 + #63654A + #805932 + #E53B1A + #2C821E + #1822CA + #F6E118 + #D050A4 + #FFFFFF + #E5E5E5 + #C9C9C9 + #AFAFAF + #747474 + #6F6F6F + #525252 + #323232 + #222222 + #000000 + + + + + + + diff --git a/data/caja-autorun-software.desktop.in.in b/data/caja-autorun-software.desktop.in.in new file mode 100644 index 00000000..d4daf70e --- /dev/null +++ b/data/caja-autorun-software.desktop.in.in @@ -0,0 +1,14 @@ +[Desktop Entry] +_Name=Autorun Prompt +TryExec=caja-autorun-software +Exec=caja-autorun-software %u +Icon=application-x-executable +NoDisplay=true +Terminal=false +StartupNotify=true +Type=Application +MimeType=x-content/software; +X-MATE-Bugzilla-Bugzilla=MATE +X-MATE-Bugzilla-Product=caja +X-MATE-Bugzilla-Component=general +X-MATE-Bugzilla-Version=@VERSION@ diff --git a/data/caja-browser.desktop.in.in b/data/caja-browser.desktop.in.in new file mode 100644 index 00000000..6fcd19a7 --- /dev/null +++ b/data/caja-browser.desktop.in.in @@ -0,0 +1,15 @@ +[Desktop Entry] +_Name=File Browser +_Comment=Browse the file system with the file manager +TryExec=caja +Exec=caja --no-desktop --browser %U +Icon=system-file-manager +Terminal=false +StartupNotify=true +Type=Application +Categories=MATE;GTK;System;Utility;Core; +OnlyShowIn=MATE; +X-MATE-Bugzilla-Bugzilla=MATE +X-MATE-Bugzilla-Product=caja +X-MATE-Bugzilla-Component=general +X-MATE-Bugzilla-Version=@VERSION@ diff --git a/data/caja-computer.desktop.in.in b/data/caja-computer.desktop.in.in new file mode 100644 index 00000000..03dcc796 --- /dev/null +++ b/data/caja-computer.desktop.in.in @@ -0,0 +1,15 @@ +[Desktop Entry] +_Name=Computer +_Comment=Browse all local and remote disks and folders accessible from this computer +TryExec=caja +Exec=caja --no-desktop computer: +Icon=computer +Terminal=false +StartupNotify=true +Type=Application +Categories=MATE;GTK;Core; +OnlyShowIn=MATE; +X-MATE-Bugzilla-Bugzilla=MATE +X-MATE-Bugzilla-Product=caja +X-MATE-Bugzilla-Component=general +X-MATE-Bugzilla-Version=@VERSION@ diff --git a/data/caja-extras.placeholder b/data/caja-extras.placeholder new file mode 100644 index 00000000..127e3dac --- /dev/null +++ b/data/caja-extras.placeholder @@ -0,0 +1,2 @@ +This file is a placeholder for the +caja extras meta-package diff --git a/data/caja-file-management-properties.desktop.in.in b/data/caja-file-management-properties.desktop.in.in new file mode 100644 index 00000000..84b98eae --- /dev/null +++ b/data/caja-file-management-properties.desktop.in.in @@ -0,0 +1,14 @@ +[Desktop Entry] +_Name=File Management +_Comment=Change the behaviour and appearance of file manager windows +Exec=caja-file-management-properties +Icon=system-file-manager +Terminal=false +Type=Application +StartupNotify=true +Categories=MATE;GTK;Settings;X-MATE-PersonalSettings; +OnlyShowIn=MATE; +X-MATE-Bugzilla-Bugzilla=MATE +X-MATE-Bugzilla-Product=caja +X-MATE-Bugzilla-Component=Preferences +X-MATE-Bugzilla-Version=@VERSION@ diff --git a/data/caja-folder-handler.desktop.in.in b/data/caja-folder-handler.desktop.in.in new file mode 100644 index 00000000..c873baf0 --- /dev/null +++ b/data/caja-folder-handler.desktop.in.in @@ -0,0 +1,15 @@ +[Desktop Entry] +_Name=Open Folder +TryExec=caja +Exec=caja --no-desktop %U +NoDisplay=true +Terminal=false +Icon=folder-open +StartupNotify=true +Type=Application +MimeType=x-directory/mate-default-handler;x-directory/normal;inode/directory;application/x-mate-saved-search; +OnlyShowIn=MATE; +X-MATE-Bugzilla-Bugzilla=MATE +X-MATE-Bugzilla-Product=caja +X-MATE-Bugzilla-Component=general +X-MATE-Bugzilla-Version=@VERSION@ diff --git a/data/caja-home.desktop.in.in b/data/caja-home.desktop.in.in new file mode 100644 index 00000000..559f2aaf --- /dev/null +++ b/data/caja-home.desktop.in.in @@ -0,0 +1,14 @@ +[Desktop Entry] +_Name=Home Folder +_Comment=Open your personal folder +TryExec=caja +Exec=caja --no-desktop +Icon=user-home +Terminal=false +StartupNotify=true +Type=Application +Categories=MATE;GTK;Core; +OnlyShowIn=MATE; +X-MATE-Bugzilla-Bugzilla=MATE +X-MATE-Bugzilla-Product=caja +X-MATE-Bugzilla-Component=general diff --git a/data/caja-suggested.placeholder b/data/caja-suggested.placeholder new file mode 100644 index 00000000..1e5b6ab9 --- /dev/null +++ b/data/caja-suggested.placeholder @@ -0,0 +1,2 @@ +This file is a placeholder for the +caja suggested meta-package diff --git a/data/caja.desktop.in.in b/data/caja.desktop.in.in new file mode 100644 index 00000000..ce0c3370 --- /dev/null +++ b/data/caja.desktop.in.in @@ -0,0 +1,17 @@ +[Desktop Entry] +_Name=File Manager +Exec=caja +Icon=system-file-manager +Terminal=false +Type=Application +StartupNotify=true +NoDisplay=true +OnlyShowIn=MATE; +X-MATE-Bugzilla-Bugzilla=MATE +X-MATE-Bugzilla-Product=caja +X-MATE-Bugzilla-Component=general +X-MATE-Bugzilla-Version=@VERSION@ +X-MATE-Autostart-Phase=Desktop +X-MATE-Autostart-Notify=true +X-MATE-AutoRestart=true +X-MATE-Provides=filemanager diff --git a/data/caja.xml.in b/data/caja.xml.in new file mode 100644 index 00000000..5d69859d --- /dev/null +++ b/data/caja.xml.in @@ -0,0 +1,8 @@ + + + + + <_comment>Saved search + + + diff --git a/data/icons/Makefile.am b/data/icons/Makefile.am new file mode 100644 index 00000000..82931541 --- /dev/null +++ b/data/icons/Makefile.am @@ -0,0 +1,86 @@ +NULL = + +public_icons_themes = \ + hicolor \ + $(NULL) + +public_icons = \ + hicolor_apps_16x16_caja.png \ + hicolor_apps_22x22_caja.png \ + hicolor_apps_24x24_caja.png \ + hicolor_apps_32x32_caja.png \ + hicolor_apps_scalable_caja.svg \ + $(NULL) + +private_icons = \ + hicolor_emblems_16x16_emblem-note.png \ + hicolor_emblems_24x24_emblem-note.png \ + hicolor_emblems_48x48_emblem-note.png \ + $(NULL) + +noinst_DATA = \ + hicolor_apps_16x16_caja.svg \ + hicolor_apps_22x22_caja.svg \ + hicolor_apps_32x32_caja.svg \ + $(NULL) + +EXTRA_DIST = \ + $(public_icons) \ + $(private_icons) \ + $(noinst_DATA) \ + $(NULL) + +############################################################################### + +gtk_update_icon_cache = gtk-update-icon-cache -f -t + +update-icon-cache: + @-if test -z "$(DESTDIR)"; then \ + echo "Updating Gtk icon cache."; \ + for theme in $(public_icons_themes); do \ + $(gtk_update_icon_cache) $(datadir)/icons/$$theme; \ + done; \ + else \ + echo "*** Icon cache not updated. After (un)install, run this:"; \ + for theme in $(public_icons_themes); do \ + echo "*** $(gtk_update_icon_cache) $(datadir)/icons/$$theme"; \ + done; \ + fi + +install-icons: + for icon in $(public_icons); do \ + THEME=`echo $$icon | cut -d_ -f1`; \ + CONTEXT=`echo $$icon | cut -d_ -f2`; \ + SIZE=`echo $$icon | cut -d_ -f3`; \ + ICONFILE=`echo $$icon | cut -d_ -f4`; \ + mkdir -p $(DESTDIR)$(datadir)/icons/$$THEME/$$SIZE/$$CONTEXT; \ + $(INSTALL_DATA) $(srcdir)/$$icon $(DESTDIR)$(datadir)/icons/$$THEME/$$SIZE/$$CONTEXT/$$ICONFILE; \ + done; \ + for icon in $(private_icons); do \ + THEME=`echo $$icon | cut -d_ -f1`; \ + CONTEXT=`echo $$icon | cut -d_ -f2`; \ + SIZE=`echo $$icon | cut -d_ -f3`; \ + ICONFILE=`echo $$icon | cut -d_ -f4`; \ + mkdir -p $(DESTDIR)$(pkgdatadir)/icons/$$THEME/$$SIZE/$$CONTEXT; \ + $(INSTALL_DATA) $(srcdir)/$$icon $(DESTDIR)$(pkgdatadir)/icons/$$THEME/$$SIZE/$$CONTEXT/$$ICONFILE; \ + done + +uninstall-icons: + -for icon in $(public_icons); do \ + THEME=`echo $$icon | cut -d_ -f1`; \ + CONTEXT=`echo $$icon | cut -d_ -f2`; \ + SIZE=`echo $$icon | cut -d_ -f3`; \ + ICONFILE=`echo $$icon | cut -d_ -f4`; \ + rm -f $(DESTDIR)$(datadir)/icons/$$THEME/$$SIZE/$$CONTEXT/$$ICONFILE; \ + done; \ + for icon in $(private_icons); do \ + THEME=`echo $$icon | cut -d_ -f1`; \ + CONTEXT=`echo $$icon | cut -d_ -f2`; \ + SIZE=`echo $$icon | cut -d_ -f3`; \ + ICONFILE=`echo $$icon | cut -d_ -f4`; \ + rm -f $(DESTDIR)$(pkgdatadir)/icons/$$THEME/$$SIZE/$$CONTEXT/$$ICONFILE; \ + done + +install-data-local: install-icons update-icon-cache + +uninstall-local: uninstall-icons update-icon-cache diff --git a/data/icons/hicolor_apps_16x16_caja.png b/data/icons/hicolor_apps_16x16_caja.png new file mode 100644 index 00000000..fa5c4691 Binary files /dev/null and b/data/icons/hicolor_apps_16x16_caja.png differ diff --git a/data/icons/hicolor_apps_16x16_caja.svg b/data/icons/hicolor_apps_16x16_caja.svg new file mode 100644 index 00000000..716ec95b --- /dev/null +++ b/data/icons/hicolor_apps_16x16_caja.svg @@ -0,0 +1,262 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Ulisse Perusin + + + Caja + + + Caja + file manager + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/icons/hicolor_apps_22x22_caja.png b/data/icons/hicolor_apps_22x22_caja.png new file mode 100644 index 00000000..945d4d74 Binary files /dev/null and b/data/icons/hicolor_apps_22x22_caja.png differ diff --git a/data/icons/hicolor_apps_22x22_caja.svg b/data/icons/hicolor_apps_22x22_caja.svg new file mode 100644 index 00000000..363e2247 --- /dev/null +++ b/data/icons/hicolor_apps_22x22_caja.svg @@ -0,0 +1,323 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Ulisse Perusin + + + Caja + + + Caja + file manager + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/icons/hicolor_apps_24x24_caja.png b/data/icons/hicolor_apps_24x24_caja.png new file mode 100644 index 00000000..ea61f182 Binary files /dev/null and b/data/icons/hicolor_apps_24x24_caja.png differ diff --git a/data/icons/hicolor_apps_32x32_caja.png b/data/icons/hicolor_apps_32x32_caja.png new file mode 100644 index 00000000..3f4f8e0f Binary files /dev/null and b/data/icons/hicolor_apps_32x32_caja.png differ diff --git a/data/icons/hicolor_apps_32x32_caja.svg b/data/icons/hicolor_apps_32x32_caja.svg new file mode 100644 index 00000000..ab12d5c2 --- /dev/null +++ b/data/icons/hicolor_apps_32x32_caja.svg @@ -0,0 +1,314 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Ulisse Perusin + + + Caja + + + Caja + file manager + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/icons/hicolor_apps_scalable_caja.svg b/data/icons/hicolor_apps_scalable_caja.svg new file mode 100644 index 00000000..e0db38ec --- /dev/null +++ b/data/icons/hicolor_apps_scalable_caja.svg @@ -0,0 +1,275 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Ulisse Perusin + + + Caja + + + Caja + file manager + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/icons/hicolor_emblems_16x16_emblem-note.png b/data/icons/hicolor_emblems_16x16_emblem-note.png new file mode 100644 index 00000000..957a459b Binary files /dev/null and b/data/icons/hicolor_emblems_16x16_emblem-note.png differ diff --git a/data/icons/hicolor_emblems_24x24_emblem-note.png b/data/icons/hicolor_emblems_24x24_emblem-note.png new file mode 100644 index 00000000..00cc4753 Binary files /dev/null and b/data/icons/hicolor_emblems_24x24_emblem-note.png differ diff --git a/data/icons/hicolor_emblems_48x48_emblem-note.png b/data/icons/hicolor_emblems_48x48_emblem-note.png new file mode 100644 index 00000000..0221d59e Binary files /dev/null and b/data/icons/hicolor_emblems_48x48_emblem-note.png differ diff --git a/data/patterns/Makefile.am b/data/patterns/Makefile.am new file mode 100644 index 00000000..63a2f48e --- /dev/null +++ b/data/patterns/Makefile.am @@ -0,0 +1,39 @@ +NULL= + +backdir = $(datadir)/caja/patterns + +back_DATA = \ + blue_gray_rough.png \ + blue_ridge.png \ + blue_type.png \ + brushed_metal.png \ + burlap.jpg \ + camouflage.png \ + chalk.jpg \ + cork.png \ + countertop.png \ + dark-mate.jpg \ + dots.png \ + fibers.png \ + fleur_de_lis.png \ + floral.png \ + fossil.png \ + mate.jpg \ + green_weave.png \ + ice.png \ + manila_paper.png \ + moss_ridge.png \ + numbers.png \ + ocean_stripes.png \ + purple_marble.png \ + reset.png \ + ridged_paper.png \ + rough_paper.png \ + sky_ridge.png \ + snow_ridge.png \ + stucco.jpg \ + terracotta.png \ + wavy_white.png \ + $(NULL) + +EXTRA_DIST = $(back_DATA) diff --git a/data/patterns/blue_gray_rough.png b/data/patterns/blue_gray_rough.png new file mode 100644 index 00000000..97e69a34 Binary files /dev/null and b/data/patterns/blue_gray_rough.png differ diff --git a/data/patterns/blue_ridge.png b/data/patterns/blue_ridge.png new file mode 100644 index 00000000..cb96282a Binary files /dev/null and b/data/patterns/blue_ridge.png differ diff --git a/data/patterns/blue_type.png b/data/patterns/blue_type.png new file mode 100644 index 00000000..f58ccf47 Binary files /dev/null and b/data/patterns/blue_type.png differ diff --git a/data/patterns/brushed_metal.png b/data/patterns/brushed_metal.png new file mode 100644 index 00000000..241ae775 Binary files /dev/null and b/data/patterns/brushed_metal.png differ diff --git a/data/patterns/burlap.jpg b/data/patterns/burlap.jpg new file mode 100644 index 00000000..5bb3da0d Binary files /dev/null and b/data/patterns/burlap.jpg differ diff --git a/data/patterns/camouflage.png b/data/patterns/camouflage.png new file mode 100644 index 00000000..9ddc6139 Binary files /dev/null and b/data/patterns/camouflage.png differ diff --git a/data/patterns/chalk.jpg b/data/patterns/chalk.jpg new file mode 100644 index 00000000..a7dc9432 Binary files /dev/null and b/data/patterns/chalk.jpg differ diff --git a/data/patterns/cork.png b/data/patterns/cork.png new file mode 100644 index 00000000..9f104559 Binary files /dev/null and b/data/patterns/cork.png differ diff --git a/data/patterns/countertop.png b/data/patterns/countertop.png new file mode 100644 index 00000000..2cd247fe Binary files /dev/null and b/data/patterns/countertop.png differ diff --git a/data/patterns/dark-mate.jpg b/data/patterns/dark-mate.jpg new file mode 100644 index 00000000..8320a1be Binary files /dev/null and b/data/patterns/dark-mate.jpg differ diff --git a/data/patterns/dots.png b/data/patterns/dots.png new file mode 100644 index 00000000..d90fae19 Binary files /dev/null and b/data/patterns/dots.png differ diff --git a/data/patterns/fibers.png b/data/patterns/fibers.png new file mode 100644 index 00000000..cb77ae35 Binary files /dev/null and b/data/patterns/fibers.png differ diff --git a/data/patterns/fleur_de_lis.png b/data/patterns/fleur_de_lis.png new file mode 100644 index 00000000..8adbec68 Binary files /dev/null and b/data/patterns/fleur_de_lis.png differ diff --git a/data/patterns/floral.png b/data/patterns/floral.png new file mode 100644 index 00000000..99b530aa Binary files /dev/null and b/data/patterns/floral.png differ diff --git a/data/patterns/fossil.png b/data/patterns/fossil.png new file mode 100644 index 00000000..36563e8e Binary files /dev/null and b/data/patterns/fossil.png differ diff --git a/data/patterns/green_weave.png b/data/patterns/green_weave.png new file mode 100644 index 00000000..e5b05010 Binary files /dev/null and b/data/patterns/green_weave.png differ diff --git a/data/patterns/ice.png b/data/patterns/ice.png new file mode 100644 index 00000000..2d0e351e Binary files /dev/null and b/data/patterns/ice.png differ diff --git a/data/patterns/manila_paper.png b/data/patterns/manila_paper.png new file mode 100644 index 00000000..b953ad20 Binary files /dev/null and b/data/patterns/manila_paper.png differ diff --git a/data/patterns/mate.jpg b/data/patterns/mate.jpg new file mode 100644 index 00000000..51d901c4 Binary files /dev/null and b/data/patterns/mate.jpg differ diff --git a/data/patterns/moss_ridge.png b/data/patterns/moss_ridge.png new file mode 100644 index 00000000..b889390b Binary files /dev/null and b/data/patterns/moss_ridge.png differ diff --git a/data/patterns/numbers.png b/data/patterns/numbers.png new file mode 100644 index 00000000..2af0c380 Binary files /dev/null and b/data/patterns/numbers.png differ diff --git a/data/patterns/ocean_stripes.png b/data/patterns/ocean_stripes.png new file mode 100644 index 00000000..d0570962 Binary files /dev/null and b/data/patterns/ocean_stripes.png differ diff --git a/data/patterns/purple_marble.png b/data/patterns/purple_marble.png new file mode 100644 index 00000000..49796d24 Binary files /dev/null and b/data/patterns/purple_marble.png differ diff --git a/data/patterns/reset.png b/data/patterns/reset.png new file mode 100644 index 00000000..34674fbd Binary files /dev/null and b/data/patterns/reset.png differ diff --git a/data/patterns/ridged_paper.png b/data/patterns/ridged_paper.png new file mode 100644 index 00000000..45842220 Binary files /dev/null and b/data/patterns/ridged_paper.png differ diff --git a/data/patterns/rough_paper.png b/data/patterns/rough_paper.png new file mode 100644 index 00000000..6ebe9557 Binary files /dev/null and b/data/patterns/rough_paper.png differ diff --git a/data/patterns/sky_ridge.png b/data/patterns/sky_ridge.png new file mode 100644 index 00000000..a7728109 Binary files /dev/null and b/data/patterns/sky_ridge.png differ diff --git a/data/patterns/snow_ridge.png b/data/patterns/snow_ridge.png new file mode 100644 index 00000000..841c3738 Binary files /dev/null and b/data/patterns/snow_ridge.png differ diff --git a/data/patterns/stucco.jpg b/data/patterns/stucco.jpg new file mode 100644 index 00000000..1dd2d5be Binary files /dev/null and b/data/patterns/stucco.jpg differ diff --git a/data/patterns/terracotta.png b/data/patterns/terracotta.png new file mode 100644 index 00000000..0712cedc Binary files /dev/null and b/data/patterns/terracotta.png differ diff --git a/data/patterns/wavy_white.png b/data/patterns/wavy_white.png new file mode 100644 index 00000000..cb273be0 Binary files /dev/null and b/data/patterns/wavy_white.png differ diff --git a/depcomp b/depcomp new file mode 100755 index 00000000..df8eea7e --- /dev/null +++ b/depcomp @@ -0,0 +1,630 @@ +#! /bin/sh +# depcomp - compile a program generating dependencies as side-effects + +scriptversion=2009-04-28.21; # UTC + +# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009 Free +# Software Foundation, Inc. + +# 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 2, 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 . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Alexandre Oliva . + +case $1 in + '') + echo "$0: No command. Try \`$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: depcomp [--help] [--version] PROGRAM [ARGS] + +Run PROGRAMS ARGS to compile a file, generating dependencies +as side-effects. + +Environment variables: + depmode Dependency tracking mode. + source Source file read by `PROGRAMS ARGS'. + object Object file output by `PROGRAMS ARGS'. + DEPDIR directory where to store dependencies. + depfile Dependency file to output. + tmpdepfile Temporary file to use when outputing dependencies. + libtool Whether libtool is used (yes/no). + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "depcomp $scriptversion" + exit $? + ;; +esac + +if test -z "$depmode" || test -z "$source" || test -z "$object"; then + echo "depcomp: Variables source, object and depmode must be set" 1>&2 + exit 1 +fi + +# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. +depfile=${depfile-`echo "$object" | + sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} +tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} + +rm -f "$tmpdepfile" + +# Some modes work just like other modes, but use different flags. We +# parameterize here, but still list the modes in the big case below, +# to make depend.m4 easier to write. Note that we *cannot* use a case +# here, because this file can only contain one case statement. +if test "$depmode" = hp; then + # HP compiler uses -M and no extra arg. + gccflag=-M + depmode=gcc +fi + +if test "$depmode" = dashXmstdout; then + # This is just like dashmstdout with a different argument. + dashmflag=-xM + depmode=dashmstdout +fi + +cygpath_u="cygpath -u -f -" +if test "$depmode" = msvcmsys; then + # This is just like msvisualcpp but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u="sed s,\\\\\\\\,/,g" + depmode=msvisualcpp +fi + +case "$depmode" in +gcc3) +## gcc 3 implements dependency tracking that does exactly what +## we want. Yay! Note: for some reason libtool 1.4 doesn't like +## it if -MD -MP comes after the -MF stuff. Hmm. +## Unfortunately, FreeBSD c89 acceptance of flags depends upon +## the command line argument order; so add the flags where they +## appear in depend2.am. Note that the slowdown incurred here +## affects only configure: in makefiles, %FASTDEP% shortcuts this. + for arg + do + case $arg in + -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; + *) set fnord "$@" "$arg" ;; + esac + shift # fnord + shift # $arg + done + "$@" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + mv "$tmpdepfile" "$depfile" + ;; + +gcc) +## There are various ways to get dependency output from gcc. Here's +## why we pick this rather obscure method: +## - Don't want to use -MD because we'd like the dependencies to end +## up in a subdir. Having to rename by hand is ugly. +## (We might end up doing this anyway to support other compilers.) +## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like +## -MM, not -M (despite what the docs say). +## - Using -M directly means running the compiler twice (even worse +## than renaming). + if test -z "$gccflag"; then + gccflag=-MD, + fi + "$@" -Wp,"$gccflag$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz +## The second -e expression handles DOS-style file names with drive letters. + sed -e 's/^[^:]*: / /' \ + -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" +## This next piece of magic avoids the `deleted header file' problem. +## The problem is that when a header file which appears in a .P file +## is deleted, the dependency causes make to die (because there is +## typically no way to rebuild the header). We avoid this by adding +## dummy dependencies for each header file. Too bad gcc doesn't do +## this for us directly. + tr ' ' ' +' < "$tmpdepfile" | +## Some versions of gcc put a space before the `:'. On the theory +## that the space means something, we add a space to the output as +## well. +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +sgi) + if test "$libtool" = yes; then + "$@" "-Wp,-MDupdate,$tmpdepfile" + else + "$@" -MDupdate "$tmpdepfile" + fi + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + + if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files + echo "$object : \\" > "$depfile" + + # Clip off the initial element (the dependent). Don't try to be + # clever and replace this with sed code, as IRIX sed won't handle + # lines with more than a fixed number of characters (4096 in + # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; + # the IRIX cc adds comments like `#:fec' to the end of the + # dependency line. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ + tr ' +' ' ' >> "$depfile" + echo >> "$depfile" + + # The second pass generates a dummy entry for each header file. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> "$depfile" + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +aix) + # The C for AIX Compiler uses -M and outputs the dependencies + # in a .u file. In older versions, this file always lives in the + # current directory. Also, the AIX compiler puts `$object:' at the + # start of each line; $object doesn't have directory information. + # Version 6 uses the directory in both cases. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.u + tmpdepfile2=$base.u + tmpdepfile3=$dir.libs/$base.u + "$@" -Wc,-M + else + tmpdepfile1=$dir$base.u + tmpdepfile2=$dir$base.u + tmpdepfile3=$dir$base.u + "$@" -M + fi + stat=$? + + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + # Each line is of the form `foo.o: dependent.h'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + # That's a tab and a space in the []. + sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +icc) + # Intel's C compiler understands `-MD -MF file'. However on + # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c + # ICC 7.0 will fill foo.d with something like + # foo.o: sub/foo.c + # foo.o: sub/foo.h + # which is wrong. We want: + # sub/foo.o: sub/foo.c + # sub/foo.o: sub/foo.h + # sub/foo.c: + # sub/foo.h: + # ICC 7.1 will output + # foo.o: sub/foo.c sub/foo.h + # and will wrap long lines using \ : + # foo.o: sub/foo.c ... \ + # sub/foo.h ... \ + # ... + + "$@" -MD -MF "$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each line is of the form `foo.o: dependent.h', + # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | + sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp2) + # The "hp" stanza above does not work with aCC (C++) and HP's ia64 + # compilers, which have integrated preprocessors. The correct option + # to use with these is +Maked; it writes dependencies to a file named + # 'foo.d', which lands next to the object file, wherever that + # happens to be. + # Much of this is similar to the tru64 case; see comments there. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir.libs/$base.d + "$@" -Wc,+Maked + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + "$@" +Maked + fi + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile" + # Add `dependent.h:' lines. + sed -ne '2,${ + s/^ *// + s/ \\*$// + s/$/:/ + p + }' "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" "$tmpdepfile2" + ;; + +tru64) + # The Tru64 compiler uses -MD to generate dependencies as a side + # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. + # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put + # dependencies in `foo.d' instead, so we check for that too. + # Subdirectories are respected. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + + if test "$libtool" = yes; then + # With Tru64 cc, shared objects can also be used to make a + # static library. This mechanism is used in libtool 1.4 series to + # handle both shared and static libraries in a single compilation. + # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d. + # + # With libtool 1.5 this exception was removed, and libtool now + # generates 2 separate objects for the 2 libraries. These two + # compilations output dependencies in $dir.libs/$base.o.d and + # in $dir$base.o.d. We have to check for both files, because + # one of the two compilations can be disabled. We should prefer + # $dir$base.o.d over $dir.libs/$base.o.d because the latter is + # automatically cleaned when .libs/ is deleted, while ignoring + # the former would cause a distcleancheck panic. + tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4 + tmpdepfile2=$dir$base.o.d # libtool 1.5 + tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5 + tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504 + "$@" -Wc,-MD + else + tmpdepfile1=$dir$base.o.d + tmpdepfile2=$dir$base.d + tmpdepfile3=$dir$base.d + tmpdepfile4=$dir$base.d + "$@" -MD + fi + + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + # That's a tab and a space in the []. + sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +#nosideeffect) + # This comment above is used by automake to tell side-effect + # dependency tracking mechanisms from slower ones. + +dashmstdout) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove `-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + test -z "$dashmflag" && dashmflag=-M + # Require at least two characters before searching for `:' + # in the target name. This is to cope with DOS-style filenames: + # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. + "$@" $dashmflag | + sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + tr ' ' ' +' < "$tmpdepfile" | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +dashXmstdout) + # This case only exists to satisfy depend.m4. It is never actually + # run, as this mode is specially recognized in the preamble. + exit 1 + ;; + +makedepend) + "$@" || exit $? + # Remove any Libtool call + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + # X makedepend + shift + cleared=no eat=no + for arg + do + case $cleared in + no) + set ""; shift + cleared=yes ;; + esac + if test $eat = yes; then + eat=no + continue + fi + case "$arg" in + -D*|-I*) + set fnord "$@" "$arg"; shift ;; + # Strip any option that makedepend may not understand. Remove + # the object too, otherwise makedepend will parse it as a source file. + -arch) + eat=yes ;; + -*|$object) + ;; + *) + set fnord "$@" "$arg"; shift ;; + esac + done + obj_suffix=`echo "$object" | sed 's/^.*\././'` + touch "$tmpdepfile" + ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + sed '1,2d' "$tmpdepfile" | tr ' ' ' +' | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" "$tmpdepfile".bak + ;; + +cpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove `-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + "$@" -E | + sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | + sed '$ s: \\$::' > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + cat < "$tmpdepfile" >> "$depfile" + sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvisualcpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + IFS=" " + for arg + do + case "$arg" in + -o) + shift + ;; + $object) + shift + ;; + "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") + set fnord "$@" + shift + shift + ;; + *) + set fnord "$@" "$arg" + shift + shift + ;; + esac + done + "$@" -E 2>/dev/null | + sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" + echo " " >> "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvcmsys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +none) + exec "$@" + ;; + +*) + echo "Unknown depmode $depmode" 1>&2 + exit 1 + ;; +esac + +exit 0 + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/distro/archlinux/PKGBUILD b/distro/archlinux/PKGBUILD new file mode 100644 index 00000000..81451949 --- /dev/null +++ b/distro/archlinux/PKGBUILD @@ -0,0 +1,41 @@ +pkgname=mate-file-manager +pkgver=2011.11.16 +pkgrel=1 +pkgdesc="The MATE shell and file manager" +arch=('i686' 'x86_64') +license=('GPL') +depends=('libexif' 'exempi' 'mate-icon-theme' 'shared-mime-info' + 'desktop-file-utils' 'gvfs' 'libunique' 'mate-desktop') +makedepends=('pkgconfig' 'intltool') +url="http://matsusoft.com.ar/projects" +options=('!libtool' '!emptydirs') +install=mate-file-manager.install +source=(http://sourceforge.net/projects/matede/files/${pkgver}/${pkgname}.tar.gz/download) +sha256sums=('d13e08c13178629d38328783704890073b650d5b19c457ea3009cc13f6eea4e1') +groups=('mate') + +build() { + cd "${srcdir}/${pkgname}" + + ./autogen.sh \ + --prefix=/usr \ + --sysconfdir=/etc \ + --localstatedir=/var \ + --disable-static \ + --libexecdir=/usr/lib/caja \ + --enable-unique \ + --disable-update-mimedb || return 1 + + make || return 1 +} + +package() { + cd "${srcdir}/${pkgname}" + + make MATECONF_DISABLE_MAKEFILE_SCHEMA_INSTALL=1 DESTDIR="${pkgdir}" install || return 1 + + install -m755 -d ${pkgdir}/usr/share/mateconf/schemas + + mateconf-merge-schema ${pkgdir}/usr/share/mateconf/schemas/${pkgname}.schemas --domain ${pkgname} ${pkgdir}/etc/mateconf/schemas/*.schemas || return 1 + rm -f ${pkgdir}/etc/mateconf/schemas/*.schemas +} diff --git a/distro/archlinux/mate-file-manager.install b/distro/archlinux/mate-file-manager.install new file mode 100644 index 00000000..3956000b --- /dev/null +++ b/distro/archlinux/mate-file-manager.install @@ -0,0 +1,28 @@ +pkgname=mate-file-manager + +post_install() { + usr/sbin/mateconfpkg --install ${pkgname} + gtk-update-icon-cache -q -t -f usr/share/icons/hicolor + + update-desktop-database -q + + update-mime-database usr/share/mime > /dev/null +} + +pre_upgrade() { + pre_remove $1 +} + +post_upgrade() { + post_install $1 +} + +pre_remove() { + usr/sbin/mateconfpkg --uninstall ${pkgname} +} + +post_remove() { + gtk-update-icon-cache -q -t -f usr/share/icons/hicolor + update-desktop-database -q + update-mime-database usr/share/mime > /dev/null +} diff --git a/distro/ubuntu/build b/distro/ubuntu/build new file mode 100755 index 00000000..f14d45b4 --- /dev/null +++ b/distro/ubuntu/build @@ -0,0 +1,36 @@ +#!/bin/bash + +# fill it +pkgname=mate-file-manager +pkgver=2011.11.10 +pkgrel=1 +pkgdesc="The MATE shell and file manager" +depends=('libexif12' 'libexempi3' 'mate-icon-theme' 'shared-mime-info' 'desktop-file-utils' 'gvfs' 'libunique-1.0-0' 'mate-desktop' 'libgail18') +makedepends=('pkgconfig' 'intltool') +url="http://matsusoft.com.ar/projects" + + +# editar esta funcion! +build() { + cd $pkgsrc + # descomprimir + tar xvzf download + # entramos a la carpeta + cd ${pkgname} + + ./configure --prefix=/usr --sysconfdir=/etc \ + --localstatedir=/var --disable-static \ + --libexecdir=/usr/lib/caja --enable-unique \ + --disable-update-mimedb || return 1 + + make || return 1 + make MATECONF_DISABLE_MAKEFILE_SCHEMA_INSTALL=1 DESTDIR="${pkgdir}" install || return 1 + + install -m755 -d ${pkgdir}/usr/share/mateconf/schemas + + mateconf-merge-schema ${pkgdir}/usr/share/mateconf/schemas/${pkgname}.schemas --domain ${pkgname} ${pkgdir}/etc/mateconf/schemas/*.schemas || return 1 + rm -f ${pkgdir}/etc/mateconf/schemas/*.schemas +} + +# esto incluye la parte que se repite en la mayoria de los builds +. /usr/share/mate-doc-utils/mate-debian.sh diff --git a/distro/ubuntu/postinst b/distro/ubuntu/postinst new file mode 100755 index 00000000..8e425b79 --- /dev/null +++ b/distro/ubuntu/postinst @@ -0,0 +1,15 @@ +#!/bin/sh + +pkgname=mate-file-manager + +if [ -f /usr/sbin/mateconfpkg ]; then + /usr/sbin/mateconfpkg --install ${pkgname} +fi + +gtk-update-icon-cache -q -t -f /usr/share/icons/hicolor + +update-desktop-database -q + +update-mime-database /usr/share/mime > /dev/null + +exit 0 diff --git a/distro/ubuntu/postrm b/distro/ubuntu/postrm new file mode 100755 index 00000000..2c84eea7 --- /dev/null +++ b/distro/ubuntu/postrm @@ -0,0 +1,10 @@ +#!/bin/sh +set -e + +pkgname=mate-file-manager + +gtk-update-icon-cache -q -t -f /usr/share/icons/hicolor +update-desktop-database -q +update-mime-database /usr/share/mime > /dev/null + +exit 0 diff --git a/distro/ubuntu/preinst b/distro/ubuntu/preinst new file mode 100755 index 00000000..0fb460a9 --- /dev/null +++ b/distro/ubuntu/preinst @@ -0,0 +1,8 @@ +#!/bin/sh -e + +pkgname=mate-file-manager + +if [ -f /usr/sbin/mateconfpkg ]; then + /usr/sbin/mateconfpkg --uninstall ${pkgname} +fi + diff --git a/distro/ubuntu/prerm b/distro/ubuntu/prerm new file mode 100755 index 00000000..0ae99ca5 --- /dev/null +++ b/distro/ubuntu/prerm @@ -0,0 +1,11 @@ +#!/bin/bash + +set -e + +pkgname=mate-file-manager + +if [ -f /usr/sbin/mateconfpkg ]; then + /usr/sbin/mateconfpkg --uninstall ${pkgname} +fi + +exit 0 diff --git a/docs/Makefile.am b/docs/Makefile.am new file mode 100644 index 00000000..71c07ba2 --- /dev/null +++ b/docs/Makefile.am @@ -0,0 +1,25 @@ +NULL = + +SUBDIRS = reference + +man_MANS = \ + caja.1 \ + caja-connect-server.1 \ + caja-file-management-properties.1 \ + $(NULL) + +EXTRA_DIST = \ + $(man_MANS) \ + architecture.txt \ + dnd.txt \ + load-states.dia \ + caja-internals.sxw \ + caja-internals.pdf \ + caja-io.txt \ + caja.faq \ + recommended-books.html \ + smoketests.html \ + state-machines.txt \ + style-guide.html \ + key_mouse_navigation.txt \ + $(NULL) diff --git a/docs/architecture.txt b/docs/architecture.txt new file mode 100644 index 00000000..83ce44fd --- /dev/null +++ b/docs/architecture.txt @@ -0,0 +1,160 @@ + + +* Caja Architecture Block Diagram + + ++-----------------------------------------------------------------------+ +| | +| caja application | +| | +| +----------------------------------------------------------+ | +| | | | +| | | | +| | CajaWindow | | +| | | | +| | | | +| +----------------------------------------------------------+ | +| | | | | +| | | | | +| \|/ \|/ \|/ | +| +---------------------+ +------------------+ +------------------+ | +| | | | | | | | +| | CajaContentView | | CajaMetaView | | CajaMetaView | | +| | | | | | | | +| +---------------------+ +------------------+ +------------------+ | +| /||\ /||\ /||\ | +| || || || | ++----------||---------------------------||------------------------||----+ + || || || + CORBA CORBA CORBA + || || || ++----------||------------------+ +------||-------------------+ +--||-----------------------+ +| \||/ | | \||/ | | \||/ | +| +--------------------------+ | | +-----------------------+ | | +-----------------------+ | +| | | | | | | | | | | | +| | CajaContentViewFrame | | | | CajaMetaViewFrame | | | | CajaMetaViewFrame | | +| | | | | | | | | | | | +| +--------------------------+ | | +-----------------------+ | | +-----------------------+ | +| | | | | | +| caja view component | | caja view component | | caja view component | +| | | | | | ++------------------------------+ +---------------------------+ +---------------------------+ + + + +* Caja Architecture Summary + +Caja is a general-purpose shell application for browsing arbitrary +content. It is implemented as `caja', a container application +which excercises overall control and provides chrome, and a number of +caja view components. These view components may use the +`libcaja' library to ease implementation. + +There are two types of views, content views and meta-views. A caja +window typically has one content view, which is displayed in the main +area of the window, and several meta-views, which are displayed on the +left, typically one at a time. The meta-views should be panels that +display information about the content being displayed, or that provide +navigation aids. + +However, ultimately multiple content views will be available and may +be switched by using an option menu. + +The caja application has a CajaWindow object for each window +it displays. The CajaWindow object provides various chrome and +uses a number of CajaView objects to communicate with view +components. The relationship between CajaWindow and the +CajaViews is mostly, but not completely one-way; primarily, the +window calls the view's methods and connects to its signals. + +The CajaView object serves as a proxy for a view component. It +provides a number of methods which correspond to the methods of the +Caja:View IDL interface, and translates calls to these methods to +CORBA calls to the view component. It also translates incoming calls +from the view component into signal emissions for a set of signals +that reflects that Caja:ViewFrame IDL interface. + +The CajaViewFrame object serves the corresponding role in the view +component. It provides methods that correspond to the +Caja:ViewFrame IDL interface which it translates to CORBA calls to +the app, and translates incoming CORBA calls from the app into signal +emissions which reflect the Caja:View IDL interface. + +Thus, whenever the application calls a CajaView method to +communicate with the view, a CORBA message is sent, and a signal is +emitted in the view component by CajaViewFrame. And conversely, +when the view component calls a CajaViewFrame method to +communicate with the app, a CORBA message is sent, and a signal is +emitted by CajaView. + + + +* Control Flow for a Location Change + +There are two possible cases. One case is when one of the views +requests a location change. The other is when the framework itself +initiates a location change. This may happen for various reasons, such +as the user typing a URI into the location bar, the user pressing the +Back or Forward buttons, or the user selecting a bookmark. + +** A view requests a location change + +For a view to initiate a location change, view-specific code in the +component calls caja_view_frame_request_location_change with the +appropriate arguments. This results in the "request_location_change" +signal being emitted by the corresponding CajaView object in the +app, as described above. The CajaWindow has connected to this +signal, so it is made aware of the request. The app may decide to +create a new window to display the new location, or to display it in +the same window. Either way, control proceeds largely as below. + + +** The framework carries out a location change + +When a CajaWindow has determined that it should carry out a +location change or load an initial location, it calls +`caja_window_change_location'. This routine begins by stopping any +previous in-progress loads. Then it determines the applicable content +views and meta-views. It then enters a state machine which results in +updating each view. + +When an individual view is being updated, one of two things may +happen. First, if the same view component is still applicable but the +location is different, `caja_view_notify_location_change' is +called which causes the "notify_location_change" signal to be emitted +in the view. If the same view component is no longer applicable, then +a new CajaView object is created, and the component for the proper +iid is loaded. Then `caja_view_notify_location_change' is called +to set it's initial location. + + +** Other component types + +Caja also has built-in support for viewing locations via MateComponent +subdocuments and MateComponent controls. This is implemented in the view and +transparent to the caja application. However, the underlying +architecture is different. + + + +* Other Communication + +The Caja:View and Caja:ViewFrame interfaces allow for other +communication as well. + +The view may request that the frame update the status message, +indicate a certain level of progress during loading, or display a +particular selection. + +The view frame may notify the view of a change in selection, tell it +to stop a load in progress, ask it to load or save its state, or ask +it to show its properties. + +Some conventions apply to the stop and progress operations. First, +`stop_location_change' should be an idempotent operation - that is, +performing it several times in a row should have the same effect as +performing it once, and it should not cause a crash. Second, the view +should send a `request_progress_change' message with a type of either +PROGRESS_DONE_OK or PROGRESS_DONE_ERROR when it is done loading, as +appropriate. This is necessary so that the stop button can be +desensitized when loading is complete. diff --git a/docs/caja-connect-server.1 b/docs/caja-connect-server.1 new file mode 100644 index 00000000..5ac49b70 --- /dev/null +++ b/docs/caja-connect-server.1 @@ -0,0 +1,50 @@ +.\" Hey, EMACS: -*- nroff -*- +.\" First parameter, NAME, should be all caps +.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection +.\" other parameters are allowed: see man(7), man(1) +.TH caja-connect-server 1 "05 Jan 2008" +.\" Please adjust this date whenever revising the manpage. +.\" +.\" Some roff macros, for reference: +.\" .nh disable hyphenation +.\" .hy enable hyphenation +.\" .ad l left justify +.\" .ad b justify to both left and right margins +.\" .nf disable filling +.\" .fi enable filling +.\" .br insert line break +.\" .sp insert n+1 empty lines +.\" for manpage-specific macros, see man(7) +.SH NAME +caja-connect-server \- To Access a remote server +.SH SYNOPSIS +.B caja-connect-server +.RI [ options ] +.RI [ URI ] +.SH DESCRIPTION +This manual page documents briefly the +.B caja-connect-server +command. +.PP +Caja Connect Server is the connection manager for the MATE desktop. +.PP +You can use the file manager to access a remote server, be it an FTP site, +a Windows share, a WebDav server or an SSH server. +.SH OPTIONS +Caja follows the usual GNU command line syntax, with long options starting +with two dashes (`-'). A summary of options is included below. +.TP +.B \-\-help +Show a summary of options. +.TP +.B \-\-version +Show version. +.TP +Other standard MATE options not listed here are also supported. +.SH SEE ALSO +Caja Connect Server documentation can be found from the "Help" menu, or by pressing the +F1 key. Caja also has a website at http://www.gnome.org/projects/caja/ +.SH AUTHOR +This manual page was written by Julian Andres Klode for the +Debian GNU/Linux system (but may be used by others), based on a manpage by +Fernando Ribeiro . diff --git a/docs/caja-file-management-properties.1 b/docs/caja-file-management-properties.1 new file mode 100644 index 00000000..64db38d3 --- /dev/null +++ b/docs/caja-file-management-properties.1 @@ -0,0 +1,49 @@ +.\" Hey, EMACS: -*- nroff -*- +.\" First parameter, NAME, should be all caps +.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection +.\" other parameters are allowed: see man(7), man(1) +.TH caja-file-management-properties 1 "05 Jan 2008" +.\" Please adjust this date whenever revising the manpage. +.\" +.\" Some roff macros, for reference: +.\" .nh disable hyphenation +.\" .hy enable hyphenation +.\" .ad l left justify +.\" .ad b justify to both left and right margins +.\" .nf disable filling +.\" .fi enable filling +.\" .br insert line break +.\" .sp insert n+1 empty lines +.\" for manpage-specific macros, see man(7) +.SH NAME +caja-file-management-properties \- File Management Preferences +.SH SYNOPSIS +.B caja-file-management-properties +.RI [ options ] +.SH DESCRIPTION +This manual page documents briefly the +.B caja-file-management-properties +command. +.PP +File Management Preferences allows an user to configure the way caja looks. +.PP +You can specify a default view, and select sort options and display options. +You can also specify default settings for icon views and list views. +.SH OPTIONS +Caja follows the usual GNU command line syntax, with long options starting +with two dashes (`-'). A summary of options is included below. +.TP +.B \-\-help +Show a summary of options. +.TP +.B \-\-version +Show version. +.TP +Other standard MATE options not listed here are also supported. +.SH SEE ALSO +File Management Preferences documentation can be found from the "Help" menu, or by pressing the +F1 key. Caja also has a website at http://www.gnome.org/projects/caja/ +.SH AUTHOR +This manual page was written by Julian Andres Klode for the +Debian GNU/Linux system (but may be used by others), based on a manpage by +Fernando Ribeiro . diff --git a/docs/caja-internals.pdf b/docs/caja-internals.pdf new file mode 100644 index 00000000..8d321f1d Binary files /dev/null and b/docs/caja-internals.pdf differ diff --git a/docs/caja-internals.sxw b/docs/caja-internals.sxw new file mode 100644 index 00000000..23f687ba Binary files /dev/null and b/docs/caja-internals.sxw differ diff --git a/docs/caja-io.txt b/docs/caja-io.txt new file mode 100644 index 00000000..2219d308 --- /dev/null +++ b/docs/caja-io.txt @@ -0,0 +1,255 @@ +Caja I/O Primer +draft ("Better Than Nothing") +2001-08-23 +Darin Adler + +The Caja shell, and the file manager inside it, does a lot of +I/O. Because of this, there are some special disciplines required when +writing Caja code. + +No I/O on the main thread + +To be able to respond to the user quickly, Caja needs to be +designed so that the main user input thread does not block. The basic +approach is to never do any disk I/O on the main thread. + +In practice, Caja code does assume that some disk I/O is fast, in +some cases intentionally and in other cases due to programmer +sloppiness. The typical assumption is that reading files from the +user's home directory and the installed files in the Caja datadir +are very fast, effectively instantaneous. + +So the general approach is to allow I/O for files that have file +system paths, assuming that the access to these files is fast, and to +prohibit I/O for files that have arbitrary URIs, assuming that access +to these could be arbitrarily slow. Although this works pretty well, +it is based on an incorrect assumption, because with NFS and other +kinds of abstract file systems, there can be arbitrarily slow parts of +the file system that have file system paths. + +For historical reasons, threading in Caja is done through the +mate-vfs asynchronous I/O abstraction rather than using threads +directly. This means that all the threads are created by mate-vfs, +and Caja code runs on the main thread only. Thus, the rule of +thumb is that synchronous mate-vfs operations like the ones in + are illegal in most Caja +code. Similarly, it's illegal to ask for a piece of information, say a +file size, and then wait until it arrives. The program's main thread +must be allowed to get back to the main loop and start asking for user +input again. + +How CajaFile is used to do this + +The CajaFile class presents an API for scheduling this +asynchronous I/O and dealing with the uncertainty of when the +information will be available. (It also does a few other things, but +that's the main service it provides.) When you want information about +a particular file or directory, you get the CajaFile object for +that item using caja_file_get. This operation, like most +CajaFile operations, is not allowed to do any disk I/O. Once you +have a CajaFile object, you can ask it questions like "What is +your file type?" by calling functions like +caja_file_get_file_type. However, for a newly created CajaFile +object the answer is almost certainly "I don't know." Each function +defines a default, which is the answer given for "I don't know." For +example, caja_file_get_type will return +MATE_VFS_FILE_TYPE_UNKNOWN if it doesn't yet know the type. + +It's worth taking a side trip to discuss the nature of the +CajaFile API. Since these classes are a private part of the +Caja implementation, we make no effort to have the API be +"complete" in an abstract sense. Instead we add operations as +necessary and give them the semantics that are most handy for our +purposes. For example, we could have a caja_file_get_size that +returns a special distinguishable value to mean "I don't know" or a +separate boolean instead of returning 0 for files where the size is +unknown. This is entirely motivated by pragmatic concerns. The intent +is that we tweak these calls as needed if the semantics aren't good +enough. + +Back to the newly created CajaFile object. If you actually need to +get the type, you need to arrange for that information to be fetched +from the file system. There are two ways to make this request. If you +are planning to display the type on an ongoing basis then you want to +tell the CajaFile that you'll be monitoring the file's type and want to +know about changes to it. If you just need one-time information about +the type then you'll want to be informed when the type is +discovered. The calls used for this are caja_file_monitor_add and +caja_file_call_when_ready respectively. Both of these calls take a +list of information needed about a file. If all you need is the file +type, for example, you would pass a list containing just +CAJA_FILE_ATTRIBUTE_FILE_TYPE (the attributes are defined in +caja-file-attributes.h). Not every call has a corresponding file +attribute type. We add new ones as needed. + +If you do a caja_file_monitor_add, you also typically connect to +the CajaFile object's changed signal. Each time any monitored +attribute changes, a changed signal is emitted. The caller typically +caches the value of the attribute that was last seen (for example, +what's displayed on screen) and does a quick check to see if the +attribute it cares about has changed. If you do a +caja_file_call_when_ready, you don't typically need to connect to +the changed signal, because your callback function will be called when +and if the requested information is ready. + +Both a monitor and a callback can be cancelled. For ease of +use, neither requires that you store an ID for +canceling. Instead, the monitor function uses an arbitrary client +pointer, which can be any kind of pointer that's known to not conflict +with other monitorers. Usually, this is a pointer to the monitoring +object, but it can also be, for example, a pointer to a global +variable. The call_when_ready function uses the callback function and callback +data to identify the particular callback to cancel. One advantage of the monitor +API is that it also lets the CajaFile framework know that the file +should be monitored for changes made outside Caja. This is how we +know when to ask FAM to monitor a file or directory for us. + +Lets review a few of the concepts: + +1) Nearly all CajaFile operations, like caja_file_get_type, + are not allowed to do any disk I/O. +2) To cause the actual I/O to be done, callers need to use set up + either a monitor or a callback. +3) The actual I/O is done by asynchronous mate-vfs calls, so the work + is done on another thread. + +To work with an entire directory of files at once, you use +a CajaDirectory object. With the CajaDirectory object you can +monitor a whole set of CajaFile objects at once, and you can +connect to a single "files_changed" signal that gets emitted whenever +files within the directory are modified. That way you don't have to +connect separately to each file you want to monitor. These calls are +also the mechanism for finding out which files are in a directory. In +most other respects, they are like the CajaFile calls. + +Caching, the good and the bad + +Another feature of the CajaFile class is the caching. If you keep +around a CajaFile object, it keeps around information about the +last known state of that file. Thus, if you call +caja_file_get_type, you might well get file type of the file found +at this location the last time you looked, rather than the information +about what the file type is now, or "unknown". There are some problems +with this, though. + +The first problem is that if wrong information is cached, you need +some way to "goose" the CajaFile object and get it to grab new +information. This is trickier than it might sound, because we don't +want to constantly distrust information we received just moments +before. To handle this, we have the +caja_file_invalidate_attributes and +caja_file_invalidate_all_attributes calls, as well as the +caja_directory_force_reload call. If some code in Caja makes a +change to a file that's known to affect the cached information, it can +call one of these to inform the CajaFile framework. Changes that +are made through the framework itself are automatically understood, so +usually these calls aren't necessary. + +The second problem is that it's hard to predict when information will +and won't be cached. The current rule that's implemented is that no +information is cached if no one retains a reference to the +CajaFile object. This means that someone else holding a +CajaFile object can subtly affect the semantics of whether you +have new data or not. Calling caja_file_call_when_ready or +caja_file_monitor_add will not invalidate the cache, but rather +will return you the already cached information. + +These problems are less pronounced when FAM is in use. With FAM, any +monitored file is highly likely to have accurate information, because +changes to the file will be noticed by FAM, and that in turn will +trigger new I/O to determine what the new status of the file is. + +Operations that change the file + +You'll note that up until this point, I've only discussed getting +information about the file, not making changes to it. CajaFile +also contains some APIs for making changes. There are two kinds of +these. + +The calls that change metadata are examples of the first kind. These +calls make changes to the internal state right away and schedule I/O +to write the changes out to the file system. There's no way to detect +if the I/O succeeds or fails, and as far as the client code is +concerned the change takes place right away. + +The calls that make other kinds of file system change are examples of +of the second kind. These calls take a +CajaFileOperationCallback. They are all cancellable, and they give +a callback when the operation completes, whether it succeeds or fails. + +Files that move + +When a file is moved, and the CajaFile framework knows it, then +the CajaFile and CajaDirectory objects follow the file rather +than staying stuck to the path. This has a direct influence on the +user interface of Caja -- if you move a directory, already-open +windows and property windows will follow the directory around. + +This means that keeping around a CajaFile object and keeping +around a URI for a file have different semantics, and there are +cases where one is the better choice and cases where the other is. + +Icons + +The current implementation of the Caja icon factory uses +synchronous I/O to get the icons and ignores these guidelines. The +only reason this doesn't ruin the Caja user experience is that it +also refuses to even try to fetch icons from URIs that don't +correspond to file system paths, which for most cases means it limits +itself to reading from the high-speed local disk. Don't ask me what +the repercussions of this are for NFS; do the research and tell me +instead! + +Slowness caused by asynchronous operations + +One danger in all this asynchronous I/O is that you might end up doing +repeated drawing and updating. If you go to display a file right +after asking for information about it, you might immediately show an +"unknown file type" icon. Then, milliseconds later, you may complete +the I/O and discover more information about the file, including the +appropriate icon. So you end up drawing the icon twice. There are a +number of strategies for preventing this problem. One of them is to +allow a bit of hysteresis and wait some fixed amount of time after +requesting the I/O before displaying the "unknown" state. One +strategy that's used in Caja is to wait until some basic +information is available until displaying anything. This might make +the program overall be faster, but it might make it seem slower, +because you don't see things right away. [What other strategies +are used in Caja now for this?] + +How to make Caja slow + +If you add I/O to the functions in CajaFile that are used simply +to fetch cached file information, you can make Caja incredibly I/O +intensive. On the other hand, the CajaFile API does not provide a +way to do arbitrary file reads, for example. So it can be tricky to +add features to Caja, since you first have to educate CajaFile +about how to do the I/O asynchronously and cache it, then request the +information and have some way to deal with the time when it's not yet +known. + +Adding new kinds of I/O usually involves working on the Caja I/O +state machine in caja-directory-async.c. If we changed Caja to +use threading instead of using mate-vfs asychronous operations, I'm +pretty sure that most of the changes would be here in this +file. That's because the external API used for CajaFile wouldn't +really have a reason to change. In either case, you'd want to schedule +work to be done, and get called back when the work is complete. + +[We probably need more about caja-directory-async.c here.] + +Future direction + +Some have suggested that by using threading directly in Caja +rather than using it indirectly through the mate-vfs async. calls, +we could simplify the I/O code in Caja. It's possible this would +make a big improvement, but it's also possible that this would primarily +affect the internals and implementation details of CajaFile and +still leave the rest of the Caja code the same. + +That's all for now + +This is a very rough early draft of this document. Let me know about +other topics that would be useful to be covered in here. + + -- Darin diff --git a/docs/caja.1 b/docs/caja.1 new file mode 100644 index 00000000..dc26cf6c --- /dev/null +++ b/docs/caja.1 @@ -0,0 +1,77 @@ +.\" Hey, EMACS: -*- nroff -*- +.\" First parameter, NAME, should be all caps +.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection +.\" other parameters are allowed: see man(7), man(1) +.TH Caja 1 "24 May 2004" +.\" Please adjust this date whenever revising the manpage. +.\" +.\" Some roff macros, for reference: +.\" .nh disable hyphenation +.\" .hy enable hyphenation +.\" .ad l left justify +.\" .ad b justify to both left and right margins +.\" .nf disable filling +.\" .fi enable filling +.\" .br insert line break +.\" .sp insert n+1 empty lines +.\" for manpage-specific macros, see man(7) +.SH NAME +caja \- the MATE File Manager +.SH SYNOPSIS +.B caja +.RI [ options ] " URIs" ... +.br +.SH DESCRIPTION +This manual page documents briefly the +.B caja +command. This manual page was written for the Debian GNU/Linux distribution +because the original program does not have a manual page. +.PP +Caja is the file manager for the MATE desktop. +.br +.SH OPTIONS +Caja follows the usual GNU command line syntax, with long options starting +with two dashes (`-'). A summary of options is included below. +.TP +.B \-\-browser +Open a browser window. +.TP +.B \-c +.TP +.B \-\-check +Perform a quick set of self-check tests. +.TP +.B \-g +.TP +.B \-\-geometry=\fIGEOMETRY\fR +Create the initial window with the given geometry. +.TP +.B \-n +.TP +.B \-\-no-default-window +Only create windows for explicitly specified URIs. +.TP +.B \-\-no-desktop +Do not manage the desktop \(em ignore the preference set in the preferences +dialog. +.TP +.B \-q +.TP +.B \-\-quit +Quit Caja. +.TP +.B \-\-help +Show a summary of options. +.TP +.B \-\-version +Show Caja' version. +.TP +Other standard MATE options not listed here are also supported. +.SH SEE ALSO +Caja documentation can be found from the "Help" menu, or by pressing the +F1 key. Caja also has a website at +http://www.gnome.org/projects/caja/ +.SH AUTHOR +This manual page was written by Takuo KITAME and Dafydd +Harries for the Debian GNU/Linux system (but may be used +by others). diff --git a/docs/caja.faq b/docs/caja.faq new file mode 100644 index 00000000..47061ed4 --- /dev/null +++ b/docs/caja.faq @@ -0,0 +1,7 @@ +1. What is Caja ? + + Caja is an open-source file manager and graphical shell being + developed by Eazel, Inc. and others. It is part of the MATE project, and its + source code can be found in the MATE CVS repository. Caja is still in + the early stages of development. It will become an integral part of the + MATE desktop environment when it is finished. diff --git a/docs/dnd.txt b/docs/dnd.txt new file mode 100644 index 00000000..91467f33 --- /dev/null +++ b/docs/dnd.txt @@ -0,0 +1,92 @@ + Caja dnd code. + ------------------ + + +Caja dnd code is pretty compilcated, it has a lot of entry points and exit points. +Trying to clarify this now. + +You have to implement: + +If you are a source: + drag_begin + drag_end + drag_get_data + +If you are a destination: + drag_motion + drag_data_received + drag_drop + drag_leave + + + 1) Source + --------- + +if you are a source, you have to start a drag trough gtk_drag_begin. +This will call drag_begin signal in the source. +Then, when the destination calls gtk_drag_finish, drag_end will be +called in the source. + +drag_get_data will be called in the source when the destination +calls gtk_drag_get_data + +So, the source is very easy to write: it just needs to implement +those 3 signals and it should not have any memory management issue. + + + 2) Destination + -------------- + +Things get a little bit complicated. +when the dragging cursor gets in your window, you will get drag_motion +events. In caja, we do many things in this function: + - we start auto-scrolling if it is necessary. + - we call caja_*_ensure_data + - we prelight what is under the cursor if it can accept the drag. + - we try to expand what is under you if it can accept the drop (tree view) + +caja_*_ensure_data is vital. It calls gtk_drag_get_data to get the +data from the source. this allows the destination to store it in advance and use it +to know if what is under the cursor can accept the drag. + +Then, when the drop occurs, drag_drop is called on the destination. +drag_drop calls gtk_drag_get_data to get the data from the source to do its drop. +Then, drag_data_received is called when the data is received. +There, we can do the actual operation involved by the drop. +Also, just before the drag_drop event, a drag_leave event is triggered. + +If no drop occurs, a drag_leave occurs. + +So, drag_data_received does 2 things: it is called to get the data when we are +in motion and store it. It is also called to do the actual drop operation when +a drop happened. + +So, drag_data_received usually does 2 tests: it tests if the data was received. +If it was received, it stores it. +Then it tests if the drop occured just before. If so, it does the operation. + +This schema involves careful memory management: + 1) 2 exit points in destination. (drag_leave and drag_data_received) + 2) a lot of things are done in the callbacks so you have to take into + account all the possible code paths. + +To solve 1), we should use ONE destroy function which cleans up the drag data. +To solve 2), we have to be very careful where we call this fution from. + +This function has to clean up: + - the list of expanded nodes (tree view). + - the autoscroll code. + - the prelighting code. + It also has to set drag_info->need_to_destroy to TRUE + so that during the next drag in this widget, the + rest of the drag data is destroyed before begening the actual + new drag. + +When we receive a drag_motion, we first test for need_to_destroy and +destroy the rest of the data left from the previous drag. This code +has to destroy/reset: + - the drag data. + - the boolean vars used to store the state of the drag. + + + diff --git a/docs/key_mouse_navigation.txt b/docs/key_mouse_navigation.txt new file mode 100644 index 00000000..d111f43e --- /dev/null +++ b/docs/key_mouse_navigation.txt @@ -0,0 +1,112 @@ +This document describes the keyboard and mouse navigation model used +in the default Caja views in detail. This is useful as a a guide +for people implementing a Caja view or something else that wants +to have a feel that is compatible with Caja. + +*********** Icon view ******************** + +Keyboard: +========= + +Navigation and selection: + +When the focus is on the icon view you can move the currently selected +icon by using: + +Arrow Keys - moves one step in the direction +Tab - moves to the "next" icon in order (i.e. at the end of one row, + go to the first icon the next row) +Shift Tab - moves to the "previous" icon in order +Home - moves to the first icon +End - moves to the last icon + +In order to allow multiple selection the above navigation keys can be +combined with the Control key to move the keyboard focus without +affecting the current selection. If you use normal movement (not using +control) all the previously selected icons will be deselected. + +If several icons are selected and there is no keyboard focus you press +up or left will start navigating from the topmost leftmost icon, while +pressing down or right will start from the bottommost rightmost +icon. This works the same way if you hold down Control. + +To select or deselect an icon position the keyboard focus on it and +press ctlr-space. ctrl-space with no keyboard focus produces a +keyboard focus at the first selected icon, or the first one if none +are selected. + +In manual layout (and especially, on the desktop) the keyboard arrow +keys work in a slightly different way. To allow all icons to be +reached the closest icon in the quadrant of the direction selected +will be used as the "next" icon when navigating. + +Other keyboard shortcuts: + +Return, Keypad Return - Activate the selected objects +Space (without control) - Activate the selected objects +Escape - Undo icon stretching if in progress + +Alt Left - go back +Alt Right - go forward +Alt Up - go up a directory +Alt Down - enter directory / activate selection + +Shift-F10 bring up context menu for selection, or the directory context menu if nothing is selected +Ctrl-F10 bring up context menu for directory + +Other key presses are used for typeahead search + +In rename mode: + +Escape - Cancel rename +Return, Keypad Return - Finish rename + +Mouse: +====== + +In double click mode: + +Clicking on an icon selects it and deselects all others on +BUTTON_PRESS. Dragging does the default dnd file operation. + +Clicking on blank space deselect all selected icons. Doesn't allow +dragging. + +Double clicking (both clicks on the same icon) with no modifiers +activates the clicked file. (And deselects the others due to the first +click.) + +Clicking when Control (Shift can also be used, which is not written +out below) is held down can be used to do multiple selections. + +Control-click on empty space does nothing. +Control-click on unselected icon selects it on BUTTON_PRESS +Control-click on selected icon de-selects it on BUTTON_RELEASE +Control-double click does nothing +Control can be held down while starting a drag + +While doing a drag modifers affect the operation the drag causes: +Control - Copy the files +Shift - Move the files +Alt - Open a menu with the available alternatives + +All the basic clicks are typically done with the left button, but can +be done with the other buttons to. [Do we want this?] However some of +the buttons also have special operations: + +Right-click on a selected icon opens the context menu for the selected +icons. +Right-click on empty space opens the context menu for the directory. +Middle-button drag always opens the menu with possible operations on +drop. + +In single click mode: + +Single click mode work just like double click mode except single +clicks on icons activate the icon on button release if you didn't +drag, didn't hold down for 1.5 secs or clicked twice within the +double-click time. + +*********** List view ******************** + +[TODO: Add stuff here] diff --git a/docs/load-states.dia b/docs/load-states.dia new file mode 100644 index 00000000..d650ceae Binary files /dev/null and b/docs/load-states.dia differ diff --git a/docs/recommended-books.html b/docs/recommended-books.html new file mode 100644 index 00000000..cedf95ab --- /dev/null +++ b/docs/recommended-books.html @@ -0,0 +1,167 @@ + + + +Eazel: Darin's Recommended Programming Books + + + + +

This document was really more for Eazel than for all Caja hackers, +but since the style guide references it, I checked it into the Caja CVS +for now. Later we can figure out what to do with it.

+ +

This document is left over from when Eazel was doing a program in C++. +Soon, I'll rearrange the document so it doesn't put all the C++ stuff first, +since C++ is immaterial for the current Caja project.

+ +

If you buy books from Amazon.com using the links on this page, Darin will get a small kickback from Amazon.

+ +

One of the main reasons for creating this list is that there are many poor C++ books out there. +I've picked out a small number of extremely useful books so you won't have to wade through the weaker ones.

+ +

C++ Reference Books

+ +

These books cover the C++ language and library. All of them except for the +C++ standard itself also contain useful introductory material. For some +programmers, these are enough to explain the features of the language.

+ +

The C++ Programming Language, Third Edition, +Bjarne Stroustrup. This is the book by the creator of the C++ language. This third edition is far superior +to the first two, and covers the ISO Standard version of the language in detail, including the library. +Any serious C++ programmer should read this book. There have been many corrections since the first printing, so get +the newest printing you can. Bjarne has supporting materials +for the book on the web, including the errata lists that enumerate all changes between printings.

+ +

The C++ Standard Library, +Nicolai M. Josuttis. This book has the best coverage of the library. There have been tons of others that cover +the library, or focus on the STL or streams. But Josuttis covers all these subjects better than any of his +predecessors. Since we use the library extensively in Eazel projects, this is a must read. +The author has some useful supporting materials on the web.

+ +

C++ Technique Books

+ +

These books are about specific programming techniques for writing code in C++. +They can help you understand idioms you'll find in our code. +This kind of idiomatic programming is important in C++, because the language +gives you so much freedom to write unusable, unmaintainable code.

+ +

Exceptional C++, +Herb Sutter. This is a collection of material that was originally part of Herb's +Guru of the Week. This includes much of the most +advanced C++ information available. I learned many of the most important techniques from Herb, including +the swap technique for writing safe assignment operators. Herb covers each topic thoroughly.

+ +

Ruminations on C++, +Andrew Koenig and Barbara Moo.

+ +

Effective C++, Second Edition +and More Effective C++, +Scott Meyers. These books contain a laundry list of important C++ idioms. The books are a bit less +important now than when they were first released, but still full of valuable stuff. There's also a +CD edition +(there's a copy of it on Rob's machine) +that contains both books in electronic form. The publisher's web site has a good collection of +supporting materials for both +the original and +the second book

+ +

The Design and Evolution of C++, +Bjarne Stroustrup. While this book doesn't prescribe any specific techniques, it will help you understand the +tradeoffs behind all the language features, and how C++ got to be what it is. I highly recommend it.

+ +

C++ Tutorial Books

+ +

These books explain C++ programming from scratch. These particular examples are so good that they +can be useful even for experienced programmers who already know C++ well.

+ +

Essential C++, +Stanley Lippman. This tutorial is much more useful than the longer and more complete works, like +C++ Primer. +It covers the features and the reasons for the features quite well. In particular, it has a good explanation +of references and pointers and why you'd use one or the other. It covers templates and exceptions fairly well.

+ +

Gtk Books

+ +

OK, so I'm not an expert on Gtk yet. But I'm becoming one.

+ +

Gtk+/Mate Application Development, +Havoc Pennington. I learned a lot from this book. But it's all Gtk+ and C; things are done +a bit differently with Gtk-- from C++. It's still worth reading.

+ +

Programming Technique Books

+ +

These books are valuable because of the ideas in them, but are not specific to a particular programming language or toolkit.

+ +

Refactoring, +Martin Fowler. This book outlines a philosophy of programming that we embrace at Eazel. The ideas +about changing existing code to improve it so it can be modified are extremely important. The ideas +about unit testing as a means to this end shape the way we use unit testing at Eazel. +All the examples in the book are in Java, but the ideas apply well to C++.

+ +

The Practice of Programming, +Brian Kernighan, Rob Pike. This book, by two of the most famous UNIX programmers, covers a lot of basic +programming smarts. I don't agree with everything they have to say, but the book is great as a whole.

+ +

Programming Pearls, Second Edition, +Jon Bentley. This classic has recently been updated with a second edition. I haven't read the second edition +yet, but I'm sure it's great. When I read it, I'll put more specific comments here.

+ +

Design Patterns. +There's also a CD edition +(there's a copy of it on Rob's machine).

+ +

Algorithms in C++, Third Edition, +Robert Sedgewick. The original version is in C. +There's also an upcoming Java version.

+ +

Books I Have Read, But Do Not Recommend

+ +

I've also read many books on these topics that were less useful than the ones listed above. +Here are a few that were not as exemplary. I won't try to sort out the ones that I found simply "not as useful as the best ones" +from the truly awful. If you see a book that's not on this list, it might be one I'd recommend. Maybe +I haven't read it.

+ +

C Interfaces and Implementations.

+ +

C++ IOStreams Handbook, +Steve Teale. Josuttis covers streams better.

+ +

Extreme Programming Explained. +My love for Refactoring had me excited about this one, but it was a disappointment.

+ +

Generic Programming and the STL, +Matt Austern. I don't know of anyone who knows more about the STL than Matt Austern, who's currently +maintaining the main implementation at SGI. But Josuttis covers the STL better.

+ +

Industrial Strength C++.

+ +

Inside the C++ Object Model.

+ +

Large-Scale C++ Software Design, +John Lakos.

+ +

Objects Unencapsulated: Java, Eiffel and C++??. +This is a basically an "Eiffel is great, C++ sucks" book. Some interesting insights, but a lot of sloppy thinking.

+ +

Books That Need Review

+ +

This is a list of possibly important books that I haven't checked out yet.

+ +

C++ Primer, Third Edition, +Stanley Lippman, Josee Lajoie. The earlier editions were good but not great. But I have reason +to believe that this one might be better than those were.

+ +

C++ Primer Answer Book. +I checked, and this answer book does go with the third edition of C++ Primer.

+ +

Design Patterns and Contracts.

+ +

Developing Linux Applications with GTK+ and GDK.

+ +

Linux Mate/Gtk Programming Bible.

+ +

Sams Teach Yourself Gtk+ Programming in 21 Days.

+ + + + diff --git a/docs/reference/Makefile.am b/docs/reference/Makefile.am new file mode 100644 index 00000000..4c6935b3 --- /dev/null +++ b/docs/reference/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = libcaja-extension diff --git a/docs/reference/Makefile.in b/docs/reference/Makefile.in new file mode 100644 index 00000000..cc8a1150 --- /dev/null +++ b/docs/reference/Makefile.in @@ -0,0 +1,646 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = docs/reference +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/gtk-doc.m4 \ + $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_GEN = $(am__v_GEN_$(V)) +am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) +am__v_GEN_0 = @echo " GEN " $@; +AM_V_at = $(am__v_at_$(V)) +am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) +am__v_at_0 = @ +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ + html-recursive info-recursive install-data-recursive \ + install-dvi-recursive install-exec-recursive \ + install-html-recursive install-info-recursive \ + install-pdf-recursive install-ps-recursive install-recursive \ + installcheck-recursive installdirs-recursive pdf-recursive \ + ps-recursive uninstall-recursive +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ + $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ + distdir +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +ACLOCAL = @ACLOCAL@ +ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@ +ALL_CFLAGS = @ALL_CFLAGS@ +ALL_LIBS = @ALL_LIBS@ +ALL_LINGUAS = @ALL_LINGUAS@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CAJA_EXTENSION_VERSION_INFO = @CAJA_EXTENSION_VERSION_INFO@ +CATALOGS = @CATALOGS@ +CATOBJEXT = @CATOBJEXT@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CORE_CFLAGS = @CORE_CFLAGS@ +CORE_LIBS = @CORE_LIBS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIRNAME = @DATADIRNAME@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DISABLE_DEPRECATED_CFLAGS = @DISABLE_DEPRECATED_CFLAGS@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ENABLE_EMPTY_VIEW = @ENABLE_EMPTY_VIEW@ +ENABLE_PROFILER = @ENABLE_PROFILER@ +EXEEXT = @EXEEXT@ +EXEMPI_CFLAGS = @EXEMPI_CFLAGS@ +EXEMPI_LIBS = @EXEMPI_LIBS@ +EXEMPI_NEW_API_CFLAGS = @EXEMPI_NEW_API_CFLAGS@ +EXEMPI_NEW_API_LIBS = @EXEMPI_NEW_API_LIBS@ +EXIF_CFLAGS = @EXIF_CFLAGS@ +EXIF_LIBS = @EXIF_LIBS@ +FGREP = @FGREP@ +GAIL_REQUIRED = @GAIL_REQUIRED@ +GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ +GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ +GLIB_REQUIRED = @GLIB_REQUIRED@ +GMOFILES = @GMOFILES@ +GMSGFMT = @GMSGFMT@ +GREP = @GREP@ +GTKDOC_CHECK = @GTKDOC_CHECK@ +GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@ +GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ +GTKDOC_MKPDF = @GTKDOC_MKPDF@ +GTKDOC_REBASE = @GTKDOC_REBASE@ +GTK_REQUIRED = @GTK_REQUIRED@ +HTML_DIR = @HTML_DIR@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INSTOBJEXT = @INSTOBJEXT@ +INTLLIBS = @INTLLIBS@ +INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ +INTLTOOL_MERGE = @INTLTOOL_MERGE@ +INTLTOOL_PERL = @INTLTOOL_PERL@ +INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ +INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@ +INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@ +INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@ +INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@ +INTROSPECTION_LIBS = @INTROSPECTION_LIBS@ +INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ +INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ +INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBCAJA_EXTENSION_CFLAGS = @LIBCAJA_EXTENSION_CFLAGS@ +LIBCAJA_EXTENSION_LIBS = @LIBCAJA_EXTENSION_LIBS@ +LIBEGG_CFLAGS = @LIBEGG_CFLAGS@ +LIBEGG_LIBS = @LIBEGG_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MATECONFTOOL = @MATECONFTOOL@ +MATECONF_SCHEMA_CONFIG_SOURCE = @MATECONF_SCHEMA_CONFIG_SOURCE@ +MATECONF_SCHEMA_FILE_DIR = @MATECONF_SCHEMA_FILE_DIR@ +MATE_DESKTOP_REQUIRED = @MATE_DESKTOP_REQUIRED@ +MKDIR_P = @MKDIR_P@ +MKINSTALLDIRS = @MKINSTALLDIRS@ +MSGFMT = @MSGFMT@ +MSGFMT_OPTS = @MSGFMT_OPTS@ +MSGMERGE = @MSGMERGE@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PANGO_REQUIRED = @PANGO_REQUIRED@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POFILES = @POFILES@ +POSUB = @POSUB@ +PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@ +PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@ +RANLIB = @RANLIB@ +RENDER_LIBS = @RENDER_LIBS@ +SED = @SED@ +SELINUX_LIBS = @SELINUX_LIBS@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +UNIQUE_CFLAGS = @UNIQUE_CFLAGS@ +UNIQUE_LIBS = @UNIQUE_LIBS@ +UPDATE_MIME_DATABASE = @UPDATE_MIME_DATABASE@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +WARNING_CFLAGS = @WARNING_CFLAGS@ +XGETTEXT = @XGETTEXT@ +XMKMF = @XMKMF@ +XML_REQUIRED = @XML_REQUIRED@ +X_CFLAGS = @X_CFLAGS@ +X_EXTRA_LIBS = @X_EXTRA_LIBS@ +X_LIBS = @X_LIBS@ +X_PRE_LIBS = @X_PRE_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +SUBDIRS = libcaja-extension +all: all-recursive + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu docs/reference/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu docs/reference/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. +$(RECURSIVE_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +$(RECURSIVE_CLEAN_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-recursive +all-am: Makefile +installdirs: installdirs-recursive +installdirs-am: +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-recursive + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: + +.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \ + install-am install-strip tags-recursive + +.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ + all all-am check check-am clean clean-generic clean-libtool \ + ctags ctags-recursive distclean distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs installdirs-am maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \ + uninstall uninstall-am + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/docs/reference/libcaja-extension/Makefile.am b/docs/reference/libcaja-extension/Makefile.am new file mode 100644 index 00000000..a73131d5 --- /dev/null +++ b/docs/reference/libcaja-extension/Makefile.am @@ -0,0 +1,84 @@ +## Process this file with automake to produce Makefile.in + +# We require automake 1.6 at least. +AUTOMAKE_OPTIONS = 1.6 + +# The name of the module, e.g. 'glib'. +DOC_MODULE=libcaja-extension + +# The top-level SGML file. +DOC_MAIN_SGML_FILE=$(DOC_MODULE)-docs.xml + +# The directory containing the source code. Relative to $(srcdir). +# gtk-doc will search all .c & .h files beneath here for inline comments +# documenting the functions and macros. +# e.g. DOC_SOURCE_DIR=../../../libcaja-extension +DOC_SOURCE_DIR=$(top_srcdir)/libcaja-extension + +# Extra options to pass to gtkdoc-scangobj. Not normally needed. +SCANGOBJ_OPTIONS=--type-init-func="g_type_init()" + +# Extra options to supply to gtkdoc-scan. +# e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED" +SCAN_OPTIONS=--deprecated-guards="G_DISABLE_DEPRECATED" + +# Extra options to supply to gtkdoc-mkdb. +MKDB_OPTIONS=--sgml-mode --output-format=xml + +# Extra options to supply to gtkdoc-mktmpl +# e.g. MKTMPL_OPTIONS=--only-section-tmpl +MKTMPL_OPTIONS= + +# Extra options to supply to gtkdoc-fixref. Not normally needed. +# e.g. FIXXREF_OPTIONS=--extra-dir=../gdk-pixbuf/html --extra-dir=../gdk/html +FIXXREF_OPTIONS= + +# Used for dependencies. The docs will be rebuilt if any of these change. +HFILE_GLOB=$(top_srcdir)/libcaja-extension/*.h +CFILE_GLOB=$(top_srcdir)/libcaja-extension/*.c + +# Header files to ignore when scanning. +IGNORE_HFILES = \ + config.h \ + caja-extension-i18n.h \ + $(NULL) + +# Images to copy into HTML directory +HTML_IMAGES = + +content_files = \ + version.xml \ + $(NULL) + +# SGML files where gtk-doc abbrevations (#GtkWidget) are expanded +# These files must be listed here *and* in content_files +# e.g. expand_content_files=running.sgml +expand_content_files= \ + $(NULL) + +# CFLAGS and LDFLAGS for compiling gtkdoc-scangobj with your library. +# Only needed if you are using gtkdoc-scangobj to dynamically query widget +# signals and properties. +# e.g. INCLUDES=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS) +# e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib) +GTKDOC_CFLAGS = \ + $(GTK_DEBUG_FLAGS) \ + -I$(srcdir) \ + -I$(top_srcdir) \ + -I$(top_srcdir)/libcaja-extension \ + -I$(top_builddir) \ + -I$(top_builddir)/libcaja-extension \ + $(LIBCAJA_EXTENSION_CFLAGS) \ + $(NULL) + +GTKDOC_LIBS = \ + $(top_builddir)/libcaja-extension/libcaja-extension.la \ + $(LIBCAJA_EXTENSION_LIBS) \ + $(NULL) + +# This includes the standard gtk-doc make rules, copied by gtkdocize. +include $(top_srcdir)/gtk-doc.make + +# Other files to distribute +# e.g. EXTRA_DIST += version.xml.in +EXTRA_DIST += version.xml.in diff --git a/docs/reference/libcaja-extension/Makefile.in b/docs/reference/libcaja-extension/Makefile.in new file mode 100644 index 00000000..992926ee --- /dev/null +++ b/docs/reference/libcaja-extension/Makefile.in @@ -0,0 +1,797 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# -*- mode: makefile -*- + +#################################### +# Everything below here is generic # +#################################### +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + $(srcdir)/version.xml.in $(top_srcdir)/gtk-doc.make +subdir = docs/reference/libcaja-extension +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/gtk-doc.m4 \ + $(top_srcdir)/m4/intltool.m4 $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = version.xml +CONFIG_CLEAN_VPATH_FILES = +AM_V_GEN = $(am__v_GEN_$(V)) +am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY)) +am__v_GEN_0 = @echo " GEN " $@; +AM_V_at = $(am__v_at_$(V)) +am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY)) +am__v_at_0 = @ +SOURCES = +DIST_SOURCES = +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +ACLOCAL_AMFLAGS = @ACLOCAL_AMFLAGS@ +ALL_CFLAGS = @ALL_CFLAGS@ +ALL_LIBS = @ALL_LIBS@ +ALL_LINGUAS = @ALL_LINGUAS@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CAJA_EXTENSION_VERSION_INFO = @CAJA_EXTENSION_VERSION_INFO@ +CATALOGS = @CATALOGS@ +CATOBJEXT = @CATOBJEXT@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CORE_CFLAGS = @CORE_CFLAGS@ +CORE_LIBS = @CORE_LIBS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DATADIRNAME = @DATADIRNAME@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DISABLE_DEPRECATED_CFLAGS = @DISABLE_DEPRECATED_CFLAGS@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ENABLE_EMPTY_VIEW = @ENABLE_EMPTY_VIEW@ +ENABLE_PROFILER = @ENABLE_PROFILER@ +EXEEXT = @EXEEXT@ +EXEMPI_CFLAGS = @EXEMPI_CFLAGS@ +EXEMPI_LIBS = @EXEMPI_LIBS@ +EXEMPI_NEW_API_CFLAGS = @EXEMPI_NEW_API_CFLAGS@ +EXEMPI_NEW_API_LIBS = @EXEMPI_NEW_API_LIBS@ +EXIF_CFLAGS = @EXIF_CFLAGS@ +EXIF_LIBS = @EXIF_LIBS@ +FGREP = @FGREP@ +GAIL_REQUIRED = @GAIL_REQUIRED@ +GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ +GLIB_GENMARSHAL = @GLIB_GENMARSHAL@ +GLIB_REQUIRED = @GLIB_REQUIRED@ +GMOFILES = @GMOFILES@ +GMSGFMT = @GMSGFMT@ +GREP = @GREP@ +GTKDOC_CHECK = @GTKDOC_CHECK@ +GTKDOC_DEPS_CFLAGS = @GTKDOC_DEPS_CFLAGS@ +GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ +GTKDOC_MKPDF = @GTKDOC_MKPDF@ +GTKDOC_REBASE = @GTKDOC_REBASE@ +GTK_REQUIRED = @GTK_REQUIRED@ +HTML_DIR = @HTML_DIR@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INSTOBJEXT = @INSTOBJEXT@ +INTLLIBS = @INTLLIBS@ +INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ +INTLTOOL_MERGE = @INTLTOOL_MERGE@ +INTLTOOL_PERL = @INTLTOOL_PERL@ +INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ +INTROSPECTION_CFLAGS = @INTROSPECTION_CFLAGS@ +INTROSPECTION_COMPILER = @INTROSPECTION_COMPILER@ +INTROSPECTION_GENERATE = @INTROSPECTION_GENERATE@ +INTROSPECTION_GIRDIR = @INTROSPECTION_GIRDIR@ +INTROSPECTION_LIBS = @INTROSPECTION_LIBS@ +INTROSPECTION_MAKEFILE = @INTROSPECTION_MAKEFILE@ +INTROSPECTION_SCANNER = @INTROSPECTION_SCANNER@ +INTROSPECTION_TYPELIBDIR = @INTROSPECTION_TYPELIBDIR@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBCAJA_EXTENSION_CFLAGS = @LIBCAJA_EXTENSION_CFLAGS@ +LIBCAJA_EXTENSION_LIBS = @LIBCAJA_EXTENSION_LIBS@ +LIBEGG_CFLAGS = @LIBEGG_CFLAGS@ +LIBEGG_LIBS = @LIBEGG_LIBS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MATECONFTOOL = @MATECONFTOOL@ +MATECONF_SCHEMA_CONFIG_SOURCE = @MATECONF_SCHEMA_CONFIG_SOURCE@ +MATECONF_SCHEMA_FILE_DIR = @MATECONF_SCHEMA_FILE_DIR@ +MATE_DESKTOP_REQUIRED = @MATE_DESKTOP_REQUIRED@ +MKDIR_P = @MKDIR_P@ +MKINSTALLDIRS = @MKINSTALLDIRS@ +MSGFMT = @MSGFMT@ +MSGFMT_OPTS = @MSGFMT_OPTS@ +MSGMERGE = @MSGMERGE@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PANGO_REQUIRED = @PANGO_REQUIRED@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PERL = @PERL@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POFILES = @POFILES@ +POSUB = @POSUB@ +PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@ +PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@ +RANLIB = @RANLIB@ +RENDER_LIBS = @RENDER_LIBS@ +SED = @SED@ +SELINUX_LIBS = @SELINUX_LIBS@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +UNIQUE_CFLAGS = @UNIQUE_CFLAGS@ +UNIQUE_LIBS = @UNIQUE_LIBS@ +UPDATE_MIME_DATABASE = @UPDATE_MIME_DATABASE@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +WARNING_CFLAGS = @WARNING_CFLAGS@ +XGETTEXT = @XGETTEXT@ +XMKMF = @XMKMF@ +XML_REQUIRED = @XML_REQUIRED@ +X_CFLAGS = @X_CFLAGS@ +X_EXTRA_LIBS = @X_EXTRA_LIBS@ +X_LIBS = @X_LIBS@ +X_PRE_LIBS = @X_PRE_LIBS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ + +# We require automake 1.6 at least. +AUTOMAKE_OPTIONS = 1.6 + +# The name of the module, e.g. 'glib'. +DOC_MODULE = libcaja-extension + +# The top-level SGML file. +DOC_MAIN_SGML_FILE = $(DOC_MODULE)-docs.xml + +# The directory containing the source code. Relative to $(srcdir). +# gtk-doc will search all .c & .h files beneath here for inline comments +# documenting the functions and macros. +# e.g. DOC_SOURCE_DIR=../../../libcaja-extension +DOC_SOURCE_DIR = $(top_srcdir)/libcaja-extension + +# Extra options to pass to gtkdoc-scangobj. Not normally needed. +SCANGOBJ_OPTIONS = --type-init-func="g_type_init()" + +# Extra options to supply to gtkdoc-scan. +# e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED" +SCAN_OPTIONS = --deprecated-guards="G_DISABLE_DEPRECATED" + +# Extra options to supply to gtkdoc-mkdb. +MKDB_OPTIONS = --sgml-mode --output-format=xml + +# Extra options to supply to gtkdoc-mktmpl +# e.g. MKTMPL_OPTIONS=--only-section-tmpl +MKTMPL_OPTIONS = + +# Extra options to supply to gtkdoc-fixref. Not normally needed. +# e.g. FIXXREF_OPTIONS=--extra-dir=../gdk-pixbuf/html --extra-dir=../gdk/html +FIXXREF_OPTIONS = + +# Used for dependencies. The docs will be rebuilt if any of these change. +HFILE_GLOB = $(top_srcdir)/libcaja-extension/*.h +CFILE_GLOB = $(top_srcdir)/libcaja-extension/*.c + +# Header files to ignore when scanning. +IGNORE_HFILES = \ + config.h \ + caja-extension-i18n.h \ + $(NULL) + + +# Images to copy into HTML directory +HTML_IMAGES = +content_files = \ + version.xml \ + $(NULL) + + +# SGML files where gtk-doc abbrevations (#GtkWidget) are expanded +# These files must be listed here *and* in content_files +# e.g. expand_content_files=running.sgml +expand_content_files = \ + $(NULL) + + +# CFLAGS and LDFLAGS for compiling gtkdoc-scangobj with your library. +# Only needed if you are using gtkdoc-scangobj to dynamically query widget +# signals and properties. +# e.g. INCLUDES=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS) +# e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib) +GTKDOC_CFLAGS = \ + $(GTK_DEBUG_FLAGS) \ + -I$(srcdir) \ + -I$(top_srcdir) \ + -I$(top_srcdir)/libcaja-extension \ + -I$(top_builddir) \ + -I$(top_builddir)/libcaja-extension \ + $(LIBCAJA_EXTENSION_CFLAGS) \ + $(NULL) + +GTKDOC_LIBS = \ + $(top_builddir)/libcaja-extension/libcaja-extension.la \ + $(LIBCAJA_EXTENSION_LIBS) \ + $(NULL) + +@GTK_DOC_USE_LIBTOOL_FALSE@GTKDOC_CC = $(CC) $(INCLUDES) $(GTKDOC_DEPS_CFLAGS) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +@GTK_DOC_USE_LIBTOOL_TRUE@GTKDOC_CC = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(INCLUDES) $(GTKDOC_DEPS_CFLAGS) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +@GTK_DOC_USE_LIBTOOL_FALSE@GTKDOC_LD = $(CC) $(GTKDOC_DEPS_LIBS) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) +@GTK_DOC_USE_LIBTOOL_TRUE@GTKDOC_LD = $(LIBTOOL) --tag=CC --mode=link $(CC) $(GTKDOC_DEPS_LIBS) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) +@GTK_DOC_USE_LIBTOOL_FALSE@GTKDOC_RUN = +@GTK_DOC_USE_LIBTOOL_TRUE@GTKDOC_RUN = $(LIBTOOL) --mode=execute + +# We set GPATH here; this gives us semantics for GNU make +# which are more like other make's VPATH, when it comes to +# whether a source that is a target of one rule is then +# searched for in VPATH/GPATH. +# +GPATH = $(srcdir) +TARGET_DIR = $(HTML_DIR)/$(DOC_MODULE) +SETUP_FILES = \ + $(content_files) \ + $(DOC_MAIN_SGML_FILE) \ + $(DOC_MODULE)-sections.txt \ + $(DOC_MODULE)-overrides.txt + + +# This includes the standard gtk-doc make rules, copied by gtkdocize. + +# Other files to distribute +# e.g. EXTRA_DIST += version.xml.in +EXTRA_DIST = $(HTML_IMAGES) $(SETUP_FILES) version.xml.in +DOC_STAMPS = setup-build.stamp scan-build.stamp tmpl-build.stamp sgml-build.stamp \ + html-build.stamp pdf-build.stamp \ + tmpl.stamp sgml.stamp html.stamp pdf.stamp + +SCANOBJ_FILES = \ + $(DOC_MODULE).args \ + $(DOC_MODULE).hierarchy \ + $(DOC_MODULE).interfaces \ + $(DOC_MODULE).prerequisites \ + $(DOC_MODULE).signals + +REPORT_FILES = \ + $(DOC_MODULE)-undocumented.txt \ + $(DOC_MODULE)-undeclared.txt \ + $(DOC_MODULE)-unused.txt + +CLEANFILES = $(SCANOBJ_FILES) $(REPORT_FILES) $(DOC_STAMPS) +@ENABLE_GTK_DOC_TRUE@@GTK_DOC_BUILD_HTML_FALSE@HTML_BUILD_STAMP = +@ENABLE_GTK_DOC_TRUE@@GTK_DOC_BUILD_HTML_TRUE@HTML_BUILD_STAMP = html-build.stamp +@ENABLE_GTK_DOC_TRUE@@GTK_DOC_BUILD_PDF_FALSE@PDF_BUILD_STAMP = +@ENABLE_GTK_DOC_TRUE@@GTK_DOC_BUILD_PDF_TRUE@PDF_BUILD_STAMP = pdf-build.stamp +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/gtk-doc.make $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu docs/reference/libcaja-extension/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu docs/reference/libcaja-extension/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +version.xml: $(top_builddir)/config.status $(srcdir)/version.xml.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +tags: TAGS +TAGS: + +ctags: CTAGS +CTAGS: + + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$(top_distdir)" distdir="$(distdir)" \ + dist-hook +check-am: all-am +check: check-am +all-am: Makefile all-local +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-local mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-local + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-data-local + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic \ + maintainer-clean-local + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-local + +.MAKE: install-am install-strip + +.PHONY: all all-am all-local check check-am clean clean-generic \ + clean-libtool clean-local dist-hook distclean \ + distclean-generic distclean-libtool distclean-local distdir \ + dvi dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-data-local install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic \ + maintainer-clean-local mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am \ + uninstall-local + + +@ENABLE_GTK_DOC_TRUE@all-local: $(HTML_BUILD_STAMP) $(PDF_BUILD_STAMP) +@ENABLE_GTK_DOC_FALSE@all-local: + +docs: $(HTML_BUILD_STAMP) $(PDF_BUILD_STAMP) + +$(REPORT_FILES): sgml-build.stamp + +#### setup #### + +setup-build.stamp: + -@if test "$(abs_srcdir)" != "$(abs_builddir)" ; then \ + echo ' DOC Preparing build'; \ + files=`echo $(SETUP_FILES) $(expand_content_files) $(DOC_MODULE).types`; \ + if test "x$$files" != "x" ; then \ + for file in $$files ; do \ + test -f $(abs_srcdir)/$$file && \ + cp -pu $(abs_srcdir)/$$file $(abs_builddir)/ || true; \ + done; \ + fi; \ + test -d $(abs_srcdir)/tmpl && \ + { cp -rp $(abs_srcdir)/tmpl $(abs_builddir)/; \ + chmod -R u+w $(abs_builddir)/tmpl; } \ + fi + @touch setup-build.stamp + +#### scan #### + +scan-build.stamp: $(HFILE_GLOB) $(CFILE_GLOB) + @echo ' DOC Scanning header files' + @_source_dir='' ; \ + for i in $(DOC_SOURCE_DIR) ; do \ + _source_dir="$${_source_dir} --source-dir=$$i" ; \ + done ; \ + gtkdoc-scan --module=$(DOC_MODULE) --ignore-headers="$(IGNORE_HFILES)" $${_source_dir} $(SCAN_OPTIONS) $(EXTRA_HFILES) + @if grep -l '^..*$$' $(DOC_MODULE).types > /dev/null 2>&1 ; then \ + echo " DOC Introspecting gobjects"; \ + scanobj_options=""; \ + gtkdoc-scangobj 2>&1 --help | grep >/dev/null "\-\-verbose"; \ + if test "$(?)" = "0"; then \ + if test "x$(V)" = "x1"; then \ + scanobj_options="--verbose"; \ + fi; \ + fi; \ + CC="$(GTKDOC_CC)" LD="$(GTKDOC_LD)" RUN="$(GTKDOC_RUN)" CFLAGS="$(GTKDOC_CFLAGS) $(CFLAGS)" LDFLAGS="$(GTKDOC_LIBS) $(LDFLAGS)" \ + gtkdoc-scangobj $(SCANGOBJ_OPTIONS) $$scanobj_options --module=$(DOC_MODULE); \ + else \ + for i in $(SCANOBJ_FILES) ; do \ + test -f $$i || touch $$i ; \ + done \ + fi + @touch scan-build.stamp + +$(DOC_MODULE)-decl.txt $(SCANOBJ_FILES) $(DOC_MODULE)-sections.txt $(DOC_MODULE)-overrides.txt: scan-build.stamp + @true + +#### templates #### + +tmpl-build.stamp: setup-build.stamp $(DOC_MODULE)-decl.txt $(SCANOBJ_FILES) $(DOC_MODULE)-sections.txt $(DOC_MODULE)-overrides.txt + @echo ' DOC Rebuilding template files' + @gtkdoc-mktmpl --module=$(DOC_MODULE) $(MKTMPL_OPTIONS) + @if test "$(abs_srcdir)" != "$(abs_builddir)" ; then \ + if test -w $(abs_srcdir) ; then \ + cp -rp $(abs_builddir)/tmpl $(abs_srcdir)/; \ + fi \ + fi + @touch tmpl-build.stamp + +tmpl.stamp: tmpl-build.stamp + @true + +$(srcdir)/tmpl/*.sgml: + @true + +#### xml #### + +sgml-build.stamp: tmpl.stamp $(DOC_MODULE)-sections.txt $(srcdir)/tmpl/*.sgml $(expand_content_files) + @echo ' DOC Building XML' + @-chmod -R u+w $(srcdir) + @_source_dir='' ; \ + for i in $(DOC_SOURCE_DIR) ; do \ + _source_dir="$${_source_dir} --source-dir=$$i" ; \ + done ; \ + gtkdoc-mkdb --module=$(DOC_MODULE) --output-format=xml --expand-content-files="$(expand_content_files)" --main-sgml-file=$(DOC_MAIN_SGML_FILE) $${_source_dir} $(MKDB_OPTIONS) + @touch sgml-build.stamp + +sgml.stamp: sgml-build.stamp + @true + +#### html #### + +html-build.stamp: sgml.stamp $(DOC_MAIN_SGML_FILE) $(content_files) + @echo ' DOC Building HTML' + @rm -rf html + @mkdir html + @mkhtml_options=""; \ + gtkdoc-mkhtml 2>&1 --help | grep >/dev/null "\-\-verbose"; \ + if test "$(?)" = "0"; then \ + if test "x$(V)" = "x1"; then \ + mkhtml_options="$$mkhtml_options --verbose"; \ + fi; \ + fi; \ + gtkdoc-mkhtml 2>&1 --help | grep >/dev/null "\-\-path"; \ + if test "$(?)" = "0"; then \ + mkhtml_options="$$mkhtml_options --path=\"$(abs_srcdir)\""; \ + fi; \ + cd html && gtkdoc-mkhtml $$mkhtml_options $(MKHTML_OPTIONS) $(DOC_MODULE) ../$(DOC_MAIN_SGML_FILE) + -@test "x$(HTML_IMAGES)" = "x" || \ + for file in $(HTML_IMAGES) ; do \ + if test -f $(abs_srcdir)/$$file ; then \ + cp $(abs_srcdir)/$$file $(abs_builddir)/html; \ + fi; \ + if test -f $(abs_builddir)/$$file ; then \ + cp $(abs_builddir)/$$file $(abs_builddir)/html; \ + fi; \ + done; + @echo ' DOC Fixing cross-references' + @gtkdoc-fixxref --module=$(DOC_MODULE) --module-dir=html --html-dir=$(HTML_DIR) $(FIXXREF_OPTIONS) + @touch html-build.stamp + +#### pdf #### + +pdf-build.stamp: sgml.stamp $(DOC_MAIN_SGML_FILE) $(content_files) + @echo ' DOC Building PDF' + @rm -f $(DOC_MODULE).pdf + @mkpdf_options=""; \ + gtkdoc-mkpdf 2>&1 --help | grep >/dev/null "\-\-verbose"; \ + if test "$(?)" = "0"; then \ + if test "x$(V)" = "x1"; then \ + mkpdf_options="$$mkpdf_options --verbose"; \ + fi; \ + fi; \ + if test "x$(HTML_IMAGES)" != "x"; then \ + for img in $(HTML_IMAGES); do \ + part=`dirname $$img`; \ + echo $$mkpdf_options | grep >/dev/null "\-\-imgdir=$$part "; \ + if test $$? != 0; then \ + mkpdf_options="$$mkpdf_options --imgdir=$$part"; \ + fi; \ + done; \ + fi; \ + gtkdoc-mkpdf --path="$(abs_srcdir)" $$mkpdf_options $(DOC_MODULE) $(DOC_MAIN_SGML_FILE) $(MKPDF_OPTIONS) + @touch pdf-build.stamp + +############## + +clean-local: + @rm -f *~ *.bak + @rm -rf .libs + +distclean-local: + @rm -rf xml html $(REPORT_FILES) $(DOC_MODULE).pdf \ + $(DOC_MODULE)-decl-list.txt $(DOC_MODULE)-decl.txt + @if test "$(abs_srcdir)" != "$(abs_builddir)" ; then \ + rm -f $(SETUP_FILES) $(expand_content_files) $(DOC_MODULE).types; \ + rm -rf tmpl; \ + fi + +maintainer-clean-local: clean + @rm -rf xml html + +install-data-local: + @installfiles=`echo $(builddir)/html/*`; \ + if test "$$installfiles" = '$(builddir)/html/*'; \ + then echo 1>&2 'Nothing to install' ; \ + else \ + if test -n "$(DOC_MODULE_VERSION)"; then \ + installdir="$(DESTDIR)$(TARGET_DIR)-$(DOC_MODULE_VERSION)"; \ + else \ + installdir="$(DESTDIR)$(TARGET_DIR)"; \ + fi; \ + $(mkinstalldirs) $${installdir} ; \ + for i in $$installfiles; do \ + echo ' $(INSTALL_DATA) '$$i ; \ + $(INSTALL_DATA) $$i $${installdir}; \ + done; \ + if test -n "$(DOC_MODULE_VERSION)"; then \ + mv -f $${installdir}/$(DOC_MODULE).devhelp2 \ + $${installdir}/$(DOC_MODULE)-$(DOC_MODULE_VERSION).devhelp2; \ + fi; \ + $(GTKDOC_REBASE) --relative --dest-dir=$(DESTDIR) --html-dir=$${installdir}; \ + fi + +uninstall-local: + @if test -n "$(DOC_MODULE_VERSION)"; then \ + installdir="$(DESTDIR)$(TARGET_DIR)-$(DOC_MODULE_VERSION)"; \ + else \ + installdir="$(DESTDIR)$(TARGET_DIR)"; \ + fi; \ + rm -rf $${installdir} + +# +# Require gtk-doc when making dist +# +@ENABLE_GTK_DOC_TRUE@dist-check-gtkdoc: +@ENABLE_GTK_DOC_FALSE@dist-check-gtkdoc: +@ENABLE_GTK_DOC_FALSE@ @echo "*** gtk-doc must be installed and enabled in order to make dist" +@ENABLE_GTK_DOC_FALSE@ @false + +dist-hook: dist-check-gtkdoc dist-hook-local + @mkdir $(distdir)/tmpl + @mkdir $(distdir)/html + @-cp ./tmpl/*.sgml $(distdir)/tmpl + @cp ./html/* $(distdir)/html + @-cp ./$(DOC_MODULE).pdf $(distdir)/ + @-cp ./$(DOC_MODULE).types $(distdir)/ + @-cp ./$(DOC_MODULE)-sections.txt $(distdir)/ + @cd $(distdir) && rm -f $(DISTCLEANFILES) + @$(GTKDOC_REBASE) --online --relative --html-dir=$(distdir)/html + +.PHONY : dist-hook-local docs + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/docs/reference/libcaja-extension/html/ch01.html b/docs/reference/libcaja-extension/html/ch01.html new file mode 100644 index 00000000..8e90e1fd --- /dev/null +++ b/docs/reference/libcaja-extension/html/ch01.html @@ -0,0 +1,63 @@ + + + + +Extension Interfaces + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/reference/libcaja-extension/html/home.png b/docs/reference/libcaja-extension/html/home.png new file mode 100644 index 00000000..17003611 Binary files /dev/null and b/docs/reference/libcaja-extension/html/home.png differ diff --git a/docs/reference/libcaja-extension/html/index.html b/docs/reference/libcaja-extension/html/index.html new file mode 100644 index 00000000..6d4ef0bf --- /dev/null +++ b/docs/reference/libcaja-extension/html/index.html @@ -0,0 +1,66 @@ + + + + +Caja Extension Reference Manual + + + + + + + +
+
+
+
+

For Caja-Extension 3:0:2 +

+
+
+
+ +
+ + + \ No newline at end of file diff --git a/docs/reference/libcaja-extension/html/index.sgml b/docs/reference/libcaja-extension/html/index.sgml new file mode 100644 index 00000000..aa9b75e4 --- /dev/null +++ b/docs/reference/libcaja-extension/html/index.sgml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/reference/libcaja-extension/html/ix01.html b/docs/reference/libcaja-extension/html/ix01.html new file mode 100644 index 00000000..289c1018 --- /dev/null +++ b/docs/reference/libcaja-extension/html/ix01.html @@ -0,0 +1,224 @@ + + + + +Index + + + + + + + + + + + + + + + +
+

+Index

+
+

N

+
+
CajaColumn, CajaColumn +
+
CajaColumn:attribute, The "attribute" property +
+
CajaColumn:attribute-q, The "attribute-q" property +
+
CajaColumn:description, The "description" property +
+
CajaColumn:label, The "label" property +
+
CajaColumn:name, The "name" property +
+
CajaColumn:xalign, The "xalign" property +
+
CajaColumnDetails, CajaColumnDetails +
+
CajaColumnProvider, CajaColumnProvider +
+
CajaColumnProviderIface, CajaColumnProviderIface +
+
CajaFile, CajaFile +
+
CajaFileInfo, caja-file-info +
+
CajaFileInfoIface, CajaFileInfoIface +
+
CajaInfoProvider, CajaInfoProvider +
+
CajaInfoProviderIface, CajaInfoProviderIface +
+
CajaInfoProviderUpdateComplete, CajaInfoProviderUpdateComplete () +
+
CajaLocationWidgetProvider, CajaLocationWidgetProvider +
+
CajaLocationWidgetProviderIface, CajaLocationWidgetProviderIface +
+
CajaMenu, CajaMenu +
+
CajaMenuItem, CajaMenuItem +
+
CajaMenuItem::activate, The "activate" signal +
+
CajaMenuItem:icon, The "icon" property +
+
CajaMenuItem:label, The "label" property +
+
CajaMenuItem:menu, The "menu" property +
+
CajaMenuItem:name, The "name" property +
+
CajaMenuItem:priority, The "priority" property +
+
CajaMenuItem:sensitive, The "sensitive" property +
+
CajaMenuItem:tip, The "tip" property +
+
CajaMenuItemDetails, CajaMenuItemDetails +
+
CajaMenuPrivate, CajaMenuPrivate +
+
CajaMenuProvider, CajaMenuProvider +
+
CajaMenuProvider::items-updated, The "items-updated" signal +
+
CajaMenuProviderIface, CajaMenuProviderIface +
+
CajaOperationHandle, CajaOperationHandle +
+
CajaOperationResult, enum CajaOperationResult +
+
CajaPropertyPage, CajaPropertyPage +
+
CajaPropertyPage:label, The "label" property +
+
CajaPropertyPage:name, The "name" property +
+
CajaPropertyPage:page, The "page" property +
+
CajaPropertyPageDetails, CajaPropertyPageDetails +
+
CajaPropertyPageProvider, CajaPropertyPageProvider +
+
CajaPropertyPageProviderIface, CajaPropertyPageProviderIface +
+
caja_column_new, caja_column_new () +
+
caja_column_provider_get_columns, caja_column_provider_get_columns () +
+
CAJA_FILE_DEFINED, CAJA_FILE_DEFINED +
+
caja_file_info_add_emblem, caja_file_info_add_emblem () +
+
caja_file_info_add_string_attribute, caja_file_info_add_string_attribute () +
+
caja_file_info_can_write, caja_file_info_can_write () +
+
caja_file_info_get_activation_uri, caja_file_info_get_activation_uri () +
+
caja_file_info_get_file_type, caja_file_info_get_file_type () +
+
caja_file_info_get_location, caja_file_info_get_location () +
+
caja_file_info_get_mime_type, caja_file_info_get_mime_type () +
+
caja_file_info_get_mount, caja_file_info_get_mount () +
+
caja_file_info_get_name, caja_file_info_get_name () +
+
caja_file_info_get_parent_info, caja_file_info_get_parent_info () +
+
caja_file_info_get_parent_location, caja_file_info_get_parent_location () +
+
caja_file_info_get_parent_uri, caja_file_info_get_parent_uri () +
+
caja_file_info_get_string_attribute, caja_file_info_get_string_attribute () +
+
caja_file_info_get_uri, caja_file_info_get_uri () +
+
caja_file_info_get_uri_scheme, caja_file_info_get_uri_scheme () +
+
caja_file_info_invalidate_extension_info, caja_file_info_invalidate_extension_info () +
+
caja_file_info_is_directory, caja_file_info_is_directory () +
+
caja_file_info_is_gone, caja_file_info_is_gone () +
+
caja_file_info_is_mime_type, caja_file_info_is_mime_type () +
+
caja_file_info_list_copy, caja_file_info_list_copy () +
+
caja_file_info_list_free, caja_file_info_list_free () +
+
caja_info_provider_cancel_update, caja_info_provider_cancel_update () +
+
caja_info_provider_update_complete_invoke, caja_info_provider_update_complete_invoke () +
+
caja_info_provider_update_file_info, caja_info_provider_update_file_info () +
+
caja_location_widget_provider_get_widget, caja_location_widget_provider_get_widget () +
+
caja_menu_append_item, caja_menu_append_item () +
+
caja_menu_get_items, caja_menu_get_items () +
+
CAJA_MENU_IS_ITEM, CAJA_MENU_IS_ITEM() +
+
CAJA_MENU_IS_ITEM_CLASS, CAJA_MENU_IS_ITEM_CLASS() +
+
CAJA_MENU_ITEM, CAJA_MENU_ITEM() +
+
caja_menu_item_activate, caja_menu_item_activate () +
+
CAJA_MENU_ITEM_CLASS, CAJA_MENU_ITEM_CLASS() +
+
CAJA_MENU_ITEM_GET_CLASS, CAJA_MENU_ITEM_GET_CLASS() +
+
caja_menu_item_get_type, caja_menu_item_get_type () +
+
caja_menu_item_list_free, caja_menu_item_list_free () +
+
caja_menu_item_new, caja_menu_item_new () +
+
caja_menu_item_set_submenu, caja_menu_item_set_submenu () +
+
caja_menu_new, caja_menu_new () +
+
caja_menu_provider_emit_items_updated_signal, caja_menu_provider_emit_items_updated_signal () +
+
caja_menu_provider_get_background_items, caja_menu_provider_get_background_items () +
+
caja_menu_provider_get_file_items, caja_menu_provider_get_file_items () +
+
caja_menu_provider_get_toolbar_items, caja_menu_provider_get_toolbar_items () +
+
caja_module_initialize, caja_module_initialize () +
+
caja_module_list_types, caja_module_list_types () +
+
caja_module_shutdown, caja_module_shutdown () +
+
caja_operation_result_get_type, caja_operation_result_get_type () +
+
caja_property_page_new, caja_property_page_new () +
+
caja_property_page_provider_get_pages, caja_property_page_provider_get_pages () +
+
CAJA_TYPE_MENU_ITEM, CAJA_TYPE_MENU_ITEM +
+
CAJA_TYPE_OPERATION_RESULT, CAJA_TYPE_OPERATION_RESULT +
+
+
+
+ + + \ No newline at end of file diff --git a/docs/reference/libcaja-extension/html/left.png b/docs/reference/libcaja-extension/html/left.png new file mode 100644 index 00000000..2d05b3d5 Binary files /dev/null and b/docs/reference/libcaja-extension/html/left.png differ diff --git a/docs/reference/libcaja-extension/html/libcaja-extension-caja-column-provider.html b/docs/reference/libcaja-extension/html/libcaja-extension-caja-column-provider.html new file mode 100644 index 00000000..d09fd267 --- /dev/null +++ b/docs/reference/libcaja-extension/html/libcaja-extension-caja-column-provider.html @@ -0,0 +1,117 @@ + + + + +caja-column-provider + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+

caja-column-provider

+

caja-column-provider

+
+ +
+

Object Hierarchy

+
+  GInterface
+   +----CajaColumnProvider
+
+
+
+

Prerequisites

+

+CajaColumnProvider requires + GObject.

+
+
+

Description

+

+

+
+
+

Details

+
+

CajaColumnProvider

+
typedef struct _CajaColumnProvider CajaColumnProvider;
+

+

+
+
+
+

CajaColumnProviderIface

+
typedef struct {
+	GTypeInterface g_iface;
+
+	GList *(*get_columns) (CajaColumnProvider *provider);
+} CajaColumnProviderIface;
+
+

+

+
+
+
+

caja_column_provider_get_columns ()

+
GList *             caja_column_provider_get_columns
+                                                        (CajaColumnProvider *provider);
+

+

+
++ + + + + + + + + + +

provider :

+

Returns :

+
+
+
+
+ + + diff --git a/docs/reference/libcaja-extension/html/libcaja-extension-caja-column.html b/docs/reference/libcaja-extension/html/libcaja-extension-caja-column.html new file mode 100644 index 00000000..53e19a1f --- /dev/null +++ b/docs/reference/libcaja-extension/html/libcaja-extension-caja-column.html @@ -0,0 +1,182 @@ + + + + +CajaColumn + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+

CajaColumn

+

CajaColumn

+
+
+

Synopsis

+
                    CajaColumnDetails;
+                    CajaColumn;
+CajaColumn *    caja_column_new                 (const char *name,
+                                                         const char *attribute,
+                                                         const char *label,
+                                                         const char *description);
+
+
+
+

Object Hierarchy

+
+  GObject
+   +----CajaColumn
+
+
+
+

Properties

+
+  "attribute"                gchar*                : Read / Write
+  "attribute-q"              guint                 : Read
+  "description"              gchar*                : Read / Write
+  "label"                    gchar*                : Read / Write
+  "name"                     gchar*                : Read / Write / Construct Only
+  "xalign"                   gfloat                : Read / Write
+
+
+
+

Description

+

+

+
+
+

Details

+
+

CajaColumnDetails

+
typedef struct _CajaColumnDetails CajaColumnDetails;
+

+

+
+
+
+

CajaColumn

+
typedef struct _CajaColumn CajaColumn;
+

+

+
+
+
+

caja_column_new ()

+
CajaColumn *    caja_column_new                 (const char *name,
+                                                         const char *attribute,
+                                                         const char *label,
+                                                         const char *description);
+

+Creates a new column +

+
++ + + + + + + + + + + + + + + + + + + + + + +

name :

identifier of the column +

attribute :

the file attribute to be displayed in the column +

label :

the user-visible label for the column +

description :

a user-visible description of the column +

Returns :

a newly created CajaColumn +
+
+
+
+

Property Details

+
+

The "attribute" property

+
  "attribute"                gchar*                : Read / Write
+

The attribute name to display.

+

Default value: NULL

+
+
+
+

The "attribute-q" property

+
  "attribute-q"              guint                 : Read
+

The attribute name to display, in quark form.

+

Default value: 0

+
+
+
+

The "description" property

+
  "description"              gchar*                : Read / Write
+

A user-visible description of the column.

+

Default value: NULL

+
+
+
+

The "label" property

+
  "label"                    gchar*                : Read / Write
+

Label to display in the column.

+

Default value: NULL

+
+
+
+

The "name" property

+
  "name"                     gchar*                : Read / Write / Construct Only
+

Name of the column.

+

Default value: NULL

+
+
+
+

The "xalign" property

+
  "xalign"                   gfloat                : Read / Write
+

The x-alignment of the column.

+

Allowed values: [0,1]

+

Default value: 0

+
+
+
+ + + diff --git a/docs/reference/libcaja-extension/html/libcaja-extension-caja-extension-types.html b/docs/reference/libcaja-extension/html/libcaja-extension-caja-extension-types.html new file mode 100644 index 00000000..c01df269 --- /dev/null +++ b/docs/reference/libcaja-extension/html/libcaja-extension-caja-extension-types.html @@ -0,0 +1,158 @@ + + + + +caja-extension-types + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+

caja-extension-types

+

caja-extension-types

+
+ +
+

Description

+

+

+
+
+

Details

+
+

CAJA_TYPE_OPERATION_RESULT

+
#define CAJA_TYPE_OPERATION_RESULT (caja_operation_result_get_type ())
+
+

+

+
+
+
+

CajaOperationHandle

+
typedef struct _CajaOperationHandle CajaOperationHandle;
+

+

+
+
+
+

enum CajaOperationResult

+
typedef enum {
+	/* Returned if the call succeeded, and the extension is done
+	 * with the request */
+	CAJA_OPERATION_COMPLETE,
+
+	/* Returned if the call failed */
+	CAJA_OPERATION_FAILED,
+
+	/* Returned if the extension has begun an async operation.
+	 * If this is returned, the extension must set the handle
+	 * parameter and call the callback closure when the
+	 * operation is complete. */
+	CAJA_OPERATION_IN_PROGRESS
+} CajaOperationResult;
+
+

+

+
+
+
+

caja_operation_result_get_type ()

+
GType               caja_operation_result_get_type  (void);
+

+

+
++ + + + +

Returns :

+
+
+
+
+

caja_module_initialize ()

+
void                caja_module_initialize          (GTypeModule *module);
+

+

+
++ + + + +

module :

+
+
+
+
+

caja_module_shutdown ()

+
void                caja_module_shutdown            (void);
+

+

+
+
+
+

caja_module_list_types ()

+
void                caja_module_list_types          (const GType **types,
+                                                         int *num_types);
+

+

+
++ + + + + + + + + + +

types :

+

num_types :

+
+
+
+
+ + + diff --git a/docs/reference/libcaja-extension/html/libcaja-extension-caja-file-info.html b/docs/reference/libcaja-extension/html/libcaja-extension-caja-file-info.html new file mode 100644 index 00000000..38398bab --- /dev/null +++ b/docs/reference/libcaja-extension/html/libcaja-extension-caja-file-info.html @@ -0,0 +1,643 @@ + + + + +caja-file-info + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+

caja-file-info

+

caja-file-info

+
+ +
+

Object Hierarchy

+
+  GInterface
+   +----CajaFileInfo
+
+
+
+

Prerequisites

+

+CajaFileInfo requires + GObject.

+
+
+

Description

+

+

+
+
+

Details

+
+

CAJA_FILE_DEFINED

+
#define CAJA_FILE_DEFINED
+
+

+

+
+
+
+

CajaFile

+
typedef struct CajaFile          CajaFile;
+
+

+

+
+
+
+

CajaFileInfo

+
typedef CajaFile                  CajaFileInfo;
+
+

+

+
+
+
+

CajaFileInfoIface

+
typedef struct {
+	GTypeInterface g_iface;
+
+	gboolean          (*is_gone)              (CajaFileInfo *file);
+
+	char *            (*get_name)             (CajaFileInfo *file);
+	char *            (*get_uri)              (CajaFileInfo *file);
+	char *            (*get_parent_uri)       (CajaFileInfo *file);
+	char *            (*get_uri_scheme)       (CajaFileInfo *file);
+
+	char *            (*get_mime_type)        (CajaFileInfo *file);
+	gboolean          (*is_mime_type)         (CajaFileInfo *file,
+						   const char       *mime_Type);
+	gboolean          (*is_directory)         (CajaFileInfo *file);
+
+	void              (*add_emblem)           (CajaFileInfo *file,
+						   const char       *emblem_name);
+	char *            (*get_string_attribute) (CajaFileInfo *file,
+						   const char       *attribute_name);
+	void              (*add_string_attribute) (CajaFileInfo *file,
+						   const char       *attribute_name,
+						   const char       *value);
+	void              (*invalidate_extension_info) (CajaFileInfo *file);
+
+	char *            (*get_activation_uri)   (CajaFileInfo *file);
+
+	GFileType         (*get_file_type)        (CajaFileInfo *file);
+	GFile *           (*get_location)         (CajaFileInfo *file);
+	GFile *           (*get_parent_location)  (CajaFileInfo *file);
+	CajaFileInfo* (*get_parent_info)      (CajaFileInfo *file);
+	GMount *          (*get_mount)            (CajaFileInfo *file);
+	gboolean          (*can_write)            (CajaFileInfo *file);
+} CajaFileInfoIface;
+
+

+

+
+
+
+

caja_file_info_list_copy ()

+
GList *             caja_file_info_list_copy        (GList *files);
+

+

+
++ + + + + + + + + + +

files :

+

Returns :

+
+
+
+
+

caja_file_info_list_free ()

+
void                caja_file_info_list_free        (GList *files);
+

+

+
++ + + + +

files :

+
+
+
+
+

caja_file_info_is_gone ()

+
gboolean            caja_file_info_is_gone          (CajaFileInfo *file);
+

+

+
++ + + + + + + + + + +

file :

+

Returns :

+
+
+
+
+

caja_file_info_get_file_type ()

+
GFileType           caja_file_info_get_file_type    (CajaFileInfo *file);
+

+

+
++ + + + + + + + + + +

file :

+

Returns :

+
+
+
+
+

caja_file_info_get_location ()

+
GFile *             caja_file_info_get_location     (CajaFileInfo *file);
+

+

+
++ + + + + + + + + + +

file :

+

Returns :

+
+
+
+
+

caja_file_info_get_name ()

+
char *              caja_file_info_get_name         (CajaFileInfo *file);
+

+

+
++ + + + + + + + + + +

file :

+

Returns :

+
+
+
+
+

caja_file_info_get_uri ()

+
char *              caja_file_info_get_uri          (CajaFileInfo *file);
+

+

+
++ + + + + + + + + + +

file :

+

Returns :

+
+
+
+
+

caja_file_info_get_activation_uri ()

+
char *              caja_file_info_get_activation_uri
+                                                        (CajaFileInfo *file);
+

+

+
++ + + + + + + + + + +

file :

+

Returns :

+
+
+
+
+

caja_file_info_get_parent_location ()

+
GFile *             caja_file_info_get_parent_location
+                                                        (CajaFileInfo *file);
+

+

+
++ + + + + + + + + + +

file :

+

Returns :

+
+
+
+
+

caja_file_info_get_parent_uri ()

+
char *              caja_file_info_get_parent_uri   (CajaFileInfo *file);
+

+

+
++ + + + + + + + + + +

file :

+

Returns :

+
+
+
+
+

caja_file_info_get_mount ()

+
GMount *            caja_file_info_get_mount        (CajaFileInfo *file);
+

+

+
++ + + + + + + + + + +

file :

+

Returns :

+
+
+
+
+

caja_file_info_get_uri_scheme ()

+
char *              caja_file_info_get_uri_scheme   (CajaFileInfo *file);
+

+

+
++ + + + + + + + + + +

file :

+

Returns :

+
+
+
+
+

caja_file_info_get_parent_info ()

+
CajaFileInfo*   caja_file_info_get_parent_info  (CajaFileInfo *file);
+

+

+
++ + + + + + + + + + +

file :

+

Returns :

+
+
+
+
+

caja_file_info_get_mime_type ()

+
char *              caja_file_info_get_mime_type    (CajaFileInfo *file);
+

+

+
++ + + + + + + + + + +

file :

+

Returns :

+
+
+
+
+

caja_file_info_is_mime_type ()

+
gboolean            caja_file_info_is_mime_type     (CajaFileInfo *file,
+                                                         const char *mime_type);
+

+

+
++ + + + + + + + + + + + + + +

file :

+

mime_type :

+

Returns :

+
+
+
+
+

caja_file_info_is_directory ()

+
gboolean            caja_file_info_is_directory     (CajaFileInfo *file);
+

+

+
++ + + + + + + + + + +

file :

+

Returns :

+
+
+
+
+

caja_file_info_can_write ()

+
gboolean            caja_file_info_can_write        (CajaFileInfo *file);
+

+

+
++ + + + + + + + + + +

file :

+

Returns :

+
+
+
+
+

caja_file_info_add_emblem ()

+
void                caja_file_info_add_emblem       (CajaFileInfo *file,
+                                                         const char *emblem_name);
+

+

+
++ + + + + + + + + + +

file :

+

emblem_name :

+
+
+
+
+

caja_file_info_get_string_attribute ()

+
char *              caja_file_info_get_string_attribute
+                                                        (CajaFileInfo *file,
+                                                         const char *attribute_name);
+

+

+
++ + + + + + + + + + + + + + +

file :

+

attribute_name :

+

Returns :

+
+
+
+
+

caja_file_info_add_string_attribute ()

+
void                caja_file_info_add_string_attribute
+                                                        (CajaFileInfo *file,
+                                                         const char *attribute_name,
+                                                         const char *value);
+

+

+
++ + + + + + + + + + + + + + +

file :

+

attribute_name :

+

value :

+
+
+
+
+

caja_file_info_invalidate_extension_info ()

+
void                caja_file_info_invalidate_extension_info
+                                                        (CajaFileInfo *file);
+

+

+
++ + + + +

file :

+
+
+
+
+ + + diff --git a/docs/reference/libcaja-extension/html/libcaja-extension-caja-info-provider.html b/docs/reference/libcaja-extension/html/libcaja-extension-caja-info-provider.html new file mode 100644 index 00000000..08fd10e2 --- /dev/null +++ b/docs/reference/libcaja-extension/html/libcaja-extension-caja-info-provider.html @@ -0,0 +1,252 @@ + + + + +caja-info-provider + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+

caja-info-provider

+

caja-info-provider

+
+ +
+

Object Hierarchy

+
+  GInterface
+   +----CajaInfoProvider
+
+
+
+

Prerequisites

+

+CajaInfoProvider requires + GObject.

+
+
+

Description

+

+

+
+
+

Details

+
+

CajaInfoProvider

+
typedef struct _CajaInfoProvider CajaInfoProvider;
+

+

+
+
+
+

CajaInfoProviderIface

+
typedef struct {
+	GTypeInterface g_iface;
+
+	CajaOperationResult (*update_file_info) (CajaInfoProvider     *provider,
+						     CajaFileInfo         *file,
+						     GClosure                 *update_complete,
+						     CajaOperationHandle **handle);
+	void                    (*cancel_update)    (CajaInfoProvider     *provider,
+						     CajaOperationHandle  *handle);
+} CajaInfoProviderIface;
+
+

+

+
+
+
+

CajaInfoProviderUpdateComplete ()

+
void                (*CajaInfoProviderUpdateComplete)
+                                                        (CajaInfoProvider *provider,
+                                                         CajaOperationHandle *handle,
+                                                         CajaOperationResult result,
+                                                         gpointer user_data);
+

+

+
++ + + + + + + + + + + + + + + + + + +

provider :

+

handle :

+

result :

+

user_data :

+
+
+
+
+

caja_info_provider_update_file_info ()

+
CajaOperationResult  caja_info_provider_update_file_info
+                                                        (CajaInfoProvider *provider,
+                                                         CajaFileInfo *file,
+                                                         GClosure *update_complete,
+                                                         CajaOperationHandle **handle);
+

+

+
++ + + + + + + + + + + + + + + + + + + + + + +

provider :

+

file :

+

update_complete :

+

handle :

+

Returns :

+
+
+
+
+

caja_info_provider_cancel_update ()

+
void                caja_info_provider_cancel_update
+                                                        (CajaInfoProvider *provider,
+                                                         CajaOperationHandle *handle);
+

+

+
++ + + + + + + + + + +

provider :

+

handle :

+
+
+
+
+

caja_info_provider_update_complete_invoke ()

+
void                caja_info_provider_update_complete_invoke
+                                                        (GClosure *update_complete,
+                                                         CajaInfoProvider *provider,
+                                                         CajaOperationHandle *handle,
+                                                         CajaOperationResult result);
+

+

+
++ + + + + + + + + + + + + + + + + + +

update_complete :

+

provider :

+

handle :

+

result :

+
+
+
+
+ + + diff --git a/docs/reference/libcaja-extension/html/libcaja-extension-caja-location-widget-provider.html b/docs/reference/libcaja-extension/html/libcaja-extension-caja-location-widget-provider.html new file mode 100644 index 00000000..975bd3a5 --- /dev/null +++ b/docs/reference/libcaja-extension/html/libcaja-extension-caja-location-widget-provider.html @@ -0,0 +1,133 @@ + + + + +caja-location-widget-provider + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+

caja-location-widget-provider

+

caja-location-widget-provider

+
+ +
+

Object Hierarchy

+
+  GInterface
+   +----CajaLocationWidgetProvider
+
+
+
+

Prerequisites

+

+CajaLocationWidgetProvider requires + GObject.

+
+
+

Description

+

+

+
+
+

Details

+
+

CajaLocationWidgetProvider

+
typedef struct _CajaLocationWidgetProvider CajaLocationWidgetProvider;
+

+

+
+
+
+

CajaLocationWidgetProviderIface

+
typedef struct {
+	GTypeInterface g_iface;
+
+	GtkWidget * (*get_widget) (CajaLocationWidgetProvider *provider,
+				   const char                     *uri,
+				   GtkWidget                      *window);
+} CajaLocationWidgetProviderIface;
+
+

+

+
+
+
+

caja_location_widget_provider_get_widget ()

+
GtkWidget *         caja_location_widget_provider_get_widget
+                                                        (CajaLocationWidgetProvider *provider,
+                                                         const char *uri,
+                                                         GtkWidget *window);
+

+

+
++ + + + + + + + + + + + + + + + + + +

provider :

+

uri :

+

window :

+

Returns :

+
+
+
+
+ + + diff --git a/docs/reference/libcaja-extension/html/libcaja-extension-caja-menu-provider.html b/docs/reference/libcaja-extension/html/libcaja-extension-caja-menu-provider.html new file mode 100644 index 00000000..bb151c71 --- /dev/null +++ b/docs/reference/libcaja-extension/html/libcaja-extension-caja-menu-provider.html @@ -0,0 +1,267 @@ + + + + +caja-menu-provider + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+

caja-menu-provider

+

caja-menu-provider

+
+ +
+

Object Hierarchy

+
+  GInterface
+   +----CajaMenuProvider
+
+
+
+

Prerequisites

+

+CajaMenuProvider requires + GObject.

+
+
+

Signals

+
+  "items-updated"                                  : Run Last
+
+
+
+

Description

+

+

+
+
+

Details

+
+

CajaMenuProvider

+
typedef struct _CajaMenuProvider CajaMenuProvider;
+

+

+
+
+
+

CajaMenuProviderIface

+
typedef struct {
+	GTypeInterface g_iface;
+
+	GList *(*get_file_items)       (CajaMenuProvider *provider,
+					GtkWidget            *window,
+					GList                *files);
+	GList *(*get_background_items) (CajaMenuProvider *provider,
+					GtkWidget            *window,
+					CajaFileInfo     *current_folder);
+	GList *(*get_toolbar_items)    (CajaMenuProvider *provider,
+					GtkWidget            *window,
+				        CajaFileInfo     *current_folder);
+} CajaMenuProviderIface;
+
+

+

+
+
+
+

caja_menu_provider_get_file_items ()

+
GList *             caja_menu_provider_get_file_items
+                                                        (CajaMenuProvider *provider,
+                                                         GtkWidget *window,
+                                                         GList *files);
+

+

+
++ + + + + + + + + + + + + + + + + + +

provider :

+

window :

+

files :

+

Returns :

+
+
+
+
+

caja_menu_provider_get_background_items ()

+
GList *             caja_menu_provider_get_background_items
+                                                        (CajaMenuProvider *provider,
+                                                         GtkWidget *window,
+                                                         CajaFileInfo *current_folder);
+

+

+
++ + + + + + + + + + + + + + + + + + +

provider :

+

window :

+

current_folder :

+

Returns :

+
+
+
+
+

caja_menu_provider_get_toolbar_items ()

+
GList *             caja_menu_provider_get_toolbar_items
+                                                        (CajaMenuProvider *provider,
+                                                         GtkWidget *window,
+                                                         CajaFileInfo *current_folder);
+

+

+
++ + + + + + + + + + + + + + + + + + +

provider :

+

window :

+

current_folder :

+

Returns :

+
+
+
+
+

caja_menu_provider_emit_items_updated_signal ()

+
void                caja_menu_provider_emit_items_updated_signal
+                                                        (CajaMenuProvider *provider);
+

+

+
++ + + + +

provider :

+
+
+
+
+

Signal Details

+
+

The "items-updated" signal

+
void                user_function                      (CajaMenuProvider *cajamenuprovider,
+                                                        gpointer              user_data)                 : Run Last
+

+

+
++ + + + + + + + + + +

cajamenuprovider :

the object which received the signal. +

user_data :

user data set when the signal handler was connected.
+
+
+
+ + + diff --git a/docs/reference/libcaja-extension/html/libcaja-extension-caja-menu.html b/docs/reference/libcaja-extension/html/libcaja-extension-caja-menu.html new file mode 100644 index 00000000..d4cc454f --- /dev/null +++ b/docs/reference/libcaja-extension/html/libcaja-extension-caja-menu.html @@ -0,0 +1,473 @@ + + + + +CajaMenuItem + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+

CajaMenuItem

+

CajaMenuItem

+
+
+

Synopsis

+
#define             CAJA_TYPE_MENU_ITEM
+#define             CAJA_MENU_ITEM                  (obj)
+#define             CAJA_MENU_ITEM_CLASS            (klass)
+#define             CAJA_MENU_IS_ITEM               (obj)
+#define             CAJA_MENU_IS_ITEM_CLASS         (klass)
+#define             CAJA_MENU_ITEM_GET_CLASS        (obj)
+                    CajaMenuPrivate;
+                    CajaMenuItemDetails;
+                    CajaMenu;
+                    CajaMenuItem;
+CajaMenu *      caja_menu_new                   (void);
+void                caja_menu_append_item           (CajaMenu *menu,
+                                                         CajaMenuItem *item);
+GList*              caja_menu_get_items             (CajaMenu *menu);
+void                caja_menu_item_list_free        (GList *item_list);
+GType               caja_menu_item_get_type         (void);
+CajaMenuItem *  caja_menu_item_new              (const char *name,
+                                                         const char *label,
+                                                         const char *tip,
+                                                         const char *icon);
+void                caja_menu_item_activate         (CajaMenuItem *item);
+void                caja_menu_item_set_submenu      (CajaMenuItem *item,
+                                                         CajaMenu *menu);
+
+
+
+

Object Hierarchy

+
+  GObject
+   +----CajaMenu
+
+
+  GObject
+   +----CajaMenuItem
+
+
+
+

Properties

+
+  "icon"                     gchar*                : Read / Write
+  "label"                    gchar*                : Read / Write
+  "menu"                     CajaMenu*         : Read / Write
+  "name"                     gchar*                : Read / Write / Construct Only
+  "priority"                 gboolean              : Read / Write
+  "sensitive"                gboolean              : Read / Write
+  "tip"                      gchar*                : Read / Write
+
+
+
+

Signals

+
+  "activate"                                       : Run Last
+
+
+
+

Description

+

+

+
+
+

Details

+
+

CAJA_TYPE_MENU_ITEM

+
#define CAJA_TYPE_MENU_ITEM            (caja_menu_item_get_type())
+
+

+

+
+
+
+

CAJA_MENU_ITEM()

+
#define CAJA_MENU_ITEM(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), CAJA_TYPE_MENU_ITEM, CajaMenuItem))
+
+

+

+
++ + + + +

obj :

+
+
+
+
+

CAJA_MENU_ITEM_CLASS()

+
#define CAJA_MENU_ITEM_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), CAJA_TYPE_MENU_ITEM, CajaMenuItemClass))
+
+

+

+
++ + + + +

klass :

+
+
+
+
+

CAJA_MENU_IS_ITEM()

+
#define CAJA_MENU_IS_ITEM(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CAJA_TYPE_MENU_ITEM))
+
+

+

+
++ + + + +

obj :

+
+
+
+
+

CAJA_MENU_IS_ITEM_CLASS()

+
#define CAJA_MENU_IS_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), CAJA_TYPE_MENU_ITEM))
+
+

+

+
++ + + + +

klass :

+
+
+
+
+

CAJA_MENU_ITEM_GET_CLASS()

+
#define CAJA_MENU_ITEM_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), CAJA_TYPE_MENU_ITEM, CajaMenuItemClass))
+
+

+

+
++ + + + +

obj :

+
+
+
+
+

CajaMenuPrivate

+
typedef struct _CajaMenuPrivate CajaMenuPrivate;
+

+

+
+
+
+

CajaMenuItemDetails

+
typedef struct _CajaMenuItemDetails CajaMenuItemDetails;
+

+

+
+
+
+

CajaMenu

+
typedef struct _CajaMenu CajaMenu;
+

+

+
+
+
+

CajaMenuItem

+
typedef struct _CajaMenuItem CajaMenuItem;
+

+

+
+
+
+

caja_menu_new ()

+
CajaMenu *      caja_menu_new                   (void);
+

+

+
++ + + + +

Returns :

+
+
+
+
+

caja_menu_append_item ()

+
void                caja_menu_append_item           (CajaMenu *menu,
+                                                         CajaMenuItem *item);
+

+

+
++ + + + + + + + + + +

menu :

+

item :

+
+
+
+
+

caja_menu_get_items ()

+
GList*              caja_menu_get_items             (CajaMenu *menu);
+

+

+
++ + + + + + + + + + +

menu :

+

Returns :

+
+
+
+
+

caja_menu_item_list_free ()

+
void                caja_menu_item_list_free        (GList *item_list);
+

+

+
++ + + + +

item_list :

+
+
+
+
+

caja_menu_item_get_type ()

+
GType               caja_menu_item_get_type         (void);
+

+

+
++ + + + +

Returns :

+
+
+
+
+

caja_menu_item_new ()

+
CajaMenuItem *  caja_menu_item_new              (const char *name,
+                                                         const char *label,
+                                                         const char *tip,
+                                                         const char *icon);
+

+Creates a new menu item that can be added to the toolbar or to a contextual menu. +

+
++ + + + + + + + + + + + + + + + + + + + + + +

name :

the identifier for the menu item +

label :

the user-visible label of the menu item +

tip :

the tooltip of the menu item +

icon :

the name of the icon to display in the menu item +

Returns :

a newly create CajaMenuItem +
+
+
+
+

caja_menu_item_activate ()

+
void                caja_menu_item_activate         (CajaMenuItem *item);
+

+emits the activate signal. +

+
++ + + + +

item :

pointer to a CajaMenuItem +
+
+
+
+

caja_menu_item_set_submenu ()

+
void                caja_menu_item_set_submenu      (CajaMenuItem *item,
+                                                         CajaMenu *menu);
+

+Attachs a menu to the given CajaMenuItem. +

+
++ + + + + + + + + + +

item :

pointer to a CajaMenuItem +

menu :

pointer to a CajaMenu to attach to the button +
+
+
+
+

Property Details

+
+

The "icon" property

+
  "icon"                     gchar*                : Read / Write
+

Name of the icon to display in the menu item.

+

Default value: NULL

+
+
+
+

The "label" property

+
  "label"                    gchar*                : Read / Write
+

Label to display to the user.

+

Default value: NULL

+
+
+
+

The "menu" property

+
  "menu"                     CajaMenu*         : Read / Write
+

The menu belonging to this item. May be null.

+
+
+
+

The "name" property

+
  "name"                     gchar*                : Read / Write / Construct Only
+

Name of the item.

+

Default value: NULL

+
+
+
+

The "priority" property

+
  "priority"                 gboolean              : Read / Write
+

Show priority text in toolbars.

+

Default value: TRUE

+
+
+
+

The "sensitive" property

+
  "sensitive"                gboolean              : Read / Write
+

Whether the menu item is sensitive.

+

Default value: TRUE

+
+
+
+

The "tip" property

+
  "tip"                      gchar*                : Read / Write
+

Tooltip for the menu item.

+

Default value: NULL

+
+
+
+

Signal Details

+
+

The "activate" signal

+
void                user_function                      (CajaMenuItem *cajamenuitem,
+                                                        gpointer          user_data)             : Run Last
+

+

+
++ + + + + + + + + + +

cajamenuitem :

the object which received the signal. +

user_data :

user data set when the signal handler was connected.
+
+
+
+ + + diff --git a/docs/reference/libcaja-extension/html/libcaja-extension-caja-property-page-provider.html b/docs/reference/libcaja-extension/html/libcaja-extension-caja-property-page-provider.html new file mode 100644 index 00000000..1fc67986 --- /dev/null +++ b/docs/reference/libcaja-extension/html/libcaja-extension-caja-property-page-provider.html @@ -0,0 +1,131 @@ + + + + +caja-property-page-provider + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+

caja-property-page-provider

+

caja-property-page-provider

+
+ +
+

Object Hierarchy

+
+  GInterface
+   +----CajaPropertyPageProvider
+
+
+
+

Prerequisites

+

+CajaPropertyPageProvider requires + GObject.

+
+
+

Description

+

+

+
+
+

Details

+
+

CajaPropertyPageProvider

+
typedef struct _CajaPropertyPageProvider CajaPropertyPageProvider;
+

+

+
+
+
+

CajaPropertyPageProviderIface

+
typedef struct {
+	GTypeInterface g_iface;
+
+	GList *(*get_pages) (CajaPropertyPageProvider     *provider,
+			     GList                    *files);
+} CajaPropertyPageProviderIface;
+
+

+

+
+
+
+

caja_property_page_provider_get_pages ()

+
GList *             caja_property_page_provider_get_pages
+                                                        (CajaPropertyPageProvider *provider,
+                                                         GList *files);
+

+This function is called by Caja when it wants property page +items from the extension. +

+

+This function is called in the main thread before a property page +is shown, so it should return quickly. +

+
++ + + + + + + + + + + + + + +

provider :

a CajaPropertyPageProvider +

files :

a GList of CajaFileInfo +

Returns :

A GList of allocated CajaPropertyPage items. +
+
+
+
+ + + diff --git a/docs/reference/libcaja-extension/html/libcaja-extension-caja-property-page.html b/docs/reference/libcaja-extension/html/libcaja-extension-caja-property-page.html new file mode 100644 index 00000000..2e77850e --- /dev/null +++ b/docs/reference/libcaja-extension/html/libcaja-extension-caja-property-page.html @@ -0,0 +1,148 @@ + + + + +CajaPropertyPage + + + + + + + + + + + + + + + + + + + +
+
+
+ + +
+

CajaPropertyPage

+

CajaPropertyPage

+
+
+

Synopsis

+
                    CajaPropertyPageDetails;
+                    CajaPropertyPage;
+CajaPropertyPage * caja_property_page_new       (const char *name,
+                                                         GtkWidget *label,
+                                                         GtkWidget *page);
+
+
+
+

Object Hierarchy

+
+  GObject
+   +----CajaPropertyPage
+
+
+
+

Properties

+
+  "label"                    GtkWidget*            : Read / Write
+  "name"                     gchar*                : Read / Write / Construct Only
+  "page"                     GtkWidget*            : Read / Write
+
+
+
+

Description

+

+

+
+
+

Details

+
+

CajaPropertyPageDetails

+
typedef struct _CajaPropertyPageDetails CajaPropertyPageDetails;
+

+

+
+
+
+

CajaPropertyPage

+
typedef struct _CajaPropertyPage CajaPropertyPage;
+

+

+
+
+
+

caja_property_page_new ()

+
CajaPropertyPage * caja_property_page_new       (const char *name,
+                                                         GtkWidget *label,
+                                                         GtkWidget *page);
+

+Creates a new CajaPropertyPage from page_widget. +

+
++ + + + + + + + + + + + + + + + + + +

name :

the identifier for the property page +

label :

the user-visible label of the property page +

page :

the property page to display +

Returns :

a newly created CajaPropertyPage +
+
+
+
+

Property Details

+
+

The "label" property

+
  "label"                    GtkWidget*            : Read / Write
+

Label widget to display in the notebook tab.

+
+
+
+

The "name" property

+
  "name"                     gchar*                : Read / Write / Construct Only
+

Name of the page.

+

Default value: NULL

+
+
+
+

The "page" property

+
  "page"                     GtkWidget*            : Read / Write
+

Widget for the property page.

+
+
+
+ + + diff --git a/docs/reference/libcaja-extension/html/libcaja-extension.devhelp b/docs/reference/libcaja-extension/html/libcaja-extension.devhelp new file mode 100644 index 00000000..21967518 --- /dev/null +++ b/docs/reference/libcaja-extension/html/libcaja-extension.devhelp @@ -0,0 +1,118 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/reference/libcaja-extension/html/libcaja-extension.devhelp2 b/docs/reference/libcaja-extension/html/libcaja-extension.devhelp2 new file mode 100644 index 00000000..1869631b --- /dev/null +++ b/docs/reference/libcaja-extension/html/libcaja-extension.devhelp2 @@ -0,0 +1,118 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/reference/libcaja-extension/html/pt01.html b/docs/reference/libcaja-extension/html/pt01.html new file mode 100644 index 00000000..2795740a --- /dev/null +++ b/docs/reference/libcaja-extension/html/pt01.html @@ -0,0 +1,68 @@ + + + + +Part I. API Reference + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/reference/libcaja-extension/html/right.png b/docs/reference/libcaja-extension/html/right.png new file mode 100644 index 00000000..92832e3a Binary files /dev/null and b/docs/reference/libcaja-extension/html/right.png differ diff --git a/docs/reference/libcaja-extension/html/style.css b/docs/reference/libcaja-extension/html/style.css new file mode 100644 index 00000000..d544a2c2 --- /dev/null +++ b/docs/reference/libcaja-extension/html/style.css @@ -0,0 +1,265 @@ +.synopsis, .classsynopsis +{ + /* tango:aluminium 1/2 */ + background: #eeeeec; + border: solid 1px #d3d7cf; + padding: 0.5em; +} +.programlisting +{ + /* tango:sky blue 0/1 */ + background: #e6f3ff; + border: solid 1px #729fcf; + padding: 0.5em; +} +.variablelist +{ + padding: 4px; + margin-left: 3em; +} +.variablelist td:first-child +{ + vertical-align: top; +} + +@media screen { + sup a.footnote + { + position: relative; + top: 0em ! important; + + } + /* this is needed so that the local anchors are displayed below the naviagtion */ + div.footnote a[name], div.refnamediv a[name], div.refsect1 a[name], div.refsect2 a[name], div.index a[name], div.glossary a[name], div.sect1 a[name] + { + position: relative; + padding-top:4.5em; + } + /* this seems to be a bug in the xsl style sheets when generating indexes */ + div.index div.index + { + top: 0em; + } + /* make space for the fixed navigation bar and add space at the bottom so that + * link targets appear somewhat close to top + */ + body + { + padding-top: 3.2em; + padding-bottom: 20em; + } + /* style and size the navigation bar */ + table.navigation#top + { + position: fixed; + /* tango:scarlet red 0/1 */ + background: #ffe6e6; + border: solid 1px #ef2929; + margin-top: 0; + margin-bottom: 0; + top: 0; + left: 0; + height: 3em; + z-index: 10; + } + .navigation a, .navigation a:visited + { + /* tango:scarlet red 3 */ + color: #a40000; + } + .navigation a:hover + { + /* tango:scarlet red 1 */ + color: #ef2929; + } + td.shortcuts + { + /* tango:scarlet red 1 */ + color: #ef2929; + font-size: 80%; + white-space: nowrap; + } +} +@media print { + table.navigation { + visibility: collapse; + display: none; + } + div.titlepage table.navigation { + visibility: visible; + display: table; + /* tango:scarlet red 0/1 */ + background: #ffe6e6; + border: solid 1px #ef2929; + margin-top: 0; + margin-bottom: 0; + top: 0; + left: 0; + height: 3em; + } +} + +.navigation .title +{ + font-size: 200%; +} + +div.gallery-float +{ + float: left; + padding: 10px; +} +div.gallery-float img +{ + border-style: none; +} +div.gallery-spacer +{ + clear: both; +} + +a, a:visited +{ + text-decoration: none; + /* tango:sky blue 2 */ + color: #3465a4; +} +a:hover +{ + text-decoration: underline; + /* tango:sky blue 1 */ + color: #729fcf; +} + +div.table table +{ + border-collapse: collapse; + border-spacing: 0px; + /* tango:aluminium 3 */ + border: solid 1px #babdb6; +} + +div.table table td, div.table table th +{ + /* tango:aluminium 3 */ + border: solid 1px #babdb6; + padding: 3px; + vertical-align: top; +} + +div.table table th +{ + /* tango:aluminium 2 */ + background-color: #d3d7cf; +} + +hr +{ + /* tango:aluminium 3 */ + color: #babdb6; + background: #babdb6; + border: none 0px; + height: 1px; + clear: both; +} + +.footer +{ + padding-top: 3.5em; + /* tango:aluminium 3 */ + color: #babdb6; + text-align: center; + font-size: 80%; +} + +.warning +{ + /* tango:orange 0/1 */ + background: #ffeed9; + border-color: #ffb04f; +} +.note +{ + /* tango:chameleon 0/0.5 */ + background: #d8ffb2; + border-color: #abf562; +} +.note, .warning +{ + padding: 0.5em; + border-width: 1px; + border-style: solid; +} +.note h3, .warning h3 +{ + margin-top: 0.0em +} +.note p, .warning p +{ + margin-bottom: 0.0em +} + +/* blob links */ +h2 .extralinks, h3 .extralinks +{ + float: right; + /* tango:aluminium 3 */ + color: #babdb6; + font-size: 80%; + font-weight: normal; +} + +.annotation +{ + /* tango:aluminium 5 */ + color: #555753; + font-size: 80%; + font-weight: normal; +} + +/* code listings */ + +.listing_code .programlisting .cbracket { color: #a40000; } /* tango: scarlet red 3 */ +.listing_code .programlisting .comment { color: #a1a39d; } /* tango: aluminium 4 */ +.listing_code .programlisting .function { color: #000000; font-weight: bold; } +.listing_code .programlisting .function a { color: #11326b; font-weight: bold; } /* tango: sky blue 4 */ +.listing_code .programlisting .keyword { color: #4e9a06; } /* tango: chameleon 3 */ +.listing_code .programlisting .linenum { color: #babdb6; } /* tango: aluminium 3 */ +.listing_code .programlisting .normal { color: #000000; } +.listing_code .programlisting .number { color: #75507b; } /* tango: plum 2 */ +.listing_code .programlisting .preproc { color: #204a87; } /* tango: sky blue 3 */ +.listing_code .programlisting .string { color: #c17d11; } /* tango: chocolate 2 */ +.listing_code .programlisting .type { color: #000000; } +.listing_code .programlisting .type a { color: #11326b; } /* tango: sky blue 4 */ +.listing_code .programlisting .symbol { color: #ce5c00; } /* tango: orange 3 */ + +.listing_frame { + /* tango:sky blue 1 */ + border: solid 1px #729fcf; + padding: 0px; +} + +.listing_lines, .listing_code { + margin-top: 0px; + margin-bottom: 0px; + padding: 0.5em; +} +.listing_lines { + /* tango:sky blue 0.5 */ + background: #a6c5e3; + /* tango:aluminium 6 */ + color: #2e3436; +} +.listing_code { + /* tango:sky blue 0 */ + background: #e6f3ff; +} +.listing_code .programlisting { + /* override from previous */ + border: none 0px; + padding: 0px; +} +.listing_lines pre, .listing_code pre { + margin: 0px; +} + diff --git a/docs/reference/libcaja-extension/html/up.png b/docs/reference/libcaja-extension/html/up.png new file mode 100644 index 00000000..85b3e2a2 Binary files /dev/null and b/docs/reference/libcaja-extension/html/up.png differ diff --git a/docs/reference/libcaja-extension/libcaja-extension-docs.xml b/docs/reference/libcaja-extension/libcaja-extension-docs.xml new file mode 100644 index 00000000..a09d9757 --- /dev/null +++ b/docs/reference/libcaja-extension/libcaja-extension-docs.xml @@ -0,0 +1,36 @@ + + +]> + + + + Caja Extension Reference Manual + For Caja-Extension &version; + + + + + API Reference + + + Extension Interfaces + + + + + + + + + + + + + + + + Index + + diff --git a/docs/reference/libcaja-extension/libcaja-extension-overrides.txt b/docs/reference/libcaja-extension/libcaja-extension-overrides.txt new file mode 100644 index 00000000..e69de29b diff --git a/docs/reference/libcaja-extension/libcaja-extension-sections.txt b/docs/reference/libcaja-extension/libcaja-extension-sections.txt new file mode 100644 index 00000000..9de8dbfe --- /dev/null +++ b/docs/reference/libcaja-extension/libcaja-extension-sections.txt @@ -0,0 +1,185 @@ +
+caja-location-widget-provider +CajaLocationWidgetProvider +CajaLocationWidgetProviderIface +caja_location_widget_provider_get_widget + +CAJA_LOCATION_WIDGET_PROVIDER +CAJA_IS_LOCATION_WIDGET_PROVIDER +CAJA_TYPE_LOCATION_WIDGET_PROVIDER +caja_location_widget_provider_get_type +CAJA_LOCATION_WIDGET_PROVIDER_GET_IFACE +
+ +
+caja-menu-provider +CajaMenuProvider +CajaMenuProviderIface +caja_menu_provider_get_file_items +caja_menu_provider_get_background_items +caja_menu_provider_get_toolbar_items +caja_menu_provider_emit_items_updated_signal + +CAJA_MENU_PROVIDER +CAJA_IS_MENU_PROVIDER +CAJA_TYPE_MENU_PROVIDER +caja_menu_provider_get_type +CAJA_MENU_PROVIDER_GET_IFACE +
+ +
+caja-menu +CAJA_TYPE_MENU_ITEM +CAJA_MENU_ITEM +CAJA_MENU_ITEM_CLASS +CAJA_MENU_IS_ITEM +CAJA_MENU_IS_ITEM_CLASS +CAJA_MENU_ITEM_GET_CLASS +CajaMenuPrivate +CajaMenuItemDetails +CajaMenu +CajaMenu +CajaMenuItem +CajaMenuItem +caja_menu_new +caja_menu_append_item +caja_menu_get_items +caja_menu_item_list_free +caja_menu_item_get_type +caja_menu_item_new +caja_menu_item_activate +caja_menu_item_set_submenu + +CAJA_MENU +CAJA_IS_MENU +CAJA_TYPE_MENU +caja_menu_get_type +CAJA_MENU_CLASS +CAJA_IS_MENU_CLASS +CAJA_MENU_GET_CLASS +
+ +
+caja-column-provider +CajaColumnProvider +CajaColumnProviderIface +caja_column_provider_get_columns + +CAJA_COLUMN_PROVIDER +CAJA_IS_COLUMN_PROVIDER +CAJA_TYPE_COLUMN_PROVIDER +caja_column_provider_get_type +CAJA_COLUMN_PROVIDER_GET_IFACE +
+ +
+caja-property-page-provider +CajaPropertyPageProvider +CajaPropertyPageProviderIface +caja_property_page_provider_get_pages + +CAJA_PROPERTY_PAGE_PROVIDER +CAJA_IS_PROPERTY_PAGE_PROVIDER +CAJA_TYPE_PROPERTY_PAGE_PROVIDER +caja_property_page_provider_get_type +CAJA_PROPERTY_PAGE_PROVIDER_GET_IFACE +
+ +
+caja-file-info +CAJA_FILE_DEFINED +CajaFile +CajaFileInfo +CajaFileInfoIface +caja_file_info_list_copy +caja_file_info_list_free +caja_file_info_is_gone +caja_file_info_get_file_type +caja_file_info_get_location +caja_file_info_get_name +caja_file_info_get_uri +caja_file_info_get_activation_uri +caja_file_info_get_parent_location +caja_file_info_get_parent_uri +caja_file_info_get_mount +caja_file_info_get_uri_scheme +caja_file_info_get_parent_info +caja_file_info_get_mime_type +caja_file_info_is_mime_type +caja_file_info_is_directory +caja_file_info_can_write +caja_file_info_add_emblem +caja_file_info_get_string_attribute +caja_file_info_add_string_attribute +caja_file_info_invalidate_extension_info + +CAJA_FILE_INFO +CAJA_IS_FILE_INFO +CAJA_TYPE_FILE_INFO +caja_file_info_get_type +CAJA_FILE_INFO_GET_IFACE +
+ +
+caja-column +CajaColumnDetails +CajaColumn +CajaColumn +caja_column_new + +CAJA_COLUMN +CAJA_INFO_IS_COLUMN +CAJA_TYPE_COLUMN +caja_column_get_type +CAJA_COLUMN_CLASS +CAJA_INFO_IS_COLUMN_CLASS +CAJA_COLUMN_GET_CLASS +
+ +
+caja-info-provider +CajaInfoProvider +CajaInfoProviderIface +CajaInfoProviderUpdateComplete +caja_info_provider_update_file_info +caja_info_provider_cancel_update +caja_info_provider_update_complete_invoke + +CAJA_INFO_PROVIDER +CAJA_IS_INFO_PROVIDER +CAJA_TYPE_INFO_PROVIDER +caja_info_provider_get_type +CAJA_INFO_PROVIDER_GET_IFACE +
+ +
+caja-property-page +CajaPropertyPageDetails +CajaPropertyPage +CajaPropertyPage +caja_property_page_new + +CAJA_PROPERTY_PAGE +CAJA_IS_PROPERTY_PAGE +CAJA_TYPE_PROPERTY_PAGE +caja_property_page_get_type +CAJA_PROPERTY_PAGE_CLASS +CAJA_IS_PROPERTY_PAGE_CLASS +CAJA_PROPERTY_PAGE_GET_CLASS +
+ +
+caja-extension-types +CAJA_TYPE_OPERATION_RESULT +CajaOperationHandle +CajaOperationResult +caja_operation_result_get_type +caja_module_initialize +caja_module_shutdown +caja_module_list_types +
+ +
+caja-menu-item +
+ diff --git a/docs/reference/libcaja-extension/libcaja-extension.types b/docs/reference/libcaja-extension/libcaja-extension.types new file mode 100644 index 00000000..2c52af5d --- /dev/null +++ b/docs/reference/libcaja-extension/libcaja-extension.types @@ -0,0 +1,11 @@ +caja_property_page_provider_get_type +caja_location_widget_provider_get_type +caja_operation_result_get_type +caja_file_info_get_type +caja_property_page_get_type +caja_info_provider_get_type +caja_column_get_type +caja_column_provider_get_type +caja_menu_provider_get_type +caja_menu_get_type +caja_menu_item_get_type diff --git a/docs/reference/libcaja-extension/tmpl/caja-column-provider.sgml b/docs/reference/libcaja-extension/tmpl/caja-column-provider.sgml new file mode 100644 index 00000000..815284de --- /dev/null +++ b/docs/reference/libcaja-extension/tmpl/caja-column-provider.sgml @@ -0,0 +1,45 @@ + +caja-column-provider + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@g_iface: +@get_columns: + + + + + + +@provider: +@Returns: + + diff --git a/docs/reference/libcaja-extension/tmpl/caja-column.sgml b/docs/reference/libcaja-extension/tmpl/caja-column.sgml new file mode 100644 index 00000000..a55b63ba --- /dev/null +++ b/docs/reference/libcaja-extension/tmpl/caja-column.sgml @@ -0,0 +1,76 @@ + +CajaColumn + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@name: +@attribute: +@label: +@description: +@Returns: + + diff --git a/docs/reference/libcaja-extension/tmpl/caja-extension-types.sgml b/docs/reference/libcaja-extension/tmpl/caja-extension-types.sgml new file mode 100644 index 00000000..1fba8e67 --- /dev/null +++ b/docs/reference/libcaja-extension/tmpl/caja-extension-types.sgml @@ -0,0 +1,78 @@ + +caja-extension-types + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@CAJA_OPERATION_COMPLETE: +@CAJA_OPERATION_FAILED: +@CAJA_OPERATION_IN_PROGRESS: + + + + + + +@void: +@Returns: + + + + + + + +@module: + + + + + + + +@void: + + + + + + + +@types: +@num_types: + + diff --git a/docs/reference/libcaja-extension/tmpl/caja-file-info.sgml b/docs/reference/libcaja-extension/tmpl/caja-file-info.sgml new file mode 100644 index 00000000..201be36a --- /dev/null +++ b/docs/reference/libcaja-extension/tmpl/caja-file-info.sgml @@ -0,0 +1,257 @@ + +caja-file-info + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@g_iface: +@is_gone: +@get_name: +@get_uri: +@get_parent_uri: +@get_uri_scheme: +@get_mime_type: +@is_mime_type: +@is_directory: +@add_emblem: +@get_string_attribute: +@add_string_attribute: +@invalidate_extension_info: +@get_activation_uri: +@get_file_type: +@get_location: +@get_parent_location: +@get_parent_info: +@get_mount: +@can_write: + + + + + + +@files: +@Returns: + + + + + + + +@files: + + + + + + + +@file: +@Returns: + + + + + + + +@file: +@Returns: + + + + + + + +@file: +@Returns: + + + + + + + +@file: +@Returns: + + + + + + + +@file: +@Returns: + + + + + + + +@file: +@Returns: + + + + + + + +@file: +@Returns: + + + + + + + +@file: +@Returns: + + + + + + + +@file: +@Returns: + + + + + + + +@file: +@Returns: + + + + + + + +@file: +@Returns: + + + + + + + +@file: +@Returns: + + + + + + + +@file: +@mime_type: +@Returns: + + + + + + + +@file: +@Returns: + + + + + + + +@file: +@Returns: + + + + + + + +@file: +@emblem_name: + + + + + + + +@file: +@attribute_name: +@Returns: + + + + + + + +@file: +@attribute_name: +@value: + + + + + + + +@file: + + diff --git a/docs/reference/libcaja-extension/tmpl/caja-info-provider.sgml b/docs/reference/libcaja-extension/tmpl/caja-info-provider.sgml new file mode 100644 index 00000000..75b0e0f7 --- /dev/null +++ b/docs/reference/libcaja-extension/tmpl/caja-info-provider.sgml @@ -0,0 +1,80 @@ + +caja-info-provider + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@g_iface: +@update_file_info: +@cancel_update: + + + + + + +@provider: +@handle: +@result: +@user_data: + + + + + + + +@provider: +@file: +@update_complete: +@handle: +@Returns: + + + + + + + +@provider: +@handle: + + + + + + + +@update_complete: +@provider: +@handle: +@result: + + diff --git a/docs/reference/libcaja-extension/tmpl/caja-location-widget-provider.sgml b/docs/reference/libcaja-extension/tmpl/caja-location-widget-provider.sgml new file mode 100644 index 00000000..d6effd30 --- /dev/null +++ b/docs/reference/libcaja-extension/tmpl/caja-location-widget-provider.sgml @@ -0,0 +1,47 @@ + +caja-location-widget-provider + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@g_iface: +@get_widget: + + + + + + +@provider: +@uri: +@window: +@Returns: + + diff --git a/docs/reference/libcaja-extension/tmpl/caja-menu-item.sgml b/docs/reference/libcaja-extension/tmpl/caja-menu-item.sgml new file mode 100644 index 00000000..627f4a4a --- /dev/null +++ b/docs/reference/libcaja-extension/tmpl/caja-menu-item.sgml @@ -0,0 +1,22 @@ + +caja-menu-item + + + + + + + + + + + + + + + + + + + + diff --git a/docs/reference/libcaja-extension/tmpl/caja-menu-provider.sgml b/docs/reference/libcaja-extension/tmpl/caja-menu-provider.sgml new file mode 100644 index 00000000..9be2de5a --- /dev/null +++ b/docs/reference/libcaja-extension/tmpl/caja-menu-provider.sgml @@ -0,0 +1,86 @@ + +caja-menu-provider + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@cajamenuprovider: the object which received the signal. + + + + + + +@g_iface: +@get_file_items: +@get_background_items: +@get_toolbar_items: + + + + + + +@provider: +@window: +@files: +@Returns: + + + + + + + +@provider: +@window: +@current_folder: +@Returns: + + + + + + + +@provider: +@window: +@current_folder: +@Returns: + + + + + + + +@provider: + + diff --git a/docs/reference/libcaja-extension/tmpl/caja-menu.sgml b/docs/reference/libcaja-extension/tmpl/caja-menu.sgml new file mode 100644 index 00000000..37187bc6 --- /dev/null +++ b/docs/reference/libcaja-extension/tmpl/caja-menu.sgml @@ -0,0 +1,208 @@ + +CajaMenuItem + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@obj: + + + + + + + +@klass: + + + + + + + +@obj: + + + + + + + +@klass: + + + + + + + +@obj: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@cajamenuitem: the object which received the signal. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@void: +@Returns: + + + + + + + +@menu: +@item: + + + + + + + +@menu: +@Returns: + + + + + + + +@item_list: + + + + + + + +@void: +@Returns: + + + + + + + +@name: +@label: +@tip: +@icon: +@Returns: + + + + + + + +@item: + + + + + + + +@item: +@menu: + + diff --git a/docs/reference/libcaja-extension/tmpl/caja-property-page-provider.sgml b/docs/reference/libcaja-extension/tmpl/caja-property-page-provider.sgml new file mode 100644 index 00000000..a7df289b --- /dev/null +++ b/docs/reference/libcaja-extension/tmpl/caja-property-page-provider.sgml @@ -0,0 +1,46 @@ + +caja-property-page-provider + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@g_iface: +@get_pages: + + + + + + +@provider: +@files: +@Returns: + + diff --git a/docs/reference/libcaja-extension/tmpl/caja-property-page.sgml b/docs/reference/libcaja-extension/tmpl/caja-property-page.sgml new file mode 100644 index 00000000..cc5753b2 --- /dev/null +++ b/docs/reference/libcaja-extension/tmpl/caja-property-page.sgml @@ -0,0 +1,60 @@ + +CajaPropertyPage + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@name: +@label: +@page: +@Returns: + + diff --git a/docs/reference/libcaja-extension/tmpl/libcaja-extension-unused.sgml b/docs/reference/libcaja-extension/tmpl/libcaja-extension-unused.sgml new file mode 100644 index 00000000..e69de29b diff --git a/docs/reference/libcaja-extension/version.xml.in b/docs/reference/libcaja-extension/version.xml.in new file mode 100644 index 00000000..d4c5173b --- /dev/null +++ b/docs/reference/libcaja-extension/version.xml.in @@ -0,0 +1 @@ +@CAJA_EXTENSION_VERSION_INFO@ diff --git a/docs/smoketests.html b/docs/smoketests.html new file mode 100644 index 00000000..80dd2dd4 --- /dev/null +++ b/docs/smoketests.html @@ -0,0 +1,555 @@ + + + + + + + + + + + + + +

Caja +Smoke Tests

+

The +Caja Smoke Tests are a minimal set of tests, to determine whether +a build is usable for testing, and to catch obvious regressions.

+



+

+

Views

+

Before +beginning this section, open a folder which contains at least one +MP3, image (GIF, JPEG or PNG), plain text, HTML, PDF, and RPM file. +(For those inside the Eazel firewall, these are in +/h/public/QE/smoketests.)

Also be sure to be in +single-click mode. (Preferences | Click Behavior | 'Active items with +single click')


+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Test + #

+
+

Test

+
+

Test + Steps

+
+

Expected + Results

+
+

V-1

+
+

View + as Icon

+
+

1. + Select "View as Icons" from pop-up menu. +

+

2. + Zoom in to 400% and out to 25%, both via the pop-up menu, and via + +/- icons.

+


+

+
+


+

+
+

V-2

+
+

View + as List

+
+

1. + Select "View as List" from pop-up menu +

+

2. + Zoom in to 400% and out to 25%, and via +/- icons.

+
+


+

+
+

V-3

+
+

View + as Music

+
+

1. + Select "View as Music" from pop-up menu. +

+

2. + Play an MP3.

+
+


+

+
+

V-4

+
+

View + as Web Page

+
+

1. + Click on a file of type "HTML Document".

+
+


+

+
+

V-5

+
+

View + as Text

+
+

1. + Click on a file of type "plain text".

+
+


+

+
+

V-6

+
+

View + as Image

+
+

1. + Click on an image of type "JPEG image", "GIF + image", or "PNG image". (confirm)

+
+


+

+
+

V-7

+
+

View + as Hardware

+
+

1. + Type "hardware:" or "hardware:overview" into + the Location bar.

+
+


+

+
+

V-8

+
+

View + as PDF Document

+
+

1. + Click on a PDF file.

+
+


+

+
+

V-9

+
+

View + as Package

+
+

1. + Click on any Red Hat Package Manager file.

+
+


+

+
+



+

+

File +Operations

+

Before +beginning this section, change your Click Behavior (in Preferences) +to 'Active items with a double click'.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Test + Number

+
+

Test

+
+

Test + Steps

+
+

Expected + Results

+
+

F-1

+
+

Rename + a file or folder

+
+

1. + Click on a file, and choose "Rename" from the File or + context menu. +

+

2. + Type in a new name

+
+


+

+
+

F-2

+
+

Duplicate + a file or folder

+
+

1. + Click on a file, and choose "Duplicate" from the File + or context menu.

+
+


+

+
+

F-3

+
+

Create + a link to a file or folder

+
+

1. + Click on a file, and choose "Create Link" from the File + or context menu.

+
+


+

+
+

F-4

+
+

Stretch + an icon

+
+

1. + Click on a file, and choose "Stretch Icon" from the + File or context menu. +

+

2. + Drag the icon by a corner, and enlarge or shrink it.

+
+


+

+
+



+

+

Desktop +Operations

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Test + Number

+
+

Test

+
+

Test + Steps

+
+

Expected + Results

+
+

D-1

+
+

Empty + Trash

+
+

1. + Drag files or folders onto the Trash icon.

+

2. + Right-click on the Trash, and select "Empty Trash" + (alternatively, double-click on the trash can, and select "Empty + Trash" from the File menu.)

+


+

+
+


+

+
+

D-2

+
+

Drag + file to Desktop

+
+

1. + Drag a file from a Caja view window to the Desktop

+
+

File + should be moved to desktop.

+
+



Preferences/Customization

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Test + Number

+
+

Test

+
+

Test + Steps

+
+

Expected + Results

+
+

P-1

+
+

Switch + Themes

+
+

1. + From a Caja window, choose "Caja Themes" from + the Edit menu. +

+

2. + Try each of the themes.

+
+


+

+
+

P-2

+
+

Switch + User Mode

+
+

1. + From a Caja window, try each of the three user modes.

+
+

In + Beginner mode: +

+
    +
  1. The + user mode menu's "Edit Beginner User Level" should + lead to a dialog with very minimal settings.

    +
  2. Dot + files (e.g. .bashrc) should not be displayed. +

    +
  3. The + "Special Flags" portion of the Show Properties + dialog's "Permissions" pane should be omitted. +

    +
+

In + Intermediate mode:

+
    +
  1. Dot + files (e.g. .bashrc) should not be displayed. +

    +
  2. The + "Special Flags" portion of the Show Properties + dialog's "Permissions" pane should be omitted. +

    +
+

In + Expert mode, none of the above user experience simplification + should occur.

+
+

P-3

+
+

Switch + Anti-aliasing mode

+
+

1. + While in Intermediate or Expert mode, choose "Preferences..." + From the user mode menu. +

+

2. + In the "Appearance" category, deselect the "Use + smoother (but slower) graphics" checkbox.

+
+

Text + and icons should no longer be anti-aliased.

+
+

P-4

+
+

Change + Background

+
+

1. + Choose "Backgrounds and Emblems" from the Edit menu. +

+

2. + Drag a few colors and backgrounds to the sidebar & main + window pane.

+
+


+

+
+



+

+

Maintained +by Josh Barrow for Caja +Quality Engineering, originally written by Eli +Goldberg; feedback welcome.
Adaptation and reuse for other +open source projects is freely permitted.
Last Updated: 9/28/2000

+ + \ No newline at end of file diff --git a/docs/state-machines.txt b/docs/state-machines.txt new file mode 100644 index 00000000..d89fcaec --- /dev/null +++ b/docs/state-machines.txt @@ -0,0 +1,77 @@ + +Proposal for the loading state machines + + +ViewFrame state machine + +States are: + + +E: Empty (the initial state right after construction) +A: Activating (waiting for component to be activated) +N: No load_location request (a view component has been loaded, but no load_location request has been sent yet) +W: Waiting (waiting for a response after a load request) +U: Underway (the component has responded and the load is assumed underway) +L: Loaded (the component has finished loading successfully) +F: Failed (there was a fatal error somewhere) + +X: this stimulus is guaranteed impossible in this state + + +Things I was unsure about: + +?2: Once a load has failed at some stage, should it be OK for Caja +to try to make further calls of any kind? + +Missing: + +1) "Component stops responding" stimulus. +2) Distinction of failure loading vs. crash of the component. + +Note: + +A "*" means that this is illegal but non-fatal, so we want to use g_warning. + + + State Transition Chart + + + Initial State + + | E | A | N | W | U | L | F | + ----------------------------------------|-----|-----|-----|-----|-----|-----|-----| + successful load_client call | A | X | X | X | X | X | ?2 | + ----------------------------------------|-----|-----|-----|-----|-----|-----|-----| + unsuccessful load_client call | F | X | X | X | X | X | ?2 | + ----------------------------------------|-----|-----|-----|-----|-----|-----|-----| + successful activated_component call | X | N | X | X | X | X | ?2 | + ----------------------------------------|-----|-----|-----|-----|-----|-----|-----| + unsuccessful activated_component call | X | F | X | X | X | X | ?2 | + ----------------------------------------|-----|-----|-----|-----|-----|-----|-----| + stop activation | E | E | X | X | X | X | ?2 | + ----------------------------------------|-----|-----|-----|-----|-----|-----|-----| + caja_view_frame_load_location call | X | F | W | W | W | W | ?2 | + ----------------------------------------|-----|-----|-----|-----|-----|-----|-----| + open_location call from component | X | X | N* | U | U | L | X | + ----------------------------------------|-----|-----|-----|-----|-----|-----|-----| + open_location_in_new_window | X | X | N* | U | U | L | X | + ----------------------------------------|-----|-----|-----|-----|-----|-----|-----| + report_location_change | X | X | N* | U | U | U | X | +S ----------------------------------------|-----|-----|-----|-----|-----|-----|-----| +t report_selection_change | X | X | N* | U | U | L | X | +i ----------------------------------------|-----|-----|-----|-----|-----|-----|-----| +m report_status | X | X | N* | U | U | L | X | +u ----------------------------------------|-----|-----|-----|-----|-----|-----|-----| +l report_load_underway | X | X | N* | U | U | U | X | +u ----------------------------------------|-----|-----|-----|-----|-----|-----|-----| +s report_load_progress | X | X | N* | U | U | U | X | + ----------------------------------------|-----|-----|-----|-----|-----|-----|-----| + report_load_complete | X | X | N* | L | L | L | X | + ----------------------------------------|-----|-----|-----|-----|-----|-----|-----| + report_load_failed | X | X | N* | F | F | F | X | + ----------------------------------------|-----|-----|-----|-----|-----|-----|-----| + set_title | X | X | N* | U | U | L | X | + ----------------------------------------|-----|-----|-----|-----|-----|-----|-----| + user hits cancel on timer dialog | X | X | X | F | X | X | X | + ----------------------------------------|-----|-----|-----|-----|-----|-----|-----| + diff --git a/docs/style-guide.html b/docs/style-guide.html new file mode 100644 index 00000000..8215456d --- /dev/null +++ b/docs/style-guide.html @@ -0,0 +1,137 @@ + + + +Caja Coding Style Guide + + + + +

To make code written for Caja look and act in a predictable way, +we follow a set of guidelines that specify some details of how we write code. +To start, we follow all the guidelines outlined in the +MATE Programming Guidelines.

+ +

This document covers both things that are not mentioned in the MATE +Programming Guidelines and things that are mentioned there but need +to be re-emphasized because people don't follow them often enough.

+ +

I'm just getting started on this document. Feedback is welcome. +Eventually I'd like better organization and tons of examples.

+ +
+

- Darin

+
+ +
+ +

We use the most-recommended coding style from the MATE Programming +Guidelines. This means that we use the Linux kernel brace style with +8-character tabs (not the GNU brace style), we put spaces before +the parentheses that introduce function argument lists, we put the +braces that open the block for an if statement on the same line as the +if statement (part of Linux kernel brace style).

+ +

We prefer to use words rather than acronyms or abbreviations. This means that +we name classes with a prefix like Caja, not Ntl, for example. And we use variables +named result rather than retval or rv.

+ +

We strive to have a minimum number of local variables. This makes it +easier to move pieces of code around. For more on this, read +Refactoring.

+ +

We use type casts as little as possible. There are many places in GTK programming +where you have to cast to make the program work, but we do whatever we can +to avoid this. Also, we prefer to cast data pointers, rather than casting +function pointers, since there's so much more to get wrong with function +pointer casts.

+ +

We use typedefs from <glib.h> for things like guint, guchar and gpointer, +but not gint, gchar, or gdouble. Using these gives a false sense +of portability. In all three cases, using system calls like printf requires +knowing that these are the "real" int, char, and double, so there's no reason +to use a typedef that's non-standard unless it's a shorter name or clearer +in some way.

+ +

We avoid in-band signaling. This means that we avoid using special +values to indicate errors, for example. This can lead to subtle bugs when a valid +result is misinterpreted as an error, and can make it hard to tell if the code +handles errors or not.

+ +

We code for clarity first. Other concerns like efficiency are secondary. +Sometimes they become more important than clarity, but only once they are proven +to be a problem.

+ +

We use for loops when they make the code easier to read. The alternative +is usually to use a while loop. It's true that +"easy to read" is a subjective thing.

+ +

We declare local variables at the beginning of a block. C99 allows you +to declare variables anywhere in a function, but a lot of compilers still do not +support C99.

+ +

We do not initialize local variables in their declarations. C allows you +to initialize a local variable when declaring it. But no other code can run before +this, because the other statements in a function must be after all the declarations. +If there are lines of code initializing the variables in the declarations, it can +be harder to change the function around, since code must move down from the declaration +if other code needs to run after it. To avoid this, we just don't use the ability +to initialize the variable when it's declared.

+ +

We always use braces, even for one-statement "blocks". Our consensus is +to do things like this:

+ +
+
+if (list != NULL) {
+        g_warning ("the list isn't empty");
+}
+
+
+ +

Instead of this:

+ +
+
+if (list != NULL)
+        g_warning ("the list isn't empty");
+
+
+ +

This applies to all control structures: if, while, for, do.

+ +

We make each header "stand alone". Our concept with C header files is +that each one must be written so it can be included without including another file +first. To test that the header files we develop have this property, we always +include the corresponding header file first in each C source file. The only exception +is the include of <config.h>, which goes first. Here's an example:

+ +
+
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*-
+ *
+ * caja-icon-factory.c: Class for obtaining icons for files and other objects.
+ *
+ * Copyright (C) 1999, 2000 Red Hat Inc.
+ * Copyright (C) 1999, 2000 Eazel, Inc.
+ *
+ * License agreement goes here.
+ *
+ * Author: John Sullivan <sullivan@eazel.com>
+ */
+
+#include <config.h>
+#include "caja-icon-factory.h"
+
+#include <string.h>
+#include <stdio.h>
+Include statements for other header files go here.
+
+Other declarations and code go here.
+
+
+ +
+ + + + diff --git a/eel/ChangeLog b/eel/ChangeLog new file mode 100644 index 00000000..ef98ce08 --- /dev/null +++ b/eel/ChangeLog @@ -0,0 +1,9642 @@ +=== caja 2.26.2 === +=== caja 2.26.1 === + +2009-03-24 Alexander Larsson + + * eel-background.c: + Ensure that we correctly free root pixmaps that are never set + as desktop background, so that they are not leaked. + +2009-03-16 Cosimo Cecchi + + * Makefile.am: remove -version-info LDFLAG from eel, + as this is not a private library anymore. + +=== caja 2.26.0 === +=== caja 2.25.93 === + +2009-03-09 Alexander Larsson + + * eel-editable-label.c: + (eel_editable_label_move_forward_word): + Don't move past end of string (#569165). + +2009-03-09 Alexander Larsson + + * eel-editable-label.c: + (eel_editable_label_move_cursor): + Revert wrong cursor move change. + +2009-02-24 Alexander Larsson + + * eel-background.c (eel_background_get_image_uri): + Don't spew warning if there is no uri. + +2009-02-17 Alexander Larsson + + * eel-background.c (eel_background_ensure_realized): + Ignore pending background changes when we've realized the + background to avoid an unnecessary re-set of the pixmap. + +=== caja 2.25.91 === +=== caja 2.25.4 === + +2009-01-28 Cosimo Cecchi + + * eel-editable-label.c: (eel_editable_label_move_cursor): + make sure we take care about UTF-8/byte conversion when we move + around the cursor (#569165). + +2009-01-22 A. Walton + + * eel-debug-drawing.c (eel_debug_show_pixbuf_in_external_viewer): + Use g_mkstemp() instead of mkstemp(). Pointed out by Paolo Borelli. + +2009-01-21 A. Walton + + * eel-debug-drawing.c (eel_debug_show_pixbuf_in_external_viewer): + Really fix bug #568630, replace mktemp() with mkstemp(). + +2009-01-21 A. Walton + + * eel-debug-drawing.c (eel_debug_show_pixbuf_in_external_viewer): + Last commit is wrong; mkstemp is not a drop in replacement for + mktemp. + +2009-01-21 A. Walton + + * eel-debug-drawing.c (eel_debug_show_pixbuf_in_external_viewer): + Bug 568630 eel should use mkstemp() instead of mktemp() + mktemp() is deprecated and should not be used. + Patch by Jasper Lievisse Adriaanse. + +2009-01-20 Cosimo Cecchi + + * eel-background.c: (on_bg_changed), (on_bg_transitioned), + (eel_background_init), (free_fade), (eel_background_finalize), + (set_root_pixmap), (fade_to_pixmap), + (eel_background_set_up_widget), (on_background_changed), + (init_fade), (eel_widget_queue_background_change), + (widget_style_set_cb), (widget_realized_setup), + (on_widget_destroyed), (eel_get_widget_background): + Support fading between backgrounds. + Bug #552859, patch by Ray Strode. + +=== caja 2.25.2 === + +2008-12-15 Alexander Larsson + + * Makefile.am: + Don't install headers + +2008-12-10 Alexander Larsson + + * eel/eel-enumeration.[ch]: + * eel/eel-preferences-builder.c: + * eel/eel-preferences.[ch]: + Make enums uint (so we can use larger values for thumbnail limit). + +2008-12-08 Cosimo Cecchi + + * test/test.h: + Flip include orders to fix the build (#563731). + +2008-12-07 Cosimo Cecchi + + * eel/eel-background.c: + * test/test.h: + Remove more useless includes. + Thanks to Luis Menina (#563569). + +2008-12-07 Cosimo Cecchi + + * eel/check-program.c: + * eel/eel-gdk-pixbuf-extensions.c: + * test/test-eel-background.c: + * test/test-eel-image-table.c: + Use single gdk-pixbuf and GTK+ headers includes. + +2008-12-01 Alexander Larsson + + * configure.in: + Post release version bump + +==================== 2.25.1 ==================== + +2008-12-01 Alexander Larsson + + * NEWS: + Update for release + +2008-11-18 Cosimo Cecchi + + * eel/eel-preferences.c: + (eel_preferences_add_auto_string_array_as_quarks): + Plug a leak. + +2008-10-09 Alexander Larsson + + * eel/eel-gdk-extensions.[ch]: + Remove old now unused function eel_gdk_color_parse() + +2008-10-07 Alexander Larsson + + * configure.in: + * eel-2.0-uninstalled.pc.in: + * eel-2.0.pc.in: + Remove deps on startup-notify, libmate* and libglade + + * eel/eel-mate-extensions.[ch]: + Remove MateIconSelector functions. + Remove glade functions + + * eel/eel-preferences-glade.c: Removed. + * eel/eel-preferences-builder.c: Added. + * eel/eel-preferences-glade.h: Removed + * eel/eel-preferences.h: + Move eel-preferences-glade.c to eel-preferences-builder.c and use + GtkBuilder instead of Glade. + Remove eel-preferences-glade.h and move GtkBuilder functions + into eel-preferences.h + + * eel/Makefile.am: + Update for file renamed/deletions + + * eel/check-program.c: + * eel/eel-stock-dialogs.c: + Don't include libmate headers. + +2008-10-07 Alexander Larsson + + * eel/eel-mate-extensions.[ch]: + Remove mate_icon_selector code + +2008-10-06 Alexander Larsson + + * eel/check-program.c: + * test/test-eel-widgets.c: + * test/test.c: + Don't use MateProgram + +2008-10-06 Alexander Larsson + + * eel/eel-stock-dialogs.c (timed_wait_callback): + Don't call mate_authentication_manager_dialog_is_visible() + anymore, not needed with no mate-vfs. + +2008-10-06 Alexander Larsson + + * eel/eel-debug-drawing.c (eel_debug_show_pixbuf_in_external_viewer): + Better ignoring of system return value. Fixes build (#555264) + +2008-10-06 Alexander Larsson + + * eel/Makefile.am: + * eel/eel-mount-operation.[ch]: + Remove EelMountOperation + +2008-10-01 Alexander Larsson + + * configure.in: + Bump version to 2.25.1. + Stable version lives on the mate-2-24 branch. + +2008-09-22 Christian Neumair + + * configure.in: post-release bump to 2.24.1 + +==================== 2.24.0 ==================== + +2008-09-22 Christian Neumair + + * NEWS: + Update for release. + +2008-09-15 Christian Neumair + + * eel/eel-mount-operation.c (ask_password): + Do not make password dialog modal. Fixes #539966. + +2008-09-13 Cosimo Cecchi + + * eel/eel-preferences.c: (update_auto_string_array_as_quarks): + Fix a warning for an uninitialized variable. + Patch by Christian Kirbach (#552135). + +2008-09-10 Christian Neumair + + * eel/eel-preferences.c (update_auto_string_array_as_quarks), + (preferences_entry_update_auto_storage), + (preferences_entry_remove_auto_storage), + (eel_preferences_add_auto_string_array_as_quarks): + * eel/eel-preferences.h: + Add eel_preferences_add_auto_string_array_as_quarks(), which maps a + string array to a quark array. No remove function yet, since up to now + it is not needed. Parly fixes #551576. + +2008-09-08 Christian Neumair + + * configure.in: post-release bump to 2.40.0 + +==================== 2.23.92 ==================== + +2008-09-08 Christian Neumair + + * NEWS: + Update for release. + +2008-09-08 Christian Neumair + + * eel/Makefile.am: + * eel/eel-app-launch-context.c: + * eel/eel-app-launch-context.h: + Remove in favor of GdkAppLaunchContext. + +2008-09-06 Christian Neumair + + * eel/eel-gdk-pixbuf-extensions.c (pixbuf_loader_size_prepared): + Explicitly cast to float when determining aspect ratio. Fixes #550997. + +2008-09-02 Cosimo Cecchi + + * eel/*.[ch]: use single headers GTK/GDK/Pango includes. + +2008-09-01 Christian Neumair + + * configure.in: post-release bump to 2.23.92. + +==================== 2.23.91 ==================== + +2008-09-01 Christian Neumair + + * NEWS: + Update for release. + +2008-09-01 Christian Neumair + + * eel/eel-vfs-extensions.c (eel_filename_strip_extension), + (eel_filename_get_rename_region): + * eel/eel-vfs-extensions.h: + Add eel_filename_strip_extension(), and use it in + eel_filename_get_rename_region(). Part of #309510. Thanks to Paolo + Borelli and Jared Moore . + +2008-09-01 Christian Neumair + + * eel/eel-gdk-pixbuf-extensions.c + (eel_gdk_pixbuf_load_from_stream), (pixbuf_loader_size_prepared), + (eel_gdk_pixbuf_load_from_stream_at_size): + * eel/eel-gdk-pixbuf-extensions.h: + Add eel_gdk_pixbuf_load_from_stream_at_size(), which sets the size of + the pixbuf loader when loading. Part of #529371. + +2008-08-03 Christian Neumair + + * configure.in: post-release bump to 2.23.91. + +==================== 2.23.90 ==================== + +2008-08-03 Christian Neumair + + * configure.in: post-release bump to 2.23.90. + +==================== 2.23.6 ==================== + +2008-07-21 Christian Neumair + + * configure.in: post-release bump to 2.23.6. + +==================== 2.23.5 ==================== + +2008-06-16 Christian Neumair + + * configure.in: post-release bump to 2.23.5. + +==================== 2.23.4 ==================== + +2008-06-16 Christian Neumair + + * configure.in: actually pre-release bump to 2.23.4. + +2008-06-16 Christian Neumair + + * NEWS: Update for release. + * configure.in: pre-release bump to 2.23.4. + +2008-06-10 Christian Neumair + + * eel/eel-editable-label.c + (eel_editable_label_get_block_cursor_location), + (eel_editable_label_draw_cursor), + (eel_editable_label_toggle_overwrite): + Use block cursor in insert mode. Fixes #511617. Thanks to Arthur + Taylor. + +2008-06-03 Vincent Untz + + * configure.in: post-release bump to 2.23.3 + +==================== 2.23.2 ==================== + +2008-06-03 Christian Neumair + + * NEWS: + * configure.in: + Require libmate 2.23.0. + +2008-06-03 Christian Neumair + + * NEWS: + Update for release. + +Sun Jun 1 21:04:04 2008 Søren Sandmann + + * eel/eel-background.c (struct EelBackgroundDetails): Remove + unused image_mtime + +Sun Jun 1 21:02:00 2008 Søren Sandmann + + * eel/eel-background.c: Don't store the image_uri - instead rely + on getting it from MateBG. + +Sun Jun 1 20:39:03 2008 Søren Sandmann + + * eel/eel-background.c: Don't monitor the file anymore; this is + done by MateBG. + +Sun Jun 1 20:24:12 2008 Søren Sandmann + + * eel/eel-background.c (struct EelBackgroundDetails): Don't store + an EelBackgroundPlacement; instead compute it from the MateBG. + +Sun Jun 1 19:30:16 2008 Søren Sandmann + + * eel/eel-background.c (eel_background_save_to_mateconf): New function. + +Sat May 31 02:23:16 2008 Søren Sandmann + + * eel/eel-background.c (eel_background_reload_image): Deal with + the case where image_uri is NULL. + +Sat May 31 00:39:25 2008 Søren Sandmann + + * eel/eel-background.c (eel_background_reload_image): Use + mate_bg_set_filename(). + + * configure.in: Require new mate-desktop + +Fri May 30 23:23:53 2008 Søren Sandmann + + * Revert last commit, since we still need to deal with file uris. + +Fri May 30 22:13:51 2008 Søren Sandmann + + * eel/eel-background.[ch]: Rename eel_background_set/get_image_uri() + to set/get_image_filename() to reflect the fact that only local + files works. + +Fri May 30 21:31:09 2008 Søren Sandmann + + * eel/eel-background.h: Remove unused + eel_background_set_image_uri_sync() function. + +2008-04-21 Christian Neumair + + * configure.in: + post release version bump + +=== eel 2.23.1 === + +2008-04-21 Christian Neumair + + * NEWS: + Update for release. + +2008-03-29 Christian Neumair + + * configure.in: + Use a slightly cleaner method of detecting libstartup-notification, + using macros instead of manually calling pkg-config (#507811). + Thanks to Loïc Minier . + +2008-03-29 Christian Neumair + + * eel/eel-debug-drawing.c + (eel_debug_show_pixbuf_in_external_viewer): + Cast system() call result to void, to avoid complier warnings + (#502579). + +2008-03-28 Alexander Larsson + + * configure.in: + Bump version to 2.23.1 + Mate 2.22 work continues on mate-2-22 branch + +2008-03-28 Christian Neumair + + * eel/eel-accessibility.h: + * eel/eel-background.c (eel_background_set_image_uri_helper), + (eel_background_is_set): + * eel/eel-canvas-rect-ellipse.c (eel_canvas_re_destroy), + (eel_canvas_re_set_property), (eel_canvas_re_get_property): + * eel/eel-canvas.c (eel_canvas_item_set_property), + (eel_canvas_item_get_property), (eel_canvas_item_dispose), + (eel_canvas_item_invoke_update), (eel_canvas_group_set_property), + (eel_canvas_group_get_property), (eel_canvas_group_destroy), + (group_remove), (eel_canvas_accessible_get_n_children), + (eel_canvas_accessible_ref_child), (eel_canvas_accessible_create), + (eel_canvas_accessible_factory_create_accessible), + (eel_canvas_destroy), (eel_canvas_map), (eel_canvas_unmap), + (eel_canvas_realize), (eel_canvas_unrealize), + (eel_canvas_size_allocate), (eel_canvas_button), + (eel_canvas_motion), (eel_canvas_key), (eel_canvas_crossing), + (eel_canvas_expose), (do_update), + (eel_canvas_item_accessible_get_extents), + (eel_canvas_item_accessible_get_mdi_zorder), + (eel_canvas_item_accessible_component_interface_init), + (eel_canvas_item_accessible_create), + (eel_canvas_item_accessible_factory_create_accessible): + * eel/eel-debug-drawing.c (debug_pixbuf_viewer_size_request), + (debug_pixbuf_viewer_expose_event), + (debug_pixbuf_viewer_set_pixbuf): + * eel/eel-editable-label.c (add_move_binding), + (eel_editable_label_finalize), (eel_editable_label_size_request), + (eel_editable_label_style_set), (_eel_draw_insertion_cursor), + (eel_editable_label_expose), + (eel_editable_label_select_region_index), (popup_position_func), + (atk_text_interface_init), (atk_editable_text_interface_init), + (eel_editable_label_accessible_get_name): + * eel/eel-enumeration.c (eel_enumeration_new), + (eel_enumeration_new_from_entries): + * eel/eel-mateconf-extensions.c (simple_value_is_equal): + * eel/eel-gdk-extensions.c (eel_gradient_new), + (eel_gradient_set_edge_color), (eel_gradient_set_left_color_spec), + (eel_gradient_set_top_color_spec), + (eel_gradient_set_right_color_spec), + (eel_gradient_set_bottom_color_spec), + (eel_gdk_color_parse_with_white_default): + * eel/eel-gdk-pixbuf-extensions.c (pixbuf_destroy_callback): + * eel/eel-graphic-effects.c (create_new_pixbuf), + (create_new_pixbuf_with_alpha): + * eel/eel-gtk-extensions.c (while_realized_disconnecter): + * eel/eel-image-table.c (eel_image_table_realize), + (eel_image_table_unrealize), (eel_image_table_remove), + (image_table_emit_signal), (image_table_handle_motion), + (ancestor_enter_notify_event), (ancestor_leave_notify_event), + (ancestor_motion_notify_event), (ancestor_button_press_event), + (ancestor_button_release_event): + * eel/eel-labeled-image.c (eel_labeled_image_set_property), + (eel_labeled_image_get_property), (eel_labeled_image_size_request), + (eel_labeled_image_size_allocate), + (eel_labeled_image_expose_event), (eel_labeled_image_map), + (eel_labeled_image_unmap), (eel_labeled_image_add), + (eel_labeled_image_remove), (eel_labeled_image_forall), + (labeled_image_get_image_dimensions), + (labeled_image_get_label_dimensions), + (labeled_image_get_image_bounds_fill), + (labeled_image_get_label_bounds_fill), + (labeled_image_update_alignments), + (labeled_image_get_content_dimensions), + (labeled_image_get_content_bounds), (labeled_image_ensure_label), + (labeled_image_ensure_image), (labeled_image_show_image), + (labeled_image_show_label), (eel_labled_set_mnemonic_widget), + (button_leave_callback), (button_focus_out_event_callback): + * eel/eel-preferences.c (preferences_mateconf_value_get_int), + (preferences_mateconf_value_get_bool), + (preferences_mateconf_value_get_string), + (preferences_mateconf_value_get_string_array), + (preferences_peek_storage_path), (preferences_set_storage_path), + (preferences_get_value), (preferences_preference_is_mateconf_key), + (preferences_key_make), (preferences_get_default_value), + (eel_preferences_get_is_invisible), (string_array_is_valid), + (preferences_callback_entry_invoke_function), + (preferences_entry_invoke_callbacks), (update_auto_string), + (update_auto_string_array), (update_auto_integer_or_boolean), + (preferences_something_changed_notice), + (preferences_entry_ensure_mateconf_connection), + (preferences_entry_add_callback), + (preferences_entry_add_auto_storage), + (preferences_entry_remove_callback), + (preferences_entry_remove_auto_storage), + (preferences_callback_entry_free), + (preferences_callback_entry_free_func), (preferences_entry_free), + (preferences_global_table_lookup), + (preferences_global_table_insert), + (preferences_global_table_lookup_or_insert), + (preferences_set_emergency_fallback_stealing_value): + * eel/eel-wrap-table.c (eel_wrap_table_set_property), + (eel_wrap_table_get_property), (eel_wrap_table_size_request), + (eel_wrap_table_size_allocate), (eel_wrap_table_expose_event), + (eel_wrap_table_map), (eel_wrap_table_unmap), + (eel_wrap_table_realize), (eel_wrap_table_add), + (eel_wrap_table_remove), (eel_wrap_table_forall), + (wrap_table_get_num_fitting), (wrap_table_layout), + (wrap_table_irect_max_dimensions), + (wrap_table_get_max_child_dimensions), + (wrap_table_get_content_dimensions), + (wrap_table_get_content_bounds), (wrap_table_child_focus_in): + g_assert() in static functions instead of using + g_return(_val)_if_fail() (#320246). Thanks to Aaditya Sood. + +2008-03-28 Alexander Larsson + + * configure.in: + Post release version bump + +=== eel 2.22.1 === + +2008-03-28 Alexander Larsson + + * NEWS: + Update for release. + +2008-03-24 Christian Neumair + + * eel/eel-string.c (skip_argv), (custom1_skip), (custom2_skip): + Fix compiler warnings about unused value by casting va_arg + calls with unused return values to void (#523899). + +2008-03-11 Christian Neumair + + * eel/eel-background.c: (background_image_file_changed), + (eel_background_update_file_monitor), + (eel_background_set_image_uri_helper): Update EelBackground if the + image file changes. Fixes #106613. + +2008-03-11 Alexander Larsson + + * eel/eel-mount-operation.c: + (ask_question): + Don't pass in NULL as primary if there + is no newline in the message. + +2008-03-10 Alexander Larsson + + * configure.in (LIBGLADE_REQUIRED): + Post release version bump + +=== eel 2.22.0 === + +2008-03-10 Alexander Larsson + + * NEWS: + Update for release + + * configure.in (LIBGLADE_REQUIRED): + Bump version to 2.22.0 + +2008-02-25 Alexander Larsson + + * configure.in: + Post release version bump + +=== eel 2.21.92 === + +2008-02-25 Alexander Larsson + + * NEWS: + Update for release + +2008-02-22 Carlos Garcia Campos + + * eel/eel-mount-operation.c: (ask_question): + Use the first line of the question message as primary text for the + dialog so that it's formatted. + +2008-02-21 Cosimo Cecchi + + * eel/eel-background.c: (eel_background_ensure_realized): + Better fix for bug #517681. + +2008-02-21 Cosimo Cecchi + + * eel/eel-background.c: (eel_background_ensure_realized): + Fix compilation warning. (#517681) + Patch from Rodrigo Moya. + +2008-02-21 Cosimo Cecchi + + * eel-2.0-uninstalled.pc.in: + * eel-2.0.pc.in: + Update dependencies (#505831). + +2008-02-18 Alexander Larsson + + * eel/eel-mount-operation.c: + Handle the save-password flags (#516997) + Patch from Carlos Garcia Campos + +2008-02-13 Christian Persch + + * eel/eel-editable-label.c: + (eel_editable_label_select_region_index): Update text targets list. + Bug #516230. + +2008-02-13 Christian Persch + + * configure.in: + * eel/eel-string.c: (eel_strdup_vprintf_with_custom): Use G_VA_COPY. + Bug #516232. + +2008-02-13 Alexander Larsson + + * configure.in: + Check for va_copy and define a replacement if not availible (#513199) + Patch from Jens Granseuer + +2008-02-11 Alexander Larsson + + * configure.in: + Post release version bump + +=== eel 2.21.91 === + +2008-02-11 Alexander Larsson + + * NEWS: + Update for release + +2008-01-28 Alexander Larsson + + * configure.in: + Post release version bump + +=== eel 2.21.90 === + +2008-01-28 Alexander Larsson + + * NEWS: + Update for release + + * configure.in: + Bump version to 2.21.90 + +2008-01-28 Alexander Larsson + + * test/test-eel-image-table.c: + Use G_STRFUNC instead of deprecated G_GNUC_FUNCTION + +Fri Jan 25 14:08:11 2008 Søren Sandmann + + * eel/eel-background.c: Add #define MATE_DESKTOP_USE_UNSTABLE_API + before including mate-bg.h + + * eel/eel-background.c: Delete eel_background_set_is_constant_size(). + +2008-01-22 Alexander Larsson + + * eel/eel-string.c: + (eel_ref_str_unref): + Fix leak and tighten up a possible race + condition when a unique string is ressurected. + +2008-01-14 Alexander Larsson + + * configure.in (LIBGLADE_REQUIRED): + Post release version bump + +=== eel 2.21.5 === + +2008-01-14 Alexander Larsson + + * configure.in (LIBGLADE_REQUIRED): + Bump version to 2.21.5 + + * NEWS: + Updated for release + +2008-01-09 Alexander Larsson + + * eel/eel-mount-operation.c: + Update for gio API changes + +2007-12-20 Alexander Larsson + + * configure.in: + Post release version bump + +=== eel 2.21.1 === + +2007-12-20 Alexander Larsson + + * NEWS: + Update for release + + * configure.in: + Require glib 2.15.0 + +2007-12-20 Alexander Larsson + + * eel/eel-app-launch-context.c: + Update to new file attribute names + +2007-12-14 Alexander Larsson + + * eel/eel-mount-operation.c: + Update to new flag enum names and values + +2007-12-14 Alexander Larsson + + * eel/eel-app-launch-context.c: + * eel/eel-app-launch-context.h: + * eel/eel-background.c: + * eel/eel-gdk-pixbuf-extensions.c: + * eel/eel-gdk-pixbuf-extensions.h: + * eel/eel-mount-operation.h: + * eel/eel-vfs-extensions.c: + Only use include + +2007-12-13 Alexander Larsson + + * eel/eel-mount-operation.c: + (ask_password): + G_PASSWORD_FLAGS_ANON_SUPPORTED -> G_PASSWORD_FLAGS_ANONYMOUS_SUPPORTED + +2007-12-10 Alexander Larsson + + * eel/eel-app-launch-context.c (add_startup_timeout): + Correct set_data name + +2007-11-30 Alexander Larsson + + * configure.in (LIBGLADE_REQUIRED): + Bump version to 2.21.1 + Remove extraversion + +2007-11-29 Alexander Larsson + + * eel/eel-app-launch-context.c: + * eel/eel-vfs-extensions.c: + Update code to handle glib version of gio + +2007-11-22 Alexander Larsson + + * eel/eel-string.c (handlers): + Make handlers static + +2007-11-22 Alexander Larsson + + * eel/eel-string.[ch]: + Added eel_strdup_vprintf_with_custom and + eel_strdup_printf_with_custom + +2007-11-06 Alexander Larsson + + * eel/eel-mount-operation.c: + Fix build for new gio + +2007-11-06 Alexander Larsson + + * configure.in: + Look for libstartupnotify + + * eel/Makefile.am: + * eel/eel-app-launch-context.[ch]: + Add EelAppLaunchContext + +2007-11-02 Paolo Borelli + + * eel/eel-string.c: + * eel/eel-string.h: + Remove two functions that were just used in eel-string-list. + +2007-11-02 Paolo Borelli + + * eel/eel-preferences-glade.c: + * eel/eel-mateconf-extensions.c: + * eel/eel-preferences.c: + * eel/eel-preferences.h: + Introduce eel_preference_[get|set]_string_array and remove + all uses of eel-string-list. + + * eel/eel-enumerations.c: + * eel/eel-enumerations.h: + Simplify implementation and API and avoid use of eel-string-list. + + * eel/eel-string-list.c: + * eel/eel-string-list.h: + * eel/Makefile.am: + Remove eel-string-list.c + +2007-11-02 Alexander Larsson + + * eel/eel-string.c (eel_str_middle_truncate): + Fix off by one bug + +2007-11-01 Alexander Larsson + + * eel/eel-string.c: + Make eel_str_middle_truncate handle utf8 strings + correctly. + +2007-10-24 Alexander Larsson + + * eel/eel-mount-operation.[ch]: + Add active_changed signal + +2007-10-24 Alexander Larsson + + * eel/Makefile.am: + * eel/eel-mount-operation.[ch]: + Add GMountOperation version with gtk+ dialogs + +2007-10-24 Alexander Larsson + + * eel/eel-gdk-pixbuf-extensions.[ch]: + * eel/eel-background.c: + Convert mate_vfs use to gio + + * configure.in: + * eel/check-program.c: + * test/test-eel-background.c: + * test/test.[ch]: + Remove dependencies on mate-vfs, libmatedesktop, etc + +2007-10-24 Alexander Larsson + + * eel/eel-art-extensions.[ch]: + * eel/eel-enumeration.c: + * eel/eel-gdk-extensions.[ch]: + * eel/eel-glib-extensions.c: + * eel/eel-gtk-extensions.[ch]: + * eel/eel-pango-extensions.[ch]: + * eel/eel-self-checks.c: + * eel/eel-string-list.[ch]: + * eel/eel-string.[ch]: + Remove even more unused functions + +2007-10-24 Alexander Larsson + + * eel/eel-editable-label.c: + * eel/eelmarshal.list: + Remove unused marshallers + +2007-10-24 Alexander Larsson + + * eel/eel-art-extensions.[ch]: + * eel/eel-debug-drawing.c: + * eel/eel-gdk-extensions.[ch]: + * eel/eel-gdk-pixbuf-extensions.[ch]: + * eel/eel-glib-extensions.[ch]: + * eel/eel-lib-self-check-functions.h: + * test/Makefile.am: + * test/test-eel-gtk-style.c: Removed. + * test/test-eel-pixbuf-tile.c: Removed. + * test/test.c: + Remove unused functions + +2007-10-23 Alexander Larsson + + * configure.in: + * eel/eel-art-extensions.[ch]: + * eel/eel-art-gtk-extensions.[ch]: + * eel/eel-background.c: + * eel/eel-debug-drawing.[ch]: + * eel/eel-gdk-pixbuf-extensions.[ch]: + * eel/eel-mate-extensions.c: + * eel/eel-graphic-effects.c: + * eel/eel-gtk-container.[ch]: + * eel/eel-image-table.c: + * eel/eel-labeled-image.[ch]: + * eel/eel-self-checks.[ch]: + * eel/eel-wrap-table.c: + * test/test-eel-gtk-style.c: + * test/test-eel-pixbuf-tile.c: + * test/test.c: + Lift in the small amount of code and typedefs we + need from libart. Remove libart dependency. + +2007-10-23 Alexander Larsson + + * eel/Makefile.am: + * eel/eel-dateedit-extensions.[ch]: Removed. + * eel/eel-mate-extensions.[ch]: + * eel/eel.h: + Remove unneeded eel functions + +2007-10-23 Alexander Larsson + + * eel/eel-lib-self-check-functions.h: + * eel/eel-vfs-extensions.[ch]: + Remove a bunch of unnecessary mate-vfs functions + +2007-10-11 Alexander Larsson + + * eel/eel-gdk-pixbuf-extensions.[ch]: + Added eel_gdk_pixbuf_load_from_stream + +2007-10-01 Alexander Larsson + + * eel/Makefile.am: + * eel/eel-mime-application-chooser.[ch]: + * eel/eel-open-with-dialog.[ch]: + Move these to caja + +2007-10-01 Alexander Larsson + + * eel/eel-mime-application-chooser.c: + * eel/eel-open-with-dialog.c: + Port more stuff to gio mimetype code + + * eel/Makefile.am: + * eel/eel-mime-extensions.[ch]: + Remove unused code + +2007-10-01 Alexander Larsson + + * configure.in: + Pull in gio when linking + + * eel/eel-open-with-dialog.[ch]: + Update to use GAppInfo and gio APIs. + +2007-09-26 Alexander Larsson + + * eel/eel-string.h: + Fix up macro definition. + It can't have a space before the param list + +2007-09-26 Alexander Larsson + + * eel/eel-string.[ch]; + Add eel_ref_str, a set of refcounted and optionally uniquified + string functions. + +2007-09-26 Alexander Larsson + + * eel/eel-vfs-extensions.[ch]: + Remove more unused code + +2007-09-26 Alexander Larsson + + * eel/eel-vfs-extensions.c: + Remove code not used by caja anymore + +2007-11-28 Soren Sandmann + + * configure.in: Require libmatedesktop 2.21.3 + + * eel/eel-background.[ch]: Make EelBackground a thin wrapper + around MateBG from libmatedesktop. + +2007-10-12 Christian Kirbach + + * eel/eel-debug-drawing.c: + * eel/eel-debug-drawing.h: + (eel_debug_show_pixbuf): unconstify parameter 1 to + unbreak the build on gcc 4.2 + +2007-09-18 Alexander Larsson + + * configure.in: + Add gio as extraversion + + * eel/eel-gdk-pixbuf-extensions.c: + * eel/eel-vfs-extensions.[ch]: + Use goffset instead of MateVFSFileSize + +=== gio-branch starts here === + +2007-09-18 Alexander Larsson + + * configure.in: + Post release version bump + +=== eel 2.20.0 === + +2007-09-18 Alexander Larsson + + * NEWS: + * configure.in: + Bump version to 2.20.0 + +2007-08-14 Martin Wehner + + * configure.in: + Post release version bump + +=== eel 2.19.90 === + +2007-08-14 Martin Wehner + + * NEWS: + Update for release + +2007-07-31 Martin Wehner + + * configure.in: + Post release version bump + +=== eel 2.19.6 === + +2007-07-31 Martin Wehner + + * NEWS: + Update for release + +2007-07-28 Martin Wehner + + * eel/eel-open-with-dialog.c: (get_all_applications_from_dir): + Don't crash if a menu entry has no exec. Fixes #455949. + Patch from Pascal Terjan + +2007-07-10 Martin Wehner + + * configure.in: + Post release version bump + +=== eel 2.19.5 === + +2007-07-10 Martin Wehner + + * NEWS: + Update for release + +2007-07-10 Martin Wehner + + * configure.in: + Remove AC_ISC_POSIX: It would have to be called after AC_PROG_CC, + but Interactive Unix is obsolete. + Replace obsolete AC_STDC_HEADERS with AC_HEADER_STDC. + Remove AM_SANITY_CHECK: It's an internal macro that is called by + AM_INIT_AUTOMAKE anyway. + Remove unused AC_C_BIGENDIAN. + Remove redundant AC_PROG_AWK call. + +2007-06-23 Martin Wehner + + * eel/eel-glib-extensions.c: (eel_self_check_glib_extensions): + Set LC_TIME="C" before testing the output of eel_strdup_strftime + instead of having the translators to provide the expected results. + Fixes 'make check' when LC_TIME != LC_MESSAGES. (#348191) + +2007-06-21 Martin Wehner + + * configure.in: + Don't set both -Wsign-compare and -Wno-sign-compare. + Don't set -Wchar-subscripts as it's included in -Wall. + +2007-06-20 Martin Wehner + + * configure.in: + Don't set extra warning flags in the user environment CFLAGS. + Fixes 'make distcheck'. + +2007-06-19 Martin Wehner + + * configure.in: + Post release version bump + +=== eel 2.19.4 === + +2006-06-18 Martin Wehner + + * NEWS: + Update for release + +2007-06-12 Martin Wehner + + * eel/eel-mime-application-chooser.c: (set_uri_and_mime_type): + Clarify message by replacing "others" with "other files" in the + application chooser dialog. (#150559) + Patch from Björn Lindqvist + +2006-06-05 Martin Wehner + + * configure.in: + Post release version bump + +=== eel 2.19.3 === + +2006-06-05 Martin Wehner + + * NEWS: + Update for release + +2007-06-01 Christian Neumair + + * eel/eel-open-with-dialog.c: (eel_open_with_search_equal_func): Match + application display name and binary path/base path. Fixes #359912. + +=== eel 2.19.2 === + +2007-05-14 Alexander Larsson + + * configure.in: + * NEWS: + Update for 2.19.2 + +2007-04-10 Alexander Larsson + + * eel/eel-mateconf-extensions.c: + (eel_mateconf_monitor_add): + (eel_mateconf_monitor_remove): + (eel_mateconf_preload_cache): + Avoid leaked refcounts on default mateconf client. (#235657) + Patch from Matthias Clasen + +2007-03-19 Alexander Larsson + + * configure.in: + Bump version to 2.19.1 + Mate 2.18 work continues on mate-2-18 branch + +2007-03-12 Alexander Larsson + + * NEWS: + Update for release + + * eel/eel-gtk-extensions.c (eel_gtk_window_set_initial_geometry): + Fix crasher due to bug sparse cleanup. + +2007-03-12 Alexander Larsson + + * configure.in: + Post release version bump + +=== eel 2.18.0 === + +2007-03-12 Alexander Larsson + + * NEWS: + Update for release + + * configure.in: + Bump version to 2.18.0 + +2007-03-02 Alexander Larsson + + * eel/eel-background.c: + * eel/eel-canvas.c: + * eel/eel-enumeration.c: + * eel/eel-gtk-extensions.c: + * eel/eel-image-table.c: + * eel/eel-labeled-image.c: + Sparse cleanups from kjartan + +2007-02-20 Christian Persch + + * eel/eel.h: Remove eel-ellipsizing-label.h inclusion. + +2007-02-20 Christian Persch + + * eel/Makefile.am: + R eel/eel-ellipsizing-label.c: + R eel/eel-ellipsizing-label.h: + * test/Makefile.am: + R test/test-eel-ellipsizing.c: Remove EelEllipsisingLabel. Bug + #409272. + +2007-02-20 Christian Persch + + * eel/Makefile.am: + * eel/eel-editable-label.c: + (eel_editable_label_select_region_index): + * eel/eel-ellipsizing-label.c: + * eel/eel-ellipsizing-label.h: + * eel/eel-string.c: (eel_self_check_string), (main): + * test/Makefile.am: + * test/test-eel-ellipsizing.c: + +2007-01-22 Alexander Larsson + + * configure.in: + Post release version bump + +=== eel 2.17.90 === + +2007-01-22 Alexander Larsson + + * NEWS: + * configure.in: + Bump to 2.17.90 + +2007-01-18 Christian Persch + + * eel/eel-accessibility.c: (eel_accessibility_add_simple_text), + (eel_accessible_text_get_type): + * eel/eel-alert-dialog.c: (eel_alert_dialog_get_type): + * eel/eel-canvas.c: (eel_canvas_item_get_type), + (eel_canvas_group_get_type), (eel_canvas_get_type), + (eel_canvas_accessible_factory_get_type), + (eel_canvas_item_accessible_get_type), + (eel_canvas_item_accessible_factory_get_type): + * eel/eel-editable-label.c: (eel_editable_label_get_type), + (eel_editable_label_get_accessible): + * eel/eel-labeled-image.c: (eel_labeled_image_get_accessible): + * eel/eel-mime-application-chooser.c: + (eel_mime_application_chooser_get_type): + * eel/eel-open-with-dialog.c: (eel_open_with_dialog_get_type): No need + to make GTypeInfo and GInterfaceInfo static. Bug #362031. + +2006-12-18 Alexander Larsson + + * configure.in: + post release version bump + +=== eel 2.17.1 === + +2006-12-18 Alexander Larsson + + * NEWS: + Update for release + +2006-12-08 Alexander Larsson + + * eel/eel-gdk-pixbuf-extensions.c: (eel_gdk_pixbuf_intersect): + * eel/eel-gdk-pixbuf-extensions.h: + * eel/eel-gtk-extensions.c: (eel_gtk_get_system_font): + * eel/eel-gtk-extensions.h: + * eel/eel-pango-extensions.c: + * eel/eel-pango-extensions.h: + Remove all traces of pangoft2 use, as we don't need this + any more. (#377711) + +2006-11-23 Alexander Larsson + + * eel/eel-open-with-dialog.c: (get_all_applications_from_dir): + Only list appliations that accept file arguments (#345521) + Patch from Tom Parker + +2006-11-23 Alexander Larsson + + * configure.in: + Bump version to 2.17.1 + Mate 2.16 work continues on mate-2-16 branch + +2006-11-20 Alexander Larsson + + * configure.in: + Post release version bump + +=== eel 2.16.3 === + +2006-11-20 Alexander Larsson + + * configure.in: + Call it 2.16.3 to match caja release + + * NEWS: + Update for release. + +2006-11-07 Alexander Larsson + + * configure.in: + post release version bump + +=== eel 2.16.1 === + +2006-11-07 Alexander Larsson + + * configure.in: + * NEWS: + Update for release. + +2006-10-19 Christian Neumair + + * eel/eel-preferences.c: + (preferences_callback_entry_compare), + (preferences_entry_add_callback), + (preferences_entry_add_auto_storage), + (preferences_entry_remove_callback), + (preferences_uninitialize), + (preferences_global_table_get_global), + (preferences_while_alive_disconnector): + Bail when trying to add or remove an entry twice, skip entry removal + on object destroy disconnection after eel shutdown. + +=== eel 2.16.0 === + +2006-09-04 Alexander Larsson + + * configure.in: + Bump version to 2.16.0 + + * NEWS: + Update for release + +2006-09-01 Alexander Larsson + + * eel/eel-editable-label.c: (eel_editable_label_enter_text): + Don't reset im context when commiting text. + +2006-08-25 Alexander Larsson + + * eel/check-program.c: (main): + Fix build with EEL_OMIT_SELF_CHECK. + +2006-08-23 Alexander Larsson + + * eel/eel-vfs-extensions.c: (eel_vfs_has_capability): + Fix crash that happened on DnD from firefox in caja. + +2006-08-21 Alexander Larsson + + * configure.in: + Post release version bump + +=== eel 2.15.92 === + +2006-08-21 Alexander Larsson + + * NEWS: + Update for release + +2006-08-15 Kjartan Maraas + + * configure.in: Fix intltool req. + +2006-08-08 Alexander Larsson + + * configure.in: + Post release version bump. + +=== eel 2.15.91 === + +2006-08-08 Alexander Larsson + + * NEWS: + Update for release + +2006-08-08 Kjartan Maraas + + * configure.in: Really depend on a newer libmate-menu. + * eel/eel-string-list.c: (eel_self_check_string_list): + * test/test-eel-gtk-style.c: (style_get_color), (style_get_gc), + (color_box_expose_event), (gc_box_expose_event), + (pixmap_box_expose_event): + * test/test-eel-image-table.c: (image_table_child_enter_callback), + (image_table_child_leave_callback): + * test/test-eel-pixbuf-tile.c: Remove and #if 0 out some dead code. + +2006-08-08 Alexander Larsson + + * eel/eel-background.c: + Fix crash in previous fix. + +2006-08-08 Alexander Larsson + + * eel/eel-background.c: + Check mtime for background uri changes. (#349962) + Patch from Matthias Clasen + +2006-07-25 Martin Wehner + + * configure.in: + Post-release version bump + +=== eel 2.15.90 === + +2006-07-25 Martin Wehner + + * NEWS: + Update for release + +2006-07-24 Martin Wehner + + * eel/eel-mime-application-chooser.c: (refresh_model), + (set_uri_and_mime_type): + * eel/eel-open-with-dialog.c: (set_uri_and_mime_type): + Fix build with gcc 2.95 (#347552) + + Patch from Jens Granseuer + +2006-07-11 Martin Wehner + + * configure.in: + Post-release version bump + +=== eel 2.15.4 === + +2006-07-11 Martin Wehner + + * NEWS: + Update for release + + * configure.in: + Bump version to 2.15.4 + +2006-07-11 Martin Wehner + + * eel/eel-open-with-dialog.c: (compare_applications), + (eel_open_with_dialog_add_items_idle): + Handle entry name == NULL without crashing. (#339904) + + Based on a patch from Miguel Quiros + +2006-07-11 Martin Wehner + + * eel/eel-accessibility.c: + (eel_accessibility_set_up_label_widget_relation): + Set up the atk widget/label relationship correctly. (#341420) + + Patch from Willie Walker + +2006-06-19 Alexander Larsson + + * configure.in: + Require new gtk+ + + * eel/eel-mime-application-chooser.c: + word+char wrap label to avoid wide dialogs on large filenames. + Fixes bug #344958 + +2006-06-12 Alexander Larsson + + * configure.in: + post release version bump + +=== eel 2.15.2 === + +2006-06-12 Alexander Larsson + + * NEWS: + Update for release + +2006-05-24 Paolo Borelli + + * eel/eel-gtk-extensions.[ch]: remove eel_gtk_signal_connect_free_data + and eel_gtk_signal_connect_free_data_custom, since there is + g_signal_connect_data. + +2006-05-24 Alexander Larsson + + * eel/Makefile.am: + * eel/eel-cell-renderer-pixbuf-list.[ch]: + Remove + +2006-05-24 Paolo Borelli + + * eel/eel-vfs-extensions.[ch]: remove eel_make_uri_from_input, + eel_make_uri_from_input_with_trailing_ws, eel_make_uri_from_shell_arg, + eel_uris_match, eel_uri_get_scheme, eel_uri_make_full_from_relative. + They have been moved into mate-vfs itself for a long time and they + are not used anymore in caja. (bug #342237) + +2006-05-16 Martin Wehner + + * configure.in: + Post-release version bump. + +=== eel 2.15.1 === + +2006-05-16 Martin Wehner + + * NEWS: + Update for release + +2006-05-07 Martin Wehner + + * eel/eel-glib-extensions.c: + * eel/eel-glib-extensions.h: + Remove obsolete eel_setenv and eel_unsetenv functions. + + * eel/eel-gtk-extensions.c: (eel_gtk_widget_set_shown): + * eel/eel-gtk-extensions.h: + Remove unused and obsolete eel_gtk_button_* functions (#170126) + +2006-05-07 Martin Wehner + + * eel/eel-mime-extensions.c: (eel_mime_get_available_mime_types): + * eel/eel-mime-extensions.h: + Fix typo in function name: s/availible/available/ (#326053) + + Patch from Josep Puigdemont + +2006-05-01 Martin Wehner + + * eel/eel-mime-application-chooser.c: (refresh_model), + (set_uri_and_mime_type): + * eel/eel-open-with-dialog.c: (set_uri_and_mime_type): + Don't include surrounding markup in translateable messages. + Fixes #150555. + + Patch from Ruben Vermeersch + +2006-04-28 Martin Wehner + + * configure.in: + * po/LINGUAS: + Update po/LINGUAS support to new guidelines. (#338017) + + Patch from Przemyslaw Grzegorczyk + +2006-04-25 Alexander Larsson + + * configure.in: + Bump version to 2.15.1 + 2.14 development continues on mate-2-14 branch. + +2006-04-15 Martin Wehner + + * po/LINGUAS: + Remove newlines to fix build with CVS intltool. (#338423) + +2006-04-11 Martin Wehner + + * configure.in: + Post-release version bump. + +=== eel 2.14.1 === + +2006-04-11 Martin Wehner + + * NEWS: + Update for release + +2006-04-10 Martin Wehner + + * Makefile.am: Add intltool artefacts. + + * po/LINGUAS: New file listing all supported languages. + + * configure.in: Require intltool and use po/LINGUAS instead of including + all languages directly in this file. See the wiki for more information: + http://live.gnome.org/MateGoals/PoLinguas + + Patch from Przemyslaw Grzegorczyk + +2006-04-08 Martin Wehner + + * configure.in: + Don't check for *env functions anymore. + + * eel/eel-glib-extensions.c: (eel_setenv), (eel_unsetenv): + Just call g_setenv and g_unsetenv. Fixes build on Darwin (#166880). + + Patch from Tony Arnold + +2006-03-26 Sebastien Bacher + + * configure.in: popt is not used by eel no need to require it + +2006-03-22 Tommi Vainikainen + + * configure.in (ALL_LINGUAS): Added Dzongkha (dz). + +2006-03-22 Paolo Borelli + + * eel/eel-enumeration.c: remove inefficient use of glist. + Fixes bug #335349. + +2006-03-20 Christian Neumair + + * configure.in: + Depend on libmate-menu 2.13.5. + * eel/eel-open-with-dialog.c: (get_all_applications): + Also request desktop items which have NoDisplay set to TRUE. + +2006-03-13 Alexander Larsson + + * configure.in: + Post release version bump + +=== eel 2.14.0 === + +2006-03-13 Alexander Larsson + + * configure.in: + Bump version to 2.14.0 + + * NEWS: + Update for release + +2006-03-01 Vladimer SIchinava + + * configure.in: Added ka (Georgian) to ALL_LINGUAS + +2006-02-28 Bill Haneman + + * eel/eel-labeled-image.c: + (eel_labeled_image_accessible_get_name): Fixed + segv due to use of labeled_image struct without NULL check. + bug #330995. + +2006-02-27 Alexander Larsson + + * configure.in: + Post release version bump + +=== eel 2.13.92 === + +2006-02-27 Alexander Larsson + + * NEWS: + Update for release + +2006-02-19 Erdal Ronahi + + * configure.in: Added ku (Kurdish) to ALL_LINGUAS + +2006-02-16 Martin Wehner + + * eel/eel-editable-label.c: + Include config.h to fix i18n of the context menu. + Fixes bug #331377. + Patch from Takao Fujiwara + +2006-02-16 Martin Wehner + + * test/test.c: (test_window_set_title_with_pid): + Add a cast to fix build on Solaris. (#117825) + Patch from Fredrik Jonsson + +2006-02-13 Alexander Larsson + + * configure.in: + Post release version bump + +=== eel 2.13.91 === + +2006-02-13 Alexander Larsson + + * NEWS: + Update for release. + +2006-02-07 Alexander Larsson + + * eel/eel-mime-extensions.c (eel_mime_add_application): + Add %f to exec line when creating open-with desktop files. + Patch from Christian Persch + Bug #169202 + +2006-01-31 Martin Wehner + + * configure.in: + Post release version bump. + +=== eel 2.13.90 === + +2006-01-31 Martin Wehner + + * NEWS: + Update for release. + + * configure.in: + Bump version to 2.13.90 + +2006-01-21 Luca Ferretti + + * .cvsignore: + Added missing files to ignore. + * eel/.cvsignore: + Ditto. + +2006-01-16 Alexander Larsson + + * configure.in: + Post release version bump. + +=== eel 2.13.4 === + +2006-01-16 Alexander Larsson + + * NEWS: + Update for release. + +2006-01-12 Alexander Larsson + + * eel/eel-background.[ch]: + Add EEL_BACKGROUND_ZOOM + + * eel/eel-gdk-pixbuf-extensions.[ch]: + Add eel_gdk_scale_to_min_factor and eel_gdk_pixbuf_scale_to_min + + Patch by Alan Swanson (#320830) + +2005-12-28 Abel Cheung + + * configure.in: Added "zh_HK" to ALL_LINGUAS. + +2005-12-20 Alexander Larsson + + * configure.in: + Actuallu bump version. + +2005-12-20 Alexander Larsson + + * eel/eel-mime-extensions.[ch]: + Add eel_mime_get_availible_mime_types + +2005-12-17 Dennis Cranston + + * eel/eel-alert-dialog.c: Hide dialog from taskbar, so it + does not display "untitled window". + +2005-12-13 Dennis Cranston + + * eel/eel-open-with-dialog.c: (eel_open_with_dialog_instance_init): + HIG fixes. + +2005-12-12 Alexander Larsson + + * configure.in: + Post release version bump. + +=== eel 2.13.3 === + +2005-12-12 Alexander Larsson + + * NEWS: + Update for release + +2005-12-09 Alexander Larsson + + * eel/eel-alert-dialog.[ch]: + * eel/eel-mateconf-extensions.c: + * eel/eel-mate-extensions.c: + * eel/eel-open-with-dialog.c: + * eel/eel-stock-dialogs.[ch]: + Remove title from alerts. (#323134) + + Patch from jaap@haitsma.org + +2005-12-08 Alexander Larsson + + * eel/eel-preferences-glade.[ch]: + Use GtkComboBox, not GtkOptionMenu + Patch from jaap@haitsma.org + +2005-11-14 Alexander Larsson + + * configure.in: + Post release version bump. + +=== eel 2.13.2 === + +2005-11-14 Alexander Larsson + + * NEWS: + Update for release. + +2005-11-14 Alexander Larsson + + * eel/eel-alert-dialog.c: + Include config.h so we get translations. + Patch from Yang Hong + +2005-10-28 Simos Xenitellis + + * configure.in: Added ky (Kirghiz) to ALL_LINGUAS. + +2005-10-27 Kjartan Maraas + + * eel/eel-art-gtk-extensions.c: + (eel_gdk_window_clip_dirty_area_to_screen): + * eel/eel-background.c: (eel_background_class_init): + * eel/eel-canvas.c: (item_post_create_setup), + (eel_canvas_group_get_property), (pick_current_item): + * eel/eel-editable-label.c: (eel_editable_label_ensure_layout), + (eel_editable_label_size_allocate), (eel_editable_label_map), + (eel_editable_label_unmap), (window_to_layout_coords), + (eel_editable_label_button_release), + (eel_editable_label_move_line), + (eel_editable_label_move_backward_word): + * eel/eel-ellipsizing-label.c: (real_expose_event): + * eel/eel-mateconf-extensions.c: (simple_value_is_equal): + * eel/eel-gdk-pixbuf-extensions.c: (eel_gdk_pixbuf_average_value): + * eel/eel-image-table.c: (eel_image_table_realize), + (image_table_emit_signal): + * eel/eel-mime-application-chooser.c: + (eel_mime_application_chooser_destroy): + * eel/eel-open-with-dialog.c: (eel_open_with_dialog_destroy): + * eel/eel-pango-extensions.c: + (eel_pango_layout_set_text_ellipsized): + * eel/eel-stock-dialogs.c: (timed_wait_free): Large amounts of + cleanups. Mostly removal of unused code and some compiler warnings. + +2005-10-24 Alexander Larsson + + * configure.in: + Post release version bump. + +=== eel 2.13.1 === + +2005-10-24 Alexander Larsson + + * NEWS: + Update for release + +2005-10-19 Christian Neumair + + * eel/eel-mime-application-chooser.c: (create_tree_view): + Sort applications by display name, filed as part of #310038. + +2005-10-03 Alexander Larsson + + * configure.in: + Bump version to 2.13.1. Further 2.12.x work is on + mate-2-12 branch. + +2005-10-03 Alexander Larsson + + * configure.in: + Post release version bump. + +=== eel 2.12.1 === + +2005-10-03 Alexander Larsson + + * NEWS: + Update for 2.12.1. + +2005-10-03 Alexander Larsson + + * eel/eel-accessibility.c: + (eel_accessibility_set_up_label_widget_relation): + Slight cleanup. Patch from Christian Neumair. + +2005-09-05 Alexander Larsson + + * configure.in: + Post release version bump + +=== eel 2.12.0 === + +2005-09-05 Alexander Larsson + + * NEWS: Update for release. + +2005-08-23 Martin Wehner + + * configure.in: + Post release version bump. + +=== eel 2.11.92 === + +2005-08-23 Martin Wehner + + * NEWS: + Update for release. + +2005-08-09 Martin Wehner + + * configure.in: + Post release version bump. + +=== eel 2.11.91 === + +2005-08-09 Martin Wehner + + * NEWS: + Update for release. + +2005-08-05 Christian Neumair + + * src/eel-wrap-table.c: Get rid of broken scrolled window viewport + code. Fixes #308996. + +2005-08-01 Christian Persch + + * eel/eel-debug.c: + (eel_make_warnings_and_criticals_stop_in_debugger): + Use g_log_set_default_handler instead of adding handlers for + tons of domains (#312268). + +2005-07-25 Martin Wehner + + * configure.in: + Post release version bump. + +=== eel 2.11.90 === + +2005-07-25 Martin Wehner + + * configure.in: + Bump version to 2.11.90 + + * NEWS: + Update for release. + +2005-07-20 Mikael Hallendal + + * eel/eel-vfs-extensions.[ch] (eel_uri_is_search): + Add x-caja-search URI. + +2005-07-19 Alexander Larsson + + * eel/eel-mime-application-chooser.c: (set_uri_and_mime_type): + * eel/eel-open-with-dialog.c: (set_uri_and_mime_type): + Add comments for translators. (#150558) + + Patch from Brent Smith + +2005-07-13 Alexander Larsson + + * eel/eel-wrap-table.c: + Take border width into account when wrapping (#155642) + Patch from Christian Neumair. + +2005-07-11 Alexander Larsson + + * configure.in: + Post release version bump + +=== eel 2.11.4 === + +2005-07-11 Alexander Larsson + + * NEWS: + Update for release. + +2005-07-06 Kjartan Maraas + + * eel/eel-open-with-dialog.c: (add_or_find_application): + Fix a small leak. + +2005-07-01 Alexander Larsson + + * configure.in: + Post release version bump + +=== eel 2.11.3 === + +2005-07-01 Alexander Larsson + + * NEWS: + Update for release. + +2005-06-11 Kjartan Maraas + + * eel/eel-mime-application-chooser.c: (remove_clicked_cb): Remove + const qualifier now that we free the application id. + +2005-06-11 Kjartan Maraas + + * eel/eel-mime-application-chooser.c: + (eel_mime_application_chooser_finalize), (remove_clicked_cb): + Plug some leaks. + * eel/eel-open-with-dialog.c: (check_application): Here too. + Closes bug #307268 and bug #307280 + +2005-06-10 Martin Wehner + + * eel/eel-labeled-image.c: (labeled_image_get_image_bounds_fill), + (eel_labeled_image_get_image_bounds), + (labeled_image_get_label_bounds_fill), + (eel_labeled_image_get_label_bounds): + Add default cases with asserts. + + * eel/eel-mime-extensions.c: (open_temp_cache_file): + Initialize filename in error case. + + * eel/eel-open-with-dialog.c: (eel_open_with_dialog_add_icon_idle): + * eel/eel-preferences.c: (preferences_entry_remove_auto_storage): + Use NULL instead of 0. + + * configure.in: + Add --Wno-pointer-sign + + Fix gcc4 compilation (#300646). Based on patches from + Kjartan Maraas and + James M. Cape + +2005-06-08 Alexander Larsson + + * configure.in (LIBGLADE_REQUIRED): + Post release version bump. + +=== eel 2.11.2 === + +2005-06-08 Alexander Larsson + + * eel/eel-open-with-dialog.c: + Fix const warning. + + * NEWS: + Update for release. + +2005-06-07 Kjartan Maraas + + * eel/eel-open-with-dialog.c: (program_list_selection_changed): + Plug a couple of leaks. Closes bug #306767. + +2005-05-22 Sebastien Bacher + + * configure.in: + Update of glib and gtk requirements to 2.6.0 (Closes: #304875). + +2005-05-17 Alexander Larsson + + * configure.in: + Post release version bump. + +=== eel 2.11.1 === + +2005-05-17 Alexander Larsson + + * NEWS: + Update for 2.11.1 release + +2005-04-12 Alexander Larsson + + * eel-2.0.pc.in: + * eel-2.0-uninstalled.pc.in: + Use gmodule-no-export-2.0 instead of gmodule-2.0 to avoid using --export-dynamic. + +2005-04-11 Mark McLoughlin + + * eel/Makefile.am, eel/eel-open-with-dialog.c: update + for libmate-menu API renaming. + +2005-04-11 Abduxukur Abdurixit + + * configure.in: Added 'ug' to ALL_LINGUAS. + +2005-04-08 Sebastien Bacher + + * configure.in: + Update matevfs requirement to 2.9.1. + +2005-04-06 Mark McLoughlin + + * eel/eel-open-with-dialog.c: (get_all_applications): + Update for slight change in menu_tree_lookup() API. + +2005-03-31 Steve Murphy + + * configure.in: Added "rw" to ALL_LINGUAS. + +2005-03-28 Martin Wehner + + * eel/eel-accessibility.c: (get_simple_text): + Return NULL if the gobject is no longer valid. + Fixes bug #168161. + + Patch from Muktha + +2005-03-27 Martin Wehner + + * configure.in: + Require libmate-menu 2.11.1 for the new API. + + * eel/eel-open-with-dialog.c: (get_all_applications_from_dir), + (get_all_applications), (eel_open_with_dialog_add_items_idle): + Update to the new libmate-menu API. + + Patch from Christian Neumair + +2005-03-24 Adi Attar + + * configure.in: Added 'xh' to ALL_LINGUAS. + +2005-03-22 Alexander Larsson + + * configure.in: + Bump version to 2.11.1 + Mate 2.10 versions are now on the mate-2-10 branch. + +2005-03-16 Alexander Larsson + + * eel/eel-background.[ch]: + Move desktop background setting here to be able to share + pixmap with root window. (#169347) + + Patch from Nickolay V. Shmyrev + +2005-03-07 Alexander Larsson + + * eel/eel-mime-extensions.c: (eel_mime_add_application): + Make sure user added desktop files don't conflict with global ones. + Patch from Christian Persch + +2005-03-07 Alexander Larsson + + * configure.in: + Post release version bump + +=== eel 2.10.0 === + +2005-03-07 Alexander Larsson + + * NEWS: + * configure.in: + Update for 2.10 release + +2005-03-01 Alexander Larsson + + * configure.in (LIBGLADE_REQUIRED): + Post release version bump + +=== eel 2.9.92 === + +2005-03-01 Alexander Larsson + + * NEWS: + Update for release + +2005-03-01 James Henstridge + + Fixes bug #164796 (approved by Alex) + + * autogen.sh: request Automake >= 1.7. + + * eel/eel-gdk-extensions.h (EEL_RGBA_COLOR_PACK): add casts to + guint32. Fixes test failures on 64-bit systems. + +2005-02-24 Alexander Larsson + + * eel/eel-vfs-extensions.c (eel_read_entire_file): + Just use mate_vfs_read_entire_file(). + We should remove this function eventually. + +2005-02-11 Alexander Larsson + + * eel/eel-mime-application-chooser.c (refresh_model): + Handle the case with no existing applications better. + +2005-02-10 Alexander Larsson + + * configure.in (LIBGLADE_REQUIRED): + Post release version bump. + +=== eel 2.9.91 === + +2005-02-10 Alexander Larsson + + * NEWS: + Update for release. + +2005-01-26 Alexander Larsson + + * eel/eel-open-with-dialog.c (eel_open_with_dialog_finalize): + Remove idle handlers when closing window. (#165208) + +2005-01-25 Alexander Larsson + + * configure.in: + Post release version bump + +=== eel 2.9.90 === + +2005-01-25 Alexander Larsson + + * NEWS: + Update for release + + * configure.in: + Bump version to 2.9.90 + +2005-01-25 Alexander Larsson + + * eel/eel-open-with-dialog.c (eel_open_with_dialog_add_icon_idle): + Don't crash if no icon . + +2005-01-24 Kjartan Maraas + + * eel/eel-accessibility.c: (eel_accessible_text_get_type): + * eel/eel-editable-label.c: + (eel_editable_label_accessible_get_selection): + * eel/eel-gdk-extensions.c: (eel_stipple_bitmap): + * eel/eel-gtk-extensions.c: + (eel_gtk_tree_view_set_activate_on_single_click): + * eel/eel-preferences.c: (preferences_get_value), + (eel_preferences_get), (eel_preferences_get_string_list): + * eel/eel-stock-dialogs.c: (eel_show_yes_no_dialog): + * eel/eel-string-list.c: (eel_string_list_find_by_function): + * eel/eel-wrap-table.c: Fix a bunch of warnings from sparse. + +2005-01-24 Alexander Larsson + + * eel/eel-open-with-dialog.c: (eel_open_with_dialog_instance_init): + Mark string for translation. + Patch from Yang Hong + +2005-01-23 Martin Wehner + + * eel/eel-mime-application-chooser.c: (create_tree_view), + (refresh_model): Show application icon in the selector. + + Patch from Fernando Herrera + +2005-01-21 Alexander Larsson + + * configure.in: + * eel/Makefile.am: + require libmate-desktop and libmate-menu + + * eel/eel-mime-extensions.[ch]: + (eel_mime_add_custom_mime_type_for_desktop_file), + (eel_mime_check_for_desktop_duplicates): + New function to check for duplicate desktop files handling a mimetype + and to add custom mime types for desktop files. + + * eel/eel-open-with-dialog.c: + Show know applications from .desktop files and move + the entry to an expander to specify a custom app/command line. + + Patch from Fernando Herrera + +2005-01-13 Alexander Larsson + + * eel/eel-alert-dialog.c (eel_alert_dialog_set_primary_label): + Escape the text put in the markup string. + +2005-01-11 Alexander Larsson + + * configure.in: + Post release version bump. + +=== eel 2.9.2 === + +2005-01-11 Alexander Larsson + + * NEWS: + Update for release. + +2004-11-25 Marco Pesenti Gritti + + reviewed by: Alexander Larsson + + * eel/eel-mime-application-chooser.c: (refresh_model): + * eel/eel-mime-extensions.c: (eel_mime_add_application), + (eel_mime_check_for_duplicates): + + Replcae usage of deprecate mime apis + +2004-11-24 Alexander Larsson + + * configure.in: + Post release bump + +=== eel 2.9.1 === + +2004-11-24 Alexander Larsson + + * NEWS: + Update for release + +2004-11-19 Alexander Larsson + + * eel/eelmarshal.list: + Add some new needed marshallers. + +2004-10-29 Alexander Larsson + + * configure.in: + Update version to 2.9.1. + Mate 2.8 versions are now on the mate-2-8 branch. + +==== mate-2-8 branched from here === + +2004-10-28 Alexander Larsson + + * configure.in: + Post release bump + +=== eel 2.8.2 === + +2004-10-28 Alexander Larsson + + * NEWS: + Update for release + +2004-10-28 Alexander Larsson + + * eel/eel-glib-extensions.[ch]: + New function, eel_get_filename_charset. + + * eel/eel-vfs-extensions.c: + Use eel_get_filename_charset to handle filename charset. + +2004-10-21 Alexander Larsson + + * eel/eel-canvas.c: (eel_canvas_group_draw), (eel_canvas_expose): + Update to latest foocanvas, fix expose returning TRUE. + +2004-10-15 Alexander Larsson + + * eel/eel-mime-extensions.c: (eel_mime_add_application), + (eel_mime_check_for_duplicates): + Handle null mimetypes (required for property page if + file has no extension). + +2004-10-11 Alexander Larsson + + * configure.in: + Post release version bump + +=== eel 2.8.1 === + +2004-10-11 Alexander Larsson + + * NEWS: + Update for 2.8.1 + +2004-09-28 Gora Mohanty + + * configure.in: Added 'or' to ALL_LINGUAS. + +2004-09-13 Alexander Larsson + + * configure.in: + Post release version bump. + +=== eel 2.8.0 === + +2004-09-13 Alexander Larsson + + * NEWS: + * configure.in: + Update for 2.8.0 + +2004-09-11 Abel Cheung + + * configure.in: Added "ang" to ALL_LINGUAS. + +2004-09-06 Alexander Larsson + + * eel/eel-mime-extensions.c: (eel_mime_set_default_application): + Create ~/.local/share/applications as needed. + +2004-08-31 Alexander Larsson + + * eel/eel-mime-application-chooser.c: + (mime_monitor_data_changed_cb): + Refresh model when mime db changes + + * eel/eel-mime-extensions.c: (mime_update_program_done): + Remove spew + +2004-08-30 Alexander Larsson + + * configure.in: + Post release version bump + +=== eel 2.7.92 === + +2004-08-30 Alexander Larsson + + * NEWS: + Update for 2.7.92 + + * configure.in: + Require new libmateui + +2004-08-25 Alexander Larsson + + * eel/eel-stock-dialogs.c (timed_wait_callback): + Don't pop up cancel dialog if password dialog is visible. + +2004-08-16 Kjartan Maraas + + * configure.in: Added nb to ALL_LINGUAS. + +2004-08-16 Alexander Larsson + + * configure.in: + Post release bump to 2.7.92 + +=== eel 2.7.4 === + +2004-08-16 Alexander Larsson + + * NEWS: + Update for 2.7.4 + + * eel/eel-canvas.c: + Update from foocanvas. + + * configure.in: + Require new mate-vfs (for default application file + type change). + +2004-08-12 Alexander Larsson + + * eel/eel-canvas-rect-ellipse.c: + * eel/eel-canvas.c: (eel_canvas_key): + Update to latest foocanvas. + +2004-08-12 Alexander Larsson + + * eel/eel-mime-extensions.c (eel_mime_set_default_application): + Use new name for default.list toplevel section. + +2004-08-09 Ray Strode + + * eel/eel-mime-extensions.c (eel_mime_add_application), + (eel_mime_set_default_application): free strings + when done with them (Spotted by Kjartan Maraas, bug 149718). + +2004-07-23 Christian Neumair + + * eel/eel-mime-application-chooser.c: + * eel/eel-open-with-dialog.c: Include gi18n-lib.h instead of gi18n.h. + +2004-07-23 Christian Neumair + + * configure.in: Require MATE-VFS 2.7.5 (HEAD). + +2004-07-23 Tomasz Kłoczko + + * configure.in: better looking PKG_CHECK_MODULES() output. + +2004-07-22 Dave Camp + + * configure.in: Post-release version bump + +=== eel 2.7.3 === + +2004-07-22 Dave Camp + + * configure.in: + * NEWS: 2.7.3 + +2004-07-21 Dave Camp + + * Merged the eel-new-mime branch. + +2004-07-21 Dave Camp + + * configure.in: + * eel/Makefile.am: + * eel/eel-mime-extensions.c: (write_desktop_file), + (mime_update_program_done), (eel_mime_add_glob_type), + (open_temp_cache_file), (line_is_for_mime_type), + (eel_mime_set_default_application), + (eel_mime_application_is_user_owned), + (eel_mime_application_remove): + * eel/eel-mime-extensions.h: + * eel/eel-mime-application-chooser.c: + * eel/eel-mime-application-chooser.h: + * eel/eel-open-with-dialog.c: (eel_open_with_dialog_instance_init), + (eel_open_with_dialog_new), (eel_add_application_dialog_new): + * eel/eel-open-with-dialog.h: Add the eel-mime-application-chooser + dialog. + +Wed Jul 21 18:30:25 2004 Jonathan Blandford + + * eel/eel-mime-extensions.c: (arg_is_exec_param), + (eel_mime_check_for_duplicates): Make fit eel coding guidelines. + + * eel/eel-open-with-dialog.c (get_run_dialog_image): Get the image + from stock. + (eel_open_with_dialog_instance_init): Use the panel mate-run + stock image. + +Wed Jul 21 02:54:32 2004 Jonathan Blandford + + * eel/eel-mime-extensions.h: New public function: + eel_mime_check_for_duplicates() + + * eel/eel-mime-extensions.c: (mime_update_program_done), + (run_update_command), (eel_mime_add_application), + (eel_mime_add_glob_type), (arg_is_exec_param), + (eel_mime_check_for_duplicates): New function that will check a + command line to see if another application with that name already + exists. Also, the post-mime-update stuff has been modified + slightly. + + * eel/eel-open-with-dialog.c: (eel_open_with_dialog_finalize), + (eel_open_with_dialog_destroy), (check_application), + (get_app_name), (add_or_find_application), (response_cb), + (eel_open_with_dialog_class_init), (chooser_response_cb), + (browse_clicked_cb), (entry_changed_cb), + (eel_open_with_dialog_instance_init), (get_extension), + (set_uri_and_mime_type), (eel_open_with_dialog_get_type): Some + whitespace 'cleanups'. Dialog packing cleanup and behavior + changes. Better error handling is included as well. + +Mon Jul 19 22:10:59 2004 Jonathan Blandford + + * eel/eel-open-with-dialog.c (eel_open_with_dialog_new): make + function have no return value. + +2004-07-19 Dave Camp + + * eel/Makefile.am: + * eel/eel-mime-extensions.c: (recursive_mkdir), (get_user_dir), + (ensure_mime_dir), (ensure_application_dir), (write_desktop_file), + (update_application_database), (eel_mime_add_application), + (get_override_filename), (get_override), (write_override), + (create_type_node), (get_type_node), (get_comment_node), + (add_glob_node), (update_mime_database), (eel_mime_add_glob_type): + * eel/eel-mime-extensions.h: + * eel/eel-open-with-dialog.c: (eel_open_with_dialog_finalize), + (eel_open_with_dialog_destroy), (check_application), + (get_app_name), (add_application), (emit_application_selected), + (response_cb), (entry_activate_cb), + (eel_open_with_dialog_class_init), (chooser_response_cb), + (browse_clicked_cb), (eel_open_with_dialog_instance_init), + (get_extension), (set_uri_and_mime_type), + (eel_open_with_dialog_new), (eel_open_with_dialog_get_type): + * eel/eel-open-with-dialog.h: + * eel/eel-preferences.c: (eel_preferences_remove_callback): + Add an Open With dialog that adds mime types and application + mappings. + +2004-07-05 Alexander Larsson + + * NEWS: + Update for 2.7.2 + +2004-06-01 Alexander Larsson + + * configure.in: + Post release bump + +=== eel 2.7.1 === + + * NEWS: + Update for 2.7.1 + +2004-05-14 Alexander Larsson + + * configure.in (LIBGLADE_REQUIRED): + Bump to 2.7.1 on HEAD, 2.6.3 is on mate-2-6 branch + +2004-05-13 Dave Camp + + * configure.in: Post-release version bump. + +=== eel 2.6.2 === + +2004-05-13 Dave Camp + + * NEWS: Updated for 2.6.2. + +2004-04-19 Alexander Larsson + + * configure.in: + Post release version bump + +=== eel 2.6.1 === + +2004-04-19 Alexander Larsson + + * NEWS: + Updates for 2.6.1 + +2004-04-09 Guntupalli Karunakar + + * configure.in: Added "gu" (Gujarati) to ALL_LINGUAS. + +2004-03-22 Alexander Larsson + + * configure.in: + Bump version to 2.6.1 + +=== eel 2.6.0 === + +2004-03-22 Alexander Larsson + + * configure.in: + Update to 2.6.0 + +2004-03-20 Guntupalli Karunakar + + * configure.in: Added "pa" (Punjabi) to ALL_LINGUAS. + +=== eel 2.5.91.1 === + +2004-03-16 Alexander Larsson + + * NEWS: + * configure.in: + Update to 2.5.91.1 + + * eel/eel-editable-label.c (eel_editable_label_retrieve_surrounding_cb): + Use correct index in gtk_im_context_set_surrounding. (#133464) + Patch from Theppitak Karoonboonyanan + +=== eel 2.5.91 === + +2004-03-15 Alexander Larsson + + * NEWS: + * configure.in: + Update to 2.5.91 + +=== eel 2.5.90 === + +2004-03-08 Alexander Larsson + + * NEWS: + * configure.in: + Update to 2.5.90 + +2004-03-02 Alexander Larsson + + * eel/eel-mate-extensions.c (eel_mate_shell_execute_on_screen): + * eel/Makefile.am: + * eel/egg-screen-exec.[c]: + Remove egg-screen-exec. Use gdk_spawn instead. + +2004-03-02 Carlos Garnacho Parro + + * eel/eel-mate-extensions.c: (eel_mate_icon_selector_new) + made it to use the new GtkFileChooser + +2004-03-02 Alexander Larsson + + * eel/eel-canvas.h: + * eel/eel-cell-renderer-pixbuf-list.c: + * eel/eel-editable-label.c: (eel_editable_label_key_press), + (popup_position_func): + * eel/eel-gdk-extensions.h: + * eel/eel-glib-extensions.c: (eel_unsetenv): + * eel/eel-labeled-image.c: + * eel/eel-wrap-table.c: + * eel/eel-wrap-table.h: + * test/test-eel-image-table.c: (image_table_child_enter_callback), + (image_table_child_leave_callback), (image_table_size_allocate): + * test/test.c: (test_quit): + * test/test.h: + Portability fixes. Patch from bugzilla-mate@thewrittenword.com. + Fixes #131647. + +2004-03-01 Alexander Larsson + + Patches from sun. + + * test/test-eel-image-table.c: (labeled_image_new): + Fix forte compiler issue + + * Makefile.am: + * configure.in: + * eel-2.0-uninstalled.pc.in: + Add uninstalled pkg-config file. + +=== eel 2.5.8 === + +2004-02-23 Alexander Larsson + + * NEWS: + * configure.in: + Bump to 2.5.8 + +2004-02-21 Christian Rose + + * configure.in: Added "en_CA" to ALL_LINGUAS. + +=== eel 2.5.7 === + +2004-02-11 Alexander Larsson + + * NEWS: + * configure.in: + Bump to 2.5.7 + +2004-02-06 Alexander Larsson + + * eel/eel-glib-extensions.c (eel_strdup_strftime): + Fix check + +2004-02-06 Alexander Larsson + + * configure.in: + * eel/eel-glib-extensions.c (eel_strdup_strftime): + Check for and support SUS modifiers. + +2004-02-05 Padraig O'Briain + + * eel/eel-alert-dialog.c (eel_alert_dialog_new): Set role of AtkObject + to ATK_ROLE_ALERT. Fixes bug #133273. + +2004-02-05 Tomasz Kӯczko + + * eel/Makefile.am: + * test/Makefile.am: trivaial fix errors for automake 1.8.x - blank + line following trailing backslash. Fixes are backward compatible with + older automake. + +=== eel 2.5.6=== + +2004-01-30 Alexander Larsson + + * NEWS: + * configure.in: + Bump to 2.5.6 + +2004-01-27 Alexander Larsson + + * eel/eel-canvas-util.c: (eel_canvas_get_miter_points): + * eel/eel-canvas.c: (emit_event): + Update from foocanvas. May fix caja event crash. + +2004-01-19 Narayana Pattipati + + * eel/eel-editable-label.c (eel_editable_label_style_set), + (eel_editable_label_expose): Change the background, foreground, + cursor and outer rectangle colors according to the theme + selected. Fixes bugzilla bug#123207 + +=== eel 2.5.5 === + +2004-01-12 Dave Camp + + * NEWS: + * configure.in: 2.5.5 + +2004-01-11 Dave Camp + + * eel/eel-glib-extensions.h: + * eel/eel-glib-extensions.c: (eel_g_str_list_index): New function. + * eel/eel-mateconf-extensions.h: + * eel/eel-mateconf-extensions.c: (eel_mateconf_unset): New function. + * eel/eel-preferences.h: + * eel/eel-preferences.c: (eel_preferences_unset): New functions. + (eel_preferences_get_string_glist), + (eel_preferences_set_string_glist) + (update_auto_string_glist), + (preferences_entry_update_auto_storage), + (eel_preferences_add_auto_string_glist): Added a GList * + interface to string list properties. + * eel/eel-string-list.h: + * eel/eel-string-list.c: (eel_string_list_as_g_slist): + Implemented differently. + (eel_string_list_as_g_list): New function. + +2004-01-03 Anders Carlsson + + * eel/eel-input-event-box.c: + * eel/eel-input-event-box.h: + Remove these too. + +2004-01-03 Anders Carlsson + + * test/Makefile.am: Remove test-eel-image-chooser.c + + * eel/eel.h: Remove references to removed headers. + + * eel/Makefile.am: + * eel/eel-caption.c: + * eel/eel-caption.h: + * eel/eel-generous-bin.c: + * eel/eel-generous-bin.h: + * eel/eel-image-chooser.c: + * eel/eel-image-chooser.h: + * eel/eel-radio-button-group.c: + * eel/eel-radio-button-group.h: + * eel/eel-string-picker.c: + * eel/eel-string-picker.h: + * test/Makefile.am: + Remove unused eel stuff. + +2004-01-02 Robert Sedak + + * configure.in: Added "hr" in ALL_LINGUAS. + +=== eel 2.5.4 === + +2003-12-29 Alexander Larsson + + * NEWS: + * configure.in: + 2.5.4 + +2003-12-11 Alexander Larsson + + * eel/eel-stock-dialogs.c (show_message_dialog): + Connect to response in the right place + +2003-12-11 Alexander Larsson + + * configure.in: + Require gtk+ 2.3.0 + + * eel/Makefile.am: + * eel/eel-alert-dialog.[ch]: + New hig suporting dialog + + * eel/eel-stock-dialogs.[ch]: + Use new dialog, split up message + in primary and secondary string. + + * eel/eel-mateconf-extensions.c: + * eel/eel-mate-extensions.c: + * test/test-eel-widgets.c: + Use new API + + Patch from dennis_cranston@yahoo.com (with some changes) + +=== eel 2.5.3 === + +2003-12-08 Alexander Larsson + + * NEWS: + * configure.in: + 2.5.3 + +2003-11-25 Padraig O'Briain + + eel/eel-accessibility.c + (eel_accessibility_set_up_label_widget_relation): Call g_object_unref + on AtkRelationSet to avoid memory leak. Fixes bug #127899. + +=== eel 2.5.2 === + +2003-11-24 Alexander Larsson + + * NEWS: + * configure.in: + Bump to 2.5.2 + +2003-11-21 Alexander Larsson + + * eel/eel-editable-label.c: + Accessibility support, and better support + for GtkEditable signals. + Patch by padraig o'briain + +=== eel 2.5.1 === + +2003-11-10 Alexander Larsson + + * NEWS: + * configure.in: + 2.5.1 + +2003-10-27 Gregory Merchan + + * eel/eel-gdk-extensions.c (eel_gdk_window_focus): + Use RevertToParent as specified in the ICCCM. + (eel_gdk_window_set_wm_hints_input): + Guard against changes to C booleans. + * eel/eel-mate-extensions.c (eel_mate_icon_selector_new) + * eel/eel-stock-dialogs.c (timed_wait_callback) + * eel/eel-stock-dialogs.c (eel_run_simple_dialog) + * eel/eel-stock-dialogs.c (create_message_dialog) + Don't set WM_CLASS. It should match the application. + * eel/eel-gtk-extensions.c: + Remove comment and unused #define from bad old algorithm. + (eel_gtk_window_event_is_close_accelerator): + Remove Escape from close accelerators; it's not HIG compliant. + This reverts change from 2001-04-30. + +2003-10-22 Alexander Larsson + + * eel/Makefile.am: + * test/Makefile.am: + Disable MATE_DISABLE_DEPRECATED for now + +2003-10-21 Alexander Larsson + + * eel/eel-preferences.c: + Fix leaks. + Patch from Martin Wehner + +=== eel 2.5.0 === + +2003-10-20 Alexander Larsson + + * NEWS: + * configure.in: + Bump to 2.5.0 + +2003-10-15 Alexander Larsson + + * eel/Makefile.am: + * test/Makefile.am: + Disable GTK_DISABLE_DEPRECATED for now, since gtk 2.4 + deprecated various widgets. + +2003-10-06 Christian Rose + + * configure.in: Added "mr" to ALL_LINGUAS. + +2003-10-02 Padraig O'Briain + + Merge from foo-canvas.c: + + * eel/eeel-canvas.c + (eel_canvas_item_accessible_ref_state_set): + Do not refer to item->canvas if item can be NULL. (bug #123179) + + (eel_canvas_set_pixels_per_unit) : round + when mapping back to integer coordinates to guard against inadverent + decrement due to lack of precision. + eg zoom of 0.85 == 0.849999999 would lose a pixel + Fix from Jody Goldberg + + (do_update): + Loop do_update if picking caused need_update to be set again. + (Thanks to George for noticing this) + Fix from Alexander Larsson + +2003-09-24 Dave Camp + + * eel/eelmarshal.list: Added VOID:STRING,LONG,LONG,POINTER. + +2003-09-19 Christian Rose + + * configure.in: Added "br" to ALL_LINGUAS. + +=== eel 2.4.0 === + +2003-09-08 Alexander Larsson + + * NEWS: + * configure.in: + 2.4.0 + +2003-09-04 Alexander Larsson + + * eel/eel-gdk-extensions.c (eel_gdk_window_focus): + Don't use RevertToNone + +=== eel 2.3.90 === + +2003-09-02 Alexander Larsson + + * NEWS: + * configure.in: 2.3.90 + +2003-08-28 Christian Rose + + * configure.in: Added "ne" to ALL_LINGUAS. + +=== eel 2.3.9 === + +2003-08-25 Alexander Larsson + + * NEWS: + * configure.in: + 2.3.9 + +=== eel 2.3.8 === + +2003-08-08 Alexander Larsson + + * configure.in: 2.3.8 + +Tue Jul 22 16:18:26 2003 George Lebl + + * eel/eel-mateconf-extensions.[ch]: add eel_mateconf_key_is_writable, + which calls mateconf_client_key_is_writable + + * eel/eel-preferences.[ch]: add eel_preferences_key_is_writable, + which in turn calls eel_mateconf_key_is_writable on the full key + + * eel/eel-preferences-glade.c: When the key is not writable on + setup, then make the widget insensitive and then monitor the + state to make sure it can't be ever made sensitive (since it can't + be ever written) + +2003-07-21 Dave Camp + + * NEWS: + * configure.in: + Bumped to 2.3.7. + +2003-07-08 Balamurali Viswanathan + + * configure.in: Checking for X Development libraries explicitly. + * eel/Makefile.am: Added X_LIBS to libeel_2_la_LDFLAGS + +2003-07-07 Alexander Larsson + + * eel/eel-canvas-rect-ellipse.c (render_rect_alpha): + Update from foocanvas, fixes #116752 + +=== eel 2.3.6 === + +2003-06-27 Dave Camp + + * NEWS: + * configure.in: + Bump version to 2.3.6. + +=== eel 2.3.5 === + +2003-06-23 Dave Camp + + * NEWS: + * configure.in: + Bump version to 2.3.5. + +2003-06-15 Frederic Crozat + + * configure.in: + Remove -Wsign-promo and add -Wno-strict-aliasing to the list + of options to test for. Fixes the gcc 3.3 aliasing warnings. + +2003-06-13 Alexander Larsson + + * eel/eel-canvas-rect-ellipse.c: (get_color_value), + (set_colors_and_stipples), (eel_canvas_re_update_shared), + (eel_canvas_re_realize), (eel_canvas_ellipse_update): + * eel/eel-canvas.c: (eel_canvas_item_dispose), + (eel_canvas_item_unrealize), (eel_canvas_item_invoke_update), + (eel_canvas_item_ungrab), (eel_canvas_item_request_update), + (eel_canvas_group_unrealize), (eel_canvas_group_map), + (eel_canvas_init), (shutdown_transients), (eel_canvas_expose), + (do_update): + * eel/eel-canvas.h: + Update to latest foo-canvas. + +=== eel 2.3.4 === + +2003-06-10 Dave Camp + + * NEWS: + * configure.in: + Bump version to 2.3.4. + +2003-06-05 Kenneth Rohde Christiansen + + * configure.in: Added li to ALL_LINGUAS. + +2003-06-04 Alexander Larsson + + * NEWS: + * configure.in: + Bump version to 2.3.3. + +2003-05-26 Anders Carlsson + + * eel/Makefile.am: + * eel/eel-caption-table.c: + * eel/eel-caption-table.h: + * eel/eel-password-dialog.c: + * eel/eel-password-dialog.h: + * eel/eel.h: + * test/Makefile.am: + * test/test-eel-password-dialog.c: + * test/test-eel-widgets.c: (main), (test_radio_changed_callback): + Remove EelCaptionTable and EelPasswordDialog since they're not + used anymore. + +=== eel 2.3.2 === + +2003-05-19 Alexander Larsson + + * NEWS: + * configure.in: + Bump to 2.3.2. + +2003-05-15 Alexander Larsson + + * eel/eel-vfs-extensions.[ch]: + New define EEL_DESKTOP_URI and function eel_uri_is_desktop. + +=== eel 2.3.1 === + +2003-05-05 Telsa Gwynne + + * configure.in: Added cy to ALL_LINGUAS + * po/cy.po: Added + +2003-05-05 Alexander Larsson + + * NEWS: + Update + + * configure.in: + Bump version + +2003-05-04 Christian Rose + + * configure.in: Added sr and sr@Latn to ALL_LINGUAS. + +2003-04-23 Masahiro Sakai + + * configure.in: call AC_LIBTOOL_WIN32_DLL. + * eel/Makefile.am (libeel_2_la_LDFLAGS): add -no-undefined. + + These are necessary for building DLL on win32 platform. + +2003-04-07 Alexander Larsson + + * eel/eel-canvas.c: + Update foocanvas. + +=== eel 2.2.3 === + +2003-03-31 Alexander Larsson + + * NEWS: + * configure.in: + Bump to 2.2.3 + +2003-03-27 Alexander Larsson + + * eel/eel-vfs-extensions.[ch] (eel_filename_get_rename_region): + New function to get the rename region for a filename. + +2003-03-19 Alexander Larsson + + * eel/eel-accessibility.c (eel_accessibility_set_atk_object_return): + Fix warning. + +2003-03-19 Padraig O'Briain + + * eel/eel-accessibility.c + (eel_accessibility_destroy): Change function name from + eel_accessibility_weak_unref. Remove call to g_object_unref(). + (eel_accessibility_set_atk_object_return): Use call to + call to g_object_qdata_full() instead of g_object_weak_ref(). + + This fixes bug #107725. + +2003-03-18 Alexander Larsson + + * eel/eel-canvas.c (eel_canvas_set_pixels_per_unit): + Update from foocanvas. Now less tearing when changing + zoom level. + +2003-03-17 Alexander Larsson + + * eel/eel-preferences-glade.[ch]: + + Add eel_preferences_glade_connect_string_enum_option_menu_slave + and eel_preferences_glade_connect_bool_slave. + +2003-03-17 Alexander Larsson + + * eel/eel-editable-label.c (eel_editable_label_expose): + Draw frame even if text is "". + +2003-03-13 Christian Rose + + * configure.in: Added "ml" to ALL_LINGUAS. + +2003-03-12 Balamurali Viswanathan + + *eel/eel-stock-dialogs.c + connect the "response" signal of the trash dialog + +=== eel 2.2.2 === + +2003-03-10 Alexander Larsson + + * NEWS: + * configure.in: + Bump version to 2.2.2. + +2003-03-04 Alexander Larsson + + * eel/Makefile.am: + * eel/eel-input-event-box.[ch]: + New widget. Basically GtkEventBox with a INPUT_ONLY window. + +2003-03-04 Alexander Larsson + + * eel/eel-canvas.c: + Update foocanvas. Fix a11y crash. + +2003-03-04 Alexander Larsson + + * eel/eel-accessibility.[ch]: + Publicaly export some utility functions. + Patch from padraig.obriain@sun.com + +2003-03-04 Alexander Larsson + + * eel/eel-canvas.c: + Update foocanvas. Gets a11y support from padraig. + +2003-03-03 Alexander Larsson + + * eel/eel-canvas.c: + Update from foo-canvas. Fixes group movement, + removes silly warning. + +2003-02-28 Alexander Larsson + + * eel/eel-editable-label.[ch]: + Add eel_editable_label_get_font_description and + eel_editable_label_set_font_description. + +2003-02-27 Taneem Ahmed + + * configur.in: Added "bn" to ALL_LINGUAS + +2003-02-25 Samúel Jón Gunnarsson + + * configur.in: Added is to ALL_LINGUAS + +2003-02-21 Paisa Seeluangsawat + + * configure.in (ALL_LINGUAS): Added "th". + +2003-02-18 Christian Rose + + * configure.in: Added "ga" to ALL_LINGUAS. + +2003-02-14 Alexander Larsson + + * eel/eel-glib-extensions.c (eel_unsetenv): + Fix bug. Patch from hidetoshi.tajima@sun.com. + +=== eel 2.2.1 === + +2003-02-11 Alexander Larsson + + * NEWS: + * configure.in: + Bump version to 2.2.1 + +2003-02-09 Christian Rose + + * configure.in: Added "kn" to ALL_LINGUAS. + +2003-02-07 Abel Cheung + + * configure.in: Removed "ga" from ALL_LINGUAS. Empty translation file. + +2003-02-06 Christian Rose + + * configure.in: Added "id" to ALL_LINGUAS. + +2003-02-05 James M. Cape + + * eel/eel-background.c, + eel/eel-canvas-rect-ellipse.c, + eel/eel-canvas.c, + eel/eel-cell-renderer-pixbuf-list.c, + eel/eel-editable-label.c, + eel/eel-gdk-pixbuf-extensions.c, + eel/eel-mate-extensions.c, + eel/eel-stock-dialogs.c, + test/test-eel-image-table.c: + Replace gtk+ functions deprecated in 2.3. + +=== eel 2.2.0.2 === + +2003-01-27 Dave Camp + + * NEWS: + * configure.in: 2.2.0.2 + +=== eel 2.2.0.1 === + +2003-01-22 Dave Camp + + * NEWS: + * configure.in: 2.2.0.1 + +2003-01-21 Christian Rose + + * configure.in: Added "mn" to ALL_LINGUAS. + +=== eel 2.2.0 === + +2003-01-20 Dave Camp + + * NEWS: + * configure.in: 2.2.0. + +2003-01-17 Alexander Larsson + + * eel/eel-preferences-glade.c: + Correct previous fix. + +2003-01-17 Alexander Larsson + + * eel/eel-preferences-glade.c: + Fix a bug in the handling of the hashtable for int enums. + +=== eel 2.1.91 === + +2003-01-13 Alexander Larsson + + * NEWS: + * configure.in: + Bump to 2.1.91. + +2003-01-13 Alexander Larsson + + * eel/eel-background.c: + Hack in eel_background_set_up_widget to always get the right size + for desktop window pixmaps. This is needed since matecomponentplug children + gets realized at the wrong size first and then the correct size. + This hack allows us to not load the background image twice and to + not flicker. + Don't draw the background for canvases. This is not needed since + we set up the correct window background. + +2003-01-12 Pablo Saratxaga + + * configure.in: Added Amharic (am) and Farsi (fa) to ALL_LINGUAS + +=== eel 2.1.6 === + +2003-01-06 Dave Camp + + * NEWS: + * configure.in: 2.1.6. + +2002-12-17 Alexander Larsson + + * configure.in: + * eel/Makefile.am: + * test/Makefile.am: + -pthread build fixes + +=== eel 2.1.5 === + +2002-12-16 Alexander Larsson + + * NEWS: + * configure.in: + Bump to 2.1.5 + +2002-12-13 Alex Duggan + + * configure.in: + * eel-2.0.pc.in: + * eel.spec.in: + remove libmatecanvas deps + +=== eel 2.1.4 === + +2002-12-09 Alexander Larsson + + * configure.in: + * NEWS: + Bump to 2.1.4 + +2002-12-05 Dave Camp + + * eel/eel-mate-extensions.c: (list_icon_selected_callback): Free + the return value of mate_icon_selection_get_icon(). Patch from + Jörgen Viksell + +Wed Dec 4 12:50:35 2002 HideToshi Tajima + + * eel/eel-editable-label.c (eel_editable_label_ensure_layout): + Fix bugzilla.gnome.org #95429 - set input method text to pango layout. + +=== eel 2.1.3 === + +2002-11-25 Alexander Larsson + + * eel/eel-vfs-extensions.c: + Fix checks so we distcheck. + +2002-11-25 Alexander Larsson + + * configure.in: + * NEWS: + Bump to 2.1.3. + +2002-11-21 Alexander Larsson + + * eel/eel-background.[ch]: + (eel_background_set_up_widget): + Set the background pixmap/color on the right window for canvas widgets. + (eel_background_get_suggested_pixmap_size): + New function. + + Based on patch from Brian.Cameron@sun.com + +2002-11-19 Alexander Larsson + + * eel/eel-editable-label.[ch]: + Don't use private gtk functions. + +2002-11-05 Dave Camp + + * test/Makefile.am: + * test/test-eel-widgets.c: (main), + (string_picker_changed_callback): + * test/test.c: + * test/test.h: Took out the tests of removed code. + +2002-11-05 Diego Gonzalez + + * po/POTFILES.in: remove eel/eel-preferencs-box.c + * eel/Makefile.am: remove eel-font-picker.[c-h], + eel-preferences-box.[c-h], eel-preferences-group.[c-h], + eel-preferences-item.[c-h], eel-preferences-pane.[c-h], + eel-text-caption.[c-h] from the build, these files aren't + used anymore + + * eel/eel.h: remove those headers from here. + +2002-11-04 Diego González + + * eel/eel-mate-extensions.h: + * eel/eel-mate-extensions.c: (get_set_value_imethod), + (do_nothing_cb), (eel_matecomponent_pbclient_set_value_async): + remove these functions since they are now in libmatecomponent + +2002-11-04 Alexander Larsson + + * eel/eel-gdk-pixbuf-extensions.c: (file_read_callback): + Fix bug with failed reads. + + * eel/eel-wrap-table.c: (eel_wrap_table_class_init), + (eel_wrap_table_init), (eel_wrap_table_realize), + (wrap_table_get_num_fitting), (wrap_table_layout), + (wrap_table_get_max_child_dimensions): + Correct size request. + Patch from Jan Arne Petersen + +2002-11-03 Dmitry G. Mastrukov + + * configure.in: Added Belarusian to ALL_LINGUAS + +=== eel 2.1.2 === + +2002-10-31 Dave Camp + + * MAINTAINERS: Updated. + + * configure.in: + * NEWS: 2.1.2 + +2002-10-31 Dave Camp + + * eel/eel-background.c: (eel_background_class_init), + (eel_background_set_image_placement), (eel_background_set_color), + (eel_background_set_image_uri_helper), + (set_image_and_color_image_loading_done_callback), + (eel_background_set_image_uri_and_color), + (eel_background_receive_dropped_background_image), + (eel_background_receive_dropped_color): * eel/eel-background.h: + Take a GdkDragAction argument to the receive_dropped_* functions, + and pass it on in the changed signal. + +2002-10-31 Dave Camp + + * eel/Makefile.am: + * eel/eel-preferences-glade.c: + * eel/eel-preferences-glade.h: New files to connect glade widgets to + preferences. Patch from Jan Arne Petersen . + +2002-10-25 Dave Camp + + * eel/Makefile.am: Oops. Removed extra \ at the end of a + commented out line. + +2002-10-19 Dave Camp + + * eel/Makefile.am: Take out -DMATECOMPONENT_DISABLE_DEPRECATED while the + make_registration_id() api is being worked out. + +=== eel 2.1.1 === + +2002-10-14 Alexander Larsson + + * NEWS: + Added news items + + * configure.in: + Bump version to 2.1.1 + +2002-10-02 Mark McLoughlin + + * acconfig.h: define HAVE_GTK_MULTIHEAD + for egg-screen-exec.c. + + * configure.in: require gtk 2.1.0 and remove + HAVE_GTK_MULTIHEAD define. + + * eel/eel-mate-extensions.c, + eel/eel-gtk-extensions.c, + eel/eel-gdk-extensions.c: don't conditionally + build multihead support, gtk HEAD is required. + +2002-10-02 Mark McLoughlin + + * eel/eel-gdk-extensions.c: + (eel_stipple_bitmap_for_screen): use gdk_screen_get_display + instead of assuming the default display. + + * eel/eel-mate-extensions.c: + (eel_mate_shell_execute_on_screen): use the default screen + if screen == NULL. + +2002-10-02 Mark McLoughlin + + * eel/eel-mate-extensions.[ch]: + (eel_mate_shell_execute_on_screen): rename from + eel_mate_screen_shell_execute. + (eel_mate_shell_execute): update. + (eel_mate_open_terminal_on_screen): rename from + eel_mate_screen_open_terminal. + (eel_mate_open_terminal): update. + +2002-10-02 Mark McLoughlin + + * eel/eel-gtk-extensions.c: (eel_gtk_window_set_initial_geometry): + fix build without HAVE_GTK_MULTIHEAD. + + * eel/egg-screen-exec.c: sync with libegg. + +2002-10-02 Mark McLoughlin + + * configure.in: add check for gtk with multihead support. + + * eel/Makefile.am: add egg-screen-exec.[ch] to the build. + + * eel/eel-gdk-extensions.[ch]: + (eel_stipple_bitmap_for_screen): implement per screen stipple + bitmaps. + (eel_stipple_bitmap): use eel_stipple_bitmap_for_screen. + + * eel/eel-mate-extensions.[ch]: + (eel_mate_screen_shell_execute): implement. + (eel_mate_screen_open_terminal): implement. + (eel_mate_open_terminal): + + * eel/eel-gtk-extensions.c: + (eel_gtk_window_set_initial_geometry): + use gdk_screen_get_(width|height). + +2002-10-01 Alexander Larsson + + * eel/eel-editable-label.[ch]: + Added eel_editable_label_set_line_wrap_mode. + +2002-09-30 Alexander Larsson + + * eel/eel-editable-label.c: + Implement GtkEditable + +2002-09-30 Alexander Larsson + + * eel/eel-editable-label.c: + Finish cut/paste and other stuff. + +=== eel 2.1.0 === + +2002-09-27 Dave Camp + + * NEWS: Updated. + +2002-09-27 Alexander Larsson + + * configure.in: + Bump version to 2.1.0. + +2002-09-26 Alexander Larsson + + * eel/eel-editable-label.c: + Remove leftover debug spew. + +2002-09-26 Alexander Larsson + + * test/Makefile.am: + * test/test-eel-canvas-items.c: + Remove canvas item test. + +2002-09-26 Alexander Larsson + + * eel/Makefile.am: + Add new files, remove old files. + + * eel/README.canvas: + * eel/eel-canvas.[ch]: + * eel/eel-canvas-util.[ch]: + * eel/eel-canvas-rect-ellipse.[ch]: + Import gtk+ only canvas from foocanvas. + + * eel/eel-canvas-rect.[ch]: + Remove old rect object not longer needed. + + * eel/eel-mate-extensions.[ch]: + Remove old canvas extensions no longer needed. + + * eel/eel-background.[ch]: + Update to the new canvas. + + * eel/eel-editable-label.[ch]: + New editable label for rename mode. + + * eel/eel-lib-self-check-functions.h: + Remove old tests. + + * eel/eelmarshal.list: + New marshallers. + + * test/Makefile.am: + * test/test-eel-editable-label.c: + Small test for EelEditableLabel + +2002-09-15 Dave Camp + + * eel/eel-preferences-item.h: + * eel/eel-preferences-item.c: + (eel_preferences_item_set_description), + (eel_preferences_item_set_accessible_description), + (eel_preferences_item_set_accessible_description_array): Allow users + to set accessible descriptions of preferences items. + * eel/eel-preferences-box.c: (preferences_box_populate_pane): + * eel/eel-preferences-box.h: Allow the user to specify accessible + descriptions for the controls. + * eel/eel-radio-button-group.c: + (eel_radio_button_group_set_entry_accessible_description), + * eel/eel-radio-button-group.h: Allow the user to specify + accessible descriptions for the radio buttons. + +2002-09-10 jacob berkman + + * eel/eel-types.c: define EEL_COMPILATION + + * eel/Makefile.am (INCLUDES): don't define EEL_COMPILATION + + this fixes actual build problems on OS X, but wasn't correct + anywhere. + +2002-09-10 Dave Camp + + * eel/eel-background.c: (eel_background_ensure_realized), + (eel_background_set_color_no_emit), (eel_background_set_use_base): + If requested, use base as the fallback color instead of bg. + +2002-09-04 Christian Rose + + * configure.in: Added "he" to ALL_LINGUAS. + +2002-09-03 Michael Meeks + + * eel/eel-background.c + (eel_background_load_image_callback): disable, + until the caja side is re-thunk. + +2002-09-03 Michael Meeks + + * eel/eel-background.c + (set_image_and_color_image_loading_done_callback): + don't double emit apperance_changed occasionaly. + (eel_background_class_init): add determine_image_placement. + (eel_background_load_image_callback): call signal. + [ based on Thomas Meeks' prototype ] + + * eel/eelmarshal.list: add enum:int,int + +2002-08-30 Alexander Larsson + + branched of mate 2.0.x development to mate-2-0 branch. + +=== eel 2.0.6 === + +2002-08-28 Alexander Larsson + + * NEWS: + * configure.in: + Bumped to 2.0.6. + +=== eel 2.0.5 === + +2002-08-23 Alexander Larsson + + * NEWS: + * configure.in: + Version bumped to 2.0.5. + +=== eel 2.0.4 === + +2002-08-14 Alexander Larsson + + * configure.in: + Version bumped to 2.0.4 + +2002-08-12 Dave Camp + + * eel/eel-string-picker.c: (eel_string_picker_set_string_list): + Use eel_string_list_peek_nth() instead of eel_string_list_nth(). + Fixes a small leak. + +=== eel 2.0.3 === + +2002-08-05 Dave Camp + + * NEWS: Updated. + * configure.in: 2.0.3. + +2002-07-28 Christian Rose + + * configure.in: Added "sq" to ALL_LINGUAS. + +2002-07-27 Dave Camp + + * eel/eel-background.c: (widget_realize_cb), + (eel_get_widget_background): Set up the widget background on + realize. + +2002-07-27 Dave Camp + + * eel/eel-background.c: (widget_style_set_cb), + (eel_get_widget_background): Put back the style_set handler. + +=== eel 2.0.2 === + +2002-07-25 Dave Camp + + * NEWS: Add a list of changes. + * configure.in: Bump version to 2.0.2. + +2002-07-25 Pablo Saratxaga + + * configure.in: Added Bosnian (bs) to ALL_LINGUAS + +2002-07-24 Dave Camp + + * eel/Makefile.am: Build eel-background-box.[ch], don't build + eel-background-style.[ch]. + * eel/eel-background-style.[ch]: Removed. + * eel/eel-background-box.[ch]: New widget that handles background + drawing itself. + * eel/eel-background.c: (eel_background_init), + (eel_get_widget_background): Removed the style setting and font + updating code. This is now the responsibility of the widget using + the EelBackground. + (eel_background_expose): Helper function for widgets using + EelBackground. + (eel_background_set_up_widget): New function. + (eel_widget_background_changed): Call + eel_background_set_up_widget(). + +=== eel 2.0.1 === + +2002-07-22 Alexander Larsson + + * NEWS: + * configure.in: + Bump version to 2.0.01. + Add list of changes. + +2002-07-18 Federico Mena Quintero + + Fixes the eel part of #46238; see Caja for the rest of the fix. + + * eel/eel-background.c (eel_background_ensure_realized): If we + fail to parse the color spec, don't default to white. Instead use + the background color from the widget's style. + (widget_style_set_cb): New callback for the widget's "style_set" + signal. We regenerate the background and its style when the theme + changes. + (eel_background_set_widget_style): We need a little hack here to + unset the GTK_USER_STYLE flag because otherwise we will not be + notified of theme changes through the "style_set" signal. The + real solution is not to use a style of our own, but rather paint + the widget by hand when needed. + (eel_background_init): Start with is_solid_color = TRUE. + +2002-07-17 Frank Worsley + + * eel/eel-gtk-extensions.c: + * eel/eel-gtk-extensions.h: + (eel_gtk_window_set_initial_geometry_from_string): + add an ignore_position parameter + +2002-07-12 Damon Chaplin + + * eel/eel-gtk-extensions.c (eel_gtk_button_new_with_stock_icon): new + function to create a button with a mnemonic label and a stock icon. + GTK+ doesn't make this easy. Needed for bug #85666. + +2002-07-10 Dave Camp + + * eel/eel-gtk-extensions.c: (tree_view_button_press_callback), + (eel_gtk_tree_view_set_activate_on_single_click): New functions + to make a GtkTreeView activate a row on a single click. + * eel/eel-gtk-extensions.h: Prototype for + eel_gtk_tree_view_set_activate_on_single_click. + * eel/eel-image-chooser.c: (eel_image_chooser_row_activated), + (eel_image_chooser_finalize), (eel_image_chooser_instance_init), + (eel_image_chooser_get_selected_path), + (eel_image_chooser_set_selected_row): Only send a changed event + when the user activates the row. + +2002-07-10 Michael Meeks + + * eel/eel-gdk-pixbuf-extensions.c + (eel_gdk_pixbuf_average_value): unsigned + dividend, width, height. + split out loop invariant and simplify, + killing umpteen multiplies for non-alpha case. + +2002-07-09 Michael Meeks + + * eel/eel-gdk-pixbuf-extensions.c (destroy_global_buffer), + (eel_gdk_pixbuf_get_global_buffer): move these into the only + place that uses them, and hide. + + * test/test-eel-pixbuf-tile.c: here + (pixbuf_drawing_area_expose_event): upd. + +2002-07-09 Damon Chaplin + + * eel/eel-preferences-box.c (eel_preferences_box_new): added a + 'Cat_egories' label and mnemonic accel above the list. Fixes part + of bug #85673. + + * eel/eel-preferences-group.c (eel_preferences_group_new): set the + border width of the second column of prefs to match the first. + +2002-07-08 Michael Meeks + + * eel/eel-labeled-image.c + (eel_labeled_image_get_accessible): cope better + with the no a11y scenario. + +2002-07-08 Michael Meeks + + * eel/eel-labeled-image.c + (eel_labeled_image_radio_button_get_type): impl. + (eel_labeled_image_radio_button_new_from_file_name), + (eel_labeled_image_radio_button_new): impl. + +2002-07-02 Michael Meeks + + * configure.in: use libglade. + + * eel-2.0.pc.in (Requires): upd. + + * eel/eel-labeled-image.c (eel_labeled_image_set_text): + set text with mnemonic. + (eel_labled_set_mnemonic_widget): impl. + (eel_labeled_*_button_new): set the mnemonic widget. + + * eel/eel-mate-extensions.c (eel_glade_get_file): impl. + +2002-06-28 Marco Pesenti Gritti + + * eel/eel-gtk-extensions.c (eel_popup_menu_position_func): + Remove context menus custom positioning code to be consistent + with other mate applications. + +2002-06-27 Frank Worsley + + * eel/eel-vfs-extensions.c: (eel_vfs_has_capability_uri): + * eel/eel-vfs-extensions.h: + implemented EEL_VFS_CAPABILITY_SAFE_TO_EXECUTE + +2002-06-25 Dave Camp + + * eel/eel-vfs-extensions.c (eel_vfs_has_capability_uri): Moved + here from eel_vfs_test_capabilities(). + (eel_vfs_has_capability): New function, takes a string uri. + * eel/eel-vfs-extensions.h: Changed EelVfsTest to EelVfsCapability, + and EEL_VFS_TEST_* to EEL_VFS_CAPABILITY_*. + +2002-06-25 Frederic Crozat + + * acconfig.h: + * configure.in: + * eel/Makefile.am: + * eel/check-program.c: (main): + * eel/eel-enumeration.c: + * eel/eel-mateconf-extensions.c: + * eel/eel-glib-extensions.c: + * eel/eel-mate-extensions.c: + * eel/eel-i18n.c: (_eel_gettext): + * eel/eel-i18n.h: + * eel/eel-password-dialog.c: + * eel/eel-preferences-box.c: + * eel/eel-stock-dialogs.c: + * eel/eel-vfs-extensions.c: + * eel/eel-xml-extensions.c: + Use our own _() macro to ensure bind_textdomain_codeset is set + (when available) + + +2002-06-14 Satyajit Kanungo + + * eel/eel-preferences-box.c : Added a call to get the active pane + for eel preference dialog box. (Applied by Damon Chaplin.) + +2002-06-13 Dave Camp + + * eel/eel-stock-dialogs.c: (eel_run_simple_dialog): Don't try to + connect to the delete_event signal of the dialog, and handle + gtk_dialog_run() returning GTK_RESPONSE_DELETE_EVENT. Fixes + #78948. + +2002-06-12 Damon Chaplin + + * eel/eel-mate-extensions.c (icon_selected): hide the dialog at the + start of the function and set the dismissed flag to indicate we're + acting on it, so if we do get called again we just return. + Fixes bug #84134. + +2002-06-10 Alexander Larsson + + * eel/eel-preferences-box.c: change treeview shadow type + to GTK_SHADOW_IN and add some spacing for consistency with + the rest of mate. + + Patch from Jorn Baayen + +2002-06-10 Alexander Larsson + + * NEWS: + Update version nr. + + * configure.in: + Update requirements to latest versions of everything. + +2002-06-10 Naba Kumar + + * configure.in: Added hi in ALL_LINGUAS. + +2002-06-09 Abel Cheung + + * eel/eel-glib-extension.c: Clarify the comment about + strftime check. + +2002-06-07 Damon Chaplin + + * test/Makefile.am (INCLUDES): + * eel/Makefile.am (INCLUDES): use $(prefix)/${DATADIRNAME}/locale + instead of $(datadir)/locale so it works on Solaris. + +2002-06-06 Michael Meeks + + * eel/eel-vfs-extensions.c + (eel_vfs_test_capabilities): impl. + +2002-06-06 Michael Meeks + + * Version 2.0.0 + +2002-06-06 Jacob Berkman + + * eel/eel-gdk-extensions.c: pangoxft.h is not present on all + systems, i think it's safe to just include pango/pango.h + +2002-06-04 Yanko Kaneti + + * configure.in: (ALL_LINGUAS) Added Bulgarian (bg). + +=== eel 1.1.17 === + +2002-06-03 Alex Larsson + + * NEWS: + Add some actual changes. + +2002-06-03 Alexander Larsson + + * NEWS: + * configure.in: + Bump version to 1.1.17 + +2002-05-31 Alex Larsson + + * eel/eel-gdk-extensions.[ch] (eel_gdk_draw_layout_with_drop_shadow): + Add new function. + +2002-05-28 Havoc Pennington + + * eel/eel-gdk-pixbuf-extensions.c: remove bogus #include , + we no longer use libpng + +2002-05-27 Michael Meeks + + * eel/eel-vfs-extensions.c + (eel_make_valid_utf8): copy from caja + (eel_format_uri_for_display_internal): use it + for awkward (invalid) cases, that we still need to + display in an error dialog. + +=== eel 1.1.16 === + +2002-05-27 Alexander Larsson + + * NEWS: + * configure.in: + Bump version to 1.1.16 + +2002-05-23 Michael Meeks + + * eel/eel-vfs-extensions.c + (eel_format_uri_for_display_internal): move the utf8 + validation assert down to after we've handled 'locale_encoded + filenames' as best we can. + +2002-05-22 Michael Meeks + + * eel/eel-vfs-extensions.c (eel_is_valid_uri): impl. + +2002-05-21 Damon Chaplin + + * eel/eel-mate-extensions.c (eel_mate_icon_selector_new): store + the dialog pointer before calling eel_remove_weak_pointer(), as that + will set it to NULL. We want to return it. + + * eel/eel-gdk-pixbuf-extensions.c (eel_gdk_pixbuf_load): close the + pixbuf loader if we get a vfs error. It complains if we unref it + without closing it. + +=== eel 1.1.15 === + +2002-05-20 Alex Larsson + + * NEWS: + * configure.in: + Bump version to 1.15. + +2002-05-18 Kjartan Maraas + + * configure.in: Added "mk" to ALL_LINGUAS. + +2002-05-16 Michael Meeks + + * eel/eel-background-style.c (eel_background_style_draw_flat_box): + unref the pixmap instead of leaking it if not changes_with_size. + +2002-05-16 Mark McLoughlin + + * eel/eel-pango-extensions.c: (measure_string_width), + (compute_character_widths), (eel_string_ellipsize_start), + (eel_string_ellipsize_end), (eel_string_ellipsize_middle), + (eel_self_check_ellipsize): don't create redundant layouts + when doing calculations. Just use the one we've already + created. + +2002-05-14 Federico Mena Quintero + + * eel/eel-text-caption.c (entry_key_press_callback): Event + handlers should return a gboolean! Fixes #75229. + +=== eel 1.1.14 === + +2002-05-13 Alex Larsson + + * NEWS: + * configure.in: + Update to 1.1.14 + +2002-05-12 Anders Carlsson + + * eel/eel-pango-extensions.c + (eel_pango_layout_fit_to_dimensions): Fix this utterly broken + function by rewriting parts of it. Fixes #81183, reported + by Owen Taylor. + +2002-05-11 Alexander Larsson + + * eel/eel-background.c: (eel_background_start_loading_image), + (eel_background_set_style_font_from_default), + (eel_background_set_widget_style), (eel_widget_font_changed), + (eel_get_widget_background): + Hacks to update the style when the default font changes. + +2002-05-08 Damon Chaplin + + * eel/eel-mate-extensions.c (eel_mate_icon_selector_new): connect + the dialog signals up before calling mate_icon_selection_show_icons() + and also add a weak pointer to the dialog. We need to do this as + MateIconSelection reenters the main loop while loading icons, so + it can be closed or a button can be clicked before returning. + Fixes bug #75387. + +=== eel 1.1.13 === + +2002-05-04 David Emory Watson + + This is needed to fix bug 46582. + + * configure.in: + * NEWS: Bump version to 1.1.13. + + * eel/eel-vfs-extensions.c: + * eel/eel-vfs-extensions.h: + (eel_make_uri_from_input_internal): Optionally strip trailing + whitespace since it could be part of a valid uri. + (eel_make_uri_from_input): Update. + (eel_make_uri_from_input_with_trailing_ws): New. + +2002-04-30 Alexander Larsson + + * eel/eel-preferences-item.c + (enumeration_menu_changed_callback), + (enumeration_list_changed_callback): + Don't use the translated string when looking up the enumeration position. + Fixes #64696 + +2002-04-29 Pablo Saratxaga + + * configure.in: Added Vietnamese (vi) to ALL_LINGUAS + * configure.in: Added Walloon (wa) to ALL_LINGUAS + * configure.in: Added Basque (eu) to ALL_LINGUAS + +=== eel 1.1.12 === + +2002-04-28 Alexander Larsson + + * configure.in: + * NEWS: + Bump version to 1.1.12. + +2002-04-28 Alexander Larsson + + * configure.in: + Removed -Wcast-align. This broke the build for Alpha on RH 7.1, + even in header files! And it's not that useful. + See bug #79860. + +2002-04-27 Murray Cumming + + * eel/eel-stock-dialogs.c (eel_show_yes_no_dialog): + Bug #80072: + Use eel_create_question_dialog instead() of show_message_dialog() + so that the custom button titles can be used. + +2002-04-26 Gustavo Giráldez + + * eel/eel-ellipsizing-label.c (real_finalize): chain call to + parent class' finalize. + +2002-04-22 Anders Carlsson + + * eel/eel-image-chooser.c: (eel_scrolled_image_chooser_new): + Set shadow type to GTK_SHADOW_IN. Fixes #73389. + +=== eel 1.1.11 === + +2002-04-21 Alexander Larsson + + * configure.in: + * NEWS: + Bump version to 1.1.11. + +2002-04-21 Alexander Larsson + + * eel/eel-background.c (eel_background_ensure_image_scaled): + Work around the fact that scaling large pixbufs to 1x1 crashes + while allocating several gigs of memory. + +2002-04-21 Anders Carlsson + + * eel/eel-gtk-extensions.c: (eel_gtk_label_set_scale), + (get_layout_location), (eel_gtk_label_expose_event), + (eel_gtk_label_size_request), (set_up_label), + (eel_gtk_label_set_drop_shadow_color), + (eel_gtk_label_set_drop_shadow_offset): + * eel/eel-gtk-extensions.h: + Add eel_gtk_label_set_drop_shadow_color and + eel_gtk_label_set_drop_shadow_offset functions. + +2002-04-18 Michael Meeks + + * eel/eel-mate-extensions.c + (do_nothing_cb, get_set_value_imethod), + (eel_matecomponent_pbclient_set_value_async): impl. + async property setter to cut throbber + latency. + +2002-04-17 Anders Carlsson + + * eel/eel-background.c: (eel_background_start_loading_image): + If we load the pixbuf sync, unref it so that we won't leak it. + + * eel/eel-image-chooser.c: (eel_image_chooser_cell_data_func): + Free strings. + + * eel/eel-labeled-image.c: (eel_labeled_image_class_init), + (eel_labeled_image_destroy), (eel_labeled_image_forall): + Add a ::destroy handler that destroys the image and label. + + * eel/eel-preferences-box.c: + (preferences_box_category_list_recreate): + Free the GtkTreeIter. + + * eel/eel-preferences-item.c: + (preferences_item_update_editable_integer): + Free the caption. + +2002-04-17 Anders Carlsson + + * eel/eel-background.c (eel_background_finalize): + Free details after using it, not before. + + * eel/eel-preferences.c: (eel_preferences_get_enum): + Free enums. + + * eel/eel-string-list.c: (eel_string_list_peek_nth): + * eel/eel-string-list.h: + Add eel_string_list_peek_nth which does not strdup the + string returned. + +=== eel 1.1.10 === + +2002-04-14 Alexander Larsson + + * NEWS: + * configure.in: + Bump version to 1.1.10 + +2002-04-14 Alexander Larsson + + * eel/eel-mate-extensions.c (eel_mate_canvas_set_scroll_region): + Don't request_update all item unless the top left corner of + the scroll region changed. + +2002-04-13 Alexander Larsson + + * eel/eel-mate-extensions.c (eel_mate_shell_execute): + Print a warning on failure. For debugging purposes. + +2002-04-12 Jody Goldberg + + * eel/eel-mate-extensions.c (eel_mate_shell_execute) : no one uses + the return type anyway, remove it and make this a wrapper around + g_spawn_command_line_async. Fixes lots of problems. + +2002-04-12 Padraig O'Briain + + * configure.in: + Update required GAIL version to 0.13 + + * eel/eel-accessibility.h: + gailtextutil.h has moved from util directory to libgail-util + + * eel/eel-accessibility.c: + Update calls to gail_text_util_get_substring as start_pos and end_pos + arguments have been changed from gint* to gint + +2002-04-07 Alexander Larsson + + * eel/eel-preferences-item.[ch]: + Add EEL_PREFERENCE_ITEM_ENUMERATION_MENU_INTEGER type that + stores the integer value of the enum. This is needed for + the Caja thumbnail size limit. + +2002-04-04 Dave Camp + + * eel/eel-preferences-item.c + (eel_preferences_item_set_description): set + text with mnemonics. + + * eel/eel-labeled-image.c + (eel_labeled_image_set_selected), + (eel_labeled_image_get_selected): impl. + + * eel/eel-gtk-extensions.c + (eel_pop_up_context_menu): tolerate a NULL event. + +2002-04-04 Michael Meeks + + * eel/eel-accessibility.c + (eel_accessibility_set_description), + (eel_accessibility_set_name): impl. + +2002-04-03 Michael Meeks + + * eel/eel-accessibility.c (get_quark_gobject), + (get_quark_accessible): share quark id's with + gobject-accessible. + (eel_accessibility_set_atk_object_return): only + hook up weak refs etc. for non GObjectAccessible + derived types - otherwise we double unref the + accessible. + +2002-04-02 Michael Meeks + + * eel/eel-accessibility.c + (eel_accessible_text_get_type): impl. + (eel_accessibility_for_object): impl. + + * eel-2.0.pc.in (Requires): add gail. + +2002-04-01 Michael Meeks + + * eel/eel-accessibility.c + (eel_accessibility_add_simple_text): impl. + (eel_accessibility_set_text_util): impl. + (get_simple_text): + + * configure.in: require gail >= 0.11 for accessibility. + +2002-03-30 Alexander Larsson + + * test/test-eel-pixbuf-scale.c: + Don't double define DEST_WIDTH and DEST_HEIGHT. + +2002-03-29 Havoc Pennington + + * eel/eel-mateconf-extensions.c (eel_mateconf_value_is_equal): don't use + private mateconf fields, and fix a bug in comparison of equality + of list values (if (a != NULL || b != NULL) return FALSE) + +2002-03-28 Michael Meeks + + * eel/eel-labeled-image.c + (eel_labeled_image_toggle_button_new_from_file_name), + (eel_labeled_image_check_button_new_from_file_name), + (eel_labeled_image_button_new_from_file_name), + (eel_labeled_image_toggle_button_new), + (eel_labeled_image_check_button_new), + (eel_labeled_image_button_new): use the new button types + so we can update accessibility support there. + (eel_labeled_image_button_class_init): use to + override all button's get_accessibles. + (eel_labeled_image_toggle_button_get_type), + (eel_labeled_image_check_button_get_type), + (eel_labeled_image_button_get_type): impl. + (eel_labeled_image_get_accessible): handle all + button and plain label accessibility setup. + (get_image): impl. + (eel_labeled_image_accessible_image_get_size): impl. + (eel_labeled_image_accessible_get_name): impl. + (eel_labeled_image_accessible_image_interface_init), + (eel_labeled_image_accessible_class_init), + (eel_labeled_image_button_class_init), + (eel_labeled_image_get_accessible): impl. etc. + +2002-03-28 Alex Larsson + + * eel/eel-gdk-pixbuf-extensions.[ch]: + Added new function eel_gdk_pixbuf_scale_down() that does + fast downscaling. Speeds up thumbnailing. + Use it in eel_gdk_pixbuf_scale_down_to_fit(). + + * test/Makefile.am: + * test/test-eel-pixbuf-scale.c: + Tests for pixmap scaling. + +2002-03-28 Michael Meeks + + * eel/eel-gtk-extensions.c + (eel_gtk_button_set_padding): many buttons (eg. + stock ones) do not have a GTK_MISC as a child, + don't do daft things to them. + + * test/test-eel-labeled-image.c + (labeled_image_button_window_new): add a plain + labeled image. + +2002-03-28 Dave Camp + + * eel/eel-labeled-image.c + (eel_labeled_image_set_can_focus): impl. + (eel_labeled_image_class_init): add activate + signal & bindings. + (eel_labeled_image_expose_event): render + selection and focus. + +2002-03-28 Michael Meeks + + * test/test-eel-widgets.c + (create_pixbuf): use DATADIR instead of a hard + coded path. + (test_ok_dialog): impl. + (main): upd. + Add window titles to elucidate function. + + * TODO: clean & add a11y bits. + + * test/test-eel-image-chooser.c: ditto. + + * eel/eel-caption-table.c + (eel_caption_table_set_row_info): set role on + invisible entries' accessibles to 'password'. + +2002-03-27 Michael Meeks + + * eel/eel-accessibility.h + (EEL_ACCESSIBLE_FACTORY): don't auto-generate the + type name. + + * eel/eel-accessibility.c + (eel_accessibility_weak_unref): notify defunct. + +2002-03-26 Michael Meeks + + * eel/eel-accessibility.c + [ cut & paste helpers from matecomponent until gail is stable ]: + (eel_accessibility_set_atk_object_return), + (eel_accessibility_get_atk_object): impl. + (eel_a11_weak_unref, get_quark_accessible): impl. + (eel_accessibility_create_derived_type): impl. + (eel_accessibility_get_atk_object): impl. + + * eel/eel-accessibility.h + (EEL_ACCESSIBLE_FACTORY, EEL_WIDGET_SET_FACTORY): + copy from gail - we need them. + +=== eel 1.1.9 === + +2002-03-24 Alexander Larsson + + * configure.in: Bump version to 1.1.9 + + * NEWS: bump version. + +2002-03-22 Dave Camp + + * eel/eel-gtk-extensions.c: (eel_gtk_viewport_get_visible_rect), + (eel_gtk_viewport_scroll_to_rect): New functions. + * eel/eel-gtk-extensions.h: Prototypes for the eel_gtk_viewport + functions. + * eel/eel-wrap-table.c: (eel_scrolled_wrap_table_new): New + function to create a wrap table inside of a scrolled window. + (eel_wrap_table_add), (eel_wrap_table_remove): If the wrap table + is scrolled, connect to focus_in_event. + (wrap_table_child_focus_in): New function, scrolls to the focused + item in the viewport. + * eel/eel-wrap-table.h: Prototype for eel_scrolled_wrap_table_new. + +2002-03-18 Anders Carlsson + + * eel/eel-string.c: + Only include eel-lib-self-check-functions.h if + EEL_OMIT_SELF_CHECK isn't defined. + + * eel/eel-pango-extensions.c: + Only include eel-lib-self-check-functions.h if + EEL_OMIT_SELF_CHECK isn't defined. + + * eel/Makefile.am: + * eel/eel-accessibility.c: + (eel_accessibility_set_up_label_widget_relation): + * eel/eel-accessibility.h: + * eel/eel-caption-table.c: (eel_caption_table_resize): + * eel/eel-caption.c: (eel_caption_set_child): + Add new accessibility utility functions and have our + label-widget composite widgets use them. + + * test/test-eel-widgets.c: (create_pixbuf): + Update path due to e-h changes. + +2002-03-17 Darin Adler + + * configure.in: Bump required versions. + +=== eel 1.1.8 === + +2002-03-17 Alexander Larsson + + * configure.in: Bump version to 1.1.8 + + * NEWS: Bump version. + + * eel/eel-vfs-extensions.c: (eel_format_uri_for_display_internal), + (eel_escape_high_chars), (eel_make_uri_from_input_internal), + (eel_format_uri_for_display), (eel_make_uri_from_input), + (eel_self_check_vfs_extensions): + Handle utf8 and G_BORKEN_FILENAMES better. + +2002-03-13 Gregory Leblanc + + * eel.spec.in: New one, from Chris Chabot + +2002-03-11 Michael Meeks + + * eel/eel-mate-extensions.c + (eel_matecomponent_make_registration_id): impl. + +2002-03-11 Anders Carlsson + + * eel/eel-gdk-extensions.c: + * eel/eel-gdk-extensions.h: + Remove the now unneeded eel_set_mini_icon function. + +=== eel 1.1.7 === + +2002-03-10 Darin Adler + + * NEWS: Bump version. + +2002-03-09 Alexander Larsson + + * eel/eel-image-table.c: (image_table_emit_signal), + (image_table_handle_motion), (ancestor_button_press_event), + (ancestor_button_release_event): + * eel/eel-image-table.h (EelImageTableEvent): + Add the original GdkEvent to the EelImageTableEvent. You + may need e.g. the time from the event. (Needed to fix + stuck grab in caja.) + +2002-03-08 Darin Adler + + * eel/eel-preferences.c: + (eel_preferences_set_emergency_fallback_string_list): Add a + g_slist_reverse so that emergency fallback string lists are + in the proper order. + + * eel/eel-background.c: Tweak formatting. + +2002-03-07 Anders Carlsson + + * configure.in: Bump version to 1.1.7 + + * eel/eel-preferences-item.c: + (preferences_item_update_editable_string), + (preferences_item_create_editable_string), + (eel_preferences_item_new), + (preferences_item_update_displayed_value), + (eel_preferences_item_set_description): + * eel/eel-preferences-item.h: + Add EEL_PREFERENCES_ITEM_EDITABLE_PASSWORD_STRING type. + + * eel/eel-text-caption.c: (eel_text_caption_set_expand_tilde), + (eel_text_caption_set_visibility): + * eel/eel-text-caption.h: + Add eel_text_caption_set_visibility which controls the visibility + of the GtkEntry. + +2002-03-06 Darin Adler + + * eel/eel-preferences-box.c: (eel_preferences_dialog_new): Make the + button say "Close" instead of "OK". + +2002-03-06 Darin Adler + + * eel/eel-cell-renderer-pixbuf-list.c: + (eel_cell_renderer_pixbuf_list_class_init): + * eel/eel-labeled-image.c: (eel_labeled_image_class_init): + Remove strings we really don't need; lets not waste time translating + these since no one ever sees them. + + * eel/eel-password-dialog.c: (eel_password_dialog_new): Tweak comment. + + * eel/eel-preferences-box.c: Add mate-i18n.h include. Not sure why + this wasn't needed before. + + * eel/eel-preferences.c: Remove unneeded mate-i18n.h include. + +2002-03-06 Darin Adler + + * eel/eel-preferences-box.c: (eel_preferences_box_new): + * eel/eel-wrap-table.c: (eel_wrap_table_class_init): + Take out some strings that we don't really need to translate. + +2002-03-06 Michael Meeks + + * eel/eel-preferences-item.c + (preferences_item_update_enumeration_radio), + (preferences_item_update_enumeration_menu), + (enumeration_radio_changed_callback), + (enumeration_menu_changed_callback): upd. for enums + + * eel/eel-preferences.c + (eel_preferences_add_auto_enum): impl. + (preferences_entry_update_auto_storage): upd. for enums. + +2002-03-05 Michael Meeks + + * eel/eel-preferences.c + (eel_preferences_get_enum, eel_preferences_set_enum): impl. + + * eel/eel-enumeration.c (eel_enumeration_get_sub_name), + (eel_enumeration_get_sub_value): impl. + +=== eel 1.1.6 === + +2002-03-04 Darin Adler + + * eel/eel-stock-dialogs.c: (show_message_dialog): Put additional button to + the left of the other buttons. Doing it this way is pretty nasty, but I + don't know any better way to match what the HI folks want. + +2002-03-03 Alexander Larsson + + * NEWS: + * configure.in: + Bump version. + + * eel/eel-background.h: + Add eel_background_set_is_constant_size() and + eel_background_get_pixmap_and_color() + Remove eel_background_is_too_complex_for_gtk_style(). + + * eel/eel-background.c: (eel_background_init), + (eel_background_finalize), (get_pixmap_size), (eel_background_unrealize), + (eel_background_ensure_realized), (eel_background_get_pixmap_and_color), + (draw_background_callback), (eel_widget_background_changed): + Add bitmap generation and caching capability. + (eel_background_set_is_constant_size): set if windows don't change size, + used by the caja desktop window. + (eel_background_is_too_complex_for_gtk_style); Remve. Not used anymore. + (eel_background_receive_dropped_background_image): Remove old reset.png hack. + + * eel/eel-background-style.c: + (eel_background_style_finalize): unref background + (eel_background_style_draw_flat_box), (eel_background_style_set_background): + Use cached pixmaps from EelBackground. + (eel_background_style_new): Set the background. No need to mess + with the base style. + (eel_background_style_clone): Need to clone the background too. + (eel_background_style_class_init): add clone and set_background virtual + methods + +2002-03-03 Anders Carlsson + + * eel/eel-preferences-item.c: + (preferences_item_create_enumeration_list), + (preferences_item_create_enumeration_menu): + * eel/eel-string-picker.c: (eel_string_picker_set_string_list), + (eel_string_picker_insert_separator): + * eel/eel-string-picker.h: + Create the string list first and then insert it into the + string picker, instead of rebuilding the option menu + on every insert. + +2002-03-01 Darin Adler + + * eel/eel-glib-extensions.h: + * eel/eel-glib-extensions.c: (eel_g_object_list_ref), + (eel_g_object_list_unref), (eel_g_object_list_free), + (eel_g_object_list_copy), (eel_add_weak_pointer), + (eel_remove_weak_pointer): New names for old functions + from eel-gtk-extensions.c. + + * eel/eel-gtk-extensions.h: + * eel/eel-gtk-extensions.c: Remove old functions. + +2002-02-28 Darin Adler + + * eel/eel-image-chooser.c: (eel_image_chooser_set_selected_row): + Handle -1 by deselecting all rows. + +2002-02-28 Darin Adler + + * eel/eel-mate-extensions.c: (icon_selected): Since this is no longer + a callback, get rid of the widget parameter. + (icon_cancel_pressed): Get rid of the widget parameter. + (entry_activated_callback): Check result of stat. + (eel_mate_icon_selector_new): Store a pointer to the dialog that we + can use later to close it. + +2002-02-27 Anders Carlsson + + * eel/eel-password-dialog.c: (dialog_show_callback), + (eel_password_dialog_set_readonly_username): + If the username is readonly, focus the password entry. Otherwise + focus the username entry. Fixes #72801. + +2002-02-27 Darin Adler + + * eel/eel-gdk-extensions.h: + * eel/eel-gdk-extensions.c: (eel_gdk_rectangle_contains_rectangle): New. + + * eel/eel-gtk-extensions.h: + * eel/eel-gtk-extensions.c: + (eel_gtk_tree_view_cell_is_completely_visible): New. + + * eel/eel-gdk-pixbuf-extensions.c: (eel_cancel_gdk_pixbuf_load): + We need to close the loader even if we are just dropping it on the floor. + Not sure that's good design, but I want to make gdk-pixbuf happy. + + * eel/eel-image-chooser.c: (eel_scrolled_image_chooser_show_selected_row): + Only scroll if row isn't already completely visible. + +=== eel 1.1.5 === + +2002-02-25 Anders Carlsson + + * eel/eel-pango-extensions.c: + (eel_pango_font_description_get_largest_fitting_font_size): + * eel/eel-pango-extensions.h: + Implement eel_pango_font_description_get_largest_fitting_font_size. + +2002-02-22 Darin Adler + + * eel/Makefile.am: + * eel/eel.h: + * eel/eel-generous-bin.c: Re-add. + * eel/eel-generous-bin.h: Re-add. + +2002-02-21 Michael Meeks + + * eel/eel-pango-extensions.c + (eel_pango_layout_fit_to_dimensions): impl. + + * eel/eel-gdk-pixbuf-extensions.c + (eel_gdk_pixbuf_draw_layout_clipped): document. + +2002-02-22 Darin Adler + + * eel/Makefile.am: + * eel/eel.h: + * eel/eel-generous-bin.c: Remove. + * eel/eel-generous-bin.h: Remove. + * eel/eel-region.c: Remove. + * eel/eel-region.h: Remove. + + * eel/eel-image-table.c: Remove include "eel-region.h". + +2002-02-22 Darin Adler + + * eel/eel-glib-extensions.h: + * eel/eel-glib-extensions.c: + Remove unused eel_g_ptr_array_* functions. + + * eel/eel-mate-extensions.h: + * eel/eel-mate-extensions.c: + Remove unused eel_mate_canvas_world_to_window_rectangle. + (eel_mate_canvas_world_to_widget_rectangle), + (eel_mate_canvas_widget_to_world), + (eel_mate_canvas_world_to_widget): + Rename to reflect a clearer conception of these. They map to the + widget coordinate system. Clearer than trying to talk about + widget->window vs. layout->bin_window . + + * eel/eel-gtk-extensions.h: + * eel/eel-gtk-extensions.c: + Remove unused eel_gtk_style_shade, + eel_get_window_list_ordered_front_to_back, + eel_gtk_widget_standard_realize, + eel_gtk_bin_standard_size_allocate, + eel_gtk_bin_standard_size_request. + (eel_gtk_widget_get_button_event_location): New. + (eel_gtk_widget_get_motion_event_location): New. + + * test/Makefile.am: + * test/dumb-box.c: Remove. + * test/dumb-box.h: Remove. + * test/test-eel-gtk-style.c: + Just keep this compiling. Not clear if it still is useful. + + * RENAMING: at_exit -> at_shutdown + +2002-02-21 Darin Adler + + * AUTHORS: + * MAINTAINERS: + Add some people. + + * eel/eel-gdk-pixbuf-extensions.c: + (eel_gdk_pixbuf_draw_layout_clipped): + Draw nothing if the rectangle is empty or "less than empty" + rather than asserting. + +2002-02-20 David Emory Watson + + eel/eel-preferences-box.c: + (eel_preferences_box_init): Remove connect. + (user_level_changed_callback): Removed. + +2002-02-20 Michael Meeks + + * eel/eel-gdk-pixbuf-extensions.c + (eel_gdk_pixbuf_draw_layout): split out into + (eel_gdk_pixbuf_draw_layout_clipped): here, new method. + +2002-02-20 Michael Meeks + + * eel/eel-wrap-table.c (eel_wrap_table_class_init): + do an eel_type_init. + + * eel/eel-types.c (eel_type_init): protect vs. + double init. + +2002-02-19 jacob berkman + + * eel/eel-mate-extensions.c (get_terminal_command_prefix): + mate-terminal 2 does not accept --login or --start-factory-server + + * eel/eel-gtk-extensions.[ch] (eel_gtk_selection_data_*_deep): + remove as these are fixed in GTK 2.0 (fixes a double free crash) + +2002-02-19 Michael Meeks + + * eel/eel-preferences-box.c + (category_list_row_activated_callback): rename to + (category_list_selection_changed): this & use the selection's + changed signal instead. + (eel_preferences_box_new): upd. + (preferences_box_category_list_recreate): upd. + +2002-02-18 Gediminas Paulauskas + + * configure.in: remove MATE_COMMON_INIT, MATE_PLATFORM_MATE_2 + +2002-02-16 Alexander Larsson + + * eel/eel-gdk-pixbuf-extensions.c (eel_gdk_pixbuf_draw_to_pixbuf_alpha): + Add G_OBJECT() casts for g_object_ref/unref so we don't give warnings + due to pixbuf being const. + +2002-02-16 David Emory Watson + + * NEWS: Bump version. + * configure.in: Bump version. + + * eel/eel-gdk-extensions.h: + * eel/eel-gdk-extensions.c: + (eel_gdk_color_parse): New. + (eel_gdk_color_parse_with_white_default): call eel_gdk_color_parse (). + +2002-02-15 Michael Meeks + + * eel/Makefile.am: add deprecated flags + permanantly. + + * eel/eel-gdk-extensions.c + (eel_gdk_choose_foreground_color), + (eel_gdk_gc_choose_foreground_color): prune, + unused, and funky color handling. + + * test/test-eel-pixbuf-tile.c: + update image paths to include the prefix. + + * eel/eel-debug-drawing.c + (eel_debug_draw_rectangle_and_cross): make sure + we allocate the color. + +2002-02-13 Michael Meeks + + * eel/eel-image-table.c + (image_table_peek_clear_gc): upd. color handling. + (eel_image_table_set_smooth_background_color), + (eel_image_table_set_is_smooth): kill, unused. + (eel_image_table_expose_event): kill. + (image_table_foreach_child_subtract_content), + (image_table_peek_clear_gc): remove + + * eel/eel-gdk-pixbuf-extensions.c + (pixbuf_destroy_callback), + (eel_gdk_pixbuf_list_ref, eel_gdk_pixbuf_list_free): + use g_object_ref/unref instead of gdk_pixbuf_~ + + * eel/eel-gdk-extensions.c + (eel_fill_rectangle_with_color): remove, color + handling not pleasant, and not used. + (eel_gdk_gc_choose_foreground_color): upd. + + + * eel/eel-debug-drawing.c + (eel_debug_draw_rectangle_and_cross): upd. color + handling. + +2002-02-12 Michael Meeks + + * eel/eel-stock-dialogs.h (eel_create_info_dialog): + fix header comment. + +2002-02-12 Darin Adler + + * eel/eel-wrap-table.c: (eel_wrap_table_class_init): + Register enums in here. This gets rid of the last place + we had MATE2_CONVERSION_COMPLETE. + + * eel/maketypes.awk: Fix to make EEL_TYPE_X instead of + EEL_TYPE_EEL_X. + +2002-02-12 Tõivo Leedjärv + + * configure.in: Added et to ALL_LINGUAS. + +2002-02-12 Michael Meeks + + * eel/eel-preferences-box.c + (eel_preferences_box_new): create a tree view & + list model + (category_list_select_row_callback): rename to + (category_list_row_activated_callback): this & re-write.. + (preferences_box_find_row): re-write. + (preferences_model_foreach_find): impl. + (eel_preferences_box_rename_pane): re-write. + (eel_preferences_box_finalize): unref the category model. + (eel_preferences_dialog_new): show after + populating with panes, so we don't get re-sizing jerkiness + on the list. + (preferences_box_select_pane): tolerate setting the name + with the existing string. + + * eel/eel-text-caption.c: remove unused TEXT_CAPTION_INVALID + + * eel/eel-password-dialog.c: remove unused DIALOG_OK_BUTTON + +2002-02-12 Anders Carlsson + + * eel/eel-canvas-rect.c (eel_canvas_rect_realize): Surround + variable declarations with HAVE_RENDER. + +2002-02-10 Darin Adler + + * configure.in: Require newer libxml where location of xml memory + calls has moved. + * eel/eel-xml-extensions.c: Remove unneeded include of xmlmemory.h. + +==== eel 1.1.4 ==== + +2002-02-09 Darin Adler + + * NEWS: Bump version. + * configure.in: Bump version. + + * eel/eel-debug.c: + (eel_make_warnings_and_criticals_stop_in_debugger): + Add mate-vfs-modules to list of domains. + +2002-02-08 Anders Carlsson + + * eel/eel-canvas-rect.c: (eel_canvas_rect_realize), + (eel_canvas_rect_unrealize): + Chain to parent implementations. + +2002-02-06 Darin Adler + + * eel/Makefile.am: Turn on MATE_DISABLE_DEPRECATED and + EEL_COMPILATION. Get rid of eel-gobject-extensions.[ch]. + + * eel/eel-art-gtk-extensions.h: + * eel/eel-art-gtk-extensions.c: (eel_gdk_window_get_bounds), + (eel_gdk_window_get_screen_relative_bounds), + (eel_gtk_widget_get_bounds), (eel_gtk_widget_get_dimensions), + (eel_gtk_widget_get_preferred_dimensions), + (eel_gdk_window_clip_dirty_area_to_screen), + (eel_gdk_window_get_dimensions), (eel_gdk_get_pointer_position): + Eliminate misguided use of const. Fix a few deprecated things. + + * eel/eel-background-style.c: (eel_gdk_window_update_sizes): + Use gdk_drawable_get_size instead of gdk_window_get_size. + + * eel/eel-background.c: (draw_background_callback): Use g_object_unref + instead of gdk_gc_unref. + (eel_get_widget_background): Use g_signal_connect_object instead + of eel_signal_connect_object_while_alive. + + * eel/eel-debug-drawing.c: (eel_debug_draw_rectangle_and_cross): + Use g_object_unref instead of gdk_gc_unref. + + * eel/eel-debug.c: Turn this back on. + + * eel/eel-mate-extensions.c: (eel_mate_icon_selector_new): Get + rid of a misguided use of eel_signal_connect_while_alive -- plain + old g_signal_connect works fine. + + * eel/eel-gobject-extensions.c: Remove. + * eel/eel-gobject-extensions.h: Remove. + + * eel/eel-image-table.c: (eel_image_table_unrealize): Use g_object_unref + instead of gdk_gc_unref. + + * eel/eel-labeled-image.c: (eel_labeled_image_check_button_new): Get + rid of some misguided use of eel_signal_connect_while alive -- plain + old g_signal_connect works fine. + + * eel/eel-password-dialog.c: (eel_password_dialog_new): Get + rid of some misguided use of eel_signal_connect_while alive -- plain + old g_signal_connect works fine. + + * eel/maketypes.awk: Grab a new copy from gtk+. Is there a way to do + this without copied and pasted code? + * eel/eel-types.c: (eel_type_init): Change name to EEL_TYPE_N_BUILTINS. + + * test/Makefile.am: Turn on G_DISABLE_DEPRECATED, GDK_DISABLE_DEPRECATED, + GTK_DISABLE_DEPRECATED, MATE_DISABLE_DEPRECATED. + + * test/test-eel-background.c: (main): Turn of GtkCTree code that was + already half-disabled. + + * test/test-eel-canvas-items.c: (item_event), (setup_item), + (create_canvas_items), (create_canvas): gtk_signal_connect -> g_signal_connect. + Remove some colormap stuff. gtk_widget_set_usize -> gtk_widget_set_size_request. + gtk_window_set_policy -> gtk_window_set_resizable. + * test/test-eel-gtk-style.c: (color_box_expose_event): gdk_gc_unref -> g_object_unref. + (pixmap_box_expose_event): gdk_window_get_size -> gdk_drawable_get_size. + * test/test.c: (test_window_new): gtk_window_set_policy -> gtk_window_set_resizable + +2002-02-06 Michael Meeks + + * eel/eel-wrap-table.c + (eel_wrap_table_class_init), + (eel_wrap_table_set_property), + (eel_wrap_table_get_property): ditto + + * eel/makeenums.pl (parse_entries): output + GEnumValue not GtkEnumValue - this should use + glib-mkenums though. + + * eel/eel-gtk-extensions.c + (eel_gtk_signal_connect_full_while_alive), + (eel_gtk_signal_connect_free_data_custom): + port deprecated bits. + (eel_gtk_class_name_make_like_existing_type): + remove - unused & not portable. + + * eel/eel-mate-extensions.c + (eel_mate_icon_selector_new): remove all + deprecated bits. + + * eel/eel-dateedit-extensions.c + (eel_mate_date_edit_get_date_as_string): ditto. + + * eel/eel-labeled-image.c + (eel_labeled_image_class_init), + (eel_labeled_image_set_property), + (eel_labeled_image_get_property), + (eel_labeled_image_check_button_new): ditto. + + * eel/eel-preferences-item.c + (preferences_item_update_displayed_value), + (preferences_item_update_displayed_value): ditto. + + * eel/eel-stock-dialogs.c + (timed_wait_callback): ditto. + +2002-02-05 Michael Meeks + + * eel/eel-dateedit-extensions.c + (eel_mate_date_edit_get_date_as_string): add + deprecated comment. + + * eel/eel-background.c + (eel_background_reset), + (eel_background_set_color), + (eel_get_widget_background), + (eel_background_set_image_placement), + (eel_background_load_image_callback), + (eel_background_cancel_loading_image), + (eel_background_set_image_uri_helper), + (set_image_and_color_image_loading_done_callback), + (eel_background_class_init): build with deprecated + things disabled. + + * eel/eel-radio-button-group.c + (eel_radio_button_group_class_init): ditto. + + * eel/eel-preferences-item.c + (preferences_item_update_custom), + (eel_preferences_item_set_description): ditto. + + * eel/eel-caption-table.c + (eel_caption_table_class_init, entry_activate), + (eel_caption_table_resize): ditto. + + * eel/eel-password-dialog.c + (eel_password_dialog_new): ditto. + + * eel/eel-gtk-extensions.c + (handle_standard_close_accelerator), + (eel_gtk_menu_set_item_visibility), + (alive_disconnecter), + (eel_gtk_signal_connect_while_realized): ditto. + + * eel/eel-mate-extensions.c + (try_terminal_command), + (eel_mate_icon_selector_new): ditto. + + * eel/eel-ellipsizing-label.c + (eel_ellipsizing_label_new): ditto. + + * eel/eel-text-caption.c + (eel_text_caption_class_init), + (eel_text_caption_set_editable), + (eel_text_caption_init, eel_text_caption_init): ditto. + + * eel/eel-string-picker.c + (eel_string_picker_class_init): ditto. + + * eel/eel-stock-dialogs.c + (timed_wait_delayed_close_timeout_callback), + (eel_show_info_dialog_with_details), + (delete_event_callback): ditto. + +2002-02-05 Darin Adler + + * eel/eel-clist.c: Remove. + * eel/eel-clist.h: Remove. + * eel/eel-ctree.c: Remove. + * eel/eel-ctree.h: Remove. + * eel/eel-dnd.c: Move back into Caja. + * eel/eel-dnd.h: Move back into Caja. + * eel/eel-list-column-title.c: Remove. + * eel/eel-list-column-title.h: Remove. + * eel/eel-list.c: Remove. + * eel/eel-list.h: Remove. + * eel/eel.h: Housekeeping. + * eel/Makefile.am: Housekeeping. + +==== eel 1.1.3 ==== + +2002-02-04 Darin Adler + + * NEWS: Update for 1.1.3. + * .cvsignore: Don't ignore the tarballs. + + * eel/eel-pango-extensions.c: (eel_string_ellipsize_middle): + * eel/eel-wrap-table.c: (wrap_table_layout): Fixes to make things + compile with gcc 3.0.2, based on a patch contributed by Anush + . + +2002-02-04 Laszlo Peter + + * COPYING: change to LGPL + + * eel/eel-background-style.c eel/eel-background-style.h + eel/eel-background.c eel/eel-background.h + eel/eel-dateedit-extensions.c eel/eel-dateedit-extensions.h + eel/eel-debug-drawing.c eel/eel-debug-drawing.h eel/eel-debug.c + eel/eel-debug.h eel/eel-enumeration.c eel/eel-enumeration.h + eel/eel-graphic-effects.h eel/eel-gtk-macros.h + eel/eel-lib-self-check-functions.c + eel/eel-lib-self-check-functions.h eel/eel-list-column-title.c + eel/eel-list-column-title.h eel/eel-region.c eel/eel-region.h + eel/eel-self-checks.c eel/eel-self-checks.h + eel/eel-string-list.c eel/eel-string-list.h: correct licensing + information in the headers by permission of the Copyright holders. + +Mon Feb 4 11:24:21 2002 Owen Taylor + + * eel/eel-mate-extensions.c (dialog_response_callback): + Labels need a statement after them. (Fixes -Werror problem + with recent GCC.) + +2002-01-30 Darin Adler + + * eel/eel-preferences-item.h: + * eel/eel-preferences-item.c: + (preferences_item_update_font), + (font_changed_callback), (preferences_item_create_font), + (eel_preferences_item_new), + (preferences_item_update_displayed_value), + (eel_preferences_item_set_description): + Make EEL_PREFERENCE_ITEM_FONT use the Eel font picker, and get + rid of all support for EEL_PREFERENCE_ITEM_SMOOTH_FONT. + +2002-01-30 Darin Adler + + * configure.in: Bump to 1.1.3 since we have an API change. + + * eel/eel-dnd.h: start_x and start_y are in window coordinates, + not world coordinates. + + * eel/eel-mate-extensions.h: + * eel/eel-mate-extensions.c: + (eel_mate_canvas_world_to_canvas_window_rectangle): New. + (eel_mate_canvas_canvas_window_to_world): New. + (eel_mate_canvas_world_to_canvas_window): New. + +==== eel 1.1.2 ==== + +2002-01-29 Darin Adler + + * eel/eel-pango-extensions.c: (eel_self_check_ellipsize), + (eel_self_check_pango_extensions): Turn off ellipsizing self-checks + because they are failing for me. + +2002-01-29 Darin Adler + + * NEWS: Update for 1.1.2 release. + +2002-01-28 Gediminas Paulauskas + + * eel/eel-glib-extensions.c, eel/eel-glib-extensions.h: + (eel_g_list_copy): remove, it was moved into glib. + * eel/eel-gtk-extensions.c, eel/eel-gtk-extensions.h: + (eel_gtk_window_present): remove, it was moved into gtk+. + +2002-01-28 Darin Adler + + * eel/Makefile.am: Use LC_ALL instead of LC_COLLATE. + * eel/eel-mate-extensions.c: (eel_mate_canvas_item_send_behind): + Oops, it was sending things in front. + +2002-01-27 Anders Carlsson + + * eel/eel-stock-dialogs.c (eel_run_simple_dialog): Start with + a response id that is 0. + +2002-01-27 Darin Adler + + * eel/eel-mate-extensions.h: + * eel/eel-mate-extensions.c: (eel_mate_canvas_item_send_behind): New. + +2002-01-27 Alexander Larsson + + * acconfig.h: + Add HAVE_RENDER + + * configure.in: + Add checks for Xrender + + * eel/Makefile.am: + Add RENDER_LIBS and eel-canvas-rect.[ch] + + * eel/eel-canvas-rect.[ch]: + New type EelCanvasRect. Implemented for the Caja + selection rectangle. + + * eel/eel-lib-self-check-functions.h: + Add eel_self_check_canvas_rect to list of tests + + * test/test-eel-canvas-items.c: + Add a test of the eel canvas items. + + * test/Makefile.am: + Build test-eel-canvas-items + +2002-01-24 Darin Adler + + * eel/eel-pango-extensions.h: + * eel/eel-pango-extensions.c: (eel_pango_ft2_get_context): New. + + * eel/eel-gtk-extensions.c: (create_pango_ft2_context): Use + the new eel_pango_ft2_get_context. + +2002-01-23 Peteris Krisjanis + + * eel/configure.in: added lv to ALL_LINGUAS + +2002-01-22 Darin Adler + + * eel/eel-font-picker.c: (font_picker_get_index_for_font): + Handle NULL family_name. + +2002-01-21 Darin Adler + + * eel/eel-font-picker.h: + * eel/eel-font-picker.c: + * test/test-eel-font-picker.c: + Rewrite to use Pango -- first cut, not done yet. + + * eel/eel-preferences-item.c: + (preferences_item_create_smooth_font): Pass NULL for the PangoContext. + +2002-01-19 Gediminas Paulauskas + + * eel/eel-glib-extensions.c: (eel_strdup_strftime): + Convert format string into locale encoding at start, and convert back + into utf-8 the result. + +2002-01-19 Darin Adler + + * test/test-eel-gtk-style.c: (style_get_color), (style_get_gc): + Fix mistake in that last change that didn't compile. + +2002-01-19 Darin Adler + + * test/test-eel-gtk-style.c: (style_get_color), (style_get_gc): + Tweak code so gcc 3.x doesn't give warnings. + +2002-01-18 Darin Adler + + * TODO: Remove some already-done items. + + * eel/check-program.c: (main): Use the new eel_debug_shut_down. + + * eel/eel-debug.h: + * eel/eel-debug.c: (eel_debug_shut_down), + (eel_debug_call_at_shutdown), + (eel_debug_call_at_shutdown_with_data): New. + + * eel/eel-debug-drawing.c: (eel_debug_show_pixbuf): + * eel/eel-enumeration.c: (enumeration_table_get): + * eel/eel-font-picker.c: (global_font_list_get): + * eel/eel-mateconf-extensions.c: (eel_mateconf_client_get_global): + * eel/eel-gdk-pixbuf-extensions.c: + (eel_gdk_pixbuf_get_global_buffer): + * eel/eel-glib-extensions.c: (eel_g_hash_table_new_free_at_exit): + * eel/eel-preferences.c: (preferences_global_table_get_global): + Switch from g_atexit to eel_debug_call_at_shutdown. + + * eel/eel-image-table.h: + * eel/eel-image-table.c: (eel_image_table_class_init), + (eel_image_table_init), (eel_image_table_new): Get rid of + set_is_smooth signal, eel_image_table_set_is_smooth, and use of + eel_smooth_widget calls. + + * eel/eel-image-with-background.c: Remove. + * eel/eel-image-with-background.h: Remove. + * eel/eel-image.c: Remove. + * eel/eel-image.h: Remove. + * eel/eel-smooth-widget.c: Remove. + * eel/eel-smooth-widget.h: Remove. + * eel/eel-viewport.c: Remove. + * eel/eel-viewport.h: Remove. + + * eel/Makefile.am: Kill eel-image-with-background.[ch], + eel-image.[ch], eel-smooth-widget.[ch], eel-viewport.[ch]. + * eel/eel.h: Ditto. + + * eel/eel-labeled-image.c: (eel_labeled_image_get_arg), + (eel_labeled_image_add), (eel_labeled_image_remove), + (labeled_image_ensure_image), (eel_labeled_image_set_pixbuf), + (eel_labeled_image_set_pixbuf_from_file_name): Port from EelImage + to GtkImage. + + * eel/eel-radio-button-group.c: + (eel_radio_button_group_set_entry_pixbuf): Port from EelImage to + GtkImage. + + * test/test-eel-image-table.c: (image_table_new_scrolled): Port + from EelViewport to GtkViewport. + + * THANKS: Fix typo. + * eel/eel-wrap-table.c: Fix comment format. + + * test/test-eel-image-background.c: Remove. + * test/test-eel-image-simple.c: Remove. + * test/test-eel-viewport-constraint.c: Remove. + + * test/.cvsignore: Remove obsolete tests. + * test/Makefile.am: Remove obsolete tests. + + * test/test-eel-image-chooser.c: (main): Remove eel_smooth_widget + call. + + * test/test.c: Remove EelImage code. + +2002-01-17 Darin Adler + + * eel/eel-pango-extensions.c: + (eel_pango_layout_set_text_ellipsized): Soften an assert to + a g_return. + +2002-01-17 Darin Adler + + * eel/Makefile.am: Fix parallel builds by getting rid of an + ill-advised use of a full path to the library. + + * eel/eel-pango-extensions.c: (eel_string_ellipsize_start), + (eel_string_ellipsize_end): These were reversed. + + * test/.cvsignore: test-eel-ellipsizing + +2002-01-17 Anders Carlsson + + * eel/eel-cell-renderer-pixbuf-list.h: Fix warning. + + * eel/Makefile.am: + Add eel-cell-renderer-pixbuf-list.[ch] + + * eel/eel-background-style.c: (eel_background_style_draw_flat_box): + Special case GtkTreeView. + + * eel/eel-cell-renderer-pixbuf-list.c: + * eel/eel-cell-renderer-pixbuf-list.h: + Add these. + + * eel/eel-stock-dialogs.c: (show_ok_dialog): + Set default response to GTK_RESPONSE_OK. + +2002-01-16 Darin Adler + + * configure.in: Bump version to 1.1.2. + +2002-01-16 Darin Adler + + * eel/eel-gdk-pixbuf-extensions.c: (eel_gdk_pixbuf_draw_layout): + Fix case where clipped height or width turns out to be 0. + * eel/eel-gtk-macros.h: Remove some unused macros, deprecate + others. + * eel/eel-pango-extensions.c: Remove extra include. + * eel/eel-preferences-box.c: (eel_preferences_dialog_new): + Don't try to eel_gtk_window_set_up_close_accelerator, since it's + a dialog that already has a close accelerator. + +2002-01-11 Havoc Pennington + + * eel/eel.h: add eel-pango-extensions.h + + * eel/eel-pango-extensions.c + (eel_pango_layout_set_text_ellipsized): put ellipsize code back in + here and port to Pango + + * eel/eel-ellipsizing-label.c: re-enable ellipsization in the + widget, change bad hack implementation to different bad hack + implementation to avoid queueing a resize in size_allocate + (real_style_set): remove style_set handler because it results in a + queue_resize anyway + (real_size_allocate): auto-select ellipsize mode based on label + alignment + +==== eel 1.1.1 ==== + +2002-01-15 Darin Adler + + * NEWS: Get ready for eel 1.1.1 release. + * eel/Makefile.am: Fix makeenums.pl stuff so it works when + srcdir != destdir. + +2002-01-15 Darin Adler + + * eel/eel-gtk-extensions.c: (create_pango_ft2_context): + Tiny tweak to the code -- makes it more readable, I think. + +2002-01-09 Alexander Larsson + + * eel/eel-gtk-extensions.c (create_pango_ft2_context): + Copy the font description from the base_context. + +Thu Jan 10 10:53:52 2002 Owen Taylor + + * eel/eel-mate-extensions.c + (eel_mate_canvas_world_to_window_rectangle): Remove + unused variable so things compile. + +2002-01-09 Darin Adler + + * eel/eel-mate-extensions.h: + * eel/eel-mate-extensions.c: + Remove mate_win_hints_*. + + * eel/eel-list.c: (eel_list_destroy): Something I missed in the + last change -- forgot to NULL out details. + +2002-01-09 Darin Adler + + * eel/eel-list.c: (eel_list_destroy), + (unschedule_keyboard_row_reveal): + Protect against double destroys, but do it in an inelegant way, + which shouldn't matter, since we plan to remove this class. + +2002-01-09 Darin Adler + + * eel/eel-gdk-font-extensions.c: Remove. + * eel/eel-gdk-font-extensions.h: Remove. + +2002-01-08 Darin Adler + + * eel/Makefile.am: + * eel/eel-ctree.c: + * eel/eel-ellipsizing-label.c: + * eel/eel-lib-self-check-functions.h: + * eel/eel-list.c: + * eel/eel.h: + Remove eel-gdk-font-extensions.[ch] + + * eel/eel-clist.h: Fix some overzealous global replace. + + * eel/eel-gobject-extensions.c: + (eel_signal_connect_object_while_alive), + (eel_signal_connect_while_alive): + Add some more g_return_if_fail. + + * eel/eel-gtk-extensions.h: + * eel/eel-gtk-extensions.c: (eel_gtk_label_set_scale): New. + (eel_gtk_widget_set_foreground_color): Set text color too. + + * eel/eel-image-table.c: + * eel/eel-image.c: + * eel/eel-labeled-image.c: + Add includes needed now that eel-gtk-extensions doesn't include + gtkclist.h or gtkpixmap.h any more. + + * eel/eel-pango-extensions.h: + * eel/eel-pango-extensions.c: (eel_pango_attr_list_copy_or_create), + (eel_pango_attr_list_apply_global_attribute): New helper functions + used by the eel_gtk_label_set_scale and the other code in here. + (apply_global_attribute): New name for an old function. + (eel_pango_layout_set_weight): New. + + * eel/eel-wrap-table.c: (eel_wrap_table_class_init): + Don't add the enums, since we just get lots of complaints and we + don't really use them right now. + +2002-01-05 Christian Rose + + * configure.in: Added "ms" to ALL_LINGUAS. + +2002-01-04 Havoc Pennington + + * eel/eel-mateconf-extensions.c (eel_mateconf_monitor_add): don't do the + recursive preload here, too much stuff in /apps/caja it seems + like. Rely on explicit preloads in other code. + + * eel/eel-font-picker.c (font_picker_get_selected_style_entry): + add FIXME and MATE2_CONVERSION_COMPLETE for similar + option_menu->menu_item issue + + * eel/eel-string-picker.c (eel_string_picker_get_selected_string): + use gtk_option_menu_get_history() instead of setting item index + as object data - option_menu->menu_item is no longer non-NULL + apparently, when we want it to be. + + * eel/eel-mateconf-extensions.c + (eel_mateconf_value_get_eel_string_list): add a function to get an + EelStringList + + * eel/eel-preferences-item.c + (preferences_item_create_enumeration_list): use emergency fallback + instead of default for deciding on number of string pickers + + * eel/eel-graphic-effects.c: don't include art_config.h, it + ended up being included twice and has no include guards + + * eel/eel-preferences.c: remove user levels, remove concept of + installing defaults here, never "fix" invalid values in mateconf + database (as we did when a list of enum values was invalid), don't + bother to cache values since MateConfClient does already, remove + callbacks_blocked which incorrectly relied on + synchronicity/non-reentrancy of mateconf, don't store the default + value, remove all suggest_sync + (eel_preferences_set_emergency_fallback): new function to replace + setting defaults + (eel_preferences_get_emergency_fallback): getter + + * eel/eel-mateconf-extensions.c (eel_mateconf_preload_cache): New + function to allow us to get a bunch of MateConf data in a single + round trip + (eel_mateconf_get_default_value): new function to get the default + from the schema + +2002-01-04 Darin Adler + + * HACKING: Update. + * NEWS: Update. + * README: Update. + * TODO: Update. + * MAINTAINERS: Update. + * Makefile.shared: Remove. + + * configure.in: Clean up. Update requirements. + * eel-2.0.pc.in: Remove bogus matecomponent-activation dependency. + * eel.spec.in: Remove bogus oaf dependency. + * eel/Makefile.am: Do CFLAGS and LIBS a new better way. + * test/Makefile.am: Change name of CFLAGS. + + * eel/eel-graphic-effects.c: Get rid of extra include. + +2002-01-04 Anders Carlsson + + * eel/eel-gdk-extensions.c (eel_gdk_rgb_to_color): Fix up + color conversion routines, as suggested by Darin. + (eel_self_check_gdk_rgb_to_color): Add debug function. + (eel_gdk_color_as_hex_string): Print all 48 bits of the + color. + (eel_self_check_gdk_extensions): Add some tests for + eel_gdk_rgb_to_color. + +2002-01-03 Darin Adler + + * test/Makefile.am: + * test/test-eel-font-picker.c: (main): + Loose ends from removing EelFontManager. + +2002-01-03 Darin Adler + + * eel/eel-mate-extensions.c: (get_terminal_command_prefix): + Port to use libmate to get terminal choice from MateConf. + + * eel/Makefile.am: + * eel/eel-font-manager.c: Remove. + * eel/eel-font-manager.h: Remove. + * eel/eel-font-picker.c: + * eel/eel-lib-self-check-functions.h: + * eel/eel.h: + * test/.cvsignore: + * test/Makefile.am: + * test/test-eel-font-manager.c: Remove. + * test/test-eel-font-picker.c: (main): + Remove EelFontManager. + +2002-01-03 Darin Adler + + * RENAMING: Lets take those "-extensions" off the names of all + the header files, since "eel" already contains the concept that + it's "extensions". I'll probably do this soon since I have the + access to do the CVS magic now. + + * eel/eel-mate-extensions.c: + (eel_mate_stock_set_icon_or_register): Remove. + + * eel/eel-gtk-extensions.c: + (eel_gtk_window_is_on_current_workspace_and_area) Remove. + + * eel/eel-gdk-font-extensions.c: (xlfd_string_get_nth_as_int): + * eel/eel-preferences-item.c: (update_integer_settings_at_idle): + * eel/eel-string.c: (eel_eat_str_to_int) (eel_self_check_string): + * eel/eel-string.h: + * test/test.c: (test_text_caption_get_text_as_int): + Death to eel_eat_str_to_int. I basically can't face Owen in + public when I know that I have an interface like that in code + that I wrote. + +2002-01-03 Anders Carlsson + + * eel/eel-pango-extensions.c + * eel/eel-pango-extensions.h + (eel_pango_layout_set_font_desc): Remove this function since + pango_layout_set_font_description does the same thing and + better. + +2002-01-03 Darin Adler + + * eel/Makefile.am: + * eel/eel-canvas-rect.c: Removed. + * eel/eel-canvas-rect.h: Removed. + * eel/eel-lib-self-check-functions.h: + Bye for now to EelCanvasRect. If we do this optimization, it + should be in libmatecanvas itself. + + * eel/eel-font-picker.c: (font_picker_populate), + (global_font_list_free), (global_font_list_get), + (font_picker_find_entries_for_font): + Hack to get rid of asserts about empty font list. This is + a short term solution. Long term we have to decide what + we are going to offer for choosing fonts. + +2002-01-03 Darin Adler + + * eel/eel-graphic-effects.c: + Fix the include. It's not legal to include art_config.h + directly. I added an art_misc.h include so that things + will work with older libart and people won't get confused. + + * data/.cvsignore: + * data/fonts/.cvsignore: + * data/fonts/urw/.cvsignore: + Re-remove these. Michael added them back in rather than + deleting the obsolete files. + + * test/.cvsignore: + Re-remove the obsolete entries in here. Again, Michael + added these back in rather than deleting the obsolete + files in his directory. + +2002-01-03 Michael Meeks + + * eel/eel-gdk-pixbuf-extensions.c + (eel_gdk_pixbuf_save_to_file): use gdk-pixbuf's save code. + + * eel/eel-graphic-effects.c: add art_config.h include. + + * eel/eel-font-manager.c: use DATADIR not EEL_DATADIR. + +2002-01-03 Anders Carlsson + + * eel/eel-pango-extensions.h: + * eel/eel-pango-extensions.c: Use the API Darin suggested instead + since that makes more sense. + +2002-01-02 Darin Adler + + * configure.in: Remove unused libpng code. + * eel.spec.in: Remove libpng, fonts, and librsvg. + +2002-01-02 Darin Adler + + * Makefile.am: + * configure.in: + * data/: Remove all of the data, since it was fonts that are not + needed any more. + + * configure.in: + * eel-2.0.pc.in: + Remove dependency on librsvg. + + * eel/Makefile.am: + * eel/eel-font-picker.h: + * eel/eel-glyph.c: Removed. + * eel/eel-glyph.h: Removed. + * eel/eel-label.c: Removed. + * eel/eel-label.h: Removed. + * eel/eel-lib-self-check-functions.h: + * eel/eel-scalable-font-private.h: Removed. + * eel/eel-scalable-font.c: Removed. + * eel/eel-scalable-font.h: Removed. + * eel/eel-smooth-text-layout.c: Removed. + * eel/eel-smooth-text-layout.h: Removed. + * eel/eel.h: + * test/test-eel-font-manager.c: + * test/test-eel-font-picker.c: (update_font), + (font_changed_update_label_callback), (use_defalt_font_callback), + (use_defalt_bold_font_callback), (main): + * test/test-eel-gtk-style.c: + * test/test-eel-image-scrolled.c: (toggle_smooth_callback), + (label_window_new), (label_window_new_scrolled): + Remove eel-glyph, eel-label, eel-scalable-font, eel-smooth-text-layout. + + * eel/eel-graphic-effects.c: + Remove incorrect art_config.h include. + + * eel/eel-labeled-image.c: (eel_labeled_image_add), + (eel_labeled_image_remove), (labeled_image_ensure_label), + (eel_labeled_image_set_text), (eel_labeled_image_get_text): + * test/test-eel-viewport-constraint.c: + (summary_view_item_label_new): + Port to GtkLabel from EelLabel. + + * test/.cvsignore: + * test/Makefile.am: + * test/test-eel-font-simple.c: Remove. + * test/test-eel-font.c: Remove. + * test/test-eel-glyph-simple.c: Remove. + * test/test-eel-glyph.c: Remove. + * test/test-eel-label-flavorful.c: Remove. + * test/test-eel-label-offset.c: Remove. + * test/test-eel-label-scrolled.c: Remove. + * test/test-eel-label-simple.c: Remove. + * test/test-eel-label-wrapped.c: Remove. + * test/test-eel-label.c: Remove. + * test/test-eel-smooth-text-layout.c: Remove. + Remove test-eel-font*, test-eel-glyph*, test-eel-label*. + + * test/test.h: + * test/test-eel-pixbuf-tile.c: + Change test includes around a tiny bit. + +2002-01-02 Darin Adler + + * eel/Makefile.am: + * eel/eel-clickable-image.c: + * eel/eel-clickable-image.h: + * eel/eel-label-with-background.c: + * eel/eel-label-with-background.h: + * eel/eel-lib-self-check-functions.h: + * eel/eel-smooth-text-layout-cache.c: + * eel/eel-smooth-text-layout-cache.h: + * eel/eel.h: + * test/test-eel-clickable-image.c: + * test/test-eel-label-background.c: + * test/Makefile.am: + * test/test.c: + Delete some unused classes and files. More to come. + + * eel/eel-ellipsizing-label.c: (real_finalize), + (eel_ellipsizing_label_class_init): + Use finalize instead of destroy. + + * eel/eel-labeled-image.c: + * eel/eel-labeled-image.h: + * test/test-eel-image-table.c: (labeled_image_new): + Remove some unused functions that are hard to implement with + GtkLabel (instead of EelLabel). + +2002-01-02 Darin Adler + + * eel/eel-gdk-pixbuf-extensions.c: (eel_gdk_pixbuf_draw_layout): + Clip the ink_rect to what will fit in the buffer. This prevents + problems with gdk_pixbuf_composite, which doesn't help us with + clipping at all. + +2002-01-02 Darin Adler + + * eel/eel-mate-extensions.c: (eel_mate_canvas_get_pango_context): + * eel/eel-gtk-extensions.h: + * eel/eel-gtk-extensions.c: (create_pango_ft2_context), + (eel_gtk_widget_get_pango_ft2_context): + Add new function to get a freetype2 context for drawing on the + client side. Code moved from the canvas-specific function that + was in here before. + +2002-01-02 Frederic Crozat + + * eel/eel-background.c: (eel_background_ensure_image_scaled), + (eel_background_start_loading_image), + (eel_background_set_image_uri_helper), + (eel_background_set_image_uri), + (eel_background_set_image_uri_sync), + (eel_background_set_image_uri_and_color): + * eel/eel-background.h: + Add support for synchronous loading of image (needed to fix + flash when starting Caja desktop) + +2002-01-02 Anders Carlsson + + * eel/eel-image-chooser.c: Use gtk_tree_model_get instead + of gtk_tree_model_get_value; this simplifies a lot since we + don't need to fool around with GValues. + +2002-01-01 Anders Carlsson + + * test/test-eel-image-chooser.c: Update picture paths. + + * eel/eel-pango-extensions.h: New file. + + * eel/eel-pango-extensions.c: New file. + + * eel/eel-vfs-extensions.c (eel_read_file_async): Fix the argument + order. + + * eel/eel-text-caption.c (eel_text_caption_init): + Call gtk_entry_set_activates_default. + + * eel/eel-radio-button-group.c (eel_radio_button_group_insert): Enable + mnemonic support. + + * eel/eel-image-chooser.c: Rewrite to use GtkTreeView. + + * eel/eel-image-chooser.h: Inherit from GtkTreeView and remove + an unused and unneeded API call. + + * eel/eel-caption.c (eel_caption_set_title_label): Use + gtk_label_set_text_with_mnemonic instead. + (eel_caption_set_child): Use gtk_label_set_mnemonic_widget. + +2001-12-20 Darin Adler + + * eel/eel-gdk-pixbuf-extensions.c: (eel_gdk_pixbuf_draw_layout): + Use ink_rect now that the pango bug that was plaguing me is fixed. + + * eel/eel-mate-extensions.c: (create_pango_context_for_aa_canvas): + Remove some unneeded casts. + +2001-12-21 Duarte Loreto + + * configure.in: Added new pt translation to ALL_LINGUAS + +2001-12-18 Michael Meeks + + * eel/eel-mateconf-extensions.c (eel_mateconf_monitor_add): + recursively cache the MateConf keys to reduce CORBA traffic. + +2001-12-17 Darin Adler + + * eel/eel-gdk-pixbuf-extensions.c: (eel_gdk_pixbuf_draw_layout): + Use the logical_rect to determine the left side. + + * eel/eel-debug.c: + (eel_make_warnings_and_criticals_stop_in_debugger): + Add GdkPixbuf. + +2001-12-17 Darin Adler + + * eel/eel-gdk-pixbuf-extensions.h: + * eel/eel-gdk-pixbuf-extensions.c: (eel_gdk_pixbuf_draw_layout): + Simplified parameters. + + * eel/eel-debug.c: + (eel_make_warnings_and_criticals_stop_in_debugger): Turn this back on. + Michael turned it off by accident. + +2001-12-13 Darin Adler + + * eel/eel-gdk-pixbuf-extensions.h: + * eel/eel-gdk-pixbuf-extensions.c: (eel_draw_layout_to_pixbuf): + New function for drawing with Pango. Seems to be agonizingly slow + due to lack of cache, but I'm not sure if that's the problem. + + * eel/eel-mate-extensions.h: + * eel/eel-mate-extensions.c: (create_pango_context_for_aa_canvas), + (eel_mate_canvas_get_pango_context): Helper function for getting + the appropriate context when drawing to an anti-aliased MateCanvas. + + * eel/eel-gtk-extensions.c: Add an include that's needed now that + I removed excess includes from eel-mate-extensions.h. + +2001-12-12 Michael Meeks + + * eel/eel-list-column-title.c (eel_list_column_title_paint): + remove erroneous style unref. + +2001-12-11 Laszlo Peter + + * eel/Makefile.am: add dependencies to fix building with make -j + +2001-12-09 Anders Carlsson + + * eel/eel-caption-table.c: (eel_caption_table_resize), + (eel_caption_table_set_row_info): Use gtk+ mnemonics. + + * eel/eel-mate-extensions.c: (icon_selected_callback), + (icon_cancel_pressed), (dialog_response_callback), + (entry_activated), (eel_mate_icon_selector_new): + * eel/eel-mate-extensions.h: + Bring back the eel icon selector and remove the + eel_dialog_get_button_by_index function. + + * eel/eel-password-dialog.c: + (caption_table_activate_callback): + Use gtk_window_activate_default instead of calling + gtk_button_clicked on the ok button. + (eel_password_dialog_new): + Use mnemonics in the Username and Password + labels. + +2001-12-08 Michael Meeks + + * eel/eel-list.c: populate from stable & port + + * eel/eel-list-column-title.c: build it + + * eel/eel-clist.[ch]: cross port changes to Gtk+2.0's + version of GtkCList. + + * eel/eel-ctree.[ch]: cross port changes to Gtk+2.0's + version of GtkCTree. + + * eel/eelmarshal.list: add lots of marshallers. + +2001-12-07 Darin Adler + + * eel/eel-art-extensions.c: (eel_art_irect_union): Add missing return. + +2001-12-07 Laszlo Peter + + * eel/eel-art-extensions.c, eel/eel-debug-drawing.c: replace illegal + uses of the ternary operator with if-else. + + * test/test-eel-clickable-image.c, test/test-eel-image-table.c: + s/__FUNCTION__/G_GNUC_FUNCTION/ + +2001-12-06 Darin Adler + + * lots of files + Get rid of unneeded casts in calls to g_object_ref/unref. + +2001-12-06 Darin Adler + + * eel/eel-debug.c: (log_handler): Remove the code that adds the + program name and pid to each message. glib now has that built + in if you set the G_MESSAGES_PREFIXED environment variable. + + * eel/eel-debug.h: + * eel/eel-debug.c: + (eel_make_warnings_and_criticals_stop_in_debugger), + New strategy for the call that makes warnings and criticals + stop in the debugger. We just use a hard-coded list of domains + here in Eel, rather than asking the caller to pass in the list + of domains. Forward looking to the day when we can do this + without explicitly doing it for each domain. + + * eel/check-program.c: (main): + * test/test.c: (test_init): + Fix callers that no longer need to list the domains. + +2001-11-30 Darin Adler + + * eel/Makefile.am: + * eel/eel-background-style.c: + * eel/eel-background-style.h: + Create EelBackgroundStyle subclass for GtkStyle that implements + gradients. This is a better version of a hack we used for Gtk 1.X. + + * eel/eel-background.c: (eel_background_set_widget_style): Use + EelBackgroundStyle. + (eel_self_check_background): Fix an unref/sink thing. + + * eel/eel-background.c: + (eel_background_receive_dropped_color): + * test/test-eel-image-background.c: + (window_new_with_eel_background_gradient), + (window_new_with_gtk_background_hacked): + * test/test-eel-label-background.c: + (window_new_with_eel_background_gradient), + (window_new_with_gtk_background_hacked): + * test/test-eel-label.c: + (red_background_color_value_changed_callback), + (green_background_color_value_changed_callback), + (blue_background_color_value_changed_callback), + (create_background_frame): + * test/test-eel-viewport-constraint.c: (create_row): + Change all rgb:RRRR/GGGG/BBBB to use #RRGGBB format instead. + + * eel/eel-gdk-extensions.h: Fix typo in name of unimplemented + function. I should probably just delete it. + + * eel/eel-gdk-extensions.c: + (eel_gdk_color_parse_with_white_default): Add placeholder for rgb: + code, in case we need it. + (eel_parse_rgb_with_white_default): Call + eel_gdk_color_parse_with_white_default so we share code. + (eel_gdk_rgb_to_color_spec): Create #RRGGBB format. + (eel_gdk_color_as_hex_string): Create #RRGGBB format. + (eel_self_check_gdk_extensions): Use #RRGGBB format. + +Tue Nov 20 20:26:25 2001 Owen Taylor + + * configure.in: Add [quoting] around AC_CHECK_HEADER + needed by some autoconf versions. + +Mon Nov 19 17:34:16 2001 Jonathan Blandford + + * eel/eel-stock-dialogs.c (eel_run_simple_dialog): remove uneeded + GTK_OBJECT_DESTROYED check. + + Patch from Gediminas Paulauskas + + * eel/check-program.c, eel/eel-debug.c, test/test.c: replace + g_log_domain_glib with "Glib" + * eel/eel-gobject-extensions.h: replace #include + with glib-object.h + +2001-11-09 Darin Adler + + * eel/eel-stock-dialogs.c: (show_ok_dialog), + (eel_create_info_dialog), (eel_show_info_dialog), + (details_dialog_response_callback): Destroy dialogs when the + button is pushed. We still need to refine this further. + +2001-11-08 Darin Adler + + * Tons of files. + Removed many unneeded G_OBJECT casts. + +2001-11-08 Darin Adler + + * eel/eel-stock-dialogs.h: + * eel/eel-stock-dialogs.c: + A cut at porting this all to GtkDialog. + +2001-11-08 jacob berkman + + * configure.in: call ourselves eel rather than eel2, and use + eel-2.0 for the gettext package name + + * acconfig.h: add GETTEXT_PACKAGE + +2001-11-06 Darin Adler + + * eel/Makefile.am: + * eel/eel-gobject-extensions.h: + * eel/eel-gobject-extensions.c: + (eel_signal_connect_object_while_alive), + (eel_signal_connect_while_alive): + Add new eel-gobject-extensions.[ch]. + + * Many of files. + More Gtk->G changes. + +2001-11-06 Darin Adler + + * Lots of files. + More GtkObject -> GObject. + +2001-11-06 Michael Meeks + + * eel/eel-gdk-pixbuf-extensions.c + (free_pixbuf_load_handle): do a g_object_unref not an + unref. + +2001-11-03 Darin Adler + + * Tons of files: + A bit more GtkObject -> GObject conversion. + +2001-11-03 Darin Adler + + * eel/eel-gtk-macros.h: Ref the parent class instead of just + peeking at it. + +2001-11-03 Darin Adler + + * eel/eel-preferences.c: (preferences_while_alive_disconnector), + (eel_preferences_add_callback_while_alive): + * eel/eel-preferences.h: + Change eel_preferences_add_callback_while_alive to work with + any GObject, not just a GtkObject. + + * eel/eel-preferences-box.c: (eel_preferences_box_init): + * eel/eel-preferences-item.c: (preferences_item_set_main_child): + * eel/eel-preferences-pane.c: (eel_preferences_pane_init), + (eel_preferences_pane_add_control_preference): + Update callers. + +2001-11-03 Darin Adler + + * eel/eel-gtk-macros.h: + Another update to the boilerplate macros. I also decided to + do a name change to take out the word "DEFINE". + + * Many files. + Update for name change. + +2001-11-01 Havoc Pennington + + * eel/eel-gtk-extensions.c (eel_gtk_window_get_geometry_string): + new function to replace mate_geometry_string + +2001-11-01 Darin Adler + + * eel/eel-gtk-macros.h: When I fixed the comma in my copy, I + made some formatting changes. + +2001-11-01 Havoc Pennington + + * eel/eel-gtk-macros.h (EEL_DEFINE_MATECOMPONENT_BOILERPLATE): add + missing comma + + * test/test-eel-label-simple.c (use_system_font_callback): adapt + to not use eel_widget_set_font(), and add note about how the use + of eel_gtk_get_system_font() here is broken and is only for + testing purposes and no one should copy it. + + * eel/eel-gtk-extensions.c (eel_gtk_window_present): that one was + easy + (eel_gtk_widget_set_font_by_name): port to GTK 2 + (eel_gtk_label_make_bold): port to GTK 2 + (eel_gtk_label_make_larger): port and note in docs that it's + broken + (eel_gtk_label_make_smaller): port and note in docs that it's + broken + (eel_gtk_widget_set_background_color): do this properly + (eel_gtk_widget_set_foreground_color): ditto + (eel_get_current_event_time): remove, just use + gtk_get_current_event_time() + (eel_drag_set_icon_pixbuf): remove, just use + gtk_drag_set_icon_pixbuf() + (eel_gtk_widget_standard_draw): delete, there is no draw method + anymore + (eel_gtk_pixmap_new_empty): make this less lame + (eel_nullify_when_destroyed): work on GObject, use + g_object_add_weak_pointer() + (eel_nullify_cancel): corresponding change + (eel_gtk_widget_set_font): remove, just use + gtk_widget_modify_font() + (eel_gtk_style_set_font): delete, this was totally broken; I don't + know what it's for but we have to do it a different way + (eel_gtk_menu_insert_separator): use GtkSeparatorMenuItem! + woo-hoo! also, remove setting it insensitive, this will be fixed + before 2.0 so it isn't required + (EEL_STANDARD_BUTTON_PADDING): remove, should fix in GTK if we are + going to fix it + (eel_gtk_button_auto_click): remove, use gtk_widget_activate() + (eel_gtk_button_set_standard_padding): remove, should not be used + (activate_button_on_double_click): use gtk_widget_activate() + instead of eel_gtk_button_auto_click() + (eel_gtk_window_set_initial_geometry): use gtk_window_move() + instead of gtk_widget_set_uposition() + (eel_gtk_window_set_up_close_accelerator): make it whine if you + use it on GtkDialog, since that breaks the standard GtkDialog + close accelerators + (eel_popup_menu_position_func): remove obsolete FIXME about + GdkPoint using gint16 + + * eel/eel-gdk-extensions.c (eel_gdk_window_set_invisible_cursor): + port to GTK 2 (not sure why it used Xlib before) + + * eel/eel-dnd.c (eel_drag_drop_action_ask): port to GTK 2 + +2001-11-01 Darin Adler + + * eel/eel-gtk-macros.h: Oops, need to pass init and fini functions + in to matecomponent_type_unique. + +2001-11-01 Darin Adler + + * configure.in: Remove some unused stuff. + * eel/eel-gtk-macros.h: Fix boilerplate to work with GObject, not + just GtkObject. Share code with the MateComponentObject case too. + +2001-10-29 Darin Adler + + * eel-2.0.pc.in: Add some Requires. + +2001-10-29 Darin Adler + + * eel/Makefile.am: Fix typo. + +2001-10-28 Darin Adler + + * configure.in: Fix comment, remove unnecessary direct pkgconfig + macro since MATE_PLATFORM_MATE_2 takes care of htat. + + * many files: + Since everyone else calls them class_init and init, renamed our + initialize_class and initialize to match existing practice. + + * eel/eel-gtk-macros.h: + Added EEL_DEFINE_MATECOMPONENT_BOILERPLATE. + + * eel/eel-xml-extensions.h: + * eel/eel-xml-extensions.c: (eel_xml_remove_node): Remove this + since xmlUnlinkNode is now implemented. + +2001-10-27 jacob berkman + + * eel/eel-background.c (eel_background_start_loading_image): + update to new vfs priority macro name + +2001-10-22 Darin Adler + + * eel/eel-gdk-extensions.c: (eel_gdk_window_set_wm_protocols): + * eel/eel-gdk-font-extensions.c: (eel_gdk_font_get_name): + Fix for GdkAtom/XAtom change in gtk. + +2001-10-20 Anders Carlsson + + * eel/eel-background.c: (eel_background_start_loading_image): + * eel/eel-gdk-pixbuf-extensions.c: (eel_gdk_pixbuf_load_async): + * eel/eel-gdk-pixbuf-extensions.h: + * eel/eel-vfs-extensions.c: (eel_read_file_async), + (eel_read_entire_file_async): + * eel/eel-vfs-extensions.h: Update async eel functions using mate-vfs + to take a priority argument because of the recent priority changes in + mate-vfs. + +2001-10-11 Ramiro Estrugo + + * eel/eel-clickable-image.c: (eel_clickable_image_new_solid): + * eel/eel-image-chooser.c: (eel_image_chooser_insert_row): + * eel/eel-image.c: (eel_image_initialize_class), + (eel_image_initialize), (eel_image_finalize), (eel_image_set_arg), + (eel_image_get_arg), (eel_image_size_request), + (eel_image_expose_event), (eel_image_new_solid): + * eel/eel-image.h: + * eel/eel-label.c: (eel_label_initialize_class), + (eel_label_initialize), (eel_label_finalize), (eel_label_set_arg), + (eel_label_get_arg), (eel_label_size_request), (label_paint), + (paint_label_smooth), (paint_label_smooth_cached), + (eel_label_expose_event), (label_can_cache_contents), + (eel_label_new_solid): + * eel/eel-label.h: + * eel/eel-labeled-image.c: (eel_labeled_image_make_smaller): + * eel/eel-labeled-image.h: + * eel/eel-smooth-widget.c: (eel_smooth_widget_paint), + (eel_smooth_widget_get_preferred_dimensions): + * eel/eel-smooth-widget.h: + * test/.cvsignore: + * test/Makefile.am: + * test/test-eel-image-background.c: + (window_new_with_eel_background_image), + (window_new_with_eel_background_gradient), + (window_new_with_gtk_background), + (window_new_with_gtk_background_hacked), + (window_new_with_solid_background): + * test/test-eel-image-simple.c: (image_window_new), (main): + * test/test-eel-image-tile.c: + * test/test-eel-image.c: + * test/test-eel-label-background.c: + (window_new_with_eel_background_image), + (window_new_with_eel_background_gradient), + (window_new_with_gtk_background), + (window_new_with_gtk_background_hacked), + (window_new_with_solid_background): + * test/test-eel-label-scrolled.c: (label_window_new), + (label_window_new_scrolled), (label_window_new_table): + * test/test-eel-labeled-image.c: (main): + * test/test-eel-viewport-constraint.c: (create_eel_label): + * test/test.c: (test_image_new), (test_label_new): + * test/test.h: + Lose the "tile" feature of EelImage and EelLabel. The short story + is that this code is unnecessary. Losing it makes the widgets + simpler and should make the transition to using GtkImage from Gtk+ + 2.0 a little easier. Blame 70% Arlo 30% Ramiro for this "feature." + +2001-10-10 Darin Adler + + * eel/eel-debug-drawing.c: + * eel/eel-label.c: + * eel/eel-smooth-text-layout.c: + Mark functions static for proper namespace hygiene. + +2001-10-02 Darin Adler + + * eel/eel-canvas-rect.c: (test_diff_rects): Change call to + g_string_printfa to use g_string_append_printf. + +2001-10-02 Darin Adler + + * .cvsignore: + * Makefile.am: + * configure.in: + Remove use of xml-i18n-tools, since we don't have anything that + we use it to localize. + +2001-10-02 Darin Adler + + * eel/eel-background.c: (eel_background_is_dark): Remove extra + factor of two that was making every background seem dark. + +2001-10-01 Darin Adler + + Now that we are setting the translation domain properly to make + _() use eel translations, we must use explicit gettext calls + when we want application translations. + + * eel/eel-dnd.c: (eel_drag_drop_action_ask): Switch into the + eel domain when calling mate_popup_menu_new so we get the + eel translations of the menu items. + + * eel/eel-enumeration.c: + (eel_enumeration_get_nth_description_translated): + * eel/eel-preferences-box.c: (preferences_box_populate_pane), + (eel_preferences_box_populate): + * eel/eel-xml-extensions.c: (eel_xml_get_property_translated): + Use gettext, not _(), to translate strings passed from elsewhere. + + * eel/eel-preferences.c: + (eel_preferences_get_user_level_name_for_display): + Use _(), not gettext, to translate strings in this code. + + * eel/eel-gdk-font-extensions.c: + Remove mate-i18n.h include where it's not used. + + * configure.in: Remove unused @REBUILD@ stuff. + * eel/eel-glib-extensions.c: Whitespace tweaks. + +2001-09-28 Darin Adler + + * eel/eel-font-manager.c: (eel_self_check_font_manager): + Cleaned up tests a bit. + + * eel/eel-string-list.c: (eel_self_check_string_list): + Changed test results back now that g_strsplit behavior has been + changed in glib. + + * configure.in: Bump required glib version to 1.3.9. + +2001-09-28 Darin Adler + + Port from destroy to finalize. + + * eel/eel-background.c: (eel_background_initialize_class), + (eel_background_finalize): + * eel/eel-canvas-rect.c: (rect_finalize), + (eel_canvas_rect_initialize_class): + * eel/eel-caption-table.c: (eel_caption_table_initialize_class), + (caption_table_finalize): + * eel/eel-caption.c: (eel_caption_initialize_class), + (eel_caption_finalize): + * eel/eel-clickable-image.c: + (eel_clickable_image_initialize_class), + (eel_clickable_image_finalize): + * eel/eel-debug-drawing.c: (debug_pixbuf_viewer_initialize_class), + (debug_pixbuf_viewer_finalize): + * eel/eel-font-picker.c: (eel_font_picker_initialize_class), + (eel_font_picker_finalize): + * eel/eel-gtk-extensions.c: (eel_gtk_style_set_font), + (eel_gtk_widget_set_font), (eel_gtk_get_system_font): + * eel/eel-gtk-extensions.h: + * eel/eel-image-chooser.c: (eel_image_chooser_initialize_class), + (eel_image_chooser_finalize), (eel_image_chooser_destroy): + * eel/eel-image-table.c: (eel_image_table_initialize_class), + (eel_image_table_finalize): + * eel/eel-image.c: (eel_image_initialize_class), + (eel_image_finalize): + * eel/eel-label.c: (eel_label_initialize_class), + (eel_label_finalize): + * eel/eel-labeled-image.c: (eel_labeled_image_initialize_class), + (eel_labeled_image_finalize): + * eel/eel-list-column-title.c: + (eel_list_column_title_initialize_class), + (eel_list_column_title_finalize): + * eel/eel-password-dialog.c: + (eel_password_dialog_initialize_class), + (eel_password_dialog_initialize), (eel_password_dialog_finalize), + (eel_password_dialog_new): + * eel/eel-preferences-box.c: + (eel_preferences_box_initialize_class), + (eel_preferences_box_finalize): + * eel/eel-preferences-group.c: + (eel_preferences_group_initialize_class), + (eel_preferences_group_finalize): + * eel/eel-preferences-item.c: + (eel_preferences_item_initialize_class), + (preferences_item_finalize): + * eel/eel-preferences-pane.c: + (eel_preferences_pane_initialize_class), + (eel_preferences_pane_finalize): + * eel/eel-radio-button-group.c: + (eel_radio_button_group_initialize_class), + (eel_radio_button_group_finalize): + * eel/eel-scalable-font.c: (eel_scalable_font_initialize_class), + (eel_scalable_font_finalize): + * eel/eel-smooth-text-layout-cache.c: + (eel_smooth_text_layout_cache_initialize_class), + (eel_smooth_text_layout_cache_finalize): + * eel/eel-smooth-text-layout.c: + (eel_smooth_text_layout_initialize_class), + (eel_smooth_text_layout_finalize): + * eel/eel-string-picker.c: (eel_string_picker_initialize_class), + (eel_string_picker_finalize): + * eel/eel-text-caption.c: (eel_text_caption_initialize_class), + (eel_text_caption_finalize): + * eel/eel-viewport.c: (eel_viewport_initialize_class), + (eel_viewport_finalize): + * eel/eel-wrap-table.c: (eel_wrap_table_initialize_class), + (eel_wrap_table_finalize): + Replace destroy default handlers with finalize ones in most cases. + In a few cases, divide an existing destroy handler into two pieces. + + * test/test-eel-label-flavorful.c: (decreasing_label_window_new): + * test/test-eel-label-simple.c: (use_system_font_callback): + Re-enable some test code. + +2001-09-27 Darin Adler + + * test/test-eel-label-flavorful.c: (label_set_label_to_font_name): + Oops. One more thing to fix in here. Use pango call. + +2001-09-26 Darin Adler + + * eel/Makefile.am: + Another pass. The last one was too simplistic. + +2001-09-26 Darin Adler + + * configure.in: + Get the path of glib-genmarshal. + + * eel/.cvsignore: + * eel/Makefile.am: + Fix up generated file build to be simpler. Most importantly, add + the feature where it won't recompile everything every time any + header changes. + + * eel/eel-gtk-extensions.h: + * eel/eel-gtk-extensions.c: (eel_gtk_get_system_font): + Wrote Pango version of this function. + + * test/test-eel-label-flavorful.c: (label_set_label_to_font_name): + Reenabled some ifdef'd out code. + +2001-09-19 Marius Andreiana + + * configure.in: Added ro (Romanian) to ALL_LINGUAS + +2001-09-18 Darin Adler + + * eel/eel-gtk-extensions.h: + * eel/eel-ellipsizing-label.c: (recompute_ellipsized_text): + * eel/eel-gdk-pixbuf-extensions.c: (check_average_value): + * eel/eel-gtk-extensions.c: (eel_gtk_widget_set_font_by_name), + (eel_gtk_label_make_bold), (eel_gtk_label_make_larger), + (eel_gtk_label_make_smaller): + * test/test-eel-label-flavorful.c: (label_set_label_to_font_name): + * test/test-eel-label-simple.c: (use_system_font_callback): + + Turned off a lot of GdkFont stuff so we can still compile. + This highlights more of the mate 2 conversion work that will + be needed. + +2001-09-17 Darin Adler + + * eel/eel-background.c: (eel_background_is_dark): Make this work + with background images that are transparent or partly-transparent. + It turns out this was another part of the problem with the default + Caja theme's text color. + + * eel/eel-gdk-pixbuf-extensions.h: + * eel/eel-gdk-pixbuf-extensions.c: (eel_gdk_pixbuf_average_value): + Fix bug that caused incorrect average values in pixbufs with more + than about 66000 pixels. Alex Larsson found the problem and + provided a fix that I used as a starting point. Also change + algorithm so that it handles the alpha channel. Also made it use + 64-bit arithmetic for simplicity -- hope that doesn't make it too + slow. Also changed it to use an argb value instead of a GdkColor. + (eel_gdk_pixbuf_intersect): Get rid of special case for + eel_gdk_pixbuf_whole_pixbuf by making just using a wide-open + rectangle instead. + (check_average_value), (eel_self_check_gdk_pixbuf_extensions): + Added some test cases for eel_gdk_pixbuf_average_value. + +2001-09-08 Wang Jian + + * configure.in(ALL_LINGUAS): Added zh_CN for Simplified Chinese. + +2001-09-07 Darin Adler + + * eel/eel-gdk-font-extensions.h: + * eel/eel-gdk-font-extensions.c: (eel_gdk_font_get_italic), + (eel_gdk_font_get_bold), (eel_gdk_font_get_larger), + (eel_gdk_font_get_largest_fitting), (font_get_bold), + (font_get_size_in_pixels): Call the new eel_gdk_font_get_name. + (eel_gdk_font_get_name): Public version of font_get_name. Code + stolen from gal used to get name from X. + + * test/test-eel-label-flavorful.c: (label_set_label_to_font_name): + Call eel_gdk_font_get_name, remove font_get_name. + +2001-09-07 Darin Adler + + * configure.in: Got rid of dependency on libmatesupport. + + * eel/eel-gdk-font-extensions.c: (font_get_name): + * test/test-eel-label-flavorful.c: (font_get_name): + Disabled these until we can figure out what to do about them. + +2001-09-03 Darin Adler + + * eel/check-program.c: (main): + * test/test-eel-password-dialog.c: (main): + * test/test-eel-widgets.c: (main): + * test/test.c: (test_init): + Use libmateui_module_info_get () instead of + libmateui_module_info. + +2001-09-01 Darin Adler + + * eel/eel-gtk-extensions.c: Remove include. + +2001-09-01 Darin Adler + + * eel/eel-dnd.c: + (is_path_that_mate_uri_list_extract_filenames_can_parse): + * eel/eel-font-manager.c: (font_description_table_add), + (next_token): + * eel/eel-glib-extensions.c: (eel_strdup_strftime): + * eel/eel-string.c: (eel_istr_has_prefix), (eel_istr_has_suffix), + (eel_str_to_int), (eel_str_capitalize): + Oops! How did I miss all of these places that needed to use + the new g_ascii_* calls? + +2001-08-31 Darin Adler + + * eel/eel-background.c: + * eel/eel-dnd.c: + * eel/eel-font-manager.c: + * eel/eel-glib-extensions.c: + * eel/eel-list.c: + * eel/eel-string.c: + * eel/eel-vfs-extensions.c: (is_valid_scheme_character), + (eel_make_uri_canonical): + Get rid of all includes of and use non-locale-specific + g_ascii_* calls from glib instead. + +2001-08-31 Darin Adler + + Rolled change from stable eel-1-0 branch: + + * eel/eel-gtk-extensions.c: + (eel_gtk_class_name_make_like_existing_type), + (eel_gtk_get_system_font): Fix storage leaks by using + gtk_object_sink to get rid of temporary widgets that are never + parented instead of using gtk_object_destroy. + +2001-08-31 Darin Adler + + * eel/eel-gtk-extensions.c: (eel_gtk_window_present): + Get things compiling again by getting rid of code that uses + mate_win_hints (for now). + +2001-08-31 Abel Cheung + + * configure.in (ALL_LINGUAS): zh_TW.Big5 -> zh_TW + +2001-08-27 Darin Adler + + Rolled change from stable eel-1-0 branch: + + 2001-08-27 Alex Larsson + + * eel/eel-list-column-title.c (truncate_string): + Fix elipsis truncation on multibyte locales. + +2001-08-27 Anders Carlsson + + * eel/eel-font-manager.c (eel_self_check_font_manager): Remove + unused original_current_dir variable. + + * eel/eel-canvas-rect.c (rect_update): Free our fill_svp + if it exists. + + * eel/eel-gdk-font-extensions.c (xlfd_string_get_nth_as_int): + Free strings returned by xlfd_string_get_nth. + +2001-08-24 Darin Adler + + * configure.in: Require librsvg 1.1, not 1.1.0. + * eel/eel-glyph.c: Use header from libart, not librsvg. + +2001-08-22 Ramiro Estrugo + + Change from the stable eel-1-0 branch. + + * eel/eel-mateconf-extensions.c: (eel_mateconf_value_set_string_list): + Fix leaks introduced in last checkin. + +2001-08-22 Ramiro Estrugo + + Change from the stable eel-1-0 branch. + + * eel/eel-mateconf-extensions.h: + * eel/eel-mateconf-extensions.c: (eel_mateconf_is_default): Use value + free cover that does its own not NULL checking. + (eel_mateconf_value_get_string_list), + (eel_mateconf_value_set_string_list): New function to deal with + MateConfValue lists of GNONF_VALUE_STRING type. + + * eel/eel-preferences.c: (preferences_mateconf_value_get_int), + (preferences_mateconf_value_get_bool), + (preferences_mateconf_value_get_string), + (preferences_mateconf_value_get_string_list), (preferences_get_value), + (preferences_preference_is_mateconf_key), (preferences_key_make), + (preferences_find_first_non_null_default_value), + (eel_preferences_get_visible_user_level), + (eel_preferences_set_visible_user_level), + (eel_preferences_set_is_invisible), (eel_preferences_set_boolean), + (eel_preferences_get_boolean), (eel_preferences_set_integer), + (eel_preferences_get_integer), (eel_preferences_set), + (eel_preferences_get), (eel_preferences_set_string_list), + (eel_preferences_get_string_list), + (eel_preferences_default_set_integer), + (eel_preferences_default_get_integer), + (eel_preferences_default_set_boolean), + (eel_preferences_default_get_boolean), + (eel_preferences_default_set_string), + (eel_preferences_default_get_string), + (eel_preferences_default_set_string_list), + (eel_preferences_default_get_string_list), + (preferences_entry_invoke_callbacks_if_needed), + (preferences_entry_update_cached_value), + (preferences_entry_ensure_mateconf_connection), + (preferences_entry_free), (preferences_global_table_free), + (eel_preferences_add_callback), (eel_preferences_add_auto_string), + (eel_preferences_add_auto_string_list), + (eel_preferences_add_auto_integer), + (eel_preferences_add_auto_boolean), + (eel_preferences_remove_auto_string), + (eel_preferences_remove_auto_string_list), + (eel_preferences_remove_auto_integer), + (eel_preferences_remove_auto_boolean), + (preferences_while_alive_disconnector), + (eel_preferences_add_callback_while_alive), + (eel_preferences_remove_callback), + (eel_preferences_set_description), + (eel_preferences_set_enumeration_id), + (eel_preferences_visible_in_current_user_level), + (eel_preferences_initialize): + Cleanup whacky system where preference visibilities and default + values were stored using mateconf. Instead, store the visibilities + and defaults values in the already existing table of preferences. + The changes make this code a bit simpler. In particular, the code + to create the right keys is now gone. Add some covers for getting + values out of MateConfValue safely and with some extra checking the + the types are right. + +2001-08-21 Maciej Stachowiak + + Merge from stable branch: + + 2001-08-20 Maciej Stachowiak + + * eel/eel-clist.c: (eel_clist_set_column_justification, + size_allocate_title_buttons): Try to remove some sources of + crashing when EelList is used as a drop-in replacement for + GtkCList. (Using EelCList directly still crashes). + * eel/eel-list-column-title.c: (eel_list_column_title_paint): More + potential crash reduction. + + * test/Makefile.am: Speed up the build a bit by removing some + redundant libraries. + * eel/Makefile.am: Likewise. + +2001-08-21 Maciej Stachowiak + + * eel/eel-font-manager.c (collect_fonts_from_directory): Adjust to + recent removal of filtering from mate-vfs. + +2001-08-21 Maciej Stachowiak + + Merge from eel-1-0 branch: + + 2001-07-20 Maciej Stachowiak + + * eel/eel-ctree.c: (draw_row): Fix bugzilla.eazel.com bug 8387 + (Dragging elements to a folder entry should make it hilighted) by + making the text of the drop target row bold in addition to making + the icon darker. I think this looks a lot better. + +2001-08-17 Darin Adler + + * eel/eel-gtk-extensions.c: Remove include of obsolete header. + +2001-08-17 Ramiro Estrugo + + Change from the stable eel-1-0 branch. + + Make these widgets more useful outside Caja by providing + functions to change ui elements (such as titles and descriptions) + as well iterators. + + These changes do not affect either binary or source compatibility + for Caja. + + * eel/eel-preferences-box.h: + * eel/eel-preferences-box.c: + (preferences_box_populate_pane), (eel_preferences_dialog_new), + (eel_preferences_dialog_get_box), Add accessor for the preferences + box of a dialog. + (eel_preferences_dialog_populate), Separate the populate function + out on its own. + (eel_preferences_box_for_each_pane), New function for iterating + panes. + (eel_preferences_box_rename_pane), New function to rename a pane. + (eel_preferences_box_get_pane_name): New function to find the name + of a pane. + + * eel/eel-preferences-group.h: + * eel/eel-preferences-group.c: + (eel_preferences_group_set_title_label), New function for changing + the title label of a group. + (eel_preferences_group_for_each_item): New function for iterating + items. + + * eel/eel-preferences-pane.h: + * eel/eel-preferences-pane.c: (eel_preferences_pane_initialize), + (eel_preferences_pane_destroy), (eel_preferences_pane_new), + (eel_preferences_pane_add_group), + (preferences_pane_get_max_caption_width), + (eel_preferences_pane_update), + (eel_preferences_pane_add_control_preference), Use more consistent + paramter names. + (eel_preferences_pane_for_each_group): New function for iterating + groups. + + * eel/eel-preferences-item.h: + * eel/eel-preferences-item.c: + * eel/eelmarshal.list: + (eel_preferences_item_initialize_class), + (preferences_item_update_custom), + (preferences_item_set_main_child), + (preferences_item_create_enumeration_list), + (preferences_item_create_boolean), + (preferences_item_create_editable_string), + (preferences_item_create_editable_integer), + (preferences_item_create_enumeration_menu), + (preferences_item_create_font), + (preferences_item_create_smooth_font), + (eel_preferences_item_get_name), (update_text_settings_at_idle), + (preferences_item_update_text_settings_at_idle), + (update_integer_settings_at_idle), + (preferences_item_update_editable_integer_settings_at_idle), + (preferences_item_update_description), + (eel_preferences_item_set_control_preference), + (eel_preferences_item_set_control_action), + (preferences_item_get_control_showing), + (eel_preferences_item_enumeration_list_set_unique_exceptions), + (eel_preferences_item_set_description): + Add new functions for changing the descriptions of items. Factor + out the code to set descriptions into its own function and make + that public. Use more consistent parameter names. Add signal for + notifying custom items about description changes. + +2001-08-15 Darin Adler + + Remove some glib extensions that are obviated by additions to + glib 2.0. + + * eel/eel-glib-extensions.h: Remove EEL_N_ELEMENTS (G_N_ELEMENTS), + eel_g_list_safe_for_each (g_list_foreach), eel_g_list_sort_custom + (g_list_sort_with_data), eel_g_string_append_len (g_string_append_len), + eel_g_hash_table_remove_deep_custom, eel_g_hash_table_remove_deep, + eel_g_hash_table_destroy_deep_custom, eel_g_hash_table_destroy_deep + (use g_hash_table_new_full instead), eel_g_ptr_array_sort + (g_ptr_array_sort_with_data), eel_shell_quote (g_shell_quote). +. + * eel/eel-glib-extensions.c: (eel_strdup_strftime): + Use g_string_append_len instead of eel_g_string_append_len. + (eel_dumb_down_for_multi_byte_locale_hack): Use G_N_ELEMENTS + instead of EEL_N_ELEMENTS. + (eel_self_check_glib_extensions): Test g_shell_quote instead + of eel_shell_quote. + + * eel/eel-mate-extensions.c: (try_terminal_command), + (try_terminal_command_argv), (get_terminal_command_prefix), + (eel_mate_make_terminal_command): + Use g_shell_quote instead of eel_shell_quote. + + * eel/eel-gtk-extensions.c: (eel_gtk_object_list_unref): + Use g_list_foreach instead of eel_g_list_safe_for_each. + + * eel/eel-scalable-font.c: (free_global_font_handle_table), + (initialize_global_stuff_if_needed): + Use g_hash_table_new_full instead of eel_g_hash_table_destroy_deep_custom. + + * eel/eel-debug.c: + (eel_make_warnings_and_criticals_stop_in_debugger): + * eel/eel-font-manager.c: (font_directory_is_ignored), + (font_foundry_is_ignored), (font_family_is_ignored), + (eel_font_manager_get_default_font), + (eel_font_manager_get_default_bold_font): + * eel/eel-font-picker.c: (font_make_style_name): + * eel/eel-list.c: (eel_list_initialize_dnd), + (get_data_on_first_target_we_support): + * test/test-eel-gtk-style.c: + * test/test-eel-image-chooser.c: (populate_image_chooser_callback), + (populate_button_group_callback): + * test/test-eel-image-table.c: (labeled_image_new), + (image_table_new_scrolled): + * test/test-eel-image.c: (main): + Use G_N_ELEMENTS instead of EEL_N_ELEMENTS. + +Wed Aug 15 16:32:56 2001 Jonathan Blandford + + * eel/eel-dnd.c (eel_drag_default_drop_action_for_icons): make the + trash directory. + +2001-08-15 Darin Adler + + * eel/eel-gdk-pixbuf-extensions.c: Use a 64K buffer instead of + a 4K one. + +2001-08-14 Darin Adler + + * eel/eel-font-manager.c: (eel_font_manager_get_bold): + Remove another ill-advised call to + eel_font_manager_file_is_scalable_font. Even if we do want + to test the file's type, we definitely don't want to do it + inside g_return_if_fail. + +2001-08-14 Alex Larsson + + * eel/eel-scalable-font.c (eel_scalable_font_new): + Don't test eel_font_manager_file_is_scalable_font (), + it does slow I/O. + (eel_scalable_font_get_default_font, + eel_scalable_font_get_default_bold_font): + Don't keep recreating new EelScalableFonts for the + default font. + +2001-08-13 Darin Adler + + * eel/eel-background.c: (eel_background_load_image_callback), + (draw_background_callback), (render_background_callback), + (eel_background_set_up_canvas): + Replace the old EelBackgroundCanvasGroup hack with code that uses + the new draw_background and render_background signals in + MateCanvas. + + * eel/Makefile.am: + * eel/eel-background-canvas-group.c: + * eel/eel-background-canvas-group.h: + Remove the old EelBackgroundCanvasGroup class. + +2001-08-09 Ramiro Estrugo + + Change from the eel-1-0 branch. + + * eel/eel-art-extensions.h: + * eel/eel-art-extensions.c: (eel_art_point_assign), + (eel_art_point_clamp), (eel_art_point_offset_by): + Add ArtPoint version of some functions. + +2001-08-08 Darin Adler + + * autogen.sh: No need for hack-macros any more. + * configure.in: No need to check for freetype, since + we don't depend on it directly. We use it via librsvg. + * eel.spec.in: No need to check for freetype. + +2001-08-06 Darin Adler + + * autogen.sh: No need to gettextize, xml-i18n-toolize, and + libtoolize twice. + * configure.in: Switch from lots of MATE_PKGCONFIG_CHECK_MODULES + calls to a lot fewer PKG_CHECK_MODULES calls. More oaf -> + matecomponent-activation renaming. No need to build intl directory. + * Makefile.am: No need to build intl directory. + + * test/Makefile.am: No need to use -I to include this directory. + + * eel/check-program.c: + * test/test-eel-password-dialog.c: + * test/test-eel-widgets.c: + -> . + +2001-07-26 Darin Adler + + * configure.in: Fix option checking code. Before it was setting + VFS_CFLAGS, which was wrong. + + * eel/Makefile.am: Add -DG_DISABLE_DEPRECATED. + + * eel/eel-background.c: (eel_widget_background_changed): + Use gtk_widget_queue_draw instead of gtk_widget_queue_clear. + * eel/eel-canvas-rect.c: (test_diff_rects): Use g_string_printfa + instead of g_string_sprintfa. + * eel/eel-caption.c: (eel_caption_get_title_label): Use + gtk_label_get_text instead of gtk_label_get. + * eel/eel-clickable-image.c: + (eel_clickable_image_initialize_class): Use g_signal_new instead + of gtk_signal_new. + (label_enter), (label_leave), (label_handle_button_release): Use + g_signal_emit instead of gtk_signal_emit. + * eel/eel-debug-drawing.c: (eel_debug_show_pixbuf): Use + gtk_window_set_resizable instead of gtk_window_set_policy. + * eel/eel-font-picker.c: (font_picker_populate): Use + gtk_radio_menu_item_get_group instead of gtk_radio_menu_item_group. + * eel/eel-gdk-extensions.c: (eel_fill_rectangle_with_color), + (eel_gdk_gc_choose_foreground_color): Get rid of unneeded calls to + gdk_rgb_init. + * eel/eel-glib-extensions.c: (eel_test_predicate): Use + g_ascii_strcasecmp instead of g_strcasecmp. + * eel/eel-gtk-extensions.h: Add ifdefs so we can compile this + header with GTK_DISABLE_DEPRECATED on -- helps us notice what we + should get rid of. + * eel/eel-image-chooser.c: (eel_image_chooser_initialize_class): + Use G_STRUCT_OFFSET instead of GTK_SIGNAL_OFFSET. + (eel_image_chooser_set_selected_row): Use g_signal_emit instead of + gtk_signal_emit. + * eel/eel-image-table.c: (eel_image_table_initialize_class), + (image_table_emit_signal): Use g_signal_emit instead of + gtk_signal_emit. + * eel/eel-image.c: (eel_image_initialize_class): Use + G_STRUCT_OFFSET instead of GTK_SIGNAL_OFFSET. + * eel/eel-label.c: (eel_label_initialize_class): Use + G_STRUCT_OFFSET instead of GTK_SIGNAL_OFFSET. + * eel/eel-preferences-box.c: (eel_preferences_dialog_new): Use + gtk_window_set_resizable instead of gtk_window_set_policy. + * eel/eel-preferences-item.c: + (preferences_item_create_editable_string): Use g_ascii_strcasecmp + instead of g_strcasecmp. + * eel/eel-radio-button-group.c: (eel_radio_button_group_insert): + Use gtk_radio_button_get_group instead of gtk_radio_button_group. + * eel/eel-stock-dialogs.c: (find_message_label): Use + gtk_label_get_text instead of gtk_label_get. + * eel/eel-string.c: (eel_strcasecmp): Use g_ascii_strcasecmp + instead of g_strcasecmp. + + * eel/eel-gdk-font-extensions.h: Fix typo in comment. + +2001-07-26 Ramiro Estrugo + + * configure.in: + * eel/.cvsignore: + * eel/Makefile.am: + * eel/eel-features.c: + * eel/eel-features.h.in: + * eel/eel.h: + Add eel-features.[ch] so that the version of the library can be + checked at runtime. + +2001-07-26 Ramiro Estrugo + + Change from the the eel-1-0 branch: + + * eel/eel-image.h: + * eel/eel-image.c: (eel_image_initialize_class), + (eel_image_initialize), (eel_image_set_arg), (eel_image_get_arg), + (eel_image_expose_event), (eel_image_get_pixbuf_opacity), + (eel_image_set_pixbuf_insensitive_opacity), + (eel_image_get_pixbuf_insensitive_opacity): + Add support for rendering the image pixbuf at a lower opacity when + the widget state is insensitive. + +2001-07-25 Ramiro Estrugo + + * eel/Makefile.am: + Add missing eelmarshal.list to EXTRA_DIST and use a sophisticated + alphabetized order on the list. + +2001-07-25 Ramiro Estrugo + + * eel-2.0.pc.in: + Change link flags to '-leel-2' instead of '-leel' + +2001-07-25 Ramiro Estrugo + + * configure.in: + Add defines for Eel library major, minor and micro version numbers + so that we can use these to properly set the shared library + version info. + Make the includedir be eel-2/eel' instead of 'eel' so that we can + have MATE1 and MATE2 installations of Eel cohabiting in the + same $prefix. + + Change the PACKAGE name to eel2. + + * data/fonts/urw/Makefile.am: + Data dir is now 'share/eel-2/eel' instead of 'share/eel' + + * eel-2.0.pc.in: + Include dir is now include/eel-2/eel' instead of 'include/eel' + + * eel.spec.in: + Update for includedir and datadir changes. + Add missing .mo file rule. + Cleanup some. + + * eel/Makefile.am: + Set the shared library version info. + Change libary name to libeel-2 so that we can install it in the + same prefix as libeel (MATE1 and MATE2 cohabitation) + Install headers in the new 'eel-2/eel' includedir. + Update EEL_DATADIR for new 'eel-2/eel' data location so that + fallback fonts can be found in the right place. + + * test/Makefile.am: + Update for includedir and datadir changes. + + * test/dumb-box.c: (eel_dumb_box_expose): + More sythetic exposure fixes. + +2001-07-24 Ramiro Estrugo + + * eel/eel-image-chooser.c: (image_chooser_expose_event): + * eel/eel-viewport.c: (eel_viewport_expose_event): + * eel/eel-wrap-table.c: (eel_wrap_table_expose_event): + More sythetic expose event fixes. + +2001-07-24 Ramiro Estrugo + + * eel/eel-gtk-container.c: (eel_gtk_container_child_expose_event): + Fix the way that expose events are synthesized for children of + containers. In Gtk+ 2.0 there is a standard and convenient way of + doing this, so we use that instead of doing it "by hand". + +2001-07-24 Ramiro Estrugo + + * eel/eel-clickable-image.c: + (eel_clickable_image_initialize_class): + * eel/eel-clickable-image.h: + * eel/eel-font-picker.c: (eel_font_picker_initialize_class): + * eel/eel-font-picker.h: + * eel/eel-image-chooser.c: (eel_image_chooser_initialize_class): + * eel/eel-image-chooser.h: + * eel/eel-image-table.c: (eel_image_table_initialize_class): + * eel/eel-image-table.h: + * eel/eel-image.c: (eel_image_initialize_class): + * eel/eel-label.c: (eel_label_initialize_class): + * eel/eel-preferences-item.c: + (eel_preferences_item_initialize_class): + * eel/eel-preferences-item.h: + * eel/eel-radio-button-group.c: + (eel_radio_button_group_initialize_class): + * eel/eel-radio-button-group.h: + * eel/eel-string-picker.c: (eel_string_picker_initialize_class): + * eel/eel-string-picker.h: + * eel/eel-text-caption.c: (eel_text_caption_initialize_class): + * eel/eel-text-caption.h: + Changes to make the GTK+ 2.0 signal system happier. Make sure + that all signals are declared in the class structure and that the + offset argument to gtk_signal_new () points to a valid method + offset. + +2001-07-24 Ramiro Estrugo + + * eel/eel-gdk-pixbuf-extensions.c: + * eel/eel-gdk-pixbuf-extensions.h: + * eel/eel-smooth-widget.c: (smooth_widget_get_gtk_background): + Remove the use of a "safe" (and very hacky) drawable to pixbuf + function, since the problems we were working around have been + fixed in GTK+ 2.0. + With this change, "smooth" widgets work again. + + * test/test.c: (test_init): + Comment out the mate_program_init() thing for now. + Currently the mate_program_init() function makes the test + programs hang for me. Using just the gtk_init () works for + most tests, so I am using just that until the mate_program_init () + function is fixed or we learn how to use it properly. + +2001-07-24 Ramiro Estrugo + + Change from the the eel-1-0 branch: + + * eel/eel-string-list.h: + * eel/eel-string-list.c: (eel_string_list_prepend): New function + to prepend a string to the collection. + (eel_string_list_append_string_list): Rename from + eel_string_list_append () which was a confusing name. + This API change doesnt affect Caja or Eel since neither used + this function. + +2001-07-18 Darin Adler + + * acconfig.h: Also need to add MATE_EXPLICIT_TRANSLATION_DOMAIN + here for autoheader. + +2001-07-17 Darin Adler + + * configure.in: Add MATE_EXPLICIT_TRANSLATION_DOMAIN so messages + withing eel get translated properly. + +2001-07-17 Darin Adler + + * eel/eel-gdk-font-extensions.c: + (eel_gdk_font_get_largest_fitting): Add FIXME about incorrect + assumption that the longest string is the widest. + (xlfd_string_get_nth): Check for extra characters before the "-", + and don't allow n == 0. + (xlfd_string_replace_nth), Check for extra characters before the + "-", don't allow n == 0, and use return_if_fail to check for bad + values of n rather than just returning NULL. + (xlfd_string_get_nth_as_int): Use return_if_fail to check for bad + values of n rather than just returning XFLD_INVALID_VALUE. Remove + extra check for NULL. + (eel_self_check_gdk_font_extensions): Add lots of new self-checks + and change rule so that we don't allow an extra trailing "-" + character. + + * eel/check-program.c: (main): Use mate_program_init correctly. + * test/test-eel-password-dialog.c: (main): Use mate_program_init + correctly. + * test/test-eel-widgets.c: (main): Use mate_program_init + correctly. + +2001-07-16 Darin Adler + + * eel/eel-self-checks.c: (eel_check_string_list_result): + Fix place where I called the wrong function. + +2001-07-15 Darin Adler + + * eel/check-program.c: (main): Fix up init calls. I am still quite + confused about how to use mate_program_init properly. + + * eel/eel-preferences-item.h: + * eel/eel-preferences-item.c: + * eel/eel-self-checks.h: + * eel/eel-string-list.h: + * eel/eel-string.h: + Corrected spelling error: "delimeter" -> "delimiter". + + * eel/eel-self-checks.c: (eel_check_string_list_result): + Changed string list check to be simpler and distinguish lists + with empty strings in them from empty lists. + +2001-07-13 Darin Adler + + * eel/check-program.c: + * eel/eel-xml-extensions.c: + * eel/eel-xml-extensions.h: + Fix mate-xml includes to use . Before it was just + picking up the wrong headers on my machine, which is why it worked. + +2001-07-13 Darin Adler + + Now things link, and the test programs compile too. + + * configure.in: + * eel/check-program.c: (main): + * eel/eel-list-column-title.c: + * eel/eel-list.c: + * eel/eel-smooth-widget.c: (smooth_widget_get_gtk_background): + * test/dumb-box.h: + * test/test-eel-image-chooser.c: (populate_image_chooser_callback): + * test/test-eel-image.c: (pixbuf_new_from_name): + * test/test-eel-label-flavorful.c: (font_get_name): + * test/test-eel-label-offset.c: + * test/test-eel-label.c: (main): + * test/test-eel-password-dialog.c: (main): + * test/test-eel-pixbuf-tile.c: (pixbuf_drawing_area_expose_event), + (drawable_drawing_area_expose_event): + * test/test-eel-viewport-constraint.c: (main): + * test/test-eel-widgets.c: (create_pixbuf), (main): + * test/test.c: (test_pixbuf_new_named), (eel_pixmap_file): + * test/test.h: + +2001-07-13 Darin Adler + + Enough to make everything compile. + The eel self-check program doesn't link yet. + + * eel/check-program.c: (main): + * eel/eel-password-dialog.c: (caption_table_activate_callback), + (eel_password_dialog_new), (eel_password_dialog_run_and_block): + * eel/eel-preferences-box.c: (eel_preferences_dialog_new): + * eel/eel-stock-dialogs.c: (timed_wait_callback), + (eel_run_simple_dialog), (create_message_dialog), + (show_message_box), (show_ok_box), (eel_create_info_dialog), + (details_dialog_clicked_callback), + (eel_show_info_dialog_with_details), + (eel_show_error_dialog_with_details), (eel_show_yes_no_dialog), + (eel_create_question_dialog): + * eel/eel-types.c: (eel_type_init): + +2001-07-13 Darin Adler + + A cut at making things compile with MATE 2. + Some things are inside #ifdef MATE2_CONVERSION_COMPLETE. + 90% of the way to compiling everything. + + * eel/.cvsignore: + * eel/Makefile.am: + * eel/check-program.c: (main): + * eel/eel-background-canvas-group.c: + (eel_background_canvas_group_supplant_root_class): + * eel/eel-background.c: (eel_background_initialize_class), + (eel_background_draw), (eel_background_draw_flat_box), + (eel_background_set_widget_style), (eel_get_widget_background), + (eel_background_receive_dropped_color): + * eel/eel-canvas-rect.c: (rect_update): + * eel/eel-canvas-rect.h: + * eel/eel-caption-table.c: (eel_caption_table_initialize_class), + (eel_caption_table_get_entry_text): + * eel/eel-clickable-image.c: + (eel_clickable_image_initialize_class): + * eel/eel-clist.c: + * eel/eel-ctree.c: (eel_ctree_class_init): + * eel/eel-dnd.c: (eel_drag_drop_action_ask): + * eel/eel-enumeration.c: + * eel/eel-font-manager.c: (file_as_string), + (font_description_table_new), (collect_fonts_from_directory), + (directory_contains_file), (try_using_font_server), + (ensure_local_font_table), (eel_font_manager_get_default_font), + (eel_font_manager_get_default_bold_font), + (eel_self_check_font_manager): + * eel/eel-font-picker.c: (eel_font_picker_initialize_class), + (font_picker_add_item), (font_picker_populate): + * eel/eel-gdk-extensions.c: (eel_gdk_window_set_invisible_cursor): + * eel/eel-gdk-font-extensions.c: (font_get_name): + * eel/eel-gdk-pixbuf-extensions.c: (eel_gdk_pixbuf_load), + (file_read_callback), (load_done), + (eel_gdk_pixbuf_get_from_window_safe): + * eel/eel-gdk-pixbuf-extensions.h: + * eel/eel-glib-extensions.c: + * eel/eel-mate-extensions.c: (eel_dialog_get_button_by_index), + (get_terminal_command_prefix), (eel_mate_icon_selector_new), + (eel_mate_stock_set_icon_or_register): + * eel/eel-mate-extensions.h: + * eel/eel-gtk-extensions.c: (send_delete_event), + (handle_standard_close_accelerator), + (eel_popup_menu_position_func), (eel_gtk_menu_insert_separator), + (eel_gtk_signal_connect_full_while_alive), + (eel_gtk_signal_connect_while_realized), + (eel_nullify_when_destroyed), (eel_nullify_cancel), + (event_get_time): + * eel/eel-gtk-extensions.h: + * eel/eel-gtk-macros.h: + * eel/eel-image-chooser.c: (eel_image_chooser_initialize_class): + * eel/eel-image-table.c: (eel_image_table_initialize_class): + * eel/eel-image.c: (eel_image_initialize_class), + (eel_image_set_pixbuf_from_file_name), + (eel_image_set_tile_pixbuf_from_file_name): + * eel/eel-label.c: (eel_label_initialize_class), + (eel_label_set_is_smooth), + (eel_label_set_tile_pixbuf_from_file_name), + (eel_label_set_never_smooth): + * eel/eel-list-column-title.c: + (eel_list_column_title_initialize_class), + (eel_list_column_title_destroy), (eel_list_column_title_finalize), + (eel_list_column_title_request), (eel_list_column_title_paint): + * eel/eel-list.c: (eel_list_initialize_class), + (eel_list_initialize), (eel_list_clear_keyboard_focus), + (eel_list_set_keyboard_focus), (eel_list_size_request), + (new_column_width), (draw_rows), (eel_list_draw), + (eel_list_expose), (eel_list_row_at): + * eel/eel-password-dialog.c: (caption_table_activate_callback), + (eel_password_dialog_new), (eel_password_dialog_run_and_block): + * eel/eel-password-dialog.h: + * eel/eel-preferences-box.c: (preferences_box_select_pane), + (eel_preferences_dialog_new): + * eel/eel-preferences-box.h: + * eel/eel-preferences-group.c: + (eel_preferences_group_get_title_label): + * eel/eel-preferences-item.c: + (eel_preferences_item_initialize_class): + * eel/eel-preferences-pane.h: + * eel/eel-preferences.c: + * eel/eel-radio-button-group.c: + (eel_radio_button_group_initialize_class): + * eel/eel-region.c: (gdk_region_new_from_irect), + (eel_region_add_rectangle), (eel_region_subtract_rectangle): + * eel/eel-scalable-font.c: + * eel/eel-smooth-widget.h: + * eel/eel-stock-dialogs.c: (add_label_to_dialog), + (timed_wait_delayed_close_timeout_callback), (timed_wait_free), + (timed_wait_dialog_destroy_callback), (timed_wait_callback), + (delete_event_callback), (eel_run_simple_dialog), + (create_message_dialog), (show_message_box), (show_ok_box), + (eel_create_info_dialog), (eel_show_info_dialog), + (details_dialog_clicked_callback), + (eel_show_info_dialog_with_details), (eel_show_warning_dialog), + (eel_show_error_dialog), (eel_show_error_dialog_with_details), + (eel_show_yes_no_dialog), (eel_create_question_dialog): + * eel/eel-stock-dialogs.h: + * eel/eel-string-picker.c: (eel_string_picker_initialize_class), + (eel_string_picker_set_string_list): + * eel/eel-text-caption.c: (eel_text_caption_initialize_class): + * eel/eel-types.c: (eel_type_init): + * eel/eel-viewport.c: (eel_viewport_initialize_class), + (eel_viewport_draw), (eel_viewport_size_allocate): + * eel/eel-xml-extensions.c: + +2001-07-11 Darin Adler + + * eel/eel-font-manager.c: (collect_fonts_from_directory): + Fix code that can segfault due to unknown MIME type. + + * eel/eel-scalable-font.c: (initialize_global_stuff_if_needed): + Tell librsvg our datadir so we don't have to be in the same prefix + as librsvg. There's this bad thing where we install fonts that the + librsvg library has to find. Lets hope we can obsolete this + completely soon. + +2001-07-09 Ramiro Estrugo + + * .cvsignore: + * Makefile.am: + * autogen.sh: + * configure.in: + * eel-2.0.pc.in: + * eel-config.in: + * eel.spec.in: + * eel/eel-art-extensions.h: + * eel/eel-art-gtk-extensions.h: + * eel/eel-background-canvas-group.c: + * eel/eel-background-canvas-group.h: + * eel/eel-background.h: + * eel/eel-canvas-rect.h: + * eel/eel-caption-table.h: + * eel/eel-caption.h: + * eel/eel-clickable-image.h: + * eel/eel-font-manager.h: + * eel/eel-font-picker.h: + * eel/eel-mateconf-extensions.h: + * eel/eel-glyph.h: + * eel/eel-image-chooser.h: + * eel/eel-image-table.h: + * eel/eel-image-with-background.h: + * eel/eel-image.h: + * eel/eel-label-with-background.h: + * eel/eel-label.h: + * eel/eel-labeled-image.h: + * eel/eel-list.h: + * eel/eel-password-dialog.h: + * eel/eel-preferences-box.h: + * eel/eel-preferences-group.h: + * eel/eel-preferences-item.h: + * eel/eel-preferences-pane.h: + * eel/eel-preferences.h: + * eel/eel-radio-button-group.h: + * eel/eel-region.h: + * eel/eel-scalable-font-private.h: + * eel/eel-scalable-font.h: + * eel/eel-smooth-text-layout-cache.h: + * eel/eel-smooth-text-layout.h: + * eel/eel-smooth-widget.h: + * eel/eel-string-picker.h: + * eel/eel-text-caption.h: + * eel/eel-vfs-extensions.h: + * eel/eel-viewport.h: + * eel/eel-wrap-table.h: + * eelConf.sh.in: + Begin port to MATE2, part 1. Make configure work in the MATE2 + universe and also a few simple s/BEGIN_MATE_DECLS/G_BEGIN_DECLS/ + +2001-07-09 Ramiro Estrugo + + * eel/eel-art-extensions.h: + * eel/eel-art-extensions.c: (eel_art_drect_get_width), + (eel_art_drect_get_height), (eel_art_irect_assign_end_points), + (eel_art_drect_assign_end_points), (eel_art_ipoint_offset_by), + (eel_art_point_equal): + More ArtDRect versions of point/rectangle stuff. + +==== eel 1.0.1 ==== + +2001-07-05 Darin Adler + + * configure.in: Bumped version to 1.0.1 + * NEWS: Some notes about recent changes. + +2001-06-26 Alexander Larsson + + * eel/eel-font-manager.c (eel_font_manager_get_default_font, + eel_font_manager_get_default_bold_font): + Don't keep looking for the files after we found them the first + time. + +2001-06-26 Ramiro Estrugo + + * eel/eel-art-extensions.h: + * eel/eel-art-extensions.c: (eel_art_irect_is_empty): New function. + (eel_art_ipoint_offset_by): New function. + +2001-06-25 Ramiro Estrugo + + * eel/eel-art-extensions.h: + * eel/eel-art-extensions.c: (eel_dimensions_clamp), + (test_dimensions_clamp), (eel_self_check_art_extensions): + New constant points. New function to clamp dimensions . + * eel/eel-string-list.h: + * eel/eel-string-list.c: (eel_string_list_insert_string_list): + New function to insert a string list into another. + +2001-06-06 Ramiro Estrugo + + Patch from Frederic Devernay + (tweaked by me to | bits instead of +) to make the Eel Font Manager + follow links when determining the mime type of fonts. + + * eel/eel-font-manager.c: (collect_fonts_from_directory), + (eel_font_manager_file_is_scalable_font): + +2001-06-06 Darin Adler + + Integrated a revised version of a patch by Eungkyu Song + to make the font manager code accept either a + tab or a space as the separator. + + * eel/eel-font-manager.c: (font_description_table_add): Use + strpbrk instead of strstr. + +2001-06-06 Alex Larsson + + * eel/eel-background.[ch] (eel_background_draw): + This function now takes both the src and dest coordinates. + (eel_background_draw_to_drawable): Update to the new + eel_background_draw API. + * eel/eel-background-canvas-group.c + (eel_background_canvas_group_draw): Update to the new + eel_background_draw API. + +2001-06-05 Ramiro Estrugo + + * eel/eel-gtk-container.c: (eel_gtk_container_child_size_allocate): + Move the critical after the child check for NULL since we allow + a NULL child to be given. + +2001-06-05 Ramiro Estrugo + + * eel/eel-art-extensions.c: (eel_art_ipoint_clamp), + (test_irect_intersect), (test_irect_union), (test_ipoint_clamp), + (eel_self_check_art_extensions): + * eel/eel-art-extensions.h: + New function to clamp a point plus checks for that. + +2001-06-04 Ramiro Estrugo + + * eel/eel-debug-drawing.h: + * eel/eel-debug-drawing.c: + (eel_debug_show_pixbuf_in_external_viewer): + Replace the hard coded eog viewer to one that can accept any + external viewer. I ran into the problem that the Eog binary + changed names from "eog" to "eog-shell" so I decided to make this + debug feature more generic. + + * eel/Makefile.am: + * eel/eel.h: + * eel/eel-gtk-container.h: + * eel/eel-gtk-container.c: (eel_gtk_container_child_expose_event), + (eel_gtk_container_child_map), (eel_gtk_container_child_unmap), + (eel_gtk_container_child_add), (eel_gtk_container_child_remove), + (eel_gtk_container_child_size_allocate): + New files. Functions to simplify the implementations of + GtkContainer widgets. + + * eel/eel-gtk-extensions.c: (eel_gtk_widget_standard_realize): + Dont hardcode the event mask. Use gtk_widget_get_events() + instead. Also document this fact so that users are aware that + they need to set the event mask using gtk_widget_set_events () - + which is the right Gtk+ way anyway. + + * eel/eel-image-chooser.c: (eel_image_chooser_initialize): + Call gtk_widget_set_events() with the right event mask for the + image chooser. + + * eel/eel-labeled-image.c: (eel_labeled_image_size_allocate), + (eel_labeled_image_expose_event), (eel_labeled_image_map), + (eel_labeled_image_unmap), (eel_labeled_image_add), + (eel_labeled_image_remove): + Simplify the implementations of GtkContainer methods by using the + functions in eel-gtk-container.[ch]. Theres probably other + widgets in Eel and Caja that could benefit from this + simplification/code sharing as well. + + * eel/eel-self-checks.c: (eel_check_double_result): + * eel/eel-self-checks.h: + New checks for double values. + + * eel/eel-string-list.h: + * eel/eel-string-list.c: (eel_string_list_new_from_string_array): + New function to allocate a EelStringList from a regular C string + array. + (eel_string_list_assign_from_string_array): New function to assign + a regular C string array to a EelStringList. + (eel_string_list_reverse): New function to reverse a string list. + (test_string_list_reverse), (test_new_from_string_array), + (eel_self_check_string_list): Self checks for the above new + functions. + + * test/dumb-box.c: (eel_dumb_box_initialize_class), + (eel_dumb_box_expose): Some dumb cleanup of old comment cruft. + * test/test-eel-font-simple.c: (main): + * test/test-eel-font.c: (main): + * test/test-eel-glyph-simple.c: (main): + * test/test-eel-glyph.c: (main): + * test/test-eel-smooth-text-layout.c: (main): + Update for changes in debug function to view pixbufs in external + viewers. + +2001-06-04 Darin Adler + + * eel/eel-font-manager.c: (collect_fonts_from_directory), + (eel_font_manager_file_is_scalable_font): + * test/test-eel-background.c: (main): + * test/test-eel-label.c: (widget_set_eel_background_image): + * test/test.c: (test_gtk_widget_set_background_image): + Fix all code that prepends "file://" to try to make a URI from a + path. Use mate_vfs_get_uri_from_local_path instead. + +2001-06-01 Alex Larsson + + * eel/eel-background.c (eel_background_draw_flat_box): + Only render area if we get passed an area. + (eel_background_draw): Do correct translation of + coordinates for destination drawable. + +2001-06-01 Darin Adler + + * configure.in: Bump version number to 1.0.0.1 + * NEWS: Mention the plans to release 1.0.1 + +2001-06-01 Darin Adler + + * eel/eel-list.c: (eel_list_button_release): Fixed code that was + passing x twice instead of x and y that prevented single-click + from working in the Caja list view. Also did some other + cleanups to behavior when multiple buttons are pressed at once. + +2001-05-22 John Harper + + Fallout from fixing bug 8220 (Having Ctrl as default "modifier + key used for default WM shortcuts" breaks everything...): + + * eel/eel-list.c (eel_list_keyboard_move_to, + eel_list_keyboard_space): changed to use Control modifier + instead of Alt + +2001-05-20 Darin Adler + + Checked in change for Miguel Rodríguez Pérez + . + + * eel/eel-preferences-item.c + (preferences_item_update_editable_string): + (preferences_item_update_editable_integer): Only update + text if it changed. + +2001-05-19 George Lebl + + * configure.in, po/cs.po: Add czech translations + +2001-05-17 Darin Adler + + * eel/eel-gtk-extensions.c: + (eel_gtk_signal_connect_full_while_alive): Weakened a + too-strong g_return_if_fail. + +2001-05-09 Ramiro Estrugo + + * eel/eel-self-checks.h: + * eel/eel-self-checks.c: + Make eel_after_check() and eel_report_check_failure() public so + that third party projects can use them to construct their own + checks and still be able to use the same check failure reporting + machinery. + +2001-05-08 Darin Adler + + * RENAMING: Refine the renaming ideas. + +==== eel 1.0 ==== + +2001-05-04 Robin * Slomkowski + + * configure.in: fixed lirsvg test for 1.0.x + +2001-05-04 Robin * Slomkowski + + * configure.in: upped version to 1.0 and changed upped + dependance too librsvg 1.0.0 + +2001-05-04 Robin * Slomkowski + + * configure.in: upped version to 0.1 + +2001-05-04 Ramiro Estrugo + + * eel/eel-preferences-item.c: + (preferences_item_create_editable_string): + Restore a silly hack for the sake of Caja. Id like to + properly fix this, but not so close to a release. + +2001-05-04 Ramiro Estrugo + + * configure.in: + Add MateConf and OAF dependency. + + * eel.spec.in: + Add MateConf and OAF dependency. Also add missing BuildRequires + entries. + + * eel/Makefile.am: + Need to set librsvg cflags directly here, since librsvg does not + appear in any public eel headers and thus not exported in + eel-config --cflags. + + * eel/eel-dateedit-extensions.c: + * eel/eel-dateedit-extensions.h: + * eel/eel-mateconf-extensions.c: + * eel/eel-mateconf-extensions.h: + * eel/eel-generous-bin.c: + * eel/eel-generous-bin.h: + * eel/eel-lib-self-check-functions.h: + * eel/eel-preferences-box.c: + * eel/eel-preferences-box.h: + * eel/eel-preferences-group.c: + * eel/eel-preferences-group.h: + * eel/eel-preferences-item.c: + * eel/eel-preferences-item.h: + * eel/eel-preferences-pane.c: + * eel/eel-preferences-pane.h: + * eel/eel-preferences.c: + * eel/eel-preferences.h: + * eel/eel.h: + Move over some more stuff over from Caja. + +2001-05-03 Darin Adler + + * RENAMING: Some renaming ideas. + +2001-05-03 Darin Adler + + * eel/eel-vfs-extensions.h: + * eel/eel-vfs-extensions.c: (eel_make_uri_from_half_baked_uri), + (eel_self_check_vfs_extensions): Add new call to make a canonical + URI from the kind of half-baked URIs that are used in gmc URL + files and in drag and drop. The definition of a half-baked URI is + that it starts with "file:" and then has a normal path, without + URI escaping. + + * Makefile.am: Fixed a typo. + +2001-05-03 Ramiro Estrugo + + * eel/eel-gdk-extensions.h: Add an opaque version of the color + packing macro. + * eel/eel-gdk-extensions.c: (eel_self_check_gdk_extensions): Add + checks for color packing macros. + + * eel/eel-art-extensions.h: + * eel/eel-art-extensions.c: (eel_art_irect_intersect), + (eel_art_irect_union), (eel_dimensions_assign), + (eel_dimensions_equal), (eel_art_ipoint_assign), + (eel_art_ipoint_equal), (test_intersect), (test_union), + (eel_self_check_art_extensions): Some more art extensions. + Currently unused in Eel or Caja. + + * eel/eel-self-checks.h: + * eel/eel-self-checks.c: + Add self check machinery for EelArtIPoints. + + * eel/eel-gdk-pixbuf-extensions.h: Dumb spacing tweak. + +2001-05-02 Darin Adler + + Fixed bug 8219 (crash under libefence): + + * eel/eel-scalable-font.c: (eel_scalable_font_new), + (free_global_font_handle_table): Dup the font names before using + them as keys, since the underlying freetype font can last longer + than the EelScalableFont. + +2001-05-02 Ramiro Estrugo + + * eel/eel-debug-drawing.c: (eel_debug_show_pixbuf_in_eog): + Update for EOG name change. eog got renamed to eog-shell. + +2001-05-02 Ramiro Estrugo + + * configure.in: + Lots of improvement. Make dealing with dependency libs/cflags simpler. + + * eel/Makefile.am: + * test/Makefile.am: + Eliminate cut-n-paste disease by using dependency macros defined + in configure.in. + +2001-05-02 Ramiro Estrugo + + * autogen.sh: + Detect whether the invocation of configure failed and print a + message accordingly. We used to always assume that configure was + successful and print misleading "now type make to build $PROJECT" + messages. + +2001-05-01 Ramiro Estrugo + + * configure.in: + Simplify the freetype2 detection insanity by using autoconf macro + technology. The new test should work with both FreeType2 RPMS as + well as freetype built from source in any prefix. + +2001-05-01 Ramiro Estrugo + + * eel/eel-gdk-pixbuf-extensions.c: + * eel/eel-gdk-pixbuf-extensions.h: + * eel/eel-glyph.c: + * eel/eel-glyph.h: + * eel/eel-label.c: + * eel/eel-scalable-font.c: + * eel/eel-scalable-font.h: + * eel/eel-smooth-text-layout.c: + * eel/eel-smooth-widget.c: + * test/test-eel-font-simple.c: + * test/test-eel-font.c: + * test/test-eel-glyph-simple.c: + * test/test-eel-glyph.c: + * test/test-eel-smooth-text-layout.c: + More work on changing parameters for functions that accept and + return ArtIRect, EelArtIPoint, ArtDRect, EelDimensions to pass by + value instead of by pointer. + +2001-05-01 Ramiro Estrugo + + * test/Makefile.am: + Add include flag for test directory. + +2001-05-01 Ramiro Estrugo + + * eel/eel-image-chooser.c: + Respect the GtkStyle. + + * test/.cvsignore: + * test/Makefile.am: + * test/dumb-box.h: + * test/dumb-box.c: + * test-eel-gtk-style.c: + Add a GtkStyle debugging tool + + * test/test-eel-image-chooser.c: + Update for style respect changes. + +2001-04-30 Ramiro Estrugo + + * eel/Makefile.am: + Remove some garbage that apparently satan tried to sneak in. + +2001-04-30 Darin Adler + + reviewed by: John Sullivan + + Fixed bug 8198 ("New Terminal" does not use MATE default + applications). This involved changing the API, so it requires + changes to Caja too. + + * eel/eel-glib-extensions.c: (eel_shell_quote): Make it smarter so + it doesn't quote simple things with no fancy characters in them. + (eel_self_check_glib_extensions): Update test. + + * eel/eel-mate-extensions.h: + * eel/eel-mate-extensions.c: (try_terminal_command), + (try_terminal_command_argv), (get_terminal_command_prefix): New + functions, used to implement eel_mate_open_terminal. These look + at the mate-config setting that controls which terminal program + is used. + (eel_mate_make_terminal_command): New public function. We've now + eliminated the concept of just getting the name of a terminal + program. + (eel_mate_open_terminal): Use eel_mate_make_terminal_command to + do the hard part. + +2001-04-30 John Sullivan + + Fixed bug 6234 (Escape should close Properties window) + Fixed bug 6271 (Close dialogs with Escape to match MATE standard) + + * eel/eel-gtk-extensions.c: + (eel_gtk_window_event_is_close_accelerator): Close dialogs with + Escape as well as Control-W. (non-MateDialogs can either call + eel_gtk_window_set_up_close_accelerator to arrange this, or can call + this querying function directly). + +2001-04-30 Ramiro Estrugo + + * eel/eel-art-extensions.c: + * eel/eel-art-extensions.h: + * eel/eel-art-gtk-extensions.c: + * eel/eel-art-gtk-extensions.h: + * eel/eel-clickable-image.c: + * eel/eel-debug-drawing.c: + * eel/eel-debug-drawing.h: + * eel/eel-gdk-pixbuf-extensions.c: + * eel/eel-gdk-pixbuf-extensions.h: + * eel/eel-glyph.c: + * eel/eel-glyph.h: + * eel/eel-mate-extensions.c: + * eel/eel-mate-extensions.h: + * eel/eel-image-chooser.c: + * eel/eel-image-table.c: + * eel/eel-image-with-background.c: + * eel/eel-image.c: + * eel/eel-label.c: + * eel/eel-labeled-image.c: + * eel/eel-region.h: + * eel/eel-smooth-text-layout.c: + * eel/eel-smooth-text-layout.h: + * eel/eel-smooth-widget.c: + * eel/eel-smooth-widget.h: + * eel/eel-wrap-table.c: + * test/test-eel-font.c: + * test/test-eel-glyph-simple.c: + * test/test-eel-glyph.c: + * test/test-eel-pixbuf-tile.c: + * test/test-eel-smooth-text-layout.c: + * test/test.c: + Change parameters for functions that accept and return ArtIRect, + EelArtIPoint, ArtDRect, EelDimensions to pass by value instead of + by pointer. + +2001-04-29 Ramiro Estrugo + + * eel/eel-enumeration.c: (eel_self_check_enumeration): + Add one more check. + + * eel/eel-string-picker.h: + * eel/eel-string-picker.c: (eel_string_picker_set_string_list), + (eel_string_picker_insert_string), + (eel_string_picker_insert_separator): + Add support for separators. + +2001-04-26 Ramiro Estrugo + + * eel/eel-art-extensions.h: + * eel/eel-art-extensions.c: (eel_art_irect_align), + (eel_dimensions_are_empty), (eel_art_irect_assign_dimensions), + (eel_self_check_art_extensions): Change constants to be lower + case. Also declare them as "extern const" and not just "extern." + + * eel/eel-art-gtk-extensions.c: (eel_gdk_rectangle_to_art_irect), + (eel_gdk_window_get_bounds), + (eel_gdk_window_get_screen_relative_bounds), + (eel_gtk_widget_get_bounds), (eel_gtk_widget_get_dimensions), + (eel_gtk_widget_get_preferred_dimensions), + (eel_gdk_window_clip_dirty_area_to_screen), + (eel_gdk_window_get_dimensions): + * eel/eel-debug-drawing.c: (debug_pixbuf_viewer_size_request): + * eel/eel-gdk-pixbuf-extensions.c: (eel_gdk_pixbuf_get_dimensions), + (eel_gdk_pixbuf_intersect): + * eel/eel-glyph.c: (eel_glyph_get_dimensions), + (eel_glyph_intersect): + * eel/eel-image-chooser.c: (image_chooser_get_partial_dimensions): + * eel/eel-image.c: (image_get_pixbuf_dimensions), + (image_get_pixbuf_bounds), (image_get_tile_dimensions): + * eel/eel-label.c: (label_composite_text_callback_cached), + (label_get_text_dimensions), (label_get_text_bounds), + (label_get_content_dimensions), (label_get_content_bounds), + (label_get_tile_dimensions): + * eel/eel-labeled-image.c: (labeled_image_get_image_dimensions), + (labeled_image_get_label_dimensions), + (labeled_image_get_image_bounds_fill), + (eel_labeled_image_get_image_bounds), + (labeled_image_get_label_bounds_fill), + (eel_labeled_image_get_label_bounds), + (labeled_image_get_content_dimensions), + (labeled_image_get_content_bounds): + * eel/eel-scalable-font.c: (eel_scalable_font_measure_text): + * eel/eel-smooth-text-layout.c: + (eel_smooth_text_layout_get_dimensions): + * eel/eel-smooth-widget.c: (smooth_widget_get_tile_origin_point), + (eel_smooth_widget_get_tile_bounds), + (eel_smooth_widget_get_preferred_dimensions): + * eel/eel-viewport.c: (eel_viewport_get_scroll_offset): + * eel/eel-wrap-table.c: (wrap_table_art_irect_max_dimensions), + (wrap_table_get_max_child_dimensions), + (wrap_table_get_content_dimensions), + (wrap_table_get_content_bounds), (wrap_table_get_scroll_offset): + Update for art extensions constants renaming. + +2001-04-26 Ramiro Estrugo + + * eel/eel-image-chooser.c: (image_chooser_motion_notify_event), + (image_chooser_button_press_event), + (image_chooser_button_release_event): + Use pointer grab technology to prevent the list from getting + events from unrelated widgets. + +2001-04-26 John Sullivan + + * eel/eel-list.c: (eel_list_get_cell_hit_rectangle), (draw_cell): + Made drawing and hit-testing code immune to NULL text. This was + spewing out tons of complaints before in search results view + (from the fancy date-squeezing code). + +2001-04-26 John Sullivan + + Merged from caja-1 branch: + + 2001-03-30 Ramiro Estrugo + + reviewed by: John Harper + + * eel/eel-stock-dialogs.c: (create_message_box): + Make sure the label is not NULL before changing its line wrap. + This works around the crashing problem. Why the label is NULL is + still a mystery. + +2001-04-26 Darin Adler + + * eel/eel-debug.h: + * eel/eel-debug.c: (call_default_log_handler_with_better_message): + Add comment about handling cases where we're out of + memory. Removed unneeded NULL-handling code. + (eel_assert_computed_str), (eel_str_equal_with_free): Removed an + old unused feature. + + * eel/eel-mate-extensions.c: Formatting tweaks. + +2001-04-26 Ramiro Estrugo + + * eel/eel-enumeration.h: + * eel/eel-enumeration.c: + (eel_enumeration_get_nth_description_translated), + (eel_enumeration_id_get_nth_description), + (eel_enumeration_id_get_nth_description_translated): + New functions to fetch translated descriptions. + +2001-04-26 Ramiro Estrugo + + * eel/Makefile.am: + Build the image chooser widget. + + * eel/eel-art-gtk-extensions.h: + * eel/eel-art-gtk-extensions.c: (eel_gdk_get_pointer_position): + New function to obtain the pointer position as a point. + + * eel/eel-caption.h: + * eel/eel-caption.c: (eel_caption_initialize_class), + (eel_caption_destroy), (caption_show_all), + (eel_caption_set_show_title): + Fix some rotten comments and other minor style tweaks. Remove + unused defines. Fix wrongly named show_all method, a cut-n-paste + mistake. + + * eel/eel-gdk-extensions.h: + * eel/eel-gdk-extensions.c: (eel_gdk_rgb_to_color): + Return the resulting color as a structure instead of a pointer. + + * eel/eel-gtk-extensions.h: + * eel/eel-gtk-extensions.c: (eel_gtk_widget_standard_realize), + (eel_gtk_widget_standard_draw), + (eel_gtk_bin_standard_size_allocate), + (eel_gtk_bin_standard_size_request): + Implementations of some standard gtk widget methods. + + * eel/eel-label.c: + (eel_label_set_solid_background_color), + (eel_label_set_text_color): Fix a bug where the label + wouldnt properly update when some color attributes changed because + of a stale solid pixbuf cache. + + * eel/eel-radio-button-group.h: + * eel/eel-radio-button-group.c: + (eel_radio_button_group_clear): New function to clear out all the + items in the group. + (eel_radio_button_group_initialize_class): + (eel_radio_button_group_initialize), + (eel_radio_button_group_destroy), (button_toggled), + (eel_radio_button_group_insert): + Caja style tweaks. Remove unused constant. Change signal + signature to be simpler. Remove the signal data nastiness and let + the caller find out the active item by using the getter methods + instead. + (eel_radio_button_group_get_active_index), + (eel_radio_button_group_set_active_index): Use signed integers for + the active index. + + * eel/eel-string-list.h: + * eel/eel-string-list.c: (eel_string_list_append): + New function to append one string list to another. + + * eel/eel-viewport.h: + * eel/eel-viewport.c: (eel_gtk_scrolled_window_add_with_viewport): + New convenience function to create scrolled windows with an + EelViewport as the child. + + * eel/eel.h: + Add eel-image-chooser.h + + * test/.cvsignore: + * test/Makefile.am: + Build the image chooser test. + + * test/test.h: + Include eel.h instead of the individual headers. + +2001-04-26 Ramiro Estrugo + + * eel/eel-image-chooser.h: + * eel/eel-image-chooser.c: + New widget to choose an image from a list. + + * test/test-eel-image-chooser.c: + Test program for the new widget. + +2001-04-24 Darin Adler + + reviewed by: Ramiro Estrugo + + * eel/eel-debug.c: + (eel_make_warnings_and_criticals_stop_in_debugger): + Add more log domains, most importantly "". + +2001-04-20 John Harper + + reviewed by: Darin Adler + + * eel/eel-mate-extensions.h, eel/eel-mate-extensions.c + (eel_mate_win_hints_get_area, + eel_mate_win_hints_get_current_area, + eel_mate_win_hints_set_area, + eel_mate_win_hints_set_current_area): new functions + + * eel/eel-gtk-extensions.c (eel_gtk_window_present): changed to + use the above new functions + + * eel/eel-gtk-extensions.h, eel/eel-gtk-extensions.c + (eel_gtk_window_is_on_current_workspace_and_area): new function + +2001-04-20 jacob berkman + + * eel/eel-gtk-extensions.c (eel_gtk_window_present): make sure the + window is also on the current viewport/area. sawfish needs to be + updated to listen to _WIN_AREA changes though. + +2001-04-20 Ramiro Estrugo + + * eel/eel-font-manager.c: (try_using_font_server): + Remove printf left in by accident. + +2001-04-20 Ramiro Estrugo + + Fix for 8084 - Not all fonts are added to the font list in + preferences dialog. + + * eel/eel-font-manager.c: (try_using_font_server), + (ensure_local_font_table): + Try more than just one know location for the font server + configuation file. If different systems (like different Linux + distributions) put this in other places, then we'll have to update + this code as we know more. Seems lame, but I guess if + distributors and "users" have a choice where to put config files, + then we have no choice but comply. + +2001-04-20 Ramiro Estrugo + + * eel/eel-glib-extensions.h: + * eel/eel-glib-extensions.c: (eel_get_operating_system_name), + (eel_self_check_glib_extensions): + New function to find out the system name. + +2001-04-20 Ramiro Estrugo + + * configure.in: + Use /usr/X instead of /usr/openwin which is the new way on + solaris. + +2001-04-20 Ramiro Estrugo + + Fix for bug 7847 - SOLARIS: When Smoother Graphics turned on - + cannot change Fonts. + + * acconfig.h: + * configure.in: + * eel/eel-font-manager.c: (ensure_local_font_table): + Add support for reaping fonts even when the system is not using + the font server. + + * eel/eel-string-list.c: (eel_self_check_string_list): + Add a few more checks for string tokenizing. + +2001-04-19 Ramiro Estrugo + + * eel/Makefile.am: Add a log domain define for Eel. + * eel/eel-debug.c: + (eel_make_warnings_and_criticals_stop_in_debugger): Remove + G_LOG_DOMAIN item as it will be the same as Eel for this module. + Add Gdk-Pixbuf to the list of standard log domains. + +2001-04-19 Ramiro Estrugo + + * eel/eel-debug.c: + (eel_make_warnings_and_criticals_stop_in_debugger): + Add a list of "standard" domains for which this debugging feature + is always turned on. + +2001-04-19 Darin Adler + + reviewed by: Ramiro Estrugo + + * eel/eel-debug.c: (get_process_name), + (call_default_log_handler_with_better_message), (log_handler), + (set_log_handler), + (eel_make_warnings_and_criticals_stop_in_debugger): + Add the process name and number prefix to all lines. Also fix + the use of getuid where we meant to use getpid. Also tweak + the names of things a bit to make it nicer. + +2001-04-19 Ramiro Estrugo + + reviewed by: Darin Adler + + * eel/eel-debug.c: (get_process_command_line): A function to try + and obtain the command line used to invoke the process. + (eel_stop_after_default_log_handler): Print out the process id + and possible command line to make the warning/critical more + useful. + +2001-04-18 Darin Adler + + * eel/eel-canvas-rect.c: (canvas_item_update_svp_no_repaint), + (canvas_item_update_svp_clip_no_repaint), (rect_update): Renamed + the internal functions to make it more clear what they do. + (eel_canvas_rect_initialize_class): Improved comment. + (rects_intersect): Changed name. + (diff_rects): Update for new name of rects_intersect. + (test_rects_intersect), (eel_self_check_canvas_rect): Added tests + for rects_intersect. + +2001-04-18 Darin Adler + + * eel/eel-canvas-rect.c: (rect_update): Removed a bunch of code + that's not needed since we decided to optimize only the case + where the canvas is an anti-aliased one. + +2001-04-18 Darin Adler + + * eel/eel-canvas-rect.c: (rect_update): Fixed backwards logic that + made it never draw the outline. + +2001-04-18 Darin Adler + + * eel/eel-canvas-rect.c: (make_drect): New function. + (make_empty_drect): New function. + (make_rect_vpath): Changed to take ArtDRect. + (eel_canvas_item_update_svp), (eel_canvas_item_update_svp_clip): + Stole functions from MateCanvas code, because we need versions + that don't do a request_update. + (canvas_request_update_rect): New function. + (rect_update): Changed to do smart calculation about what to + update using the diff_rects function. + (diff_rects_guts), (diff_rects): New implementation that doesn't + use macros. Also changed to leave out empty rectangles. + (eel_self_check_canvas_rect): Updated tests that involve empty + rectangles and added some new ones. + +2001-04-18 Christopher James Lahey + + * eel/eel-canvas-rect.c (intersect_rectangles): Fixed the + intersect_rectangles function to have rectangles that are tangent + return as not intersecting. + (eel_self_check_canvas_rect): Fixed the tests. + +2001-04-18 Darin Adler + + * eel/eel-canvas-rect.c: (rect_update): Call diff_rectangles so we + don't get an unused function warning. + (diff_rectangles): Took out of #if 0 and made it compile without + warnings. + (test_diff_rectangles): Test function that uses string for result. + (eel_self_check_canvas_rect): Added two self-tests. The one that + currently fails is commented out. + +2001-04-18 Darin Adler + + * eel/eel-canvas-rect.h: + * eel/eel-canvas-rect.c: (set_gc_foreground), (set_stipple), + (set_outline_gc_width), (re_update_shared), (re_get_bounds), + (make_rect_vpath), (rect_update): Copied the update function + and everything it needs in here, so we can prepare to modify it. + +2001-04-18 Christopher James Lahey + + * eel/eel-canvas-rect.c: Added some tests #ifdefed out. Wrote the + diff and intersection functions. + +2001-04-18 Darin Adler + + * eel/eel-canvas-rect.c: (eel_self_check_canvas_rect): + * eel/eel-lib-self-check-functions.h: + Added a self-check function for EelCanvasRect. + + * eel/eel-self-checks.c: (eel_exit_if_self_checks_failed): + Formatting tweak. + +2001-04-18 Darin Adler + + * eel/Makefile.am: + * eel/eel-canvas-rect.c: + * eel/eel-canvas-rect.h: + Added new class that Chris Lahey and I are working on should make + the selection rectangle in Caja much faster. + +2001-04-18 Ramiro Estrugo + + * eel/Makefile.am: Add the generated files to the CLEANFILES so + that 'make clean' gets rid of them properly. + +2001-04-18 Ramiro Estrugo + + * eel/eel-enumeration.h: + * eel/eel-enumeration.c: (eel_enumeration_contains_name), + (eel_enumeration_id_contains_name), (eel_self_check_enumeration): + New functions to check whether an enumeration contains a specific + name. + + * eel/eel-string-picker.h: + * eel/eel-string-picker.c: (eel_string_picker_initialize), + (eel_string_picker_destroy), (option_menu_activate_callback), + (menu_item_set_sensitivity_callback), + (menu_item_update_sensitivity), + (string_picker_update_menu_sensitivities), + (eel_string_picker_set_insensitive_list): + Add support for installing a list of insensitive choices. + (eel_string_picker_set_string_list): Make sure the list is + different before actually doing any work. + (eel_string_picker_get_string_list), + (eel_string_picker_get_selected_string), + (eel_string_picker_set_selected_string), + (eel_string_picker_set_selected_string_index), + (eel_string_picker_insert_string), (eel_string_picker_contains), + (eel_string_picker_get_index_for_string), + (eel_string_picker_clear): Some minor tweaking to conform with + Caja style some more. + +2001-04-17 Darin Adler + + * eel/Makefile.am: + * eel/eel.h: + Take eel-dnd.h out. This should go back to Caja at some + point, I think. + + * eel/eel-dnd.h: + * eel/eel-dnd.c: + (is_path_that_mate_uri_list_extract_filenames_can_parse), + (add_one_compatible_uri), (eel_drag_drag_data_get): Another cut + at making the kind of "URL" that is compatible with bad old + URL-parsing code. + +2001-04-17 Ramiro Estrugo + + * eel/eel-string-list.h: + * eel/eel-string-list.c: + (eel_string_list_copy): Better name for this function. Dont need + case_sensitive parameter since it can be fetched from the + string_list we are about to copy. + (eel_string_list_as_g_slist): Change list variable name to make + things a tiny bit clearer. + (eel_string_list_as_string): Better name for this function. Add a + num_strings parameter that can be used to limit the number of + strings from the list used to make the new concatenated string. + (eel_self_check_string_list): Update for _as_string changes. + + * eel/eel-enumeration.c: (eel_enumeration_copy), + (eel_enumeration_get_names): Update for _copy changes. + + * eel/eel-gdk-font-extensions.c: (xlfd_string_replace_nth): + Update for _as_string changes. + + * eel/eel-self-checks.c: (eel_check_string_list_result): Update + for _as_string changes. + + * eel/eel-string-picker.c: (eel_string_picker_get_string_list), + (eel_string_picker_insert_string): Update for _copy changes. + +2001-04-17 Darin Adler + + * eel/eel-dnd.c: (add_one_path_with_file_prefix): Coddle existing + drag and drop recipients who use the mate-libs helper functions. + For them, we must provide a "URL" (quotes intentional) that is + just a full path with "file:" stuck on the beginning. + +2001-04-17 Ramiro Estrugo + + * eel/eel-string-list.h: + * eel/eel-string-list.c: + (eel_string_list_new_from_g_slist): New function to create string + lists from GLists. + (eel_string_list_new_from_g_list), (eel_string_list_as_g_slist): + Better names for the GLlist and GSList functions. + (eel_string_list_as_concatenated_string): Return an empty string + ("") if the input string list is NULL. + (eel_string_list_for_each): Make the for_each iterator a little + more type safe. + (eel_self_check_string_list): New checks for GSList functions. + New function to create string lists from GLists. Better names for + the GLlist and GSList functions. + +2001-04-17 Ramiro Estrugo + + * eel/eel-string-list.h: + * eel/eel-string-list.c: (eel_string_list_new_from_slist), + (eel_string_list_as_slist), (eel_self_check_string_list): + New function to create string lists from slists. + +2001-04-17 Ramiro Estrugo + + * eel/eel-string-list.h: + * eel/eel-string-list.c: (eel_string_list_new), + (eel_string_list_new_from_string), + (eel_string_list_new_from_string_list), + (eel_string_list_new_from_tokens), + (eel_string_list_assign_from_string_list), + (eel_string_list_insert), (eel_string_list_nth), + (eel_string_list_nth_as_integer), (eel_string_list_modify_nth), + (eel_string_list_remove_nth), (eel_string_list_contains), + (eel_string_list_find_by_function), (eel_string_list_get_length), + (eel_string_list_clear), (eel_string_list_equals), + (eel_string_list_as_g_slist), + (eel_string_list_get_index_for_string), + (eel_string_list_as_concatenated_string), (eel_string_list_sort), + (eel_string_list_sort_by_function), + (eel_string_list_remove_duplicates), (eel_string_list_for_each), + (eel_string_list_get_longest_string), + (eel_string_list_get_longest_string_length), (str_is_equal), + (eel_self_check_string_list): + Change implementation of string list to use a GSList instead of a + GList. A few changes to match the caja style more. + +2001-04-16 Ramiro Estrugo + + * eel/Makefile.am: + Use RSVG_CFLAGS not RSVG_LIBS. + + * eel/eel-self-checks.c: (eel_check_string_list_result): + * eel/eel-self-checks.h: + Add support for EelStringList checks. + + * eel/eel-string-list.h: + * eel/eel-string-list.c: (eel_string_list_is_case_sensitive): + New function that returns whether the string list is case + sensitive or not. + +2001-04-16 Ramiro Estrugo + + * eel/Makefile.am: Make the self checks header private and dont + install it. Remove some unused include flags and a debug printf. + + * eel/eel.h: Dont include the self checks header since its now + private. + + * test/Makefile.am: Remove some unused include flags. + +2001-04-16 Maciej Stachowiak + + * eel/Makefile.am: Fix `make distcheck'. + +2001-04-16 Darin Adler + + * eel/Makefile.am: Remove stray reference to eel-boxed.defs + that was making the Tinderbox unhappy. + +2001-04-16 Maciej Stachowiak + + * configure.in, eel/.cvsignore, eel/Makefile.am, eel/eel-types.c, + eel/eel-types.h, eel/eel.h, eel/makeenums.pl, eel/maketypes.awk: + Automatically generate GtkTypes for the various enumerations in + eel like gtk+ and mate do. This is needed for language bindings. + +2001-04-13 Pavel Cisler + + * eel/eel-list.c: (get_cell_text), + (eel_list_get_cell_hit_rectangle), (eel_list_item_hit), + (eel_list_button_press), (eel_list_button_release): + Add proper hit testing to the list view -- items now only get hit when + you click on text or an icon, clicking in empty space deselects. + + * eel/eel-list.c:(eel_list_setup_style_colors): + Tweak divider line colors to match Arlo's original spec. + + * eel/eel-list.c: (draw_cell), + (eel_list_get_initial_drag_offset): + Some small tweaks. + +2001-04-13 Ramiro Estrugo + + * eel/eel-gdk-font-extensions.c: (eel_gdk_font_get_fixed): + Dont use the translated font anymore, thats the old broken way. + Try to load just a font (not a fontset) if the first try fails. + +2001-04-12 Ramiro Estrugo + + * eel/check-program.c: (main): + * eel/eel-glib-extensions.c: (eel_g_hash_table_new_free_at_exit): + Use CAJA_DEBUG, not EEL_DEBUG for now. + + * eel/eel-font-manager.c: (ensure_local_font_table): + Use ~/.caja instead of ~/.eel for compatibility. + +2001-04-09 Pavel Cisler + + reviewed by: Mike Engber + + * eel/eel-ellipsizing-label.c: (recompute_ellipsized_text): + * eel/eel-gdk-font-extensions.c: (eel_string_ellipsize), + (eel_self_check_ellipsize): + * eel/eel-gdk-font-extensions.h: + Tweak the API of the ellipsizing functions to make it a little + more convenient to use. + +2001-04-09 John Sullivan + + reviewed by: Pavel Cisler + + * eel/eel-list-column-title.h: + * eel/eel-list-column-title.c: + (eel_list_column_title_queue_draw): New public function. + + * eel/eel-list.h: + * eel/eel-list.c: + (eel_list_set_sort_column), (eel_list_set_sort_type): New + functions that call eel_clist versions and also make the + column titles redraw. + +2001-04-08 Ramiro Estrugo + + * eel/eel-enumeration.h: + * eel/eel-enumeration.c: (eel_enumeration_new), + (eel_enumeration_copy), (eel_enumeration_free), + (eel_enumeration_insert), (eel_enumeration_get_id), + (eel_enumeration_get_nth_name), + (eel_enumeration_get_nth_description), + (eel_enumeration_get_nth_value), (eel_enumeration_get_length), + (eel_enumeration_new_from_tokens), + (eel_enumeration_get_name_position), + (eel_enumeration_get_description_position), + (eel_enumeration_get_value_position), (eel_enumeration_get_names), + (eel_enumeration_insert_entries), + (enumeration_table_free_one_node), (enumeration_table_free), + (enumeration_table_get), (enumeration_table_lookup), + (enumeration_register), (eel_enumeration_register), + (eel_enumeration_lookup), (eel_enumeration_id_get_nth_name), + (eel_enumeration_id_get_nth_description), + (eel_enumeration_id_get_nth_value), + (eel_enumeration_id_get_length), + (eel_enumeration_id_get_name_position), + (eel_enumeration_id_get_description_position), + (eel_enumeration_id_get_value_position), + (eel_self_check_enumeration): + Add a way to register and query a global preference table using + string ids. Makes it easier to deal with enumerations. Perhaps + we can even lost the non id based functions. + +2001-04-05 Andy Hertzfeld + + * eel/eel-gtk-extensions.c: (eel_gtk_marshal_POINTER__POINTER_INT): + * eel/eel-gtk-extensions.h: + added marshalling function needed for my post-1_0 branch + +2001-04-05 Pavel Cisler + + reviewed by: John Harper + + Code needed to support nice list view column resizing. + + * eel/eel-gtk-extensions.c: + (eel_gtk_marshal_POINTER__INT_INT_POINTER_POINTER): + * eel/eel-gtk-extensions.h: + Add a marshalling function. + + * eel/eel-list.c: (eel_list_initialize_class), (get_cell_text), + (draw_cell): + * eel/eel-list.h: + Use a signal to get the cell text, formatted for the right width. + +2001-04-05 Pavel Cisler + + * eel/Makefile.am: + More fixes to not pick up libraries from /usr/lib first. + Checking in for Ramiro. + +2001-04-05 Ramiro Estrugo + + * eel/Makefile.am: + Put freettype and png libs at end of link line to prevent /usr/lib conflict. + +2001-04-05 Ramiro Estrugo + + * eel/eel-dnd.h: + * eel/eel-dnd.c: (eel_drag_init), (eel_drag_selection_item_new), + (drag_selection_item_destroy), (eel_drag_build_selection_list), + (eel_drag_items_local), (eel_drag_items_in_trash), + (eel_drag_default_drop_action_for_icons): + Make some constant private as they were not used anywhere else. + Make sure all public structures have an Eel namespace. + + * eel/eel-clist.c: + * eel/eel-clist.h: + * eel/eel-list.c: + * eel/eel-list.h: + Indentation. + + * Makefile.am: + * eel/eel-string-map.h: + * eel/eel-string-map.c: + * eel/eel-lib-self-check-functions.h: + Retire unused code. + + * eel/eel-vfs-extensions.h: + * eel/eel-vfs-extensions.c: + Fix the authors blurb. + +2001-04-04 Ramiro Estrugo + + * eel/Makefile.am: + * eel/eel-clist.c: + * eel/eel-clist.h: + * eel/eel-ctree.c: + * eel/eel-ctree.h: + * eel/eel-dnd.c: + * eel/eel-dnd.h: + * eel/eel-list-column-title.c: + * eel/eel-list-column-title.h: + * eel/eel-list.c: + * eel/eel-list.h: + Move clist, ctree, and list widgets over from Caja. + +2001-04-04 Ramiro Estrugo + + * eel.spec.in: + Fix a dumb mistake in how the date was specified. + +2001-04-04 Ramiro Estrugo + + * eel/Makefile.am: + * eel/eel-lib-self-check-functions.h: + * eel/eel-vfs-extensions.h: + * eel/eel-vfs-extensions.c: (eel_read_entire_file), + (read_file_close_callback), (read_file_close), + (read_file_succeeded), (read_file_failed), + (read_file_read_callback), (read_file_read_chunk), + (read_file_open_callback), + (pthread_eel_read_file_callback_idle_binder), + (pthread_eel_read_file_callback_common), + (pthread_eel_read_file_synchronous_callback), + (pthread_eel_read_file_asynchronous_callback), + (pthread_eel_read_file_thread_entry), + (pthread_eel_read_file_async), + (pthread_eel_read_file_async_cancel), (eel_read_file_async), + (eel_read_entire_file_async), (eel_read_file_cancel), + (eel_uri_is_trash), (eel_uri_is_trash_folder), + (eel_uri_is_in_trash), (eel_format_uri_for_display), + (is_valid_scheme_character), (has_valid_scheme), + (eel_make_uri_from_input), (file_uri_from_local_relative_path), + (eel_make_uri_from_shell_arg), (eel_uri_get_basename), + (eel_uri_get_scheme), (is_uri_partial), + (remove_internal_relative_components), + (eel_uri_make_full_from_relative), (eel_uri_is_local_scheme), + (eel_handle_trailing_slashes), (eel_make_uri_canonical), + (eel_make_uri_canonical_strip_fragment), (uris_match), + (eel_uris_match), (eel_uris_match_ignore_fragments), + (eel_is_remote_uri), (eel_make_directory_and_parents), + (eel_copy_uri_simple), (eel_self_check_vfs_extensions): + Move mate-vfs extensions over from + caja/caja-file-utilities.[ch] + +2001-04-04 Ramiro Estrugo + + * HACKING: + * README: + * RENAMING: + * THANKS: + Updated to be Eel specific. Removed crufy leftover from Caja + move. + + * configure.in: + * eel.spec.in: + Remove unused popt and imlib depenencies. + +2001-04-04 Ramiro Estrugo + + * eel/check-program.c: (main): + Cleanup a lot of leftover cruft. + + * eel/eel-art-extensions.h: + * eel/eel-art-gtk-extensions.h: + * eel/eel-background-canvas-group.c: + * eel/eel-background.c: + * eel/eel-background.h: + * eel/eel-caption-table.c: + * eel/eel-caption-table.h: + * eel/eel-caption.c: + * eel/eel-caption.h: + * eel/eel-clickable-image.c: + * eel/eel-clickable-image.h: + * eel/eel-debug-drawing.c: + * eel/eel-debug-drawing.h: + * eel/eel-debug.h: + * eel/eel-ellipsizing-label.c: + * eel/eel-ellipsizing-label.h: + * eel/eel-enumeration.h: + * eel/eel-font-manager.c: + * eel/eel-font-manager.h: + * eel/eel-font-picker.c: + * eel/eel-font-picker.h: + * eel/eel-gdk-extensions.h: + * eel/eel-gdk-font-extensions.c: + * eel/eel-gdk-font-extensions.h: + * eel/eel-gdk-pixbuf-extensions.c: + * eel/eel-gdk-pixbuf-extensions.h: + * eel/eel-glib-extensions.h: + * eel/eel-glyph.c: + * eel/eel-glyph.h: + * eel/eel-mate-extensions.h: + * eel/eel-graphic-effects.h: + * eel/eel-gtk-extensions.h: + * eel/eel-image-table.c: + * eel/eel-image-table.h: + * eel/eel-image.c: + * eel/eel-image.h: + * eel/eel-label.c: + * eel/eel-label.h: + * eel/eel-labeled-image.c: + * eel/eel-labeled-image.h: + * eel/eel-password-dialog.c: + * eel/eel-password-dialog.h: + * eel/eel-radio-button-group.c: + * eel/eel-radio-button-group.h: + * eel/eel-region.h: + * eel/eel-scalable-font.c: + * eel/eel-scalable-font.h: + * eel/eel-self-checks.h: + * eel/eel-smooth-text-layout-cache.c: + * eel/eel-smooth-text-layout-cache.h: + * eel/eel-smooth-text-layout.c: + * eel/eel-smooth-text-layout.h: + * eel/eel-smooth-widget.c: + * eel/eel-smooth-widget.h: + * eel/eel-stock-dialogs.h: + * eel/eel-string-list.c: + * eel/eel-string-list.h: + * eel/eel-string-map.c: + * eel/eel-string-map.h: + * eel/eel-string-picker.c: + * eel/eel-string-picker.h: + * eel/eel-string.h: + * eel/eel-text-caption.c: + * eel/eel-text-caption.h: + * eel/eel-viewport.c: + * eel/eel-viewport.h: + * eel/eel-wrap-table.c: + * eel/eel-wrap-table.h: + * eel/eel-xml-extensions.h: + Many style and indention changes. + +2001-04-03 Darin Adler + + reviewed by: Ramiro + + * eel/Makefile.am: Make a eel-background-canvas-group.h + private. Remove duplicate FREETYPE2_LIBS. + * eel/eel-glib-extensions.h: Get rid of EEL_MACRO_BEGIN and + EEL_MACRO_END (too close to G_STMT_START/END). + +2001-04-03 Ramiro Estrugo + + * eel/eel-ellipsizing-label.c: (recompute_ellipsized_text): + Synchronize with Caja (for the last time hopefully). + +2001-04-02 Ramiro Estrugo + + * test/test-eel-label.c: + * test/test.h: + Remove rogue unused #includes. + +2001-04-02 Ramiro Estrugo + + * configure.in: + Stuff that goes in eelConf.sh was missing. + +2001-04-02 Ramiro Estrugo + + * eel-config.in: + * eelConf.sh.in: + Eelify. + +2001-04-02 Ramiro Estrugo + + * eel/check-eel: + Run checks with --sm-disable so that the session manager will not + hang and show dialogs. + +2001-04-02 Ramiro Estrugo + + * eel/eel-background-canvas-group.c: + (eel_background_canvas_group_initialize_common): + * eel/eel-font-manager.c: (eel_font_manager_get_default_font): + * eel/eel-gdk-font-extensions.c: + * eel/eel-stock-dialogs.c: + (timed_wait_delayed_close_timeout_callback), (timed_wait_free): + * eel/eel-text-caption.c: + Synchronize with Caja. + +2001-04-02 Ramiro Estrugo + + * acconfig.h: + * configure.in: + * eel.spec.in: + * eel/Makefile.am: + * eel/eel-art-extensions.h: + * eel/eel-art-gtk-extensions.h: + * eel/eel-background-canvas-group.c: + (eel_background_canvas_group_initialize_common): + * eel/eel-background.c: (eel_background_destroy): + * eel/eel-background.h: + * eel/eel-caption-table.h: + * eel/eel-caption.c: (eel_caption_set_child), + (eel_caption_set_extra_spacing): + * eel/eel-caption.h: + * eel/eel-clickable-image.h: + * eel/eel-debug-drawing.c: (eel_debug_show_pixbuf_in_eog): + * eel/eel-debug-drawing.h: + * eel/eel-debug.h: + * eel/eel-ellipsizing-label.h: + * eel/eel-entry.c: (emacs_shortcuts_preference_changed_callback), + (eel_entry_initialize), (eel_entry_destroy): + * eel/eel-entry.h: + * eel/eel-enumeration.c: (eel_enumeration_new_from_tokens), + (eel_enumeration_get_entry_position), + (eel_enumeration_get_value_position), + (eel_enumeration_get_entries), (eel_self_check_enumeration): + * eel/eel-enumeration.h: + * eel/eel-file-utilities.h: + * eel/eel-font-factory.c: + (eel_font_factory_get_font_from_preferences): + * eel/eel-font-factory.h: + * eel/eel-font-manager.c: (font_description_table_add), + (font_description_table_new), (directory_contains_file), + (ensure_local_font_table), (eel_font_manager_get_default_font), + (eel_font_manager_get_default_bold_font), + (eel_self_check_font_manager): + * eel/eel-font-manager.h: + * eel/eel-font-picker.h: + * eel/eel-gdk-extensions.h: + * eel/eel-gdk-font-extensions.c: (eel_string_ellipsize_start), + (eel_string_ellipsize_end), (eel_string_ellipsize_middle), + (eel_self_check_ellipsize), (eel_self_check_ellipsize_start), + (eel_self_check_ellipsize_middle), (eel_self_check_ellipsize_end), + (eel_self_check_gdk_font_extensions): + * eel/eel-gdk-font-extensions.h: + * eel/eel-gdk-pixbuf-extensions.h: + * eel/eel-glib-extensions.h: + * eel/eel-glyph.h: + * eel/eel-mate-extensions.h: + * eel/eel-graphic-effects.h: + * eel/eel-gtk-extensions.h: + * eel/eel-image-table.h: + * eel/eel-image.h: + * eel/eel-label.c: (eel_label_set_text): + * eel/eel-label.h: + * eel/eel-labeled-image.h: + * eel/eel-lib-self-check-functions.h: + * eel/eel-password-dialog.h: + * eel/eel-radio-button-group.h: + * eel/eel-region.h: + * eel/eel-scalable-font.h: + * eel/eel-self-checks.h: + * eel/eel-smooth-text-layout-cache.h: + * eel/eel-smooth-text-layout.h: + * eel/eel-smooth-widget.c: + (eel_smooth_widget_global_set_is_smooth), + (eel_smooth_widget_register): + * eel/eel-smooth-widget.h: + * eel/eel-stock-dialogs.h: + * eel/eel-string-list.h: + * eel/eel-string-map.h: + * eel/eel-string-picker.h: + * eel/eel-string.h: + * eel/eel-text-caption.h: + * eel/eel-viewport.h: + * eel/eel-wrap-table.h: + * eel/eel-xml-extensions.h: + * test/Makefile.am: + * test/test.c: (eel_pixmap_file): + * test/test.h: + Synchronize with caja. + +2001-03-28 Ramiro Estrugo + + * eel.spec.in: + First pass at making the spec file valid. + +2001-03-28 Ramiro Estrugo + + * Makefile.am: + * acconfig.h: + * configure.in: + Remove more Caja cruft. Make distcheck now passes. + +2001-03-28 Ramiro Estrugo + + Change 'caja' namespace to 'eel' everywhere. + + * eel/Makefile.am: + * eel/check-program.c: (main): + * eel/eel-art-extensions.c: (eel_art_irect_contains_irect), + (eel_art_irect_contains_point), (eel_art_irect_hits_irect), + (eel_art_irect_equal), (eel_art_drect_equal), + (eel_art_irect_is_valid), (eel_art_irect_assign), + (eel_art_irect_get_width), (eel_art_irect_get_height), + (eel_art_irect_align), (eel_dimensions_empty), + (eel_art_irect_assign_dimensions), (eel_art_irect_offset_by), + (eel_art_irect_offset_to), (eel_art_irect_scale_by), + (eel_art_irect_inset), (eel_art_drect_offset_by), + (eel_art_drect_offset_to), (eel_art_irect_offset_by_point), + (eel_art_irect_offset_to_point), (eel_art_drect_scale_by), + (eel_art_drect_inset), (eel_self_check_art_extensions): + * eel/eel-art-extensions.h: + * eel/eel-art-gtk-extensions.c: (eel_gdk_rectangle_to_art_irect), + (eel_screen_get_dimensions), (eel_gdk_window_get_bounds), + (eel_gdk_window_get_screen_relative_bounds), + (eel_gtk_widget_get_bounds), (eel_gtk_widget_get_dimensions), + (eel_gtk_widget_get_preferred_dimensions), + (eel_gdk_window_clip_dirty_area_to_screen), + (eel_art_irect_to_gdk_rectangle), (eel_gdk_window_get_dimensions): + * eel/eel-art-gtk-extensions.h: + * eel/eel-background-canvas-group.c: + (eel_background_canvas_group_initialize_class), + (eel_background_canvas_group_initialize_common), + (eel_background_canvas_group_initialize), + (eel_background_canvas_group_supplant_root_class), + (eel_background_canvas_group_update), + (eel_background_canvas_group_draw), + (eel_background_canvas_group_render): + * eel/eel-background-canvas-group.h: + * eel/eel-background.c: (eel_background_initialize_class), + (eel_background_initialize), (eel_background_remove_current_image), + (eel_background_destroy), (eel_background_get_combine_mode), + (eel_background_set_combine_mode), + (eel_background_get_image_placement), + (eel_background_set_image_placement_no_emit), + (eel_background_set_image_placement), (eel_background_new), + (reset_cached_color_info), + (eel_background_ensure_gradient_buffered), + (fill_canvas_from_gradient_buffer), + (eel_background_image_totally_obscures), + (eel_background_ensure_image_scaled), (eel_background_pre_draw), + (eel_background_draw), (eel_background_draw_to_drawable), + (eel_background_draw_to_pixbuf), (draw_pixbuf_tiled_aa), + (eel_background_draw_aa), (eel_background_draw_to_canvas), + (eel_background_get_color), (eel_background_get_image_uri), + (eel_background_set_color_no_emit), (eel_background_set_color), + (eel_background_load_image_callback), + (eel_background_is_image_load_in_progress), + (eel_background_cancel_loading_image), + (eel_background_start_loading_image), + (eel_background_set_image_uri_helper), + (eel_background_set_image_uri), + (set_image_and_color_image_loading_done_callback), + (eel_background_set_image_uri_and_color), + (eel_background_receive_dropped_background_image), + (eel_gtk_style_get_default_class), (eel_gdk_window_update_sizes), + (eel_background_draw_flat_box), + (eel_background_get_gtk_style_class), + (eel_background_set_widget_style), (eel_background_is_set), + (eel_background_is_loaded), (eel_background_reset), + (eel_background_set_up_canvas), (eel_widget_background_changed), + (eel_get_widget_background), (eel_widget_has_attached_background), + (eel_gtk_widget_find_background_ancestor), + (eel_background_is_too_complex_for_gtk_style), + (eel_background_is_dark), (eel_background_receive_dropped_color), + (eel_self_check_background): + * eel/eel-background.h: + * eel/eel-caption-table.c: (eel_caption_table_initialize_class), + (eel_caption_table_initialize), (caption_table_destroy), + (eel_caption_table_resize), (caption_table_index_of_entry), + (caption_table_find_next_sensitive_entry), (entry_activate), + (eel_caption_table_new), (eel_caption_table_set_row_info), + (eel_caption_table_set_entry_text), + (eel_caption_table_set_entry_readonly), + (eel_caption_table_entry_grab_focus), + (eel_caption_table_get_entry_text), + (eel_caption_table_get_num_rows): + * eel/eel-caption-table.h: + * eel/eel-caption.c: (eel_caption_initialize_class), + (eel_caption_initialize), (eel_caption_destroy), + (eel_font_picker_show_all), (update_title), (eel_caption_new), + (eel_caption_set_title_label), (eel_caption_set_show_title), + (eel_caption_get_title_label), (eel_caption_get_title_label_width), + (eel_caption_set_child), (eel_caption_set_spacing): + * eel/eel-caption.h: + * eel/eel-clickable-image.c: + (eel_clickable_image_initialize_class), + (eel_clickable_image_initialize), (eel_clickable_image_destroy), + (eel_clickable_image_get_arg), (eel_clickable_image_realize), + (label_enter), (label_leave), (label_handle_motion), + (label_handle_button_press), (label_handle_button_release), + (ancestor_enter_notify_event), (ancestor_leave_notify_event), + (ancestor_motion_notify_event), (ancestor_button_press_event), + (ancestor_button_release_event), + (eel_clickable_image_expose_event), + (eel_clickable_image_set_up_pixbufs), (eel_clickable_image_new), + (eel_clickable_image_new_from_file_name), + (eel_clickable_image_new_solid), + (eel_clickable_image_set_prelight): + * eel/eel-clickable-image.h: + * eel/eel-debug-drawing.c: (debug_pixbuf_viewer_destroy), + (debug_pixbuf_viewer_size_request), + (debug_pixbuf_viewer_expose_event), + (debug_pixbuf_viewer_set_pixbuf), + (eel_debug_draw_rectangle_and_cross), + (eel_debug_show_pixbuf_in_eog), (eel_debug_show_pixbuf), + (eel_debug_pixbuf_draw_point), (eel_debug_pixbuf_draw_rectangle), + (eel_debug_pixbuf_draw_rectangle_inset): + * eel/eel-debug-drawing.h: + * eel/eel-debug.c: (eel_stop_in_debugger), + (eel_stop_after_default_log_handler), + (eel_set_stop_after_default_log_handler), + (eel_make_warnings_and_criticals_stop_in_debugger), + (eel_get_available_file_descriptor_count), + (eel_str_equal_with_free): + * eel/eel-debug.h: + * eel/eel-ellipsizing-label.c: + (eel_ellipsizing_label_initialize_class), + (eel_ellipsizing_label_initialize), (real_destroy), + (eel_ellipsizing_label_new), (recompute_ellipsized_text), + (eel_ellipsizing_label_set_text), (real_size_request), + (real_size_allocate), (real_style_set): + * eel/eel-ellipsizing-label.h: + * eel/eel-entry.c: (eel_entry_initialize), (eel_entry_new), + (eel_entry_new_with_max_length), (eel_entry_destroy), + (obscure_cursor), (eel_entry_key_press), (eel_entry_motion_notify), + (eel_entry_select_all), (select_all_at_idle), + (eel_entry_select_all_at_idle), (eel_entry_set_text), + (eel_entry_set_selection), (eel_entry_button_press), + (eel_entry_button_release), (eel_entry_insert_text), + (eel_entry_delete_text), (eel_entry_selection_clear), + (eel_entry_initialize_class): + * eel/eel-entry.h: + * eel/eel-enumeration.c: (eel_enumeration_new), + (eel_enumeration_free), (eel_enumeration_insert), + (eel_enumeration_get_nth_entry), + (eel_enumeration_get_nth_description), + (eel_enumeration_get_nth_value), (eel_enumeration_get_num_entries), + (eel_self_check_enumeration): + * eel/eel-enumeration.h: + * eel/eel-file-utilities.c: (eel_format_uri_for_display), + (eel_make_uri_from_input), (file_uri_from_local_relative_path), + (eel_make_uri_from_shell_arg), (eel_uri_get_basename), + (eel_uri_get_scheme), (eel_uri_make_full_from_relative), + (eel_uri_is_trash), (eel_uri_is_trash_folder), + (eel_uri_is_in_trash), (eel_uri_is_local_scheme), + (eel_handle_trailing_slashes), (eel_make_uri_canonical), + (eel_make_uri_canonical_strip_fragment), (uris_match), + (eel_uris_match), (eel_uris_match_ignore_fragments), + (eel_file_name_matches_hidden_pattern), + (eel_file_name_matches_backup_pattern), (eel_make_path), + (eel_get_user_directory), (eel_get_desktop_directory), + (eel_user_main_directory_exists), (eel_get_pixmap_directory), + (eel_is_remote_uri), (eel_pixmap_file), (eel_read_entire_file), + (read_file_close), (read_file_succeeded), (read_file_failed), + (read_file_read_callback), (read_file_read_chunk), + (read_file_open_callback), + (pthread_eel_read_file_callback_idle_binder), + (pthread_eel_read_file_callback_common), + (pthread_eel_read_file_synchronous_callback), + (pthread_eel_read_file_asynchronous_callback), + (pthread_eel_read_file_thread_entry), + (pthread_eel_read_file_async), + (pthread_eel_read_file_async_cancel), (eel_read_file_async), + (eel_read_entire_file_async), (eel_read_file_cancel), + (eel_make_directory_and_parents), (eel_copy_uri_simple), + (eel_unique_temporary_file_name), (eel_get_build_time_stamp), + (eel_get_build_message), (eel_self_check_file_utilities): + * eel/eel-file-utilities.h: + * eel/eel-font-factory.c: (eel_get_current_font_factory), + (eel_font_factory_get), (eel_font_factory_initialize), + (eel_font_factory_initialize_class), (destroy), + (font_hash_node_lookup), (font_hash_node_lookup_with_insertion), + (eel_font_factory_get_font_by_family), + (eel_font_factory_get_font_from_preferences): + * eel/eel-font-factory.h: + * eel/eel-font-manager.c: (font_description_new), + (font_description_table_add), (font_get_font_type), + (font_description_table_find), (font_description_table_for_each), + (font_description_table_new), (directory_contains_file), + (font_directory_is_ignored), (font_foundry_is_ignored), + (font_family_is_ignored), (font_manager_collect_font_tables), + (ensure_local_font_table), (eel_font_manager_for_each_font), + (eel_font_manager_get_default_font), + (eel_font_manager_get_default_bold_font), + (eel_font_manager_file_is_scalable_font), + (font_list_find_bold_callback), (eel_font_manager_get_bold), + (eel_font_manager_weight_is_bold), (get_test_font_dir), + (eel_self_check_font_manager): + * eel/eel-font-manager.h: + * eel/eel-font-picker.c: (eel_font_picker_initialize_class), + (option_menu_button_press_event), (menu_deactivate), + (eel_font_picker_initialize), (eel_font_picker_destroy), + (font_list_find), (style_menu_item_activate_callback), + (style_menu_item_button_release_event), (font_picker_add_item), + (font_picker_populate), (font_find_style), (font_make_style_name), + (font_slant_string_to_enum), (font_set_width_string_to_enum), + (font_style_entry_new), (font_list_count_families), + (compare_font_entry), (global_font_list_get), (compare_style), + (global_font_list_populate_callback), + (eel_gtk_menu_shell_get_num_items), + (font_picker_get_selected_style_entry), + (font_picker_find_entries_for_font), + (font_picker_get_index_for_entry), (eel_font_picker_new), + (eel_font_picker_get_selected_font), + (eel_font_picker_set_selected_font): + * eel/eel-font-picker.h: + * eel/eel-gdk-extensions.c: (eel_fill_rectangle), + (eel_fill_rectangle_with_color), (eel_rectangle_contains), + (eel_rectangle_inset), (eel_interpolate_color), (eel_gradient_new), + (eel_gradient_is_gradient), (eel_gradient_is_horizontal), + (eel_gradient_strip_trailing_direction_if_any), + (eel_gradient_parse_one_color_spec), + (eel_gradient_get_start_color_spec), + (eel_gradient_get_end_color_spec), (eel_gradient_set_edge_color), + (eel_gradient_set_left_color_spec), + (eel_gradient_set_top_color_spec), + (eel_gradient_set_right_color_spec), + (eel_gradient_set_bottom_color_spec), + (eel_gdk_color_parse_with_white_default), + (eel_parse_rgb_with_white_default), (eel_rgb16_to_rgb), + (eel_rgb8_to_rgb), (eel_gdk_color_to_rgb), (eel_gdk_rgb_to_color), + (eel_gdk_rgb_to_color_spec), (eel_shift_color_component), + (eel_rgb_shift_color), (eel_gdk_color_is_dark), + (eel_gdk_choose_foreground_color), + (eel_gdk_gc_choose_foreground_color), (eel_stipple_bitmap), + (eel_gdk_window_bring_to_front), (eel_gdk_window_focus), + (eel_gdk_window_set_wm_protocols), (eel_set_mini_icon), + (eel_gdk_window_set_wm_hints_input), + (eel_gdk_window_set_invisible_cursor), (eel_gdk_parse_geometry), + (eel_gdk_color_as_hex_string), (eel_self_check_parse), + (eel_self_check_gdk_extensions): + * eel/eel-gdk-extensions.h: + * eel/eel-gdk-font-extensions.c: (eel_gdk_font_get_italic), + (eel_gdk_font_get_bold), (font_bitmap_get_by_size), + (eel_gdk_font_get_larger), (eel_gdk_font_get_smaller), + (eel_gdk_font_equal), (eel_gdk_font_get_largest_fitting), + (eel_string_ellipsize_start), (font_get_bold), (font_list_fonts), + (font_list_table_free_one_node), (font_list_fonts_cached), + (eel_gdk_font_get_fixed), (xlfd_string_get_nth), + (xlfd_string_replace_nth), (xlfd_string_get_nth_as_int), + (xlfd_string_could_be_scalable_non_bitmap), + (eel_gdk_font_xlfd_string_new), (font_entry_has_bold_weight_test), + (font_entry_has_italic_slant_test), + (font_entry_is_scalable_non_bitmap_test), + (eel_self_check_ellipsize_start), + (eel_self_check_gdk_font_extensions): + * eel/eel-gdk-font-extensions.h: + * eel/eel-gdk-pixbuf-extensions.c: (eel_gdk_pixbuf_list_ref), + (eel_gdk_pixbuf_list_free), (eel_gdk_pixbuf_load), + (eel_gdk_pixbuf_load_async), (file_opened_callback), + (file_read_callback), (free_pixbuf_load_handle), (load_done), + (eel_cancel_gdk_pixbuf_load), (eel_gdk_pixbuf_average_value), + (eel_gdk_scale_to_fit_factor), (eel_gdk_pixbuf_scale_to_fit), + (eel_gdk_pixbuf_scale_down_to_fit), (eel_gdk_pixbuf_is_valid), + (eel_gdk_pixbuf_get_dimensions), + (eel_gdk_pixbuf_fill_rectangle_with_color), + (eel_gdk_pixbuf_save_to_file), (eel_gdk_pixbuf_ref_if_not_null), + (eel_gdk_pixbuf_unref_if_not_null), + (eel_gdk_pixbuf_draw_to_drawable), (eel_gdk_pixbuf_draw_to_pixbuf), + (eel_gdk_pixbuf_draw_to_pixbuf_alpha), + (eel_gdk_pixbuf_new_from_pixbuf_sub_area), + (eel_gdk_pixbuf_new_from_existing_buffer), (pixbuf_draw_tiled), + (draw_tile_to_pixbuf_callback), (draw_tile_to_drawable_callback), + (eel_gdk_pixbuf_draw_to_pixbuf_tiled), + (eel_gdk_pixbuf_draw_to_drawable_tiled), + (eel_gdk_pixbuf_get_global_buffer), + (eel_gdk_pixbuf_get_from_window_safe), (eel_gdk_pixbuf_intersect), + (eel_self_check_gdk_pixbuf_extensions): + * eel/eel-gdk-pixbuf-extensions.h: + * eel/eel-glib-extensions.c: (eel_setenv), (eel_unsetenv), + (eel_g_date_new_tm), (eel_strdup_strftime), + (eel_g_list_exactly_one_item), (eel_g_list_more_than_one_item), + (eel_g_list_equal), (eel_g_list_copy), (eel_g_str_list_equal), + (eel_g_str_list_copy), (eel_g_str_list_alphabetize), + (eel_g_list_free_deep_custom), (eel_g_list_free_deep), + (eel_g_slist_free_deep_custom), (eel_g_slist_free_deep), + (eel_g_strv_find), (eel_g_list_safe_for_each), + (eel_g_list_sort_merge), (eel_g_list_is_already_sorted), + (eel_g_list_sort_custom), + (eel_g_lists_sort_and_check_for_intersection), + (eel_g_list_partition), (eel_g_ptr_array_new_from_list), + (eel_g_ptr_array_sort), (eel_g_ptr_array_search), + (eel_get_system_time), (eel_g_hash_table_new_free_at_exit), + (eel_g_hash_table_safe_for_each), + (eel_g_hash_table_remove_deep_custom), + (eel_g_hash_table_remove_deep), + (eel_g_hash_table_destroy_deep_custom), + (eel_g_hash_table_destroy_deep), (eel_g_string_append_len), + (eel_shell_quote), (eel_round), (eel_g_list_from_g_slist), + (eel_g_slist_from_g_list), + (eel_dumb_down_for_multi_byte_locale_hack), (eel_compare_integer), + (check_tm_to_g_date), (eel_test_predicate), (test_strftime), + (eel_self_check_glib_extensions): + * eel/eel-glib-extensions.h: + * eel/eel-glyph.c: (eel_glyph_new), (eel_glyph_free), + (glyph_get_width_space_safe), (glyph_get_height_space_safe), + (eel_glyph_get_width), (eel_glyph_get_height), + (eel_glyph_get_dimensions), (eel_glyph_get_underline_rectangle), + (glyph_is_valid), (eel_glyph_draw_to_pixbuf), + (eel_glyph_intersect), (eel_glyph_compare): + * eel/eel-glyph.h: + * eel/eel-mate-extensions.c: + (eel_mate_canvas_world_to_window_rectangle), + (eel_mate_canvas_world_to_canvas_rectangle), + (eel_mate_canvas_item_get_current_canvas_bounds), + (eel_mate_canvas_item_request_redraw), + (eel_mate_canvas_request_redraw_rectangle), + (eel_mate_canvas_item_get_world_bounds), + (eel_mate_canvas_item_get_canvas_bounds), + (eel_mate_canvas_draw_pixbuf_helper), + (eel_mate_canvas_draw_pixbuf_helper_alpha), + (eel_mate_canvas_draw_pixbuf), (eel_mate_canvas_fill_rgb), + (eel_mate_dialog_get_button_by_index), + (eel_mate_canvas_item_request_update_deep), + (eel_mate_canvas_request_update_all), + (eel_mate_canvas_set_scroll_region), + (eel_mate_canvas_set_scroll_region_left_justify), + (eel_mate_canvas_set_scroll_region_include_visible_area), + (eel_mate_shell_execute), (eel_mate_get_terminal_path), + (eel_mate_open_terminal), (icon_selected_callback), + (eel_mate_icon_selector_new), + (eel_mate_stock_set_icon_or_register): + * eel/eel-mate-extensions.h: + * eel/eel-graphic-effects.c: (eel_create_spotlight_pixbuf), + (eel_create_darkened_pixbuf), (eel_create_colorized_pixbuf), + (eel_stretch_frame_image), (eel_embed_image_in_frame), + (eel_make_semi_transparent): + * eel/eel-graphic-effects.h: + * eel/eel-gtk-extensions.c: (finish_button_activation), + (eel_gtk_button_auto_click), (eel_gtk_button_set_padding), + (eel_gtk_button_set_standard_padding), + (eel_gtk_clist_get_first_selected_row), + (eel_gtk_clist_get_last_selected_row), + (activate_button_on_double_click), + (eel_gtk_clist_set_double_click_button), + (eel_gtk_signal_connect_free_data_custom), + (eel_gtk_signal_connect_free_data), (eel_gtk_window_present), + (handle_standard_close_accelerator), + (eel_gtk_window_event_is_close_accelerator), + (eel_gtk_window_set_up_close_accelerator), + (eel_gtk_window_set_initial_geometry), + (eel_gtk_window_set_initial_geometry_from_string), + (eel_gtk_selection_data_copy_deep), + (eel_gtk_selection_data_free_deep), (eel_popup_menu_position_func), + (eel_truncate_text_for_menu_item), (eel_pop_up_context_menu), + (eel_gtk_menu_append_separator), (eel_gtk_menu_insert_separator), + (eel_gtk_menu_set_item_visibility), + (eel_gtk_marshal_NONE__POINTER_INT_INT_DOUBLE), + (eel_gtk_marshal_NONE__INT_INT_INT), + (eel_gtk_marshal_NONE__POINTER_INT_INT_INT), + (eel_gtk_marshal_NONE__POINTER_INT_POINTER_POINTER), + (eel_gtk_marshal_NONE__POINTER_POINTER_INT_INT_INT), + (eel_gtk_marshal_BOOL__INT_POINTER_INT_INT_UINT), + (eel_gtk_marshal_NONE__INT_POINTER_INT_INT_UINT), + (eel_gtk_marshal_NONE__POINTER_POINTER_POINTER_INT_INT_INT), + (eel_gtk_marshal_NONE__POINTER_POINTER_POINTER_POINTER_INT_INT_UINT + ), (eel_gtk_marshal_NONE__POINTER_INT_INT_DOUBLE_DOUBLE), + (eel_gtk_marshal_NONE__DOUBLE), + (eel_gtk_marshal_NONE__DOUBLE_DOUBLE_DOUBLE), + (eel_gtk_marshal_POINTER__NONE), (eel_gtk_marshal_INT__NONE), + (eel_gtk_marshal_POINTER__INT), (eel_gtk_marshal_POINTER__POINTER), + (eel_gtk_marshal_INT__POINTER_POINTER), + (eel_gtk_marshal_INT__POINTER_INT), + (eel_gtk_marshal_POINTER__POINTER_POINTER), + (eel_gtk_marshal_POINTER__POINTER_POINTER_POINTER), + (eel_gtk_marshal_NONE__POINTER_POINTER_POINTER_POINTER), + (eel_gtk_marshal_POINTER__POINTER_INT_INT_POINTER_POINTER), + (eel_gtk_marshal_NONE__POINTER_POINTER_POINTER_POINTER_POINTER_POIN + TER), (eel_point_in_allocation), (eel_point_in_widget), + (eel_gtk_object_list_ref), (eel_gtk_object_list_unref), + (eel_gtk_object_list_free), (eel_gtk_object_list_copy), + (eel_gtk_style_set_font), (eel_gtk_widget_set_font), + (eel_gtk_widget_set_shown), (eel_gtk_widget_set_font_by_name), + (eel_gtk_signal_connect_full_while_alive), + (eel_gtk_signal_connect_while_realized), + (eel_nullify_when_destroyed), (eel_nullify_cancel), + (eel_gtk_container_get_first_child), + (eel_gtk_container_foreach_deep), (eel_gtk_pixmap_new_empty), + (eel_gtk_adjustment_set_value), (eel_gtk_adjustment_clamp_value), + (eel_gtk_label_make_bold), (eel_gtk_label_make_larger), + (eel_gtk_label_make_smaller), + (eel_gtk_widget_set_background_color), + (eel_gtk_widget_set_foreground_color), + (eel_gtk_widget_find_windowed_ancestor), (eel_gtk_style_shade), + (eel_gtk_class_name_make_like_existing_type), + (eel_get_window_list_ordered_front_to_back), + (eel_gtk_get_system_font), (eel_get_current_event_time), + (eel_drag_set_icon_pixbuf): + * eel/eel-gtk-extensions.h: + * eel/eel-gtk-macros.h: + * eel/eel-image-table.c: (eel_image_table_initialize_class), + (eel_image_table_initialize), (eel_image_table_destroy), + (eel_image_table_expose_event), (eel_image_table_realize), + (eel_image_table_unrealize), (eel_image_table_remove), + (eel_image_table_child_type), + (eel_image_table_set_is_smooth_signal), + (image_table_foreach_child_subtract_content), + (image_table_clear_dirty_areas), (image_table_peek_clear_gc), + (image_table_emit_signal), (image_table_handle_motion), + (ancestor_enter_notify_event), (ancestor_leave_notify_event), + (ancestor_motion_notify_event), (ancestor_button_press_event), + (ancestor_button_release_event), (eel_image_table_new), + (eel_image_table_set_is_smooth), + (eel_image_table_set_smooth_background_color), + (eel_image_table_add_empty_image): + * eel/eel-image-table.h: + * eel/eel-image-with-background.c: (draw_background_callback), + (eel_image_new_with_background): + * eel/eel-image-with-background.h: + * eel/eel-image.c: (eel_image_initialize_class), + (eel_image_initialize), (eel_image_destroy), (eel_image_set_arg), + (eel_image_get_arg), (eel_image_size_request), + (image_paint_pixbuf_callback), (image_composite_pixbuf_callback), + (eel_image_expose_event), (eel_image_set_is_smooth_signal), + (image_get_pixbuf_dimensions), (image_get_pixbuf_bounds), + (image_get_tile_dimensions), (image_is_smooth), (eel_image_new), + (eel_image_set_is_smooth), (eel_image_get_is_smooth), + (eel_image_set_tile_pixbuf), (eel_image_get_tile_pixbuf), + (eel_image_set_pixbuf), (eel_image_set_pixbuf_from_file_name), + (eel_image_get_pixbuf), (eel_image_set_pixbuf_opacity), + (eel_image_get_pixbuf_opacity), (eel_image_set_tile_opacity), + (eel_image_get_tile_opacity), (eel_image_set_tile_width), + (eel_image_get_tile_width), (eel_image_set_tile_height), + (eel_image_get_tile_height), (eel_image_set_tile_mode_vertical), + (eel_image_get_tile_mode_vertical), + (eel_image_set_tile_mode_horizontal), + (eel_image_get_tile_mode_horizontal), + (eel_image_set_tile_pixbuf_from_file_name), + (eel_image_set_background_mode), (eel_image_get_background_mode), + (eel_image_set_solid_background_color), + (eel_image_get_solid_background_color), (eel_image_new_solid), + (eel_image_set_never_smooth): + * eel/eel-image.h: + * eel/eel-label-with-background.c: (draw_background_callback), + (eel_label_new_with_background): + * eel/eel-label-with-background.h: + * eel/eel-label.c: (eel_label_initialize_class), + (eel_label_initialize), (eel_label_destroy), (eel_label_set_arg), + (eel_label_get_arg), (eel_label_size_request), + (eel_label_size_allocate), (label_paint_pixbuf_callback), + (label_composite_text_callback_cached), + (label_composite_text_callback), + (label_composite_text_and_shadow_callback), (label_paint), + (paint_label_smooth), (paint_label_smooth_cached), + (eel_label_expose_event), (eel_label_set_is_smooth_signal), + (label_get_default_line_wrap_width), (label_get_text_dimensions), + (label_get_text_bounds), (label_get_content_dimensions), + (label_get_content_bounds), (label_get_tile_dimensions), + (label_solid_cache_pixbuf_clear), (label_can_cache_contents), + (label_peek_text), (label_smooth_text_ensure), + (label_smooth_text_clear), (label_is_smooth), (eel_label_new), + (eel_label_set_smooth_font), (eel_label_get_smooth_font), + (eel_label_set_smooth_font_size), (eel_label_get_smooth_font_size), + (label_force_cached_requisition_flush), (eel_label_set_is_smooth), + (eel_label_get_is_smooth), (eel_label_set_tile_pixbuf), + (eel_label_get_tile_pixbuf), (eel_label_set_text_opacity), + (eel_label_get_text_opacity), (eel_label_set_tile_opacity), + (eel_label_get_tile_opacity), (eel_label_set_tile_width), + (eel_label_get_tile_width), (eel_label_set_tile_height), + (eel_label_get_tile_height), (eel_label_set_tile_mode_vertical), + (eel_label_get_tile_mode_vertical), + (eel_label_set_tile_mode_horizontal), + (eel_label_get_tile_mode_horizontal), + (eel_label_set_tile_pixbuf_from_file_name), + (eel_label_set_background_mode), (eel_label_get_background_mode), + (eel_label_set_solid_background_color), + (eel_label_get_solid_background_color), + (eel_label_set_smooth_line_wrap_width), + (eel_label_get_smooth_line_wrap_width), (eel_label_set_text_color), + (eel_label_get_text_color), + (eel_label_set_smooth_drop_shadow_offset), + (eel_label_get_smooth_drop_shadow_offset), + (eel_label_set_smooth_drop_shadow_color), + (eel_label_get_smooth_drop_shadow_color), (eel_label_set_justify), + (eel_label_get_text_justify), (eel_label_set_text), + (eel_label_get_text), (eel_label_set_wrap), (eel_label_get_wrap), + (eel_label_new_solid), (eel_label_make_bold), + (eel_label_make_larger), (eel_label_make_smaller), + (eel_label_set_never_smooth), + (eel_label_set_adjust_wrap_on_resize), + (eel_label_get_adjust_wrap_on_resize): + * eel/eel-label.h: + * eel/eel-labeled-image.c: (eel_labeled_image_initialize_class), + (eel_labeled_image_initialize), (eel_labeled_image_destroy), + (eel_labeled_image_set_arg), (eel_labeled_image_get_arg), + (eel_labeled_image_size_request), + (eel_labeled_image_size_allocate), + (eel_labeled_image_expose_event), (eel_labeled_image_map), + (eel_labeled_image_unmap), (eel_labeled_image_add), + (eel_labeled_image_remove), (eel_labeled_image_forall), + (is_fixed_height), (labeled_image_get_image_dimensions), + (labeled_image_get_label_dimensions), + (labeled_image_get_image_bounds_fill), + (eel_labeled_image_get_image_bounds), + (labeled_image_get_label_bounds_fill), + (eel_labeled_image_get_label_bounds), + (labeled_image_update_alignments), + (labeled_image_get_content_dimensions), + (labeled_image_get_content_bounds), (labeled_image_ensure_label), + (labeled_image_ensure_image), (labeled_image_show_image), + (labeled_image_show_label), (eel_labeled_image_new), + (eel_labeled_image_new_from_file_name), + (eel_labeled_image_set_label_position), + (eel_labeled_image_get_label_position), + (eel_labeled_image_set_show_label), + (eel_labeled_image_get_show_label), + (eel_labeled_image_set_show_image), + (eel_labeled_image_get_show_image), + (eel_labeled_image_set_fixed_image_height), + (eel_labeled_image_set_spacing), (eel_labeled_image_get_spacing), + (eel_labeled_image_set_x_padding), + (eel_labeled_image_get_x_padding), + (eel_labeled_image_set_y_padding), + (eel_labeled_image_get_y_padding), + (eel_labeled_image_set_x_alignment), + (eel_labeled_image_get_x_alignment), + (eel_labeled_image_set_y_alignment), + (eel_labeled_image_get_y_alignment), (eel_labeled_image_set_fill), + (eel_labeled_image_get_fill), (eel_labeled_image_button_new), + (eel_labeled_image_button_new_from_file_name), + (eel_labeled_image_toggle_button_new), + (eel_labeled_image_toggle_button_new_from_file_name), + (button_leave_callback), (eel_labeled_image_check_button_new), + (eel_labeled_image_check_button_new_from_file_name), + (eel_labeled_image_set_pixbuf), + (eel_labeled_image_set_pixbuf_from_file_name), + (eel_labeled_image_set_tile_pixbuf), + (eel_labeled_image_set_tile_pixbuf_from_file_name), + (eel_labeled_image_get_pixbuf), (eel_labeled_image_set_text), + (eel_labeled_image_get_text), (eel_labeled_image_make_bold), + (eel_labeled_image_make_larger), (eel_labeled_image_make_smaller), + (eel_labeled_image_set_tile_width), + (eel_labeled_image_set_tile_height), + (eel_labeled_image_set_background_mode), + (eel_labeled_image_set_solid_background_color), + (eel_labeled_image_set_smooth_drop_shadow_offset), + (eel_labeled_image_set_smooth_drop_shadow_color), + (eel_labeled_image_set_text_color), + (eel_labeled_image_set_label_never_smooth): + * eel/eel-labeled-image.h: + * eel/eel-lib-self-check-functions.c: (eel_run_lib_self_checks): + * eel/eel-lib-self-check-functions.h: + * eel/eel-password-dialog.c: + (eel_password_dialog_initialize_class), + (eel_password_dialog_initialize), (eel_password_dialog_destroy), + (dialog_show_callback), (dialog_close_callback), + (caption_table_activate_callback), (eel_password_dialog_new), + (eel_password_dialog_run_and_block), + (eel_password_dialog_set_username), + (eel_password_dialog_set_password), + (eel_password_dialog_set_readonly_username), + (eel_password_dialog_get_username), + (eel_password_dialog_get_password), + (eel_password_dialog_get_remember), + (eel_password_dialog_set_remember), + (eel_password_dialog_set_remember_label_text): + * eel/eel-password-dialog.h: + * eel/eel-radio-button-group.c: + (eel_radio_button_group_initialize_class), + (eel_radio_button_group_initialize), + (eel_radio_button_group_destroy), + (radio_button_group_emit_changed_signal), + (radio_button_group_free_button_group), (button_toggled), + (eel_radio_button_group_new), (eel_radio_button_group_insert), + (eel_radio_button_group_get_active_index), + (eel_radio_button_group_set_active_index), + (eel_radio_button_group_set_entry_pixbuf), + (eel_radio_button_group_set_entry_description_text): + * eel/eel-radio-button-group.h: + * eel/eel-region.c: (eel_region_new), (eel_region_free), + (gdk_region_new_from_irect), (eel_region_add_rectangle), + (eel_region_subtract_rectangle), (eel_region_set_gc_clip_region): + * eel/eel-region.h: + * eel/eel-scalable-font-private.h: + * eel/eel-scalable-font.c: (eel_scalable_font_initialize_class), + (eel_scalable_font_initialize), (eel_scalable_font_destroy), + (eel_scalable_font_new), (eel_scalable_font_make_bold), + (eel_scalable_font_measure_text), (eel_scalable_font_text_width), + (eel_scalable_font_draw_text), + (eel_scalable_font_largest_fitting_font_size), + (eel_scalable_font_get_default_font), + (eel_scalable_font_get_default_bold_font), + (eel_scalable_font_get_rsvg_handle), + (eel_scalable_font_get_rsvg_context), + (eel_self_check_scalable_font): + * eel/eel-scalable-font.h: + * eel/eel-self-checks.c: (eel_exit_if_self_checks_failed), + (eel_report_check_failure), (eel_strdup_boolean), + (eel_before_check), (eel_after_check), (eel_check_boolean_result), + (eel_check_rectangle_result), (eel_check_dimensions_result), + (eel_check_integer_result), (eel_check_string_result), + (eel_before_check_function), (eel_after_check_function): + * eel/eel-self-checks.h: + * eel/eel-smooth-text-layout-cache.c: (cache_index_new), + (cache_insert), (cache_remove), (cache_enter), (cache_evict), + (cache_lookup), (cache_trim), + (eel_smooth_text_layout_cache_render), + (eel_smooth_text_layout_cache_new), + (eel_smooth_text_layout_cache_initialize_class), + (eel_smooth_text_layout_cache_initialize), (free_one_cache_entry), + (eel_smooth_text_layout_cache_destroy), (check_one), + (eel_self_check_smooth_text_layout_cache): + * eel/eel-smooth-text-layout-cache.h: + * eel/eel-smooth-text-layout.c: + (eel_smooth_text_layout_initialize_class), + (eel_smooth_text_layout_initialize), + (eel_smooth_text_layout_destroy), (smooth_text_layout_clear_lines), + (smooth_text_layout_ensure_lines), + (smooth_text_layout_line_list_new), + (smooth_text_layout_line_list_free), + (smooth_text_layout_line_list_draw_to_pixbuf), + (smooth_text_layout_line_list_new_wrapped), + (smooth_text_layout_get_empty_line_height), + (smooth_text_layout_get_num_empty_lines), + (smooth_text_layout_get_max_line_width), + (smooth_text_layout_get_total_line_height), + (smooth_text_layout_get_line_wrap_width), + (eel_smooth_text_layout_new), + (eel_smooth_text_layout_draw_to_pixbuf), + (eel_smooth_text_layout_draw_to_pixbuf_shadow), + (eel_smooth_text_layout_get_dimensions), + (eel_smooth_text_layout_get_width), + (eel_smooth_text_layout_get_height), + (eel_smooth_text_layout_set_wrap), + (eel_smooth_text_layout_get_wrap), + (eel_smooth_text_layout_set_font), + (eel_smooth_text_layout_get_font), + (eel_smooth_text_layout_set_font_size), + (eel_smooth_text_layout_get_font_size), + (eel_smooth_text_layout_set_line_spacing), + (eel_smooth_text_layout_get_line_spacing), + (eel_smooth_text_layout_set_empty_line_height), + (eel_smooth_text_layout_get_empty_line_height), + (smooth_text_layout_set_text), + (eel_smooth_text_layout_set_line_break_characters), + (eel_smooth_text_layout_get_line_break_characters), + (eel_smooth_text_layout_set_line_wrap_width), + (text_layout_free_row), (eel_text_layout_free), + (eel_text_layout_new), (eel_smooth_text_layout_compare): + * eel/eel-smooth-text-layout.h: + * eel/eel-smooth-widget.c: (preferences_get_is_smooth), + (eel_smooth_widget_register), + (smooth_widget_get_tile_origin_point), + (smooth_widget_get_gtk_background), (smooth_widget_get_background), + (smooth_widget_paint_tile_opaque), + (smooth_widget_paint_tile_transparent), + (smooth_widget_paint_content_opaque), + (smooth_widget_paint_content_transparent), + (smooth_widget_paint_tile_and_content_transparent), + (eel_smooth_widget_paint), (eel_smooth_widget_get_tile_bounds), + (eel_smooth_widget_get_preferred_dimensions), + (eel_smooth_widget_register_type): + * eel/eel-smooth-widget.h: + * eel/eel-stock-dialogs.c: (timed_wait_free), + (timed_wait_dialog_destroy_callback), (timed_wait_callback), + (eel_timed_wait_start_with_duration), (eel_timed_wait_start), + (eel_timed_wait_stop), (eel_run_simple_dialog), + (find_message_label), (create_message_box), + (eel_create_info_dialog), (eel_show_info_dialog), + (details_dialog_clicked_callback), + (eel_show_info_dialog_with_details), (eel_show_warning_dialog), + (eel_show_error_dialog), (eel_show_error_dialog_with_details), + (eel_show_yes_no_dialog), (eel_create_question_dialog): + * eel/eel-stock-dialogs.h: + * eel/eel-string-list.c: (eel_string_list_new), + (eel_string_list_new_from_string), + (eel_string_list_new_from_string_list), + (eel_string_list_new_from_tokens), + (eel_string_list_assign_from_string_list), (eel_string_list_free), + (eel_string_list_insert), (eel_string_list_nth), + (eel_string_list_nth_as_integer), (eel_string_list_modify_nth), + (eel_string_list_remove_nth), (eel_string_list_contains), + (eel_string_list_find_by_function), (eel_string_list_get_length), + (eel_string_list_clear), (eel_string_list_equals), + (eel_string_list_as_g_list), + (eel_string_list_get_index_for_string), + (eel_string_list_as_concatenated_string), (eel_string_list_sort), + (eel_string_list_sort_by_function), + (eel_string_list_remove_duplicates), (eel_string_list_for_each), + (eel_string_list_get_longest_string), + (eel_string_list_get_longest_string_length), (str_is_equal), + (test_dog), (test_data), (test_true), (test_false), + (compare_number), (eel_self_check_string_list): + * eel/eel-string-list.h: + * eel/eel-string-map.c: (eel_string_map_new), + (eel_string_map_free), (eel_string_map_clear), + (eel_string_map_lookup), (eel_string_map_add), (map_entry_new), + (map_entry_free), (map_entry_list_lookup), (str_is_equal), + (eel_self_check_string_map): + * eel/eel-string-map.h: + * eel/eel-string-picker.c: (eel_string_picker_initialize_class), + (eel_string_picker_initialize), (eel_string_picker_destroy), + (option_menu_activate_callback), (eel_string_picker_new), + (eel_string_picker_set_string_list), + (eel_string_picker_get_string_list), + (eel_string_picker_get_selected_string), + (eel_string_picker_set_selected_string), + (eel_string_picker_set_selected_string_index), + (eel_string_picker_insert_string), (eel_string_picker_contains), + (eel_string_picker_get_index_for_string), + (eel_string_picker_clear): + * eel/eel-string-picker.h: + * eel/eel-string.c: (eel_strlen), (eel_strchr), (eel_strcmp), + (eel_strcasecmp), (eel_strcmp_case_breaks_ties), (eel_strcoll), + (eel_str_is_empty), (eel_str_is_equal), (eel_istr_is_equal), + (eel_strcmp_compare_func), (eel_strcoll_compare_func), + (eel_strcasecmp_compare_func), (eel_str_has_prefix), + (eel_str_has_suffix), (eel_istr_has_prefix), (eel_istr_has_suffix), + (eel_str_get_prefix), (eel_str_get_after_prefix), (eel_str_to_int), + (eel_str_strip_chr), (eel_str_strip_trailing_chr), + (eel_str_strip_trailing_str), (eel_eat_str_to_int), + (eel_str_double_underscores), (eel_str_capitalize), + (eel_str_middle_truncate), (eel_str_count_characters), + (eel_str_strip_substring_and_after), (eel_str_replace_substring), + (eel_str_remove_bracketed_text), (call_str_to_int), + (call_eat_str_to_int), (eel_self_check_string): + * eel/eel-string.h: + * eel/eel-text-caption.c: (eel_text_caption_initialize_class), + (eel_text_caption_initialize), (eel_text_caption_destroy), + (entry_changed_callback), (entry_key_press_callback), + (eel_text_caption_new), (eel_text_caption_get_text), + (eel_text_caption_set_text), (eel_text_caption_set_editable), + (eel_text_caption_set_expand_tilde): + * eel/eel-text-caption.h: + * eel/eel-viewport.c: (eel_viewport_initialize_class), + (eel_viewport_initialize), (eel_viewport_destroy), + (eel_viewport_draw), (eel_viewport_size_allocate), + (eel_viewport_expose_event), (eel_viewport_realize), + (eel_viewport_paint), (eel_viewport_set_is_smooth_signal), + (eel_viewport_new), (eel_viewport_set_is_smooth), + (eel_viewport_get_is_smooth), (eel_viewport_set_constrain_width), + (eel_viewport_get_constrain_width), + (eel_viewport_set_constrain_height), + (eel_viewport_get_constrain_height), + (eel_viewport_set_never_smooth), (eel_viewport_get_scroll_offset): + * eel/eel-viewport.h: + * eel/eel-wrap-table.c: (eel_wrap_table_initialize_class), + (eel_wrap_table_initialize), (eel_wrap_table_destroy), + (eel_wrap_table_set_arg), (eel_wrap_table_get_arg), + (eel_wrap_table_size_request), (eel_wrap_table_size_allocate), + (eel_wrap_table_expose_event), (eel_wrap_table_map), + (eel_wrap_table_unmap), (eel_wrap_table_add), + (eel_wrap_table_remove), (eel_wrap_table_forall), + (eel_wrap_table_child_type), (wrap_table_layout), + (wrap_table_art_irect_max_dimensions), + (wrap_table_get_max_child_dimensions), + (wrap_table_get_content_dimensions), + (wrap_table_get_content_bounds), (wrap_table_get_scroll_offset), + (wrap_table_find_child_at_point), (eel_wrap_table_new), + (eel_wrap_table_set_x_spacing), (eel_wrap_table_get_x_spacing), + (eel_wrap_table_set_y_spacing), (eel_wrap_table_get_y_spacing), + (eel_wrap_table_find_child_at_event_point), + (eel_wrap_table_set_x_justification), + (eel_wrap_table_get_x_justification), + (eel_wrap_table_set_y_justification), + (eel_wrap_table_get_y_justification), + (eel_wrap_table_set_homogeneous), (eel_wrap_table_get_homogeneous), + (eel_wrap_table_reorder_child), (eel_wrap_table_get_num_children): + * eel/eel-wrap-table.h: + * eel/eel-xml-extensions.c: (eel_xml_get_children), + (eel_xml_get_root_children), + (eel_xml_get_child_by_name_and_property), + (eel_xml_get_child_by_name), + (eel_xml_get_root_child_by_name_and_property), + (eel_xml_get_property_for_children), + (eel_xml_get_property_translated), (eel_xml_remove_node): + * eel/eel-xml-extensions.h: + * test/Makefile.am: + * test/test-eel-background.c: (main): + * test/test-eel-clickable-image.c: (clicked_callback), + (enter_callback), (leave_callback), (clickable_image_new): + * test/test-eel-font-manager.c: (font_type_to_string), + (font_iterator_callback), (main): + * test/test-eel-font-picker.c: (update_font), + (font_changed_update_label_callback), + (font_changed_update_file_name_callback), + (use_defalt_font_callback), (use_defalt_bold_font_callback), + (use_defalt_font_update_picker_callback), + (use_defalt_bold_font_update_picker_callback), + (print_selected_font_callback), (main): + * test/test-eel-font-simple.c: (main): + * test/test-eel-font.c: (main): + * test/test-eel-glyph-simple.c: (glyph_new), (main): + * test/test-eel-glyph.c: (glyph_new), (main): + * test/test-eel-image-background.c: + (window_new_with_eel_background_image), + (window_new_with_eel_background_gradient), + (window_new_with_solid_background), (main): + * test/test-eel-image-scrolled.c: (toggle_smooth_callback), + (label_window_new), (label_window_new_scrolled): + * test/test-eel-image-simple.c: (toggle_smooth_callback), + (image_window_new), (main): + * test/test-eel-image-table.c: (labeled_image_new), + (image_table_child_enter_callback), + (image_table_child_leave_callback), + (image_table_child_pressed_callback), + (image_table_child_released_callback), + (image_table_child_clicked_callback), (image_table_size_allocate), + (image_table_new_scrolled): + * test/test-eel-image-tile.c: + (window_new_with_eel_background_image), + (window_new_with_eel_background_gradient), (window_four_new), + (main): + * test/test-eel-image.c: (icon_get_path), (label_new), + (label_enter_event), (label_leave_event), (label_free_data), + (image_new), (image_new_from_name), (label_add_prelighting), + (header_new), (main): + * test/test-eel-label-background.c: + (window_new_with_eel_background_image), + (window_new_with_eel_background_gradient), + (window_new_with_solid_background), (main): + * test/test-eel-label-flavorful.c: (increasing_label_window_new), + (decreasing_label_window_new), (main): + * test/test-eel-label-offset.c: (main): + * test/test-eel-label-scrolled.c: (label_window_new), + (label_window_new_scrolled), (label_window_new_table): + * test/test-eel-label-simple.c: (use_system_font_callback), + (use_system_font_bold_callback), (main): + * test/test-eel-label-wrapped.c: (create_eel_label), + (create_gtk_label_window), (create_eel_label_window), (main): + * test/test-eel-label.c: (red_label_color_value_changed_callback), + (green_label_color_value_changed_callback), + (blue_label_color_value_changed_callback), + (alpha_label_color_value_changed_callback), + (red_background_color_value_changed_callback), + (green_background_color_value_changed_callback), + (blue_background_color_value_changed_callback), + (alpha_background_color_value_changed_callback), + (text_caption_changed_callback), (create_value_scale), + (create_color_picker_frame), (create_text_caption_frame), + (widget_set_eel_background_image), + (widget_set_eel_background_color), + (widget_get_eel_background_color), (widget_set_background_reset), + (background_changed_callback), (justification_changed_callback), + (drop_shadow_offset_changed_callback), (create_background_frame), + (create_justification_frame), (create_drop_shadow_offset_frame), + (main): + * test/test-eel-labeled-image.c: (labeled_image_new), + (labeled_image_window_new), (labeled_image_button_window_new), + (main): + * test/test-eel-password-dialog.c: (authenticate_boink_callback): + * test/test-eel-pixbuf-tile.c: (pixbuf_drawing_area_expose_event), + (drawable_drawing_area_expose_event): + * test/test-eel-smooth-text-layout.c: (main): + * test/test-eel-viewport-constraint.c: + (widget_set_eel_background_color), (create_eel_label), + (summary_view_item_label_new), (create_row), (main): + * test/test-eel-widgets.c: (create_pixbuf), + (radio_group_load_it_up), (test_radio_group), + (test_radio_group_horizontal), (test_caption_table), + (test_string_picker), (test_text_caption), + (string_picker_changed_callback), (text_caption_changed_callback), + (test_radio_changed_callback): + * test/test.c: (test_init), (test_gtk_widget_set_background_image), + (test_gtk_widget_set_background_color), (test_pixbuf_new_named), + (test_image_new), (test_label_new), + (test_text_caption_get_text_as_int), + (test_pixbuf_draw_rectangle_tiled): + * test/test.h: + +2001-03-28 Ramiro Estrugo + + Started ChangeLog + +# Local Variables: +# coding: utf-8 +# End: diff --git a/eel/Makefile.am b/eel/Makefile.am new file mode 100644 index 00000000..d690eba2 --- /dev/null +++ b/eel/Makefile.am @@ -0,0 +1,186 @@ +NULL= + +noinst_LTLIBRARIES=libeel-2.la + +INCLUDES = \ + -DG_LOG_DOMAIN=\"Eel\" \ + -I$(top_srcdir) \ + $(CORE_CFLAGS) \ + $(WARNING_CFLAGS) \ + -DDATADIR=\""$(datadir)"\" \ + -DSOURCE_DATADIR=\""$(top_srcdir)/data"\" \ + -DMATELOCALEDIR=\""$(prefix)/${DATADIRNAME}/locale"\" \ + -DG_DISABLE_DEPRECATED \ + -DGDK_PIXBUF_DISABLE_DEPRECATED \ + -DMATEMENU_I_KNOW_THIS_IS_UNSTABLE \ + $(NULL) + +libeel_2_la_LDFLAGS = \ + -no-undefined \ + $(CORE_CFLAGS) \ + $(NULL) + +libeel_2_la_LIBADD = \ + $(CORE_LIBS) \ + $(RENDER_LIBS) \ + $(X_LIBS) \ + $(NULL) + +libeel_2_la_SOURCES = \ + eel-accessibility.c \ + eel-alert-dialog.c \ + eel-art-extensions.c \ + eel-art-gtk-extensions.c \ + eel-background.c \ + eel-background-box.c \ + eel-canvas.c \ + eel-canvas-util.c \ + eel-canvas-rect-ellipse.c \ + eel-debug-drawing.c \ + eel-debug.c \ + eel-editable-label.c \ + eel-enumeration.c \ + eel-mateconf-extensions.c \ + eel-gdk-extensions.c \ + eel-gdk-pixbuf-extensions.c \ + eel-glib-extensions.c \ + eel-mate-extensions.c \ + eel-graphic-effects.c \ + eel-gtk-container.c \ + eel-gtk-extensions.c \ + eel-i18n.c \ + eel-image-table.c \ + eel-labeled-image.c \ + eel-lib-self-check-functions.c \ + eel-pango-extensions.c \ + eel-preferences-builder.c \ + eel-preferences.c \ + eel-self-checks.c \ + eel-stock-dialogs.c \ + eel-string.c \ + eel-types.c \ + eel-vfs-extensions.c \ + eel-wrap-table.c \ + eel-xml-extensions.c \ + eel-lib-self-check-functions.h \ + $(NULL) + +eel_headers = \ + eel-accessibility.h \ + eel-alert-dialog.h \ + eel-art-extensions.h \ + eel-art-gtk-extensions.h \ + eel-background.h \ + eel-background-box.h \ + eel-canvas.h \ + eel-canvas-util.h \ + eel-canvas-rect-ellipse.h \ + eel-debug-drawing.h \ + eel-debug.h \ + eel-editable-label.h \ + eel-enumeration.h \ + eel-mateconf-extensions.h \ + eel-gdk-extensions.h \ + eel-gdk-pixbuf-extensions.h \ + eel-glib-extensions.h \ + eel-mate-extensions.h \ + eel-graphic-effects.h \ + eel-gtk-container.h \ + eel-gtk-extensions.h \ + eel-gtk-macros.h \ + eel-i18n.h \ + eel-image-table.h \ + eel-labeled-image.h \ + eel-pango-extensions.h \ + eel-preferences.h \ + eel-self-checks.h \ + eel-stock-dialogs.h \ + eel-string.h \ + eel-types.h \ + eel-vfs-extensions.h \ + eel-wrap-table.h \ + eel-xml-extensions.h \ + eel.h \ + $(NULL) + +marshal_sources = \ + eel-marshal.h \ + eel-marshal.c \ + $(NULL) + +eel-marshal.h: eelmarshal.list $(GLIB_GENMARSHAL) + $(AM_V_GEN)$(GLIB_GENMARSHAL) $< --header --prefix=eel_marshal > $@ +eel-marshal.c: eelmarshal.list $(GLIB_GENMARSHAL) + $(AM_V_GEN)$(GLIB_GENMARSHAL) $< --body --prefix=eel_marshal > $@ + +stamp_sources = \ + eel-enums.defs \ + eel-type-builtins-evals.c \ + $(NULL) + +stamps = \ + eel-makeenums-stamp \ + eel-stamp \ + $(NULL) + +eel-makeenums-stamp: makeenums.pl $(eel_headers) + $(AM_V_GEN)$(PERL) $< defs $(filter-out $<,$^) > xgen-eed \ + && (cmp -s xgen-eed eel-enums.defs || mv -f xgen-eed eel-enums.defs) \ + && rm -f xgen-eed \ + && $(PERL) $< arrays $(filter-out $<,$^) > xgen-etbe \ + && (cmp -s xgen-etbe eel-type-builtins-evals.c || mv -f xgen-etbe eel-type-builtins-evals.c) \ + && rm -f xgen-etbe \ + && echo timestamp > $@ + +maketypes_sources = \ + eel-type-builtins.h \ + eel-type-builtins-ids.c \ + eel-type-builtins-vars.c \ + $(NULL) + +eel-stamp: eel-makeenums-stamp $(maketypes_sources) + echo timestamp > $@ + +eel-type-builtins.h: eel-enums.defs maketypes.awk eel-makeenums-stamp + LC_ALL=C $(AWK) -f $(srcdir)/maketypes.awk $< macros > $@ +eel-type-builtins-vars.c: eel-enums.defs maketypes.awk eel-makeenums-stamp + LC_ALL=C $(AWK) -f $(srcdir)/maketypes.awk $< variables > $@ +eel-type-builtins-ids.c: eel-enums.defs maketypes.awk eel-makeenums-stamp + LC_ALL=C $(AWK) -f $(srcdir)/maketypes.awk $< entries > $@ + +noinst_PROGRAMS = check-program + +check_program_SOURCES = check-program.c +check_program_DEPENDENCIES = libeel-2.la +check_program_LDADD = $(EEL_LIBS) +check_program_LDFLAGS = $(check_program_DEPENDENCIES) -lm + +TESTS = check-eel + +EXTRA_DIST = \ + $(eel_headers) \ + eel-type-builtins.h \ + eel-marshal.h \ + check-eel \ + eelmarshal.list \ + makeenums.pl \ + maketypes.awk \ + $(NULL) + +$(libeel_2_la_OBJECTS): $(marshal_sources) + +# This trick causes the stamp file to be built first. +Makefile: eel-stamp + +# This trick causes the generated files to be built the first time. +$(stamp_sources): # never add any dependencies + test -f $@ || touch $@ + +built_sources = $(stamps) $(stamp_sources) $(maketypes_sources) $(marshal_sources) +CLEANFILES = $(built_sources) +DONT_DIST_FILES = $(built_sources) + +dist-hook: + for file in $(DONT_DIST_FILES) ; do \ + rm -f $(distdir)/$$file ; \ + done diff --git a/eel/README b/eel/README new file mode 100644 index 00000000..15d86bba --- /dev/null +++ b/eel/README @@ -0,0 +1,4 @@ +README for eel/eel + +Writeme + diff --git a/eel/check-eel b/eel/check-eel new file mode 100755 index 00000000..d1c67b62 --- /dev/null +++ b/eel/check-eel @@ -0,0 +1,3 @@ +#!/bin/sh +./check-program --g-fatal-warnings --sm-disable + diff --git a/eel/check-program.c b/eel/check-program.c new file mode 100644 index 00000000..b1e0a3c7 --- /dev/null +++ b/eel/check-program.c @@ -0,0 +1,60 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* check-program.c: A simple driver for eel self checks. + + Copyright (C) 2000 Eazel, Inc. + + The Mate Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Mate Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Mate Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Authors: Ramiro Estrugo +*/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +int +main (int argc, char *argv[]) +{ +#if !defined (EEL_OMIT_SELF_CHECK) + + eel_make_warnings_and_criticals_stop_in_debugger (); + + + LIBXML_TEST_VERSION + gtk_init (&argc, &argv); + + /* Run the checks for eel twice. */ + + eel_run_lib_self_checks (); + eel_exit_if_self_checks_failed (); + + eel_run_lib_self_checks (); + eel_exit_if_self_checks_failed (); + + eel_debug_shut_down (); + +#endif /* !EEL_OMIT_SELF_CHECK */ + + return EXIT_SUCCESS; +} diff --git a/eel/eel-accessibility.c b/eel/eel-accessibility.c new file mode 100644 index 00000000..1a8a8037 --- /dev/null +++ b/eel/eel-accessibility.c @@ -0,0 +1,432 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* eel-accessibility.h - Utility functions for accessibility + + Copyright (C) 2002 Anders Carlsson, Sun Microsystems, Inc. + + The Eel Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Eel Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Eel Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Authors: + Anders Carlsson + Michael Meeks +*/ +#include +#include +#include +#include + +void +eel_accessibility_set_up_label_widget_relation (GtkWidget *label, GtkWidget *widget) +{ + AtkObject *atk_widget, *atk_label; + + atk_label = gtk_widget_get_accessible (label); + atk_widget = gtk_widget_get_accessible (widget); + + /* Create the label -> widget relation */ + atk_object_add_relationship (atk_label, ATK_RELATION_LABEL_FOR, atk_widget); + + /* Create the widget -> label relation */ + atk_object_add_relationship (atk_widget, ATK_RELATION_LABELLED_BY, atk_label); +} + +/* + * Hacks to make re-using gail somewhat easier. + */ + +/** + * eel_accessibility_create_derived_type: + * @type_name: the name for the new accessible type eg. CajaIconCanvasItemAccessible + * @existing_gobject_with_proxy: the GType of an object that has a registered factory that + * manufactures the type we want to inherit from. ie. to inherit from a GailCanvasItem + * we need to pass MATE_TYPE_CANVAS_ITEM - since GailCanvasItem is registered against + * that type. + * @opt_gail_parent_class: the name of the Gail class to derive from eg. GailCanvasItem + * @class_init: the init function to run for this class + * + * This should be run to register the type, it can subsequently be run with + * the same name and will not re-register it, but simply return it. + * + * NB. to do instance init, you prolly want to override AtkObject::initialize + * + * Return value: the registered type, or 0 on failure. + **/ +GType +eel_accessibility_create_derived_type (const char *type_name, + GType existing_gobject_with_proxy, + EelAccessibilityClassInitFn class_init) +{ + GType type; + GType parent_atk_type; + GTypeInfo tinfo = { 0 }; + GTypeQuery query; + AtkObjectFactory *factory; + + if ((type = g_type_from_name (type_name))) + { + return type; + } + + factory = atk_registry_get_factory + (atk_get_default_registry (), + existing_gobject_with_proxy); + if (!factory) + { + return G_TYPE_INVALID; + } + + parent_atk_type = atk_object_factory_get_accessible_type (factory); + if (!parent_atk_type) + { + return G_TYPE_INVALID; + } + + /* + * Figure out the size of the class and instance + * we are deriving from + */ + g_type_query (parent_atk_type, &query); + + if (class_init) + { + tinfo.class_init = (GClassInitFunc) class_init; + } + + tinfo.class_size = query.class_size; + tinfo.instance_size = query.instance_size; + + /* Register the type */ + type = g_type_register_static ( + parent_atk_type, type_name, &tinfo, 0); + + return type; +} + + +static GQuark +get_quark_accessible (void) +{ + static GQuark quark_accessible_object = 0; + + if (!quark_accessible_object) + { + quark_accessible_object = g_quark_from_static_string + ("accessible-object"); + } + + return quark_accessible_object; +} + +static GQuark +get_quark_gobject (void) +{ + static GQuark quark_accessible_gobject = 0; + + if (!quark_accessible_gobject) + { + quark_accessible_gobject = g_quark_from_static_string + ("object-for-accessible"); + } + + return quark_accessible_gobject; +} + +/** + * eel_accessibility_get_atk_object: + * @object: a GObject of some sort + * + * gets an AtkObject associated with a GObject + * + * Return value: the associated accessible if one exists or NULL + **/ +AtkObject * +eel_accessibility_get_atk_object (gpointer object) +{ + return g_object_get_qdata (object, get_quark_accessible ()); +} + +/** + * eel_accessibilty_for_object: + * @object: a GObject of some sort + * + * gets an AtkObject associated with a GObject and if it doesn't + * exist creates a suitable accessible object. + * + * Return value: an associated accessible. + **/ +AtkObject * +eel_accessibility_for_object (gpointer object) +{ + if (GTK_IS_WIDGET (object)) + return gtk_widget_get_accessible (object); + + return atk_gobject_accessible_for_object (object); +} + +/** + * eel_accessibility_get_gobject: + * @object: an AtkObject + * + * gets the GObject associated with the AtkObject, for which + * @object provides accessibility support. + * + * Return value: the accessible's associated GObject + **/ +gpointer +eel_accessibility_get_gobject (AtkObject *object) +{ + return g_object_get_qdata (G_OBJECT (object), get_quark_gobject ()); +} + +static void +eel_accessibility_destroy (gpointer data, + GObject *where_the_object_was) +{ + atk_object_notify_state_change + (ATK_OBJECT (data), ATK_STATE_DEFUNCT, TRUE); +} + +/** + * eel_accessibility_set_atk_object_return: + * @object: a GObject + * @atk_object: it's AtkObject + * + * used to register and return a new accessible object for something + * + * Return value: @atk_object. + **/ +AtkObject * +eel_accessibility_set_atk_object_return (gpointer object, + AtkObject *atk_object) +{ + atk_object_initialize (atk_object, object); + + if (!ATK_IS_GOBJECT_ACCESSIBLE (atk_object)) + { + g_object_set_qdata_full + (object, get_quark_accessible (), atk_object, + (GDestroyNotify)eel_accessibility_destroy); + g_object_set_qdata + (G_OBJECT (atk_object), get_quark_gobject (), object); + } + + return atk_object; +} + +static GailTextUtil * +get_simple_text (gpointer object) +{ + GObject *gobject; + EelAccessibleTextIface *aif; + + if (GTK_IS_ACCESSIBLE (object)) + { + gobject = G_OBJECT (gtk_accessible_get_widget (GTK_ACCESSIBLE (object))); + } + else + { + gobject = eel_accessibility_get_gobject (object); + } + + if (!gobject) + { + return NULL; + } + + aif = EEL_ACCESSIBLE_TEXT_GET_IFACE (gobject); + if (!aif) + { + g_warning ("No accessible text inferface on '%s'", + g_type_name_from_instance ((gpointer) gobject)); + + } + else if (aif->get_text) + { + return aif->get_text (gobject); + } + + return NULL; +} + +char * +eel_accessibility_text_get_text (AtkText *text, + gint start_pos, + gint end_pos) +{ + GailTextUtil *util = get_simple_text (text); + g_return_val_if_fail (util != NULL, NULL); + + return gail_text_util_get_substring (util, start_pos, end_pos); +} + +gunichar +eel_accessibility_text_get_character_at_offset (AtkText *text, + gint offset) +{ + char *txt, *index; + gint sucks1 = 0, sucks2 = -1; + gunichar c; + GailTextUtil *util = get_simple_text (text); + g_return_val_if_fail (util != NULL, 0); + + txt = gail_text_util_get_substring (util, sucks1, sucks2); + + index = g_utf8_offset_to_pointer (txt, offset); + c = g_utf8_get_char (index); + g_free (txt); + + return c; +} + +char * +eel_accessibility_text_get_text_before_offset (AtkText *text, + gint offset, + AtkTextBoundary boundary_type, + gint *start_offset, + gint *end_offset) +{ + GailTextUtil *util = get_simple_text (text); + g_return_val_if_fail (util != NULL, NULL); + + return gail_text_util_get_text ( + util, NULL, GAIL_BEFORE_OFFSET, + boundary_type, offset, start_offset, end_offset); +} + +char * +eel_accessibility_text_get_text_at_offset (AtkText *text, + gint offset, + AtkTextBoundary boundary_type, + gint *start_offset, + gint *end_offset) +{ + GailTextUtil *util = get_simple_text (text); + g_return_val_if_fail (util != NULL, NULL); + + return gail_text_util_get_text ( + util, NULL, GAIL_AT_OFFSET, + boundary_type, offset, start_offset, end_offset); +} + +gchar* +eel_accessibility_text_get_text_after_offset (AtkText *text, + gint offset, + AtkTextBoundary boundary_type, + gint *start_offset, + gint *end_offset) +{ + GailTextUtil *util = get_simple_text (text); + g_return_val_if_fail (util != NULL, NULL); + + return gail_text_util_get_text ( + util, NULL, GAIL_AFTER_OFFSET, + boundary_type, offset, start_offset, end_offset); +} + +gint +eel_accessibility_text_get_character_count (AtkText *text) +{ + GailTextUtil *util = get_simple_text (text); + g_return_val_if_fail (util != NULL, -1); + + return gtk_text_buffer_get_char_count (util->buffer); +} + +static void +eel_accessibility_simple_text_interface_init (AtkTextIface *iface) +{ + iface->get_text = eel_accessibility_text_get_text; + iface->get_character_at_offset = eel_accessibility_text_get_character_at_offset; + iface->get_text_before_offset = eel_accessibility_text_get_text_before_offset; + iface->get_text_at_offset = eel_accessibility_text_get_text_at_offset; + iface->get_text_after_offset = eel_accessibility_text_get_text_after_offset; + iface->get_character_count = eel_accessibility_text_get_character_count; + + /* iface->get_caret_offset = eel_accessibility_text_get_caret_offset; + iface->set_caret_offset = eel_accessibility_text_set_caret_offset; + iface->get_selection = eel_accessibility_text_get_selection; + iface->get_n_selections = eel_accessibility_text_get_n_selections; + iface->add_selection = eel_accessibility_text_add_selection; + iface->remove_selection = eel_accessibility_text_remove_selection; + iface->set_selection = eel_accessibility_text_set_selection; + iface->get_run_attributes = eel_accessibility_text_get_run_attributes; + iface->get_default_attributes = eel_accessibility_text_get_default_attributes; + iface->get_character_extents = eel_accessibility_text_get_character_extents; + iface->get_offset_at_point = eel_accessibility_text_get_offset_at_point; */ +} + +void +eel_accessibility_add_simple_text (GType type) +{ + const GInterfaceInfo simple_text_info = + { + (GInterfaceInitFunc) + eel_accessibility_simple_text_interface_init, + (GInterfaceFinalizeFunc) NULL, + NULL + }; + + g_return_if_fail (type != G_TYPE_INVALID); + + g_type_add_interface_static ( + type, ATK_TYPE_TEXT, &simple_text_info); +} + +GType +eel_accessible_text_get_type (void) +{ + static GType type = 0; + + if (!type) + { + const GTypeInfo tinfo = + { + sizeof (AtkTextIface), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) NULL, + (GClassFinalizeFunc) NULL + }; + + type = g_type_register_static ( + G_TYPE_INTERFACE, "EelAccessibleText", &tinfo, 0); + } + + return type; +} + +void +eel_accessibility_set_name (gpointer object, + const char *name) +{ + AtkObject *atk_object = eel_accessibility_for_object (object); + + if (atk_object) + { + atk_object_set_name (atk_object, name); + } +} + +void +eel_accessibility_set_description (gpointer object, + const char *description) +{ + AtkObject *atk_object = eel_accessibility_for_object (object); + + if (atk_object) + { + atk_object_set_description (atk_object, description); + } +} diff --git a/eel/eel-accessibility.h b/eel/eel-accessibility.h new file mode 100644 index 00000000..3ca24a0f --- /dev/null +++ b/eel/eel-accessibility.h @@ -0,0 +1,153 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* eel-accessibility.h - Utility functions for accessibility + + Copyright (C) 2002 Anders Carlsson + + The Eel Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Eel Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Eel Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Authors: Anders Carlsson +*/ + +#ifndef EEL_ACCESSIBILITY_H +#define EEL_ACCESSIBILITY_H + +#include +#include +#include +#include +#include +#include + +void eel_accessibility_set_up_label_widget_relation (GtkWidget *label, GtkWidget *widget); + +typedef void (*EelAccessibilityClassInitFn) (AtkObjectClass *klass); + +AtkObject *eel_accessibility_get_atk_object (gpointer object); +AtkObject *eel_accessibility_for_object (gpointer object); +gpointer eel_accessibility_get_gobject (AtkObject *object); +AtkObject *eel_accessibility_set_atk_object_return (gpointer object, + AtkObject *atk_object); +GType eel_accessibility_create_derived_type (const char *type_name, + GType existing_gobject_with_proxy, + EelAccessibilityClassInitFn class_init); +void eel_accessibility_set_name (gpointer object, + const char *name); +void eel_accessibility_set_description (gpointer object, + const char *description); + +char* eel_accessibility_text_get_text (AtkText *text, + gint start_pos, + gint end_pos); +gunichar eel_accessibility_text_get_character_at_offset +(AtkText *text, + gint offset); +char* eel_accessibility_text_get_text_before_offset +(AtkText *text, + gint offset, + AtkTextBoundary boundary_type, + gint *start_offset, + gint *end_offset); +char* eel_accessibility_text_get_text_at_offset +(AtkText *text, + gint offset, + AtkTextBoundary boundary_type, + gint *start_offset, + gint *end_offset); +char* eel_accessibility_text_get_text_after_offset +(AtkText *text, + gint offset, + AtkTextBoundary boundary_type, + gint *start_offset, + gint *end_offset); +gint eel_accessibility_text_get_character_count +(AtkText *text); + + +#define EEL_TYPE_ACCESSIBLE_TEXT (eel_accessible_text_get_type ()) +#define EEL_IS_ACCESSIBLE_TEXT(obj) G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEL_TYPE_ACCESSIBLE_TEXT) +#define EEL_ACCESSIBLE_TEXT(obj) G_TYPE_CHECK_INSTANCE_CAST ((obj), EEL_TYPE_ACCESSIBLE_TEXT, EelAccessibleText) +#define EEL_ACCESSIBLE_TEXT_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), EEL_TYPE_ACCESSIBLE_TEXT, EelAccessibleTextIface)) + +/* Instead of implementing the AtkText interface, implement this */ +typedef struct _EelAccessibleText EelAccessibleText; + +typedef struct +{ + GTypeInterface parent; + + GailTextUtil *(*get_text) (GObject *text); + PangoLayout *(*get_layout) (GObject *text); +} EelAccessibleTextIface; + +GType eel_accessible_text_get_type (void); +void eel_accessibility_add_simple_text (GType type); + +/* From gail - should be unneccessary when AtkObjectFactory is fixed */ +#define EEL_ACCESSIBLE_FACTORY(type, factory_name, type_as_function, opt_create_accessible) \ + \ +static GType \ +type_as_function ## _factory_get_accessible_type (void) \ +{ \ + return type; \ +} \ + \ +static AtkObject* \ +type_as_function ## _factory_create_accessible (GObject *obj) \ +{ \ + AtkObject *accessible; \ + \ + g_assert (G_IS_OBJECT (obj)); \ + \ + accessible = opt_create_accessible (obj); \ + \ + return accessible; \ +} \ + \ +static void \ +type_as_function ## _factory_class_init (AtkObjectFactoryClass *klass) \ +{ \ + klass->create_accessible = type_as_function ## _factory_create_accessible; \ + klass->get_accessible_type = type_as_function ## _factory_get_accessible_type;\ +} \ + \ +static GType \ +type_as_function ## _factory_get_type (void) \ +{ \ + static GType t = 0; \ + \ + if (!t) \ + { \ + static const GTypeInfo tinfo = \ + { \ + sizeof (AtkObjectFactoryClass), \ + NULL, NULL, (GClassInitFunc) type_as_function ## _factory_class_init, \ + NULL, NULL, sizeof (AtkObjectFactory), 0, NULL, NULL \ + }; \ + \ + t = g_type_register_static ( \ + ATK_TYPE_OBJECT_FACTORY, factory_name, &tinfo, 0); \ + } \ + \ + return t; \ +} + +#define EEL_OBJECT_SET_FACTORY(object_type, type_as_function) \ + atk_registry_set_factory_type (atk_get_default_registry (), \ + object_type, \ + type_as_function ## _factory_get_type ()) + + +#endif /* EEL_ACCESSIBILITY_H */ diff --git a/eel/eel-alert-dialog.c b/eel/eel-alert-dialog.c new file mode 100644 index 00000000..976c1227 --- /dev/null +++ b/eel/eel-alert-dialog.c @@ -0,0 +1,490 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* eel-alert-dialog.c: An HIG compliant alert dialog. + + The Mate Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Mate Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Mate Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + +*/ +#include + +#include "eel-alert-dialog.h" +#include "eel-i18n.h" +#include "eel-gtk-macros.h" +#include +#include + +enum +{ + PROP_0, + PROP_ALERT_TYPE, + PROP_BUTTONS +}; + +struct _EelAlertDialogDetails +{ + GtkWidget *image; + GtkWidget *primary_label; + GtkWidget *secondary_label; + GtkWidget *details_expander; + GtkWidget *details_label; + GtkMessageType type; +}; + + +static gpointer parent_class; + +static void eel_alert_dialog_finalize (GObject *object); +static void eel_alert_dialog_class_init (EelAlertDialogClass *klass); +static void eel_alert_dialog_init (EelAlertDialog *dialog); +static void eel_alert_dialog_style_set (GtkWidget *widget, + GtkStyle *prev_style); +static void eel_alert_dialog_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static void eel_alert_dialog_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); +static void eel_alert_dialog_add_buttons (EelAlertDialog *alert_dialog, + GtkButtonsType buttons); + +GType +eel_alert_dialog_get_type (void) +{ + static GType dialog_type = 0; + + if (!dialog_type) + { + + const GTypeInfo dialog_info = + { + sizeof (EelAlertDialogClass), + NULL, + NULL, + (GClassInitFunc) eel_alert_dialog_class_init, + NULL, + NULL, + sizeof (EelAlertDialog), + 0, + (GInstanceInitFunc) eel_alert_dialog_init, + }; + + dialog_type = g_type_register_static (GTK_TYPE_DIALOG, "EelAlertDialog", + &dialog_info, 0); + } + return dialog_type; +} + +static void +eel_alert_dialog_class_init (EelAlertDialogClass *class) +{ + GtkWidgetClass *widget_class; + GObjectClass *gobject_class; + + widget_class = GTK_WIDGET_CLASS (class); + gobject_class = G_OBJECT_CLASS (class); + + parent_class = g_type_class_peek_parent (class); + + G_OBJECT_CLASS (class)->finalize = eel_alert_dialog_finalize; + + widget_class->style_set = eel_alert_dialog_style_set; + + gobject_class->set_property = eel_alert_dialog_set_property; + gobject_class->get_property = eel_alert_dialog_get_property; + + gtk_widget_class_install_style_property (widget_class, + g_param_spec_int ("alert_border", + _("Image/label border"), + _("Width of border around the label and image in the alert dialog"), + 0, + G_MAXINT, + 5, + G_PARAM_READABLE)); + + g_object_class_install_property (gobject_class, + PROP_ALERT_TYPE, + g_param_spec_enum ("alert_type", + _("Alert Type"), + _("The type of alert"), + GTK_TYPE_MESSAGE_TYPE, + GTK_MESSAGE_INFO, + G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT)); + + g_object_class_install_property (gobject_class, + PROP_BUTTONS, + g_param_spec_enum ("buttons", + _("Alert Buttons"), + _("The buttons shown in the alert dialog"), + GTK_TYPE_BUTTONS_TYPE, + GTK_BUTTONS_NONE, + G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); +} + +static void +eel_alert_dialog_finalize (GObject *object) +{ + EelAlertDialog *dialog; + + dialog = EEL_ALERT_DIALOG (object); + + g_free (dialog->details); + + EEL_CALL_PARENT (G_OBJECT_CLASS, finalize, (object)); +} + + +static void +eel_alert_dialog_init (EelAlertDialog *dialog) +{ + GtkWidget *hbox; + GtkWidget *vbox; + GtkWidget *expander; + + dialog->details = g_new0 (EelAlertDialogDetails, 1); + + dialog->details->primary_label = gtk_label_new (NULL); + dialog->details->secondary_label = gtk_label_new (NULL); + dialog->details->details_label = gtk_label_new (NULL); + dialog->details->image = gtk_image_new_from_stock (NULL, GTK_ICON_SIZE_DIALOG); + gtk_misc_set_alignment (GTK_MISC (dialog->details->image), 0.5, 0.0); + + gtk_label_set_line_wrap (GTK_LABEL (dialog->details->primary_label), TRUE); + gtk_label_set_selectable (GTK_LABEL (dialog->details->primary_label), TRUE); + gtk_label_set_use_markup (GTK_LABEL (dialog->details->primary_label), TRUE); + gtk_misc_set_alignment (GTK_MISC (dialog->details->primary_label), 0.0, 0.5); + + gtk_label_set_line_wrap (GTK_LABEL (dialog->details->secondary_label), TRUE); + gtk_label_set_selectable (GTK_LABEL (dialog->details->secondary_label), TRUE); + gtk_misc_set_alignment (GTK_MISC (dialog->details->secondary_label), 0.0, 0.5); + + gtk_label_set_line_wrap (GTK_LABEL (dialog->details->details_label), TRUE); + gtk_label_set_selectable (GTK_LABEL (dialog->details->details_label), TRUE); + gtk_misc_set_alignment (GTK_MISC (dialog->details->details_label), 0.0, 0.5); + + hbox = gtk_hbox_new (FALSE, 12); + gtk_container_set_border_width (GTK_CONTAINER (hbox), 5); + + gtk_box_pack_start (GTK_BOX (hbox), dialog->details->image, + FALSE, FALSE, 0); + + vbox = gtk_vbox_new (FALSE, 12); + + gtk_box_pack_start (GTK_BOX (hbox), vbox, + FALSE, FALSE, 0); + + gtk_box_pack_start (GTK_BOX (vbox), dialog->details->primary_label, + FALSE, FALSE, 0); + + gtk_box_pack_start (GTK_BOX (vbox), dialog->details->secondary_label, + FALSE, FALSE, 0); + + expander = gtk_expander_new_with_mnemonic (_("Show more _details")); + dialog->details->details_expander = expander; + gtk_expander_set_spacing (GTK_EXPANDER (expander), 6); + gtk_container_add (GTK_CONTAINER (expander), dialog->details->details_label); + + gtk_box_pack_start (GTK_BOX (vbox), expander, + FALSE, FALSE, 0); + + + gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), hbox, + FALSE, FALSE, 0); + + gtk_widget_show_all (hbox); + gtk_widget_hide (expander); + +} + +static void +setup_type (EelAlertDialog *dialog, + GtkMessageType type) +{ + const gchar *stock_id = NULL; + GtkStockItem item; + + switch (type) + { + case GTK_MESSAGE_INFO: + stock_id = GTK_STOCK_DIALOG_INFO; + break; + case GTK_MESSAGE_QUESTION: + stock_id = GTK_STOCK_DIALOG_QUESTION; + break; + case GTK_MESSAGE_WARNING: + stock_id = GTK_STOCK_DIALOG_WARNING; + break; + case GTK_MESSAGE_ERROR: + stock_id = GTK_STOCK_DIALOG_ERROR; + break; + default: + g_warning ("Unknown GtkMessageType %d", type); + break; + } + + if (stock_id == NULL) + { + stock_id = GTK_STOCK_DIALOG_INFO; + } + + if (gtk_stock_lookup (stock_id, &item)) + { + gtk_image_set_from_stock (GTK_IMAGE (dialog->details->image), stock_id, + GTK_ICON_SIZE_DIALOG); + } + else + { + g_warning ("Stock dialog ID doesn't exist?"); + } +} + +static void +eel_alert_dialog_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + EelAlertDialog *dialog; + + dialog = EEL_ALERT_DIALOG (object); + + switch (prop_id) + { + case PROP_ALERT_TYPE: + dialog->details->type = g_value_get_enum (value); + setup_type (dialog, dialog->details->type); + break; + case PROP_BUTTONS: + eel_alert_dialog_add_buttons (dialog, g_value_get_enum (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +eel_alert_dialog_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + EelAlertDialog *dialog; + + dialog = EEL_ALERT_DIALOG (object); + + switch (prop_id) + { + case PROP_ALERT_TYPE: + g_value_set_enum (value, dialog->details->type); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +void +eel_alert_dialog_set_primary_label (EelAlertDialog *dialog, + const gchar *message) +{ + gchar *markup_str; + char *escaped_message; + + if (message != NULL) + { + escaped_message = g_markup_escape_text (message, -1); + markup_str = g_strconcat ("", escaped_message, "", NULL); + gtk_label_set_markup (GTK_LABEL (EEL_ALERT_DIALOG (dialog)->details->primary_label), + markup_str); + g_free (markup_str); + g_free (escaped_message); + } +} + +void +eel_alert_dialog_set_secondary_label (EelAlertDialog *dialog, + const gchar *message) +{ + if (message != NULL) + { + gtk_label_set_text (GTK_LABEL (EEL_ALERT_DIALOG (dialog)->details->secondary_label), + message); + } + else + { + gtk_widget_hide (EEL_ALERT_DIALOG (dialog)->details->secondary_label); + } +} + +void +eel_alert_dialog_set_details_label (EelAlertDialog *dialog, + const gchar *message) +{ + if (message != NULL) + { + gtk_widget_show (dialog->details->details_expander); + gtk_label_set_text (GTK_LABEL (dialog->details->details_label), message); + } + else + { + gtk_widget_hide (dialog->details->details_expander); + } +} + + +GtkWidget* +eel_alert_dialog_new (GtkWindow *parent, + GtkDialogFlags flags, + GtkMessageType type, + GtkButtonsType buttons, + const gchar *primary_message, + const gchar *secondary_message) +{ + GtkWidget *widget; + GtkDialog *dialog; + + g_return_val_if_fail (parent == NULL || GTK_IS_WINDOW (parent), NULL); + + widget = g_object_new (EEL_TYPE_ALERT_DIALOG, + "alert_type", type, + "buttons", buttons, + NULL); + atk_object_set_role (gtk_widget_get_accessible (widget), ATK_ROLE_ALERT); + + dialog = GTK_DIALOG (widget); + + gtk_container_set_border_width (GTK_CONTAINER (dialog), 5); + gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), 14); + gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE); + gtk_dialog_set_has_separator (dialog, FALSE); + + /* Make sure we don't get a window title. + * HIG says that alert dialogs should not have window title + */ + gtk_window_set_title (GTK_WINDOW (dialog), ""); + gtk_window_set_skip_taskbar_hint (GTK_WINDOW (dialog), TRUE); + + eel_alert_dialog_set_primary_label (EEL_ALERT_DIALOG (dialog), + primary_message); + + eel_alert_dialog_set_secondary_label (EEL_ALERT_DIALOG (dialog), + secondary_message); + + if (parent != NULL) + { + gtk_window_set_transient_for (GTK_WINDOW (widget), + GTK_WINDOW (parent)); + } + + if (flags & GTK_DIALOG_MODAL) + { + gtk_window_set_modal (GTK_WINDOW (dialog), TRUE); + } + + if (flags & GTK_DIALOG_DESTROY_WITH_PARENT) + { + gtk_window_set_destroy_with_parent (GTK_WINDOW (dialog), TRUE); + } + return widget; +} + +static void +eel_alert_dialog_add_buttons (EelAlertDialog* alert_dialog, + GtkButtonsType buttons) +{ + GtkDialog* dialog; + + dialog = GTK_DIALOG (alert_dialog); + + switch (buttons) + { + case GTK_BUTTONS_NONE: + break; + case GTK_BUTTONS_OK: + gtk_dialog_add_button (dialog, + GTK_STOCK_OK, + GTK_RESPONSE_OK); + gtk_dialog_set_default_response (dialog, + GTK_RESPONSE_OK); + break; + case GTK_BUTTONS_CLOSE: + gtk_dialog_add_button (dialog, + GTK_STOCK_CLOSE, + GTK_RESPONSE_CLOSE); + gtk_dialog_set_default_response (dialog, + GTK_RESPONSE_CLOSE); + break; + case GTK_BUTTONS_CANCEL: + gtk_dialog_add_button (dialog, + GTK_STOCK_CANCEL, + GTK_RESPONSE_CANCEL); + gtk_dialog_set_default_response (dialog, + GTK_RESPONSE_CANCEL); + break; + case GTK_BUTTONS_YES_NO: + gtk_dialog_add_button (dialog, + GTK_STOCK_NO, + GTK_RESPONSE_NO); + gtk_dialog_add_button (dialog, + GTK_STOCK_YES, + GTK_RESPONSE_YES); + gtk_dialog_set_default_response (dialog, + GTK_RESPONSE_YES); + break; + case GTK_BUTTONS_OK_CANCEL: + gtk_dialog_add_button (dialog, + GTK_STOCK_CANCEL, + GTK_RESPONSE_CANCEL); + gtk_dialog_add_button (dialog, + GTK_STOCK_OK, + GTK_RESPONSE_OK); + gtk_dialog_set_default_response (dialog, + GTK_RESPONSE_OK); + break; + default: + g_warning ("Unknown GtkButtonsType"); + break; + } + g_object_notify (G_OBJECT (alert_dialog), "buttons"); +} + +static void +eel_alert_dialog_style_set (GtkWidget *widget, + GtkStyle *prev_style) +{ + GtkWidget *parent; + gint border_width; + + border_width = 0; + + parent = GTK_WIDGET (gtk_widget_get_parent (EEL_ALERT_DIALOG (widget)->details->image)); + + if (parent != NULL) + { + gtk_widget_style_get (widget, "alert_border", + &border_width, NULL); + + gtk_container_set_border_width (GTK_CONTAINER (parent), + border_width); + } + + if (GTK_WIDGET_CLASS (parent_class)->style_set) + { + (GTK_WIDGET_CLASS (parent_class)->style_set) (widget, prev_style); + } +} diff --git a/eel/eel-alert-dialog.h b/eel/eel-alert-dialog.h new file mode 100644 index 00000000..62d86a27 --- /dev/null +++ b/eel/eel-alert-dialog.h @@ -0,0 +1,60 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* eel-alert-dialog.h: An HIG compliant alert dialog. + + The Mate Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Mate Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Mate Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + +*/ + +#ifndef EEL_ALERT_DIALOG_H +#define EEL_ALERT_DIALOG_H + +#include + +#define EEL_TYPE_ALERT_DIALOG (eel_alert_dialog_get_type ()) +#define EEL_ALERT_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEL_TYPE_ALERT_DIALOG, EelAlertDialog)) + +typedef struct _EelAlertDialog EelAlertDialog; +typedef struct _EelAlertDialogClass EelAlertDialogClass; +typedef struct _EelAlertDialogDetails EelAlertDialogDetails; + +struct _EelAlertDialog +{ + GtkDialog parent_instance; + EelAlertDialogDetails *details; +}; + +struct _EelAlertDialogClass +{ + GtkDialogClass parent_class; +}; + +GType eel_alert_dialog_get_type (void); + +GtkWidget* eel_alert_dialog_new (GtkWindow *parent, + GtkDialogFlags flags, + GtkMessageType type, + GtkButtonsType buttons, + const gchar *primary_message, + const gchar *secondary_message); +void eel_alert_dialog_set_primary_label (EelAlertDialog *dialog, + const gchar *message); +void eel_alert_dialog_set_secondary_label (EelAlertDialog *dialog, + const gchar *message); +void eel_alert_dialog_set_details_label (EelAlertDialog *dialog, + const gchar *message); + +#endif /* EEL_ALERT_DIALOG_H */ diff --git a/eel/eel-art-extensions.c b/eel/eel-art-extensions.c new file mode 100644 index 00000000..c245101b --- /dev/null +++ b/eel/eel-art-extensions.c @@ -0,0 +1,321 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* eel-art-extensions.c - implementation of libart extension functions. + + Copyright (C) 2000 Eazel, Inc. + + The Mate Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Mate Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Mate Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Authors: Darin Adler + Ramiro Estrugo +*/ + +#include + +#include "eel-art-extensions.h" +#include "eel-lib-self-check-functions.h" +#include + +const EelDRect eel_drect_empty = { 0.0, 0.0, 0.0, 0.0 }; +const EelIRect eel_irect_empty = { 0, 0, 0, 0 }; +const EelIPoint eel_ipoint_max = { G_MAXINT, G_MAXINT }; +const EelIPoint eel_ipoint_min = { G_MININT, G_MININT }; +const EelIPoint eel_ipoint_zero = { 0, 0 }; +const EelDimensions eel_dimensions_empty = { 0, 0 }; + +void +eel_irect_copy (EelIRect *dest, const EelIRect *src) +{ + dest->x0 = src->x0; + dest->y0 = src->y0; + dest->x1 = src->x1; + dest->y1 = src->y1; +} + +void +eel_irect_union (EelIRect *dest, + const EelIRect *src1, + const EelIRect *src2) +{ + if (eel_irect_is_empty (src1)) + { + eel_irect_copy (dest, src2); + } + else if (eel_irect_is_empty (src2)) + { + eel_irect_copy (dest, src1); + } + else + { + dest->x0 = MIN (src1->x0, src2->x0); + dest->y0 = MIN (src1->y0, src2->y0); + dest->x1 = MAX (src1->x1, src2->x1); + dest->y1 = MAX (src1->y1, src2->y1); + } +} + +void +eel_irect_intersect (EelIRect *dest, + const EelIRect *src1, + const EelIRect *src2) +{ + dest->x0 = MAX (src1->x0, src2->x0); + dest->y0 = MAX (src1->y0, src2->y0); + dest->x1 = MIN (src1->x1, src2->x1); + dest->y1 = MIN (src1->y1, src2->y1); +} + +gboolean +eel_irect_is_empty (const EelIRect *src) +{ + return (src->x1 <= src->x0 || + src->y1 <= src->y0); +} + +EelIRect +eel_irect_assign (int x, + int y, + int width, + int height) +{ + EelIRect rectangle; + + rectangle.x0 = x; + rectangle.y0 = y; + rectangle.x1 = rectangle.x0 + width; + rectangle.y1 = rectangle.y0 + height; + + return rectangle; +} + +/** + * eel_irect_assign_dimensions: + * + * @x: X coodinate for resulting rectangle. + * @y: Y coodinate for resulting rectangle. + * @dimensions: A EelDimensions structure for the rect's width and height. + * + * Returns: An EelIRect with the given coordinates and dimensions. + */ +EelIRect +eel_irect_assign_dimensions (int x, + int y, + EelDimensions dimensions) +{ + EelIRect rectangle; + + rectangle.x0 = x; + rectangle.y0 = y; + rectangle.x1 = rectangle.x0 + dimensions.width; + rectangle.y1 = rectangle.y0 + dimensions.height; + + return rectangle; +} + +/** + * eel_irect_get_width: + * + * @rectangle: An EelIRect. + * + * Returns: The width of the rectangle. + * + */ +int +eel_irect_get_width (EelIRect rectangle) +{ + return rectangle.x1 - rectangle.x0; +} + +/** + * eel_irect_get_height: + * + * @rectangle: An EelIRect. + * + * Returns: The height of the rectangle. + * + */ +int +eel_irect_get_height (EelIRect rectangle) +{ + return rectangle.y1 - rectangle.y0; +} + + +static void +eel_drect_copy (EelDRect *dest, + const EelDRect *src) +{ + dest->x0 = src->x0; + dest->y0 = src->y0; + dest->x1 = src->x1; + dest->y1 = src->y1; +} + +static gboolean +eel_drect_is_empty (const EelDRect *src) +{ + return (src->x1 <= src->x0 || src->y1 <= src->y0); +} + +void +eel_drect_union (EelDRect *dest, + const EelDRect *src1, + const EelDRect *src2) +{ + if (eel_drect_is_empty (src1)) + { + eel_drect_copy (dest, src2); + } + else if (eel_drect_is_empty (src2)) + { + eel_drect_copy (dest, src1); + } + else + { + dest->x0 = MIN (src1->x0, src2->x0); + dest->y0 = MIN (src1->y0, src2->y0); + dest->x1 = MAX (src1->x1, src2->x1); + dest->y1 = MAX (src1->y1, src2->y1); + } +} + + +/** + * eel_irect_contains_point: + * + * @rectangle: An EelIRect. + * @x: X coordinate to test. + * @y: Y coordinate to test. + * + * Returns: A boolean value indicating whether the rectangle + * contains the x,y coordinate. + * + */ +gboolean +eel_irect_contains_point (EelIRect rectangle, + int x, + int y) +{ + return x >= rectangle.x0 + && x <= rectangle.x1 + && y >= rectangle.y0 + && y <= rectangle.y1; +} + +gboolean +eel_irect_hits_irect (EelIRect rectangle_a, + EelIRect rectangle_b) +{ + EelIRect intersection; + eel_irect_intersect (&intersection, &rectangle_a, &rectangle_b); + return !eel_irect_is_empty (&intersection); +} + +gboolean +eel_irect_equal (EelIRect rectangle_a, + EelIRect rectangle_b) +{ + return rectangle_a.x0 == rectangle_b.x0 + && rectangle_a.y0 == rectangle_b.y0 + && rectangle_a.x1 == rectangle_b.x1 + && rectangle_a.y1 == rectangle_b.y1; +} + +/** + * eel_irect_align: + * + * @container: The rectangle that is to contain the aligned rectangle. + * @aligned_width: Width of rectangle being algined. + * @aligned_height: Height of rectangle being algined. + * @x_alignment: X alignment. + * @y_alignment: Y alignment. + * + * Returns: A rectangle aligned within a container rectangle + * using the given alignment parameters. + */ +EelIRect +eel_irect_align (EelIRect container, + int aligned_width, + int aligned_height, + float x_alignment, + float y_alignment) +{ + EelIRect aligned; + int available_width; + int available_height; + + if (eel_irect_is_empty (&container)) + { + return eel_irect_empty; + } + + if (aligned_width == 0 || aligned_height == 0) + { + return eel_irect_empty; + } + + /* Make sure the aligment parameters are within range */ + x_alignment = MAX (0, x_alignment); + x_alignment = MIN (1.0, x_alignment); + y_alignment = MAX (0, y_alignment); + y_alignment = MIN (1.0, y_alignment); + + available_width = eel_irect_get_width (container) - aligned_width; + available_height = eel_irect_get_height (container) - aligned_height; + + aligned.x0 = floor (container.x0 + (available_width * x_alignment) + 0.5); + aligned.y0 = floor (container.y0 + (available_height * y_alignment) + 0.5); + aligned.x1 = aligned.x0 + aligned_width; + aligned.y1 = aligned.y0 + aligned_height; + + return aligned; +} + + +/** + * eel_dimensions_are_empty: + * + * @dimensions: A EelDimensions structure. + * + * Returns: Whether the dimensions are empty. + */ +gboolean +eel_dimensions_are_empty (EelDimensions dimensions) +{ + return dimensions.width <= 0 || dimensions.height <= 0; +} + +EelIRect +eel_irect_offset_by (EelIRect rectangle, int x, int y) +{ + rectangle.x0 += x; + rectangle.x1 += x; + rectangle.y0 += y; + rectangle.y1 += y; + + return rectangle; +} + +EelIRect +eel_irect_scale_by (EelIRect rectangle, double scale) +{ + rectangle.x0 *= scale; + rectangle.x1 *= scale; + rectangle.y0 *= scale; + rectangle.y1 *= scale; + + return rectangle; +} diff --git a/eel/eel-art-extensions.h b/eel/eel-art-extensions.h new file mode 100644 index 00000000..67f5aa04 --- /dev/null +++ b/eel/eel-art-extensions.h @@ -0,0 +1,120 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* eel-art-extensions.h - interface of libart extension functions. + + Copyright (C) 2000 Eazel, Inc. + + The Mate Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Mate Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Mate Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Authors: Darin Adler + Ramiro Estrugo +*/ + +#ifndef EEL_ART_EXTENSIONS_H +#define EEL_ART_EXTENSIONS_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + typedef struct + { + double x, y; + } EelDPoint; + + typedef struct + { + int x; + int y; + } EelIPoint; + + typedef struct + { + double x0, y0, x1, y1; + } EelDRect; + + typedef struct + { + /*< public >*/ + int x0, y0, x1, y1; + } EelIRect; + + typedef struct + { + int width; + int height; + } EelDimensions; + + extern const EelDRect eel_drect_empty; + extern const EelIRect eel_irect_empty; + extern const EelIPoint eel_ipoint_max; + extern const EelIPoint eel_ipoint_min; + extern const EelIPoint eel_ipoint_zero; + extern const EelDimensions eel_dimensions_empty; + + void eel_irect_copy (EelIRect *dest, + const EelIRect *src); + void eel_irect_union (EelIRect *dest, + const EelIRect *src1, + const EelIRect *src2); + void eel_irect_intersect (EelIRect *dest, + const EelIRect *src1, + const EelIRect *src2); + gboolean eel_irect_equal (EelIRect rectangle_a, + EelIRect rectangle_b); + gboolean eel_irect_hits_irect (EelIRect rectangle_a, + EelIRect rectangle_b); + EelIRect eel_irect_offset_by (EelIRect rectangle, + int x, + int y); + EelIRect eel_irect_scale_by (EelIRect rectangle, + double scale); + gboolean eel_irect_is_empty (const EelIRect *rectangle); + gboolean eel_irect_contains_point (EelIRect outer_rectangle, + int x, + int y); + EelIRect eel_irect_assign (int x, + int y, + int width, + int height); + EelIRect eel_irect_assign_dimensions (int x, + int y, + EelDimensions dimensions); + int eel_irect_get_width (EelIRect rectangle); + int eel_irect_get_height (EelIRect rectangle); + EelIRect eel_irect_align (EelIRect container, + int aligned_width, + int aligned_height, + float x_alignment, + float y_alignment); + + + void eel_drect_union (EelDRect *dest, + const EelDRect *src1, + const EelDRect *src2); + + + /* EelDimensions functions. */ + gboolean eel_dimensions_are_empty (EelDimensions dimensions); + + +#ifdef __cplusplus +} +#endif + +#endif /* EEL_ART_EXTENSIONS_H */ diff --git a/eel/eel-art-gtk-extensions.c b/eel/eel-art-gtk-extensions.c new file mode 100644 index 00000000..f3ccef3c --- /dev/null +++ b/eel/eel-art-gtk-extensions.c @@ -0,0 +1,346 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* eel-eel-gtk-extensions.c - Access gtk/gdk attributes as libeel rectangles. + + Copyright (C) 2000 Eazel, Inc. + + The Mate Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Mate Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PEELICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Mate Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Authors: Ramiro Estrugo +*/ + +#include + +#include "eel-art-gtk-extensions.h" +#include + +/** + * eel_gdk_rectangle_to_eel_irect: + * @gdk_rectangle: The source GdkRectangle. + * + * Return value: An EelIRect representation of the GdkRectangle. + * + * This is a very simple conversion of rectangles from the Gdk to the Libeel + * universe. This is useful in code that does clipping (or other operations) + * using libeel and has a GdkRectangle to work with - for example expose_event() + * in GtkWidget's. + */ +EelIRect +eel_gdk_rectangle_to_eel_irect (GdkRectangle gdk_rectangle) +{ + EelIRect rectangle; + + rectangle.x0 = gdk_rectangle.x; + rectangle.y0 = gdk_rectangle.y; + rectangle.x1 = rectangle.x0 + (int) gdk_rectangle.width; + rectangle.y1 = rectangle.y0 + (int) gdk_rectangle.height; + + return rectangle; +} + +/** + * eel_screen_get_dimensions: + * + * Return value: The screen dimensions. + * + */ +EelDimensions +eel_screen_get_dimensions (void) +{ + EelDimensions screen_dimensions; + + screen_dimensions.width = gdk_screen_width (); + screen_dimensions.height = gdk_screen_height (); + + g_assert (screen_dimensions.width > 0); + g_assert (screen_dimensions.height > 0); + + return screen_dimensions; +} + +/** + * eel_gdk_window_get_bounds: + * @gdk_window: The source GdkWindow. + * + * Return value: An EelIRect representation of the given GdkWindow's geometry + * relative to its parent in the Gdk window hierarchy. + * + */ +EelIRect +eel_gdk_window_get_bounds (GdkWindow *gdk_window) +{ + EelIRect bounds; + int width; + int height; + + g_return_val_if_fail (gdk_window != NULL, eel_irect_empty); + + gdk_window_get_position (gdk_window, &bounds.x0, &bounds.y0); + +#if GTK_CHECK_VERSION(3, 0, 0) + width = gdk_window_get_width(gdk_window); + height = gdk_window_get_height(gdk_window); +#else + gdk_drawable_get_size (gdk_window, &width, &height); +#endif + + + bounds.x1 = bounds.x0 + width; + bounds.y1 = bounds.y0 + height; + + return bounds; +} + +/** + * eel_gdk_window_get_bounds: + * @gdk_window: The source GdkWindow. + * + * Return value: An EelIRect representation of the given GdkWindow's geometry + * relative to the screen. + * + */ +EelIRect +eel_gdk_window_get_screen_relative_bounds (GdkWindow *gdk_window) +{ + EelIRect screen_bounds; + int width; + int height; + + g_return_val_if_fail (gdk_window != NULL, eel_irect_empty); + + if (!gdk_window_get_origin (gdk_window, + &screen_bounds.x0, + &screen_bounds.y0)) + { + return eel_irect_empty; + } + +#if GTK_CHECK_VERSION(3, 0, 0) + width = gdk_window_get_width(gdk_window); + height = gdk_window_get_height(gdk_window); +#else + gdk_drawable_get_size(gdk_window, &width, &height); +#endif + + screen_bounds.x1 = screen_bounds.x0 + width; + screen_bounds.y1 = screen_bounds.y0 + height; + + return screen_bounds; +} + +/** + * eel_gtk_widget_get_bounds: + * @gtk_widget: The source GtkWidget. + * + * Return value: An EelIRect representation of the given GtkWidget's geometry + * relative to its parent. In the Gtk universe this is known as "allocation." + * + */ +EelIRect +eel_gtk_widget_get_bounds (GtkWidget *gtk_widget) +{ + GtkAllocation allocation; + g_return_val_if_fail (GTK_IS_WIDGET (gtk_widget), eel_irect_empty); + + gtk_widget_get_allocation (gtk_widget, &allocation); + return eel_irect_assign (allocation.x, + allocation.y, + (int) allocation.width, + (int) allocation.height); +} + +/** + * eel_gtk_widget_get_dimensions: + * @gtk_widget: The source GtkWidget. + * + * Return value: The widget's dimensions. The returned dimensions are only valid + * after the widget's geometry has been "allocated" by its container. + */ +EelDimensions +eel_gtk_widget_get_dimensions (GtkWidget *gtk_widget) +{ + EelDimensions dimensions; + GtkAllocation allocation; + + g_return_val_if_fail (GTK_IS_WIDGET (gtk_widget), eel_dimensions_empty); + + gtk_widget_get_allocation (gtk_widget, &allocation); + dimensions.width = (int) allocation.width; + dimensions.height = (int) allocation.height; + + return dimensions; +} + +/** + * eel_gtk_widget_get_preferred_dimensions: + * @gtk_widget: The source GtkWidget. + * + * Return value: The widget's preferred dimensions. The preferred dimensions are + * computed by calling the widget's 'size_request' method and thus + * could potentially be expensive for complicated widgets. + */ +EelDimensions +eel_gtk_widget_get_preferred_dimensions (GtkWidget *gtk_widget) +{ + GtkRequisition requisition; + EelDimensions preferred_dimensions; + + g_return_val_if_fail (GTK_IS_WIDGET (gtk_widget), eel_dimensions_empty); + + gtk_widget_size_request (gtk_widget, &requisition); + + preferred_dimensions.width = (int) requisition.width; + preferred_dimensions.height = (int) requisition.height; + + return preferred_dimensions; +} + +/** + * eel_gdk_window_clip_dirty_area_to_screen: + * @gdk_window: The GdkWindow that the damage occured on. + * @dirty_area: The dirty area as an EelIRect. + * + * Return value: An EelIRect of the dirty area clipped to the screen. + * + * This function is useful to do less work in expose_event() GtkWidget methods. + * It also ensures that any drawing that the widget does is actually onscreen. + */ +EelIRect +eel_gdk_window_clip_dirty_area_to_screen (GdkWindow *gdk_window, + EelIRect dirty_area) +{ + EelIRect clipped; + EelDimensions screen_dimensions; + EelIRect screen_relative_bounds; + int dirty_width; + int dirty_height; + + g_return_val_if_fail (gdk_window != NULL, eel_irect_empty); + + dirty_width = dirty_area.x1 - dirty_area.x0; + dirty_height = dirty_area.y1 - dirty_area.y0; + + g_return_val_if_fail (dirty_width > 0, eel_irect_empty); + g_return_val_if_fail (dirty_height > 0, eel_irect_empty); + + screen_dimensions = eel_screen_get_dimensions (); + screen_relative_bounds = eel_gdk_window_get_screen_relative_bounds (gdk_window); + + /* Window is obscured by left edge of screen */ + if ((screen_relative_bounds.x0 + dirty_area.x0) < 0) + { + int clipped_width = screen_relative_bounds.x0 + dirty_area.x0 + dirty_width; + clipped.x0 = dirty_area.x0 + dirty_width - clipped_width; + clipped.x1 = clipped.x0 + clipped_width; + } + else + { + clipped.x0 = dirty_area.x0; + clipped.x1 = clipped.x0 + dirty_width; + } + + /* Window is obscured by right edge of screen */ + if (screen_relative_bounds.x1 > screen_dimensions.width) + { + int obscured_width; + + obscured_width = + screen_relative_bounds.x0 + dirty_area.x0 + dirty_width - screen_dimensions.width; + + if (obscured_width > 0) + { + clipped.x1 -= obscured_width; + } + } + + /* Window is obscured by top edge of screen */ + if ((screen_relative_bounds.y0 + dirty_area.y0) < 0) + { + int clipped_height = screen_relative_bounds.y0 + dirty_area.y0 + dirty_height; + clipped.y0 = dirty_area.y0 + dirty_height - clipped_height; + clipped.y1 = clipped.y0 + clipped_height; + } + else + { + clipped.y0 = dirty_area.y0; + clipped.y1 = clipped.y0 + dirty_height; + } + + /* Window is obscured by bottom edge of screen */ + if (screen_relative_bounds.y1 > screen_dimensions.height) + { + int obscured_height; + + obscured_height = + screen_relative_bounds.y0 + dirty_area.y0 + dirty_height - screen_dimensions.height; + + if (obscured_height > 0) + { + clipped.y1 -= obscured_height; + } + } + + if (eel_irect_is_empty (&clipped)) + { + clipped = eel_irect_empty; + } + + return clipped; +} + +GdkRectangle +eel_irect_to_gdk_rectangle (EelIRect rectangle) +{ + GdkRectangle gdk_rect; + + gdk_rect.x = rectangle.x0; + gdk_rect.y = rectangle.y0; + gdk_rect.width = eel_irect_get_width (rectangle); + gdk_rect.height = eel_irect_get_height (rectangle); + + return gdk_rect; +} + +EelDimensions +eel_gdk_window_get_dimensions (GdkWindow *gdk_window) +{ + EelDimensions dimensions; + + g_return_val_if_fail (gdk_window != NULL, eel_dimensions_empty); + +#if GTK_CHECK_VERSION(3, 0, 0) + dimensions.width = gdk_window_get_width(gdk_window); + dimensions.height = gdk_window_get_height(gdk_window); +#else + gdk_drawable_get_size (gdk_window, &dimensions.width, &dimensions.height); +#endif + + return dimensions; +} + +EelIPoint +eel_gdk_get_pointer_position (void) +{ + + EelIPoint position; + + gdk_window_get_pointer (gdk_get_default_root_window (), + &position.x, + &position.y, + NULL); + + return position; +} diff --git a/eel/eel-art-gtk-extensions.h b/eel/eel-art-gtk-extensions.h new file mode 100644 index 00000000..3ad24f2d --- /dev/null +++ b/eel/eel-art-gtk-extensions.h @@ -0,0 +1,74 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* eel-art-gtk-extensions.h - Access gtk/gdk attributes as libart rectangles. + + Copyright (C) 2000 Eazel, Inc. + + The Mate Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Mate Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Mate Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Authors: Ramiro Estrugo +*/ + +/* The following functions accept gtk/gdk structures and + * return their bounds and dimensions, where: + * + * bounds: The (x,y) and (width, height) of something. + * dimensions: The (width, height) of something. + * + * These are very useful in code that uses libart functions + * to do operations on ArtIRects (such as intersection) + */ + +#ifndef EEL_ART_GTK_EXTENSIONS_H +#define EEL_ART_GTK_EXTENSIONS_H + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + + /* Convert between GdkRectangle and EelIRect and back */ + GdkRectangle eel_irect_to_gdk_rectangle (EelIRect rectangle); + EelIRect eel_gdk_rectangle_to_eel_irect (GdkRectangle gdk_rectangle); + EelDimensions eel_screen_get_dimensions (void); + + /* GdkWindow parent-relative bounds */ + EelIRect eel_gdk_window_get_bounds (GdkWindow *window); + + /* GdkWindow dimensions */ + EelDimensions eel_gdk_window_get_dimensions (GdkWindow *window); + + /* GdkWindow screen parent-relative bounds */ + EelIRect eel_gdk_window_get_screen_relative_bounds (GdkWindow *window); + + /* Clip a dirty area (from exposures) to the on screen parts of a GdkWindow */ + EelIRect eel_gdk_window_clip_dirty_area_to_screen (GdkWindow *window, + EelIRect dirty_area); + + /* GtkWidget bounds and dimensions */ + EelIRect eel_gtk_widget_get_bounds (GtkWidget *widget); + EelDimensions eel_gtk_widget_get_dimensions (GtkWidget *widget); + EelDimensions eel_gtk_widget_get_preferred_dimensions (GtkWidget *widget); + EelIPoint eel_gdk_get_pointer_position (void); + +#ifdef __cplusplus +} +#endif + +#endif /* EEL_ART_GTK_EXTENSIONS_H */ diff --git a/eel/eel-background-box.c b/eel/eel-background-box.c new file mode 100644 index 00000000..614d89ab --- /dev/null +++ b/eel/eel-background-box.c @@ -0,0 +1,70 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* eel-background-box.c - an event box that renders an eel background + + Copyright (C) 2002 Sun Microsystems, Inc. + + The Mate Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Mate Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Mate Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Dave Camp +*/ + +#include +#include "eel-background-box.h" + +#include "eel-gtk-macros.h" +#include "eel-background.h" + +static void eel_background_box_class_init (EelBackgroundBoxClass *background_box_class); +static void eel_background_box_init (EelBackgroundBox *background); + +EEL_CLASS_BOILERPLATE (EelBackgroundBox, eel_background_box, GTK_TYPE_EVENT_BOX) + +static gboolean +eel_background_box_expose_event (GtkWidget *widget, + GdkEventExpose *event) +{ + eel_background_expose (widget, event); + + gtk_container_propagate_expose (GTK_CONTAINER (widget), + gtk_bin_get_child (GTK_BIN (widget)), + event); + + return TRUE; +} + +static void +eel_background_box_class_init (EelBackgroundBoxClass *klass) +{ + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + + widget_class->expose_event = eel_background_box_expose_event; +} + +static void +eel_background_box_init (EelBackgroundBox *box) +{ +} + +GtkWidget* +eel_background_box_new (void) +{ + EelBackgroundBox *background_box; + + background_box = EEL_BACKGROUND_BOX (gtk_widget_new (eel_background_box_get_type (), NULL)); + + return GTK_WIDGET (background_box); +} diff --git a/eel/eel-background-box.h b/eel/eel-background-box.h new file mode 100644 index 00000000..849f5ebf --- /dev/null +++ b/eel/eel-background-box.h @@ -0,0 +1,71 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* eel-background-box.c - an event box that renders an eel background + + Copyright (C) 2002 Sun Microsystems, Inc. + + The Mate Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Mate Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Mate Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Dave Camp +*/ + +#ifndef EEL_BACKGROUND_BOX_H +#define EEL_BACKGROUND_BOX_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define EEL_TYPE_BACKGROUND_BOX eel_background_box_get_type() +#define EEL_BACKGROUND_BOX(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEL_TYPE_BACKGROUND_BOX, EelBackgroundBox)) +#define EEL_BACKGROUND_BOX_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), EEL_TYPE_BACKGROUND_BOX, EelBackgroundBoxClass)) +#define EEL_IS_BACKGROUND_BOX(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEL_TYPE_BACKGROUND_BOX)) +#define EEL_IS_BACKGROUND_BOX_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), EEL_TYPE_BACKGROUND_BOX)) +#define EEL_BACKGROUND_BOX_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), EEL_TYPE_BACKGROUND_BOX, EelBackgroundBoxClass)) + + typedef struct EelBackgroundBox EelBackgroundBox; + typedef struct EelBackgroundBoxClass EelBackgroundBoxClass; + typedef struct EelBackgroundBoxDetails EelBackgroundBoxDetails; + + struct EelBackgroundBox + { + /* Superclass */ + GtkEventBox event_box; + }; + + struct EelBackgroundBoxClass + { + GtkEventBoxClass parent_class; + }; + + GType eel_background_box_get_type (void); + GtkWidget *eel_background_box_new (void); + +#ifdef __cplusplus +} +#endif + +#endif /* EEL_BACKGROUND_TABLE_H */ + + diff --git a/eel/eel-background.c b/eel/eel-background.c new file mode 100644 index 00000000..4d12b37f --- /dev/null +++ b/eel/eel-background.c @@ -0,0 +1,1273 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- + + eel-background.c: Object for the background of a widget. + + Copyright (C) 2000 Eazel, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this program; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Darin Adler +*/ + +#include +#include "eel-background.h" +#include "eel-gdk-extensions.h" +#include "eel-gdk-pixbuf-extensions.h" +#include "eel-glib-extensions.h" +#include "eel-mate-extensions.h" +#include "eel-gtk-macros.h" +#include "eel-lib-self-check-functions.h" +#include "eel-string.h" +#include "eel-marshal.h" +#include "eel-types.h" +#include "eel-type-builtins.h" +#include +#include +#include +#include +#include +#include +#include +#define MATE_DESKTOP_USE_UNSTABLE_API +#include + +static void eel_background_class_init (gpointer klass); +static void eel_background_init (gpointer object, + gpointer klass); +static void eel_background_finalize (GObject *object); +static GdkPixmap *eel_background_get_pixmap_and_color (EelBackground *background, + GdkWindow *window, + GdkColor *color); + +static void set_image_properties (EelBackground *background); + +static void init_fade (EelBackground *background, GtkWidget *widget); +static void free_fade (EelBackground *background); + +EEL_CLASS_BOILERPLATE (EelBackground, eel_background, GTK_TYPE_OBJECT) + +enum +{ + APPEARANCE_CHANGED, + SETTINGS_CHANGED, + RESET, + LAST_SIGNAL +}; + +/* This is the size of the GdkRGB dither matrix, in order to avoid + * bad dithering when tiling the gradient + */ +#define GRADIENT_PIXMAP_TILE_SIZE 128 + +static guint signals[LAST_SIGNAL]; + +struct EelBackgroundDetails +{ + char *color; + + MateBG *bg; + GtkWidget *widget; + + /* Realized data: */ + GdkPixmap *background_pixmap; + gboolean background_pixmap_is_unset_root_pixmap; + MateBGCrossfade *fade; + int background_entire_width; + int background_entire_height; + GdkColor default_color; + + gboolean use_base; + + /* Is this background attached to desktop window */ + gboolean is_desktop; + /* Desktop screen size watcher */ + gulong screen_size_handler; + /* Desktop monitors configuration watcher */ + gulong screen_monitors_handler; + /* Can we use common pixmap for root window and desktop window */ + gboolean use_common_pixmap; + guint change_idle_id; + + /* activity status */ + gboolean is_active; +}; + +static void +eel_background_class_init (gpointer klass) +{ + GObjectClass *object_class; + + object_class = G_OBJECT_CLASS (klass); + + eel_type_init (); + + signals[APPEARANCE_CHANGED] = + g_signal_new ("appearance_changed", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE, + G_STRUCT_OFFSET (EelBackgroundClass, + appearance_changed), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); + signals[SETTINGS_CHANGED] = + g_signal_new ("settings_changed", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE, + G_STRUCT_OFFSET (EelBackgroundClass, + settings_changed), + NULL, NULL, + g_cclosure_marshal_VOID__INT, + G_TYPE_NONE, + 1, G_TYPE_INT); + signals[RESET] = + g_signal_new ("reset", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE, + G_STRUCT_OFFSET (EelBackgroundClass, + reset), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); + + object_class->finalize = eel_background_finalize; +} + +static void +on_bg_changed (MateBG *bg, EelBackground *background) +{ + init_fade (background, background->details->widget); + g_signal_emit (G_OBJECT (background), + signals[APPEARANCE_CHANGED], 0); +} + +static void +on_bg_transitioned (MateBG *bg, EelBackground *background) +{ + free_fade (background); + g_signal_emit (G_OBJECT (background), + signals[APPEARANCE_CHANGED], 0); +} + +static void +eel_background_init (gpointer object, gpointer klass) +{ + EelBackground *background; + + background = EEL_BACKGROUND (object); + + background->details = g_new0 (EelBackgroundDetails, 1); + background->details->default_color.red = 0xffff; + background->details->default_color.green = 0xffff; + background->details->default_color.blue = 0xffff; + background->details->bg = mate_bg_new (); + background->details->is_active = TRUE; + + g_signal_connect (background->details->bg, "changed", + G_CALLBACK (on_bg_changed), background); + g_signal_connect (background->details->bg, "transitioned", + G_CALLBACK (on_bg_transitioned), background); + +} + +/* The safe way to clear an image from a background is: + * eel_background_set_image_uri (NULL); + * This fn is a private utility - it does NOT clear + * the details->bg_uri setting. + */ +static void +eel_background_remove_current_image (EelBackground *background) +{ + if (background->details->bg != NULL) + { + g_object_unref (G_OBJECT (background->details->bg)); + background->details->bg = NULL; + } +} + +static void +free_fade (EelBackground *background) +{ + if (background->details->fade != NULL) + { + g_object_unref (background->details->fade); + background->details->fade = NULL; + } +} + +static void +free_background_pixmap (EelBackground *background) +{ + GdkDisplay *display; + GdkPixmap *pixmap; + + pixmap = background->details->background_pixmap; + if (pixmap != NULL) + { + /* If we created a root pixmap and didn't set it as background + it will live forever, so we need to kill it manually. + If set as root background it will be killed next time the + background is changed. */ + if (background->details->background_pixmap_is_unset_root_pixmap) + { + display = gdk_drawable_get_display (GDK_DRAWABLE (pixmap)); + XKillClient (GDK_DISPLAY_XDISPLAY (display), + GDK_PIXMAP_XID (pixmap)); + } + g_object_unref (pixmap); + background->details->background_pixmap = NULL; + } +} + + +static void +eel_background_finalize (GObject *object) +{ + EelBackground *background; + + background = EEL_BACKGROUND (object); + + g_free (background->details->color); + eel_background_remove_current_image (background); + + free_background_pixmap (background); + + free_fade (background); + + g_free (background->details); + + EEL_CALL_PARENT (G_OBJECT_CLASS, finalize, (object)); +} + +static EelBackgroundImagePlacement +placement_mate_to_eel (MateBGPlacement p) +{ + switch (p) + { + case MATE_BG_PLACEMENT_CENTERED: + return EEL_BACKGROUND_CENTERED; + case MATE_BG_PLACEMENT_FILL_SCREEN: + return EEL_BACKGROUND_SCALED; + case MATE_BG_PLACEMENT_SCALED: + return EEL_BACKGROUND_SCALED_ASPECT; + case MATE_BG_PLACEMENT_ZOOMED: + return EEL_BACKGROUND_ZOOM; + case MATE_BG_PLACEMENT_TILED: + return EEL_BACKGROUND_TILED; + case MATE_BG_PLACEMENT_SPANNED: + return EEL_BACKGROUND_SPANNED; + } + + return EEL_BACKGROUND_TILED; +} + +static MateBGPlacement +placement_eel_to_mate (EelBackgroundImagePlacement p) +{ + switch (p) + { + case EEL_BACKGROUND_CENTERED: + return MATE_BG_PLACEMENT_CENTERED; + case EEL_BACKGROUND_SCALED: + return MATE_BG_PLACEMENT_FILL_SCREEN; + case EEL_BACKGROUND_SCALED_ASPECT: + return MATE_BG_PLACEMENT_SCALED; + case EEL_BACKGROUND_ZOOM: + return MATE_BG_PLACEMENT_ZOOMED; + case EEL_BACKGROUND_TILED: + return MATE_BG_PLACEMENT_TILED; + case EEL_BACKGROUND_SPANNED: + return MATE_BG_PLACEMENT_SPANNED; + } + + return MATE_BG_PLACEMENT_TILED; +} + +EelBackgroundImagePlacement +eel_background_get_image_placement (EelBackground *background) +{ + g_return_val_if_fail (EEL_IS_BACKGROUND (background), EEL_BACKGROUND_TILED); + + return placement_mate_to_eel (mate_bg_get_placement (background->details->bg)); +} + +void +eel_background_set_image_placement (EelBackground *background, + EelBackgroundImagePlacement new_placement) +{ + g_return_if_fail (EEL_IS_BACKGROUND (background)); + + mate_bg_set_placement (background->details->bg, + placement_eel_to_mate (new_placement)); +} + +EelBackground * +eel_background_new (void) +{ + return EEL_BACKGROUND (g_object_new (EEL_TYPE_BACKGROUND, NULL)); +} + +static void +eel_background_unrealize (EelBackground *background) +{ + free_background_pixmap (background); + + background->details->background_entire_width = 0; + background->details->background_entire_height = 0; + background->details->default_color.red = 0xffff; + background->details->default_color.green = 0xffff; + background->details->default_color.blue = 0xffff; +} + +static void +drawable_get_adjusted_size (EelBackground *background, + GdkDrawable *drawable, + int *width, + int *height) +{ + GdkScreen *screen; + + /* + * Screen resolution change makes root drawable have incorrect size. + */ +#if GTK_CHECK_VERSION(3, 0, 0) + width = gdk_window_get_width(GDK_WINDOW(drawable)); + height = gdk_window_get_height(GDK_WINDOW(drawable)); +#else + gdk_drawable_get_size(drawable, width, height); // FIXME: this is right? +#endif + + + if (background->details->is_desktop) + { + screen = gdk_drawable_get_screen (drawable); + *width = gdk_screen_get_width (screen); + *height = gdk_screen_get_height (screen); + } +} + +static gboolean +eel_background_ensure_realized (EelBackground *background, GdkWindow *window) +{ + gpointer data; + GtkWidget *widget; + GtkStyle *style; + gboolean changed; + int entire_width; + int entire_height; + + drawable_get_adjusted_size (background, window, &entire_width, &entire_height); + + /* Set the default color */ + + /* Get the widget to which the window belongs and its style as well */ + gdk_window_get_user_data (window, &data); + widget = GTK_WIDGET (data); + if (widget != NULL) + { + style = gtk_widget_get_style (widget); + if (background->details->use_base) + { + background->details->default_color = style->base[GTK_STATE_NORMAL]; + } + else + { + background->details->default_color = style->bg[GTK_STATE_NORMAL]; + } + + gdk_rgb_find_color (style->colormap, &(background->details->default_color)); + } + + /* If the window size is the same as last time, don't update */ + if (entire_width == background->details->background_entire_width && + entire_height == background->details->background_entire_height) + { + return FALSE; + } + + free_background_pixmap (background); + + changed = FALSE; + + set_image_properties (background); + + background->details->background_pixmap = mate_bg_create_pixmap (background->details->bg, + window, + entire_width, entire_height, + background->details->is_desktop); + background->details->background_pixmap_is_unset_root_pixmap = background->details->is_desktop; + + /* We got the pixmap and everything, so we don't care about a change + that is pending (unless things actually change after this time) */ + g_object_set_data (G_OBJECT (background->details->bg), + "ignore-pending-change", GINT_TO_POINTER (TRUE)); + changed = TRUE; + + + background->details->background_entire_width = entire_width; + background->details->background_entire_height = entire_height; + + return changed; +} + +#define CLAMP_COLOR(v) (t = (v), CLAMP (t, 0, G_MAXUSHORT)) +#define SATURATE(v) ((1.0 - saturation) * intensity + saturation * (v)) + +static void +make_color_inactive (EelBackground *background, GdkColor *color) +{ + double intensity, saturation; + gushort t; + + if (!background->details->is_active) + { + saturation = 0.7; + intensity = color->red * 0.30 + color->green * 0.59 + color->blue * 0.11; + color->red = SATURATE (color->red); + color->green = SATURATE (color->green); + color->blue = SATURATE (color->blue); + + if (intensity > G_MAXUSHORT / 2) + { + color->red *= 0.9; + color->green *= 0.9; + color->blue *= 0.9; + } + else + { + color->red *= 1.25; + color->green *= 1.25; + color->blue *= 1.25; + } + + color->red = CLAMP_COLOR (color->red); + color->green = CLAMP_COLOR (color->green); + color->blue = CLAMP_COLOR (color->blue); + } +} + +static GdkPixmap * +eel_background_get_pixmap_and_color (EelBackground *background, + GdkWindow *window, + GdkColor *color) +{ + int entire_width; + int entire_height; + + drawable_get_adjusted_size (background, window, &entire_width, &entire_height); + + eel_background_ensure_realized (background, window); + + *color = background->details->default_color; + make_color_inactive (background, color); + + if (background->details->background_pixmap != NULL) + { + return g_object_ref (background->details->background_pixmap); + } + return NULL; +} + +void +eel_background_expose (GtkWidget *widget, + GdkEventExpose *event) +{ + GdkColor color; + int window_width; + int window_height; + GdkPixmap *pixmap; + GdkGC *gc; + GdkGCValues gc_values; + GdkGCValuesMask value_mask; + GdkWindow *widget_window; + + EelBackground *background; + + widget_window = gtk_widget_get_window (widget); + if (event->window != widget_window) + { + return; + } + + background = eel_get_widget_background (widget); + + drawable_get_adjusted_size (background, widget_window, &window_width, &window_height); + + pixmap = eel_background_get_pixmap_and_color (background, + widget_window, + &color); + + if (pixmap) + { + gc_values.tile = pixmap; + gc_values.ts_x_origin = 0; + gc_values.ts_y_origin = 0; + gc_values.fill = GDK_TILED; + value_mask = GDK_GC_FILL | GDK_GC_TILE | GDK_GC_TS_X_ORIGIN | GDK_GC_TS_Y_ORIGIN; + } + else + { + gdk_rgb_find_color (gtk_widget_get_colormap (widget), &color); + gc_values.foreground = color; + gc_values.fill = GDK_SOLID; + value_mask = GDK_GC_FILL | GDK_GC_FOREGROUND; + } + + gc = gdk_gc_new_with_values (widget_window, &gc_values, value_mask); + + gdk_gc_set_clip_rectangle (gc, &event->area); + + gdk_draw_rectangle (widget_window, gc, TRUE, 0, 0, window_width, window_height); + + g_object_unref (gc); + + if (pixmap) + { + g_object_unref (pixmap); + } +} + +static void +set_image_properties (EelBackground *background) +{ + GdkColor c; + if (!background->details->color) + { + c = background->details->default_color; + make_color_inactive (background, &c); + mate_bg_set_color (background->details->bg, MATE_BG_COLOR_SOLID, + &c, NULL); + } + else if (!eel_gradient_is_gradient (background->details->color)) + { + eel_gdk_color_parse_with_white_default (background->details->color, &c); + make_color_inactive (background, &c); + mate_bg_set_color (background->details->bg, MATE_BG_COLOR_SOLID, &c, NULL); + } + else + { + GdkColor c1; + GdkColor c2; + char *spec; + + spec = eel_gradient_get_start_color_spec (background->details->color); + eel_gdk_color_parse_with_white_default (spec, &c1); + make_color_inactive (background, &c1); + g_free (spec); + + spec = eel_gradient_get_end_color_spec (background->details->color); + eel_gdk_color_parse_with_white_default (spec, &c2); + make_color_inactive (background, &c2); + g_free (spec); + + if (eel_gradient_is_horizontal (background->details->color)) + mate_bg_set_color (background->details->bg, MATE_BG_COLOR_H_GRADIENT, &c1, &c2); + else + mate_bg_set_color (background->details->bg, MATE_BG_COLOR_V_GRADIENT, &c1, &c2); + + } +} + +char * +eel_background_get_color (EelBackground *background) +{ + g_return_val_if_fail (EEL_IS_BACKGROUND (background), NULL); + + return g_strdup (background->details->color); +} + +char * +eel_background_get_image_uri (EelBackground *background) +{ + const char *filename; + + g_return_val_if_fail (EEL_IS_BACKGROUND (background), NULL); + + filename = mate_bg_get_filename (background->details->bg); + if (filename) + { + return g_filename_to_uri (filename, NULL, NULL); + } + return NULL; +} + +/* Use style->base as the default color instead of bg */ +void +eel_background_set_use_base (EelBackground *background, + gboolean use_base) +{ + background->details->use_base = use_base; +} + +void +eel_background_set_color (EelBackground *background, + const char *color) +{ + if (eel_strcmp (background->details->color, color) != 0) + { + g_free (background->details->color); + background->details->color = g_strdup (color); + + set_image_properties (background); + } +} + +static gboolean +eel_background_set_image_uri_helper (EelBackground *background, + const char *image_uri, + gboolean emit_signal) +{ + char *filename; + + if (image_uri != NULL) + { + filename = g_filename_from_uri (image_uri, NULL, NULL); + } + else + { + filename = NULL; + } + + mate_bg_set_filename (background->details->bg, filename); + + if (emit_signal) + { + g_signal_emit (GTK_OBJECT (background), signals[SETTINGS_CHANGED], 0, GDK_ACTION_COPY); + } + + set_image_properties (background); + + g_free (filename); + + return TRUE; +} + +void +eel_background_set_image_uri (EelBackground *background, const char *image_uri) +{ + + + eel_background_set_image_uri_helper (background, image_uri, TRUE); +} + +/* Use this fn to set both the image and color and avoid flash. The color isn't + * changed till after the image is done loading, that way if an update occurs + * before then, it will use the old color and image. + */ +static void +eel_background_set_image_uri_and_color (EelBackground *background, GdkDragAction action, + const char *image_uri, const char *color) +{ + eel_background_set_image_uri_helper (background, image_uri, FALSE); + eel_background_set_color (background, color); + + /* We always emit, even if the color didn't change, because the image change + * relies on us doing it here. + */ + + g_signal_emit (background, signals[SETTINGS_CHANGED], 0, action); +} + +void +eel_background_receive_dropped_background_image (EelBackground *background, + GdkDragAction action, + const char *image_uri) +{ + /* Currently, we only support tiled images. So we set the placement. + * We rely on eel_background_set_image_uri_and_color to emit + * the SETTINGS_CHANGED & APPEARANCE_CHANGE signals. + */ + eel_background_set_image_placement (background, EEL_BACKGROUND_TILED); + + eel_background_set_image_uri_and_color (background, action, image_uri, NULL); +} + +/** + * eel_background_is_set: + * + * Check whether the background's color or image has been set. + */ +gboolean +eel_background_is_set (EelBackground *background) +{ + g_assert (EEL_IS_BACKGROUND (background)); + + return background->details->color != NULL + || mate_bg_get_filename (background->details->bg) != NULL; +} + +/** + * eel_background_reset: + * + * Emit the reset signal to forget any color or image that has been + * set previously. + */ +void +eel_background_reset (EelBackground *background) +{ + g_return_if_fail (EEL_IS_BACKGROUND (background)); + + g_signal_emit (GTK_OBJECT (background), signals[RESET], 0); +} + +static void +set_root_pixmap (EelBackground *background, + GdkWindow *window) +{ + GdkPixmap *pixmap, *root_pixmap; + GdkScreen *screen; + GdkColor color; + + pixmap = eel_background_get_pixmap_and_color (background, + window, + &color); + screen = gdk_drawable_get_screen (window); + + if (background->details->use_common_pixmap) + { + background->details->background_pixmap_is_unset_root_pixmap = FALSE; + root_pixmap = g_object_ref (pixmap); + } + else + { + root_pixmap = mate_bg_create_pixmap (background->details->bg, window, + gdk_screen_get_width (screen), gdk_screen_get_height (screen), TRUE); + } + + mate_bg_set_pixmap_as_root (screen, pixmap); + + g_object_unref (pixmap); + g_object_unref (root_pixmap); +} + +static gboolean +fade_to_pixmap (EelBackground *background, + GdkWindow *window, + GdkPixmap *pixmap) +{ + if (background->details->fade == NULL) + { + return FALSE; + } + + if (!mate_bg_crossfade_set_end_pixmap (background->details->fade, + pixmap)) + { + return FALSE; + } + + if (!mate_bg_crossfade_is_started (background->details->fade)) + { + mate_bg_crossfade_start (background->details->fade, window); + if (background->details->is_desktop) + { + g_signal_connect_swapped (background->details->fade, + "finished", + G_CALLBACK (set_root_pixmap), background); + } + } + + return mate_bg_crossfade_is_started (background->details->fade); +} + + +static void +eel_background_set_up_widget (EelBackground *background, GtkWidget *widget) +{ + GtkStyle *style; + GdkPixmap *pixmap; + GdkColor color; + + int window_width; + int window_height; + + GdkWindow *window; + GdkWindow *widget_window; + gboolean in_fade; + + if (!gtk_widget_get_realized (widget)) + { + return; + } + + widget_window = gtk_widget_get_window (widget); + drawable_get_adjusted_size (background, widget_window, &window_width, &window_height); + + pixmap = eel_background_get_pixmap_and_color (background, + widget_window, + &color); + + style = gtk_widget_get_style (widget); + + gdk_rgb_find_color (style->colormap, &color); + + if (EEL_IS_CANVAS (widget)) + { + window = gtk_layout_get_bin_window (GTK_LAYOUT (widget)); + } + else + { + window = widget_window; + } + + if (background->details->fade != NULL) + { + in_fade = fade_to_pixmap (background, window, pixmap); + } + else + { + in_fade = FALSE; + } + + if (!in_fade) + { + if (background->details->is_desktop) + { + gdk_window_set_back_pixmap (window, pixmap, FALSE); + } + else + { + gdk_window_set_background (window, &color); + gdk_window_set_back_pixmap (window, pixmap, FALSE); + } + } + + if (background->details->is_desktop && !in_fade) + { + set_root_pixmap (background, window); + } + + if (pixmap) + { + g_object_unref (pixmap); + } +} + +static gboolean +on_background_changed (EelBackground *background) +{ + if (background->details->change_idle_id == 0) + { + return FALSE; + } + + background->details->change_idle_id = 0; + + eel_background_unrealize (background); + eel_background_set_up_widget (background, background->details->widget); + + gtk_widget_queue_draw (background->details->widget); + + return FALSE; +} + +static void +init_fade (EelBackground *background, GtkWidget *widget) +{ + if (widget == NULL || !gtk_widget_get_realized (widget)) + return; + + if (!background->details->is_desktop) + { + return; + } + + if (background->details->fade == NULL) + { + GdkWindow *window; + int old_width, old_height, width, height; + + /* If this was the result of a screen size change, + * we don't want to crossfade + */ + window = gtk_widget_get_window (widget); + +#if GTK_CHECK_VERSION(3, 0, 0) + old_width = gdk_window_get_width(GDK_WINDOW(window)); + old_height = gdk_window_get_height(GDK_WINDOW(window)); +#else + gdk_drawable_get_size(window, &old_width, &old_height); +#endif + + drawable_get_adjusted_size (background, window, + &width, &height); + if (old_width == width && old_height == height) + { + background->details->fade = mate_bg_crossfade_new (width, height); + g_signal_connect_swapped (background->details->fade, + "finished", + G_CALLBACK (free_fade), + background); + } + } + + if (background->details->fade != NULL && !mate_bg_crossfade_is_started (background->details->fade)) + { + GdkPixmap *start_pixmap; + + if (background->details->background_pixmap == NULL) + { + start_pixmap = mate_bg_get_pixmap_from_root (gtk_widget_get_screen (widget)); + } + else + { + start_pixmap = g_object_ref (background->details->background_pixmap); + } + mate_bg_crossfade_set_start_pixmap (background->details->fade, + start_pixmap); + g_object_unref (start_pixmap); + } +} + +static void +eel_widget_queue_background_change (GtkWidget *widget) +{ + EelBackground *background; + + background = eel_get_widget_background (widget); + + if (background->details->change_idle_id > 0) + { + return; + } + + background->details->change_idle_id = g_idle_add ((GSourceFunc) on_background_changed, background); +} + +/* Callback used when the style of a widget changes. We have to regenerate its + * EelBackgroundStyle so that it will match the chosen GTK+ theme. + */ +static void +widget_style_set_cb (GtkWidget *widget, GtkStyle *previous_style, gpointer data) +{ + EelBackground *background; + + background = EEL_BACKGROUND (data); + + if (previous_style != NULL) + { + eel_widget_queue_background_change (widget); + } +} + +static void +screen_size_changed (GdkScreen *screen, EelBackground *background) +{ + g_signal_emit (background, signals[APPEARANCE_CHANGED], 0); +} + +static void +widget_realized_setup (GtkWidget *widget, gpointer data) +{ + EelBackground *background; + + background = EEL_BACKGROUND (data); + + if (background->details->is_desktop) + { + GdkWindow *root_window; + GdkScreen *screen; + + screen = gtk_widget_get_screen (widget); + + if (background->details->screen_size_handler > 0) + { + g_signal_handler_disconnect (screen, + background->details->screen_size_handler); + } + + background->details->screen_size_handler = + g_signal_connect (screen, "size_changed", + G_CALLBACK (screen_size_changed), background); + if (background->details->screen_monitors_handler > 0) + { + g_signal_handler_disconnect (screen, + background->details->screen_monitors_handler); + } + background->details->screen_monitors_handler = + g_signal_connect (screen, "monitors-changed", + G_CALLBACK (screen_size_changed), background); + + root_window = gdk_screen_get_root_window(screen); + +#if GTK_CHECK_VERSION(3, 0, 0) + if (gdk_window_get_visual(root_window) == gtk_widget_get_visual(widget)) +#else + if (gdk_drawable_get_visual(root_window) == gtk_widget_get_visual(widget)) +#endif + { + background->details->use_common_pixmap = TRUE; + } + else + { + background->details->use_common_pixmap = FALSE; + } + + init_fade (background, widget); + } +} + +static void +widget_realize_cb (GtkWidget *widget, gpointer data) +{ + EelBackground *background; + + background = EEL_BACKGROUND (data); + + widget_realized_setup (widget, data); + + eel_background_set_up_widget (background, widget); +} + +static void +widget_unrealize_cb (GtkWidget *widget, gpointer data) +{ + EelBackground *background; + + background = EEL_BACKGROUND (data); + + if (background->details->screen_size_handler > 0) + { + g_signal_handler_disconnect (gtk_widget_get_screen (GTK_WIDGET (widget)), + background->details->screen_size_handler); + background->details->screen_size_handler = 0; + } + if (background->details->screen_monitors_handler > 0) + { + g_signal_handler_disconnect (gtk_widget_get_screen (GTK_WIDGET (widget)), + background->details->screen_monitors_handler); + background->details->screen_monitors_handler = 0; + } + background->details->use_common_pixmap = FALSE; +} + +void +eel_background_set_desktop (EelBackground *background, GtkWidget *widget, gboolean is_desktop) +{ + background->details->is_desktop = is_desktop; + + if (gtk_widget_get_realized (widget) && background->details->is_desktop) + { + widget_realized_setup (widget, background); + } + +} + +gboolean +eel_background_is_desktop (EelBackground *background) +{ + return background->details->is_desktop; +} + +static void +on_widget_destroyed (GtkWidget *widget, EelBackground *background) +{ + if (background->details->change_idle_id != 0) + { + g_source_remove (background->details->change_idle_id); + background->details->change_idle_id = 0; + } + + background->details->widget = NULL; +} + +/* Gets the background attached to a widget. + + If the widget doesn't already have a EelBackground object, + this will create one. To change the widget's background, you can + just call eel_background methods on the widget. + + If the widget is a canvas, nothing more needs to be done. For + normal widgets, you need to call eel_background_expose() from your + expose handler to draw the background. + + Later, we might want a call to find out if we already have a background, + or a way to share the same background among multiple widgets; both would + be straightforward. +*/ +EelBackground * +eel_get_widget_background (GtkWidget *widget) +{ + gpointer data; + EelBackground *background; + + g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL); + + /* Check for an existing background. */ + data = g_object_get_data (G_OBJECT (widget), "eel_background"); + if (data != NULL) + { + g_assert (EEL_IS_BACKGROUND (data)); + return data; + } + + /* Store the background in the widget's data. */ + background = eel_background_new (); + g_object_ref_sink (background); + g_object_set_data_full (G_OBJECT (widget), "eel_background", + background, g_object_unref); + background->details->widget = widget; + g_signal_connect_object (widget, "destroy", G_CALLBACK (on_widget_destroyed), background, 0); + + /* Arrange to get the signal whenever the background changes. */ + g_signal_connect_object (background, "appearance_changed", + G_CALLBACK (eel_widget_queue_background_change), widget, G_CONNECT_SWAPPED); + eel_widget_queue_background_change (widget); + + g_signal_connect_object (widget, "style_set", + G_CALLBACK (widget_style_set_cb), + background, + 0); + g_signal_connect_object (widget, "realize", + G_CALLBACK (widget_realize_cb), + background, + 0); + g_signal_connect_object (widget, "unrealize", + G_CALLBACK (widget_unrealize_cb), + background, + 0); + + return background; +} + +/* determine if a background is darker or lighter than average, to help clients know what + colors to draw on top with */ +gboolean +eel_background_is_dark (EelBackground *background) +{ + GdkScreen *screen; + GdkRectangle rect; + + /* only check for the background on the 0th monitor */ + screen = gdk_screen_get_default (); + gdk_screen_get_monitor_geometry (screen, 0, &rect); + + return mate_bg_is_dark (background->details->bg, rect.width, rect.height); +} + +/* handle dropped colors */ +void +eel_background_receive_dropped_color (EelBackground *background, + GtkWidget *widget, + GdkDragAction action, + int drop_location_x, + int drop_location_y, + const GtkSelectionData *selection_data) +{ + guint16 *channels; + char *color_spec; + char *new_gradient_spec; + int left_border, right_border, top_border, bottom_border; + GtkAllocation allocation; + + g_return_if_fail (EEL_IS_BACKGROUND (background)); + g_return_if_fail (GTK_IS_WIDGET (widget)); + g_return_if_fail (selection_data != NULL); + + /* Convert the selection data into a color spec. */ + if (gtk_selection_data_get_length ((GtkSelectionData *) selection_data) != 8 || + gtk_selection_data_get_format ((GtkSelectionData *) selection_data) != 16) + { + g_warning ("received invalid color data"); + return; + } + channels = (guint16 *) gtk_selection_data_get_data ((GtkSelectionData *) selection_data); + color_spec = g_strdup_printf ("#%02X%02X%02X", + channels[0] >> 8, + channels[1] >> 8, + channels[2] >> 8); + + /* Figure out if the color was dropped close enough to an edge to create a gradient. + For the moment, this is hard-wired, but later the widget will have to have some + say in where the borders are. + */ + gtk_widget_get_allocation (widget, &allocation); + left_border = 32; + right_border = allocation.width - 32; + top_border = 32; + bottom_border = allocation.height - 32; + if (drop_location_x < left_border && drop_location_x <= right_border) + { + new_gradient_spec = eel_gradient_set_left_color_spec (background->details->color, color_spec); + } + else if (drop_location_x >= left_border && drop_location_x > right_border) + { + new_gradient_spec = eel_gradient_set_right_color_spec (background->details->color, color_spec); + } + else if (drop_location_y < top_border && drop_location_y <= bottom_border) + { + new_gradient_spec = eel_gradient_set_top_color_spec (background->details->color, color_spec); + } + else if (drop_location_y >= top_border && drop_location_y > bottom_border) + { + new_gradient_spec = eel_gradient_set_bottom_color_spec (background->details->color, color_spec); + } + else + { + new_gradient_spec = g_strdup (color_spec); + } + + g_free (color_spec); + + eel_background_set_image_uri_and_color (background, action, NULL, new_gradient_spec); + + g_free (new_gradient_spec); +} + +void +eel_background_save_to_mateconf (EelBackground *background) +{ + MateConfClient *client = mateconf_client_get_default (); + + if (background->details->bg) + mate_bg_save_to_preferences (background->details->bg, client); +} + +void +eel_background_set_active (EelBackground *background, + gboolean is_active) +{ + if (background->details->is_active != is_active) + { + background->details->is_active = is_active; + set_image_properties (background); + } +} + +/* self check code */ + +#if !defined (EEL_OMIT_SELF_CHECK) + +void +eel_self_check_background (void) +{ + EelBackground *background; + + background = eel_background_new (); + + eel_background_set_color (background, NULL); + eel_background_set_color (background, ""); + eel_background_set_color (background, "red"); + eel_background_set_color (background, "red-blue"); + eel_background_set_color (background, "red-blue:h"); + + g_object_ref_sink (background); + g_object_unref (background); +} + +#endif diff --git a/eel/eel-background.h b/eel/eel-background.h new file mode 100644 index 00000000..36a6c3f5 --- /dev/null +++ b/eel/eel-background.h @@ -0,0 +1,162 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- + + eel-background.h: Object for the background of a widget. + + Copyright (C) 2000 Eazel, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this program; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Authors: Darin Adler +*/ + +#ifndef EEL_BACKGROUND_H +#define EEL_BACKGROUND_H + +/* Windows for Eel can contain backgrounds that are either tiled + with an image, a solid color, or a color gradient. This class manages + the process of loading the image if necessary and parsing the string + that specifies either a color or color gradient. + + The color or gradient is always present, even if there's a tiled image + on top of it. This is used when the tiled image can't be loaded for + some reason (or just has not been loaded yet). + + The EelBackground object is easier to modify than a GtkStyle. + You can just call eel_get_window_background and modify the + returned background directly, unlike a style, which must be copied, + modified and then set. +*/ + +#include +#include + +#include + +typedef struct EelBackground EelBackground; +typedef struct EelBackgroundClass EelBackgroundClass; + +#define EEL_TYPE_BACKGROUND eel_background_get_type() +#define EEL_BACKGROUND(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEL_TYPE_BACKGROUND, EelBackground)) +#define EEL_BACKGROUND_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), EEL_TYPE_BACKGROUND, EelBackgroundClass)) +#define EEL_IS_BACKGROUND(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEL_TYPE_BACKGROUND)) +#define EEL_IS_BACKGROUND_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), EEL_TYPE_BACKGROUND)) +#define EEL_BACKGROUND_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), EEL_TYPE_BACKGROUND, EelBackgroundClass)) + +typedef enum +{ + EEL_BACKGROUND_TILED = 0, /* zero makes this the default placement */ + EEL_BACKGROUND_CENTERED, + EEL_BACKGROUND_SCALED, + EEL_BACKGROUND_SCALED_ASPECT, + EEL_BACKGROUND_ZOOM, + EEL_BACKGROUND_SPANNED +} EelBackgroundImagePlacement; + +GType eel_background_get_type (void); +EelBackground * eel_background_new (void); + + +/* Calls to change a background. */ +void eel_background_set_use_base (EelBackground *background, + gboolean use_base); +void eel_background_set_color (EelBackground *background, + const char *color_or_gradient); +void eel_background_set_image_uri (EelBackground *background, + const char *image_uri); + +void eel_background_reset (EelBackground *background); +void eel_background_set_image_placement (EelBackground *background, + EelBackgroundImagePlacement placement); + +/* Should be TRUE for desktop background */ +void eel_background_set_desktop (EelBackground *background, + GtkWidget *widget, + gboolean is_desktop); +gboolean eel_background_is_desktop (EelBackground *background); + +/* Calls to interrogate the current state of a background. */ +char * eel_background_get_color (EelBackground *background); +char * eel_background_get_image_uri (EelBackground *background); +EelBackgroundImagePlacement eel_background_get_image_placement (EelBackground *background); +gboolean eel_background_is_dark (EelBackground *background); +gboolean eel_background_is_set (EelBackground *background); + +/* Helper function for widgets using EelBackground */ +void eel_background_expose (GtkWidget *widget, + GdkEventExpose *event); + +/* Handles a dragged color being dropped on a widget to change the background color. */ +void eel_background_receive_dropped_color (EelBackground *background, + GtkWidget *widget, + GdkDragAction action, + int drop_location_x, + int drop_location_y, + const GtkSelectionData *dropped_color); + +/* Handles a special-case image name that means "reset to default background" too. */ +void eel_background_receive_dropped_background_image (EelBackground *background, + GdkDragAction action, + const char *image_uri); + +/* Gets or creates a background so that it's attached to a widget. */ +EelBackground * eel_get_widget_background (GtkWidget *widget); +void eel_background_save_to_mateconf (EelBackground *background); + +/* Set activity status of background. Inactive backgrounds are drawn in the theme's INSENSITIVE color. */ +void eel_background_set_active (EelBackground *background, + gboolean is_active); + +typedef struct EelBackgroundDetails EelBackgroundDetails; + +struct EelBackground +{ + GtkObject object; + EelBackgroundDetails *details; +}; + +struct EelBackgroundClass +{ + GtkObjectClass parent_class; + + /* This signal is emitted whenever the background settings are + * changed. + */ + void (* settings_changed) (EelBackground *); + + /* This signal is emitted whenever the appearance of the + * background has changed, like when the background settings are + * altered or when an image is loaded. + */ + void (* appearance_changed) (EelBackground *); + + /* This signal is emitted when image loading is over - whether it + * was successfully loaded or not. + */ + void (* image_loading_done) (EelBackground *background, gboolean successful_load); + + /* This signal is emitted when the background is reset by receiving + the reset property from a drag + */ + void (* reset) (EelBackground *); + +}; + +#endif /* EEL_BACKGROUND_H */ diff --git a/eel/eel-canvas-rect-ellipse.c b/eel/eel-canvas-rect-ellipse.c new file mode 100644 index 00000000..9481a7fd --- /dev/null +++ b/eel/eel-canvas-rect-ellipse.c @@ -0,0 +1,1550 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: 8; c-basic-offset: 8 -*- */ +/* + * Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation + * All rights reserved. + * + * This file is part of the Mate Library. + * + * The Mate Library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * The Mate Library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the Mate Library; see the file COPYING.LIB. If not, + * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ +/* + @NOTATION@ + */ +/* Rectangle and ellipse item types for EelCanvas widget + * + * EelCanvas is basically a port of the Tk toolkit's most excellent canvas widget. Tk is + * copyrighted by the Regents of the University of California, Sun Microsystems, and other parties. + * + * + * Author: Federico Mena + */ + +#include +#include +#include "eel-canvas-rect-ellipse.h" +#include "eel-canvas-util.h" +#include + +#ifdef HAVE_RENDER +#include +#include +#endif + +/* Base class for rectangle and ellipse item types */ + +#define noVERBOSE + +enum +{ + PROP_0, + PROP_X1, + PROP_Y1, + PROP_X2, + PROP_Y2, + PROP_FILL_COLOR, + PROP_FILL_COLOR_GDK, + PROP_FILL_COLOR_RGBA, + PROP_OUTLINE_COLOR, + PROP_OUTLINE_COLOR_GDK, + PROP_OUTLINE_COLOR_RGBA, + PROP_FILL_STIPPLE, + PROP_OUTLINE_STIPPLE, + PROP_WIDTH_PIXELS, + PROP_WIDTH_UNITS +}; + + +static void eel_canvas_re_class_init (EelCanvasREClass *klass); +static void eel_canvas_re_init (EelCanvasRE *re); +static void eel_canvas_re_destroy (GtkObject *object); +static void eel_canvas_re_set_property (GObject *object, + guint param_id, + const GValue *value, + GParamSpec *pspec); +static void eel_canvas_re_get_property (GObject *object, + guint param_id, + GValue *value, + GParamSpec *pspec); + +static void eel_canvas_re_update_shared (EelCanvasItem *item, + double i2w_dx, double i2w_dy, int flags); +static void eel_canvas_re_realize (EelCanvasItem *item); +static void eel_canvas_re_unrealize (EelCanvasItem *item); +static void eel_canvas_re_bounds (EelCanvasItem *item, double *x1, double *y1, double *x2, double *y2); +static void eel_canvas_re_translate (EelCanvasItem *item, double dx, double dy); +static void eel_canvas_rect_update (EelCanvasItem *item, double i2w_dx, double i2w_dy, int flags); +static void eel_canvas_ellipse_update (EelCanvasItem *item, double i2w_dx, double i2w_dy, int flags); + +typedef struct +{ + /*< public >*/ + int x0, y0, x1, y1; +} Rect; + +static Rect make_rect (int x0, int y0, int x1, int y1); +static void diff_rects (Rect r1, Rect r2, int *count, Rect result[4]); + +static EelCanvasItemClass *re_parent_class; +static EelCanvasREClass *rect_parent_class; + + +GType +eel_canvas_re_get_type (void) +{ + static GType re_type = 0; + + if (!re_type) + { + GTypeInfo re_info = + { + sizeof (EelCanvasREClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) eel_canvas_re_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (EelCanvasRE), + 0, /* n_preallocs */ + (GInstanceInitFunc) eel_canvas_re_init + }; + + re_type = g_type_register_static (eel_canvas_item_get_type (), + "EelCanvasRE", + &re_info, + 0); + } + + return re_type; +} + +static void +eel_canvas_re_class_init (EelCanvasREClass *klass) +{ + GObjectClass *gobject_class; + GtkObjectClass *object_class; + EelCanvasItemClass *item_class; + + gobject_class = (GObjectClass *) klass; + object_class = (GtkObjectClass *) klass; + item_class = (EelCanvasItemClass *) klass; + + re_parent_class = g_type_class_peek_parent (klass); + + gobject_class->set_property = eel_canvas_re_set_property; + gobject_class->get_property = eel_canvas_re_get_property; + + g_object_class_install_property + (gobject_class, + PROP_X1, + g_param_spec_double ("x1", NULL, NULL, + -G_MAXDOUBLE, G_MAXDOUBLE, 0, + G_PARAM_READWRITE)); + g_object_class_install_property + (gobject_class, + PROP_Y1, + g_param_spec_double ("y1", NULL, NULL, + -G_MAXDOUBLE, G_MAXDOUBLE, 0, + G_PARAM_READWRITE)); + g_object_class_install_property + (gobject_class, + PROP_X2, + g_param_spec_double ("x2", NULL, NULL, + -G_MAXDOUBLE, G_MAXDOUBLE, 0, + G_PARAM_READWRITE)); + g_object_class_install_property + (gobject_class, + PROP_Y2, + g_param_spec_double ("y2", NULL, NULL, + -G_MAXDOUBLE, G_MAXDOUBLE, 0, + G_PARAM_READWRITE)); + g_object_class_install_property + (gobject_class, + PROP_FILL_COLOR, + g_param_spec_string ("fill-color", NULL, NULL, + NULL, + G_PARAM_READWRITE)); + g_object_class_install_property + (gobject_class, + PROP_FILL_COLOR_GDK, + g_param_spec_boxed ("fill-color-gdk", NULL, NULL, + GDK_TYPE_COLOR, + G_PARAM_READWRITE)); + g_object_class_install_property + (gobject_class, + PROP_FILL_COLOR_RGBA, + g_param_spec_uint ("fill-color-rgba", NULL, NULL, + 0, G_MAXUINT, 0, + G_PARAM_READWRITE)); + g_object_class_install_property + (gobject_class, + PROP_FILL_STIPPLE, + g_param_spec_object ("fill-stipple", NULL, NULL, + GDK_TYPE_DRAWABLE, + G_PARAM_READWRITE)); + g_object_class_install_property + (gobject_class, + PROP_OUTLINE_COLOR, + g_param_spec_string ("outline-color", NULL, NULL, + NULL, + G_PARAM_READWRITE)); + g_object_class_install_property + (gobject_class, + PROP_OUTLINE_COLOR_GDK, + g_param_spec_boxed ("outline-color-gdk", NULL, NULL, + GDK_TYPE_COLOR, + G_PARAM_READWRITE)); + g_object_class_install_property + (gobject_class, + PROP_OUTLINE_COLOR_RGBA, + g_param_spec_uint ("outline-color-rgba", NULL, NULL, + 0, G_MAXUINT, 0, + G_PARAM_READWRITE)); + g_object_class_install_property + (gobject_class, + PROP_OUTLINE_STIPPLE, + g_param_spec_object ("outline-stipple", NULL, NULL, + GDK_TYPE_DRAWABLE, + G_PARAM_READWRITE)); + g_object_class_install_property + (gobject_class, + PROP_WIDTH_PIXELS, + g_param_spec_uint ("width-pixels", NULL, NULL, + 0, G_MAXUINT, 0, + G_PARAM_READWRITE)); + g_object_class_install_property + (gobject_class, + PROP_WIDTH_UNITS, + g_param_spec_double ("width-units", NULL, NULL, + 0.0, G_MAXDOUBLE, 0.0, + G_PARAM_READWRITE)); + + object_class->destroy = eel_canvas_re_destroy; + + item_class->realize = eel_canvas_re_realize; + item_class->unrealize = eel_canvas_re_unrealize; + item_class->translate = eel_canvas_re_translate; + item_class->bounds = eel_canvas_re_bounds; +} + +static void +eel_canvas_re_init (EelCanvasRE *re) +{ + re->x1 = 0.0; + re->y1 = 0.0; + re->x2 = 0.0; + re->y2 = 0.0; + re->width = 0.0; +} + +static void +eel_canvas_re_destroy (GtkObject *object) +{ + EelCanvasRE *re; + + g_return_if_fail (object != NULL); + g_return_if_fail (EEL_IS_CANVAS_RE (object)); + + re = EEL_CANVAS_RE (object); + + /* remember, destroy can be run multiple times! */ + + if (re->fill_stipple) + g_object_unref (re->fill_stipple); + re->fill_stipple = NULL; + + if (re->outline_stipple) + g_object_unref (re->outline_stipple); + re->outline_stipple = NULL; + + if (GTK_OBJECT_CLASS (re_parent_class)->destroy) + (* GTK_OBJECT_CLASS (re_parent_class)->destroy) (object); +} + +static void get_bounds (EelCanvasRE *re, double *px1, double *py1, double *px2, double *py2) +{ + EelCanvasItem *item; + double x1, y1, x2, y2; + int cx1, cy1, cx2, cy2; + double hwidth; + +#ifdef VERBOSE + g_print ("re get_bounds\n"); +#endif + item = EEL_CANVAS_ITEM (re); + + if (re->width_pixels) + hwidth = (re->width / item->canvas->pixels_per_unit) / 2.0; + else + hwidth = re->width / 2.0; + + x1 = re->x1; + y1 = re->y1; + x2 = re->x2; + y2 = re->y2; + + eel_canvas_item_i2w (item, &x1, &y1); + eel_canvas_item_i2w (item, &x2, &y2); + eel_canvas_w2c (item->canvas, x1 - hwidth, y1 - hwidth, &cx1, &cy1); + eel_canvas_w2c (item->canvas, x2 + hwidth, y2 + hwidth, &cx2, &cy2); + *px1 = cx1; + *py1 = cy1; + *px2 = cx2; + *py2 = cy2; + + /* Some safety fudging */ + + *px1 -= 2; + *py1 -= 2; + *px2 += 2; + *py2 += 2; +} + +/* Convenience function to set a GC's foreground color to the specified pixel value */ +static void +set_gc_foreground (GdkGC *gc, gulong pixel) +{ + GdkColor c; + + if (!gc) + return; + + c.pixel = pixel; + gdk_gc_set_foreground (gc, &c); +} + +/* Sets the stipple pattern for the specified gc */ +static void +set_stipple (GdkGC *gc, GdkBitmap **internal_stipple, GdkBitmap *stipple, int reconfigure) +{ + if (*internal_stipple && !reconfigure) + g_object_unref (*internal_stipple); + + *internal_stipple = stipple; + if (stipple && !reconfigure) + g_object_ref (stipple); + + if (gc) + { + if (stipple) + { + gdk_gc_set_stipple (gc, stipple); + gdk_gc_set_fill (gc, GDK_STIPPLED); + } + else + gdk_gc_set_fill (gc, GDK_SOLID); + } +} + +/* Recalculate the outline width of the rectangle/ellipse and set it in its GC */ +static void +set_outline_gc_width (EelCanvasRE *re) +{ + int width; + + if (!re->outline_gc) + return; + + if (re->width_pixels) + width = (int) re->width; + else + width = (int) (re->width * re->item.canvas->pixels_per_unit + 0.5); + + gdk_gc_set_line_attributes (re->outline_gc, width, + GDK_LINE_SOLID, GDK_CAP_PROJECTING, GDK_JOIN_MITER); +} + +static void +eel_canvas_re_set_fill (EelCanvasRE *re, gboolean fill_set) +{ + if (re->fill_set != fill_set) + { + re->fill_set = fill_set; + eel_canvas_item_request_update (EEL_CANVAS_ITEM (re)); + } +} + +static void +eel_canvas_re_set_outline (EelCanvasRE *re, gboolean outline_set) +{ + if (re->outline_set != outline_set) + { + re->outline_set = outline_set; + eel_canvas_item_request_update (EEL_CANVAS_ITEM (re)); + } +} + +static void +eel_canvas_re_set_property (GObject *object, + guint param_id, + const GValue *value, + GParamSpec *pspec) +{ + EelCanvasItem *item; + EelCanvasRE *re; + GdkColor color = { 0, 0, 0, 0, }; + GdkColor *pcolor; + int have_pixel; + + g_return_if_fail (object != NULL); + g_return_if_fail (EEL_IS_CANVAS_RE (object)); + + item = EEL_CANVAS_ITEM (object); + re = EEL_CANVAS_RE (object); + have_pixel = FALSE; + + switch (param_id) + { + case PROP_X1: + re->x1 = g_value_get_double (value); + + eel_canvas_item_request_update (item); + break; + + case PROP_Y1: + re->y1 = g_value_get_double (value); + + eel_canvas_item_request_update (item); + break; + + case PROP_X2: + re->x2 = g_value_get_double (value); + + eel_canvas_item_request_update (item); + break; + + case PROP_Y2: + re->y2 = g_value_get_double (value); + + eel_canvas_item_request_update (item); + break; + + case PROP_FILL_COLOR: + case PROP_FILL_COLOR_GDK: + case PROP_FILL_COLOR_RGBA: + switch (param_id) + { + case PROP_FILL_COLOR: + if (g_value_get_string (value) && + gdk_color_parse (g_value_get_string (value), &color)) + eel_canvas_re_set_fill (re, TRUE); + else + eel_canvas_re_set_fill (re, FALSE); + + re->fill_color = ((color.red & 0xff00) << 16 | + (color.green & 0xff00) << 8 | + (color.blue & 0xff00) | + 0xff); + break; + + case PROP_FILL_COLOR_GDK: + pcolor = g_value_get_boxed (value); + eel_canvas_re_set_fill (re, pcolor != NULL); + + if (pcolor) + { + GdkColormap *colormap; + + color = *pcolor; + colormap = gtk_widget_get_colormap (GTK_WIDGET (item->canvas)); + gdk_rgb_find_color (colormap, &color); + have_pixel = TRUE; + } + + re->fill_color = ((color.red & 0xff00) << 16 | + (color.green & 0xff00) << 8 | + (color.blue & 0xff00) | + 0xff); + break; + + case PROP_FILL_COLOR_RGBA: + eel_canvas_re_set_fill (re, TRUE); + re->fill_color = g_value_get_uint (value); + break; + } +#ifdef VERBOSE + g_print ("re fill color = %08x\n", re->fill_color); +#endif + if (have_pixel) + re->fill_pixel = color.pixel; + else + re->fill_pixel = eel_canvas_get_color_pixel (item->canvas, re->fill_color); + + set_gc_foreground (re->fill_gc, re->fill_pixel); + + eel_canvas_item_request_redraw (item); + break; + + case PROP_OUTLINE_COLOR: + case PROP_OUTLINE_COLOR_GDK: + case PROP_OUTLINE_COLOR_RGBA: + switch (param_id) + { + case PROP_OUTLINE_COLOR: + if (g_value_get_string (value) && + gdk_color_parse (g_value_get_string (value), &color)) + eel_canvas_re_set_outline (re, TRUE); + else + eel_canvas_re_set_outline (re, FALSE); + + re->outline_color = ((color.red & 0xff00) << 16 | + (color.green & 0xff00) << 8 | + (color.blue & 0xff00) | + 0xff); + break; + + case PROP_OUTLINE_COLOR_GDK: + pcolor = g_value_get_boxed (value); + eel_canvas_re_set_outline (re, pcolor != NULL); + + if (pcolor) + { + GdkColormap *colormap; + + color = *pcolor; + colormap = gtk_widget_get_colormap (GTK_WIDGET (item->canvas)); + gdk_rgb_find_color (colormap, &color); + + have_pixel = TRUE; + } + + re->outline_color = ((color.red & 0xff00) << 16 | + (color.green & 0xff00) << 8 | + (color.blue & 0xff00) | + 0xff); + break; + + case PROP_OUTLINE_COLOR_RGBA: + eel_canvas_re_set_outline (re, TRUE); + re->outline_color = g_value_get_uint (value); + break; + } +#ifdef VERBOSE + g_print ("re outline color %x %x %x\n", color.red, color.green, color.blue); +#endif + if (have_pixel) + re->outline_pixel = color.pixel; + else + re->outline_pixel = eel_canvas_get_color_pixel (item->canvas, + re->outline_color); + + set_gc_foreground (re->outline_gc, re->outline_pixel); + + eel_canvas_item_request_redraw (item); + break; + + case PROP_FILL_STIPPLE: + set_stipple (re->fill_gc, &re->fill_stipple, (GdkBitmap *) g_value_get_object (value), FALSE); + + break; + + case PROP_OUTLINE_STIPPLE: + set_stipple (re->outline_gc, &re->outline_stipple, (GdkBitmap *) g_value_get_object (value), FALSE); + break; + + case PROP_WIDTH_PIXELS: + re->width = g_value_get_uint (value); + re->width_pixels = TRUE; + set_outline_gc_width (re); + + eel_canvas_item_request_update (item); + break; + + case PROP_WIDTH_UNITS: + re->width = fabs (g_value_get_double (value)); + re->width_pixels = FALSE; + set_outline_gc_width (re); + + eel_canvas_item_request_update (item); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); + break; + } +} + +/* Allocates a GdkColor structure filled with the specified pixel, and puts it into the specified + * value for returning it in the get_property method. + */ +static void +get_color_value (EelCanvasRE *re, gulong pixel, GValue *value) +{ + GdkColor color; + EelCanvasItem *item = (EelCanvasItem *) re; + GdkColormap *colormap = gtk_widget_get_colormap (GTK_WIDGET (item->canvas)); + + gdk_colormap_query_color (colormap, pixel, &color); + g_value_set_boxed (value, &color); +} + +static void +eel_canvas_re_get_property (GObject *object, + guint param_id, + GValue *value, + GParamSpec *pspec) +{ + EelCanvasRE *re; + + g_return_if_fail (object != NULL); + g_return_if_fail (EEL_IS_CANVAS_RE (object)); + + re = EEL_CANVAS_RE (object); + + switch (param_id) + { + case PROP_X1: + g_value_set_double (value, re->x1); + break; + + case PROP_Y1: + g_value_set_double (value, re->y1); + break; + + case PROP_X2: + g_value_set_double (value, re->x2); + break; + + case PROP_Y2: + g_value_set_double (value, re->y2); + break; + + case PROP_FILL_COLOR_GDK: + get_color_value (re, re->fill_pixel, value); + break; + + case PROP_OUTLINE_COLOR_GDK: + get_color_value (re, re->outline_pixel, value); + break; + + case PROP_FILL_COLOR_RGBA: + g_value_set_uint (value, re->fill_color); + break; + + case PROP_OUTLINE_COLOR_RGBA: + g_value_set_uint (value, re->outline_color); + break; + + case PROP_FILL_STIPPLE: + g_value_set_object (value, (GObject *) re->fill_stipple); + break; + + case PROP_OUTLINE_STIPPLE: + g_value_set_object (value, (GObject *) re->outline_stipple); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); + break; + } +} + +static void +set_colors_and_stipples (EelCanvasRE *re) +{ + set_gc_foreground (re->fill_gc, re->fill_pixel); + set_gc_foreground (re->outline_gc, re->outline_pixel); + set_stipple (re->fill_gc, &re->fill_stipple, re->fill_stipple, TRUE); + set_stipple (re->outline_gc, &re->outline_stipple, re->outline_stipple, TRUE); + set_outline_gc_width (re); +} + +static void +eel_canvas_re_update_shared (EelCanvasItem *item, double i2w_dx, double i2w_dy, int flags) +{ + EelCanvasRE *re; + +#ifdef VERBOSE + g_print ("eel_canvas_re_update_shared\n"); +#endif + re = EEL_CANVAS_RE (item); + + if (re_parent_class->update) + (* re_parent_class->update) (item, i2w_dx, i2w_dy, flags); + + set_colors_and_stipples (re); + +#ifdef OLD_XFORM + recalc_bounds (re); +#endif +} + +static void +eel_canvas_re_realize (EelCanvasItem *item) +{ + EelCanvasRE *re; + +#ifdef VERBOSE + g_print ("eel_canvas_re_realize\n"); +#endif + re = EEL_CANVAS_RE (item); + + if (re_parent_class->realize) + (* re_parent_class->realize) (item); + + re->fill_gc = gdk_gc_new (gtk_layout_get_bin_window (&item->canvas->layout)); + re->fill_pixel = eel_canvas_get_color_pixel (item->canvas, re->fill_color); + re->outline_gc = gdk_gc_new (gtk_layout_get_bin_window (&item->canvas->layout)); + re->outline_pixel = eel_canvas_get_color_pixel (item->canvas, re->outline_color); + set_colors_and_stipples (re); + +#ifdef OLD_XFORM + (* EEL_CANVAS_ITEM_CLASS (item->object.klass)->update) (item, NULL, NULL, 0); +#endif +} + +static void +eel_canvas_re_unrealize (EelCanvasItem *item) +{ + EelCanvasRE *re; + + re = EEL_CANVAS_RE (item); + + g_object_unref (re->fill_gc); + re->fill_gc = NULL; + g_object_unref (re->outline_gc); + re->outline_gc = NULL; + + if (re_parent_class->unrealize) + (* re_parent_class->unrealize) (item); +} + +static void +eel_canvas_re_translate (EelCanvasItem *item, double dx, double dy) +{ + EelCanvasRE *re; + +#ifdef VERBOSE + g_print ("eel_canvas_re_translate\n"); +#endif + re = EEL_CANVAS_RE (item); + + re->x1 += dx; + re->y1 += dy; + re->x2 += dx; + re->y2 += dy; +} + + +static void +eel_canvas_re_bounds (EelCanvasItem *item, double *x1, double *y1, double *x2, double *y2) +{ + EelCanvasRE *re; + double hwidth; + +#ifdef VERBOSE + g_print ("eel_canvas_re_bounds\n"); +#endif + re = EEL_CANVAS_RE (item); + + if (re->width_pixels) + hwidth = (re->width / item->canvas->pixels_per_unit) / 2.0; + else + hwidth = re->width / 2.0; + + *x1 = re->x1 - hwidth; + *y1 = re->y1 - hwidth; + *x2 = re->x2 + hwidth; + *y2 = re->y2 + hwidth; +} + +/* Rectangle item */ + + +static void eel_canvas_rect_class_init (EelCanvasRectClass *klass); +static void eel_canvas_rect_init (EelCanvasRect *rect); +static void eel_canvas_rect_finalize (GObject *object); +static void eel_canvas_rect_realize (EelCanvasItem *item); + +static void eel_canvas_rect_draw (EelCanvasItem *item, GdkDrawable *drawable, GdkEventExpose *expose); +static double eel_canvas_rect_point (EelCanvasItem *item, double x, double y, int cx, int cy, + EelCanvasItem **actual_item); + +struct _EelCanvasRectPrivate +{ + Rect last_update_rect; + Rect last_outline_update_rect; + int last_outline_update_width; + +#ifdef HAVE_RENDER + gboolean use_render; + XRenderPictFormat *format; +#endif +}; + +GType +eel_canvas_rect_get_type (void) +{ + static GType rect_type = 0; + + if (!rect_type) + { + GTypeInfo rect_info = + { + sizeof (EelCanvasRectClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) eel_canvas_rect_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (EelCanvasRect), + 0, /* n_preallocs */ + (GInstanceInitFunc) eel_canvas_rect_init + }; + + rect_type = g_type_register_static (eel_canvas_re_get_type (), + "EelCanvasRect", + &rect_info, + 0); + } + + return rect_type; +} + +static void +eel_canvas_rect_class_init (EelCanvasRectClass *klass) +{ + EelCanvasItemClass *item_class; + + rect_parent_class = g_type_class_peek_parent (klass); + + item_class = (EelCanvasItemClass *) klass; + + item_class->draw = eel_canvas_rect_draw; + item_class->point = eel_canvas_rect_point; + item_class->update = eel_canvas_rect_update; + item_class->realize = eel_canvas_rect_realize; + + G_OBJECT_CLASS (klass)->finalize = eel_canvas_rect_finalize; + +} + +static void +eel_canvas_rect_init (EelCanvasRect *rect) +{ + rect->priv = g_new0 (EelCanvasRectPrivate, 1); +} + +static void +eel_canvas_rect_finalize (GObject *object) +{ + EelCanvasRect *rect = EEL_CANVAS_RECT (object); + + if (rect->priv) + { + g_free (rect->priv); + } + + G_OBJECT_CLASS (rect_parent_class)->finalize (object); +} + +static void +eel_canvas_rect_realize (EelCanvasItem *item) +{ +#ifdef HAVE_RENDER + EelCanvasRectPrivate *priv; + int event_base, error_base; + Display *dpy; + + priv = EEL_CANVAS_RECT (item)->priv; + + dpy = gdk_x11_drawable_get_xdisplay (gtk_widget_get_window (GTK_WIDGET (item->canvas))); + priv->use_render = XRenderQueryExtension (dpy, &event_base, &error_base); + + if (priv->use_render) + { + GdkVisual *gdk_visual; + Visual *visual; + + gdk_visual = gtk_widget_get_visual (GTK_WIDGET (item->canvas)); + visual = gdk_x11_visual_get_xvisual (gdk_visual); + + priv->format = XRenderFindVisualFormat (dpy, visual); + } +#endif + + if (EEL_CANVAS_ITEM_CLASS (rect_parent_class)->realize) + { + (* EEL_CANVAS_ITEM_CLASS (rect_parent_class)->realize) (item); + } +} + + +static void +render_rect_alpha (EelCanvasRect *rect, + GdkDrawable *drawable, + int x, int y, + int width, int height, + guint32 rgba) +{ + GdkPixbuf *pixbuf; + guchar *data; + int rowstride, i; + guchar r, g, b, a; + EelCanvasRectPrivate *priv; + + if (width <= 0 || height <= 0 ) + { + return; + } + + priv = rect->priv; + + r = (rgba >> 24) & 0xff; + g = (rgba >> 16) & 0xff; + b = (rgba >> 8) & 0xff; + a = (rgba >> 0) & 0xff; + +#ifdef HAVE_RENDER + /* Every visual is not guaranteed to have a matching + * XRenderPictFormat. So make sure that format is not null before + * trying to render using Xrender calls. + */ + if (priv->use_render && (priv->format != NULL)) + { + GdkDrawable *real_drawable; + int x_offset, y_offset; + + Display *dpy; + Picture pict; + XRenderPictureAttributes attributes; + XRenderColor color; + + gdk_window_get_internal_paint_info (drawable, &real_drawable, + &x_offset, &y_offset); + + dpy = gdk_x11_drawable_get_xdisplay (real_drawable); + + pict = XRenderCreatePicture (dpy, + gdk_x11_drawable_get_xid (real_drawable), + priv->format, + 0, + &attributes); + + + /* Convert to premultiplied alpha: */ + r = r * a / 255; + g = g * a / 255; + b = b * a / 255; + + color.red = (r << 8) + r; + color.green = (g << 8) + g; + color.blue = (b << 8) + b; + color.alpha = (a << 8) + a; + + XRenderFillRectangle (dpy, + PictOpOver, + pict, + &color, + x - x_offset, y - y_offset, + width, height); + + XRenderFreePicture (dpy, pict); + + return; + } +#endif + pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, width, height); + data = gdk_pixbuf_get_pixels (pixbuf); + rowstride = gdk_pixbuf_get_rowstride (pixbuf); + + r = (rgba >> 24) & 0xff; + g = (rgba >> 16) & 0xff; + b = (rgba >> 8) & 0xff; + a = (rgba >> 0) & 0xff; + + for (i = 0; i < width*4; ) + { + data[i++] = r; + data[i++] = g; + data[i++] = b; + data[i++] = a; + } + + for (i = 1; i < height; i++) + { + memcpy (data + i*rowstride, data, width*4); + } + + gdk_draw_pixbuf (drawable, NULL, pixbuf, + 0, 0, x, y, width, height, + GDK_RGB_DITHER_NONE, 0, 0); + g_object_unref (pixbuf); +} + + +static void +eel_canvas_rect_draw (EelCanvasItem *item, GdkDrawable *drawable, GdkEventExpose *expose) +{ + EelCanvasRE *re; + double x1, y1, x2, y2; + int cx1, cy1, cx2, cy2; + double i2w_dx, i2w_dy; + + re = EEL_CANVAS_RE (item); + + /* Get canvas pixel coordinates */ + i2w_dx = 0.0; + i2w_dy = 0.0; + eel_canvas_item_i2w (item, &i2w_dx, &i2w_dy); + + x1 = re->x1 + i2w_dx; + y1 = re->y1 + i2w_dy; + x2 = re->x2 + i2w_dx; + y2 = re->y2 + i2w_dy; + + eel_canvas_w2c (item->canvas, x1, y1, &cx1, &cy1); + eel_canvas_w2c (item->canvas, x2, y2, &cx2, &cy2); + + if (re->fill_set) + { + if ((re->fill_color & 0xff) != 255) + { + GdkRectangle *rectangles; + gint i, n_rectangles; + GdkRectangle draw_rect; + GdkRectangle part; + + draw_rect.x = cx1; + draw_rect.y = cy1; + draw_rect.width = cx2 - cx1 + 1; + draw_rect.height = cy2 - cy1 + 1; + + /* For alpha mode, only render the parts of the region + that are actually exposed */ + gdk_region_get_rectangles (expose->region, + &rectangles, + &n_rectangles); + + for (i = 0; i < n_rectangles; i++) + { + if (gdk_rectangle_intersect (&rectangles[i], + &draw_rect, + &part)) + { + render_rect_alpha (EEL_CANVAS_RECT (item), + drawable, + part.x, part.y, + part.width, part.height, + re->fill_color); + } + } + + g_free (rectangles); + } + else + { + if (re->fill_stipple) + eel_canvas_set_stipple_origin (item->canvas, re->fill_gc); + + gdk_draw_rectangle (drawable, + re->fill_gc, + TRUE, + cx1, cy1, + cx2 - cx1 + 1, + cy2 - cy1 + 1); + } + } + + if (re->outline_set) + { + if (re->outline_stipple) + eel_canvas_set_stipple_origin (item->canvas, re->outline_gc); + + gdk_draw_rectangle (drawable, + re->outline_gc, + FALSE, + cx1, + cy1, + cx2 - cx1, + cy2 - cy1); + } +} + +static double +eel_canvas_rect_point (EelCanvasItem *item, double x, double y, int cx, int cy, EelCanvasItem **actual_item) +{ + EelCanvasRE *re; + double x1, y1, x2, y2; + double hwidth; + double dx, dy; + double tmp; + +#ifdef VERBOSE + g_print ("eel_canvas_rect_point\n"); +#endif + re = EEL_CANVAS_RE (item); + + *actual_item = item; + + /* Find the bounds for the rectangle plus its outline width */ + + x1 = re->x1; + y1 = re->y1; + x2 = re->x2; + y2 = re->y2; + + if (re->outline_set) + { + if (re->width_pixels) + hwidth = (re->width / item->canvas->pixels_per_unit) / 2.0; + else + hwidth = re->width / 2.0; + + x1 -= hwidth; + y1 -= hwidth; + x2 += hwidth; + y2 += hwidth; + } + else + hwidth = 0.0; + + /* Is point inside rectangle (which can be hollow if it has no fill set)? */ + + if ((x >= x1) && (y >= y1) && (x <= x2) && (y <= y2)) + { + if (re->fill_set || !re->outline_set) + return 0.0; + + dx = x - x1; + tmp = x2 - x; + if (tmp < dx) + dx = tmp; + + dy = y - y1; + tmp = y2 - y; + if (tmp < dy) + dy = tmp; + + if (dy < dx) + dx = dy; + + dx -= 2.0 * hwidth; + + if (dx < 0.0) + return 0.0; + else + return dx; + } + + /* Point is outside rectangle */ + + if (x < x1) + dx = x1 - x; + else if (x > x2) + dx = x - x2; + else + dx = 0.0; + + if (y < y1) + dy = y1 - y; + else if (y > y2) + dy = y - y2; + else + dy = 0.0; + + return sqrt (dx * dx + dy * dy); +} + +static void +request_redraw_borders (EelCanvas *canvas, + Rect *update_rect, + int width) +{ + eel_canvas_request_redraw (canvas, + update_rect->x0, update_rect->y0, + update_rect->x1, update_rect->y0 + width); + eel_canvas_request_redraw (canvas, + update_rect->x0, update_rect->y1-width, + update_rect->x1, update_rect->y1); + eel_canvas_request_redraw (canvas, + update_rect->x0, update_rect->y0, + update_rect->x0+width, update_rect->y1); + eel_canvas_request_redraw (canvas, + update_rect->x1-width, update_rect->y0, + update_rect->x1, update_rect->y1); +} + + +static void +eel_canvas_rect_update (EelCanvasItem *item, double i2w_dx, double i2w_dy, gint flags) +{ + EelCanvasRE *re; + double x1, y1, x2, y2; + int cx1, cy1, cx2, cy2; + int repaint_rects_count, i; + int width_pixels; + int width_lt, width_rb; + Rect update_rect, repaint_rects[4]; + EelCanvasRectPrivate *priv; + + eel_canvas_re_update_shared (item, i2w_dx, i2w_dy, flags); + + re = EEL_CANVAS_RE (item); + priv = EEL_CANVAS_RECT (item)->priv; + + x1 = re->x1 + i2w_dx; + y1 = re->y1 + i2w_dy; + x2 = re->x2 + i2w_dx; + y2 = re->y2 + i2w_dy; + + eel_canvas_w2c (item->canvas, x1, y1, &cx1, &cy1); + eel_canvas_w2c (item->canvas, x2, y2, &cx2, &cy2); + + update_rect = make_rect (cx1, cy1, cx2+1, cy2+1); +#if 0 + eel_canvas_request_redraw (item->canvas, + update_rect.x0, update_rect.y0, + update_rect.x1, update_rect.y1); + eel_canvas_request_redraw (item->canvas, + priv->last_update_rect.x0, priv->last_update_rect.y0, + priv->last_update_rect.x1, priv->last_update_rect.y1); +#else + diff_rects (update_rect, priv->last_update_rect, + &repaint_rects_count, repaint_rects); + for (i = 0; i < repaint_rects_count; i++) + { + eel_canvas_request_redraw (item->canvas, + repaint_rects[i].x0, repaint_rects[i].y0, + repaint_rects[i].x1, repaint_rects[i].y1); + } +#endif + priv->last_update_rect = update_rect; + + if (re->outline_set) + { + /* Outline and bounding box */ + if (re->width_pixels) + width_pixels = (int) re->width; + else + width_pixels = (int) floor (re->width * re->item.canvas->pixels_per_unit + 0.5); + + width_lt = width_pixels / 2; + width_rb = (width_pixels + 1) / 2; + + cx1 -= width_lt; + cy1 -= width_lt; + cx2 += width_rb; + cy2 += width_rb; + + update_rect = make_rect (cx1, cy1, cx2, cy2); + request_redraw_borders (item->canvas, &update_rect, + (width_lt + width_rb)); + request_redraw_borders (item->canvas, &priv->last_outline_update_rect, + priv->last_outline_update_width); + priv->last_outline_update_rect = update_rect; + priv->last_outline_update_width = width_lt + width_rb; + + item->x1 = cx1; + item->y1 = cy1; + item->x2 = cx2+1; + item->y2 = cy2+1; + } + else + { + item->x1 = cx1; + item->y1 = cy1; + item->x2 = cx2+1; + item->y2 = cy2+1; + } +} + +/* Ellipse item */ + + +static void eel_canvas_ellipse_class_init (EelCanvasEllipseClass *klass); + +static void eel_canvas_ellipse_draw (EelCanvasItem *item, GdkDrawable *drawable, GdkEventExpose *expose); +static double eel_canvas_ellipse_point (EelCanvasItem *item, double x, double y, int cx, int cy, + EelCanvasItem **actual_item); + + +GType +eel_canvas_ellipse_get_type (void) +{ + static GType ellipse_type = 0; + + if (!ellipse_type) + { + GTypeInfo ellipse_info = + { + sizeof (EelCanvasEllipseClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) eel_canvas_ellipse_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (EelCanvasEllipse), + 0, /* n_preallocs */ + (GInstanceInitFunc) NULL + + }; + + ellipse_type = g_type_register_static (eel_canvas_re_get_type (), + "EelCanvasEllipse", + &ellipse_info, + 0); + } + + return ellipse_type; +} + +static void +eel_canvas_ellipse_class_init (EelCanvasEllipseClass *klass) +{ + EelCanvasItemClass *item_class; + + item_class = (EelCanvasItemClass *) klass; + + item_class->draw = eel_canvas_ellipse_draw; + item_class->point = eel_canvas_ellipse_point; + item_class->update = eel_canvas_ellipse_update; +} + +static void +eel_canvas_ellipse_draw (EelCanvasItem *item, GdkDrawable *drawable, GdkEventExpose *expose) +{ + EelCanvasRE *re; + int x1, y1, x2, y2; + double i2w_dx, i2w_dy; + + re = EEL_CANVAS_RE (item); + + /* Get canvas pixel coordinates */ + + i2w_dx = 0.0; + i2w_dy = 0.0; + eel_canvas_item_i2w (item, &i2w_dx, &i2w_dy); + + eel_canvas_w2c (item->canvas, + re->x1 + i2w_dx, + re->y1 + i2w_dy, + &x1, &y1); + eel_canvas_w2c (item->canvas, + re->x2 + i2w_dx, + re->y2 + i2w_dy, + &x2, &y2); + + if (re->fill_set) + { + if (re->fill_stipple) + eel_canvas_set_stipple_origin (item->canvas, re->fill_gc); + + gdk_draw_arc (drawable, + re->fill_gc, + TRUE, + x1, + y1, + x2 - x1, + y2 - y1, + 0 * 64, + 360 * 64); + } + + if (re->outline_set) + { + if (re->outline_stipple) + eel_canvas_set_stipple_origin (item->canvas, re->outline_gc); + + gdk_draw_arc (drawable, + re->outline_gc, + FALSE, + x1, + y1, + x2 - x1, + y2 - y1, + 0 * 64, + 360 * 64); + } +} + +static double +eel_canvas_ellipse_point (EelCanvasItem *item, double x, double y, int cx, int cy, EelCanvasItem **actual_item) +{ + EelCanvasRE *re; + double dx, dy; + double scaled_dist; + double outline_dist; + double center_dist; + double width; + double a, b; + double diamx, diamy; + + re = EEL_CANVAS_RE (item); + + *actual_item = item; + + if (re->outline_set) + { + if (re->width_pixels) + width = re->width / item->canvas->pixels_per_unit; + else + width = re->width; + } + else + width = 0.0; + + /* Compute the distance between the center of the ellipse and the point, with the ellipse + * considered as being scaled to a circle. + */ + + dx = x - (re->x1 + re->x2) / 2.0; + dy = y - (re->y1 + re->y2) / 2.0; + center_dist = sqrt (dx * dx + dy * dy); + + a = dx / ((re->x2 + width - re->x1) / 2.0); + b = dy / ((re->y2 + width - re->y1) / 2.0); + scaled_dist = sqrt (a * a + b * b); + + /* If the scaled distance is greater than 1, then we are outside. Compute the distance from + * the point to the edge of the circle, then scale back to the original un-scaled coordinate + * system. + */ + + if (scaled_dist > 1.0) + return (center_dist / scaled_dist) * (scaled_dist - 1.0); + + /* We are inside the outer edge of the ellipse. If it is filled, then we are "inside". + * Otherwise, do the same computation as above, but also check whether we are inside the + * outline. + */ + + if (re->fill_set) + return 0.0; + + if (scaled_dist > EEL_CANVAS_EPSILON) + outline_dist = (center_dist / scaled_dist) * (1.0 - scaled_dist) - width; + else + { + /* Handle very small distance */ + + diamx = re->x2 - re->x1; + diamy = re->y2 - re->y1; + + if (diamx < diamy) + outline_dist = (diamx - width) / 2.0; + else + outline_dist = (diamy - width) / 2.0; + } + + if (outline_dist < 0.0) + return 0.0; + + return outline_dist; +} + +static void +eel_canvas_ellipse_update (EelCanvasItem *item, double i2w_dx, double i2w_dy, gint flags) +{ + EelCanvasRE *re; + double x0, y0, x1, y1; + +#ifdef VERBOSE + g_print ("eel_canvas_sllipse_update item %x\n", item); +#endif + + eel_canvas_re_update_shared (item, i2w_dx, i2w_dy, flags); + re = EEL_CANVAS_RE (item); + + get_bounds (re, &x0, &y0, &x1, &y1); + eel_canvas_update_bbox (item, x0, y0, x1, y1); +} + +static int +rect_empty (const Rect *src) +{ + return (src->x1 <= src->x0 || src->y1 <= src->y0); +} + +static Rect +make_rect (int x0, int y0, int x1, int y1) +{ + Rect r; + + r.x0 = x0; + r.y0 = y0; + r.x1 = x1; + r.y1 = y1; + return r; +} + +static gboolean +rects_intersect (Rect r1, Rect r2) +{ + if (r1.x0 >= r2.x1) + { + return FALSE; + } + if (r2.x0 >= r1.x1) + { + return FALSE; + } + if (r1.y0 >= r2.y1) + { + return FALSE; + } + if (r2.y0 >= r1.y1) + { + return FALSE; + } + return TRUE; +} + +static void +diff_rects_guts (Rect ra, Rect rb, int *count, Rect result[4]) +{ + if (ra.x0 < rb.x0) + { + result[(*count)++] = make_rect (ra.x0, ra.y0, rb.x0, ra.y1); + } + if (ra.y0 < rb.y0) + { + result[(*count)++] = make_rect (ra.x0, ra.y0, ra.x1, rb.y0); + } + if (ra.x1 < rb.x1) + { + result[(*count)++] = make_rect (ra.x1, rb.y0, rb.x1, rb.y1); + } + if (ra.y1 < rb.y1) + { + result[(*count)++] = make_rect (rb.x0, ra.y1, rb.x1, rb.y1); + } +} + +static void +diff_rects (Rect r1, Rect r2, int *count, Rect result[4]) +{ + g_assert (count != NULL); + g_assert (result != NULL); + + *count = 0; + + if (rects_intersect (r1, r2)) + { + diff_rects_guts (r1, r2, count, result); + diff_rects_guts (r2, r1, count, result); + } + else + { + if (!rect_empty (&r1)) + { + result[(*count)++] = r1; + } + if (!rect_empty (&r2)) + { + result[(*count)++] = r2; + } + } +} diff --git a/eel/eel-canvas-rect-ellipse.h b/eel/eel-canvas-rect-ellipse.h new file mode 100644 index 00000000..06f1eeab --- /dev/null +++ b/eel/eel-canvas-rect-ellipse.h @@ -0,0 +1,184 @@ +/* + * Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation + * All rights reserved. + * + * This file is part of the Mate Library. + * + * The Mate Library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * The Mate Library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the Mate Library; see the file COPYING.LIB. If not, + * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ +/* + @NOTATION@ + */ +/* Rectangle and ellipse item types for EelCanvas widget + * + * EelCanvas is basically a port of the Tk toolkit's most excellent canvas widget. Tk is + * copyrighted by the Regents of the University of California, Sun Microsystems, and other parties. + * + * + * Author: Federico Mena + */ + +#ifndef EEL_CANVAS_RECT_ELLIPSE_H +#define EEL_CANVAS_RECT_ELLIPSE_H + + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + + /* Base class for rectangle and ellipse item types. These are defined by their top-left and + * bottom-right corners. Rectangles and ellipses share the following arguments: + * + * name type read/write description + * ------------------------------------------------------------------------------------------ + * x1 double RW Leftmost coordinate of rectangle or ellipse + * y1 double RW Topmost coordinate of rectangle or ellipse + * x2 double RW Rightmost coordinate of rectangle or ellipse + * y2 double RW Bottommost coordinate of rectangle or ellipse + * fill_color string W X color specification for fill color, + * or NULL pointer for no color (transparent) + * fill_color_gdk GdkColor* RW Allocated GdkColor for fill + * outline_color string W X color specification for outline color, + * or NULL pointer for no color (transparent) + * outline_color_gdk GdkColor* RW Allocated GdkColor for outline + * fill_stipple GdkBitmap* RW Stipple pattern for fill + * outline_stipple GdkBitmap* RW Stipple pattern for outline + * width_pixels uint RW Width of the outline in pixels. The outline will + * not be scaled when the canvas zoom factor is changed. + * width_units double RW Width of the outline in canvas units. The outline + * will be scaled when the canvas zoom factor is changed. + */ + + +#define EEL_TYPE_CANVAS_RE (eel_canvas_re_get_type ()) +#define EEL_CANVAS_RE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEL_TYPE_CANVAS_RE, EelCanvasRE)) +#define EEL_CANVAS_RE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEL_TYPE_CANVAS_RE, EelCanvasREClass)) +#define EEL_IS_CANVAS_RE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEL_TYPE_CANVAS_RE)) +#define EEL_IS_CANVAS_RE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEL_TYPE_CANVAS_RE)) +#define EEL_CANVAS_RE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEL_TYPE_CANVAS_RE, EelCanvasREClass)) + + + typedef struct _EelCanvasRE EelCanvasRE; + typedef struct _EelCanvasREClass EelCanvasREClass; + + struct _EelCanvasRE + { + EelCanvasItem item; + + GdkBitmap *fill_stipple; /* Stipple for fill */ + GdkBitmap *outline_stipple; /* Stipple for outline */ + + GdkGC *fill_gc; /* GC for filling */ + GdkGC *outline_gc; /* GC for outline */ + + gulong fill_pixel; /* Fill color */ + gulong outline_pixel; /* Outline color */ + + double x1, y1, x2, y2; /* Corners of item */ + double width; /* Outline width */ + + guint fill_color; /* Fill color, RGBA */ + guint outline_color; /* Outline color, RGBA */ + + /* Configuration flags */ + + unsigned int fill_set : 1; /* Is fill color set? */ + unsigned int outline_set : 1; /* Is outline color set? */ + unsigned int width_pixels : 1; /* Is outline width specified in pixels or units? */ + }; + + struct _EelCanvasREClass + { + EelCanvasItemClass parent_class; + }; + + + /* Standard Gtk function */ + GType eel_canvas_re_get_type (void) G_GNUC_CONST; + + + /* Rectangle item. No configurable or queryable arguments are available (use those in + * EelCanvasRE). + */ + + +#define EEL_TYPE_CANVAS_RECT (eel_canvas_rect_get_type ()) +#define EEL_CANVAS_RECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEL_TYPE_CANVAS_RECT, EelCanvasRect)) +#define EEL_CANVAS_RECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEL_TYPE_CANVAS_RECT, EelCanvasRectClass)) +#define EEL_IS_CANVAS_RECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEL_TYPE_CANVAS_RECT)) +#define EEL_IS_CANVAS_RECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEL_TYPE_CANVAS_RECT)) +#define EEL_CANVAS_RECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEL_TYPE_CANVAS_RECT, EelCanvasRectClass)) + + + typedef struct _EelCanvasRect EelCanvasRect; + typedef struct _EelCanvasRectPrivate EelCanvasRectPrivate; + typedef struct _EelCanvasRectClass EelCanvasRectClass; + + struct _EelCanvasRect + { + EelCanvasRE re; + EelCanvasRectPrivate *priv; + }; + + struct _EelCanvasRectClass + { + EelCanvasREClass parent_class; + }; + + + /* Standard Gtk function */ + GType eel_canvas_rect_get_type (void) G_GNUC_CONST; + + + /* Ellipse item. No configurable or queryable arguments are available (use those in + * EelCanvasRE). + */ + + +#define EEL_TYPE_CANVAS_ELLIPSE (eel_canvas_ellipse_get_type ()) +#define EEL_CANVAS_ELLIPSE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEL_TYPE_CANVAS_ELLIPSE, EelCanvasEllipse)) +#define EEL_CANVAS_ELLIPSE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEL_TYPE_CANVAS_ELLIPSE, EelCanvasEllipseClass)) +#define EEL_IS_CANVAS_ELLIPSE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEL_TYPE_CANVAS_ELLIPSE)) +#define EEL_IS_CANVAS_ELLIPSE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEL_TYPE_CANVAS_ELLIPSE)) +#define EEL_CANVAS_ELLIPSE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEL_TYPE_CANVAS_ELLIPSE, EelCanvasEllipseClass)) + + + typedef struct _EelCanvasEllipse EelCanvasEllipse; + typedef struct _EelCanvasEllipseClass EelCanvasEllipseClass; + + struct _EelCanvasEllipse + { + EelCanvasRE re; + }; + + struct _EelCanvasEllipseClass + { + EelCanvasREClass parent_class; + }; + + + /* Standard Gtk function */ + GType eel_canvas_ellipse_get_type (void) G_GNUC_CONST; + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/eel/eel-canvas-util.c b/eel/eel-canvas-util.c new file mode 100644 index 00000000..ac90177f --- /dev/null +++ b/eel/eel-canvas-util.c @@ -0,0 +1,426 @@ +/* + * Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation + * All rights reserved. + * + * This file is part of the Mate Library. + * + * The Mate Library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * The Mate Library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the Mate Library; see the file COPYING.LIB. If not, + * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ +/* + @NOTATION@ + */ +/* Miscellaneous utility functions for the EelCanvas widget + * + * EelCanvas is basically a port of the Tk toolkit's most excellent canvas widget. Tk is + * copyrighted by the Regents of the University of California, Sun Microsystems, and other parties. + * + * + * Author: Federico Mena + */ + +#include + +#include +#include +#include + +#include "eel-canvas.h" +#include "eel-canvas-util.h" + +/* + * Ok, so some systems require magic incantations for M_PI to be defined. + * It's not important enough to worry about. + */ +#ifndef M_PI +#define M_PI 3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117 +#endif + +/** + * eel_canvas_points_new: + * @num_points: The number of points to allocate space for in the array. + * + * Creates a structure that should be used to pass an array of points to + * items. + * + * Return value: A newly-created array of points. It should be filled in + * by the user. + **/ +EelCanvasPoints * +eel_canvas_points_new (int num_points) +{ + EelCanvasPoints *points; + + g_return_val_if_fail (num_points > 1, NULL); + + points = g_new (EelCanvasPoints, 1); + points->num_points = num_points; + points->coords = g_new (double, 2 * num_points); + points->ref_count = 1; + + return points; +} + +/** + * eel_canvas_points_ref: + * @points: A canvas points structure. + * + * Increases the reference count of the specified points structure. + * + * Return value: The canvas points structure itself. + **/ +EelCanvasPoints * +eel_canvas_points_ref (EelCanvasPoints *points) +{ + g_return_val_if_fail (points != NULL, NULL); + + points->ref_count += 1; + return points; +} + +/** + * eel_canvas_points_free: + * @points: A canvas points structure. + * + * Decreases the reference count of the specified points structure. If it + * reaches zero, then the structure is freed. + **/ +void +eel_canvas_points_free (EelCanvasPoints *points) +{ + g_return_if_fail (points != NULL); + + points->ref_count -= 1; + if (points->ref_count == 0) + { + g_free (points->coords); + g_free (points); + } +} + +/** + * eel_canvas_get_miter_points: + * @x1: X coordinate of the first point + * @y1: Y coordinate of the first point + * @x2: X coordinate of the second (angle) point + * @y2: Y coordinate of the second (angle) point + * @x3: X coordinate of the third point + * @y3: Y coordinate of the third point + * @width: Width of the line + * @mx1: The X coordinate of the first miter point is returned here. + * @my1: The Y coordinate of the first miter point is returned here. + * @mx2: The X coordinate of the second miter point is returned here. + * @my2: The Y coordinate of the second miter point is returned here. + * + * Given three points forming an angle, computes the coordinates of the inside + * and outside points of the mitered corner formed by a line of a given width at + * that angle. + * + * Return value: FALSE if the angle is less than 11 degrees (this is the same + * threshold as X uses. If this occurs, the return points are not modified. + * Otherwise, returns TRUE. + **/ +int +eel_canvas_get_miter_points (double x1, double y1, double x2, double y2, double x3, double y3, + double width, + double *mx1, double *my1, double *mx2, double *my2) +{ + double theta1; /* angle of segment p2-p1 */ + double theta2; /* angle of segment p2-p3 */ + double theta; /* angle between line segments */ + double theta3; /* angle that bisects theta1 and theta2 and points to p1 */ + double dist; /* distance of miter points from p2 */ + double dx, dy; /* x and y offsets corresponding to dist */ + + double ELEVEN_DEGREES = 11.0 * M_PI / 180.0; + + /* Degenerate cases. */ + if ((x1 == x2 && y1 == y2) || (x2 == x3 && y2 == y3)) + return FALSE; + + theta1 = atan2 (y1 - y2, x1 - x2); + theta2 = atan2 (y3 - y2, x3 - x2); + theta = theta1 - theta2; + + /* Normalize to (-pi; pi]. */ + if (theta > M_PI) + theta -= 2.0 * M_PI; + else if (theta <= -M_PI) + theta += 2.0 * M_PI; + + if (fabs (theta) < ELEVEN_DEGREES) + return FALSE; + + dist = fabs (0.5 * width / sin (0.5 * theta)); + + theta3 = (theta1 + theta2) / 2.0; + if (sin (theta3 - theta1) > 0.0) + theta3 += M_PI; + + dx = dist * cos (theta3); + dy = dist * sin (theta3); + + *mx1 = x2 + dx; + *mx2 = x2 - dx; + *my1 = y2 + dy; + *my2 = y2 - dy; + + return TRUE; +} + +/** + * eel_canvas_get_butt_points: + * @x1: X coordinate of first point in the line + * @y1: Y cooordinate of first point in the line + * @x2: X coordinate of second point (endpoint) of the line + * @y2: Y coordinate of second point (endpoint) of the line + * @width: Width of the line + * @project: Whether the butt points should project out by width/2 distance + * @bx1: X coordinate of first butt point is returned here + * @by1: Y coordinate of first butt point is returned here + * @bx2: X coordinate of second butt point is returned here + * @by2: Y coordinate of second butt point is returned here + * + * Computes the butt points of a line segment. + **/ +void +eel_canvas_get_butt_points (double x1, double y1, double x2, double y2, + double width, int project, + double *bx1, double *by1, double *bx2, double *by2) +{ + double length; + double dx, dy; + + width *= 0.5; + dx = x2 - x1; + dy = y2 - y1; + length = sqrt (dx * dx + dy * dy); + + if (length < EEL_CANVAS_EPSILON) + { + *bx1 = *bx2 = x2; + *by1 = *by2 = y2; + } + else + { + dx = -width * (y2 - y1) / length; + dy = width * (x2 - x1) / length; + + *bx1 = x2 + dx; + *bx2 = x2 - dx; + *by1 = y2 + dy; + *by2 = y2 - dy; + + if (project) + { + *bx1 += dy; + *bx2 += dy; + *by1 -= dx; + *by2 -= dx; + } + } +} + +/** + * eel_canvas_polygon_to_point: + * @poly: Vertices of the polygon. X coordinates are in the even indices, and Y + * coordinates are in the odd indices + * @num_points: Number of points in the polygon + * @x: X coordinate of the point + * @y: Y coordinate of the point + * + * Computes the distance between a point and a polygon. + * + * Return value: The distance from the point to the polygon, or zero if the + * point is inside the polygon. + **/ +double +eel_canvas_polygon_to_point (double *poly, int num_points, double x, double y) +{ + double best; + int intersections; + int i; + double *p; + double dx, dy; + + /* Iterate through all the edges in the polygon, updating best and intersections. + * + * When computing intersections, include left X coordinate of line within its range, but not + * Y coordinate. Otherwise if the point lies exactly below a vertex we'll count it as two + * intersections. + */ + + best = 1.0e36; + if (poly == NULL) + return best; + + intersections = 0; + + for (i = num_points, p = poly; i > 1; i--, p += 2) + { + double px, py, dist; + + /* Compute the point on the current edge closest to the point and update the + * intersection count. This must be done separately for vertical edges, horizontal + * edges, and others. + */ + + if (p[2] == p[0]) + { + /* Vertical edge */ + + px = p[0]; + + if (p[1] >= p[3]) + { + py = MIN (p[1], y); + py = MAX (py, p[3]); + } + else + { + py = MIN (p[3], y); + py = MAX (py, p[1]); + } + } + else if (p[3] == p[1]) + { + /* Horizontal edge */ + + py = p[1]; + + if (p[0] >= p[2]) + { + px = MIN (p[0], x); + px = MAX (px, p[2]); + + if ((y < py) && (x < p[0]) && (x >= p[2])) + intersections++; + } + else + { + px = MIN (p[2], x); + px = MAX (px, p[0]); + + if ((y < py) && (x < p[2]) && (x >= p[0])) + intersections++; + } + } + else + { + double m1, b1, m2, b2; + int lower; + + /* Diagonal edge. Convert the edge to a line equation (y = m1*x + b1), then + * compute a line perpendicular to this edge but passing through the point, + * (y = m2*x + b2). + */ + + m1 = (p[3] - p[1]) / (p[2] - p[0]); + b1 = p[1] - m1 * p[0]; + + m2 = -1.0 / m1; + b2 = y - m2 * x; + + px = (b2 - b1) / (m1 - m2); + py = m1 * px + b1; + + if (p[0] > p[2]) + { + if (px > p[0]) + { + px = p[0]; + py = p[1]; + } + else if (px < p[2]) + { + px = p[2]; + py = p[3]; + } + } + else + { + if (px > p[2]) + { + px = p[2]; + py = p[3]; + } + else if (px < p[0]) + { + px = p[0]; + py = p[1]; + } + } + + lower = (m1 * x + b1) > y; + + if (lower && (x >= MIN (p[0], p[2])) && (x < MAX (p[0], p[2]))) + intersections++; + } + + /* Compute the distance to the closest point, and see if that is the best so far */ + + dx = x - px; + dy = y - py; + dist = sqrt (dx * dx + dy * dy); + if (dist < best) + best = dist; + } + + /* We've processed all the points. If the number of intersections is odd, the point is + * inside the polygon. + */ + + if (intersections & 0x1) + return 0.0; + else + return best; +} + +/** + * eel_canvas_item_reset_bounds: + * @item: A canvas item + * + * Resets the bounding box of a canvas item to an empty rectangle. + **/ +void +eel_canvas_item_reset_bounds (EelCanvasItem *item) +{ + item->x1 = 0.0; + item->y1 = 0.0; + item->x2 = 0.0; + item->y2 = 0.0; +} + +/** + * eel_canvas_update_bbox: + * @canvas: the canvas needing update + * @x1: Left coordinate of the new bounding box + * @y1: Top coordinate of the new bounding box + * @x2: Right coordinate of the new bounding box + * @y2: Bottom coordinate of the new bounding box + * + * Sets the bbox to the new value, requesting full repaint. + **/ +void +eel_canvas_update_bbox (EelCanvasItem *item, int x1, int y1, int x2, int y2) +{ + eel_canvas_item_request_redraw (item); + item->x1 = x1; + item->y1 = y1; + item->x2 = x2; + item->y2 = y2; + eel_canvas_item_request_redraw (item); +} + diff --git a/eel/eel-canvas-util.h b/eel/eel-canvas-util.h new file mode 100644 index 00000000..e4484cde --- /dev/null +++ b/eel/eel-canvas-util.h @@ -0,0 +1,110 @@ +/* + * Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation + * All rights reserved. + * + * This file is part of the Mate Library. + * + * The Mate Library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * The Mate Library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the Mate Library; see the file COPYING.LIB. If not, + * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ +/* + @NOTATION@ + */ +/* Miscellaneous utility functions for the EelCanvas widget + * + * EelCanvas is basically a port of the Tk toolkit's most excellent canvas widget. Tk is + * copyrighted by the Regents of the University of California, Sun Microsystems, and other parties. + * + * Author: Federico Mena + */ + +#ifndef EEL_CANVAS_UTIL_H +#define EEL_CANVAS_UTIL_H + + +#ifdef __cplusplus +extern "C" { +#endif + + + /* This structure defines an array of points. X coordinates are stored in the even-numbered + * indices, and Y coordinates are stored in the odd-numbered indices. num_points indicates the + * number of points, so the array is 2*num_points elements big. + */ + typedef struct + { + double *coords; + int num_points; + int ref_count; + } EelCanvasPoints; + + + /* Allocate a new EelCanvasPoints structure with enough space for the specified number of points */ + EelCanvasPoints *eel_canvas_points_new (int num_points); + + /* Increate ref count */ + EelCanvasPoints *eel_canvas_points_ref (EelCanvasPoints *points); +#define eel_canvas_points_unref eel_canvas_points_free + + /* Decrease ref count and free structure if it has reached zero */ + void eel_canvas_points_free (EelCanvasPoints *points); + + /* Given three points forming an angle, compute the coordinates of the inside and outside points of + * the mitered corner formed by a line of a given width at that angle. + * + * If the angle is less than 11 degrees, then FALSE is returned and the return points are not + * modified. Otherwise, TRUE is returned. + */ + int eel_canvas_get_miter_points (double x1, double y1, double x2, double y2, double x3, double y3, + double width, + double *mx1, double *my1, double *mx2, double *my2); + + /* Compute the butt points of a line segment. If project is FALSE, then the results are as follows: + * + * -------------------* (bx1, by1) + * | + * (x1, y1) *------------------* (x2, y2) + * | + * -------------------* (bx2, by2) + * + * that is, the line is not projected beyond (x2, y2). If project is TRUE, then the results are as + * follows: + * + * -------------------* (bx1, by1) + * (x2, y2) | + * (x1, y1) *-------------* | + * | + * -------------------* (bx2, by2) + */ + void eel_canvas_get_butt_points (double x1, double y1, double x2, double y2, + double width, int project, + double *bx1, double *by1, double *bx2, double *by2); + + /* Calculate the distance from a polygon to a point. The polygon's X coordinates are in the even + * indices of the poly array, and the Y coordinates are in the odd indices. + */ + double eel_canvas_polygon_to_point (double *poly, int num_points, double x, double y); + + + void eel_canvas_item_reset_bounds (EelCanvasItem *item); + + /* Sets the bbox to the new value, requesting full repaint. */ + void eel_canvas_update_bbox (EelCanvasItem *item, int x1, int y1, int x2, int y2); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/eel/eel-canvas.c b/eel/eel-canvas.c new file mode 100644 index 00000000..afa038f0 --- /dev/null +++ b/eel/eel-canvas.c @@ -0,0 +1,4213 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: 8; c-basic-offset: 8 -*- */ +/* + * Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation + * All rights reserved. + * + * This file is part of the Mate Library. + * + * The Mate Library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * The Mate Library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the Mate Library; see the file COPYING.LIB. If not, + * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ +/* + @NOTATION@ + */ +/* + * EelCanvas widget - Tk-like canvas widget for Mate + * + * EelCanvas is basically a port of the Tk toolkit's most excellent canvas widget. Tk is + * copyrighted by the Regents of the University of California, Sun Microsystems, and other parties. + * + * + * Authors: Federico Mena + * Raph Levien + */ + +/* + * TO-DO list for the canvas: + * + * - Allow to specify whether EelCanvasImage sizes are in units or pixels (scale or don't scale). + * + * - Implement a flag for eel_canvas_item_reparent() that tells the function to keep the item + * visually in the same place, that is, to keep it in the same place with respect to the canvas + * origin. + * + * - GC put functions for items. + * + * - Widget item (finish it). + * + * - GList *eel_canvas_gimme_all_items_contained_in_this_area (EelCanvas *canvas, Rectangle area); + * + * - Retrofit all the primitive items with microtile support. + * + * - Curve support for line item. + * + * - Arc item (Havoc has it; to be integrated in EelCanvasEllipse). + * + * - Sane font handling API. + * + * - Get_arg methods for items: + * - How to fetch the outline width and know whether it is in pixels or units? + */ + +#include + +#include +#include +#include +#include +#include +#include "eel-canvas.h" +#include "eel-i18n.h" + +#include "eel-marshal.h" + +static void eel_canvas_request_update (EelCanvas *canvas); +static void group_add (EelCanvasGroup *group, + EelCanvasItem *item); +static void group_remove (EelCanvasGroup *group, + EelCanvasItem *item); +static void redraw_and_repick_if_mapped (EelCanvasItem *item); + +/*** EelCanvasItem ***/ + +/* Some convenience stuff */ +#define GCI_UPDATE_MASK (EEL_CANVAS_UPDATE_REQUESTED | EEL_CANVAS_UPDATE_DEEP) +#define GCI_EPSILON 1e-18 + +enum +{ + ITEM_PROP_0, + ITEM_PROP_PARENT, + ITEM_PROP_VISIBLE +}; + +enum +{ + ITEM_EVENT, + ITEM_LAST_SIGNAL +}; + +static void eel_canvas_item_class_init (EelCanvasItemClass *klass); +static void eel_canvas_item_init (EelCanvasItem *item); +static int emit_event (EelCanvas *canvas, GdkEvent *event); + +static guint item_signals[ITEM_LAST_SIGNAL]; + +static GtkObjectClass *item_parent_class; + +static gpointer accessible_item_parent_class; +static gpointer accessible_parent_class; + + +/** + * eel_canvas_item_get_type: + * + * Registers the &EelCanvasItem class if necessary, and returns the type ID + * associated to it. + * + * Return value: The type ID of the &EelCanvasItem class. + **/ +GType +eel_canvas_item_get_type (void) +{ + static GType canvas_item_type = 0; + + if (!canvas_item_type) + { + static const GTypeInfo canvas_item_info = + { + sizeof (EelCanvasItemClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) eel_canvas_item_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (EelCanvasItem), + 0, /* n_preallocs */ + (GInstanceInitFunc) eel_canvas_item_init + }; + + canvas_item_type = g_type_register_static (gtk_object_get_type (), + "EelCanvasItem", + &canvas_item_info, + 0); + } + + return canvas_item_type; +} + +/* Object initialization function for EelCanvasItem */ +static void +eel_canvas_item_init (EelCanvasItem *item) +{ + item->flags |= EEL_CANVAS_ITEM_VISIBLE; +} + +/** + * eel_canvas_item_new: + * @parent: The parent group for the new item. + * @type: The object type of the item. + * @first_arg_name: A list of object argument name/value pairs, NULL-terminated, + * used to configure the item. For example, "fill_color", "black", + * "width_units", 5.0, NULL. + * @Varargs: + * + * Creates a new canvas item with @parent as its parent group. The item is + * created at the top of its parent's stack, and starts up as visible. The item + * is of the specified @type, for example, it can be + * eel_canvas_rect_get_type(). The list of object arguments/value pairs is + * used to configure the item. + * + * Return value: The newly-created item. + **/ +EelCanvasItem * +eel_canvas_item_new (EelCanvasGroup *parent, GType type, const gchar *first_arg_name, ...) +{ + EelCanvasItem *item; + va_list args; + + g_return_val_if_fail (EEL_IS_CANVAS_GROUP (parent), NULL); + g_return_val_if_fail (g_type_is_a (type, eel_canvas_item_get_type ()), NULL); + + item = EEL_CANVAS_ITEM (g_object_new (type, NULL)); + + va_start (args, first_arg_name); + eel_canvas_item_construct (item, parent, first_arg_name, args); + va_end (args); + + return item; +} + + +/* Performs post-creation operations on a canvas item (adding it to its parent + * group, etc.) + */ +static void +item_post_create_setup (EelCanvasItem *item) +{ + group_add (EEL_CANVAS_GROUP (item->parent), item); + + redraw_and_repick_if_mapped (item); +} + +/* Set_property handler for canvas items */ +static void +eel_canvas_item_set_property (GObject *gobject, guint param_id, + const GValue *value, GParamSpec *pspec) +{ + EelCanvasItem *item; + + g_return_if_fail (EEL_IS_CANVAS_ITEM (gobject)); + + item = EEL_CANVAS_ITEM (gobject); + + switch (param_id) + { + case ITEM_PROP_PARENT: + if (item->parent != NULL) + { + g_warning ("Cannot set `parent' argument after item has " + "already been constructed."); + } + else if (g_value_get_object (value)) + { + item->parent = EEL_CANVAS_ITEM (g_value_get_object (value)); + item->canvas = item->parent->canvas; + item_post_create_setup (item); + } + break; + case ITEM_PROP_VISIBLE: + if (g_value_get_boolean (value)) + { + eel_canvas_item_show (item); + } + else + { + eel_canvas_item_hide (item); + } + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, param_id, pspec); + break; + } +} + +/* Get_property handler for canvas items */ +static void +eel_canvas_item_get_property (GObject *gobject, guint param_id, + GValue *value, GParamSpec *pspec) +{ + EelCanvasItem *item; + + g_return_if_fail (EEL_IS_CANVAS_ITEM (gobject)); + + item = EEL_CANVAS_ITEM (gobject); + + switch (param_id) + { + case ITEM_PROP_VISIBLE: + g_value_set_boolean (value, item->flags & EEL_CANVAS_ITEM_VISIBLE); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, param_id, pspec); + break; + } +} + +/** + * eel_canvas_item_construct: + * @item: An unconstructed canvas item. + * @parent: The parent group for the item. + * @first_arg_name: The name of the first argument for configuring the item. + * @args: The list of arguments used to configure the item. + * + * Constructs a canvas item; meant for use only by item implementations. + **/ +void +eel_canvas_item_construct (EelCanvasItem *item, EelCanvasGroup *parent, + const gchar *first_arg_name, va_list args) +{ + g_return_if_fail (EEL_IS_CANVAS_GROUP (parent)); + g_return_if_fail (EEL_IS_CANVAS_ITEM (item)); + + item->parent = EEL_CANVAS_ITEM (parent); + item->canvas = item->parent->canvas; + + g_object_set_valist (G_OBJECT (item), first_arg_name, args); + + item_post_create_setup (item); +} + + +static void +redraw_and_repick_if_mapped (EelCanvasItem *item) +{ + if (item->flags & EEL_CANVAS_ITEM_MAPPED) + { + eel_canvas_item_request_redraw (item); + item->canvas->need_repick = TRUE; + } +} + +/* Dispose handler for canvas items */ +static void +eel_canvas_item_dispose (GObject *object) +{ + EelCanvasItem *item; + + g_return_if_fail (EEL_IS_CANVAS_ITEM (object)); + + item = EEL_CANVAS_ITEM (object); + + if (item->canvas) + { + eel_canvas_item_request_redraw (item); + + /* Make the canvas forget about us */ + + if (item == item->canvas->current_item) + { + item->canvas->current_item = NULL; + item->canvas->need_repick = TRUE; + } + + if (item == item->canvas->new_current_item) + { + item->canvas->new_current_item = NULL; + item->canvas->need_repick = TRUE; + } + + if (item == item->canvas->grabbed_item) + { + GdkDisplay *display = gtk_widget_get_display (GTK_WIDGET (item->canvas)); + item->canvas->grabbed_item = NULL; + gdk_display_pointer_ungrab (display, GDK_CURRENT_TIME); + } + + if (item == item->canvas->focused_item) + item->canvas->focused_item = NULL; + + /* Normal destroy stuff */ + + if (item->flags & EEL_CANVAS_ITEM_MAPPED) + (* EEL_CANVAS_ITEM_GET_CLASS (item)->unmap) (item); + + if (item->flags & EEL_CANVAS_ITEM_REALIZED) + (* EEL_CANVAS_ITEM_GET_CLASS (item)->unrealize) (item); + + if (item->parent) + group_remove (EEL_CANVAS_GROUP (item->parent), item); + + item->canvas = NULL; + } + + G_OBJECT_CLASS (item_parent_class)->dispose (object); +} + + +/* Realize handler for canvas items */ +static void +eel_canvas_item_realize (EelCanvasItem *item) +{ + if (item->parent && !(item->parent->flags & EEL_CANVAS_ITEM_REALIZED)) + (* EEL_CANVAS_ITEM_GET_CLASS (item->parent)->realize) (item->parent); + + if (item->parent == NULL && !gtk_widget_get_realized (GTK_WIDGET (item->canvas))) + gtk_widget_realize (GTK_WIDGET (item->canvas)); + + item->flags |= EEL_CANVAS_ITEM_REALIZED; + + eel_canvas_item_request_update (item); +} + +/* Unrealize handler for canvas items */ +static void +eel_canvas_item_unrealize (EelCanvasItem *item) +{ + if (item->flags & EEL_CANVAS_ITEM_MAPPED) + (* EEL_CANVAS_ITEM_GET_CLASS (item)->unmap) (item); + + item->flags &= ~(EEL_CANVAS_ITEM_REALIZED); +} + +/* Map handler for canvas items */ +static void +eel_canvas_item_map (EelCanvasItem *item) +{ + item->flags |= EEL_CANVAS_ITEM_MAPPED; +} + +/* Unmap handler for canvas items */ +static void +eel_canvas_item_unmap (EelCanvasItem *item) +{ + item->flags &= ~(EEL_CANVAS_ITEM_MAPPED); +} + +/* Update handler for canvas items */ +static void +eel_canvas_item_update (EelCanvasItem *item, double i2w_dx, double i2w_dy, int flags) +{ + item->flags &= ~(EEL_CANVAS_ITEM_NEED_UPDATE); + item->flags &= ~(EEL_CANVAS_ITEM_NEED_DEEP_UPDATE); +} + +/* + * This routine invokes the update method of the item + * Please notice, that we take parent to canvas pixel matrix as argument + * unlike virtual method ::update, whose argument is item 2 canvas pixel + * matrix + * + * I will try to force somewhat meaningful naming for affines (Lauris) + * General naming rule is FROM2TO, where FROM and TO are abbreviations + * So p2cpx is Parent2CanvasPixel and i2cpx is Item2CanvasPixel + * I hope that this helps to keep track of what really happens + * + */ + +static void +eel_canvas_item_invoke_update (EelCanvasItem *item, + double i2w_dx, + double i2w_dy, + int flags) +{ + int child_flags; + + child_flags = flags; + + /* apply object flags to child flags */ + child_flags &= ~EEL_CANVAS_UPDATE_REQUESTED; + + if (item->flags & EEL_CANVAS_ITEM_NEED_UPDATE) + child_flags |= EEL_CANVAS_UPDATE_REQUESTED; + + if (item->flags & EEL_CANVAS_ITEM_NEED_DEEP_UPDATE) + child_flags |= EEL_CANVAS_UPDATE_DEEP; + + if (child_flags & GCI_UPDATE_MASK) + { + if (EEL_CANVAS_ITEM_GET_CLASS (item)->update) + EEL_CANVAS_ITEM_GET_CLASS (item)->update (item, i2w_dx, i2w_dy, child_flags); + } + + /* If this fail you probably forgot to chain up to + * EelCanvasItem::update from a derived class */ + g_return_if_fail (!(item->flags & EEL_CANVAS_ITEM_NEED_UPDATE)); +} + +/* + * This routine invokes the point method of the item. + * The arguments x, y should be in the parent item local coordinates. + */ + +static double +eel_canvas_item_invoke_point (EelCanvasItem *item, double x, double y, int cx, int cy, EelCanvasItem **actual_item) +{ + /* Calculate x & y in item local coordinates */ + + if (EEL_CANVAS_ITEM_GET_CLASS (item)->point) + return EEL_CANVAS_ITEM_GET_CLASS (item)->point (item, x, y, cx, cy, actual_item); + + return 1e18; +} + +/** + * eel_canvas_item_set: + * @item: A canvas item. + * @first_arg_name: The list of object argument name/value pairs used to configure the item. + * @Varargs: + * + * Configures a canvas item. The arguments in the item are set to the specified + * values, and the item is repainted as appropriate. + **/ +void +eel_canvas_item_set (EelCanvasItem *item, const gchar *first_arg_name, ...) +{ + va_list args; + + va_start (args, first_arg_name); + eel_canvas_item_set_valist (item, first_arg_name, args); + va_end (args); +} + + +/** + * eel_canvas_item_set_valist: + * @item: A canvas item. + * @first_arg_name: The name of the first argument used to configure the item. + * @args: The list of object argument name/value pairs used to configure the item. + * + * Configures a canvas item. The arguments in the item are set to the specified + * values, and the item is repainted as appropriate. + **/ +void +eel_canvas_item_set_valist (EelCanvasItem *item, const gchar *first_arg_name, va_list args) +{ + g_return_if_fail (EEL_IS_CANVAS_ITEM (item)); + + g_object_set_valist (G_OBJECT (item), first_arg_name, args); + +#if 0 + /* I commented this out, because item implementations have to schedule update/redraw */ + eel_canvas_item_request_redraw (item); +#endif + + item->canvas->need_repick = TRUE; +} + + +/** + * eel_canvas_item_move: + * @item: A canvas item. + * @dx: Horizontal offset. + * @dy: Vertical offset. + * + * Moves a canvas item by creating an affine transformation matrix for + * translation by using the specified values. This happens in item + * local coordinate system, so if you have nontrivial transform, it + * most probably does not do, what you want. + **/ +void +eel_canvas_item_move (EelCanvasItem *item, double dx, double dy) +{ + g_return_if_fail (item != NULL); + g_return_if_fail (EEL_IS_CANVAS_ITEM (item)); + + if (!EEL_CANVAS_ITEM_GET_CLASS (item)->translate) + { + g_warning ("Item type %s does not implement translate method.\n", + g_type_name (G_OBJECT_TYPE (item))); + return; + } + + (* EEL_CANVAS_ITEM_GET_CLASS (item)->translate) (item, dx, dy); + + if (item->flags & EEL_CANVAS_ITEM_MAPPED) + item->canvas->need_repick = TRUE; + + if (!(item->flags & EEL_CANVAS_ITEM_NEED_DEEP_UPDATE)) + { + item->flags |= EEL_CANVAS_ITEM_NEED_DEEP_UPDATE; + if (item->parent != NULL) + eel_canvas_item_request_update (item->parent); + else + eel_canvas_request_update (item->canvas); + } + +} + +/* Convenience function to reorder items in a group's child list. This puts the + * specified link after the "before" link. Returns TRUE if the list was changed. + */ +static gboolean +put_item_after (GList *link, GList *before) +{ + EelCanvasGroup *parent; + + if (link == before) + return FALSE; + + parent = EEL_CANVAS_GROUP (EEL_CANVAS_ITEM (link->data)->parent); + + if (before == NULL) + { + if (link == parent->item_list) + return FALSE; + + link->prev->next = link->next; + + if (link->next) + link->next->prev = link->prev; + else + parent->item_list_end = link->prev; + + link->prev = before; + link->next = parent->item_list; + link->next->prev = link; + parent->item_list = link; + } + else + { + if ((link == parent->item_list_end) && (before == parent->item_list_end->prev)) + return FALSE; + + if (link->next) + link->next->prev = link->prev; + + if (link->prev) + link->prev->next = link->next; + else + { + parent->item_list = link->next; + parent->item_list->prev = NULL; + } + + link->prev = before; + link->next = before->next; + + link->prev->next = link; + + if (link->next) + link->next->prev = link; + else + parent->item_list_end = link; + } + return TRUE; +} + + +/** + * eel_canvas_item_raise: + * @item: A canvas item. + * @positions: Number of steps to raise the item. + * + * Raises the item in its parent's stack by the specified number of positions. + * If the number of positions is greater than the distance to the top of the + * stack, then the item is put at the top. + **/ +void +eel_canvas_item_raise (EelCanvasItem *item, int positions) +{ + GList *link, *before; + EelCanvasGroup *parent; + + g_return_if_fail (EEL_IS_CANVAS_ITEM (item)); + g_return_if_fail (positions >= 0); + + if (!item->parent || positions == 0) + return; + + parent = EEL_CANVAS_GROUP (item->parent); + link = g_list_find (parent->item_list, item); + g_assert (link != NULL); + + for (before = link; positions && before; positions--) + before = before->next; + + if (!before) + before = parent->item_list_end; + + if (put_item_after (link, before)) + { + redraw_and_repick_if_mapped (item); + } +} + + +/** + * eel_canvas_item_lower: + * @item: A canvas item. + * @positions: Number of steps to lower the item. + * + * Lowers the item in its parent's stack by the specified number of positions. + * If the number of positions is greater than the distance to the bottom of the + * stack, then the item is put at the bottom. + **/ +void +eel_canvas_item_lower (EelCanvasItem *item, int positions) +{ + GList *link, *before; + EelCanvasGroup *parent; + + g_return_if_fail (EEL_IS_CANVAS_ITEM (item)); + g_return_if_fail (positions >= 1); + + if (!item->parent || positions == 0) + return; + + parent = EEL_CANVAS_GROUP (item->parent); + link = g_list_find (parent->item_list, item); + g_assert (link != NULL); + + if (link->prev) + for (before = link->prev; positions && before; positions--) + before = before->prev; + else + before = NULL; + + if (put_item_after (link, before)) + { + redraw_and_repick_if_mapped (item); + } +} + + +/** + * eel_canvas_item_raise_to_top: + * @item: A canvas item. + * + * Raises an item to the top of its parent's stack. + **/ +void +eel_canvas_item_raise_to_top (EelCanvasItem *item) +{ + GList *link; + EelCanvasGroup *parent; + + g_return_if_fail (EEL_IS_CANVAS_ITEM (item)); + + if (!item->parent) + return; + + parent = EEL_CANVAS_GROUP (item->parent); + link = g_list_find (parent->item_list, item); + g_assert (link != NULL); + + if (put_item_after (link, parent->item_list_end)) + { + redraw_and_repick_if_mapped (item); + } +} + + +/** + * eel_canvas_item_lower_to_bottom: + * @item: A canvas item. + * + * Lowers an item to the bottom of its parent's stack. + **/ +void +eel_canvas_item_lower_to_bottom (EelCanvasItem *item) +{ + GList *link; + EelCanvasGroup *parent; + + g_return_if_fail (EEL_IS_CANVAS_ITEM (item)); + + if (!item->parent) + return; + + parent = EEL_CANVAS_GROUP (item->parent); + link = g_list_find (parent->item_list, item); + g_assert (link != NULL); + + if (put_item_after (link, NULL)) + { + redraw_and_repick_if_mapped (item); + } +} + +/** + * eel_canvas_item_send_behind: + * @item: A canvas item. + * @behind_item: The canvas item to put item behind, or NULL + * + * Moves item to a in the position in the stacking order so that + * it is placed immediately below behind_item, or at the top if + * behind_item is NULL. + **/ +void +eel_canvas_item_send_behind (EelCanvasItem *item, + EelCanvasItem *behind_item) +{ + GList *item_list; + int item_position, behind_position; + + g_return_if_fail (EEL_IS_CANVAS_ITEM (item)); + + if (behind_item == NULL) + { + eel_canvas_item_raise_to_top (item); + return; + } + + g_return_if_fail (EEL_IS_CANVAS_ITEM (behind_item)); + g_return_if_fail (item->parent == behind_item->parent); + + item_list = EEL_CANVAS_GROUP (item->parent)->item_list; + + item_position = g_list_index (item_list, item); + g_assert (item_position != -1); + behind_position = g_list_index (item_list, behind_item); + g_assert (behind_position != -1); + g_assert (item_position != behind_position); + + if (item_position == behind_position - 1) + { + return; + } + + if (item_position < behind_position) + { + eel_canvas_item_raise (item, (behind_position - 1) - item_position); + } + else + { + eel_canvas_item_lower (item, item_position - behind_position); + } +} + +/** + * eel_canvas_item_show: + * @item: A canvas item. + * + * Shows a canvas item. If the item was already shown, then no action is taken. + **/ +void +eel_canvas_item_show (EelCanvasItem *item) +{ + g_return_if_fail (EEL_IS_CANVAS_ITEM (item)); + + if (!(item->flags & EEL_CANVAS_ITEM_VISIBLE)) + { + item->flags |= EEL_CANVAS_ITEM_VISIBLE; + + if (!(item->flags & EEL_CANVAS_ITEM_REALIZED)) + (* EEL_CANVAS_ITEM_GET_CLASS (item)->realize) (item); + + if (item->parent != NULL) + { + if (!(item->flags & EEL_CANVAS_ITEM_MAPPED) && + item->parent->flags & EEL_CANVAS_ITEM_MAPPED) + (* EEL_CANVAS_ITEM_GET_CLASS (item)->map) (item); + } + else + { + if (!(item->flags & EEL_CANVAS_ITEM_MAPPED) && + gtk_widget_get_mapped (GTK_WIDGET (item->canvas))) + (* EEL_CANVAS_ITEM_GET_CLASS (item)->map) (item); + } + + redraw_and_repick_if_mapped (item); + } +} + + +/** + * eel_canvas_item_hide: + * @item: A canvas item. + * + * Hides a canvas item. If the item was already hidden, then no action is + * taken. + **/ +void +eel_canvas_item_hide (EelCanvasItem *item) +{ + g_return_if_fail (EEL_IS_CANVAS_ITEM (item)); + + if (item->flags & EEL_CANVAS_ITEM_VISIBLE) + { + item->flags &= ~EEL_CANVAS_ITEM_VISIBLE; + + redraw_and_repick_if_mapped (item); + + if (item->flags & EEL_CANVAS_ITEM_MAPPED) + (* EEL_CANVAS_ITEM_GET_CLASS (item)->unmap) (item); + + /* No need to unrealize when we just want to hide */ + } +} + + +/** + * eel_canvas_item_grab: + * @item: A canvas item. + * @event_mask: Mask of events that will be sent to this item. + * @cursor: If non-NULL, the cursor that will be used while the grab is active. + * @etime: The timestamp required for grabbing the mouse, or GDK_CURRENT_TIME. + * + * Specifies that all events that match the specified event mask should be sent + * to the specified item, and also grabs the mouse by calling + * gdk_pointer_grab(). The event mask is also used when grabbing the pointer. + * If @cursor is not NULL, then that cursor is used while the grab is active. + * The @etime parameter is the timestamp required for grabbing the mouse. + * + * Return value: If an item was already grabbed, it returns %GDK_GRAB_ALREADY_GRABBED. If + * the specified item was hidden by calling eel_canvas_item_hide(), then it + * returns %GDK_GRAB_NOT_VIEWABLE. Else, it returns the result of calling + * gdk_pointer_grab(). + **/ +int +eel_canvas_item_grab (EelCanvasItem *item, guint event_mask, GdkCursor *cursor, guint32 etime) +{ + int retval; + + g_return_val_if_fail (EEL_IS_CANVAS_ITEM (item), GDK_GRAB_NOT_VIEWABLE); + g_return_val_if_fail (gtk_widget_get_mapped (GTK_WIDGET (item->canvas)), + GDK_GRAB_NOT_VIEWABLE); + + if (item->canvas->grabbed_item) + return GDK_GRAB_ALREADY_GRABBED; + + if (!(item->flags & EEL_CANVAS_ITEM_MAPPED)) + return GDK_GRAB_NOT_VIEWABLE; + + retval = gdk_pointer_grab (gtk_layout_get_bin_window (&item->canvas->layout), + FALSE, + event_mask, + NULL, + cursor, + etime); + + if (retval != GDK_GRAB_SUCCESS) + return retval; + + item->canvas->grabbed_item = item; + item->canvas->grabbed_event_mask = event_mask; + item->canvas->current_item = item; /* So that events go to the grabbed item */ + + return retval; +} + + +/** + * eel_canvas_item_ungrab: + * @item: A canvas item that holds a grab. + * @etime: The timestamp for ungrabbing the mouse. + * + * Ungrabs the item, which must have been grabbed in the canvas, and ungrabs the + * mouse. + **/ +void +eel_canvas_item_ungrab (EelCanvasItem *item, guint32 etime) +{ + GdkDisplay *display; + + g_return_if_fail (EEL_IS_CANVAS_ITEM (item)); + + if (item->canvas->grabbed_item != item) + return; + + display = gtk_widget_get_display (GTK_WIDGET (item->canvas)); + item->canvas->grabbed_item = NULL; + gdk_display_pointer_ungrab (display, etime); +} + + +/** + * eel_canvas_item_w2i: + * @item: A canvas item. + * @x: X coordinate to convert (input/output value). + * @y: Y coordinate to convert (input/output value). + * + * Converts a coordinate pair from world coordinates to item-relative + * coordinates. + **/ +void +eel_canvas_item_w2i (EelCanvasItem *item, double *x, double *y) +{ + g_return_if_fail (EEL_IS_CANVAS_ITEM (item)); + g_return_if_fail (x != NULL); + g_return_if_fail (y != NULL); + + item = item->parent; + while (item) + { + if (EEL_IS_CANVAS_GROUP (item)) + { + *x -= EEL_CANVAS_GROUP (item)->xpos; + *y -= EEL_CANVAS_GROUP (item)->ypos; + } + + item = item->parent; + } +} + + +/** + * eel_canvas_item_i2w: + * @item: A canvas item. + * @x: X coordinate to convert (input/output value). + * @y: Y coordinate to convert (input/output value). + * + * Converts a coordinate pair from item-relative coordinates to world + * coordinates. + **/ +void +eel_canvas_item_i2w (EelCanvasItem *item, double *x, double *y) +{ + g_return_if_fail (EEL_IS_CANVAS_ITEM (item)); + g_return_if_fail (x != NULL); + g_return_if_fail (y != NULL); + + item = item->parent; + while (item) + { + if (EEL_IS_CANVAS_GROUP (item)) + { + *x += EEL_CANVAS_GROUP (item)->xpos; + *y += EEL_CANVAS_GROUP (item)->ypos; + } + + item = item->parent; + } +} + +/* Returns whether the item is an inferior of or is equal to the parent. */ +static int +is_descendant (EelCanvasItem *item, EelCanvasItem *parent) +{ + for (; item; item = item->parent) + if (item == parent) + return TRUE; + + return FALSE; +} + +/** + * eel_canvas_item_reparent: + * @item: A canvas item. + * @new_group: A canvas group. + * + * Changes the parent of the specified item to be the new group. The item keeps + * its group-relative coordinates as for its old parent, so the item may change + * its absolute position within the canvas. + **/ +void +eel_canvas_item_reparent (EelCanvasItem *item, EelCanvasGroup *new_group) +{ + g_return_if_fail (EEL_IS_CANVAS_ITEM (item)); + g_return_if_fail (EEL_IS_CANVAS_GROUP (new_group)); + + /* Both items need to be in the same canvas */ + g_return_if_fail (item->canvas == EEL_CANVAS_ITEM (new_group)->canvas); + + /* The group cannot be an inferior of the item or be the item itself -- + * this also takes care of the case where the item is the root item of + * the canvas. */ + g_return_if_fail (!is_descendant (EEL_CANVAS_ITEM (new_group), item)); + + /* Everything is ok, now actually reparent the item */ + + g_object_ref (G_OBJECT (item)); /* protect it from the unref in group_remove */ + + eel_canvas_item_request_redraw (item); + + group_remove (EEL_CANVAS_GROUP (item->parent), item); + item->parent = EEL_CANVAS_ITEM (new_group); + /* item->canvas is unchanged. */ + group_add (new_group, item); + + /* Redraw and repick */ + + redraw_and_repick_if_mapped (item); + + g_object_unref (G_OBJECT (item)); +} + +/** + * eel_canvas_item_grab_focus: + * @item: A canvas item. + * + * Makes the specified item take the keyboard focus, so all keyboard events will + * be sent to it. If the canvas widget itself did not have the focus, it grabs + * it as well. + **/ +void +eel_canvas_item_grab_focus (EelCanvasItem *item) +{ + EelCanvasItem *focused_item; + GdkEvent ev; + + g_return_if_fail (EEL_IS_CANVAS_ITEM (item)); + g_return_if_fail (gtk_widget_get_can_focus (GTK_WIDGET (item->canvas))); + + focused_item = item->canvas->focused_item; + + if (focused_item) + { + ev.focus_change.type = GDK_FOCUS_CHANGE; + ev.focus_change.window = gtk_layout_get_bin_window (GTK_LAYOUT (item->canvas)); + ev.focus_change.send_event = FALSE; + ev.focus_change.in = FALSE; + + emit_event (item->canvas, &ev); + } + + item->canvas->focused_item = item; + gtk_widget_grab_focus (GTK_WIDGET (item->canvas)); + + if (focused_item) + { + ev.focus_change.type = GDK_FOCUS_CHANGE; + ev.focus_change.window = gtk_layout_get_bin_window (GTK_LAYOUT (item->canvas)); + ev.focus_change.send_event = FALSE; + ev.focus_change.in = TRUE; + + emit_event (item->canvas, &ev); + } +} + + +/** + * eel_canvas_item_get_bounds: + * @item: A canvas item. + * @x1: Leftmost edge of the bounding box (return value). + * @y1: Upper edge of the bounding box (return value). + * @x2: Rightmost edge of the bounding box (return value). + * @y2: Lower edge of the bounding box (return value). + * + * Queries the bounding box of a canvas item. The bounds are returned in the + * coordinate system of the item's parent. + **/ +void +eel_canvas_item_get_bounds (EelCanvasItem *item, double *x1, double *y1, double *x2, double *y2) +{ + double tx1, ty1, tx2, ty2; + + g_return_if_fail (EEL_IS_CANVAS_ITEM (item)); + + tx1 = ty1 = tx2 = ty2 = 0.0; + + /* Get the item's bounds in its coordinate system */ + + if (EEL_CANVAS_ITEM_GET_CLASS (item)->bounds) + (* EEL_CANVAS_ITEM_GET_CLASS (item)->bounds) (item, &tx1, &ty1, &tx2, &ty2); + + /* Return the values */ + + if (x1) + *x1 = tx1; + + if (y1) + *y1 = ty1; + + if (x2) + *x2 = tx2; + + if (y2) + *y2 = ty2; +} + + +/** + * eel_canvas_item_request_update + * @item: A canvas item. + * + * To be used only by item implementations. Requests that the canvas queue an + * update for the specified item. + **/ +void +eel_canvas_item_request_update (EelCanvasItem *item) +{ + if (NULL == item->canvas) + return; + + g_return_if_fail (!item->canvas->doing_update); + + if (item->flags & EEL_CANVAS_ITEM_NEED_UPDATE) + return; + + item->flags |= EEL_CANVAS_ITEM_NEED_UPDATE; + + if (item->parent != NULL) + { + /* Recurse up the tree */ + eel_canvas_item_request_update (item->parent); + } + else + { + /* Have reached the top of the tree, make sure the update call gets scheduled. */ + eel_canvas_request_update (item->canvas); + } +} + +/** + * eel_canvas_item_request_update + * @item: A canvas item. + * + * Convenience function that informs a canvas that the specified item needs + * to be repainted. To be used by item implementations + **/ +void +eel_canvas_item_request_redraw (EelCanvasItem *item) +{ + if (item->flags & EEL_CANVAS_ITEM_MAPPED) + eel_canvas_request_redraw (item->canvas, + item->x1, item->y1, + item->x2 + 1, item->y2 + 1); +} + + + +/*** EelCanvasGroup ***/ + + +enum +{ + GROUP_PROP_0, + GROUP_PROP_X, + GROUP_PROP_Y +}; + + +static void eel_canvas_group_class_init (EelCanvasGroupClass *klass); +static void eel_canvas_group_init (EelCanvasGroup *group); +static void eel_canvas_group_set_property(GObject *object, + guint param_id, + const GValue *value, + GParamSpec *pspec); +static void eel_canvas_group_get_property(GObject *object, + guint param_id, + GValue *value, + GParamSpec *pspec); + +static void eel_canvas_group_destroy (GtkObject *object); + +static void eel_canvas_group_update (EelCanvasItem *item, + double i2w_dx, + double i2w_dy, + int flags); +static void eel_canvas_group_unrealize (EelCanvasItem *item); +static void eel_canvas_group_map (EelCanvasItem *item); +static void eel_canvas_group_unmap (EelCanvasItem *item); +static void eel_canvas_group_draw (EelCanvasItem *item, GdkDrawable *drawable, + GdkEventExpose *expose); +static double eel_canvas_group_point (EelCanvasItem *item, double x, double y, + int cx, int cy, + EelCanvasItem **actual_item); +static void eel_canvas_group_translate (EelCanvasItem *item, double dx, double dy); +static void eel_canvas_group_bounds (EelCanvasItem *item, double *x1, double *y1, + double *x2, double *y2); + + +static EelCanvasItemClass *group_parent_class; + + +/** + * eel_canvas_group_get_type: + * + * Registers the &EelCanvasGroup class if necessary, and returns the type ID + * associated to it. + * + * Return value: The type ID of the &EelCanvasGroup class. + **/ +GType +eel_canvas_group_get_type (void) +{ + static GType group_type = 0; + + if (!group_type) + { + static const GTypeInfo group_info = + { + sizeof (EelCanvasGroupClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) eel_canvas_group_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (EelCanvasGroup), + 0, /* n_preallocs */ + (GInstanceInitFunc) eel_canvas_group_init + + + }; + + group_type = g_type_register_static (eel_canvas_item_get_type (), + "EelCanvasGroup", + &group_info, + 0); + } + + return group_type; +} + +/* Class initialization function for EelCanvasGroupClass */ +static void +eel_canvas_group_class_init (EelCanvasGroupClass *klass) +{ + GObjectClass *gobject_class; + GtkObjectClass *object_class; + EelCanvasItemClass *item_class; + + gobject_class = (GObjectClass *) klass; + object_class = (GtkObjectClass *) klass; + item_class = (EelCanvasItemClass *) klass; + + group_parent_class = g_type_class_peek_parent (klass); + + gobject_class->set_property = eel_canvas_group_set_property; + gobject_class->get_property = eel_canvas_group_get_property; + + g_object_class_install_property + (gobject_class, GROUP_PROP_X, + g_param_spec_double ("x", + _("X"), + _("X"), + -G_MAXDOUBLE, G_MAXDOUBLE, 0.0, + G_PARAM_READWRITE)); + g_object_class_install_property + (gobject_class, GROUP_PROP_Y, + g_param_spec_double ("y", + _("Y"), + _("Y"), + -G_MAXDOUBLE, G_MAXDOUBLE, 0.0, + G_PARAM_READWRITE)); + + object_class->destroy = eel_canvas_group_destroy; + + item_class->update = eel_canvas_group_update; + item_class->unrealize = eel_canvas_group_unrealize; + item_class->map = eel_canvas_group_map; + item_class->unmap = eel_canvas_group_unmap; + item_class->draw = eel_canvas_group_draw; + item_class->point = eel_canvas_group_point; + item_class->translate = eel_canvas_group_translate; + item_class->bounds = eel_canvas_group_bounds; +} + +/* Object initialization function for EelCanvasGroup */ +static void +eel_canvas_group_init (EelCanvasGroup *group) +{ + group->xpos = 0.0; + group->ypos = 0.0; +} + +/* Set_property handler for canvas groups */ +static void +eel_canvas_group_set_property (GObject *gobject, guint param_id, + const GValue *value, GParamSpec *pspec) +{ + EelCanvasItem *item; + EelCanvasGroup *group; + double old; + gboolean moved; + + g_return_if_fail (EEL_IS_CANVAS_GROUP (gobject)); + + item = EEL_CANVAS_ITEM (gobject); + group = EEL_CANVAS_GROUP (gobject); + + moved = FALSE; + switch (param_id) + { + case GROUP_PROP_X: + old = group->xpos; + group->xpos = g_value_get_double (value); + if (old != group->xpos) + moved = TRUE; + break; + + case GROUP_PROP_Y: + old = group->ypos; + group->ypos = g_value_get_double (value); + if (old != group->ypos) + moved = TRUE; + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, param_id, pspec); + break; + } + + if (moved) + { + item->flags |= EEL_CANVAS_ITEM_NEED_DEEP_UPDATE; + if (item->parent != NULL) + eel_canvas_item_request_update (item->parent); + else + eel_canvas_request_update (item->canvas); + } +} + +/* Get_property handler for canvas groups */ +static void +eel_canvas_group_get_property (GObject *gobject, guint param_id, + GValue *value, GParamSpec *pspec) +{ + EelCanvasItem *item; + EelCanvasGroup *group; + + g_return_if_fail (EEL_IS_CANVAS_GROUP (gobject)); + + item = EEL_CANVAS_ITEM (gobject); + group = EEL_CANVAS_GROUP (gobject); + + switch (param_id) + { + case GROUP_PROP_X: + g_value_set_double (value, group->xpos); + break; + + case GROUP_PROP_Y: + g_value_set_double (value, group->ypos); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, param_id, pspec); + break; + } +} + +/* Destroy handler for canvas groups */ +static void +eel_canvas_group_destroy (GtkObject *object) +{ + EelCanvasGroup *group; + EelCanvasItem *child; + GList *list; + + g_return_if_fail (EEL_IS_CANVAS_GROUP (object)); + + group = EEL_CANVAS_GROUP (object); + + list = group->item_list; + while (list) + { + child = list->data; + list = list->next; + + gtk_object_destroy (GTK_OBJECT (child)); + } + + if (GTK_OBJECT_CLASS (group_parent_class)->destroy) + (* GTK_OBJECT_CLASS (group_parent_class)->destroy) (object); +} + +/* Update handler for canvas groups */ +static void +eel_canvas_group_update (EelCanvasItem *item, double i2w_dx, double i2w_dy, int flags) +{ + EelCanvasGroup *group; + GList *list; + EelCanvasItem *i; + double bbox_x0, bbox_y0, bbox_x1, bbox_y1; + gboolean first = TRUE; + + group = EEL_CANVAS_GROUP (item); + + (* group_parent_class->update) (item, i2w_dx, i2w_dy, flags); + + bbox_x0 = 0; + bbox_y0 = 0; + bbox_x1 = 0; + bbox_y1 = 0; + + for (list = group->item_list; list; list = list->next) + { + i = list->data; + + eel_canvas_item_invoke_update (i, i2w_dx + group->xpos, i2w_dy + group->ypos, flags); + + if (first) + { + first = FALSE; + bbox_x0 = i->x1; + bbox_y0 = i->y1; + bbox_x1 = i->x2; + bbox_y1 = i->y2; + } + else + { + bbox_x0 = MIN (bbox_x0, i->x1); + bbox_y0 = MIN (bbox_y0, i->y1); + bbox_x1 = MAX (bbox_x1, i->x2); + bbox_y1 = MAX (bbox_y1, i->y2); + } + } + item->x1 = bbox_x0; + item->y1 = bbox_y0; + item->x2 = bbox_x1; + item->y2 = bbox_y1; +} + +/* Unrealize handler for canvas groups */ +static void +eel_canvas_group_unrealize (EelCanvasItem *item) +{ + EelCanvasGroup *group; + GList *list; + EelCanvasItem *i; + + group = EEL_CANVAS_GROUP (item); + + /* Unmap group before children to avoid flash */ + if (item->flags & EEL_CANVAS_ITEM_MAPPED) + (* EEL_CANVAS_ITEM_GET_CLASS (item)->unmap) (item); + + for (list = group->item_list; list; list = list->next) + { + i = list->data; + + if (i->flags & EEL_CANVAS_ITEM_REALIZED) + (* EEL_CANVAS_ITEM_GET_CLASS (i)->unrealize) (i); + } + + (* group_parent_class->unrealize) (item); +} + +/* Map handler for canvas groups */ +static void +eel_canvas_group_map (EelCanvasItem *item) +{ + EelCanvasGroup *group; + GList *list; + EelCanvasItem *i; + + group = EEL_CANVAS_GROUP (item); + + for (list = group->item_list; list; list = list->next) + { + i = list->data; + + if (i->flags & EEL_CANVAS_ITEM_VISIBLE && + !(i->flags & EEL_CANVAS_ITEM_MAPPED)) + { + if (!(i->flags & EEL_CANVAS_ITEM_REALIZED)) + (* EEL_CANVAS_ITEM_GET_CLASS (i)->realize) (i); + + (* EEL_CANVAS_ITEM_GET_CLASS (i)->map) (i); + } + } + + (* group_parent_class->map) (item); +} + +/* Unmap handler for canvas groups */ +static void +eel_canvas_group_unmap (EelCanvasItem *item) +{ + EelCanvasGroup *group; + GList *list; + EelCanvasItem *i; + + group = EEL_CANVAS_GROUP (item); + + for (list = group->item_list; list; list = list->next) + { + i = list->data; + + if (i->flags & EEL_CANVAS_ITEM_MAPPED) + (* EEL_CANVAS_ITEM_GET_CLASS (i)->unmap) (i); + } + + (* group_parent_class->unmap) (item); +} + +/* Draw handler for canvas groups */ +static void +eel_canvas_group_draw (EelCanvasItem *item, GdkDrawable *drawable, + GdkEventExpose *expose) +{ + EelCanvasGroup *group; + GList *list; + EelCanvasItem *child = NULL; + + group = EEL_CANVAS_GROUP (item); + + for (list = group->item_list; list; list = list->next) + { + child = list->data; + + if ((child->flags & EEL_CANVAS_ITEM_MAPPED) && + (EEL_CANVAS_ITEM_GET_CLASS (child)->draw)) + { + GdkRectangle child_rect; + + child_rect.x = child->x1; + child_rect.y = child->y1; + child_rect.width = child->x2 - child->x1 + 1; + child_rect.height = child->y2 - child->y1 + 1; + + if (gdk_region_rect_in (expose->region, &child_rect) != GDK_OVERLAP_RECTANGLE_OUT) + (* EEL_CANVAS_ITEM_GET_CLASS (child)->draw) (child, drawable, expose); + } + } +} + +/* Point handler for canvas groups */ +static double +eel_canvas_group_point (EelCanvasItem *item, double x, double y, int cx, int cy, + EelCanvasItem **actual_item) +{ + EelCanvasGroup *group; + GList *list; + EelCanvasItem *child, *point_item; + int x1, y1, x2, y2; + double gx, gy; + double dist, best; + int has_point; + + group = EEL_CANVAS_GROUP (item); + + x1 = cx - item->canvas->close_enough; + y1 = cy - item->canvas->close_enough; + x2 = cx + item->canvas->close_enough; + y2 = cy + item->canvas->close_enough; + + best = 0.0; + *actual_item = NULL; + + gx = x - group->xpos; + gy = y - group->ypos; + + dist = 0.0; /* keep gcc happy */ + + for (list = group->item_list; list; list = list->next) + { + child = list->data; + + if ((child->x1 > x2) || (child->y1 > y2) || (child->x2 < x1) || (child->y2 < y1)) + continue; + + point_item = NULL; /* cater for incomplete item implementations */ + + if ((child->flags & EEL_CANVAS_ITEM_MAPPED) + && EEL_CANVAS_ITEM_GET_CLASS (child)->point) + { + dist = eel_canvas_item_invoke_point (child, gx, gy, cx, cy, &point_item); + has_point = TRUE; + } + else + has_point = FALSE; + + if (has_point + && point_item + && ((int) (dist * item->canvas->pixels_per_unit + 0.5) + <= item->canvas->close_enough)) + { + best = dist; + *actual_item = point_item; + } + } + + return best; +} + +void +eel_canvas_group_translate (EelCanvasItem *item, double dx, double dy) +{ + EelCanvasGroup *group; + + group = EEL_CANVAS_GROUP (item); + + group->xpos += dx; + group->ypos += dy; +} + +/* Bounds handler for canvas groups */ +static void +eel_canvas_group_bounds (EelCanvasItem *item, double *x1, double *y1, double *x2, double *y2) +{ + EelCanvasGroup *group; + EelCanvasItem *child; + GList *list; + double tx1, ty1, tx2, ty2; + double minx, miny, maxx, maxy; + int set; + + group = EEL_CANVAS_GROUP (item); + + /* Get the bounds of the first visible item */ + + child = NULL; /* Unnecessary but eliminates a warning. */ + + set = FALSE; + + for (list = group->item_list; list; list = list->next) + { + child = list->data; + + if (child->flags & EEL_CANVAS_ITEM_MAPPED) + { + set = TRUE; + eel_canvas_item_get_bounds (child, &minx, &miny, &maxx, &maxy); + break; + } + } + + /* If there were no visible items, return an empty bounding box */ + + if (!set) + { + *x1 = *y1 = *x2 = *y2 = 0.0; + return; + } + + /* Now we can grow the bounds using the rest of the items */ + + list = list->next; + + for (; list; list = list->next) + { + child = list->data; + + if (!(child->flags & EEL_CANVAS_ITEM_MAPPED)) + continue; + + eel_canvas_item_get_bounds (child, &tx1, &ty1, &tx2, &ty2); + + if (tx1 < minx) + minx = tx1; + + if (ty1 < miny) + miny = ty1; + + if (tx2 > maxx) + maxx = tx2; + + if (ty2 > maxy) + maxy = ty2; + } + + /* Make the bounds be relative to our parent's coordinate system */ + + if (item->parent) + { + minx += group->xpos; + miny += group->ypos; + maxx += group->xpos; + maxy += group->ypos; + } + + *x1 = minx; + *y1 = miny; + *x2 = maxx; + *y2 = maxy; +} + +/* Adds an item to a group */ +static void +group_add (EelCanvasGroup *group, EelCanvasItem *item) +{ +#if GLIB_CHECK_VERSION(2,10,0) && GTK_CHECK_VERSION(2,8,14) + g_object_ref_sink (item); +#else + g_object_ref (item); + gtk_object_sink (GTK_OBJECT (item)); +#endif + + if (!group->item_list) + { + group->item_list = g_list_append (group->item_list, item); + group->item_list_end = group->item_list; + } + else + group->item_list_end = g_list_append (group->item_list_end, item)->next; + + if (item->flags & EEL_CANVAS_ITEM_VISIBLE && + group->item.flags & EEL_CANVAS_ITEM_MAPPED) + { + if (!(item->flags & EEL_CANVAS_ITEM_REALIZED)) + (* EEL_CANVAS_ITEM_GET_CLASS (item)->realize) (item); + + if (!(item->flags & EEL_CANVAS_ITEM_MAPPED)) + (* EEL_CANVAS_ITEM_GET_CLASS (item)->map) (item); + } +} + +/* Removes an item from a group */ +static void +group_remove (EelCanvasGroup *group, EelCanvasItem *item) +{ + GList *children; + + g_return_if_fail (EEL_IS_CANVAS_GROUP (group)); + g_return_if_fail (EEL_IS_CANVAS_ITEM (item)); + + for (children = group->item_list; children; children = children->next) + if (children->data == item) + { + if (item->flags & EEL_CANVAS_ITEM_MAPPED) + (* EEL_CANVAS_ITEM_GET_CLASS (item)->unmap) (item); + + if (item->flags & EEL_CANVAS_ITEM_REALIZED) + (* EEL_CANVAS_ITEM_GET_CLASS (item)->unrealize) (item); + + /* Unparent the child */ + + item->parent = NULL; + /* item->canvas = NULL; */ + g_object_unref (G_OBJECT (item)); + + /* Remove it from the list */ + + if (children == group->item_list_end) + group->item_list_end = children->prev; + + group->item_list = g_list_remove_link (group->item_list, children); + g_list_free (children); + break; + } +} + + +/*** EelCanvas ***/ + + +enum +{ + DRAW_BACKGROUND, + LAST_SIGNAL +}; + +static void eel_canvas_class_init (EelCanvasClass *klass); +static void eel_canvas_init (EelCanvas *canvas); +static void eel_canvas_destroy (GtkObject *object); +static void eel_canvas_map (GtkWidget *widget); +static void eel_canvas_unmap (GtkWidget *widget); +static void eel_canvas_realize (GtkWidget *widget); +static void eel_canvas_unrealize (GtkWidget *widget); +static void eel_canvas_size_allocate (GtkWidget *widget, + GtkAllocation *allocation); +static gint eel_canvas_button (GtkWidget *widget, + GdkEventButton *event); +static gint eel_canvas_motion (GtkWidget *widget, + GdkEventMotion *event); +static gint eel_canvas_expose (GtkWidget *widget, + GdkEventExpose *event); +static gint eel_canvas_key (GtkWidget *widget, + GdkEventKey *event); +static gint eel_canvas_crossing (GtkWidget *widget, + GdkEventCrossing *event); +static gint eel_canvas_focus_in (GtkWidget *widget, + GdkEventFocus *event); +static gint eel_canvas_focus_out (GtkWidget *widget, + GdkEventFocus *event); +static void eel_canvas_request_update_real (EelCanvas *canvas); +static void eel_canvas_draw_background (EelCanvas *canvas, + int x, + int y, + int width, + int height); + + +static GtkLayoutClass *canvas_parent_class; + +static guint canvas_signals[LAST_SIGNAL]; + +/** + * eel_canvas_get_type: + * + * Registers the &EelCanvas class if necessary, and returns the type ID + * associated to it. + * + * Return value: The type ID of the &EelCanvas class. + **/ +GType +eel_canvas_get_type (void) +{ + static GType canvas_type = 0; + + if (!canvas_type) + { + static const GTypeInfo canvas_info = + { + sizeof (EelCanvasClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) eel_canvas_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (EelCanvas), + 0, /* n_preallocs */ + (GInstanceInitFunc) eel_canvas_init + }; + + canvas_type = g_type_register_static (gtk_layout_get_type (), + "EelCanvas", + &canvas_info, + 0); + } + + return canvas_type; +} + +static void +eel_canvas_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + switch (prop_id) + { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +eel_canvas_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (prop_id) + { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +eel_canvas_accessible_adjustment_changed (GtkAdjustment *adjustment, + gpointer data) +{ + AtkObject *atk_obj; + + /* The scrollbars have changed */ + atk_obj = ATK_OBJECT (data); + + g_signal_emit_by_name (atk_obj, "visible_data_changed"); +} + +static void +eel_canvas_accessible_initialize (AtkObject *obj, + gpointer data) +{ + EelCanvas *canvas; + + if (ATK_OBJECT_CLASS (accessible_parent_class)->initialize != NULL) + ATK_OBJECT_CLASS (accessible_parent_class)->initialize (obj, data); + + canvas = EEL_CANVAS (data); + g_signal_connect (gtk_layout_get_hadjustment (&canvas->layout), + "value_changed", + G_CALLBACK (eel_canvas_accessible_adjustment_changed), + obj); + g_signal_connect (gtk_layout_get_vadjustment (&canvas->layout), + "value_changed", + G_CALLBACK (eel_canvas_accessible_adjustment_changed), + obj); + + obj->role = ATK_ROLE_LAYERED_PANE; +} + +static gint +eel_canvas_accessible_get_n_children (AtkObject* obj) +{ + GtkAccessible *accessible; + GtkWidget *widget; + EelCanvas *canvas; + EelCanvasGroup *root_group; + + accessible = GTK_ACCESSIBLE (obj); + widget = gtk_accessible_get_widget (accessible); + if (widget == NULL) + { + /* State is defunct */ + return 0; + } + + g_return_val_if_fail (EEL_IS_CANVAS (widget), 0); + + canvas = EEL_CANVAS (widget); + root_group = eel_canvas_root (canvas); + g_return_val_if_fail (root_group, 0); + return 1; +} + +static AtkObject* +eel_canvas_accessible_ref_child (AtkObject *obj, + gint i) +{ + GtkAccessible *accessible; + GtkWidget *widget; + EelCanvas *canvas; + EelCanvasGroup *root_group; + AtkObject *atk_object; + + /* Canvas only has one child, so return NULL if index is non zero */ + if (i != 0) + { + return NULL; + } + + accessible = GTK_ACCESSIBLE (obj); + widget = gtk_accessible_get_widget (accessible); + if (widget == NULL) + { + /* State is defunct */ + return NULL; + } + + canvas = EEL_CANVAS (widget); + root_group = eel_canvas_root (canvas); + g_return_val_if_fail (root_group, NULL); + atk_object = atk_gobject_accessible_for_object (G_OBJECT (root_group)); + g_object_ref (atk_object); + + g_warning ("Accessible support for FooGroup needs to be implemented"); + + return atk_object; +} + +static void +eel_canvas_accessible_class_init (AtkObjectClass *klass) +{ + accessible_parent_class = g_type_class_peek_parent (klass); + + klass->initialize = eel_canvas_accessible_initialize; + klass->get_n_children = eel_canvas_accessible_get_n_children; + klass->ref_child = eel_canvas_accessible_ref_child; +} + +static GType +eel_canvas_accessible_get_type (void) +{ + static GType type = 0; + + if (!type) + { + AtkObjectFactory *factory; + GType parent_atk_type; + GTypeQuery query; + GTypeInfo tinfo = { 0 }; + + factory = atk_registry_get_factory (atk_get_default_registry(), + GTK_TYPE_WIDGET); + if (!factory) + { + return G_TYPE_INVALID; + } + parent_atk_type = atk_object_factory_get_accessible_type (factory); + if (!parent_atk_type) + { + return G_TYPE_INVALID; + } + g_type_query (parent_atk_type, &query); + tinfo.class_init = (GClassInitFunc) eel_canvas_accessible_class_init; + tinfo.class_size = query.class_size; + tinfo.instance_size = query.instance_size; + type = g_type_register_static (parent_atk_type, + "EelCanvasAccessibility", + &tinfo, 0); + } + return type; +} + +static AtkObject * +eel_canvas_accessible_create (GObject *for_object) +{ + GType type; + AtkObject *accessible; + EelCanvas *canvas; + + canvas = EEL_CANVAS (for_object); + g_return_val_if_fail (canvas != NULL, NULL); + + type = eel_canvas_accessible_get_type (); + + if (type == G_TYPE_INVALID) + { + return atk_no_op_object_new (for_object); + } + + accessible = g_object_new (type, NULL); + atk_object_initialize (accessible, for_object); + return accessible; +} + +static GType +eel_canvas_accessible_factory_get_accessible_type (void) +{ + return eel_canvas_accessible_get_type (); +} + +static AtkObject* +eel_canvas_accessible_factory_create_accessible (GObject *obj) +{ + AtkObject *accessible; + + g_return_val_if_fail (G_IS_OBJECT (obj), NULL); + + accessible = eel_canvas_accessible_create (obj); + + return accessible; +} + +static void +eel_canvas_accessible_factory_class_init (AtkObjectFactoryClass *klass) +{ + klass->create_accessible = eel_canvas_accessible_factory_create_accessible; + klass->get_accessible_type = eel_canvas_accessible_factory_get_accessible_type; +} + +static GType +eel_canvas_accessible_factory_get_type (void) +{ + static GType type = 0; + + if (!type) + { + static const GTypeInfo tinfo = + { + sizeof (AtkObjectFactoryClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) eel_canvas_accessible_factory_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (AtkObjectFactory), + 0, /* n_preallocs */ + NULL + }; + type = g_type_register_static (ATK_TYPE_OBJECT_FACTORY, + "EelCanvasAccessibilityFactory", + &tinfo, 0); + } + + return type; +} + + +/* Class initialization function for EelCanvasClass */ +static void +eel_canvas_class_init (EelCanvasClass *klass) +{ + GObjectClass *gobject_class; + GtkObjectClass *object_class; + GtkWidgetClass *widget_class; + + gobject_class = (GObjectClass *)klass; + object_class = (GtkObjectClass *) klass; + widget_class = (GtkWidgetClass *) klass; + + canvas_parent_class = g_type_class_peek_parent (klass); + + gobject_class->set_property = eel_canvas_set_property; + gobject_class->get_property = eel_canvas_get_property; + + object_class->destroy = eel_canvas_destroy; + + widget_class->map = eel_canvas_map; + widget_class->unmap = eel_canvas_unmap; + widget_class->realize = eel_canvas_realize; + widget_class->unrealize = eel_canvas_unrealize; + widget_class->size_allocate = eel_canvas_size_allocate; + widget_class->button_press_event = eel_canvas_button; + widget_class->button_release_event = eel_canvas_button; + widget_class->motion_notify_event = eel_canvas_motion; + widget_class->expose_event = eel_canvas_expose; + widget_class->key_press_event = eel_canvas_key; + widget_class->key_release_event = eel_canvas_key; + widget_class->enter_notify_event = eel_canvas_crossing; + widget_class->leave_notify_event = eel_canvas_crossing; + widget_class->focus_in_event = eel_canvas_focus_in; + widget_class->focus_out_event = eel_canvas_focus_out; + + klass->draw_background = eel_canvas_draw_background; + klass->request_update = eel_canvas_request_update_real; + + canvas_signals[DRAW_BACKGROUND] = + g_signal_new ("draw_background", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (EelCanvasClass, draw_background), + NULL, NULL, + eel_marshal_VOID__INT_INT_INT_INT, + G_TYPE_NONE, 4, + G_TYPE_INT, G_TYPE_INT, G_TYPE_INT, G_TYPE_INT); + + atk_registry_set_factory_type (atk_get_default_registry (), + EEL_TYPE_CANVAS, + eel_canvas_accessible_factory_get_type ()); +} + +/* Callback used when the root item of a canvas is destroyed. The user should + * never ever do this, so we panic if this happens. + */ +static void +panic_root_destroyed (GtkObject *object, gpointer data) +{ + g_error ("Eeeek, root item %p of canvas %p was destroyed!", object, data); +} + +/* Object initialization function for EelCanvas */ +static void +eel_canvas_init (EelCanvas *canvas) +{ + guint width, height; + gtk_widget_set_can_focus (GTK_WIDGET (canvas), TRUE); + + gtk_widget_set_redraw_on_allocate (GTK_WIDGET (canvas), FALSE); + + canvas->scroll_x1 = 0.0; + canvas->scroll_y1 = 0.0; + gtk_layout_get_size (&canvas->layout, + &width, &height); + canvas->scroll_x2 = width; + canvas->scroll_y2 = height; + + canvas->pixels_per_unit = 1.0; + + canvas->pick_event.type = GDK_LEAVE_NOTIFY; + canvas->pick_event.crossing.x = 0; + canvas->pick_event.crossing.y = 0; + + gtk_layout_set_hadjustment (GTK_LAYOUT (canvas), NULL); + gtk_layout_set_vadjustment (GTK_LAYOUT (canvas), NULL); + + /* Create the root item as a special case */ + + canvas->root = EEL_CANVAS_ITEM (g_object_new (eel_canvas_group_get_type (), NULL)); + canvas->root->canvas = canvas; + +#if GLIB_CHECK_VERSION(2,10,0) && GTK_CHECK_VERSION(2,8,14) + g_object_ref_sink (canvas->root); +#else + g_object_ref (canvas->root); + gtk_object_sink (GTK_OBJECT (canvas->root)); +#endif + + canvas->root_destroy_id = g_signal_connect (G_OBJECT (canvas->root), + "destroy", G_CALLBACK (panic_root_destroyed), canvas); + + canvas->need_repick = TRUE; + canvas->doing_update = FALSE; +} + +/* Convenience function to remove the idle handler of a canvas */ +static void +remove_idle (EelCanvas *canvas) +{ + if (canvas->idle_id == 0) + return; + + g_source_remove (canvas->idle_id); + canvas->idle_id = 0; +} + +/* Removes the transient state of the canvas (idle handler, grabs). */ +static void +shutdown_transients (EelCanvas *canvas) +{ + /* We turn off the need_redraw flag, since if the canvas is mapped again + * it will request a redraw anyways. We do not turn off the need_update + * flag, though, because updates are not queued when the canvas remaps + * itself. + */ + if (canvas->need_redraw) + { + canvas->need_redraw = FALSE; + } + + if (canvas->grabbed_item) + { + GdkDisplay *display = gtk_widget_get_display (GTK_WIDGET (canvas)); + canvas->grabbed_item = NULL; + gdk_display_pointer_ungrab (display, GDK_CURRENT_TIME); + } + + remove_idle (canvas); +} + +/* Destroy handler for EelCanvas */ +static void +eel_canvas_destroy (GtkObject *object) +{ + EelCanvas *canvas; + + g_return_if_fail (EEL_IS_CANVAS (object)); + + /* remember, destroy can be run multiple times! */ + + canvas = EEL_CANVAS (object); + + if (canvas->root_destroy_id) + { + g_signal_handler_disconnect (G_OBJECT (canvas->root), canvas->root_destroy_id); + canvas->root_destroy_id = 0; + } + if (canvas->root) + { + EelCanvasItem *root = canvas->root; + canvas->root = NULL; + gtk_object_destroy (GTK_OBJECT (root)); + g_object_unref (root); + } + + shutdown_transients (canvas); + + if (GTK_OBJECT_CLASS (canvas_parent_class)->destroy) + (* GTK_OBJECT_CLASS (canvas_parent_class)->destroy) (object); +} + +/** + * eel_canvas_new: + * @void: + * + * Creates a new empty canvas. If you wish to use the + * &EelCanvasImage item inside this canvas, then you must push the gdk_imlib + * visual and colormap before calling this function, and they can be popped + * afterwards. + * + * Return value: A newly-created canvas. + **/ +GtkWidget * +eel_canvas_new (void) +{ + return GTK_WIDGET (g_object_new (eel_canvas_get_type (), NULL)); +} + +/* Map handler for the canvas */ +static void +eel_canvas_map (GtkWidget *widget) +{ + EelCanvas *canvas; + + g_return_if_fail (EEL_IS_CANVAS (widget)); + + /* Normal widget mapping stuff */ + + if (GTK_WIDGET_CLASS (canvas_parent_class)->map) + (* GTK_WIDGET_CLASS (canvas_parent_class)->map) (widget); + + canvas = EEL_CANVAS (widget); + + /* Map items */ + + if (canvas->root->flags & EEL_CANVAS_ITEM_VISIBLE && + !(canvas->root->flags & EEL_CANVAS_ITEM_MAPPED) && + EEL_CANVAS_ITEM_GET_CLASS (canvas->root)->map) + (* EEL_CANVAS_ITEM_GET_CLASS (canvas->root)->map) (canvas->root); +} + +/* Unmap handler for the canvas */ +static void +eel_canvas_unmap (GtkWidget *widget) +{ + EelCanvas *canvas; + + g_return_if_fail (EEL_IS_CANVAS (widget)); + + canvas = EEL_CANVAS (widget); + + shutdown_transients (canvas); + + /* Unmap items */ + + if (EEL_CANVAS_ITEM_GET_CLASS (canvas->root)->unmap) + (* EEL_CANVAS_ITEM_GET_CLASS (canvas->root)->unmap) (canvas->root); + + /* Normal widget unmapping stuff */ + + if (GTK_WIDGET_CLASS (canvas_parent_class)->unmap) + (* GTK_WIDGET_CLASS (canvas_parent_class)->unmap) (widget); +} + +/* Realize handler for the canvas */ +static void +eel_canvas_realize (GtkWidget *widget) +{ + EelCanvas *canvas; + + g_return_if_fail (EEL_IS_CANVAS (widget)); + + /* Normal widget realization stuff */ + + if (GTK_WIDGET_CLASS (canvas_parent_class)->realize) + (* GTK_WIDGET_CLASS (canvas_parent_class)->realize) (widget); + + canvas = EEL_CANVAS (widget); + + gdk_window_set_events (gtk_layout_get_bin_window (&canvas->layout), + (gdk_window_get_events (gtk_layout_get_bin_window (&canvas->layout)) + | GDK_EXPOSURE_MASK + | GDK_BUTTON_PRESS_MASK + | GDK_BUTTON_RELEASE_MASK + | GDK_POINTER_MOTION_MASK + | GDK_KEY_PRESS_MASK + | GDK_KEY_RELEASE_MASK + | GDK_ENTER_NOTIFY_MASK + | GDK_LEAVE_NOTIFY_MASK + | GDK_FOCUS_CHANGE_MASK)); + + /* Create our own temporary pixmap gc and realize all the items */ + + canvas->pixmap_gc = gdk_gc_new (gtk_layout_get_bin_window (&canvas->layout)); + + (* EEL_CANVAS_ITEM_GET_CLASS (canvas->root)->realize) (canvas->root); +} + +/* Unrealize handler for the canvas */ +static void +eel_canvas_unrealize (GtkWidget *widget) +{ + EelCanvas *canvas; + + g_return_if_fail (EEL_IS_CANVAS (widget)); + + canvas = EEL_CANVAS (widget); + + shutdown_transients (canvas); + + /* Unrealize items and parent widget */ + + (* EEL_CANVAS_ITEM_GET_CLASS (canvas->root)->unrealize) (canvas->root); + + g_object_unref (canvas->pixmap_gc); + canvas->pixmap_gc = NULL; + + if (GTK_WIDGET_CLASS (canvas_parent_class)->unrealize) + (* GTK_WIDGET_CLASS (canvas_parent_class)->unrealize) (widget); +} + +/* Handles scrolling of the canvas. Adjusts the scrolling and zooming offset to + * keep as much as possible of the canvas scrolling region in view. + */ +static void +scroll_to (EelCanvas *canvas, int cx, int cy) +{ + int scroll_width, scroll_height; + int right_limit, bottom_limit; + int old_zoom_xofs, old_zoom_yofs; + int changed_x = FALSE, changed_y = FALSE; + int canvas_width, canvas_height; + GtkAllocation allocation; + GtkAdjustment *vadjustment, *hadjustment; + guint width, height; + + gtk_widget_get_allocation (GTK_WIDGET (canvas), &allocation); + canvas_width = allocation.width; + canvas_height = allocation.height; + + scroll_width = floor ((canvas->scroll_x2 - canvas->scroll_x1) * canvas->pixels_per_unit + 0.5); + scroll_height = floor ((canvas->scroll_y2 - canvas->scroll_y1) * canvas->pixels_per_unit + 0.5); + + right_limit = scroll_width - canvas_width; + bottom_limit = scroll_height - canvas_height; + + old_zoom_xofs = canvas->zoom_xofs; + old_zoom_yofs = canvas->zoom_yofs; + + if (right_limit < 0) + { + cx = 0; + if (canvas->center_scroll_region) + { + canvas->zoom_xofs = (canvas_width - scroll_width) / 2; + scroll_width = canvas_width; + } + else + { + canvas->zoom_xofs = 0; + } + } + else if (cx < 0) + { + cx = 0; + canvas->zoom_xofs = 0; + } + else if (cx > right_limit) + { + cx = right_limit; + canvas->zoom_xofs = 0; + } + else + canvas->zoom_xofs = 0; + + if (bottom_limit < 0) + { + cy = 0; + if (canvas->center_scroll_region) + { + canvas->zoom_yofs = (canvas_height - scroll_height) / 2; + scroll_height = canvas_height; + } + else + { + canvas->zoom_yofs = 0; + } + } + else if (cy < 0) + { + cy = 0; + canvas->zoom_yofs = 0; + } + else if (cy > bottom_limit) + { + cy = bottom_limit; + canvas->zoom_yofs = 0; + } + else + canvas->zoom_yofs = 0; + + if ((canvas->zoom_xofs != old_zoom_xofs) || (canvas->zoom_yofs != old_zoom_yofs)) + { + /* This can only occur, if either canvas size or widget size changes */ + /* So I think we can request full redraw here */ + /* More stuff - we have to mark root as needing fresh affine (Lauris) */ + if (!(canvas->root->flags & EEL_CANVAS_ITEM_NEED_DEEP_UPDATE)) + { + canvas->root->flags |= EEL_CANVAS_ITEM_NEED_DEEP_UPDATE; + eel_canvas_request_update (canvas); + } + gtk_widget_queue_draw (GTK_WIDGET (canvas)); + } + + hadjustment = gtk_layout_get_hadjustment (&canvas->layout); + vadjustment = gtk_layout_get_vadjustment (&canvas->layout); + + if (((int) gtk_adjustment_get_value (hadjustment)) != cx) + { + gtk_adjustment_set_value (hadjustment, cx); + changed_x = TRUE; + } + + if (((int) gtk_adjustment_get_value (vadjustment)) != cy) + { + gtk_adjustment_set_value (vadjustment, cy); + changed_y = TRUE; + } + + gtk_layout_get_size (&canvas->layout, &width, &height); + if ((scroll_width != (int) width )|| (scroll_height != (int) height)) + { + gtk_layout_set_size (GTK_LAYOUT (canvas), scroll_width, scroll_height); + } + + /* Signal GtkLayout that it should do a redraw. */ + if (changed_x) + g_signal_emit_by_name (hadjustment, "value_changed"); + if (changed_y) + g_signal_emit_by_name (vadjustment, "value_changed"); +} + +/* Size allocation handler for the canvas */ +static void +eel_canvas_size_allocate (GtkWidget *widget, GtkAllocation *allocation) +{ + EelCanvas *canvas; + GtkAdjustment *vadjustment, *hadjustment; + + g_return_if_fail (EEL_IS_CANVAS (widget)); + g_return_if_fail (allocation != NULL); + + if (GTK_WIDGET_CLASS (canvas_parent_class)->size_allocate) + (* GTK_WIDGET_CLASS (canvas_parent_class)->size_allocate) (widget, allocation); + + canvas = EEL_CANVAS (widget); + + /* Recenter the view, if appropriate */ + + hadjustment = gtk_layout_get_hadjustment (&canvas->layout); + vadjustment = gtk_layout_get_vadjustment (&canvas->layout); + + gtk_adjustment_set_page_size (hadjustment, allocation->width); + gtk_adjustment_set_page_increment (hadjustment, allocation->width / 2); + + gtk_adjustment_set_page_size (vadjustment, allocation->height); + gtk_adjustment_set_page_increment (vadjustment, allocation->height / 2); + + scroll_to (canvas, + gtk_adjustment_get_value (hadjustment), + gtk_adjustment_get_value (vadjustment)); + + g_signal_emit_by_name (hadjustment, "changed"); + g_signal_emit_by_name (vadjustment, "changed"); +} + +/* Emits an event for an item in the canvas, be it the current item, grabbed + * item, or focused item, as appropriate. + */ + +static int +emit_event (EelCanvas *canvas, GdkEvent *event) +{ + GdkEvent ev; + gint finished; + EelCanvasItem *item; + EelCanvasItem *parent; + guint mask; + + /* Could be an old pick event */ + if (!gtk_widget_get_realized (GTK_WIDGET (canvas))) + { + return FALSE; + } + + /* Perform checks for grabbed items */ + + if (canvas->grabbed_item && + !is_descendant (canvas->current_item, canvas->grabbed_item)) + { + return FALSE; + } + + if (canvas->grabbed_item) + { + switch (event->type) + { + case GDK_ENTER_NOTIFY: + mask = GDK_ENTER_NOTIFY_MASK; + break; + + case GDK_LEAVE_NOTIFY: + mask = GDK_LEAVE_NOTIFY_MASK; + break; + + case GDK_MOTION_NOTIFY: + mask = GDK_POINTER_MOTION_MASK; + break; + + case GDK_BUTTON_PRESS: + case GDK_2BUTTON_PRESS: + case GDK_3BUTTON_PRESS: + mask = GDK_BUTTON_PRESS_MASK; + break; + + case GDK_BUTTON_RELEASE: + mask = GDK_BUTTON_RELEASE_MASK; + break; + + case GDK_KEY_PRESS: + mask = GDK_KEY_PRESS_MASK; + break; + + case GDK_KEY_RELEASE: + mask = GDK_KEY_RELEASE_MASK; + break; + + default: + mask = 0; + break; + } + + if (!(mask & canvas->grabbed_event_mask)) + return FALSE; + } + + /* Convert to world coordinates -- we have two cases because of diferent + * offsets of the fields in the event structures. + */ + + ev = *event; + + switch (ev.type) + { + case GDK_ENTER_NOTIFY: + case GDK_LEAVE_NOTIFY: + eel_canvas_window_to_world (canvas, + ev.crossing.x, ev.crossing.y, + &ev.crossing.x, &ev.crossing.y); + break; + + case GDK_MOTION_NOTIFY: + eel_canvas_window_to_world (canvas, + ev.motion.x, ev.motion.y, + &ev.motion.x, &ev.motion.y); + break; + + case GDK_BUTTON_PRESS: + case GDK_2BUTTON_PRESS: + case GDK_3BUTTON_PRESS: + eel_canvas_window_to_world (canvas, + ev.motion.x, ev.motion.y, + &ev.motion.x, &ev.motion.y); + break; + + case GDK_BUTTON_RELEASE: + eel_canvas_window_to_world (canvas, + ev.motion.x, ev.motion.y, + &ev.motion.x, &ev.motion.y); + break; + + default: + break; + } + + /* Choose where we send the event */ + + item = canvas->current_item; + + if (canvas->focused_item + && ((event->type == GDK_KEY_PRESS) || + (event->type == GDK_KEY_RELEASE) || + (event->type == GDK_FOCUS_CHANGE))) + item = canvas->focused_item; + + /* The event is propagated up the hierarchy (for if someone connected to + * a group instead of a leaf event), and emission is stopped if a + * handler returns TRUE, just like for GtkWidget events. + */ + + finished = FALSE; + + while (item && !finished) + { + g_object_ref (GTK_OBJECT (item)); + + g_signal_emit ( + G_OBJECT (item), item_signals[ITEM_EVENT], 0, + &ev, &finished); + + parent = item->parent; + g_object_unref (GTK_OBJECT (item)); + + item = parent; + } + + return finished; +} + +/* Re-picks the current item in the canvas, based on the event's coordinates. + * Also emits enter/leave events for items as appropriate. + */ +static int +pick_current_item (EelCanvas *canvas, GdkEvent *event) +{ + int button_down; + double x, y; + int cx, cy; + int retval; + + retval = FALSE; + + /* If a button is down, we'll perform enter and leave events on the + * current item, but not enter on any other item. This is more or less + * like X pointer grabbing for canvas items. + */ + button_down = canvas->state & (GDK_BUTTON1_MASK + | GDK_BUTTON2_MASK + | GDK_BUTTON3_MASK + | GDK_BUTTON4_MASK + | GDK_BUTTON5_MASK); + if (!button_down) + canvas->left_grabbed_item = FALSE; + + /* Save the event in the canvas. This is used to synthesize enter and + * leave events in case the current item changes. It is also used to + * re-pick the current item if the current one gets deleted. Also, + * synthesize an enter event. + */ + if (event != &canvas->pick_event) + { + if ((event->type == GDK_MOTION_NOTIFY) || (event->type == GDK_BUTTON_RELEASE)) + { + /* these fields have the same offsets in both types of events */ + + canvas->pick_event.crossing.type = GDK_ENTER_NOTIFY; + canvas->pick_event.crossing.window = event->motion.window; + canvas->pick_event.crossing.send_event = event->motion.send_event; + canvas->pick_event.crossing.subwindow = NULL; + canvas->pick_event.crossing.x = event->motion.x; + canvas->pick_event.crossing.y = event->motion.y; + canvas->pick_event.crossing.mode = GDK_CROSSING_NORMAL; + canvas->pick_event.crossing.detail = GDK_NOTIFY_NONLINEAR; + canvas->pick_event.crossing.focus = FALSE; + canvas->pick_event.crossing.state = event->motion.state; + + /* these fields don't have the same offsets in both types of events */ + + if (event->type == GDK_MOTION_NOTIFY) + { + canvas->pick_event.crossing.x_root = event->motion.x_root; + canvas->pick_event.crossing.y_root = event->motion.y_root; + } + else + { + canvas->pick_event.crossing.x_root = event->button.x_root; + canvas->pick_event.crossing.y_root = event->button.y_root; + } + } + else + canvas->pick_event = *event; + } + + /* Don't do anything else if this is a recursive call */ + + if (canvas->in_repick) + return retval; + + /* LeaveNotify means that there is no current item, so we don't look for one */ + + if (canvas->pick_event.type != GDK_LEAVE_NOTIFY) + { + /* these fields don't have the same offsets in both types of events */ + + if (canvas->pick_event.type == GDK_ENTER_NOTIFY) + { + x = canvas->pick_event.crossing.x; + y = canvas->pick_event.crossing.y; + } + else + { + x = canvas->pick_event.motion.x; + y = canvas->pick_event.motion.y; + } + + /* canvas pixel coords */ + + cx = (int) (x + 0.5); + cy = (int) (y + 0.5); + + /* world coords */ + eel_canvas_c2w (canvas, cx, cy, &x, &y); + + /* find the closest item */ + if (canvas->root->flags & EEL_CANVAS_ITEM_MAPPED) + eel_canvas_item_invoke_point (canvas->root, x, y, cx, cy, + &canvas->new_current_item); + else + canvas->new_current_item = NULL; + } + else + canvas->new_current_item = NULL; + + if ((canvas->new_current_item == canvas->current_item) && !canvas->left_grabbed_item) + return retval; /* current item did not change */ + + /* Synthesize events for old and new current items */ + + if ((canvas->new_current_item != canvas->current_item) + && (canvas->current_item != NULL) + && !canvas->left_grabbed_item) + { + GdkEvent new_event; + EelCanvasItem *item; + + item = canvas->current_item; + + new_event = canvas->pick_event; + new_event.type = GDK_LEAVE_NOTIFY; + + new_event.crossing.detail = GDK_NOTIFY_ANCESTOR; + new_event.crossing.subwindow = NULL; + canvas->in_repick = TRUE; + retval = emit_event (canvas, &new_event); + canvas->in_repick = FALSE; + } + + /* new_current_item may have been set to NULL during the call to emit_event() above */ + + if ((canvas->new_current_item != canvas->current_item) && button_down) + { + canvas->left_grabbed_item = TRUE; + return retval; + } + + /* Handle the rest of cases */ + + canvas->left_grabbed_item = FALSE; + canvas->current_item = canvas->new_current_item; + + if (canvas->current_item != NULL) + { + GdkEvent new_event; + + new_event = canvas->pick_event; + new_event.type = GDK_ENTER_NOTIFY; + new_event.crossing.detail = GDK_NOTIFY_ANCESTOR; + new_event.crossing.subwindow = NULL; + retval = emit_event (canvas, &new_event); + } + + return retval; +} + +/* Button event handler for the canvas */ +static gint +eel_canvas_button (GtkWidget *widget, GdkEventButton *event) +{ + EelCanvas *canvas; + int mask; + int retval; + + g_return_val_if_fail (EEL_IS_CANVAS (widget), FALSE); + g_return_val_if_fail (event != NULL, FALSE); + + retval = FALSE; + + canvas = EEL_CANVAS (widget); + + /* + * dispatch normally regardless of the event's window if an item has + * has a pointer grab in effect + */ + if (!canvas->grabbed_item && event->window != gtk_layout_get_bin_window (&canvas->layout)) + return retval; + + switch (event->button) + { + case 1: + mask = GDK_BUTTON1_MASK; + break; + case 2: + mask = GDK_BUTTON2_MASK; + break; + case 3: + mask = GDK_BUTTON3_MASK; + break; + case 4: + mask = GDK_BUTTON4_MASK; + break; + case 5: + mask = GDK_BUTTON5_MASK; + break; + default: + mask = 0; + } + + switch (event->type) + { + case GDK_BUTTON_PRESS: + case GDK_2BUTTON_PRESS: + case GDK_3BUTTON_PRESS: + /* Pick the current item as if the button were not pressed, and + * then process the event. + */ + canvas->state = event->state; + pick_current_item (canvas, (GdkEvent *) event); + canvas->state ^= mask; + retval = emit_event (canvas, (GdkEvent *) event); + break; + + case GDK_BUTTON_RELEASE: + /* Process the event as if the button were pressed, then repick + * after the button has been released + */ + canvas->state = event->state; + retval = emit_event (canvas, (GdkEvent *) event); + event->state ^= mask; + canvas->state = event->state; + pick_current_item (canvas, (GdkEvent *) event); + event->state ^= mask; + break; + + default: + g_assert_not_reached (); + } + + return retval; +} + +/* Motion event handler for the canvas */ +static gint +eel_canvas_motion (GtkWidget *widget, GdkEventMotion *event) +{ + EelCanvas *canvas; + + g_return_val_if_fail (EEL_IS_CANVAS (widget), FALSE); + g_return_val_if_fail (event != NULL, FALSE); + + canvas = EEL_CANVAS (widget); + + if (event->window != gtk_layout_get_bin_window (&canvas->layout)) + return FALSE; + + canvas->state = event->state; + pick_current_item (canvas, (GdkEvent *) event); + return emit_event (canvas, (GdkEvent *) event); +} + +/* Key event handler for the canvas */ +static gint +eel_canvas_key (GtkWidget *widget, GdkEventKey *event) +{ + EelCanvas *canvas; + + g_return_val_if_fail (EEL_IS_CANVAS (widget), FALSE); + g_return_val_if_fail (event != NULL, FALSE); + + canvas = EEL_CANVAS (widget); + + if (emit_event (canvas, (GdkEvent *) event)) + return TRUE; + if (event->type == GDK_KEY_RELEASE) + return GTK_WIDGET_CLASS (canvas_parent_class)->key_release_event (widget, event); + else + return GTK_WIDGET_CLASS (canvas_parent_class)->key_press_event (widget, event); +} + + +/* Crossing event handler for the canvas */ +static gint +eel_canvas_crossing (GtkWidget *widget, GdkEventCrossing *event) +{ + EelCanvas *canvas; + + g_return_val_if_fail (EEL_IS_CANVAS (widget), FALSE); + g_return_val_if_fail (event != NULL, FALSE); + + canvas = EEL_CANVAS (widget); + + if (event->window != gtk_layout_get_bin_window (&canvas->layout)) + return FALSE; + + canvas->state = event->state; + return pick_current_item (canvas, (GdkEvent *) event); +} + +/* Focus in handler for the canvas */ +static gint +eel_canvas_focus_in (GtkWidget *widget, GdkEventFocus *event) +{ + EelCanvas *canvas; + + canvas = EEL_CANVAS (widget); + + if (canvas->focused_item) + return emit_event (canvas, (GdkEvent *) event); + else + return FALSE; +} + +/* Focus out handler for the canvas */ +static gint +eel_canvas_focus_out (GtkWidget *widget, GdkEventFocus *event) +{ + EelCanvas *canvas; + + canvas = EEL_CANVAS (widget); + + if (canvas->focused_item) + return emit_event (canvas, (GdkEvent *) event); + else + return FALSE; +} + +/* Expose handler for the canvas */ +static gint +eel_canvas_expose (GtkWidget *widget, GdkEventExpose *event) +{ + EelCanvas *canvas; + + canvas = EEL_CANVAS (widget); + + if (!gtk_widget_is_drawable (widget) || (event->window != gtk_layout_get_bin_window (&canvas->layout))) return FALSE; + +#ifdef VERBOSE + g_print ("Expose\n"); +#endif + /* If there are any outstanding items that need updating, do them now */ + if (canvas->idle_id) + { + g_source_remove (canvas->idle_id); + canvas->idle_id = 0; + } + if (canvas->need_update) + { + g_return_val_if_fail (!canvas->doing_update, FALSE); + + canvas->doing_update = TRUE; + eel_canvas_item_invoke_update (canvas->root, 0, 0, 0); + + g_return_val_if_fail (canvas->doing_update, FALSE); + + canvas->doing_update = FALSE; + + canvas->need_update = FALSE; + } + + /* Hmmm. Would like to queue antiexposes if the update marked + anything that is gonna get redrawn as invalid */ + + + g_signal_emit (G_OBJECT (canvas), canvas_signals[DRAW_BACKGROUND], 0, + event->area.x, event->area.y, + event->area.width, event->area.height); + + if (canvas->root->flags & EEL_CANVAS_ITEM_MAPPED) + (* EEL_CANVAS_ITEM_GET_CLASS (canvas->root)->draw) (canvas->root, + gtk_layout_get_bin_window (&canvas->layout), + event); + + + + /* Chain up to get exposes on child widgets */ + GTK_WIDGET_CLASS (canvas_parent_class)->expose_event (widget, event); + + return FALSE; +} + +static void +eel_canvas_draw_background (EelCanvas *canvas, + int x, int y, int width, int height) +{ + /* By default, we use the style background. */ + gdk_gc_set_foreground (canvas->pixmap_gc, + >k_widget_get_style (GTK_WIDGET (canvas))->bg[GTK_STATE_NORMAL]); + gdk_draw_rectangle (gtk_layout_get_bin_window (&canvas->layout), + canvas->pixmap_gc, + TRUE, + x, y, + width, height); +} + +static void +do_update (EelCanvas *canvas) +{ + /* Cause the update if necessary */ + +update_again: + if (canvas->need_update) + { + g_return_if_fail (!canvas->doing_update); + + canvas->doing_update = TRUE; + eel_canvas_item_invoke_update (canvas->root, 0, 0, 0); + + g_return_if_fail (canvas->doing_update); + + canvas->doing_update = FALSE; + + canvas->need_update = FALSE; + } + + /* Pick new current item */ + + while (canvas->need_repick) + { + canvas->need_repick = FALSE; + pick_current_item (canvas, &canvas->pick_event); + } + + /* it is possible that during picking we emitted an event in which + the user then called some function which then requested update + of something. Without this we'd be left in a state where + need_update would have been left TRUE and the canvas would have + been left unpainted. */ + if (canvas->need_update) + { + goto update_again; + } +} + +/* Idle handler for the canvas. It deals with pending updates and redraws. */ +static gint +idle_handler (gpointer data) +{ + EelCanvas *canvas; + + GDK_THREADS_ENTER (); + + canvas = EEL_CANVAS (data); + do_update (canvas); + + /* Reset idle id */ + canvas->idle_id = 0; + + GDK_THREADS_LEAVE (); + + return FALSE; +} + +/* Convenience function to add an idle handler to a canvas */ +static void +add_idle (EelCanvas *canvas) +{ + if (!canvas->idle_id) + { + /* We let the update idle handler have higher priority + * than the redraw idle handler so the canvas state + * will be updated during the expose event. canvas in + * expose_event. + */ + canvas->idle_id = g_idle_add_full (GDK_PRIORITY_REDRAW - 20, + idle_handler, canvas, NULL); + } +} + +/** + * eel_canvas_root: + * @canvas: A canvas. + * + * Queries the root group of a canvas. + * + * Return value: The root group of the specified canvas. + **/ +EelCanvasGroup * +eel_canvas_root (EelCanvas *canvas) +{ + g_return_val_if_fail (EEL_IS_CANVAS (canvas), NULL); + + return EEL_CANVAS_GROUP (canvas->root); +} + + +/** + * eel_canvas_set_scroll_region: + * @canvas: A canvas. + * @x1: Leftmost limit of the scrolling region. + * @y1: Upper limit of the scrolling region. + * @x2: Rightmost limit of the scrolling region. + * @y2: Lower limit of the scrolling region. + * + * Sets the scrolling region of a canvas to the specified rectangle. The canvas + * will then be able to scroll only within this region. The view of the canvas + * is adjusted as appropriate to display as much of the new region as possible. + **/ +void +eel_canvas_set_scroll_region (EelCanvas *canvas, double x1, double y1, double x2, double y2) +{ + double wxofs, wyofs; + int xofs, yofs; + GtkAdjustment *vadjustment, *hadjustment; + + g_return_if_fail (EEL_IS_CANVAS (canvas)); + + if ((canvas->scroll_x1 == x1) && (canvas->scroll_y1 == y1) && + (canvas->scroll_x2 == x2) && (canvas->scroll_y2 == y2)) + { + return; + } + + /* + * Set the new scrolling region. If possible, do not move the visible contents of the + * canvas. + */ + hadjustment = gtk_layout_get_hadjustment (GTK_LAYOUT (canvas)); + vadjustment = gtk_layout_get_vadjustment (GTK_LAYOUT (canvas)); + + eel_canvas_c2w (canvas, + gtk_adjustment_get_value (hadjustment) + canvas->zoom_xofs, + gtk_adjustment_get_value (vadjustment) + canvas->zoom_yofs, + /*canvas->zoom_xofs, + canvas->zoom_yofs,*/ + &wxofs, &wyofs); + + canvas->scroll_x1 = x1; + canvas->scroll_y1 = y1; + canvas->scroll_x2 = x2; + canvas->scroll_y2 = y2; + + eel_canvas_w2c (canvas, wxofs, wyofs, &xofs, &yofs); + + scroll_to (canvas, xofs, yofs); + + canvas->need_repick = TRUE; + + if (!(canvas->root->flags & EEL_CANVAS_ITEM_NEED_DEEP_UPDATE)) + { + canvas->root->flags |= EEL_CANVAS_ITEM_NEED_DEEP_UPDATE; + eel_canvas_request_update (canvas); + } +} + + +/** + * eel_canvas_get_scroll_region: + * @canvas: A canvas. + * @x1: Leftmost limit of the scrolling region (return value). + * @y1: Upper limit of the scrolling region (return value). + * @x2: Rightmost limit of the scrolling region (return value). + * @y2: Lower limit of the scrolling region (return value). + * + * Queries the scrolling region of a canvas. + **/ +void +eel_canvas_get_scroll_region (EelCanvas *canvas, double *x1, double *y1, double *x2, double *y2) +{ + g_return_if_fail (EEL_IS_CANVAS (canvas)); + + if (x1) + *x1 = canvas->scroll_x1; + + if (y1) + *y1 = canvas->scroll_y1; + + if (x2) + *x2 = canvas->scroll_x2; + + if (y2) + *y2 = canvas->scroll_y2; +} + +void +eel_canvas_set_center_scroll_region (EelCanvas *canvas, + gboolean center_scroll_region) +{ + GtkAdjustment *vadjustment, *hadjustment; + + g_return_if_fail (EEL_IS_CANVAS (canvas)); + + canvas->center_scroll_region = center_scroll_region != 0; + + hadjustment = gtk_layout_get_hadjustment (&canvas->layout); + vadjustment = gtk_layout_get_vadjustment (&canvas->layout); + + scroll_to (canvas, + gtk_adjustment_get_value (hadjustment), + gtk_adjustment_get_value (vadjustment)); +} + + +/** + * eel_canvas_set_pixels_per_unit: + * @canvas: A canvas. + * @n: The number of pixels that correspond to one canvas unit. + * + * Sets the zooming factor of a canvas by specifying the number of pixels that + * correspond to one canvas unit. + **/ +void +eel_canvas_set_pixels_per_unit (EelCanvas *canvas, double n) +{ + GtkWidget *widget; + double cx, cy; + int x1, y1; + int center_x, center_y; + GdkWindow *window; + GdkWindowAttr attributes; + gint attributes_mask; + GtkAllocation allocation; + GtkAdjustment *vadjustment, *hadjustment; + + g_return_if_fail (EEL_IS_CANVAS (canvas)); + g_return_if_fail (n > EEL_CANVAS_EPSILON); + + widget = GTK_WIDGET (canvas); + + gtk_widget_get_allocation (widget, &allocation); + center_x = allocation.width / 2; + center_y = allocation.height / 2; + + /* Find the coordinates of the screen center in units. */ + hadjustment = gtk_layout_get_hadjustment (&canvas->layout); + vadjustment = gtk_layout_get_vadjustment (&canvas->layout); + cx = (gtk_adjustment_get_value (hadjustment) + center_x) / canvas->pixels_per_unit + canvas->scroll_x1 + canvas->zoom_xofs; + cy = (gtk_adjustment_get_value (vadjustment) + center_y) / canvas->pixels_per_unit + canvas->scroll_y1 + canvas->zoom_yofs; + + /* Now calculate the new offset of the upper left corner. (round not truncate) */ + x1 = ((cx - canvas->scroll_x1) * n) - center_x + .5; + y1 = ((cy - canvas->scroll_y1) * n) - center_y + .5; + + canvas->pixels_per_unit = n; + + if (!(canvas->root->flags & EEL_CANVAS_ITEM_NEED_DEEP_UPDATE)) + { + canvas->root->flags |= EEL_CANVAS_ITEM_NEED_DEEP_UPDATE; + eel_canvas_request_update (canvas); + } + + /* Map a background None window over the bin_window to avoid + * scrolling the window scroll causing exposes. + */ + window = NULL; + if (gtk_widget_get_mapped (widget)) + { + GtkAllocation allocation; + attributes.window_type = GDK_WINDOW_CHILD; + gtk_widget_get_allocation (widget, &allocation); + attributes.x = allocation.x; + attributes.y = allocation.y; + attributes.width = allocation.width; + attributes.height = allocation.height; + attributes.wclass = GDK_INPUT_OUTPUT; + attributes.visual = gtk_widget_get_visual (widget); + attributes.colormap = gtk_widget_get_colormap (widget); + attributes.event_mask = GDK_VISIBILITY_NOTIFY_MASK; + + attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP; + + window = gdk_window_new (gtk_widget_get_parent_window (widget), + &attributes, attributes_mask); + gdk_window_set_back_pixmap (window, NULL, FALSE); + gdk_window_set_user_data (window, widget); + + gdk_window_show (window); + } + + scroll_to (canvas, x1, y1); + + /* If we created a an overlapping background None window, remove it how. + * + * TODO: We would like to temporarily set the bin_window background to + * None to avoid clearing the bin_window to the background, but gdk doesn't + * expose enought to let us do this, so we get a flash-effect here. At least + * it looks better than scroll + expose. + */ + if (window != NULL) + { + gdk_window_hide (window); + gdk_window_set_user_data (window, NULL); + gdk_window_destroy (window); + } + + canvas->need_repick = TRUE; +} + +/** + * eel_canvas_scroll_to: + * @canvas: A canvas. + * @cx: Horizontal scrolling offset in canvas pixel units. + * @cy: Vertical scrolling offset in canvas pixel units. + * + * Makes a canvas scroll to the specified offsets, given in canvas pixel units. + * The canvas will adjust the view so that it is not outside the scrolling + * region. This function is typically not used, as it is better to hook + * scrollbars to the canvas layout's scrolling adjusments. + **/ +void +eel_canvas_scroll_to (EelCanvas *canvas, int cx, int cy) +{ + g_return_if_fail (EEL_IS_CANVAS (canvas)); + + scroll_to (canvas, cx, cy); +} + +/** + * eel_canvas_get_scroll_offsets: + * @canvas: A canvas. + * @cx: Horizontal scrolling offset (return value). + * @cy: Vertical scrolling offset (return value). + * + * Queries the scrolling offsets of a canvas. The values are returned in canvas + * pixel units. + **/ +void +eel_canvas_get_scroll_offsets (EelCanvas *canvas, int *cx, int *cy) +{ + GtkAdjustment *vadjustment, *hadjustment; + + g_return_if_fail (EEL_IS_CANVAS (canvas)); + + hadjustment = gtk_layout_get_hadjustment (&canvas->layout); + vadjustment = gtk_layout_get_vadjustment (&canvas->layout); + + if (cx) + *cx = gtk_adjustment_get_value (hadjustment); + + if (cy) + *cy = gtk_adjustment_get_value (vadjustment); +} + +/** + * eel_canvas_update_now: + * @canvas: A canvas. + * + * Forces an immediate update and redraw of a canvas. If the canvas does not + * have any pending update or redraw requests, then no action is taken. This is + * typically only used by applications that need explicit control of when the + * display is updated, like games. It is not needed by normal applications. + */ +void +eel_canvas_update_now (EelCanvas *canvas) +{ + g_return_if_fail (EEL_IS_CANVAS (canvas)); + + if (!(canvas->need_update || canvas->need_redraw)) + return; + remove_idle (canvas); + do_update (canvas); +} + +/** + * eel_canvas_get_item_at: + * @canvas: A canvas. + * @x: X position in world coordinates. + * @y: Y position in world coordinates. + * + * Looks for the item that is under the specified position, which must be + * specified in world coordinates. + * + * Return value: The sought item, or NULL if no item is at the specified + * coordinates. + **/ +EelCanvasItem * +eel_canvas_get_item_at (EelCanvas *canvas, double x, double y) +{ + EelCanvasItem *item; + double dist; + int cx, cy; + + g_return_val_if_fail (EEL_IS_CANVAS (canvas), NULL); + + eel_canvas_w2c (canvas, x, y, &cx, &cy); + + dist = eel_canvas_item_invoke_point (canvas->root, x, y, cx, cy, &item); + if ((int) (dist * canvas->pixels_per_unit + 0.5) <= canvas->close_enough) + return item; + else + return NULL; +} + +/* Queues an update of the canvas */ +static void +eel_canvas_request_update (EelCanvas *canvas) +{ + EEL_CANVAS_GET_CLASS (canvas)->request_update (canvas); +} + +static void +eel_canvas_request_update_real (EelCanvas *canvas) +{ + canvas->need_update = TRUE; + add_idle (canvas); +} + +/** + * eel_canvas_request_redraw: + * @canvas: A canvas. + * @x1: Leftmost coordinate of the rectangle to be redrawn. + * @y1: Upper coordinate of the rectangle to be redrawn. + * @x2: Rightmost coordinate of the rectangle to be redrawn, plus 1. + * @y2: Lower coordinate of the rectangle to be redrawn, plus 1. + * + * Convenience function that informs a canvas that the specified rectangle needs + * to be repainted. The rectangle includes @x1 and @y1, but not @x2 and @y2. + * To be used only by item implementations. + **/ +void +eel_canvas_request_redraw (EelCanvas *canvas, int x1, int y1, int x2, int y2) +{ + GdkRectangle bbox; + + g_return_if_fail (EEL_IS_CANVAS (canvas)); + + if (!gtk_widget_is_drawable (GTK_WIDGET (canvas)) + || (x1 >= x2) || (y1 >= y2)) return; + + bbox.x = x1; + bbox.y = y1; + bbox.width = x2 - x1; + bbox.height = y2 - y1; + + gdk_window_invalidate_rect (gtk_layout_get_bin_window (&canvas->layout), + &bbox, FALSE); +} + +/** + * eel_canvas_w2c: + * @canvas: A canvas. + * @wx: World X coordinate. + * @wy: World Y coordinate. + * @cx: X pixel coordinate (return value). + * @cy: Y pixel coordinate (return value). + * + * Converts world coordinates into canvas pixel coordinates. + **/ +void +eel_canvas_w2c (EelCanvas *canvas, double wx, double wy, int *cx, int *cy) +{ + double zoom; + + g_return_if_fail (EEL_IS_CANVAS (canvas)); + + zoom = canvas->pixels_per_unit; + + if (cx) + *cx = floor ((wx - canvas->scroll_x1)*zoom + canvas->zoom_xofs + 0.5); + if (cy) + *cy = floor ((wy - canvas->scroll_y1)*zoom + canvas->zoom_yofs + 0.5); +} + +/** + * eel_canvas_w2c: + * @canvas: A canvas. + * @world: rectangle in world coordinates. + * @canvas: rectangle in canvase coordinates. + * + * Converts rectangles in world coordinates into canvas pixel coordinates. + **/ +void +eel_canvas_w2c_rect_d (EelCanvas *canvas, + double *x1, double *y1, + double *x2, double *y2) +{ + eel_canvas_w2c_d (canvas, + *x1, *y1, + x1, y1); + eel_canvas_w2c_d (canvas, + *x2, *y2, + x2, y2); +} + + + +/** + * eel_canvas_w2c_d: + * @canvas: A canvas. + * @wx: World X coordinate. + * @wy: World Y coordinate. + * @cx: X pixel coordinate (return value). + * @cy: Y pixel coordinate (return value). + * + * Converts world coordinates into canvas pixel coordinates. This version + * produces coordinates in floating point coordinates, for greater precision. + **/ +void +eel_canvas_w2c_d (EelCanvas *canvas, double wx, double wy, double *cx, double *cy) +{ + double zoom; + + g_return_if_fail (EEL_IS_CANVAS (canvas)); + + zoom = canvas->pixels_per_unit; + + if (cx) + *cx = (wx - canvas->scroll_x1)*zoom + canvas->zoom_xofs; + if (cy) + *cy = (wy - canvas->scroll_y1)*zoom + canvas->zoom_yofs; +} + + +/** + * eel_canvas_c2w: + * @canvas: A canvas. + * @cx: Canvas pixel X coordinate. + * @cy: Canvas pixel Y coordinate. + * @wx: X world coordinate (return value). + * @wy: Y world coordinate (return value). + * + * Converts canvas pixel coordinates to world coordinates. + **/ +void +eel_canvas_c2w (EelCanvas *canvas, int cx, int cy, double *wx, double *wy) +{ + double zoom; + + g_return_if_fail (EEL_IS_CANVAS (canvas)); + + zoom = canvas->pixels_per_unit; + + if (wx) + *wx = (cx - canvas->zoom_xofs)/zoom + canvas->scroll_x1; + if (wy) + *wy = (cy - canvas->zoom_yofs)/zoom + canvas->scroll_y1; +} + + +/** + * eel_canvas_window_to_world: + * @canvas: A canvas. + * @winx: Window-relative X coordinate. + * @winy: Window-relative Y coordinate. + * @worldx: X world coordinate (return value). + * @worldy: Y world coordinate (return value). + * + * Converts window-relative coordinates into world coordinates. You can use + * this when you need to convert mouse coordinates into world coordinates, for + * example. + * Window coordinates are really the same as canvas coordinates now, but this + * function is here for backwards compatibility reasons. + **/ +void +eel_canvas_window_to_world (EelCanvas *canvas, double winx, double winy, + double *worldx, double *worldy) +{ + g_return_if_fail (EEL_IS_CANVAS (canvas)); + + if (worldx) + *worldx = canvas->scroll_x1 + ((winx - canvas->zoom_xofs) + / canvas->pixels_per_unit); + + if (worldy) + *worldy = canvas->scroll_y1 + ((winy - canvas->zoom_yofs) + / canvas->pixels_per_unit); +} + + +/** + * eel_canvas_world_to_window: + * @canvas: A canvas. + * @worldx: World X coordinate. + * @worldy: World Y coordinate. + * @winx: X window-relative coordinate. + * @winy: Y window-relative coordinate. + * + * Converts world coordinates into window-relative coordinates. + * Window coordinates are really the same as canvas coordinates now, but this + * function is here for backwards compatibility reasons. + **/ +void +eel_canvas_world_to_window (EelCanvas *canvas, double worldx, double worldy, + double *winx, double *winy) +{ + g_return_if_fail (EEL_IS_CANVAS (canvas)); + + if (winx) + *winx = (canvas->pixels_per_unit)*(worldx - canvas->scroll_x1) + canvas->zoom_xofs; + + if (winy) + *winy = (canvas->pixels_per_unit)*(worldy - canvas->scroll_y1) + canvas->zoom_yofs; +} + + + +/** + * eel_canvas_get_color: + * @canvas: A canvas. + * @spec: X color specification, or NULL for "transparent". + * @color: Returns the allocated color. + * + * Allocates a color based on the specified X color specification. As a + * convenience to item implementations, it returns TRUE if the color was + * allocated, or FALSE if the specification was NULL. A NULL color + * specification is considered as "transparent" by the canvas. + * + * Return value: TRUE if @spec is non-NULL and the color is allocated. If @spec + * is NULL, then returns FALSE. + **/ +int +eel_canvas_get_color (EelCanvas *canvas, const char *spec, GdkColor *color) +{ + GdkColormap *colormap; + + g_return_val_if_fail (EEL_IS_CANVAS (canvas), FALSE); + g_return_val_if_fail (color != NULL, FALSE); + + if (!spec) + { + color->pixel = 0; + color->red = 0; + color->green = 0; + color->blue = 0; + return FALSE; + } + + gdk_color_parse (spec, color); + + colormap = gtk_widget_get_colormap (GTK_WIDGET (canvas)); + + gdk_rgb_find_color (colormap, color); + + return TRUE; +} + +/** + * eel_canvas_get_color_pixel: + * @canvas: A canvas. + * @rgba: RGBA color specification. + * + * Allocates a color from the RGBA value passed into this function. The alpha + * opacity value is discarded, since normal X colors do not support it. + * + * Return value: Allocated pixel value corresponding to the specified color. + **/ +gulong +eel_canvas_get_color_pixel (EelCanvas *canvas, guint rgba) +{ + GdkColormap *colormap; + GdkColor color; + + g_return_val_if_fail (EEL_IS_CANVAS (canvas), 0); + + color.red = ((rgba & 0xff000000) >> 16) + ((rgba & 0xff000000) >> 24); + color.green = ((rgba & 0x00ff0000) >> 8) + ((rgba & 0x00ff0000) >> 16); + color.blue = (rgba & 0x0000ff00) + ((rgba & 0x0000ff00) >> 8); + color.pixel = 0; + + colormap = gtk_widget_get_colormap (GTK_WIDGET (canvas)); + + gdk_rgb_find_color (colormap, &color); + + return color.pixel; +} + + +/* FIXME: This function is not useful anymore */ +/** + * eel_canvas_set_stipple_origin: + * @canvas: A canvas. + * @gc: GC on which to set the stipple origin. + * + * Sets the stipple origin of the specified GC as is appropriate for the canvas, + * so that it will be aligned with other stipple patterns used by canvas items. + * This is typically only needed by item implementations. + **/ +void +eel_canvas_set_stipple_origin (EelCanvas *canvas, GdkGC *gc) +{ + g_return_if_fail (EEL_IS_CANVAS (canvas)); + g_return_if_fail (GDK_IS_GC (gc)); + + gdk_gc_set_ts_origin (gc, 0, 0); +} + +static gboolean +boolean_handled_accumulator (GSignalInvocationHint *ihint, + GValue *return_accu, + const GValue *handler_return, + gpointer dummy) +{ + gboolean continue_emission; + gboolean signal_handled; + + signal_handled = g_value_get_boolean (handler_return); + g_value_set_boolean (return_accu, signal_handled); + continue_emission = !signal_handled; + + return continue_emission; +} + +static guint +eel_canvas_item_accessible_add_focus_handler (AtkComponent *component, + AtkFocusHandler handler) +{ + GSignalMatchType match_type; + guint signal_id; + + match_type = G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC; + signal_id = g_signal_lookup ("focus-event", ATK_TYPE_OBJECT); + + if (!g_signal_handler_find (component, match_type, signal_id, 0, NULL, + (gpointer) handler, NULL)) + { + return g_signal_connect_closure_by_id (component, + signal_id, 0, + g_cclosure_new ( + G_CALLBACK (handler), NULL, + (GClosureNotify) NULL), + FALSE); + } + return 0; +} + +static void +eel_canvas_item_accessible_get_item_extents (EelCanvasItem *item, + GdkRectangle *rect) +{ + double bx1, bx2, by1, by2; + gint scroll_x, scroll_y; + gint x1, x2, y1, y2; + + eel_canvas_item_get_bounds (item, &bx1, &by1, &bx2, &by2); + eel_canvas_w2c_rect_d (item->canvas, &bx1, &by1, &bx2, &by2); + eel_canvas_get_scroll_offsets (item->canvas, &scroll_x, &scroll_y); + x1 = floor (bx1 + .5); + y1 = floor (by1 + .5); + x2 = floor (bx2 + .5); + y2 = floor (by2 + .5); + rect->x = x1 - scroll_x; + rect->y = y1 - scroll_y; + rect->width = x2 - x1; + rect->height = y2 - y1; +} + +static gboolean +eel_canvas_item_accessible_is_item_in_window (EelCanvasItem *item, + GdkRectangle *rect) +{ + GtkWidget *widget; + gboolean retval; + + widget = GTK_WIDGET (item->canvas); + if (gtk_widget_get_window (widget)) + { + int window_width, window_height; + + gdk_window_get_geometry (gtk_widget_get_window (widget), NULL, NULL, + &window_width, &window_height, NULL); + /* + * Check whether rectangles intersect + */ + if (rect->x + rect->width < 0 || + rect->y + rect->height < 0 || + rect->x > window_width || + rect->y > window_height) + { + retval = FALSE; + } + else + { + retval = TRUE; + } + } + else + { + retval = FALSE; + } + return retval; +} + + +static void +eel_canvas_item_accessible_get_extents (AtkComponent *component, + gint *x, + gint *y, + gint *width, + gint *height, + AtkCoordType coord_type) +{ + AtkGObjectAccessible *atk_gobj; + GObject *obj; + EelCanvasItem *item; + gint window_x, window_y; + gint toplevel_x, toplevel_y; + GdkRectangle rect; + GdkWindow *window; + GtkWidget *canvas; + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (component); + obj = atk_gobject_accessible_get_object (atk_gobj); + + if (obj == NULL) + { + /* item is defunct */ + return; + } + + /* Get the CanvasItem */ + item = EEL_CANVAS_ITEM (obj); + + /* If this item has no parent canvas, something's broken */ + g_return_if_fail (GTK_IS_WIDGET (item->canvas)); + + eel_canvas_item_accessible_get_item_extents (item, &rect); + *width = rect.width; + *height = rect.height; + if (!eel_canvas_item_accessible_is_item_in_window (item, &rect)) + { + *x = G_MININT; + *y = G_MININT; + return; + } + + canvas = GTK_WIDGET (item->canvas); + window = gtk_widget_get_parent_window (canvas); + gdk_window_get_origin (window, &window_x, &window_y); + *x = rect.x + window_x; + *y = rect.y + window_y; + if (coord_type == ATK_XY_WINDOW) + { + window = gdk_window_get_toplevel (gtk_widget_get_window (canvas)); + gdk_window_get_origin (window, &toplevel_x, &toplevel_y); + *x -= toplevel_x; + *y -= toplevel_y; + } + return; +} + +static gint +eel_canvas_item_accessible_get_mdi_zorder (AtkComponent *component) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + EelCanvasItem *item; + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (component); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (g_obj == NULL) + { + /* Object is defunct */ + return -1; + } + + item = EEL_CANVAS_ITEM (g_obj); + if (item->parent) + { + return g_list_index (EEL_CANVAS_GROUP (item->parent)->item_list, item); + } + else + { + g_return_val_if_fail (item->canvas->root == item, -1); + return 0; + } +} + +static gboolean +eel_canvas_item_accessible_grab_focus (AtkComponent *component) +{ + AtkGObjectAccessible *atk_gobj; + GObject *obj; + EelCanvasItem *item; + GtkWidget *toplevel; + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (component); + obj = atk_gobject_accessible_get_object (atk_gobj); + + item = EEL_CANVAS_ITEM (obj); + if (item == NULL) + { + /* item is defunct */ + return FALSE; + } + + eel_canvas_item_grab_focus (item); + toplevel = gtk_widget_get_toplevel (GTK_WIDGET (item->canvas)); + if (gtk_widget_is_toplevel (toplevel)) + { + gtk_window_present (GTK_WINDOW (toplevel)); + } + + return TRUE; +} + +static void +eel_canvas_item_accessible_remove_focus_handler (AtkComponent *component, + guint handler_id) +{ + g_signal_handler_disconnect (component, handler_id); +} + +static void +eel_canvas_item_accessible_component_interface_init (AtkComponentIface *iface) +{ + g_return_if_fail (iface != NULL); + + iface->add_focus_handler = eel_canvas_item_accessible_add_focus_handler; + iface->get_extents = eel_canvas_item_accessible_get_extents; + iface->get_mdi_zorder = eel_canvas_item_accessible_get_mdi_zorder; + iface->grab_focus = eel_canvas_item_accessible_grab_focus; + iface->remove_focus_handler = eel_canvas_item_accessible_remove_focus_handler; +} + +static gboolean +eel_canvas_item_accessible_is_item_on_screen (EelCanvasItem *item) +{ + GdkRectangle rect; + + eel_canvas_item_accessible_get_item_extents (item, &rect); + return eel_canvas_item_accessible_is_item_in_window (item, &rect); +} + +static void +eel_canvas_item_accessible_initialize (AtkObject *obj, gpointer data) +{ + if (ATK_OBJECT_CLASS (accessible_item_parent_class)->initialize != NULL) + ATK_OBJECT_CLASS (accessible_item_parent_class)->initialize (obj, data); + g_object_set_data (G_OBJECT (obj), "atk-component-layer", + GINT_TO_POINTER (ATK_LAYER_MDI)); +} + +static AtkStateSet* +eel_canvas_item_accessible_ref_state_set (AtkObject *accessible) +{ + AtkGObjectAccessible *atk_gobj; + GObject *obj; + EelCanvasItem *item; + AtkStateSet *state_set; + + state_set = ATK_OBJECT_CLASS (accessible_item_parent_class)->ref_state_set (accessible); + atk_gobj = ATK_GOBJECT_ACCESSIBLE (accessible); + obj = atk_gobject_accessible_get_object (atk_gobj); + + item = EEL_CANVAS_ITEM (obj); + if (item == NULL) + { + atk_state_set_add_state (state_set, ATK_STATE_DEFUNCT); + } + else + { + if (item->flags & EEL_CANVAS_ITEM_VISIBLE) + { + atk_state_set_add_state (state_set, ATK_STATE_VISIBLE); + + if (eel_canvas_item_accessible_is_item_on_screen (item)) + { + atk_state_set_add_state (state_set, ATK_STATE_SHOWING); + } + } + if (gtk_widget_get_can_focus (GTK_WIDGET (item->canvas))) + { + atk_state_set_add_state (state_set, ATK_STATE_FOCUSABLE); + + if (item->canvas->focused_item == item) + { + atk_state_set_add_state (state_set, ATK_STATE_FOCUSED); + } + } + } + + return state_set; +} + +static void +eel_canvas_item_accessible_class_init (AtkObjectClass *klass) +{ + accessible_item_parent_class = g_type_class_peek_parent (klass); + + klass->initialize = eel_canvas_item_accessible_initialize; + klass->ref_state_set = eel_canvas_item_accessible_ref_state_set; +} + +static GType +eel_canvas_item_accessible_get_type (void) +{ + static GType type = 0; + + if (!type) + { + static const GInterfaceInfo atk_component_info = + { + (GInterfaceInitFunc) eel_canvas_item_accessible_component_interface_init, + (GInterfaceFinalizeFunc) NULL, + NULL + }; + AtkObjectFactory *factory; + GType parent_atk_type; + GTypeQuery query; + GTypeInfo tinfo = { 0 }; + + factory = atk_registry_get_factory (atk_get_default_registry(), + GTK_TYPE_OBJECT); + if (!factory) + { + return G_TYPE_INVALID; + } + parent_atk_type = atk_object_factory_get_accessible_type (factory); + if (!parent_atk_type) + { + return G_TYPE_INVALID; + } + g_type_query (parent_atk_type, &query); + tinfo.class_init = (GClassInitFunc) eel_canvas_item_accessible_class_init; + tinfo.class_size = query.class_size; + tinfo.instance_size = query.instance_size; + type = g_type_register_static (parent_atk_type, + "EelCanvasItemAccessibility", + &tinfo, 0); + + g_type_add_interface_static (type, ATK_TYPE_COMPONENT, + &atk_component_info); + + } + + return type; +} + +static AtkObject * +eel_canvas_item_accessible_create (GObject *for_object) +{ + GType type; + AtkObject *accessible; + EelCanvasItem *item; + + item = EEL_CANVAS_ITEM (for_object); + g_return_val_if_fail (item != NULL, NULL); + + type = eel_canvas_item_accessible_get_type (); + if (type == G_TYPE_INVALID) + { + return atk_no_op_object_new (for_object); + } + + accessible = g_object_new (type, NULL); + atk_object_initialize (accessible, for_object); + return accessible; +} + +static GType +eel_canvas_item_accessible_factory_get_accessible_type (void) +{ + return eel_canvas_item_accessible_get_type (); +} + +static AtkObject* +eel_canvas_item_accessible_factory_create_accessible (GObject *obj) +{ + AtkObject *accessible; + + g_return_val_if_fail (G_IS_OBJECT (obj), NULL); + + accessible = eel_canvas_item_accessible_create (obj); + + return accessible; +} + +static void +eel_canvas_item_accessible_factory_class_init (AtkObjectFactoryClass *klass) +{ + klass->create_accessible = eel_canvas_item_accessible_factory_create_accessible; + klass->get_accessible_type = eel_canvas_item_accessible_factory_get_accessible_type; +} + +static GType +eel_canvas_item_accessible_factory_get_type (void) +{ + static GType type = 0; + + if (!type) + { + static const GTypeInfo tinfo = + { + sizeof (AtkObjectFactoryClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) eel_canvas_item_accessible_factory_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (AtkObjectFactory), + 0, /* n_preallocs */ + NULL + }; + type = g_type_register_static (ATK_TYPE_OBJECT_FACTORY, + "EelCanvasItemAccessibilityFactory", + &tinfo, 0); + } + + return type; +} + +/* Class initialization function for EelCanvasItemClass */ +static void +eel_canvas_item_class_init (EelCanvasItemClass *klass) +{ + GObjectClass *gobject_class = (GObjectClass *) klass; + + item_parent_class = g_type_class_peek_parent (klass); + + gobject_class->set_property = eel_canvas_item_set_property; + gobject_class->get_property = eel_canvas_item_get_property; + gobject_class->dispose = eel_canvas_item_dispose; + + g_object_class_install_property + (gobject_class, ITEM_PROP_PARENT, + g_param_spec_object ("parent", NULL, NULL, + EEL_TYPE_CANVAS_ITEM, + G_PARAM_READWRITE)); + + g_object_class_install_property + (gobject_class, ITEM_PROP_VISIBLE, + g_param_spec_boolean ("visible", NULL, NULL, + TRUE, + G_PARAM_READWRITE)); + + item_signals[ITEM_EVENT] = + g_signal_new ("event", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (EelCanvasItemClass, event), + boolean_handled_accumulator, NULL, + eel_marshal_BOOLEAN__BOXED, + G_TYPE_BOOLEAN, 1, + GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE); + + klass->realize = eel_canvas_item_realize; + klass->unrealize = eel_canvas_item_unrealize; + klass->map = eel_canvas_item_map; + klass->unmap = eel_canvas_item_unmap; + klass->update = eel_canvas_item_update; + + atk_registry_set_factory_type (atk_get_default_registry (), + EEL_TYPE_CANVAS_ITEM, + eel_canvas_item_accessible_factory_get_type ()); +} diff --git a/eel/eel-canvas.h b/eel/eel-canvas.h new file mode 100644 index 00000000..1d185a76 --- /dev/null +++ b/eel/eel-canvas.h @@ -0,0 +1,545 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: 8; c-basic-offset: 8 -*- */ +/* + * Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation + * All rights reserved. + * + * This file is part of the Mate Library. + * + * The Mate Library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * The Mate Library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the Mate Library; see the file COPYING.LIB. If not, + * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ +/* + @NOTATION@ + */ +/* EelCanvas widget - Tk-like canvas widget for Mate + * + * EelCanvas is basically a port of the Tk toolkit's most excellent canvas + * widget. Tk is copyrighted by the Regents of the University of California, + * Sun Microsystems, and other parties. + * + * + * Authors: Federico Mena + * Raph Levien + */ + +#ifndef EEL_CANVAS_H +#define EEL_CANVAS_H + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + + + /* "Small" value used by canvas stuff */ +#define EEL_CANVAS_EPSILON 1e-10 + + + /* Macros for building colors that fit in a 32-bit integer. The values are in + * [0, 255]. + */ + +#define EEL_CANVAS_COLOR(r, g, b) ((((int) (r) & 0xff) << 24) \ + | (((int) (g) & 0xff) << 16) \ + | (((int) (b) & 0xff) << 8) \ + | 0xff) + +#define EEL_CANVAS_COLOR_A(r, g, b, a) ((((int) (r) & 0xff) << 24) \ + | (((int) (g) & 0xff) << 16) \ + | (((int) (b) & 0xff) << 8) \ + | ((int) (a) & 0xff)) + + + typedef struct _EelCanvas EelCanvas; + typedef struct _EelCanvasClass EelCanvasClass; + typedef struct _EelCanvasItem EelCanvasItem; + typedef struct _EelCanvasItemClass EelCanvasItemClass; + typedef struct _EelCanvasGroup EelCanvasGroup; + typedef struct _EelCanvasGroupClass EelCanvasGroupClass; + + + /* EelCanvasItem - base item class for canvas items + * + * All canvas items are derived from EelCanvasItem. The only information a + * EelCanvasItem contains is its parent canvas, its parent canvas item group, + * and its bounding box in world coordinates. + * + * Items inside a canvas are organized in a tree of EelCanvasItemGroup nodes + * and EelCanvasItem leaves. Each canvas has a single root group, which can + * be obtained with the eel_canvas_get_root() function. + * + * The abstract EelCanvasItem class does not have any configurable or + * queryable attributes. + */ + + /* Object flags for items */ + enum + { + EEL_CANVAS_ITEM_REALIZED = 1 << 4, + EEL_CANVAS_ITEM_MAPPED = 1 << 5, + EEL_CANVAS_ITEM_ALWAYS_REDRAW = 1 << 6, + EEL_CANVAS_ITEM_VISIBLE = 1 << 7, + EEL_CANVAS_ITEM_NEED_UPDATE = 1 << 8, + EEL_CANVAS_ITEM_NEED_DEEP_UPDATE = 1 << 9 + }; + + /* Update flags for items */ + enum + { + EEL_CANVAS_UPDATE_REQUESTED = 1 << 0, + EEL_CANVAS_UPDATE_DEEP = 1 << 1 + }; + +#define EEL_TYPE_CANVAS_ITEM (eel_canvas_item_get_type ()) +#define EEL_CANVAS_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEL_TYPE_CANVAS_ITEM, EelCanvasItem)) +#define EEL_CANVAS_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEL_TYPE_CANVAS_ITEM, EelCanvasItemClass)) +#define EEL_IS_CANVAS_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEL_TYPE_CANVAS_ITEM)) +#define EEL_IS_CANVAS_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEL_TYPE_CANVAS_ITEM)) +#define EEL_CANVAS_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEL_TYPE_CANVAS_ITEM, EelCanvasItemClass)) + + + struct _EelCanvasItem + { + GtkObject object; + + /* Parent canvas for this item */ + EelCanvas *canvas; + + /* Parent canvas group for this item (a EelCanvasGroup) */ + EelCanvasItem *parent; + + /* Bounding box for this item (in canvas coordinates) */ + double x1, y1, x2, y2; + + /* Object flags */ + guint flags; + }; + + struct _EelCanvasItemClass + { + GtkObjectClass parent_class; + + /* Tell the item to update itself. The flags are from the update flags + * defined above. The item should update its internal state from its + * queued state, and recompute and request its repaint area. The + * update method also recomputes the bounding box of the item. + */ + void (* update) (EelCanvasItem *item, double i2w_dx, double i2w_dy, int flags); + + /* Realize an item -- create GCs, etc. */ + void (* realize) (EelCanvasItem *item); + + /* Unrealize an item */ + void (* unrealize) (EelCanvasItem *item); + + /* Map an item - normally only need by items with their own GdkWindows */ + void (* map) (EelCanvasItem *item); + + /* Unmap an item */ + void (* unmap) (EelCanvasItem *item); + + /* Draw an item of this type. (x, y) are the upper-left canvas pixel + * coordinates of the drawable, a temporary pixmap, where things get + * drawn. (width, height) are the dimensions of the drawable. + */ + void (* draw) (EelCanvasItem *item, GdkDrawable *drawable, GdkEventExpose *expose); + + /* Calculate the distance from an item to the specified point. It also + * returns a canvas item which is the item itself in the case of the + * object being an actual leaf item, or a child in case of the object + * being a canvas group. (cx, cy) are the canvas pixel coordinates that + * correspond to the item-relative coordinates (x, y). + */ + double (* point) (EelCanvasItem *item, double x, double y, int cx, int cy, + EelCanvasItem **actual_item); + + void (* translate) (EelCanvasItem *item, double dx, double dy); + + /* Fetch the item's bounding box (need not be exactly tight). This + * should be in item-relative coordinates. + */ + void (* bounds) (EelCanvasItem *item, double *x1, double *y1, double *x2, double *y2); + + /* Signal: an event ocurred for an item of this type. The (x, y) + * coordinates are in the canvas world coordinate system. + */ + gboolean (* event) (EelCanvasItem *item, GdkEvent *event); + + /* Reserved for future expansion */ + gpointer spare_vmethods [4]; + }; + + + /* Standard Gtk function */ + GType eel_canvas_item_get_type (void) G_GNUC_CONST; + + /* Create a canvas item using the standard Gtk argument mechanism. The item is + * automatically inserted at the top of the specified canvas group. The last + * argument must be a NULL pointer. + */ + EelCanvasItem *eel_canvas_item_new (EelCanvasGroup *parent, GType type, + const gchar *first_arg_name, ...); + + /* Constructors for use in derived classes and language wrappers */ + void eel_canvas_item_construct (EelCanvasItem *item, EelCanvasGroup *parent, + const gchar *first_arg_name, va_list args); + + /* Configure an item using the standard Gtk argument mechanism. The last + * argument must be a NULL pointer. + */ + void eel_canvas_item_set (EelCanvasItem *item, const gchar *first_arg_name, ...); + + /* Used only for language wrappers and the like */ + void eel_canvas_item_set_valist (EelCanvasItem *item, + const gchar *first_arg_name, va_list args); + + /* Move an item by the specified amount */ + void eel_canvas_item_move (EelCanvasItem *item, double dx, double dy); + + /* Raise an item in the z-order of its parent group by the specified number of + * positions. + */ + void eel_canvas_item_raise (EelCanvasItem *item, int positions); + + /* Lower an item in the z-order of its parent group by the specified number of + * positions. + */ + void eel_canvas_item_lower (EelCanvasItem *item, int positions); + + /* Raise an item to the top of its parent group's z-order. */ + void eel_canvas_item_raise_to_top (EelCanvasItem *item); + + /* Lower an item to the bottom of its parent group's z-order */ + void eel_canvas_item_lower_to_bottom (EelCanvasItem *item); + + /* Send an item behind another item */ + void eel_canvas_item_send_behind (EelCanvasItem *item, + EelCanvasItem *behind_item); + + + /* Show an item (make it visible). If the item is already shown, it has no + * effect. + */ + void eel_canvas_item_show (EelCanvasItem *item); + + /* Hide an item (make it invisible). If the item is already invisible, it has + * no effect. + */ + void eel_canvas_item_hide (EelCanvasItem *item); + + /* Grab the mouse for the specified item. Only the events in event_mask will be + * reported. If cursor is non-NULL, it will be used during the duration of the + * grab. Time is a proper X event time parameter. Returns the same values as + * XGrabPointer(). + */ + int eel_canvas_item_grab (EelCanvasItem *item, unsigned int event_mask, + GdkCursor *cursor, guint32 etime); + + /* Ungrabs the mouse -- the specified item must be the same that was passed to + * eel_canvas_item_grab(). Time is a proper X event time parameter. + */ + void eel_canvas_item_ungrab (EelCanvasItem *item, guint32 etime); + + /* These functions convert from a coordinate system to another. "w" is world + * coordinates and "i" is item coordinates. + */ + void eel_canvas_item_w2i (EelCanvasItem *item, double *x, double *y); + void eel_canvas_item_i2w (EelCanvasItem *item, double *x, double *y); + + /* Remove the item from its parent group and make the new group its parent. The + * item will be put on top of all the items in the new group. The item's + * coordinates relative to its new parent to *not* change -- this means that the + * item could potentially move on the screen. + * + * The item and the group must be in the same canvas. An item cannot be + * reparented to a group that is the item itself or that is an inferior of the + * item. + */ + void eel_canvas_item_reparent (EelCanvasItem *item, EelCanvasGroup *new_group); + + /* Used to send all of the keystroke events to a specific item as well as + * GDK_FOCUS_CHANGE events. + */ + void eel_canvas_item_grab_focus (EelCanvasItem *item); + + /* Fetch the bounding box of the item. The bounding box may not be exactly + * tight, but the canvas items will do the best they can. The returned bounding + * box is in the coordinate system of the item's parent. + */ + void eel_canvas_item_get_bounds (EelCanvasItem *item, + double *x1, double *y1, double *x2, double *y2); + + /* Request that the update method eventually get called. This should be used + * only by item implementations. + */ + void eel_canvas_item_request_update (EelCanvasItem *item); + + /* Request a redraw of the bounding box of the canvas item */ + void eel_canvas_item_request_redraw (EelCanvasItem *item); + + /* EelCanvasGroup - a group of canvas items + * + * A group is a node in the hierarchical tree of groups/items inside a canvas. + * Groups serve to give a logical structure to the items. + * + * Consider a circuit editor application that uses the canvas for its schematic + * display. Hierarchically, there would be canvas groups that contain all the + * components needed for an "adder", for example -- this includes some logic + * gates as well as wires. You can move stuff around in a convenient way by + * doing a eel_canvas_item_move() of the hierarchical groups -- to move an + * adder, simply move the group that represents the adder. + * + * The following arguments are available: + * + * name type read/write description + * -------------------------------------------------------------------------------- + * x double RW X coordinate of group's origin + * y double RW Y coordinate of group's origin + */ + + +#define EEL_TYPE_CANVAS_GROUP (eel_canvas_group_get_type ()) +#define EEL_CANVAS_GROUP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEL_TYPE_CANVAS_GROUP, EelCanvasGroup)) +#define EEL_CANVAS_GROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEL_TYPE_CANVAS_GROUP, EelCanvasGroupClass)) +#define EEL_IS_CANVAS_GROUP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEL_TYPE_CANVAS_GROUP)) +#define EEL_IS_CANVAS_GROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEL_TYPE_CANVAS_GROUP)) +#define EEL_CANVAS_GROUP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEL_TYPE_CANVAS_GROUP, EelCanvasGroupClass)) + + + struct _EelCanvasGroup + { + EelCanvasItem item; + + double xpos, ypos; + + /* Children of the group */ + GList *item_list; + GList *item_list_end; + }; + + struct _EelCanvasGroupClass + { + EelCanvasItemClass parent_class; + }; + + + /* Standard Gtk function */ + GType eel_canvas_group_get_type (void) G_GNUC_CONST; + + + /*** EelCanvas ***/ + + +#define EEL_TYPE_CANVAS (eel_canvas_get_type ()) +#define EEL_CANVAS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEL_TYPE_CANVAS, EelCanvas)) +#define EEL_CANVAS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EEL_TYPE_CANVAS, EelCanvasClass)) +#define EEL_IS_CANVAS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEL_TYPE_CANVAS)) +#define EEL_IS_CANVAS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EEL_TYPE_CANVAS)) +#define EEL_CANVAS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EEL_TYPE_CANVAS, EelCanvasClass)) + + + struct _EelCanvas + { + GtkLayout layout; + + /* Root canvas group */ + EelCanvasItem *root; + + /* The item containing the mouse pointer, or NULL if none */ + EelCanvasItem *current_item; + + /* Item that is about to become current (used to track deletions and such) */ + EelCanvasItem *new_current_item; + + /* Item that holds a pointer grab, or NULL if none */ + EelCanvasItem *grabbed_item; + + /* If non-NULL, the currently focused item */ + EelCanvasItem *focused_item; + + /* GC for temporary draw pixmap */ + GdkGC *pixmap_gc; + + /* Event on which selection of current item is based */ + GdkEvent pick_event; + + /* Scrolling region */ + double scroll_x1, scroll_y1; + double scroll_x2, scroll_y2; + + /* Scaling factor to be used for display */ + double pixels_per_unit; + + /* Idle handler ID */ + guint idle_id; + + /* Signal handler ID for destruction of the root item */ + guint root_destroy_id; + + /* Internal pixel offsets when zoomed out */ + int zoom_xofs, zoom_yofs; + + /* Last known modifier state, for deferred repick when a button is down */ + int state; + + /* Event mask specified when grabbing an item */ + guint grabbed_event_mask; + + /* Tolerance distance for picking items */ + int close_enough; + + /* Whether the canvas should center the canvas in the middle of + * the window if the scroll region is smaller than the window */ + unsigned int center_scroll_region : 1; + + /* Whether items need update at next idle loop iteration */ + unsigned int need_update : 1; + + /* Are we in the midst of an update */ + unsigned int doing_update : 1; + + /* Whether the canvas needs redrawing at the next idle loop iteration */ + unsigned int need_redraw : 1; + + /* Whether current item will be repicked at next idle loop iteration */ + unsigned int need_repick : 1; + + /* For use by internal pick_current_item() function */ + unsigned int left_grabbed_item : 1; + + /* For use by internal pick_current_item() function */ + unsigned int in_repick : 1; + }; + + struct _EelCanvasClass + { + GtkLayoutClass parent_class; + + /* Draw the background for the area given. + */ + void (* draw_background) (EelCanvas *canvas, + int x, int y, int width, int height); + + /* Private Virtual methods for groping the canvas inside matecomponent */ + void (* request_update) (EelCanvas *canvas); + + /* Reserved for future expansion */ + gpointer spare_vmethods [4]; + }; + + + /* Standard Gtk function */ + GType eel_canvas_get_type (void) G_GNUC_CONST; + + /* Creates a new canvas. You should check that the canvas is created with the + * proper visual and colormap. Any visual will do unless you intend to insert + * gdk_imlib images into it, in which case you should use the gdk_imlib visual. + * + * You should call eel_canvas_set_scroll_region() soon after calling this + * function to set the desired scrolling limits for the canvas. + */ + GtkWidget *eel_canvas_new (void); + + /* Returns the root canvas item group of the canvas */ + EelCanvasGroup *eel_canvas_root (EelCanvas *canvas); + + /* Sets the limits of the scrolling region, in world coordinates */ + void eel_canvas_set_scroll_region (EelCanvas *canvas, + double x1, double y1, double x2, double y2); + + /* Gets the limits of the scrolling region, in world coordinates */ + void eel_canvas_get_scroll_region (EelCanvas *canvas, + double *x1, double *y1, double *x2, double *y2); + + /* Sets the number of pixels that correspond to one unit in world coordinates */ + void eel_canvas_set_pixels_per_unit (EelCanvas *canvas, double n); + + /* Wether the canvas centers the scroll region if it is smaller than the window */ + void eel_canvas_set_center_scroll_region (EelCanvas *canvas, gboolean center_scroll_region); + + /* Scrolls the canvas to the specified offsets, given in canvas pixel coordinates */ + void eel_canvas_scroll_to (EelCanvas *canvas, int cx, int cy); + + /* Returns the scroll offsets of the canvas in canvas pixel coordinates. You + * can specify NULL for any of the values, in which case that value will not be + * queried. + */ + void eel_canvas_get_scroll_offsets (EelCanvas *canvas, int *cx, int *cy); + + /* Requests that the canvas be repainted immediately instead of in the idle + * loop. + */ + void eel_canvas_update_now (EelCanvas *canvas); + + /* Returns the item that is at the specified position in world coordinates, or + * NULL if no item is there. + */ + EelCanvasItem *eel_canvas_get_item_at (EelCanvas *canvas, double x, double y); + + /* For use only by item type implementations. Request that the canvas + * eventually redraw the specified region, specified in canvas pixel + * coordinates. The region contains (x1, y1) but not (x2, y2). + */ + void eel_canvas_request_redraw (EelCanvas *canvas, int x1, int y1, int x2, int y2); + + /* These functions convert from a coordinate system to another. "w" is world + * coordinates, "c" is canvas pixel coordinates (pixel coordinates that are + * (0,0) for the upper-left scrolling limit and something else for the + * lower-left scrolling limit). + */ + void eel_canvas_w2c_rect_d (EelCanvas *canvas, + double *x1, double *y1, + double *x2, double *y2); + void eel_canvas_w2c (EelCanvas *canvas, double wx, double wy, int *cx, int *cy); + void eel_canvas_w2c_d (EelCanvas *canvas, double wx, double wy, double *cx, double *cy); + void eel_canvas_c2w (EelCanvas *canvas, int cx, int cy, double *wx, double *wy); + + /* This function takes in coordinates relative to the GTK_LAYOUT + * (canvas)->bin_window and converts them to world coordinates. + * These days canvas coordinates and window coordinates are the same, but + * these are left for backwards compat reasons. + */ + void eel_canvas_window_to_world (EelCanvas *canvas, + double winx, double winy, double *worldx, double *worldy); + + /* This is the inverse of eel_canvas_window_to_world() */ + void eel_canvas_world_to_window (EelCanvas *canvas, + double worldx, double worldy, double *winx, double *winy); + + /* Takes a string specification for a color and allocates it into the specified + * GdkColor. If the string is null, then it returns FALSE. Otherwise, it + * returns TRUE. + */ + int eel_canvas_get_color (EelCanvas *canvas, const char *spec, GdkColor *color); + + /* Allocates a color from the RGB value passed into this function. */ + gulong eel_canvas_get_color_pixel (EelCanvas *canvas, + guint rgba); + + + /* Sets the stipple origin of the specified gc so that it will be aligned with + * all the stipples used in the specified canvas. This is intended for use only + * by canvas item implementations. + */ + void eel_canvas_set_stipple_origin (EelCanvas *canvas, GdkGC *gc); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/eel/eel-debug-drawing.c b/eel/eel-debug-drawing.c new file mode 100644 index 00000000..aee400d5 --- /dev/null +++ b/eel/eel-debug-drawing.c @@ -0,0 +1,566 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- + + eel-debug-drawing.c: Eel drawing debugging aids. + + Copyright (C) 2000 Eazel, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this program; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Ramiro Estrugo +*/ + +#include +#include "eel-debug-drawing.h" + +#include "eel-art-gtk-extensions.h" +#include "eel-debug.h" +#include "eel-gdk-extensions.h" +#include "eel-gdk-extensions.h" +#include "eel-gdk-pixbuf-extensions.h" +#include "eel-gtk-extensions.h" +#include "eel-gtk-extensions.h" +#include "eel-gtk-macros.h" + +#include + +#include +#include +#include + +/* + * PixbufViewer is a very simple "private" widget that displays + * a GdkPixbuf. It is used by eel_debug_show_pixbuf() to + * display a pixbuf in an in process pixbuf debugging window. + * + * We cant use EelImage for this because part of the reason + * for pixbuf debugging is to debug EelImage itself. + */ + +#define DEBUG_TYPE_PIXBUF_VIEWER debug_pixbuf_viewer_get_type() +#define DEBUG_PIXBUF_VIEWER(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), DEBUG_TYPE_PIXBUF_VIEWER, DebugPixbufViewer)) +#define DEBUG_IS_PIXBUF_VIEWER(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), DEBUG_TYPE_PIXBUF_VIEWER)) + +typedef struct DebugPixbufViewer DebugPixbufViewer; +typedef struct DebugPixbufViewerClass DebugPixbufViewerClass; + +static GType debug_pixbuf_viewer_get_type (void); +static void debug_pixbuf_viewer_set_pixbuf (DebugPixbufViewer *viewer, + GdkPixbuf *pixbuf); + +struct DebugPixbufViewer +{ + GtkWidget widget; + GdkPixbuf *pixbuf; +}; + +struct DebugPixbufViewerClass +{ + GtkWidgetClass parent_class; +}; + +/* GtkObjectClass methods */ +static void debug_pixbuf_viewer_class_init (DebugPixbufViewerClass *pixbuf_viewer_class); +static void debug_pixbuf_viewer_init (DebugPixbufViewer *pixbuf_viewer); +static void debug_pixbuf_viewer_finalize (GObject *object); + +/* GtkWidgetClass methods */ +static void debug_pixbuf_viewer_size_request (GtkWidget *widget, + GtkRequisition *requisition); +static int debug_pixbuf_viewer_expose_event (GtkWidget *widget, + GdkEventExpose *event); + +EEL_CLASS_BOILERPLATE (DebugPixbufViewer, debug_pixbuf_viewer, GTK_TYPE_WIDGET) + +static void +debug_pixbuf_viewer_class_init (DebugPixbufViewerClass *pixbuf_viewer_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (pixbuf_viewer_class); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (pixbuf_viewer_class); + + object_class->finalize = debug_pixbuf_viewer_finalize; + widget_class->size_request = debug_pixbuf_viewer_size_request; + widget_class->expose_event = debug_pixbuf_viewer_expose_event; +} + +static void +debug_pixbuf_viewer_init (DebugPixbufViewer *viewer) +{ + gtk_widget_set_can_focus (GTK_WIDGET (viewer), FALSE); + gtk_widget_set_has_window (GTK_WIDGET (viewer), FALSE); +} + +static void +debug_pixbuf_viewer_finalize (GObject *object) +{ + DebugPixbufViewer *viewer; + + viewer = DEBUG_PIXBUF_VIEWER (object); + eel_gdk_pixbuf_unref_if_not_null (viewer->pixbuf); + viewer->pixbuf = NULL; + + EEL_CALL_PARENT (G_OBJECT_CLASS, finalize, (object)); +} + +static void +debug_pixbuf_viewer_size_request (GtkWidget *widget, GtkRequisition *requisition) +{ + DebugPixbufViewer *viewer; + EelDimensions dimensions; + + g_assert (DEBUG_IS_PIXBUF_VIEWER (widget)); + g_assert (requisition != NULL); + + viewer = DEBUG_PIXBUF_VIEWER (widget); + + if (viewer->pixbuf != NULL) + { + dimensions = eel_gdk_pixbuf_get_dimensions (viewer->pixbuf); + } + else + { + dimensions = eel_dimensions_empty; + } + + requisition->width = MAX (2, dimensions.width); + requisition->height = MAX (2, dimensions.height); +} + +static int +debug_pixbuf_viewer_expose_event (GtkWidget *widget, GdkEventExpose *event) +{ + DebugPixbufViewer *viewer; + EelIRect clipped_dirty_area; + EelIRect dirty_area; + EelIRect bounds; + GtkAllocation allocation; + + g_assert (DEBUG_IS_PIXBUF_VIEWER (widget)); + g_assert (event != NULL); + g_assert (event->window == gtk_widget_get_window (widget)); + g_assert (gtk_widget_get_realized (widget)); + + viewer = DEBUG_PIXBUF_VIEWER (widget); + + if (viewer->pixbuf == NULL) + { + return TRUE; + } + + gtk_widget_get_allocation (widget, &allocation); + bounds.x0 = allocation.x + (allocation.width - gdk_pixbuf_get_width (viewer->pixbuf)) / 2; + bounds.y0 = allocation.y + (allocation.height - gdk_pixbuf_get_height (viewer->pixbuf)) / 2; + bounds.x1 = bounds.x0 + gdk_pixbuf_get_width (viewer->pixbuf); + bounds.y1 = bounds.y0 + gdk_pixbuf_get_height (viewer->pixbuf); + + /* Clip the dirty area to the screen; bail if no work to do */ + dirty_area = eel_gdk_rectangle_to_eel_irect (event->area); + clipped_dirty_area = eel_gdk_window_clip_dirty_area_to_screen (event->window, + dirty_area); + if (!eel_irect_is_empty (&clipped_dirty_area)) + { + EelIRect clipped_bounds; + + eel_irect_intersect (&clipped_bounds, &bounds, &clipped_dirty_area); + + if (!eel_irect_is_empty (&clipped_bounds)) + { + g_assert (clipped_bounds.x0 >= bounds.x0); + g_assert (clipped_bounds.y0 >= bounds.y0); + + eel_gdk_pixbuf_draw_to_drawable (viewer->pixbuf, + event->window, + gtk_widget_get_style (widget)->white_gc, + clipped_bounds.x0 - bounds.x0, + clipped_bounds.y0 - bounds.y0, + clipped_bounds, + GDK_RGB_DITHER_NONE, + GDK_PIXBUF_ALPHA_BILEVEL, + EEL_STANDARD_ALPHA_THRESHHOLD); + } + } + + bounds.x0 -= 1; + bounds.y0 -= 1; + bounds.x1 += 1; + bounds.y1 += 1; + + return TRUE; +} + +static void +debug_pixbuf_viewer_set_pixbuf (DebugPixbufViewer *viewer, GdkPixbuf *pixbuf) +{ + g_assert (DEBUG_IS_PIXBUF_VIEWER (viewer)); + + if (pixbuf != viewer->pixbuf) + { + eel_gdk_pixbuf_unref_if_not_null (viewer->pixbuf); + eel_gdk_pixbuf_ref_if_not_null (pixbuf); + viewer->pixbuf = pixbuf; + gtk_widget_queue_resize (GTK_WIDGET (viewer)); + } +} + +/** + * eel_debug_draw_rectangle_and_cross: + * @rectangle: Rectangle bounding the rectangle. + * @color: Color to use for the rectangle and cross. + * + * Draw a rectangle and cross. Useful for debugging exposure events. + */ +void +eel_debug_draw_rectangle_and_cross (GdkDrawable *drawable, + EelIRect rectangle, + guint32 color, + gboolean draw_cross) +{ + GdkGC *gc; + GdkColor color_gdk = { 0 }; + + int width; + int height; + + g_return_if_fail (drawable != NULL); + g_return_if_fail (!eel_irect_is_empty (&rectangle)); + + width = rectangle.x1 - rectangle.x0; + height = rectangle.y1 - rectangle.y0; + + gc = gdk_gc_new (drawable); + gdk_gc_set_function (gc, GDK_COPY); + + color_gdk.red = ((color >> 16) & 0xff) << 8; + color_gdk.green = ((color >> 8) & 0xff) << 8; + color_gdk.blue = ((color ) & 0xff) << 8; + gdk_colormap_alloc_color ( + gdk_drawable_get_colormap (drawable), + &color_gdk, FALSE, FALSE); + gdk_gc_set_rgb_fg_color (gc, &color_gdk); + + gdk_draw_rectangle (drawable, + gc, + FALSE, + rectangle.x0, + rectangle.y0, + width - 1, + height - 1); + + if (draw_cross) + { + gdk_draw_line (drawable, + gc, + rectangle.x0, + rectangle.y0, + rectangle.x0 + width - 1, + rectangle.y0 + height - 1); + + gdk_draw_line (drawable, + gc, + rectangle.x0 + width - 1, + rectangle.y0, + rectangle.x0, + rectangle.y0 + height - 1); + } + + g_object_unref (gc); +} + +/** + * eel_debug_show_pixbuf_in_external_viewer: + * @pixbuf: Pixbuf to show. + * @viewer_name: Viewer name. + * + * Show the given pixbuf in an external out of process viewer. + * This is very useful for debugging pixbuf stuff. + * + * Perhaps this function should be #ifdef DEBUG or something like that. + */ +void +eel_debug_show_pixbuf_in_external_viewer (const GdkPixbuf *pixbuf, + const char *viewer_name) +{ + char *command; + char *file_name; + gboolean save_result; + int ignore; + int fd; + + g_return_if_fail (pixbuf != NULL); + g_return_if_fail (viewer_name != NULL); + + file_name = g_strdup ("/tmp/eel-debug-png-file-XXXXXX"); + + fd = g_mkstemp (file_name); + if (fd == -1) + { + g_free (file_name); + file_name = g_strdup_printf ("/tmp/isis-debug-png-file-%d", getpid ()); + } + else + { + close (fd); + } + + save_result = eel_gdk_pixbuf_save_to_file (pixbuf, file_name); + + if (save_result == FALSE) + { + g_warning ("Failed to save '%s'", file_name); + g_free (file_name); + return; + } + + command = g_strdup_printf ("%s %s", viewer_name, file_name); + + ignore = system (command); + g_free (command); + remove (file_name); + g_free (file_name); +} + +static GtkWidget *debug_window = NULL; +static GtkWidget *debug_image = NULL; + +static void +debug_delete_event (GtkWidget *widget, GdkEvent *event, gpointer callback_data) +{ + gtk_widget_hide (widget); +} + +static void +destroy_debug_window (void) +{ + if (debug_window != NULL) + { + gtk_widget_destroy (debug_window); + debug_window = NULL; + } +} + +/** + * eel_debug_show_pixbuf_in: + * @pixbuf: Pixbuf to show. + * + * Show the given pixbuf in an in process window. + */ +void +eel_debug_show_pixbuf (GdkPixbuf *pixbuf) +{ + if (debug_window == NULL) + { + GtkWidget *vbox; + + debug_window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + vbox = gtk_vbox_new (FALSE, 0); + gtk_container_add (GTK_CONTAINER (debug_window), vbox); + gtk_window_set_title (GTK_WINDOW (debug_window), "Pixbuf debugging"); + gtk_window_set_resizable (GTK_WINDOW (debug_window), TRUE); + gtk_container_set_border_width (GTK_CONTAINER (debug_window), 10); + g_signal_connect (debug_window, "delete_event", G_CALLBACK (debug_delete_event), NULL); + + debug_image = gtk_widget_new (debug_pixbuf_viewer_get_type (), NULL); + + gtk_box_pack_start (GTK_BOX (vbox), debug_image, TRUE, TRUE, 0); + + eel_gtk_widget_set_background_color (debug_window, "white"); + + eel_debug_call_at_shutdown (destroy_debug_window); + + gtk_widget_show (debug_image); + gtk_widget_show (vbox); + } + + gtk_widget_show (debug_window); + debug_pixbuf_viewer_set_pixbuf (DEBUG_PIXBUF_VIEWER (debug_image), pixbuf); + + gdk_window_clear_area_e (gtk_widget_get_window (debug_window), 0, 0, -1, -1); +} + +void +eel_debug_pixbuf_draw_point (GdkPixbuf *pixbuf, + int x, + int y, + guint32 color, + int opacity) +{ + EelDimensions dimensions; + guchar *pixels; + gboolean has_alpha; + guint pixel_offset; + guint rowstride; + guchar red; + guchar green; + guchar blue; + guchar alpha; + guchar *offset; + + g_return_if_fail (eel_gdk_pixbuf_is_valid (pixbuf)); + g_return_if_fail (opacity >= EEL_OPACITY_FULLY_TRANSPARENT); + g_return_if_fail (opacity <= EEL_OPACITY_FULLY_OPAQUE); + + dimensions = eel_gdk_pixbuf_get_dimensions (pixbuf); + + g_return_if_fail (x >= 0 && x < dimensions.width); + g_return_if_fail (y >= 0 && y < dimensions.height); + + pixels = gdk_pixbuf_get_pixels (pixbuf); + rowstride = gdk_pixbuf_get_rowstride (pixbuf); + has_alpha = gdk_pixbuf_get_has_alpha (pixbuf); + pixel_offset = has_alpha ? 4 : 3; + + red = EEL_RGBA_COLOR_GET_R (color); + green = EEL_RGBA_COLOR_GET_G (color); + blue = EEL_RGBA_COLOR_GET_B (color); + alpha = (guchar) opacity; + + offset = pixels + y * rowstride + x * pixel_offset; + + *(offset + 0) = red; + *(offset + 1) = green; + *(offset + 2) = blue; + + if (has_alpha) + { + *(offset + 3) = alpha; + } +} + +void +eel_debug_pixbuf_draw_rectangle (GdkPixbuf *pixbuf, + gboolean filled, + int x0, + int y0, + int x1, + int y1, + guint32 color, + int opacity) +{ + EelDimensions dimensions; + int x; + int y; + + g_return_if_fail (eel_gdk_pixbuf_is_valid (pixbuf)); + g_return_if_fail (opacity >= EEL_OPACITY_FULLY_TRANSPARENT); + g_return_if_fail (opacity <= EEL_OPACITY_FULLY_OPAQUE); + + dimensions = eel_gdk_pixbuf_get_dimensions (pixbuf); + + if (x0 == -1) + { + x0 = 0; + } + + if (y0 == -1) + { + y0 = 0; + } + + if (x1 == -1) + { + x1 = dimensions.width - 1; + } + + if (y1 == -1) + { + y1 = dimensions.height - 1; + } + + g_return_if_fail (x1 > x0); + g_return_if_fail (y1 > y0); + g_return_if_fail (x0 >= 0 && x0 < dimensions.width); + g_return_if_fail (y0 >= 0 && y0 < dimensions.height); + g_return_if_fail (x1 >= 0 && x1 < dimensions.width); + g_return_if_fail (y1 >= 0 && y1 < dimensions.height); + + if (filled) + { + for (y = y0; y <= y1; y++) + { + for (x = x0; x <= x1; x++) + { + eel_debug_pixbuf_draw_point (pixbuf, x, y, color, opacity); + } + } + } + else + { + /* Top / Bottom */ + for (x = x0; x <= x1; x++) + { + eel_debug_pixbuf_draw_point (pixbuf, x, y0, color, opacity); + eel_debug_pixbuf_draw_point (pixbuf, x, y1, color, opacity); + } + + /* Left / Right */ + for (y = y0; y <= y1; y++) + { + eel_debug_pixbuf_draw_point (pixbuf, x0, y, color, opacity); + eel_debug_pixbuf_draw_point (pixbuf, x1, y, color, opacity); + } + } +} + +void +eel_debug_pixbuf_draw_rectangle_inset (GdkPixbuf *pixbuf, + gboolean filled, + int x0, + int y0, + int x1, + int y1, + guint32 color, + int opacity, + int inset) +{ + EelDimensions dimensions; + + g_return_if_fail (eel_gdk_pixbuf_is_valid (pixbuf)); + g_return_if_fail (opacity >= EEL_OPACITY_FULLY_TRANSPARENT); + g_return_if_fail (opacity <= EEL_OPACITY_FULLY_OPAQUE); + + dimensions = eel_gdk_pixbuf_get_dimensions (pixbuf); + + if (x0 == -1) + { + x0 = 0; + } + + if (y0 == -1) + { + y0 = 0; + } + + if (x1 == -1) + { + x1 = dimensions.width - 1; + } + + if (y1 == -1) + { + y1 = dimensions.height - 1; + } + + x0 += inset; + y0 += inset; + x1 -= inset; + y1 -= inset; + + g_return_if_fail (x1 > x0); + g_return_if_fail (y1 > y0); + + eel_debug_pixbuf_draw_rectangle (pixbuf, filled, x0, y0, x1, y1, color, opacity); +} diff --git a/eel/eel-debug-drawing.h b/eel/eel-debug-drawing.h new file mode 100644 index 00000000..ce655c23 --- /dev/null +++ b/eel/eel-debug-drawing.h @@ -0,0 +1,72 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- + + eel-debug-drawing.h: Eel drawing debugging aids. + + Copyright (C) 2000 Eazel, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this program; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Ramiro Estrugo +*/ + +#ifndef EEL_DEBUG_DRAWING_H +#define EEL_DEBUG_DRAWING_H + +#include + +/* Draw a rectangle and cross on the given window */ +void eel_debug_draw_rectangle_and_cross (GdkDrawable *drawable, + EelIRect rectangle, + guint32 color, + gboolean draw_cross); + +/* Show the given pixbuf in an external out of process viewer */ +void eel_debug_show_pixbuf_in_external_viewer (const GdkPixbuf *pixbuf, + const char *viewer_name); + +/* Show the given pixbuf in an in process window */ +void eel_debug_show_pixbuf (GdkPixbuf *pixbuf); + +/* Draw a point in a pixbuf */ +void eel_debug_pixbuf_draw_point (GdkPixbuf *pixbuf, + int x, + int y, + guint32 color, + int opacity); +/* Draw a rectangle in a pixbuf. The coordinates (-1,-1( (-1,-1) will use + * the whole pixbuf. */ +void eel_debug_pixbuf_draw_rectangle (GdkPixbuf *pixbuf, + gboolean filled, + int x0, + int y0, + int x1, + int y1, + guint32 color, + int opacity); +/* Draw an inset rectangle in a pixbuf. Positive inset make the rectangle + * smaller. Negative inset makes it larger. + */ +void eel_debug_pixbuf_draw_rectangle_inset (GdkPixbuf *pixbuf, + gboolean filled, + int x0, + int y0, + int x1, + int y1, + guint32 color, + int opacity, + int inset); + +#endif /* EEL_DEBUG_DRAWING_H */ diff --git a/eel/eel-debug.c b/eel/eel-debug.c new file mode 100644 index 00000000..e651baed --- /dev/null +++ b/eel/eel-debug.c @@ -0,0 +1,135 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- + + eel-debug.c: Eel debugging aids. + + Copyright (C) 2000, 2001 Eazel, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this program; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Darin Adler +*/ + +#include +#include "eel-debug.h" + +#include +#include +#include + +typedef struct +{ + gpointer data; + GFreeFunc function; +} ShutdownFunction; + +static GList *shutdown_functions; + +/* Raise a SIGINT signal to get the attention of the debugger. + * When not running under the debugger, we don't want to stop, + * so we ignore the signal for just the moment that we raise it. + */ +void +eel_stop_in_debugger (void) +{ + void (* saved_handler) (int); + + saved_handler = signal (SIGINT, SIG_IGN); + raise (SIGINT); + signal (SIGINT, saved_handler); +} + +/* Stop in the debugger after running the default log handler. + * This makes certain kinds of messages stop in the debugger + * without making them fatal (you can continue). + */ +static void +log_handler (const char *domain, + GLogLevelFlags level, + const char *message, + gpointer data) +{ + g_log_default_handler (domain, level, message, data); + if ((level & (G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING)) != 0) + { + eel_stop_in_debugger (); + } +} + +void +eel_make_warnings_and_criticals_stop_in_debugger (void) +{ + g_log_set_default_handler (log_handler, NULL); +} + +int +eel_get_available_file_descriptor_count (void) +{ + int count; + GList *list; + GList *p; + FILE *file; + + list = NULL; + for (count = 0; ; count++) + { + file = fopen ("/dev/null", "r"); + if (file == NULL) + { + break; + } + list = g_list_prepend (list, file); + } + + for (p = list; p != NULL; p = p->next) + { + fclose (p->data); + } + g_list_free (list); + + return count; +} + +void +eel_debug_shut_down (void) +{ + ShutdownFunction *f; + + while (shutdown_functions != NULL) + { + f = shutdown_functions->data; + shutdown_functions = g_list_remove (shutdown_functions, f); + + f->function (f->data); + g_free (f); + } +} + +void +eel_debug_call_at_shutdown (EelFunction function) +{ + eel_debug_call_at_shutdown_with_data ((GFreeFunc) function, NULL); +} + +void +eel_debug_call_at_shutdown_with_data (GFreeFunc function, gpointer data) +{ + ShutdownFunction *f; + + f = g_new (ShutdownFunction, 1); + f->data = data; + f->function = function; + shutdown_functions = g_list_prepend (shutdown_functions, f); +} diff --git a/eel/eel-debug.h b/eel/eel-debug.h new file mode 100644 index 00000000..be7f0ab7 --- /dev/null +++ b/eel/eel-debug.h @@ -0,0 +1,52 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- + + eel-debug.h: Eel debugging aids. + + Copyright (C) 2000, 2001 Eazel, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this program; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Darin Adler +*/ + +#ifndef EEL_DEBUG_H +#define EEL_DEBUG_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + typedef void (* EelFunction) (void); + + void eel_stop_in_debugger (void); + void eel_make_warnings_and_criticals_stop_in_debugger (void); + int eel_get_available_file_descriptor_count (void); + + /* A way to do cleanup at exit for compatibility with shutdown tools + * like the ones in MateComponent. + */ + void eel_debug_shut_down (void); + void eel_debug_call_at_shutdown (EelFunction function); + void eel_debug_call_at_shutdown_with_data (GFreeFunc function, + gpointer data); + +#ifdef __cplusplus +} +#endif + +#endif /* EEL_DEBUG_H */ diff --git a/eel/eel-editable-label.c b/eel/eel-editable-label.c new file mode 100644 index 00000000..b41f197d --- /dev/null +++ b/eel/eel-editable-label.c @@ -0,0 +1,4402 @@ +/* GTK - The GIMP Toolkit + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GTK+ Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GTK+ at ftp://ftp.gtk.org/pub/gtk/. + */ + +#include +#include +#include + +#include "eel-editable-label.h" +#include "eel-i18n.h" +#include "eel-marshal.h" +#include "eel-accessibility.h" +#include + +#include +#include +#include + +enum +{ + MOVE_CURSOR, + POPULATE_POPUP, + DELETE_FROM_CURSOR, + CUT_CLIPBOARD, + COPY_CLIPBOARD, + PASTE_CLIPBOARD, + TOGGLE_OVERWRITE, + LAST_SIGNAL +}; + +enum +{ + PROP_0, + PROP_TEXT, + PROP_JUSTIFY, + PROP_WRAP, + PROP_CURSOR_POSITION, + PROP_SELECTION_BOUND +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +static void eel_editable_label_editable_init (GtkEditableClass *iface); +static void eel_editable_label_class_init (EelEditableLabelClass *klass); +static void eel_editable_label_init (EelEditableLabel *label); +static void eel_editable_label_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static void eel_editable_label_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); +static void eel_editable_label_finalize (GObject *object); +static void eel_editable_label_size_request (GtkWidget *widget, + GtkRequisition *requisition); +static void eel_editable_label_size_allocate (GtkWidget *widget, + GtkAllocation *allocation); +static void eel_editable_label_state_changed (GtkWidget *widget, + GtkStateType state); +static void eel_editable_label_style_set (GtkWidget *widget, + GtkStyle *previous_style); +static void eel_editable_label_direction_changed (GtkWidget *widget, + GtkTextDirection previous_dir); +static gint eel_editable_label_expose (GtkWidget *widget, + GdkEventExpose *event); +static void eel_editable_label_realize (GtkWidget *widget); +static void eel_editable_label_unrealize (GtkWidget *widget); +static void eel_editable_label_map (GtkWidget *widget); +static void eel_editable_label_unmap (GtkWidget *widget); +static gint eel_editable_label_button_press (GtkWidget *widget, + GdkEventButton *event); +static gint eel_editable_label_button_release (GtkWidget *widget, + GdkEventButton *event); +static gint eel_editable_label_motion (GtkWidget *widget, + GdkEventMotion *event); +static gint eel_editable_label_key_press (GtkWidget *widget, + GdkEventKey *event); +static gint eel_editable_label_key_release (GtkWidget *widget, + GdkEventKey *event); +static gint eel_editable_label_focus_in (GtkWidget *widget, + GdkEventFocus *event); +static gint eel_editable_label_focus_out (GtkWidget *widget, + GdkEventFocus *event); +static AtkObject *eel_editable_label_get_accessible (GtkWidget *widget); +static void eel_editable_label_commit_cb (GtkIMContext *context, + const gchar *str, + EelEditableLabel *label); +static void eel_editable_label_preedit_changed_cb (GtkIMContext *context, + EelEditableLabel *label); +static gboolean eel_editable_label_retrieve_surrounding_cb (GtkIMContext *context, + EelEditableLabel *label); +static gboolean eel_editable_label_delete_surrounding_cb (GtkIMContext *slave, + gint offset, + gint n_chars, + EelEditableLabel *label); +static void eel_editable_label_clear_layout (EelEditableLabel *label); +static void eel_editable_label_recompute (EelEditableLabel *label); +static void eel_editable_label_ensure_layout (EelEditableLabel *label, + gboolean include_preedit); +static void eel_editable_label_select_region_index (EelEditableLabel *label, + gint anchor_index, + gint end_index); +static gboolean eel_editable_label_focus (GtkWidget *widget, + GtkDirectionType direction); +static void eel_editable_label_move_cursor (EelEditableLabel *label, + GtkMovementStep step, + gint count, + gboolean extend_selection); +static void eel_editable_label_delete_from_cursor (EelEditableLabel *label, + GtkDeleteType type, + gint count); +static void eel_editable_label_copy_clipboard (EelEditableLabel *label); +static void eel_editable_label_cut_clipboard (EelEditableLabel *label); +static void eel_editable_label_paste (EelEditableLabel *label, + GdkAtom selection); +static void eel_editable_label_paste_clipboard (EelEditableLabel *label); +static void eel_editable_label_select_all (EelEditableLabel *label); +static void eel_editable_label_do_popup (EelEditableLabel *label, + GdkEventButton *event); +static void eel_editable_label_toggle_overwrite (EelEditableLabel *label); +static gint eel_editable_label_move_forward_word (EelEditableLabel *label, + gint start); +static gint eel_editable_label_move_backward_word (EelEditableLabel *label, + gint start); +static void eel_editable_label_reset_im_context (EelEditableLabel *label); +static void eel_editable_label_check_cursor_blink (EelEditableLabel *label); +static void eel_editable_label_pend_cursor_blink (EelEditableLabel *label); + +/* Editable implementation: */ +static void editable_insert_text_emit (GtkEditable *editable, + const gchar *new_text, + gint new_text_length, + gint *position); +static void editable_delete_text_emit (GtkEditable *editable, + gint start_pos, + gint end_pos); +static void editable_insert_text (GtkEditable *editable, + const gchar *new_text, + gint new_text_length, + gint *position); +static void editable_delete_text (GtkEditable *editable, + gint start_pos, + gint end_pos); +static gchar * editable_get_chars (GtkEditable *editable, + gint start_pos, + gint end_pos); +static void editable_set_selection_bounds (GtkEditable *editable, + gint start, + gint end); +static gboolean editable_get_selection_bounds (GtkEditable *editable, + gint *start, + gint *end); +static void editable_real_set_position (GtkEditable *editable, + gint position); +static gint editable_get_position (GtkEditable *editable); + +static GdkGC * make_cursor_gc (GtkWidget *widget, + const gchar *property_name, + GdkColor *fallback); + +G_DEFINE_TYPE_WITH_CODE (EelEditableLabel, eel_editable_label, GTK_TYPE_MISC, + G_IMPLEMENT_INTERFACE (GTK_TYPE_EDITABLE, eel_editable_label_editable_init)); + +static void +add_move_binding (GtkBindingSet *binding_set, + guint keyval, + guint modmask, + GtkMovementStep step, + gint count) +{ + g_assert ((modmask & GDK_SHIFT_MASK) == 0); + + gtk_binding_entry_add_signal (binding_set, keyval, modmask, + "move_cursor", 3, + G_TYPE_ENUM, step, + G_TYPE_INT, count, + G_TYPE_BOOLEAN, FALSE); + + /* Selection-extending version */ + gtk_binding_entry_add_signal (binding_set, keyval, modmask | GDK_SHIFT_MASK, + "move_cursor", 3, + G_TYPE_ENUM, step, + G_TYPE_INT, count, + G_TYPE_BOOLEAN, TRUE); +} + +static void +eel_editable_label_class_init (EelEditableLabelClass *class) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (class); + GtkObjectClass *object_class = GTK_OBJECT_CLASS (class); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class); + GtkBindingSet *binding_set; + + gobject_class->set_property = eel_editable_label_set_property; + gobject_class->get_property = eel_editable_label_get_property; + gobject_class->finalize = eel_editable_label_finalize; + + widget_class->size_request = eel_editable_label_size_request; + widget_class->size_allocate = eel_editable_label_size_allocate; + widget_class->state_changed = eel_editable_label_state_changed; + widget_class->style_set = eel_editable_label_style_set; + widget_class->direction_changed = eel_editable_label_direction_changed; + widget_class->expose_event = eel_editable_label_expose; + widget_class->realize = eel_editable_label_realize; + widget_class->unrealize = eel_editable_label_unrealize; + widget_class->map = eel_editable_label_map; + widget_class->unmap = eel_editable_label_unmap; + widget_class->button_press_event = eel_editable_label_button_press; + widget_class->button_release_event = eel_editable_label_button_release; + widget_class->motion_notify_event = eel_editable_label_motion; + widget_class->focus = eel_editable_label_focus; + widget_class->key_press_event = eel_editable_label_key_press; + widget_class->key_release_event = eel_editable_label_key_release; + widget_class->focus_in_event = eel_editable_label_focus_in; + widget_class->focus_out_event = eel_editable_label_focus_out; + widget_class->get_accessible = eel_editable_label_get_accessible; + + class->move_cursor = eel_editable_label_move_cursor; + class->delete_from_cursor = eel_editable_label_delete_from_cursor; + class->copy_clipboard = eel_editable_label_copy_clipboard; + class->cut_clipboard = eel_editable_label_cut_clipboard; + class->paste_clipboard = eel_editable_label_paste_clipboard; + class->toggle_overwrite = eel_editable_label_toggle_overwrite; + + signals[MOVE_CURSOR] = + g_signal_new ("move_cursor", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (EelEditableLabelClass, move_cursor), + NULL, NULL, + eel_marshal_VOID__ENUM_INT_BOOLEAN, + G_TYPE_NONE, 3, GTK_TYPE_MOVEMENT_STEP, G_TYPE_INT, G_TYPE_BOOLEAN); + + signals[COPY_CLIPBOARD] = + g_signal_new ("copy_clipboard", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (EelEditableLabelClass, copy_clipboard), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + signals[POPULATE_POPUP] = + g_signal_new ("populate_popup", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (EelEditableLabelClass, populate_popup), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, GTK_TYPE_MENU); + + signals[DELETE_FROM_CURSOR] = + g_signal_new ("delete_from_cursor", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (EelEditableLabelClass, delete_from_cursor), + NULL, NULL, + eel_marshal_VOID__ENUM_INT, + G_TYPE_NONE, 2, GTK_TYPE_DELETE_TYPE, G_TYPE_INT); + + signals[CUT_CLIPBOARD] = + g_signal_new ("cut_clipboard", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (EelEditableLabelClass, cut_clipboard), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + signals[PASTE_CLIPBOARD] = + g_signal_new ("paste_clipboard", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (EelEditableLabelClass, paste_clipboard), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + signals[TOGGLE_OVERWRITE] = + g_signal_new ("toggle_overwrite", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (EelEditableLabelClass, toggle_overwrite), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + + g_object_class_install_property (G_OBJECT_CLASS(object_class), + PROP_TEXT, + g_param_spec_string ("text", + _("Text"), + _("The text of the label."), + NULL, + G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, + PROP_JUSTIFY, + g_param_spec_enum ("justify", + _("Justification"), + _("The alignment of the lines in the text of the label relative to each other. This does NOT affect the alignment of the label within its allocation. See GtkMisc::xalign for that."), + GTK_TYPE_JUSTIFICATION, + GTK_JUSTIFY_LEFT, + G_PARAM_READWRITE)); + + g_object_class_install_property (gobject_class, + PROP_WRAP, + g_param_spec_boolean ("wrap", + _("Line wrap"), + _("If set, wrap lines if the text becomes too wide."), + FALSE, + G_PARAM_READWRITE)); + + g_object_class_install_property (gobject_class, + PROP_CURSOR_POSITION, + g_param_spec_int ("cursor_position", + _("Cursor Position"), + _("The current position of the insertion cursor in chars."), + 0, + G_MAXINT, + 0, + G_PARAM_READABLE)); + + g_object_class_install_property (gobject_class, + PROP_SELECTION_BOUND, + g_param_spec_int ("selection_bound", + _("Selection Bound"), + _("The position of the opposite end of the selection from the cursor in chars."), + 0, + G_MAXINT, + 0, + G_PARAM_READABLE)); + + /* + * Key bindings + */ + + binding_set = gtk_binding_set_by_class (class); + + /* Moving the insertion point */ + add_move_binding (binding_set, GDK_Right, 0, + GTK_MOVEMENT_VISUAL_POSITIONS, 1); + + add_move_binding (binding_set, GDK_Left, 0, + GTK_MOVEMENT_VISUAL_POSITIONS, -1); + + add_move_binding (binding_set, GDK_KP_Right, 0, + GTK_MOVEMENT_VISUAL_POSITIONS, 1); + + add_move_binding (binding_set, GDK_KP_Left, 0, + GTK_MOVEMENT_VISUAL_POSITIONS, -1); + + add_move_binding (binding_set, GDK_f, GDK_CONTROL_MASK, + GTK_MOVEMENT_LOGICAL_POSITIONS, 1); + + add_move_binding (binding_set, GDK_b, GDK_CONTROL_MASK, + GTK_MOVEMENT_LOGICAL_POSITIONS, -1); + + add_move_binding (binding_set, GDK_Right, GDK_CONTROL_MASK, + GTK_MOVEMENT_WORDS, 1); + + add_move_binding (binding_set, GDK_Left, GDK_CONTROL_MASK, + GTK_MOVEMENT_WORDS, -1); + + add_move_binding (binding_set, GDK_KP_Right, GDK_CONTROL_MASK, + GTK_MOVEMENT_WORDS, 1); + + add_move_binding (binding_set, GDK_KP_Left, GDK_CONTROL_MASK, + GTK_MOVEMENT_WORDS, -1); + + add_move_binding (binding_set, GDK_a, GDK_CONTROL_MASK, + GTK_MOVEMENT_PARAGRAPH_ENDS, -1); + + add_move_binding (binding_set, GDK_e, GDK_CONTROL_MASK, + GTK_MOVEMENT_PARAGRAPH_ENDS, 1); + + add_move_binding (binding_set, GDK_f, GDK_MOD1_MASK, + GTK_MOVEMENT_WORDS, 1); + + add_move_binding (binding_set, GDK_b, GDK_MOD1_MASK, + GTK_MOVEMENT_WORDS, -1); + + add_move_binding (binding_set, GDK_Home, 0, + GTK_MOVEMENT_DISPLAY_LINE_ENDS, -1); + + add_move_binding (binding_set, GDK_End, 0, + GTK_MOVEMENT_DISPLAY_LINE_ENDS, 1); + + add_move_binding (binding_set, GDK_KP_Home, 0, + GTK_MOVEMENT_DISPLAY_LINE_ENDS, -1); + + add_move_binding (binding_set, GDK_KP_End, 0, + GTK_MOVEMENT_DISPLAY_LINE_ENDS, 1); + + add_move_binding (binding_set, GDK_Home, GDK_CONTROL_MASK, + GTK_MOVEMENT_BUFFER_ENDS, -1); + + add_move_binding (binding_set, GDK_End, GDK_CONTROL_MASK, + GTK_MOVEMENT_BUFFER_ENDS, 1); + + add_move_binding (binding_set, GDK_KP_Home, GDK_CONTROL_MASK, + GTK_MOVEMENT_BUFFER_ENDS, -1); + + add_move_binding (binding_set, GDK_KP_End, GDK_CONTROL_MASK, + GTK_MOVEMENT_BUFFER_ENDS, 1); + + add_move_binding (binding_set, GDK_Up, 0, + GTK_MOVEMENT_DISPLAY_LINES, -1); + + add_move_binding (binding_set, GDK_KP_Up, 0, + GTK_MOVEMENT_DISPLAY_LINES, -1); + + add_move_binding (binding_set, GDK_Down, 0, + GTK_MOVEMENT_DISPLAY_LINES, 1); + + add_move_binding (binding_set, GDK_KP_Down, 0, + GTK_MOVEMENT_DISPLAY_LINES, 1); + + /* Select all + */ + gtk_binding_entry_add_signal (binding_set, GDK_a, GDK_CONTROL_MASK, + "move_cursor", 3, + GTK_TYPE_MOVEMENT_STEP, GTK_MOVEMENT_BUFFER_ENDS, + G_TYPE_INT, -1, + G_TYPE_BOOLEAN, FALSE); + gtk_binding_entry_add_signal (binding_set, GDK_a, GDK_CONTROL_MASK, + "move_cursor", 3, + GTK_TYPE_MOVEMENT_STEP, GTK_MOVEMENT_BUFFER_ENDS, + G_TYPE_INT, 1, + G_TYPE_BOOLEAN, TRUE); + + /* Deleting text */ + gtk_binding_entry_add_signal (binding_set, GDK_Delete, 0, + "delete_from_cursor", 2, + G_TYPE_ENUM, GTK_DELETE_CHARS, + G_TYPE_INT, 1); + + gtk_binding_entry_add_signal (binding_set, GDK_KP_Delete, 0, + "delete_from_cursor", 2, + G_TYPE_ENUM, GTK_DELETE_CHARS, + G_TYPE_INT, 1); + + gtk_binding_entry_add_signal (binding_set, GDK_BackSpace, 0, + "delete_from_cursor", 2, + G_TYPE_ENUM, GTK_DELETE_CHARS, + G_TYPE_INT, -1); + + /* Make this do the same as Backspace, to help with mis-typing */ + gtk_binding_entry_add_signal (binding_set, GDK_BackSpace, GDK_SHIFT_MASK, + "delete_from_cursor", 2, + G_TYPE_ENUM, GTK_DELETE_CHARS, + G_TYPE_INT, -1); + + gtk_binding_entry_add_signal (binding_set, GDK_Delete, GDK_CONTROL_MASK, + "delete_from_cursor", 2, + G_TYPE_ENUM, GTK_DELETE_WORD_ENDS, + G_TYPE_INT, 1); + + gtk_binding_entry_add_signal (binding_set, GDK_KP_Delete, GDK_CONTROL_MASK, + "delete_from_cursor", 2, + G_TYPE_ENUM, GTK_DELETE_WORD_ENDS, + G_TYPE_INT, 1); + + gtk_binding_entry_add_signal (binding_set, GDK_BackSpace, GDK_CONTROL_MASK, + "delete_from_cursor", 2, + G_TYPE_ENUM, GTK_DELETE_WORD_ENDS, + G_TYPE_INT, -1); + + /* Cut/copy/paste */ + + gtk_binding_entry_add_signal (binding_set, GDK_x, GDK_CONTROL_MASK, + "cut_clipboard", 0); + gtk_binding_entry_add_signal (binding_set, GDK_c, GDK_CONTROL_MASK, + "copy_clipboard", 0); + gtk_binding_entry_add_signal (binding_set, GDK_v, GDK_CONTROL_MASK, + "paste_clipboard", 0); + + gtk_binding_entry_add_signal (binding_set, GDK_Delete, GDK_SHIFT_MASK, + "cut_clipboard", 0); + gtk_binding_entry_add_signal (binding_set, GDK_Insert, GDK_CONTROL_MASK, + "copy_clipboard", 0); + gtk_binding_entry_add_signal (binding_set, GDK_Insert, GDK_SHIFT_MASK, + "paste_clipboard", 0); + + /* Overwrite */ + gtk_binding_entry_add_signal (binding_set, GDK_Insert, 0, + "toggle_overwrite", 0); + gtk_binding_entry_add_signal (binding_set, GDK_KP_Insert, 0, + "toggle_overwrite", 0); +} + +static void +eel_editable_label_editable_init (GtkEditableClass *iface) +{ + iface->do_insert_text = editable_insert_text_emit; + iface->do_delete_text = editable_delete_text_emit; + iface->insert_text = editable_insert_text; + iface->delete_text = editable_delete_text; + iface->get_chars = editable_get_chars; + iface->set_selection_bounds = editable_set_selection_bounds; + iface->get_selection_bounds = editable_get_selection_bounds; + iface->set_position = editable_real_set_position; + iface->get_position = editable_get_position; +} + + +static void +eel_editable_label_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + EelEditableLabel *label; + + label = EEL_EDITABLE_LABEL (object); + + switch (prop_id) + { + case PROP_TEXT: + eel_editable_label_set_text (label, g_value_get_string (value)); + break; + case PROP_JUSTIFY: + eel_editable_label_set_justify (label, g_value_get_enum (value)); + break; + case PROP_WRAP: + eel_editable_label_set_line_wrap (label, g_value_get_boolean (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +eel_editable_label_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + EelEditableLabel *label; + gint offset; + + label = EEL_EDITABLE_LABEL (object); + + switch (prop_id) + { + case PROP_TEXT: + g_value_set_string (value, label->text); + break; + case PROP_JUSTIFY: + g_value_set_enum (value, label->jtype); + break; + case PROP_WRAP: + g_value_set_boolean (value, label->wrap); + break; + case PROP_CURSOR_POSITION: + offset = g_utf8_pointer_to_offset (label->text, + label->text + label->selection_end); + g_value_set_int (value, offset); + break; + case PROP_SELECTION_BOUND: + offset = g_utf8_pointer_to_offset (label->text, + label->text + label->selection_anchor); + g_value_set_int (value, offset); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +eel_editable_label_init (EelEditableLabel *label) +{ + label->jtype = GTK_JUSTIFY_LEFT; + label->wrap = FALSE; + label->wrap_mode = PANGO_WRAP_WORD; + + label->layout = NULL; + label->text_size = 1; + label->text = g_malloc (label->text_size); + label->text[0] = '\0'; + label->n_bytes = 0; + + gtk_widget_set_can_focus (GTK_WIDGET (label), TRUE); + + /* This object is completely private. No external entity can gain a reference + * to it; so we create it here and destroy it in finalize(). + */ + label->im_context = gtk_im_multicontext_new (); + + g_signal_connect (G_OBJECT (label->im_context), "commit", + G_CALLBACK (eel_editable_label_commit_cb), label); + g_signal_connect (G_OBJECT (label->im_context), "preedit_changed", + G_CALLBACK (eel_editable_label_preedit_changed_cb), label); + g_signal_connect (G_OBJECT (label->im_context), "retrieve_surrounding", + G_CALLBACK (eel_editable_label_retrieve_surrounding_cb), label); + g_signal_connect (G_OBJECT (label->im_context), "delete_surrounding", + G_CALLBACK (eel_editable_label_delete_surrounding_cb), label); +} + +/** + * eel_editable_label_new: + * @str: The text of the label + * + * Creates a new label with the given text inside it. You can + * pass %NULL to get an empty label widget. + * + * Return value: the new #EelEditableLabel + **/ +GtkWidget* +eel_editable_label_new (const gchar *str) +{ + EelEditableLabel *label; + + label = g_object_new (EEL_TYPE_EDITABLE_LABEL, NULL); + + if (str && *str) + eel_editable_label_set_text (label, str); + + return GTK_WIDGET (label); +} + +/** + * eel_editable_label_set_text: + * @label: a #EelEditableLabel + * @str: The text you want to set. + * + * Sets the text within the #EelEditableLabel widget. It overwrites any text that + * was there before. + * + * This will also clear any previously set mnemonic accelerators. + **/ +void +eel_editable_label_set_text (EelEditableLabel *label, + const gchar *str) +{ + GtkEditable *editable; + int tmp_pos; + + g_return_if_fail (EEL_IS_EDITABLE_LABEL (label)); + g_return_if_fail (str != NULL); + + if (strcmp (label->text, str) == 0) + return; + + editable = GTK_EDITABLE (label); + gtk_editable_delete_text (editable, 0, -1); + tmp_pos = 0; + gtk_editable_insert_text (editable, str, strlen (str), &tmp_pos); +} + +/** + * eel_editable_label_get_text: + * @label: a #EelEditableLabel + * + * Fetches the text from a label widget, as displayed on the + * screen. This does not include any embedded underlines + * indicating mnemonics or Pango markup. (See eel_editable_label_get_label()) + * + * Return value: the text in the label widget. This is the internal + * string used by the label, and must not be modified. + **/ +const gchar* eel_editable_label_get_text(EelEditableLabel* label) +{ + g_return_val_if_fail(EEL_IS_EDITABLE_LABEL(label), NULL); + + return label->text; +} + +/** + * eel_editable_label_set_justify: + * @label: a #EelEditableLabel + * @jtype: a #GtkJustification + * + * Sets the alignment of the lines in the text of the label relative to + * each other. %GTK_JUSTIFY_LEFT is the default value when the + * widget is first created with eel_editable_label_new(). If you instead want + * to set the alignment of the label as a whole, use + * gtk_misc_set_alignment() instead. eel_editable_label_set_justify() has no + * effect on labels containing only a single line. + **/ +void +eel_editable_label_set_justify (EelEditableLabel *label, + GtkJustification jtype) +{ + g_return_if_fail (EEL_IS_EDITABLE_LABEL (label)); + g_return_if_fail (jtype >= GTK_JUSTIFY_LEFT && jtype <= GTK_JUSTIFY_FILL); + + if ((GtkJustification) label->jtype != jtype) + { + label->jtype = jtype; + + /* No real need to be this drastic, but easier than duplicating the code */ + eel_editable_label_recompute (label); + + g_object_notify (G_OBJECT (label), "justify"); + gtk_widget_queue_resize (GTK_WIDGET (label)); + } +} + +/** + * eel_editable_label_get_justify: + * @label: a #EelEditableLabel + * + * Returns the justification of the label. See eel_editable_label_set_justify (). + * + * Return value: #GtkJustification + **/ +GtkJustification +eel_editable_label_get_justify (EelEditableLabel *label) +{ + g_return_val_if_fail (EEL_IS_EDITABLE_LABEL (label), 0); + + return label->jtype; +} + +void +eel_editable_label_set_draw_outline (EelEditableLabel *label, + gboolean draw_outline) +{ + draw_outline = draw_outline != FALSE; + + if (label->draw_outline != draw_outline) + { + label->draw_outline = draw_outline; + + gtk_widget_queue_draw (GTK_WIDGET (label)); + } + +} + + +/** + * eel_editable_label_set_line_wrap: + * @label: a #EelEditableLabel + * @wrap: the setting + * + * Toggles line wrapping within the #EelEditableLabel widget. %TRUE makes it break + * lines if text exceeds the widget's size. %FALSE lets the text get cut off + * by the edge of the widget if it exceeds the widget size. + **/ +void +eel_editable_label_set_line_wrap (EelEditableLabel *label, + gboolean wrap) +{ + g_return_if_fail (EEL_IS_EDITABLE_LABEL (label)); + + wrap = wrap != FALSE; + + if (label->wrap != wrap) + { + label->wrap = wrap; + g_object_notify (G_OBJECT (label), "wrap"); + + gtk_widget_queue_resize (GTK_WIDGET (label)); + } +} + + +void +eel_editable_label_set_line_wrap_mode (EelEditableLabel *label, + PangoWrapMode mode) +{ + g_return_if_fail (EEL_IS_EDITABLE_LABEL (label)); + + if (label->wrap_mode != mode) + { + label->wrap_mode = mode; + + gtk_widget_queue_resize (GTK_WIDGET (label)); + } + +} + + +/** + * eel_editable_label_get_line_wrap: + * @label: a #EelEditableLabel + * + * Returns whether lines in the label are automatically wrapped. See eel_editable_label_set_line_wrap (). + * + * Return value: %TRUE if the lines of the label are automatically wrapped. + */ +gboolean +eel_editable_label_get_line_wrap (EelEditableLabel *label) +{ + g_return_val_if_fail (EEL_IS_EDITABLE_LABEL (label), FALSE); + + return label->wrap; +} + +PangoFontDescription * +eel_editable_label_get_font_description (EelEditableLabel *label) +{ + if (label->font_desc) + return pango_font_description_copy (label->font_desc); + + return NULL; +} + +void +eel_editable_label_set_font_description (EelEditableLabel *label, + const PangoFontDescription *desc) +{ + if (label->font_desc) + pango_font_description_free (label->font_desc); + + if (desc) + label->font_desc = pango_font_description_copy (desc); + else + label->font_desc = NULL; + + eel_editable_label_clear_layout (label); +} + +static void +eel_editable_label_finalize (GObject *object) +{ + EelEditableLabel *label; + + g_assert (EEL_IS_EDITABLE_LABEL (object)); + + label = EEL_EDITABLE_LABEL (object); + + if (label->font_desc) + { + pango_font_description_free (label->font_desc); + label->font_desc = NULL; + } + + g_object_unref (G_OBJECT (label->im_context)); + label->im_context = NULL; + + g_free (label->text); + label->text = NULL; + + if (label->layout) + { + g_object_unref (G_OBJECT (label->layout)); + label->layout = NULL; + } + + G_OBJECT_CLASS (eel_editable_label_parent_class)->finalize (object); +} + +static void +eel_editable_label_clear_layout (EelEditableLabel *label) +{ + if (label->layout) + { + g_object_unref (G_OBJECT (label->layout)); + label->layout = NULL; + } +} + +static void +eel_editable_label_recompute (EelEditableLabel *label) +{ + eel_editable_label_clear_layout (label); + eel_editable_label_check_cursor_blink (label); +} + +typedef struct _LabelWrapWidth LabelWrapWidth; +struct _LabelWrapWidth +{ + gint width; + PangoFontDescription *font_desc; +}; + +static void +label_wrap_width_free (gpointer data) +{ + LabelWrapWidth *wrap_width = data; + pango_font_description_free (wrap_width->font_desc); + g_free (wrap_width); +} + +static gint +get_label_wrap_width (EelEditableLabel *label) +{ + PangoLayout *layout; + GtkStyle *style = gtk_widget_get_style (GTK_WIDGET (label)); + + LabelWrapWidth *wrap_width = g_object_get_data (G_OBJECT (style), "gtk-label-wrap-width"); + if (!wrap_width) + { + wrap_width = g_new0 (LabelWrapWidth, 1); + g_object_set_data_full (G_OBJECT (style), "gtk-label-wrap-width", + wrap_width, label_wrap_width_free); + } + + if (wrap_width->font_desc && pango_font_description_equal (wrap_width->font_desc, style->font_desc)) + return wrap_width->width; + + if (wrap_width->font_desc) + pango_font_description_free (wrap_width->font_desc); + + wrap_width->font_desc = pango_font_description_copy (style->font_desc); + + layout = gtk_widget_create_pango_layout (GTK_WIDGET (label), + "This long string gives a good enough length for any line to have."); + pango_layout_get_size (layout, &wrap_width->width, NULL); + g_object_unref (layout); + + return wrap_width->width; +} + +static void +eel_editable_label_ensure_layout (EelEditableLabel *label, + gboolean include_preedit) +{ + GtkWidget *widget; + PangoRectangle logical_rect; + + /* Normalize for comparisons */ + include_preedit = include_preedit != 0; + + if (label->preedit_length > 0 && + include_preedit != label->layout_includes_preedit) + eel_editable_label_clear_layout (label); + + widget = GTK_WIDGET (label); + + if (label->layout == NULL) + { + gchar *preedit_string = NULL; + gint preedit_length = 0; + PangoAttrList *preedit_attrs = NULL; + PangoAlignment align = PANGO_ALIGN_LEFT; /* Quiet gcc */ + PangoAttrList *tmp_attrs = pango_attr_list_new (); + + if (include_preedit) + { + gtk_im_context_get_preedit_string (label->im_context, + &preedit_string, &preedit_attrs, NULL); + preedit_length = label->preedit_length; + } + + if (preedit_length) + { + GString *tmp_string = g_string_new (NULL); + + g_string_prepend_len (tmp_string, label->text, label->n_bytes); + g_string_insert (tmp_string, label->selection_anchor, preedit_string); + + label->layout = gtk_widget_create_pango_layout (widget, tmp_string->str); + + pango_attr_list_splice (tmp_attrs, preedit_attrs, + label->selection_anchor, preedit_length); + + g_string_free (tmp_string, TRUE); + } + else + { + label->layout = gtk_widget_create_pango_layout (widget, label->text); + } + label->layout_includes_preedit = include_preedit; + + if (label->font_desc != NULL) + pango_layout_set_font_description (label->layout, label->font_desc); + + pango_layout_set_attributes (label->layout, tmp_attrs); + + if (preedit_string) + g_free (preedit_string); + if (preedit_attrs) + pango_attr_list_unref (preedit_attrs); + pango_attr_list_unref (tmp_attrs); + + switch (label->jtype) + { + case GTK_JUSTIFY_LEFT: + align = PANGO_ALIGN_LEFT; + break; + case GTK_JUSTIFY_RIGHT: + align = PANGO_ALIGN_RIGHT; + break; + case GTK_JUSTIFY_CENTER: + align = PANGO_ALIGN_CENTER; + break; + case GTK_JUSTIFY_FILL: + /* FIXME: This just doesn't work to do this */ + align = PANGO_ALIGN_LEFT; + pango_layout_set_justify (label->layout, TRUE); + break; + default: + g_assert_not_reached(); + } + + pango_layout_set_alignment (label->layout, align); + + if (label->wrap) + { + gint longest_paragraph; + gint width, height; + gint set_width; + + gtk_widget_get_size_request (widget, &set_width, NULL); + if (set_width > 0) + pango_layout_set_width (label->layout, set_width * PANGO_SCALE); + else + { + gint wrap_width; + + pango_layout_set_width (label->layout, -1); + pango_layout_get_extents (label->layout, NULL, &logical_rect); + + width = logical_rect.width; + + /* Try to guess a reasonable maximum width */ + longest_paragraph = width; + + wrap_width = get_label_wrap_width (label); + width = MIN (width, wrap_width); + width = MIN (width, + PANGO_SCALE * (gdk_screen_width () + 1) / 2); + + pango_layout_set_width (label->layout, width); + pango_layout_get_extents (label->layout, NULL, &logical_rect); + width = logical_rect.width; + height = logical_rect.height; + + /* Unfortunately, the above may leave us with a very unbalanced looking paragraph, + * so we try short search for a narrower width that leaves us with the same height + */ + if (longest_paragraph > 0) + { + gint nlines, perfect_width; + + nlines = pango_layout_get_line_count (label->layout); + perfect_width = (longest_paragraph + nlines - 1) / nlines; + + if (perfect_width < width) + { + pango_layout_set_width (label->layout, perfect_width); + pango_layout_get_extents (label->layout, NULL, &logical_rect); + + if (logical_rect.height <= height) + width = logical_rect.width; + else + { + gint mid_width = (perfect_width + width) / 2; + + if (mid_width > perfect_width) + { + pango_layout_set_width (label->layout, mid_width); + pango_layout_get_extents (label->layout, NULL, &logical_rect); + + if (logical_rect.height <= height) + width = logical_rect.width; + } + } + } + } + pango_layout_set_width (label->layout, width); + } + pango_layout_set_wrap (label->layout, label->wrap_mode); + } + else /* !label->wrap */ + pango_layout_set_width (label->layout, -1); + } +} + +static void +eel_editable_label_size_request (GtkWidget *widget, + GtkRequisition *requisition) +{ + EelEditableLabel *label; + gint width, height; + PangoRectangle logical_rect; + gint set_width; + gfloat xpad, ypad; + + g_assert (EEL_IS_EDITABLE_LABEL (widget)); + g_assert (requisition != NULL); + + label = EEL_EDITABLE_LABEL (widget); + + /* + * If word wrapping is on, then the height requisition can depend + * on: + * + * - Any width set on the widget via gtk_widget_set_size_request(). + * - The padding of the widget (xpad, set by gtk_misc_set_padding) + * + * Instead of trying to detect changes to these quantities, if we + * are wrapping, we just rewrap for each size request. Since + * size requisitions are cached by the GTK+ core, this is not + * expensive. + */ + + if (label->wrap) + eel_editable_label_recompute (label); + + eel_editable_label_ensure_layout (label, TRUE); + + gtk_misc_get_alignment (&label->misc, + &xpad, &ypad); + width = xpad * 2; + height = ypad * 2; + + pango_layout_get_extents (label->layout, NULL, &logical_rect); + + gtk_widget_get_size_request (widget, &set_width, NULL); + if (label->wrap && set_width > 0) + width += set_width; + else + width += PANGO_PIXELS (logical_rect.width); + + height += PANGO_PIXELS (logical_rect.height); + + requisition->width = width; + requisition->height = height; +} + +static void +eel_editable_label_size_allocate (GtkWidget *widget, + GtkAllocation *allocation) +{ + (* GTK_WIDGET_CLASS (eel_editable_label_parent_class)->size_allocate) (widget, allocation); +} + +static void +eel_editable_label_state_changed (GtkWidget *widget, + GtkStateType prev_state) +{ + EelEditableLabel *label; + + label = EEL_EDITABLE_LABEL (widget); + + eel_editable_label_select_region (label, 0, 0); + + if (GTK_WIDGET_CLASS (eel_editable_label_parent_class)->state_changed) + GTK_WIDGET_CLASS (eel_editable_label_parent_class)->state_changed (widget, prev_state); +} + +static void +eel_editable_label_style_set (GtkWidget *widget, + GtkStyle *previous_style) +{ + EelEditableLabel *label; + static GdkColor gray = { 0, 0x8888, 0x8888, 0x8888 }; + + g_assert (EEL_IS_EDITABLE_LABEL (widget)); + + label = EEL_EDITABLE_LABEL (widget); + + /* We have to clear the layout, fonts etc. may have changed */ + eel_editable_label_recompute (label); + + /* Set the background, foreground and cursor colors based on + * the new theme selected. + */ + if (gtk_widget_get_realized (widget)) + { + GtkStyle *style; + + style = gtk_widget_get_style (widget); + gdk_window_set_background (gtk_widget_get_window (widget), &style->base[gtk_widget_get_state (widget)]); + + if (label->primary_cursor_gc != NULL) + { + gtk_gc_release (label->primary_cursor_gc); + label->primary_cursor_gc = NULL; + } + + if (label->secondary_cursor_gc != NULL) + { + gtk_gc_release (label->secondary_cursor_gc); + label->secondary_cursor_gc = NULL; + } + + label->primary_cursor_gc = make_cursor_gc (widget, + "cursor-color", + &style->black); + + label->secondary_cursor_gc = make_cursor_gc (widget, + "secondary-cursor-color", + &gray); + } +} + +static void +eel_editable_label_direction_changed (GtkWidget *widget, + GtkTextDirection previous_dir) +{ + EelEditableLabel *label = EEL_EDITABLE_LABEL (widget); + + if (label->layout) + pango_layout_context_changed (label->layout); + + GTK_WIDGET_CLASS (eel_editable_label_parent_class)->direction_changed (widget, previous_dir); +} + +static void +get_layout_location (EelEditableLabel *label, + gint *xp, + gint *yp) +{ + GtkMisc *misc; + GtkWidget *widget; + gfloat xalign, yalign; + GtkRequisition req; + gint x, y, xpad, ypad; + GtkAllocation allocation; + + misc = GTK_MISC (label); + widget = GTK_WIDGET (label); + gtk_misc_get_alignment (misc, &xalign, &yalign); + + if (gtk_widget_get_direction (widget) != GTK_TEXT_DIR_LTR) + xalign = 1.0 - xalign; + + gtk_widget_get_child_requisition (widget, &req); + gtk_misc_get_padding (misc, &xpad, &ypad); + + gtk_widget_get_allocation (widget, &allocation); + x = floor (xpad + + ((allocation.width - req.width) * xalign) + + 0.5); + + y = floor (ypad + + ((allocation.height - req.height) * yalign) + + 0.5); + + if (xp) + *xp = x; + + if (yp) + *yp = y; +} + +static void +eel_editable_label_get_cursor_pos (EelEditableLabel *label, + PangoRectangle *strong_pos, + PangoRectangle *weak_pos) +{ + const gchar *text; + const gchar *preedit_text; + gint index; + + eel_editable_label_ensure_layout (label, TRUE); + + text = pango_layout_get_text (label->layout); + preedit_text = text + label->selection_anchor; + index = label->selection_anchor + + g_utf8_offset_to_pointer (preedit_text, label->preedit_cursor) - preedit_text; + + pango_layout_get_cursor_pos (label->layout, index, strong_pos, weak_pos); +} + +/* Copied from gtkutil private function */ +static gboolean +eel_editable_label_get_block_cursor_location (EelEditableLabel *label, + gint *index, + PangoRectangle *pos, + gboolean *at_line_end) +{ + const gchar *text; + const gchar *preedit_text; + PangoLayoutLine *layout_line; + PangoRectangle strong_pos, weak_pos; + gint line_no; + gboolean rtl; + PangoContext *context; + PangoFontMetrics *metrics; + const PangoFontDescription *font_desc; + + eel_editable_label_ensure_layout (label, TRUE); + + text = pango_layout_get_text (label->layout); + preedit_text = text + label->selection_anchor; + text = g_utf8_offset_to_pointer (preedit_text, label->preedit_cursor); + index[0] = label->selection_anchor + text - preedit_text; + + pango_layout_index_to_pos (label->layout, index[0], pos); + + index[1] = label->selection_anchor + g_utf8_next_char (text) - preedit_text; + + if (pos->width != 0) + { + if (at_line_end) + *at_line_end = FALSE; + if (pos->width < 0) /* RTL char, shift x value back to top left of rect */ + { + pos->x += pos->width; + pos->width = -pos->width; + } + return TRUE; + } + + pango_layout_index_to_line_x (label->layout, index[0], FALSE, &line_no, NULL); + layout_line = pango_layout_get_line_readonly (label->layout, line_no); + if (layout_line == NULL) + return FALSE; + + text = pango_layout_get_text (label->layout); + if (index[0] < layout_line->start_index + layout_line->length) + { + /* this may be a zero-width character in the middle of the line, + * or it could be a character where line is wrapped, we do want + * block cursor in latter case */ + if (g_utf8_next_char (text + index[0]) - text != + layout_line->start_index + layout_line->length) + { + /* zero-width character in the middle of the line, do not + * bother with block cursor */ + return FALSE; + } + } + + /* Cursor is at the line end. It may be an empty line, or it could + * be on the left or on the right depending on text direction, or it + * even could be in the middle of visual layout in bidi text. */ + + pango_layout_get_cursor_pos (label->layout, index[0], &strong_pos, &weak_pos); + + if (strong_pos.x != weak_pos.x) + { + /* do not show block cursor in this case, since the character typed + * in may or may not appear at the cursor position */ + return FALSE; + } + + context = pango_layout_get_context (label->layout); + + /* In case when index points to the end of line, pos->x is always most right + * pixel of the layout line, so we need to correct it for RTL text. */ + if (layout_line->length) + { + if (layout_line->resolved_dir == PANGO_DIRECTION_RTL) + { + PangoLayoutIter *iter; + PangoRectangle line_rect; + gint i; + gint left, right; + const gchar *p; + + p = g_utf8_prev_char (text + index[0]); + + pango_layout_line_index_to_x (layout_line, p - text, FALSE, &left); + pango_layout_line_index_to_x (layout_line, p - text, TRUE, &right); + pos->x = MIN (left, right); + + iter = pango_layout_get_iter (label->layout); + for (i = 0; i < line_no; i++) + pango_layout_iter_next_line (iter); + pango_layout_iter_get_line_extents (iter, NULL, &line_rect); + pango_layout_iter_free (iter); + + rtl = TRUE; + pos->x += line_rect.x; + } + else + rtl = FALSE; + } + else + { + rtl = pango_context_get_base_dir (context) == PANGO_DIRECTION_RTL; + } + + font_desc = pango_layout_get_font_description (label->layout); + if (!font_desc) + font_desc = pango_context_get_font_description (context); + + metrics = pango_context_get_metrics (context, font_desc, NULL); + pos->width = pango_font_metrics_get_approximate_char_width (metrics); + pango_font_metrics_unref (metrics); + + if (rtl) + pos->x -= pos->width - 1; + + if (at_line_end) + *at_line_end = TRUE; + + return pos->width != 0; +} + + +/* These functions are copies from gtk+, as they are not exported from gtk+ */ + +static GdkGC * +make_cursor_gc (GtkWidget *widget, + const gchar *property_name, + GdkColor *fallback) +{ + GdkGCValues gc_values; + GdkGCValuesMask gc_values_mask; + GdkColor *cursor_color; + GtkStyle *style; + + style = gtk_widget_get_style (widget); + gtk_widget_style_get (widget, property_name, &cursor_color, NULL); + + gc_values_mask = GDK_GC_FOREGROUND; + if (cursor_color) + { + gc_values.foreground = *cursor_color; + gdk_color_free (cursor_color); + } + else + gc_values.foreground = *fallback; + + gdk_rgb_find_color (style->colormap, &gc_values.foreground); + return gtk_gc_get (style->depth, style->colormap, &gc_values, gc_values_mask); +} + +static void +_eel_draw_insertion_cursor (GtkWidget *widget, + GdkDrawable *drawable, + GdkGC *gc, + GdkRectangle *location, + GtkTextDirection direction, + gboolean draw_arrow) +{ + gint stem_width; + gint arrow_width; + gint x, y; + gint i; + gfloat cursor_aspect_ratio; + gint offset; + + g_assert (direction != GTK_TEXT_DIR_NONE); + + gtk_widget_style_get (widget, "cursor-aspect-ratio", &cursor_aspect_ratio, NULL); + + stem_width = location->height * cursor_aspect_ratio + 1; + arrow_width = stem_width + 1; + + /* put (stem_width % 2) on the proper side of the cursor */ + if (direction == GTK_TEXT_DIR_LTR) + offset = stem_width / 2; + else + offset = stem_width - stem_width / 2; + + for (i = 0; i < stem_width; i++) + gdk_draw_line (drawable, gc, + location->x + i - offset, location->y, + location->x + i - offset, location->y + location->height - 1); + + if (draw_arrow) + { + if (direction == GTK_TEXT_DIR_RTL) + { + x = location->x - offset - 1; + y = location->y + location->height - arrow_width * 2 - arrow_width + 1; + + for (i = 0; i < arrow_width; i++) + { + gdk_draw_line (drawable, gc, + x, y + i + 1, + x, y + 2 * arrow_width - i - 1); + x --; + } + } + else if (direction == GTK_TEXT_DIR_LTR) + { + x = location->x + stem_width - offset; + y = location->y + location->height - arrow_width * 2 - arrow_width + 1; + + for (i = 0; i < arrow_width; i++) + { + gdk_draw_line (drawable, gc, + x, y + i + 1, + x, y + 2 * arrow_width - i - 1); + x++; + } + } + } +} + +static void +eel_editable_label_draw_cursor (EelEditableLabel *label, gint xoffset, gint yoffset) +{ + if (gtk_widget_is_drawable (GTK_WIDGET (label))) + { + GtkWidget *widget = GTK_WIDGET (label); + + GtkTextDirection keymap_direction; + GtkTextDirection widget_direction; + gboolean split_cursor; + gboolean block; + gboolean block_at_line_end; + gint range[2]; + PangoRectangle strong_pos, weak_pos; + PangoRectangle *cursor1 = NULL; + PangoRectangle *cursor2 = NULL; + GdkRectangle cursor_location; + GtkTextDirection dir1 = GTK_TEXT_DIR_NONE; + GtkTextDirection dir2 = GTK_TEXT_DIR_NONE; + + keymap_direction = + (gdk_keymap_get_direction (gdk_keymap_get_default ()) == PANGO_DIRECTION_LTR) ? + GTK_TEXT_DIR_LTR : GTK_TEXT_DIR_RTL; + + widget_direction = gtk_widget_get_direction (widget); + + if (label->overwrite_mode && + eel_editable_label_get_block_cursor_location (label, range, + &strong_pos, + &block_at_line_end)) + block = TRUE; + else + block = FALSE; + + if (!block) + { + eel_editable_label_get_cursor_pos (label, &strong_pos, &weak_pos); + + g_object_get (gtk_widget_get_settings (widget), + "gtk-split-cursor", &split_cursor, + NULL); + + dir1 = widget_direction; + + if (split_cursor) + { + cursor1 = &strong_pos; + + if (strong_pos.x != weak_pos.x || + strong_pos.y != weak_pos.y) + { + dir2 = (widget_direction == GTK_TEXT_DIR_LTR) ? GTK_TEXT_DIR_RTL : GTK_TEXT_DIR_LTR; + cursor2 = &weak_pos; + } + } + else + { + if (keymap_direction == widget_direction) + cursor1 = &strong_pos; + else + cursor1 = &weak_pos; + } + + cursor_location.x = xoffset + PANGO_PIXELS (cursor1->x); + cursor_location.y = yoffset + PANGO_PIXELS (cursor1->y); + cursor_location.width = 0; + cursor_location.height = PANGO_PIXELS (cursor1->height); + + _eel_draw_insertion_cursor (widget, gtk_widget_get_window (widget), + label->primary_cursor_gc, + &cursor_location, dir1, + dir2 != GTK_TEXT_DIR_NONE); + + if (dir2 != GTK_TEXT_DIR_NONE) + { + cursor_location.x = xoffset + PANGO_PIXELS (cursor2->x); + cursor_location.y = yoffset + PANGO_PIXELS (cursor2->y); + cursor_location.width = 0; + cursor_location.height = PANGO_PIXELS (cursor2->height); + + _eel_draw_insertion_cursor (widget, gtk_widget_get_window (widget), + label->secondary_cursor_gc, + &cursor_location, dir2, TRUE); + } + } + else /* Block cursor */ + { + GdkRegion *clip; + + gdk_draw_rectangle (gtk_widget_get_window (widget), label->primary_cursor_gc, TRUE, + xoffset + PANGO_PIXELS (strong_pos.x), + yoffset + PANGO_PIXELS (strong_pos.y), + PANGO_PIXELS (strong_pos.width), + PANGO_PIXELS (strong_pos.height)); + + if (!block_at_line_end) + { + clip = gdk_pango_layout_get_clip_region (label->layout, + xoffset, yoffset, + range, 1); + + /* FIXME should use gtk_paint, but it can't use a clip + * region + */ + + gdk_gc_set_clip_region (label->primary_cursor_gc, clip); + + gdk_draw_layout_with_colors (gtk_widget_get_window (widget), + label->primary_cursor_gc, + xoffset, yoffset, + label->layout, + >k_widget_get_style (widget)->base[GTK_STATE_NORMAL], + NULL); + + gdk_gc_set_clip_region (label->primary_cursor_gc, NULL); + gdk_region_destroy (clip); + } + } + } +} + + +static gint +eel_editable_label_expose (GtkWidget *widget, + GdkEventExpose *event) +{ + EelEditableLabel *label; + GtkStyle *style; + gint x, y; + + g_assert (EEL_IS_EDITABLE_LABEL (widget)); + g_assert (event != NULL); + + label = EEL_EDITABLE_LABEL (widget); + style = gtk_widget_get_style (widget); + + eel_editable_label_ensure_layout (label, TRUE); + + if (gtk_widget_get_visible (widget) && gtk_widget_get_mapped (widget) && + label->text) + { + get_layout_location (label, &x, &y); + + gtk_paint_layout (style, + gtk_widget_get_window (widget), + gtk_widget_get_state (widget), + TRUE, + &event->area, + widget, + "label", + x, y, + label->layout); + + if (label->selection_anchor != label->selection_end) + { + gint range[2]; + const char *text; + GdkRegion *clip; + GtkStateType state; + + range[0] = label->selection_anchor; + range[1] = label->selection_end; + + /* Handle possible preedit string */ + if (label->preedit_length > 0 && + range[1] > label->selection_anchor) + { + text = pango_layout_get_text (label->layout) + label->selection_anchor; + range[1] += g_utf8_offset_to_pointer (text, label->preedit_length) - text; + } + + if (range[0] > range[1]) + { + gint tmp = range[0]; + range[0] = range[1]; + range[1] = tmp; + } + + clip = gdk_pango_layout_get_clip_region (label->layout, + x, y, + range, + 1); + + /* FIXME should use gtk_paint, but it can't use a clip + * region + */ + + gdk_gc_set_clip_region (style->black_gc, clip); + + + state = GTK_STATE_SELECTED; + if (!gtk_widget_has_focus (widget)) + state = GTK_STATE_ACTIVE; + + gdk_draw_layout_with_colors (gtk_widget_get_window (widget), + style->black_gc, + x, y, + label->layout, + &style->text[state], + &style->base[state]); + + gdk_gc_set_clip_region (style->black_gc, NULL); + gdk_region_destroy (clip); + } + else if (gtk_widget_has_focus (widget)) + eel_editable_label_draw_cursor (label, x, y); + + if (label->draw_outline) + { + GtkAllocation allocation; + gtk_widget_get_allocation (widget, &allocation); + gdk_draw_rectangle (gtk_widget_get_window (widget), + style->text_gc [gtk_widget_get_state (widget)], + FALSE, + 0, 0, + allocation.width - 1, + allocation.height - 1); + } + } + + return FALSE; +} + +static void +eel_editable_label_realize (GtkWidget *widget) +{ + EelEditableLabel *label; + GdkWindowAttr attributes; + gint attributes_mask; + static GdkColor gray = { 0, 0x8888, 0x8888, 0x8888 }; + GtkAllocation allocation; + GdkWindow *window; + GtkStyle *style; + + gtk_widget_set_realized (widget, TRUE); + label = EEL_EDITABLE_LABEL (widget); + gtk_widget_get_allocation (widget, &allocation); + + attributes.wclass = GDK_INPUT_OUTPUT; + attributes.window_type = GDK_WINDOW_CHILD; + attributes.x = allocation.x; + attributes.y = allocation.y; + attributes.width = allocation.width; + attributes.height = allocation.height; + attributes.visual = gtk_widget_get_visual (widget); + attributes.colormap = gtk_widget_get_colormap (widget); + attributes.cursor = gdk_cursor_new (GDK_XTERM); + attributes.event_mask = gtk_widget_get_events (widget) | + (GDK_EXPOSURE_MASK | + GDK_BUTTON_PRESS_MASK | + GDK_BUTTON_RELEASE_MASK | + GDK_BUTTON1_MOTION_MASK | + GDK_BUTTON3_MOTION_MASK | + GDK_POINTER_MOTION_HINT_MASK | + GDK_POINTER_MOTION_MASK | + GDK_ENTER_NOTIFY_MASK | + GDK_LEAVE_NOTIFY_MASK); + + attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP | GDK_WA_CURSOR; + + window = gdk_window_new (gtk_widget_get_parent_window (widget), + &attributes, attributes_mask); + gtk_widget_set_window (widget, window); + gdk_window_set_user_data (window, widget); + + gdk_cursor_unref (attributes.cursor); + + style = gtk_style_attach (gtk_widget_get_style (widget) , gtk_widget_get_window (widget)); + gtk_widget_set_style (widget, style); + + gdk_window_set_background (gtk_widget_get_window (widget), &style->base[gtk_widget_get_state (widget)]); + + gtk_im_context_set_client_window (label->im_context, gtk_widget_get_window (widget)); + + label->primary_cursor_gc = make_cursor_gc (widget, + "cursor-color", + &style->black); + + label->secondary_cursor_gc = make_cursor_gc (widget, + "secondary-cursor-color", + &gray); +} + +static void +eel_editable_label_unrealize (GtkWidget *widget) +{ + EelEditableLabel *label; + + label = EEL_EDITABLE_LABEL (widget); + + gtk_gc_release (label->primary_cursor_gc); + label->primary_cursor_gc = NULL; + + gtk_gc_release (label->secondary_cursor_gc); + label->secondary_cursor_gc = NULL; + + /* Strange. Copied from GtkEntry, should be NULL? */ + gtk_im_context_set_client_window (label->im_context, NULL); + + (* GTK_WIDGET_CLASS (eel_editable_label_parent_class)->unrealize) (widget); +} + +static void +eel_editable_label_map (GtkWidget *widget) +{ + (* GTK_WIDGET_CLASS (eel_editable_label_parent_class)->map) (widget); +} + +static void +eel_editable_label_unmap (GtkWidget *widget) +{ + (* GTK_WIDGET_CLASS (eel_editable_label_parent_class)->unmap) (widget); +} + +static void +window_to_layout_coords (EelEditableLabel *label, + gint *x, + gint *y) +{ + gint lx, ly; + + /* get layout location in gtk_widget_get_window (widget) coords */ + get_layout_location (label, &lx, &ly); + + if (x) + *x -= lx; /* go to layout */ + + if (y) + *y -= ly; /* go to layout */ +} + +static void +get_layout_index (EelEditableLabel *label, + gint x, + gint y, + gint *index) +{ + gint trailing = 0; + const gchar *cluster; + const gchar *cluster_end; + + *index = 0; + + eel_editable_label_ensure_layout (label, TRUE); + + window_to_layout_coords (label, &x, &y); + + x *= PANGO_SCALE; + y *= PANGO_SCALE; + + pango_layout_xy_to_index (label->layout, + x, y, + index, &trailing); + + if (*index >= label->selection_anchor && label->preedit_length) + { + if (*index >= label->selection_anchor + label->preedit_length) + *index -= label->preedit_length; + else + { + *index = label->selection_anchor; + trailing = 0; + } + } + + cluster = label->text + *index; + cluster_end = cluster; + while (trailing) + { + cluster_end = g_utf8_next_char (cluster_end); + --trailing; + } + + *index += (cluster_end - cluster); +} + +static void +eel_editable_label_select_word (EelEditableLabel *label) +{ + gint min, max; + + gint start_index = eel_editable_label_move_backward_word (label, label->selection_end); + gint end_index = eel_editable_label_move_forward_word (label, label->selection_end); + + min = MIN (label->selection_anchor, + label->selection_end); + max = MAX (label->selection_anchor, + label->selection_end); + + min = MIN (min, start_index); + max = MAX (max, end_index); + + eel_editable_label_select_region_index (label, min, max); +} + +static gint +eel_editable_label_button_press (GtkWidget *widget, + GdkEventButton *event) +{ + EelEditableLabel *label; + gint index = 0; + + label = EEL_EDITABLE_LABEL (widget); + + if (event->button == 1) + { + if (!gtk_widget_has_focus (widget)) + gtk_widget_grab_focus (widget); + + if (event->type == GDK_3BUTTON_PRESS) + { + eel_editable_label_select_region_index (label, 0, strlen (label->text)); + return TRUE; + } + + if (event->type == GDK_2BUTTON_PRESS) + { + eel_editable_label_select_word (label); + return TRUE; + } + + get_layout_index (label, event->x, event->y, &index); + + if ((label->selection_anchor != + label->selection_end) && + (event->state & GDK_SHIFT_MASK)) + { + gint min, max; + + /* extend (same as motion) */ + min = MIN (label->selection_anchor, + label->selection_end); + max = MAX (label->selection_anchor, + label->selection_end); + + min = MIN (min, index); + max = MAX (max, index); + + /* ensure the anchor is opposite index */ + if (index == min) + { + gint tmp = min; + min = max; + max = tmp; + } + + eel_editable_label_select_region_index (label, min, max); + } + else + { + if (event->type == GDK_3BUTTON_PRESS) + eel_editable_label_select_region_index (label, 0, strlen (label->text)); + else if (event->type == GDK_2BUTTON_PRESS) + eel_editable_label_select_word (label); + else + /* start a replacement */ + eel_editable_label_select_region_index (label, index, index); + } + + return TRUE; + } + else if (event->button == 2 && event->type == GDK_BUTTON_PRESS) + { + get_layout_index (label, event->x, event->y, &index); + + eel_editable_label_select_region_index (label, index, index); + eel_editable_label_paste (label, GDK_SELECTION_PRIMARY); + + return TRUE; + } + else if (event->button == 3 && event->type == GDK_BUTTON_PRESS) + { + eel_editable_label_do_popup (label, event); + + return TRUE; + + } + return FALSE; +} + +static gint +eel_editable_label_button_release (GtkWidget *widget, + GdkEventButton *event) + +{ + if (event->button != 1) + return FALSE; + + /* The goal here is to return TRUE iff we ate the + * button press to start selecting. + */ + + return TRUE; +} + +static gint +eel_editable_label_motion (GtkWidget *widget, + GdkEventMotion *event) +{ + EelEditableLabel *label; + gint index; + gint x, y; + + label = EEL_EDITABLE_LABEL (widget); + + if ((event->state & GDK_BUTTON1_MASK) == 0) + return FALSE; + + gdk_window_get_pointer (gtk_widget_get_window (widget), + &x, &y, NULL); + + get_layout_index (label, x, y, &index); + + eel_editable_label_select_region_index (label, + label->selection_anchor, + index); + + return TRUE; +} + +static void +get_text_callback (GtkClipboard *clipboard, + GtkSelectionData *selection_data, + guint info, + gpointer user_data_or_owner) +{ + EelEditableLabel *label; + + label = EEL_EDITABLE_LABEL (user_data_or_owner); + + if ((label->selection_anchor != label->selection_end) && + label->text) + { + gint start, end; + gint len; + + start = MIN (label->selection_anchor, + label->selection_end); + end = MAX (label->selection_anchor, + label->selection_end); + + len = strlen (label->text); + + if (end > len) + end = len; + + if (start > len) + start = len; + + gtk_selection_data_set_text (selection_data, + label->text + start, + end - start); + } +} + +static void +clear_text_callback (GtkClipboard *clipboard, + gpointer user_data_or_owner) +{ + EelEditableLabel *label; + + label = EEL_EDITABLE_LABEL (user_data_or_owner); + + label->selection_anchor = label->selection_end; + + gtk_widget_queue_draw (GTK_WIDGET (label)); +} + +static void +eel_editable_label_select_region_index (EelEditableLabel *label, + gint anchor_index, + gint end_index) +{ + GtkClipboard *clipboard; + + g_assert (EEL_IS_EDITABLE_LABEL (label)); + + + if (label->selection_anchor == anchor_index && + label->selection_end == end_index) + return; + + eel_editable_label_reset_im_context (label); + + label->selection_anchor = anchor_index; + label->selection_end = end_index; + + clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY); + + if (anchor_index != end_index) + { + GtkTargetList *list; + GtkTargetEntry *targets; + guint n_targets; + + list = gtk_target_list_new (NULL, 0); + gtk_target_list_add_text_targets (list, 0); + targets = gtk_target_table_new_from_list (list, &n_targets); + + gtk_clipboard_set_with_owner (clipboard, + targets, n_targets, + get_text_callback, + clear_text_callback, + G_OBJECT (label)); + + gtk_clipboard_set_can_store (clipboard, NULL, 0); + gtk_target_table_free (targets, n_targets); + gtk_target_list_unref (list); + } + else + { + if (gtk_clipboard_get_owner (clipboard) == G_OBJECT (label)) + gtk_clipboard_clear (clipboard); + } + + gtk_widget_queue_draw (GTK_WIDGET (label)); + + g_object_freeze_notify (G_OBJECT (label)); + g_object_notify (G_OBJECT (label), "cursor_position"); + g_object_notify (G_OBJECT (label), "selection_bound"); + g_object_thaw_notify (G_OBJECT (label)); +} + +/** + * eel_editable_label_select_region: + * @label: a #EelEditableLabel + * @start_offset: start offset (in characters not bytes) + * @end_offset: end offset (in characters not bytes) + * + * Selects a range of characters in the label, if the label is selectable. + * See eel_editable_label_set_selectable(). If the label is not selectable, + * this function has no effect. If @start_offset or + * @end_offset are -1, then the end of the label will be substituted. + * + **/ +void +eel_editable_label_select_region (EelEditableLabel *label, + gint start_offset, + gint end_offset) +{ + g_return_if_fail (EEL_IS_EDITABLE_LABEL (label)); + + if (label->text) + { + if (start_offset < 0) + start_offset = g_utf8_strlen (label->text, -1); + + if (end_offset < 0) + end_offset = g_utf8_strlen (label->text, -1); + + eel_editable_label_select_region_index (label, + g_utf8_offset_to_pointer (label->text, start_offset) - label->text, + g_utf8_offset_to_pointer (label->text, end_offset) - label->text); + } +} + +/** + * eel_editable_label_get_selection_bounds: + * @label: a #EelEditableLabel + * @start: return location for start of selection, as a character offset + * @end: return location for end of selection, as a character offset + * + * Gets the selected range of characters in the label, returning %TRUE + * if there's a selection. + * + * Return value: %TRUE if selection is non-empty + **/ +gboolean +eel_editable_label_get_selection_bounds (EelEditableLabel *label, + gint *start, + gint *end) +{ + gint start_index, end_index; + gint start_offset, end_offset; + gint len; + + g_return_val_if_fail (EEL_IS_EDITABLE_LABEL (label), FALSE); + + + start_index = MIN (label->selection_anchor, + label->selection_end); + end_index = MAX (label->selection_anchor, + label->selection_end); + + len = strlen (label->text); + + if (end_index > len) + end_index = len; + + if (start_index > len) + start_index = len; + + start_offset = g_utf8_strlen (label->text, start_index); + end_offset = g_utf8_strlen (label->text, end_index); + + if (start_offset > end_offset) + { + gint tmp = start_offset; + start_offset = end_offset; + end_offset = tmp; + } + + if (start) + *start = start_offset; + + if (end) + *end = end_offset; + + return start_offset != end_offset; +} + + +/** + * eel_editable_label_get_layout: + * @label: a #EelEditableLabel + * + * Gets the #PangoLayout used to display the label. + * The layout is useful to e.g. convert text positions to + * pixel positions, in combination with eel_editable_label_get_layout_offsets(). + * The returned layout is owned by the label so need not be + * freed by the caller. + * + * Return value: the #PangoLayout for this label + **/ +PangoLayout* +eel_editable_label_get_layout (EelEditableLabel *label) +{ + g_return_val_if_fail (EEL_IS_EDITABLE_LABEL (label), NULL); + + eel_editable_label_ensure_layout (label, TRUE); + + return label->layout; +} + +/** + * eel_editable_label_get_layout_offsets: + * @label: a #EelEditableLabel + * @x: location to store X offset of layout, or %NULL + * @y: location to store Y offset of layout, or %NULL + * + * Obtains the coordinates where the label will draw the #PangoLayout + * representing the text in the label; useful to convert mouse events + * into coordinates inside the #PangoLayout, e.g. to take some action + * if some part of the label is clicked. Of course you will need to + * create a #GtkEventBox to receive the events, and pack the label + * inside it, since labels are a #GTK_NO_WINDOW widget. Remember + * when using the #PangoLayout functions you need to convert to + * and from pixels using PANGO_PIXELS() or #PANGO_SCALE. + * + **/ +void +eel_editable_label_get_layout_offsets (EelEditableLabel *label, + gint *x, + gint *y) +{ + g_return_if_fail (EEL_IS_EDITABLE_LABEL (label)); + + get_layout_location (label, x, y); +} + +static void +eel_editable_label_pend_cursor_blink (EelEditableLabel *label) +{ + /* TODO */ +} + +static void +eel_editable_label_check_cursor_blink (EelEditableLabel *label) +{ + /* TODO */ +} + +static gint +eel_editable_label_key_press (GtkWidget *widget, + GdkEventKey *event) +{ + EelEditableLabel *label = EEL_EDITABLE_LABEL (widget); + + eel_editable_label_pend_cursor_blink (label); + + if (gtk_im_context_filter_keypress (label->im_context, event)) + { + /*TODO eel_editable_label_obscure_mouse_cursor (label);*/ + label->need_im_reset = TRUE; + return TRUE; + } + + if (GTK_WIDGET_CLASS (eel_editable_label_parent_class)->key_press_event (widget, event)) + /* Activate key bindings + */ + return TRUE; + + return FALSE; +} + +static gint +eel_editable_label_key_release (GtkWidget *widget, + GdkEventKey *event) +{ + EelEditableLabel *label = EEL_EDITABLE_LABEL (widget); + + if (gtk_im_context_filter_keypress (label->im_context, event)) + { + label->need_im_reset = TRUE; + return TRUE; + } + + return GTK_WIDGET_CLASS (eel_editable_label_parent_class)->key_release_event (widget, event); +} + +static void +eel_editable_label_keymap_direction_changed (GdkKeymap *keymap, + EelEditableLabel *label) +{ + gtk_widget_queue_draw (GTK_WIDGET (label)); +} + +static gint +eel_editable_label_focus_in (GtkWidget *widget, + GdkEventFocus *event) +{ + EelEditableLabel *label = EEL_EDITABLE_LABEL (widget); + + gtk_widget_queue_draw (widget); + + label->need_im_reset = TRUE; + gtk_im_context_focus_in (label->im_context); + + g_signal_connect (gdk_keymap_get_default (), + "direction_changed", + G_CALLBACK (eel_editable_label_keymap_direction_changed), label); + + eel_editable_label_check_cursor_blink (label); + + return FALSE; +} + +static gint +eel_editable_label_focus_out (GtkWidget *widget, + GdkEventFocus *event) +{ + EelEditableLabel *label = EEL_EDITABLE_LABEL (widget); + + gtk_widget_queue_draw (widget); + + label->need_im_reset = TRUE; + gtk_im_context_focus_out (label->im_context); + + eel_editable_label_check_cursor_blink (label); + + g_signal_handlers_disconnect_by_func (gdk_keymap_get_default (), + (gpointer) eel_editable_label_keymap_direction_changed, + label); + + return FALSE; +} + +static void +eel_editable_label_delete_text (EelEditableLabel *label, + int start_pos, + int end_pos) +{ + int anchor, end; + + if (start_pos < 0) + start_pos = 0; + if (end_pos < 0 || end_pos > label->n_bytes) + end_pos = label->n_bytes; + + if (start_pos < end_pos) + { + g_memmove (label->text + start_pos, label->text + end_pos, label->n_bytes + 1 - end_pos); + label->n_bytes -= (end_pos - start_pos); + + anchor = label->selection_anchor; + if (anchor > start_pos) + anchor -= MIN (anchor, end_pos) - start_pos; + + end = label->selection_end; + if (end > start_pos) + end -= MIN (end, end_pos) - start_pos; + + /* We might have changed the selection */ + eel_editable_label_select_region_index (label, anchor, end); + + eel_editable_label_recompute (label); + gtk_widget_queue_resize (GTK_WIDGET (label)); + + g_object_notify (G_OBJECT (label), "text"); + g_signal_emit_by_name (GTK_EDITABLE (label), "changed"); + } +} + +static void +eel_editable_label_insert_text (EelEditableLabel *label, + const gchar *new_text, + gint new_text_length, + gint *index) +{ + if (new_text_length + label->n_bytes + 1 > label->text_size) + { + while (new_text_length + label->n_bytes + 1 > label->text_size) + { + if (label->text_size == 0) + label->text_size = 16; + else + label->text_size *= 2; + } + + label->text = g_realloc (label->text, label->text_size); + } + + g_object_freeze_notify (G_OBJECT (label)); + + g_memmove (label->text + *index + new_text_length, label->text + *index, label->n_bytes - *index); + memcpy (label->text + *index, new_text, new_text_length); + + label->n_bytes += new_text_length; + + /* NUL terminate for safety and convenience */ + label->text[label->n_bytes] = '\0'; + + g_object_notify (G_OBJECT (label), "text"); + + if (label->selection_anchor > *index) + { + g_object_notify (G_OBJECT (label), "cursor_position"); + g_object_notify (G_OBJECT (label), "selection_bound"); + label->selection_anchor += new_text_length; + } + + if (label->selection_end > *index) + { + label->selection_end += new_text_length; + g_object_notify (G_OBJECT (label), "selection_bound"); + } + + *index += new_text_length; + + eel_editable_label_recompute (label); + gtk_widget_queue_resize (GTK_WIDGET (label)); + + g_object_thaw_notify (G_OBJECT (label)); + g_signal_emit_by_name (GTK_EDITABLE (label), "changed"); +} + +/* Used for im_commit_cb and inserting Unicode chars */ +static void +eel_editable_label_enter_text (EelEditableLabel *label, + const gchar *str) +{ + GtkEditable *editable = GTK_EDITABLE (label); + gint tmp_pos; + gboolean old_need_im_reset; + + /* Never reset the im while commiting, as that resets possible im state */ + old_need_im_reset = label->need_im_reset; + label->need_im_reset = FALSE; + + if (label->selection_end != label->selection_anchor) + gtk_editable_delete_selection (editable); + else + { + if (label->overwrite_mode) + eel_editable_label_delete_from_cursor (label, GTK_DELETE_CHARS, 1); + } + + tmp_pos = g_utf8_pointer_to_offset (label->text, + label->text + label->selection_anchor); + gtk_editable_insert_text (GTK_EDITABLE (label), str, strlen (str), &tmp_pos); + tmp_pos = g_utf8_offset_to_pointer (label->text, tmp_pos) - label->text; + eel_editable_label_select_region_index (label, tmp_pos, tmp_pos); + + label->need_im_reset = old_need_im_reset; +} + +/* IM Context Callbacks + */ + +static void +eel_editable_label_commit_cb (GtkIMContext *context, + const gchar *str, + EelEditableLabel *label) +{ + eel_editable_label_enter_text (label, str); +} + +static void +eel_editable_label_preedit_changed_cb (GtkIMContext *context, + EelEditableLabel *label) +{ + gchar *preedit_string; + gint cursor_pos; + + gtk_im_context_get_preedit_string (label->im_context, + &preedit_string, NULL, + &cursor_pos); + label->preedit_length = strlen (preedit_string); + cursor_pos = CLAMP (cursor_pos, 0, g_utf8_strlen (preedit_string, -1)); + label->preedit_cursor = cursor_pos; + g_free (preedit_string); + + eel_editable_label_recompute (label); + gtk_widget_queue_resize (GTK_WIDGET (label)); +} + +static gboolean +eel_editable_label_retrieve_surrounding_cb (GtkIMContext *context, + EelEditableLabel *label) +{ + gtk_im_context_set_surrounding (context, + label->text, + strlen (label->text) + 1, + label->selection_end); + + return TRUE; +} + +static gboolean +eel_editable_label_delete_surrounding_cb (GtkIMContext *slave, + gint offset, + gint n_chars, + EelEditableLabel *label) +{ + gint current_pos; + + current_pos = g_utf8_pointer_to_offset (label->text, label->text + label->selection_anchor); + gtk_editable_delete_text (GTK_EDITABLE (label), + current_pos + offset, + current_pos + offset + n_chars); + + return TRUE; +} + +static gboolean +eel_editable_label_focus (GtkWidget *widget, + GtkDirectionType direction) +{ + /* We never want to be in the tab chain */ + return FALSE; +} + +/* Compute the X position for an offset that corresponds to the "more important + * cursor position for that offset. We use this when trying to guess to which + * end of the selection we should go to when the user hits the left or + * right arrow key. + */ +static void +get_better_cursor (EelEditableLabel *label, + gint index, + gint *x, + gint *y) +{ + GtkTextDirection keymap_direction = + (gdk_keymap_get_direction (gdk_keymap_get_default ()) == PANGO_DIRECTION_LTR) ? + GTK_TEXT_DIR_LTR : GTK_TEXT_DIR_RTL; + GtkTextDirection widget_direction = gtk_widget_get_direction (GTK_WIDGET (label)); + gboolean split_cursor; + PangoRectangle strong_pos, weak_pos; + + g_object_get (gtk_widget_get_settings (GTK_WIDGET (label)), + "gtk-split-cursor", &split_cursor, + NULL); + + eel_editable_label_get_cursor_pos (label, &strong_pos, &weak_pos); + + if (split_cursor) + { + *x = strong_pos.x / PANGO_SCALE; + *y = strong_pos.y / PANGO_SCALE; + } + else + { + if (keymap_direction == widget_direction) + { + *x = strong_pos.x / PANGO_SCALE; + *y = strong_pos.y / PANGO_SCALE; + } + else + { + *x = weak_pos.x / PANGO_SCALE; + *y = weak_pos.y / PANGO_SCALE; + } + } +} + + +static gint +eel_editable_label_move_logically (EelEditableLabel *label, + gint start, + gint count) +{ + gint offset = g_utf8_pointer_to_offset (label->text, + label->text + start); + + if (label->text) + { + PangoLogAttr *log_attrs; + gint n_attrs; + gint length; + + eel_editable_label_ensure_layout (label, FALSE); + + length = g_utf8_strlen (label->text, -1); + + pango_layout_get_log_attrs (label->layout, &log_attrs, &n_attrs); + + while (count > 0 && offset < length) + { + do + offset++; + while (offset < length && !log_attrs[offset].is_cursor_position); + + count--; + } + while (count < 0 && offset > 0) + { + do + offset--; + while (offset > 0 && !log_attrs[offset].is_cursor_position); + + count++; + } + + g_free (log_attrs); + } + + return g_utf8_offset_to_pointer (label->text, offset) - label->text; +} + +static gint +eel_editable_label_move_visually (EelEditableLabel *label, + gint start, + gint count) +{ + gint index; + + index = start; + + while (count != 0) + { + int new_index, new_trailing; + gboolean split_cursor; + gboolean strong; + + eel_editable_label_ensure_layout (label, FALSE); + + g_object_get (gtk_widget_get_settings (GTK_WIDGET (label)), + "gtk-split-cursor", &split_cursor, + NULL); + + if (split_cursor) + strong = TRUE; + else + { + GtkTextDirection keymap_direction = + (gdk_keymap_get_direction (gdk_keymap_get_default ()) == PANGO_DIRECTION_LTR) ? + GTK_TEXT_DIR_LTR : GTK_TEXT_DIR_RTL; + + strong = keymap_direction == gtk_widget_get_direction (GTK_WIDGET (label)); + } + + if (count > 0) + { + pango_layout_move_cursor_visually (label->layout, strong, index, 0, 1, &new_index, &new_trailing); + count--; + } + else + { + pango_layout_move_cursor_visually (label->layout, strong, index, 0, -1, &new_index, &new_trailing); + count++; + } + + if (new_index < 0 || new_index == G_MAXINT) + break; + + index = new_index; + + while (new_trailing--) + index = g_utf8_next_char (label->text + new_index) - label->text; + } + + return index; +} + +static gint +eel_editable_label_move_line (EelEditableLabel *label, + gint start, + gint count) +{ + int n_lines, i; + int x; + PangoLayoutLine *line; + int index; + + eel_editable_label_ensure_layout (label, FALSE); + + n_lines = pango_layout_get_line_count (label->layout); + + for (i = 0; i < n_lines; i++) + { + line = pango_layout_get_line (label->layout, i); + if (start >= line->start_index && + start <= line->start_index + line->length) + { + pango_layout_line_index_to_x (line, start, FALSE, &x); + break; + } + } + if (i == n_lines) + i = n_lines - 1; + + i += count; + i = CLAMP (i, 0, n_lines - 1); + + line = pango_layout_get_line (label->layout, i); + if (pango_layout_line_x_to_index (line, + x, + &index, NULL)) + return index; + else + { + if (i == n_lines - 1) + return line->start_index + line->length; + else + return line->start_index + line->length - 1; + } +} + +static gint +eel_editable_label_move_forward_word (EelEditableLabel *label, + gint start) +{ + gint new_pos = g_utf8_pointer_to_offset (label->text, + label->text + start); + gint length; + + length = g_utf8_strlen (label->text, -1); + if (new_pos < length) + { + PangoLogAttr *log_attrs; + gint n_attrs; + + eel_editable_label_ensure_layout (label, FALSE); + + pango_layout_get_log_attrs (label->layout, &log_attrs, &n_attrs); + + /* Find the next word end, + (remember, n_attrs is one more than the number of of chars) */ + new_pos++; + while (new_pos < (n_attrs - 1) && !log_attrs[new_pos].is_word_end) + new_pos++; + + g_free (log_attrs); + } + + return g_utf8_offset_to_pointer (label->text, new_pos) - label->text; +} + + +static gint +eel_editable_label_move_backward_word (EelEditableLabel *label, + gint start) +{ + gint new_pos = g_utf8_pointer_to_offset (label->text, + label->text + start); + + if (new_pos > 0) + { + PangoLogAttr *log_attrs; + gint n_attrs; + + eel_editable_label_ensure_layout (label, FALSE); + + pango_layout_get_log_attrs (label->layout, &log_attrs, &n_attrs); + + new_pos -= 1; + + /* Find the previous word beginning */ + while (new_pos > 0 && !log_attrs[new_pos].is_word_start) + new_pos--; + + g_free (log_attrs); + } + + return g_utf8_offset_to_pointer (label->text, new_pos) - label->text; +} + +static void +eel_editable_label_move_cursor (EelEditableLabel *label, + GtkMovementStep step, + gint count, + gboolean extend_selection) +{ + gint new_pos; + + new_pos = label->selection_end; + + if (label->selection_end != label->selection_anchor && + !extend_selection) + { + /* If we have a current selection and aren't extending it, move to the + * start/or end of the selection as appropriate + */ + switch (step) + { + case GTK_MOVEMENT_DISPLAY_LINES: + case GTK_MOVEMENT_VISUAL_POSITIONS: + { + gint end_x, end_y; + gint anchor_x, anchor_y; + gboolean end_is_left; + + get_better_cursor (label, label->selection_end, &end_x, &end_y); + get_better_cursor (label, label->selection_anchor, &anchor_x, &anchor_y); + + end_is_left = (end_y < anchor_y) || (end_y == anchor_y && end_x < anchor_x); + + if (count < 0) + new_pos = end_is_left ? label->selection_end : label->selection_anchor; + else + new_pos = !end_is_left ? label->selection_end : label->selection_anchor; + + break; + } + case GTK_MOVEMENT_LOGICAL_POSITIONS: + case GTK_MOVEMENT_WORDS: + if (count < 0) + new_pos = MIN (label->selection_end, label->selection_anchor); + else + new_pos = MAX (label->selection_end, label->selection_anchor); + break; + case GTK_MOVEMENT_DISPLAY_LINE_ENDS: + case GTK_MOVEMENT_PARAGRAPH_ENDS: + case GTK_MOVEMENT_BUFFER_ENDS: + /* FIXME: Can do better here */ + new_pos = count < 0 ? 0 : strlen (label->text); + break; + case GTK_MOVEMENT_PARAGRAPHS: + case GTK_MOVEMENT_PAGES: + break; + default: + g_assert_not_reached (); + break; + } + } + else + { + switch (step) + { + case GTK_MOVEMENT_LOGICAL_POSITIONS: + new_pos = eel_editable_label_move_logically (label, new_pos, count); + break; + case GTK_MOVEMENT_VISUAL_POSITIONS: + new_pos = eel_editable_label_move_visually (label, new_pos, count); + break; + case GTK_MOVEMENT_WORDS: + while (count > 0) + { + new_pos = eel_editable_label_move_forward_word (label, new_pos); + count--; + } + while (count < 0) + { + new_pos = eel_editable_label_move_backward_word (label, new_pos); + count++; + } + break; + case GTK_MOVEMENT_DISPLAY_LINE_ENDS: + case GTK_MOVEMENT_PARAGRAPH_ENDS: + case GTK_MOVEMENT_BUFFER_ENDS: + /* FIXME: Can do better here */ + new_pos = count < 0 ? 0 : strlen (label->text); + break; + case GTK_MOVEMENT_DISPLAY_LINES: + new_pos = eel_editable_label_move_line (label, new_pos, count); + break; + break; + case GTK_MOVEMENT_PARAGRAPHS: + case GTK_MOVEMENT_PAGES: + break; + default: + g_assert_not_reached (); + break; + } + } + + if (extend_selection) + eel_editable_label_select_region_index (label, + label->selection_anchor, + new_pos); + else + eel_editable_label_select_region_index (label, new_pos, new_pos); +} + +static void +eel_editable_label_reset_im_context (EelEditableLabel *label) +{ + if (label->need_im_reset) + { + label->need_im_reset = 0; + gtk_im_context_reset (label->im_context); + } +} + + +static void +eel_editable_label_delete_from_cursor (EelEditableLabel *label, + GtkDeleteType type, + gint count) +{ + GtkEditable *editable = GTK_EDITABLE (label); + gint start_pos = label->selection_anchor; + gint end_pos = label->selection_anchor; + + eel_editable_label_reset_im_context (label); + + if (label->selection_anchor != label->selection_end) + { + gtk_editable_delete_selection (editable); + return; + } + + switch (type) + { + case GTK_DELETE_CHARS: + end_pos = eel_editable_label_move_logically (label, start_pos, count); + start_pos = g_utf8_pointer_to_offset (label->text, label->text + start_pos); + end_pos = g_utf8_pointer_to_offset (label->text, label->text + end_pos); + gtk_editable_delete_text (GTK_EDITABLE (label), MIN (start_pos, end_pos), MAX (start_pos, end_pos)); + break; + case GTK_DELETE_WORDS: + if (count < 0) + { + /* Move to end of current word, or if not on a word, end of previous word */ + end_pos = eel_editable_label_move_backward_word (label, end_pos); + end_pos = eel_editable_label_move_forward_word (label, end_pos); + } + else if (count > 0) + { + /* Move to beginning of current word, or if not on a word, begining of next word */ + start_pos = eel_editable_label_move_forward_word (label, start_pos); + start_pos = eel_editable_label_move_backward_word (label, start_pos); + } + + /* Fall through */ + case GTK_DELETE_WORD_ENDS: + while (count < 0) + { + start_pos = eel_editable_label_move_backward_word (label, start_pos); + count++; + } + while (count > 0) + { + end_pos = eel_editable_label_move_forward_word (label, end_pos); + count--; + } + start_pos = g_utf8_pointer_to_offset (label->text, label->text + start_pos); + end_pos = g_utf8_pointer_to_offset (label->text, label->text + end_pos); + + gtk_editable_delete_text (GTK_EDITABLE (label), start_pos, end_pos); + break; + case GTK_DELETE_DISPLAY_LINE_ENDS: + case GTK_DELETE_PARAGRAPH_ENDS: + end_pos = g_utf8_pointer_to_offset (label->text, label->text + label->selection_anchor); + if (count < 0) + gtk_editable_delete_text (GTK_EDITABLE (label), 0, end_pos); + else + gtk_editable_delete_text (GTK_EDITABLE (label), end_pos, -1); + break; + case GTK_DELETE_DISPLAY_LINES: + case GTK_DELETE_PARAGRAPHS: + gtk_editable_delete_text (GTK_EDITABLE (label), 0, -1); + break; + case GTK_DELETE_WHITESPACE: + /* TODO eel_editable_label_delete_whitespace (label); */ + break; + } + + eel_editable_label_pend_cursor_blink (label); +} + + +static void +eel_editable_label_copy_clipboard (EelEditableLabel *label) +{ + if (label->text) + { + gint start, end; + gint len; + + start = MIN (label->selection_anchor, + label->selection_end); + end = MAX (label->selection_anchor, + label->selection_end); + + len = strlen (label->text); + + if (end > len) + end = len; + + if (start > len) + start = len; + + if (start != end) + gtk_clipboard_set_text (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD), + label->text + start, end - start); + } +} + +static void +eel_editable_label_cut_clipboard (EelEditableLabel *label) +{ + if (label->text) + { + gint start, end; + gint len; + + start = MIN (label->selection_anchor, + label->selection_end); + end = MAX (label->selection_anchor, + label->selection_end); + + len = strlen (label->text); + + if (end > len) + end = len; + + if (start > len) + start = len; + + if (start != end) + { + gtk_clipboard_set_text (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD), + label->text + start, end - start); + start = g_utf8_pointer_to_offset (label->text, label->text + start); + end = g_utf8_pointer_to_offset (label->text, label->text + end); + gtk_editable_delete_text (GTK_EDITABLE (label), start, end); + } + } +} + +static void +paste_received (GtkClipboard *clipboard, + const gchar *text, + gpointer data) +{ + EelEditableLabel *label = EEL_EDITABLE_LABEL (data); + GtkEditable *editable = GTK_EDITABLE (label); + gint tmp_pos; + + if (text) + { + if (label->selection_end != label->selection_anchor) + gtk_editable_delete_selection (editable); + + tmp_pos = g_utf8_pointer_to_offset (label->text, + label->text + label->selection_anchor); + gtk_editable_insert_text (GTK_EDITABLE (label), text, strlen (text), &tmp_pos); + tmp_pos = g_utf8_offset_to_pointer (label->text, tmp_pos) - label->text; + eel_editable_label_select_region_index (label, tmp_pos, tmp_pos); + } + + g_object_unref (G_OBJECT (label)); +} + +static void +eel_editable_label_paste (EelEditableLabel *label, + GdkAtom selection) +{ + g_object_ref (G_OBJECT (label)); + gtk_clipboard_request_text (gtk_widget_get_clipboard (GTK_WIDGET (label), selection), + paste_received, label); +} + +static void +eel_editable_label_paste_clipboard (EelEditableLabel *label) +{ + eel_editable_label_paste (label, GDK_NONE); +} + +static void +eel_editable_label_select_all (EelEditableLabel *label) +{ + eel_editable_label_select_region_index (label, 0, strlen (label->text)); +} + +/* Quick hack of a popup menu + */ +static void +activate_cb (GtkWidget *menuitem, + EelEditableLabel *label) +{ + const gchar *signal = g_object_get_data (G_OBJECT (menuitem), "gtk-signal"); + g_signal_emit_by_name (GTK_OBJECT (label), signal); +} + +static void +append_action_signal (EelEditableLabel *label, + GtkWidget *menu, + const gchar *stock_id, + const gchar *signal, + gboolean sensitive) +{ + GtkWidget *menuitem = gtk_image_menu_item_new_from_stock (stock_id, NULL); + + g_object_set_data (G_OBJECT (menuitem), "gtk-signal", (char *)signal); + g_signal_connect (menuitem, "activate", + G_CALLBACK (activate_cb), label); + + gtk_widget_set_sensitive (menuitem, sensitive); + + gtk_widget_show (menuitem); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem); +} + +static void +popup_menu_detach (GtkWidget *attach_widget, + GtkMenu *menu) +{ + EelEditableLabel *label; + label = EEL_EDITABLE_LABEL (attach_widget); + + label->popup_menu = NULL; +} + +static void +popup_position_func (GtkMenu *menu, + gint *x, + gint *y, + gboolean *push_in, + gpointer user_data) +{ + EelEditableLabel *label; + GtkWidget *widget; + GtkRequisition req; + GtkAllocation allocation; + + label = EEL_EDITABLE_LABEL (user_data); + widget = GTK_WIDGET (label); + + g_assert (gtk_widget_get_realized (widget)); + + gdk_window_get_origin (gtk_widget_get_window (widget), x, y); + + /*gtk_widget_size_request (label->popup_menu, &req);*/ + gtk_widget_get_requisition (widget, &req); + gtk_widget_get_allocation (widget, &allocation); + + *x += allocation.width / 2; + *y += allocation.height; + + *x = CLAMP (*x, 0, MAX (0, gdk_screen_width () - req.width)); + *y = CLAMP (*y, 0, MAX (0, gdk_screen_height () - req.height)); +} + +static void +eel_editable_label_toggle_overwrite (EelEditableLabel *label) +{ + label->overwrite_mode = !label->overwrite_mode; + gtk_widget_queue_draw (GTK_WIDGET (label)); +} + +typedef struct +{ + EelEditableLabel *label; + gint button; + guint time; +} PopupInfo; + +static void +popup_targets_received (GtkClipboard *clipboard, + GtkSelectionData *data, + gpointer user_data) +{ + GtkWidget *menuitem, *submenu; + gboolean have_selection; + gboolean clipboard_contains_text; + PopupInfo *info; + EelEditableLabel *label; + + info = user_data; + label = info->label; + + if (gtk_widget_get_realized (GTK_WIDGET (label))) + { + if (label->popup_menu) + gtk_widget_destroy (label->popup_menu); + + label->popup_menu = gtk_menu_new (); + + gtk_menu_attach_to_widget (GTK_MENU (label->popup_menu), + GTK_WIDGET (label), + popup_menu_detach); + + have_selection = + label->selection_anchor != label->selection_end; + + clipboard_contains_text = gtk_selection_data_targets_include_text (data); + + append_action_signal (label, label->popup_menu, GTK_STOCK_CUT, "cut_clipboard", + have_selection); + append_action_signal (label, label->popup_menu, GTK_STOCK_COPY, "copy_clipboard", + have_selection); + append_action_signal (label, label->popup_menu, GTK_STOCK_PASTE, "paste_clipboard", + clipboard_contains_text); + + menuitem = gtk_menu_item_new_with_label (_("Select All")); + g_signal_connect_object (menuitem, "activate", + G_CALLBACK (eel_editable_label_select_all), label, + G_CONNECT_SWAPPED); + gtk_widget_show (menuitem); + gtk_menu_shell_append (GTK_MENU_SHELL (label->popup_menu), menuitem); + + menuitem = gtk_separator_menu_item_new (); + gtk_widget_show (menuitem); + gtk_menu_shell_append (GTK_MENU_SHELL (label->popup_menu), menuitem); + + menuitem = gtk_menu_item_new_with_label (_("Input Methods")); + gtk_widget_show (menuitem); + submenu = gtk_menu_new (); + gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu); + + gtk_menu_shell_append (GTK_MENU_SHELL (label->popup_menu), menuitem); + + gtk_im_multicontext_append_menuitems (GTK_IM_MULTICONTEXT (label->im_context), + GTK_MENU_SHELL (submenu)); + + g_signal_emit (GTK_OBJECT (label), + signals[POPULATE_POPUP], 0, + label->popup_menu); + + if (info->button) + gtk_menu_popup (GTK_MENU (label->popup_menu), NULL, NULL, + NULL, NULL, + info->button, info->time); + else + { + gtk_menu_popup (GTK_MENU (label->popup_menu), NULL, NULL, + popup_position_func, label, + info->button, info->time); + gtk_menu_shell_select_first (GTK_MENU_SHELL (label->popup_menu), FALSE); + } + } + + g_object_unref (label); + g_free (info); +} + +static void +eel_editable_label_do_popup (EelEditableLabel *label, + GdkEventButton *event) +{ + PopupInfo *info = g_new (PopupInfo, 1); + + /* In order to know what entries we should make sensitive, we + * ask for the current targets of the clipboard, and when + * we get them, then we actually pop up the menu. + */ + info->label = g_object_ref (label); + + if (event) + { + info->button = event->button; + info->time = event->time; + } + else + { + info->button = 0; + info->time = gtk_get_current_event_time (); + } + + gtk_clipboard_request_contents (gtk_widget_get_clipboard (GTK_WIDGET (label), GDK_SELECTION_CLIPBOARD), + gdk_atom_intern ("TARGETS", FALSE), + popup_targets_received, + info); +} + +/************ Editable implementation ****************/ + +static void +editable_insert_text_emit (GtkEditable *editable, + const gchar *new_text, + gint new_text_length, + gint *position) +{ + EelEditableLabel *label = EEL_EDITABLE_LABEL (editable); + gchar buf[64]; + gchar *text; + int text_length; + + text_length = g_utf8_strlen (label->text, -1); + + if (*position < 0 || *position > text_length) + *position = text_length; + + g_object_ref (G_OBJECT (editable)); + + if (new_text_length <= 63) + text = buf; + else + text = g_new (gchar, new_text_length + 1); + + text[new_text_length] = '\0'; + strncpy (text, new_text, new_text_length); + + g_signal_emit_by_name (editable, "insert_text", text, new_text_length, position); + + if (new_text_length > 63) + g_free (text); + + g_object_unref (G_OBJECT (editable)); +} + +static void +editable_delete_text_emit (GtkEditable *editable, + gint start_pos, + gint end_pos) +{ + EelEditableLabel *label = EEL_EDITABLE_LABEL (editable); + int text_length; + + text_length = g_utf8_strlen (label->text, -1); + + if (end_pos < 0 || end_pos > text_length) + end_pos = text_length; + if (start_pos < 0) + start_pos = 0; + if (start_pos > end_pos) + start_pos = end_pos; + + g_object_ref (G_OBJECT (editable)); + + g_signal_emit_by_name (editable, "delete_text", start_pos, end_pos); + + g_object_unref (G_OBJECT (editable)); +} + +static void +editable_insert_text (GtkEditable *editable, + const gchar *new_text, + gint new_text_length, + gint *position) +{ + EelEditableLabel *label = EEL_EDITABLE_LABEL (editable); + gint index; + + if (new_text_length < 0) + new_text_length = strlen (new_text); + + index = g_utf8_offset_to_pointer (label->text, *position) - label->text; + + eel_editable_label_insert_text (label, + new_text, + new_text_length, + &index); + + *position = g_utf8_pointer_to_offset (label->text, label->text + index); +} + +static void +editable_delete_text (GtkEditable *editable, + gint start_pos, + gint end_pos) +{ + EelEditableLabel *label = EEL_EDITABLE_LABEL (editable); + int text_length; + gint start_index, end_index; + + text_length = g_utf8_strlen (label->text, -1); + + if (end_pos < 0 || end_pos > text_length) + end_pos = text_length; + if (start_pos < 0) + start_pos = 0; + if (start_pos > end_pos) + start_pos = end_pos; + + start_index = g_utf8_offset_to_pointer (label->text, start_pos) - label->text; + end_index = g_utf8_offset_to_pointer (label->text, end_pos) - label->text; + + eel_editable_label_delete_text (label, start_index, end_index); +} + +static gchar * +editable_get_chars (GtkEditable *editable, + gint start_pos, + gint end_pos) +{ + EelEditableLabel *label = EEL_EDITABLE_LABEL (editable); + int text_length; + gint start_index, end_index; + + text_length = g_utf8_strlen (label->text, -1); + + if (end_pos < 0 || end_pos > text_length) + end_pos = text_length; + if (start_pos < 0) + start_pos = 0; + if (start_pos > end_pos) + start_pos = end_pos; + + start_index = g_utf8_offset_to_pointer (label->text, start_pos) - label->text; + end_index = g_utf8_offset_to_pointer (label->text, end_pos) - label->text; + + return g_strndup (label->text + start_index, end_index - start_index); +} + +static void +editable_set_selection_bounds (GtkEditable *editable, + gint start, + gint end) +{ + EelEditableLabel *label = EEL_EDITABLE_LABEL (editable); + int text_length; + gint start_index, end_index; + + text_length = g_utf8_strlen (label->text, -1); + + if (end < 0 || end > text_length) + end = text_length; + if (start < 0) + start = text_length; + if (start > text_length) + start = text_length; + + eel_editable_label_reset_im_context (label); + + start_index = g_utf8_offset_to_pointer (label->text, start) - label->text; + end_index = g_utf8_offset_to_pointer (label->text, end) - label->text; + + eel_editable_label_select_region_index (label, start_index, end_index); +} + +static gboolean +editable_get_selection_bounds (GtkEditable *editable, + gint *start, + gint *end) +{ + EelEditableLabel *label = EEL_EDITABLE_LABEL (editable); + + *start = g_utf8_pointer_to_offset (label->text, label->text + label->selection_anchor); + *end = g_utf8_pointer_to_offset (label->text, label->text + label->selection_end); + + return (label->selection_anchor != label->selection_end); +} + +static void +editable_real_set_position (GtkEditable *editable, + gint position) +{ + EelEditableLabel *label = EEL_EDITABLE_LABEL (editable); + int text_length; + int index; + + text_length = g_utf8_strlen (label->text, -1); + + if (position < 0 || position > text_length) + position = text_length; + + index = g_utf8_offset_to_pointer (label->text, position) - label->text; + + if (index != label->selection_anchor || + index != label->selection_end) + { + eel_editable_label_select_region_index (label, index, index); + } +} + +static gint +editable_get_position (GtkEditable *editable) +{ + EelEditableLabel *label = EEL_EDITABLE_LABEL (editable); + + return g_utf8_pointer_to_offset (label->text, label->text + label->selection_anchor); +} + + +static AtkObjectClass *a11y_parent_class = NULL; + +static const char* eel_editable_label_accessible_data = "eel-editable-label-accessible-data"; + +/************ Accessible implementation ****************/ + +typedef struct +{ + GailTextUtil *textutil; + gint selection_anchor; + gint selection_end; + gchar *signal_name; + gint position; + gint length; +} EelEditableLabelAccessiblePrivate; + +typedef struct +{ + EelEditableLabel* label; + gint position; +} EelEditableLabelAccessiblePaste; + + +static gchar* +eel_editable_label_accessible_get_text (AtkText *text, + gint start_pos, + gint end_pos) +{ + GtkWidget *widget; + EelEditableLabelAccessiblePrivate *priv; + + widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text)); + if (widget == NULL) + /* State is defunct */ + return NULL; + + priv = g_object_get_data (G_OBJECT (text), eel_editable_label_accessible_data); + return gail_text_util_get_substring (priv->textutil, start_pos, end_pos); +} + +static gunichar +eel_editable_label_accessible_get_character_at_offset (AtkText *text, + gint offset) +{ + GtkWidget *widget; + EelEditableLabelAccessiblePrivate *priv; + gchar *string; + gchar *index; + gunichar unichar; + + widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text)); + if (widget == NULL) + /* State is defunct */ + return '\0'; + + priv = g_object_get_data (G_OBJECT (text), eel_editable_label_accessible_data); + string = gail_text_util_get_substring (priv->textutil, 0, -1); + if (offset >= g_utf8_strlen (string, -1)) + { + unichar = '\0'; + } + else + { + index = g_utf8_offset_to_pointer (string, offset); + + unichar = g_utf8_get_char(index); + } + + g_free(string); + return unichar; +} + +static gchar* +eel_editable_label_accessible_get_text_before_offset (AtkText *text, + gint offset, + AtkTextBoundary boundary_type, + gint *start_offset, + gint *end_offset) +{ + GtkWidget *widget; + EelEditableLabel *label; + EelEditableLabelAccessiblePrivate *priv; + + widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text)); + if (widget == NULL) + /* State is defunct */ + return NULL; + + label = EEL_EDITABLE_LABEL (widget); + priv = g_object_get_data (G_OBJECT (text), eel_editable_label_accessible_data); + + return gail_text_util_get_text (priv->textutil, + eel_editable_label_get_layout (label), + GAIL_BEFORE_OFFSET, + boundary_type, offset, + start_offset, end_offset); +} + +static gchar* +eel_editable_label_accessible_get_text_at_offset (AtkText *text, + gint offset, + AtkTextBoundary boundary_type, + gint *start_offset, + gint *end_offset) +{ + GtkWidget *widget; + EelEditableLabel *label; + EelEditableLabelAccessiblePrivate *priv; + + widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text)); + if (widget == NULL) + /* State is defunct */ + return NULL; + + + label = EEL_EDITABLE_LABEL (widget); + priv = g_object_get_data (G_OBJECT (text), eel_editable_label_accessible_data); + return gail_text_util_get_text (priv->textutil, + eel_editable_label_get_layout (label), + GAIL_AT_OFFSET, + boundary_type, offset, + start_offset, end_offset); +} + +static gchar* +eel_editable_label_accessible_get_text_after_offset (AtkText *text, + gint offset, + AtkTextBoundary boundary_type, + gint *start_offset, + gint *end_offset) +{ + GtkWidget *widget; + EelEditableLabel *label; + EelEditableLabelAccessiblePrivate *priv; + + widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text)); + if (widget == NULL) + /* State is defunct */ + return NULL; + + label = EEL_EDITABLE_LABEL (widget); + priv = g_object_get_data (G_OBJECT (text), eel_editable_label_accessible_data); + return gail_text_util_get_text (priv->textutil, + eel_editable_label_get_layout (label), + GAIL_AFTER_OFFSET, + boundary_type, offset, + start_offset, end_offset); +} + +static gint +eel_editable_label_accessible_get_caret_offset (AtkText *text) +{ + GtkWidget *widget; + + widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text)); + if (widget == NULL) + /* State is defunct */ + return 0; + + return gtk_editable_get_position (GTK_EDITABLE (widget)); +} + +static gboolean +eel_editable_label_accessible_set_caret_offset (AtkText *text, gint offset) +{ + GtkWidget *widget; + + widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text)); + if (widget == NULL) + /* State is defunct */ + return FALSE; + + gtk_editable_set_position (GTK_EDITABLE (widget), offset); + return TRUE; +} + +static gint +eel_editable_label_accessible_get_character_count (AtkText *text) +{ + GtkWidget *widget; + EelEditableLabel *label; + + widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text)); + if (widget == NULL) + /* State is defunct */ + return 0; + + label = EEL_EDITABLE_LABEL (widget); + return g_utf8_strlen (eel_editable_label_get_text (label), -1); +} + +static gint +eel_editable_label_accessible_get_n_selections (AtkText *text) +{ + GtkWidget *widget; + EelEditableLabel *label; + gint select_start, select_end; + + widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text)); + if (widget == NULL) + /* State is defunct */ + return -1; + + label = EEL_EDITABLE_LABEL (widget); + gtk_editable_get_selection_bounds (GTK_EDITABLE (label), &select_start, + &select_end); + + if (select_start != select_end) + return 1; + else + return 0; +} + +static gchar* +eel_editable_label_accessible_get_selection (AtkText *text, + gint selection_num, + gint *start_pos, + gint *end_pos) +{ + GtkWidget *widget; + EelEditableLabel *label; + + widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text)); + if (widget == NULL) + /* State is defunct */ + return NULL; + + /* Only let the user get the selection if one is set, and if the + * selection_num is 0. + */ + if (selection_num != 0) + return NULL; + + label = EEL_EDITABLE_LABEL (widget); + gtk_editable_get_selection_bounds (GTK_EDITABLE (label), start_pos, end_pos); + + if (*start_pos != *end_pos) + return gtk_editable_get_chars (GTK_EDITABLE (label), *start_pos, *end_pos); + else + return NULL; +} + +static gboolean +eel_editable_label_accessible_add_selection (AtkText *text, + gint start_pos, + gint end_pos) +{ + GtkWidget *widget; + EelEditableLabel *label; + gint select_start, select_end; + + widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text)); + if (widget == NULL) + /* State is defunct */ + return FALSE; + + label = EEL_EDITABLE_LABEL (widget); + gtk_editable_get_selection_bounds (GTK_EDITABLE (label), &select_start, + &select_end); + + /* If there is already a selection, then don't allow another to be added, + * since EelEditableLabel only supports one selected region. + */ + if (select_start == select_end) + { + gtk_editable_select_region (GTK_EDITABLE (label), start_pos, end_pos); + return TRUE; + } + else + return FALSE; +} + +static gboolean +eel_editable_label_accessible_remove_selection (AtkText *text, + gint selection_num) +{ + GtkWidget *widget; + EelEditableLabel *label; + gint select_start, select_end, caret_pos; + + widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text)); + if (widget == NULL) + /* State is defunct */ + return FALSE; + + if (selection_num != 0) + return FALSE; + + label = EEL_EDITABLE_LABEL (widget); + gtk_editable_get_selection_bounds (GTK_EDITABLE (label), &select_start, + &select_end); + + if (select_start != select_end) + { + /* Setting the start & end of the selected region to the caret position + * turns off the selection. + */ + caret_pos = gtk_editable_get_position (GTK_EDITABLE (label)); + gtk_editable_select_region (GTK_EDITABLE (label), caret_pos, caret_pos); + return TRUE; + } + else + return FALSE; +} + +static gboolean +eel_editable_label_accessible_set_selection (AtkText *text, + gint selection_num, + gint start_pos, + gint end_pos) +{ + GtkWidget *widget; + EelEditableLabel *label; + gint select_start, select_end; + + widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text)); + if (widget == NULL) + /* State is defunct */ + return FALSE; + + /* Only let the user move the selection if one is set, and if the + * selection_num is 0 + */ + if (selection_num != 0) + return FALSE; + + label = EEL_EDITABLE_LABEL (widget); + gtk_editable_get_selection_bounds (GTK_EDITABLE (label), &select_start, + &select_end); + + if (select_start != select_end) + { + gtk_editable_select_region (GTK_EDITABLE (label), start_pos, end_pos); + return TRUE; + } + else + return FALSE; +} + +static AtkAttributeSet* +eel_editable_label_accessible_get_run_attributes (AtkText *text, + gint offset, + gint *start_offset, + gint *end_offset) +{ + GtkWidget *widget; + EelEditableLabel *label; + AtkAttributeSet *at_set = NULL; + GtkTextDirection dir; + + widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text)); + if (widget == NULL) + /* State is defunct */ + return NULL; + + label = EEL_EDITABLE_LABEL (widget); + + dir = gtk_widget_get_direction (widget); + if (dir == GTK_TEXT_DIR_RTL) + { + at_set = gail_misc_add_attribute (at_set, + ATK_TEXT_ATTR_DIRECTION, + g_strdup (atk_text_attribute_get_value (ATK_TEXT_ATTR_DIRECTION, dir))); + } + + at_set = gail_misc_layout_get_run_attributes (at_set, + eel_editable_label_get_layout (label), + label->text, + offset, + start_offset, + end_offset); + return at_set; +} + +static AtkAttributeSet* +eel_editable_label_accessible_get_default_attributes (AtkText *text) +{ + GtkWidget *widget; + EelEditableLabel *label; + AtkAttributeSet *at_set = NULL; + + widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text)); + if (widget == NULL) + /* State is defunct */ + return NULL; + + label = EEL_EDITABLE_LABEL (widget); + + at_set = gail_misc_get_default_attributes (at_set, + eel_editable_label_get_layout (label), + widget); + return at_set; +} + +static void +eel_editable_label_accessible_get_character_extents (AtkText *text, + gint offset, + gint *x, + gint *y, + gint *width, + gint *height, + AtkCoordType coords) +{ + GtkWidget *widget; + EelEditableLabel *label; + PangoRectangle char_rect; + gint index, cursor_index, x_layout, y_layout; + + widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text)); + if (widget == NULL) + /* State is defunct */ + return; + + label = EEL_EDITABLE_LABEL (widget); + eel_editable_label_get_layout_offsets (label, &x_layout, &y_layout); + index = g_utf8_offset_to_pointer (label->text, offset) - label->text; + cursor_index = label->selection_anchor; + if (index > cursor_index) + index += label->preedit_length; + pango_layout_index_to_pos (eel_editable_label_get_layout(label), index, &char_rect); + + gail_misc_get_extents_from_pango_rectangle (widget, &char_rect, + x_layout, y_layout, x, y, width, height, coords); +} + +static gint +eel_editable_label_accessible_get_offset_at_point (AtkText *text, + gint x, + gint y, + AtkCoordType coords) +{ + GtkWidget *widget; + EelEditableLabel *label; + gint index, cursor_index, x_layout, y_layout; + + widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text)); + if (widget == NULL) + /* State is defunct */ + return -1; + + label = EEL_EDITABLE_LABEL (widget); + + eel_editable_label_get_layout_offsets (label, &x_layout, &y_layout); + + index = gail_misc_get_index_at_point_in_layout (widget, + eel_editable_label_get_layout(label), x_layout, y_layout, x, y, coords); + if (index == -1) + { + if (coords == ATK_XY_SCREEN || coords == ATK_XY_WINDOW) + return g_utf8_strlen (label->text, -1); + + return index; + } + else + { + cursor_index = label->selection_anchor; + if (index >= cursor_index && label->preedit_length) + { + if (index >= cursor_index + label->preedit_length) + index -= label->preedit_length; + else + index = cursor_index; + } + return g_utf8_pointer_to_offset (label->text, label->text + index); + } +} + +static void +atk_text_interface_init (AtkTextIface *iface) +{ + g_assert (iface != NULL); + + iface->get_text = eel_editable_label_accessible_get_text; + iface->get_character_at_offset = eel_editable_label_accessible_get_character_at_offset; + iface->get_text_before_offset = eel_editable_label_accessible_get_text_before_offset; + iface->get_text_at_offset = eel_editable_label_accessible_get_text_at_offset; + iface->get_text_after_offset = eel_editable_label_accessible_get_text_after_offset; + iface->get_caret_offset = eel_editable_label_accessible_get_caret_offset; + iface->set_caret_offset = eel_editable_label_accessible_set_caret_offset; + iface->get_character_count = eel_editable_label_accessible_get_character_count; + iface->get_n_selections = eel_editable_label_accessible_get_n_selections; + iface->get_selection = eel_editable_label_accessible_get_selection; + iface->add_selection = eel_editable_label_accessible_add_selection; + iface->remove_selection = eel_editable_label_accessible_remove_selection; + iface->set_selection = eel_editable_label_accessible_set_selection; + iface->get_run_attributes = eel_editable_label_accessible_get_run_attributes; + iface->get_default_attributes = eel_editable_label_accessible_get_default_attributes; + iface->get_character_extents = eel_editable_label_accessible_get_character_extents; + iface->get_offset_at_point = eel_editable_label_accessible_get_offset_at_point; +} + +static void +eel_editable_label_accessible_set_text_contents (AtkEditableText *text, + const gchar *string) +{ + GtkWidget *widget; + EelEditableLabel *label; + + widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text)); + if (widget == NULL) + /* State is defunct */ + return; + + label = EEL_EDITABLE_LABEL (widget); + + eel_editable_label_set_text (label, string); +} + +static void +eel_editable_label_accessible_insert_text (AtkEditableText *text, + const gchar *string, + gint length, + gint *position) +{ + GtkWidget *widget; + EelEditableLabel *label; + GtkEditable *editable; + + widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text)); + if (widget == NULL) + /* State is defunct */ + return; + + label = EEL_EDITABLE_LABEL (widget); + editable = GTK_EDITABLE (label); + + gtk_editable_insert_text (editable, string, length, position); +} + +static void +eel_editable_label_accessible_copy_text (AtkEditableText *text, + gint start_pos, + gint end_pos) +{ + GtkWidget *widget; + EelEditableLabel *label; + GtkEditable *editable; + gchar *str; + + widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text)); + if (widget == NULL) + /* State is defunct */ + return; + + label = EEL_EDITABLE_LABEL (widget); + editable = GTK_EDITABLE (label); + str = gtk_editable_get_chars (editable, start_pos, end_pos); + gtk_clipboard_set_text (gtk_clipboard_get (GDK_NONE), str, -1); +} + +static void +eel_editable_label_accessible_cut_text (AtkEditableText *text, + gint start_pos, + gint end_pos) +{ + GtkWidget *widget; + EelEditableLabel *label; + GtkEditable *editable; + gchar *str; + + widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text)); + if (widget == NULL) + /* State is defunct */ + return; + + label = EEL_EDITABLE_LABEL (widget); + editable = GTK_EDITABLE (label); + str = gtk_editable_get_chars (editable, start_pos, end_pos); + gtk_clipboard_set_text (gtk_clipboard_get (GDK_NONE), str, -1); + gtk_editable_delete_text (editable, start_pos, end_pos); +} + +static void +eel_editable_label_accessible_delete_text (AtkEditableText *text, + gint start_pos, + gint end_pos) +{ + GtkWidget *widget; + EelEditableLabel *label; + GtkEditable *editable; + + widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text)); + if (widget == NULL) + /* State is defunct */ + return; + + label = EEL_EDITABLE_LABEL (widget); + editable = GTK_EDITABLE (label); + + gtk_editable_delete_text (editable, start_pos, end_pos); +} + +static void +eel_editable_label_accessible_paste_received (GtkClipboard *clipboard, + const gchar *text, + gpointer data) +{ + EelEditableLabelAccessiblePaste* paste_struct = (EelEditableLabelAccessiblePaste *)data; + + if (text) + gtk_editable_insert_text (GTK_EDITABLE (paste_struct->label), text, -1, + &(paste_struct->position)); + + g_object_unref (paste_struct->label); +} + +static void +eel_editable_label_accessible_paste_text (AtkEditableText *text, + gint position) +{ + GtkWidget *widget; + GtkEditable *editable; + EelEditableLabelAccessiblePaste paste_struct; + + widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text)); + if (widget == NULL) + /* State is defunct */ + return; + + editable = GTK_EDITABLE (widget); + if (!gtk_editable_get_editable (editable)) + return; + paste_struct.label = EEL_EDITABLE_LABEL (widget); + paste_struct.position = position; + + g_object_ref (paste_struct.label); + gtk_clipboard_request_text (gtk_clipboard_get (GDK_NONE), + eel_editable_label_accessible_paste_received, &paste_struct); +} + +static void +atk_editable_text_interface_init (AtkEditableTextIface *iface) +{ + g_assert (iface != NULL); + + iface->set_text_contents = eel_editable_label_accessible_set_text_contents; + iface->insert_text = eel_editable_label_accessible_insert_text; + iface->copy_text = eel_editable_label_accessible_copy_text; + iface->cut_text = eel_editable_label_accessible_cut_text; + iface->delete_text = eel_editable_label_accessible_delete_text; + iface->paste_text = eel_editable_label_accessible_paste_text; +} + +static void +eel_editable_label_accessible_notify_insert (AtkObject *accessible) +{ + EelEditableLabelAccessiblePrivate *priv; + + priv = g_object_get_data (G_OBJECT (accessible), eel_editable_label_accessible_data); + if (priv->signal_name) + { + g_signal_emit_by_name (accessible, + priv->signal_name, + priv->position, + priv->length); + priv->signal_name = NULL; + } +} + +static gboolean +eel_editable_label_accessible_idle_notify_insert (gpointer data) +{ + eel_editable_label_accessible_notify_insert (data); + return FALSE; +} + +/* Note arg1 returns the character at the start of the insert. + * arg2 returns the number of characters inserted. + */ +static void +eel_editable_label_accessible_insert_text_cb (EelEditableLabel *label, + gchar *arg1, + gint arg2, + gpointer arg3) +{ + AtkObject *accessible; + EelEditableLabelAccessiblePrivate *priv; + gint *position = (gint *) arg3; + + accessible = gtk_widget_get_accessible (GTK_WIDGET (label)); + priv = g_object_get_data (G_OBJECT (accessible), eel_editable_label_accessible_data); + if (!priv->signal_name) + { + priv->signal_name = "text_changed::insert"; + priv->position = *position; + priv->length = arg2; + } + /* + * The signal will be emitted when the cursor position is updated. + * or in an idle handler if it not updated. + */ + g_idle_add (eel_editable_label_accessible_idle_notify_insert, accessible); +} + +/* Note arg1 returns the start of the delete range, arg2 returns the + * end of the delete range if multiple characters are deleted. + */ +static void +eel_editable_label_accessible_delete_text_cb (EelEditableLabel *label, + gint arg1, + gint arg2) +{ + AtkObject *accessible; + + accessible = gtk_widget_get_accessible (GTK_WIDGET (label)); + + /* + * Zero length text deleted so ignore + */ + if (arg2 - arg1 == 0) + return; + + g_signal_emit_by_name (accessible, "text_changed::delete", arg1, arg2 - arg1); +} + +static void +eel_editable_label_accessible_changed_cb (EelEditableLabel *label) +{ + AtkObject *accessible; + EelEditableLabelAccessiblePrivate *priv; + + accessible = gtk_widget_get_accessible (GTK_WIDGET (label)); + priv = g_object_get_data (G_OBJECT (accessible), eel_editable_label_accessible_data); + gail_text_util_text_setup (priv->textutil, eel_editable_label_get_text (label)); +} + +static gboolean +check_for_selection_change (AtkObject *accessible, + GtkWidget *widget) +{ + EelEditableLabelAccessiblePrivate *priv; + EelEditableLabel *label; + gboolean ret_val = FALSE; + + priv = g_object_get_data (G_OBJECT (accessible), eel_editable_label_accessible_data); + label = EEL_EDITABLE_LABEL (widget); + + if (label->selection_anchor != label->selection_end) + { + if (label->selection_anchor != priv->selection_anchor || + label->selection_end != priv->selection_end) + /* + * This check is here as this function can be called + * for notification of selection_end and selection_anchor. + * The values of selection_anchor and selection_end may be the same + * for both notifications and we only want to generate one + * text_selection_changed signal. + */ + ret_val = TRUE; + } + else + { + /* We had a selection */ + ret_val = (priv->selection_anchor != priv->selection_end); + } + priv->selection_anchor = label->selection_anchor; + priv->selection_end = label->selection_end; + + return ret_val; +} + +static void +eel_editable_label_accessible_notify_gtk (GObject *obj, + GParamSpec *pspec) +{ + GtkWidget *widget; + AtkObject *accessible; + EelEditableLabel *label; + + widget = GTK_WIDGET (obj); + label = EEL_EDITABLE_LABEL (widget); + accessible = gtk_widget_get_accessible (widget); + + if (strcmp (pspec->name, "cursor-position") == 0) + { + eel_editable_label_accessible_notify_insert (accessible); + if (check_for_selection_change (accessible, widget)) + g_signal_emit_by_name (accessible, "text_selection_changed"); + /* + * The label cursor position has moved so generate the signal. + */ + g_signal_emit_by_name (accessible, "text_caret_moved", + g_utf8_pointer_to_offset (label->text, + label->text + label->selection_anchor)); + } + else if (strcmp (pspec->name, "selection-bound") == 0) + { + eel_editable_label_accessible_notify_insert (accessible); + + if (check_for_selection_change (accessible, widget)) + g_signal_emit_by_name (accessible, "text_selection_changed"); + } +} + +static void +eel_editable_label_accessible_initialize (AtkObject *accessible, + gpointer widget) +{ + EelEditableLabelAccessiblePrivate *priv; + EelEditableLabel *label; + + a11y_parent_class->initialize (accessible, widget); + + label = EEL_EDITABLE_LABEL (widget); + priv = g_new0 (EelEditableLabelAccessiblePrivate, 1); + priv->textutil = gail_text_util_new (); + gail_text_util_text_setup (priv->textutil, eel_editable_label_get_text (EEL_EDITABLE_LABEL (widget))); + priv->selection_anchor = label->selection_anchor; + priv->selection_end = label->selection_end; + g_object_set_data (G_OBJECT (accessible), eel_editable_label_accessible_data, priv); + g_signal_connect (widget, "insert-text", + G_CALLBACK (eel_editable_label_accessible_insert_text_cb), NULL); + g_signal_connect (widget, "delete-text", + G_CALLBACK (eel_editable_label_accessible_delete_text_cb), NULL); + g_signal_connect (widget, "changed", + G_CALLBACK (eel_editable_label_accessible_changed_cb), NULL); + + g_signal_connect (widget, + "notify", + G_CALLBACK (eel_editable_label_accessible_notify_gtk), + NULL); + atk_object_set_role (accessible, ATK_ROLE_TEXT); +} + +static const gchar* eel_editable_label_accessible_get_name(AtkObject* accessible) +{ + if (accessible->name != NULL) + { + return accessible->name; + } + else + { + GtkWidget* widget; + + widget = gtk_accessible_get_widget(GTK_ACCESSIBLE(accessible)); + + if (widget == NULL) + { + /* State is defunct */ + return NULL; + } + + g_assert(EEL_IS_EDITABLE_LABEL(widget)); + + return eel_editable_label_get_text(EEL_EDITABLE_LABEL(widget)); + } +} + +static AtkStateSet* +eel_editable_label_accessible_ref_state_set (AtkObject *accessible) +{ + AtkStateSet *state_set; + GtkWidget *widget; + + state_set = a11y_parent_class->ref_state_set (accessible); + widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (accessible)); + + if (widget == NULL) + return state_set; + + atk_state_set_add_state (state_set, ATK_STATE_EDITABLE); + atk_state_set_add_state (state_set, ATK_STATE_MULTI_LINE); + return state_set; +} + +static void +eel_editable_label_accessible_finalize (GObject *object) +{ + EelEditableLabelAccessiblePrivate *priv; + + priv = g_object_get_data (object, eel_editable_label_accessible_data); + g_object_unref (priv->textutil); + g_free (priv); + G_OBJECT_CLASS (a11y_parent_class)->finalize (object); +} + +static void +eel_editable_label_accessible_class_init (AtkObjectClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + a11y_parent_class = g_type_class_peek_parent (klass); + + klass->initialize = eel_editable_label_accessible_initialize; + klass->get_name = eel_editable_label_accessible_get_name; + klass->ref_state_set = eel_editable_label_accessible_ref_state_set; + gobject_class->finalize = eel_editable_label_accessible_finalize; +} + +static AtkObject * +eel_editable_label_get_accessible (GtkWidget *widget) +{ + static GType type = 0; + AtkObject *accessible; + + if ((accessible = eel_accessibility_get_atk_object (widget))) + return accessible; + + if (!type) + { + const GInterfaceInfo atk_editable_text_info = + { + (GInterfaceInitFunc) atk_editable_text_interface_init, + (GInterfaceFinalizeFunc) NULL, + NULL + }; + const GInterfaceInfo atk_text_info = + { + (GInterfaceInitFunc) atk_text_interface_init, + (GInterfaceFinalizeFunc) NULL, + NULL + }; + + type = eel_accessibility_create_derived_type ("EelEditableLabelAccessible", + G_TYPE_FROM_INSTANCE (widget), + eel_editable_label_accessible_class_init); + + if (!type) + return NULL; + + g_type_add_interface_static (type, ATK_TYPE_EDITABLE_TEXT, &atk_editable_text_info); + g_type_add_interface_static (type, ATK_TYPE_TEXT, &atk_text_info); + } + + accessible = g_object_new (type, NULL); + + return eel_accessibility_set_atk_object_return (widget, accessible); +} + diff --git a/eel/eel-editable-label.h b/eel/eel-editable-label.h new file mode 100644 index 00000000..559ac6a1 --- /dev/null +++ b/eel/eel-editable-label.h @@ -0,0 +1,145 @@ +/* GTK - The GIMP Toolkit + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GTK+ Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GTK+ at ftp://ftp.gtk.org/pub/gtk/. + */ + +#ifndef __EEL_EDITABLE_LABEL_H__ +#define __EEL_EDITABLE_LABEL_H__ + + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define EEL_TYPE_EDITABLE_LABEL eel_editable_label_get_type() +#define EEL_EDITABLE_LABEL(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEL_TYPE_EDITABLE_LABEL, EelEditableLabel)) +#define EEL_EDITABLE_LABEL_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), EEL_TYPE_EDITABLE_LABEL, EelEditableLabelClass)) +#define EEL_IS_EDITABLE_LABEL(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEL_TYPE_EDITABLE_LABEL)) +#define EEL_IS_EDITABLE_LABEL_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), EEL_TYPE_EDITABLE_LABEL)) +#define EEL_EDITABLE_LABEL_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), EEL_TYPE_EDITABLE_LABEL, EelEditableLabelClass)) + + typedef struct _EelEditableLabel EelEditableLabel; + typedef struct _EelEditableLabelClass EelEditableLabelClass; + + typedef struct _EelEditableLabelSelectionInfo EelEditableLabelSelectionInfo; + + struct _EelEditableLabel + { + GtkMisc misc; + + /*< private >*/ + guint jtype : 2; + guint wrap : 1; + guint overwrite_mode : 1; + guint draw_outline : 1; + PangoWrapMode wrap_mode; + + gchar *text; + int text_size; /* allocated size, in bytes */ + int n_bytes; /* length in use (not including terminating zero), in bytes */ + + PangoLayout *layout; + guint layout_includes_preedit : 1; + + int selection_anchor; /* cursor pos, byte index */ + int selection_end; /* byte index */ + + GtkWidget *popup_menu; + + GtkIMContext *im_context; + gboolean need_im_reset; + int preedit_length; /* length of preedit string, in bytes */ + int preedit_cursor; /* offset of cursor within preedit string, in chars */ + + GdkGC *primary_cursor_gc; + GdkGC *secondary_cursor_gc; + + PangoFontDescription *font_desc; + }; + + struct _EelEditableLabelClass + { + GtkMiscClass parent_class; + + void (* move_cursor) (EelEditableLabel *label, + GtkMovementStep step, + gint count, + gboolean extend_selection); + void (* insert_at_cursor) (EelEditableLabel *label, + const gchar *str); + void (* delete_from_cursor) (EelEditableLabel *label, + GtkDeleteType type, + gint count); + void (* cut_clipboard) (EelEditableLabel *label); + void (* copy_clipboard) (EelEditableLabel *label); + void (* paste_clipboard) (EelEditableLabel *label); + void (* toggle_overwrite) (EelEditableLabel *label); + + /* Hook to customize right-click popup for selectable labels */ + void (* populate_popup) (EelEditableLabel *label, + GtkMenu *menu); + }; + + GType eel_editable_label_get_type (void) G_GNUC_CONST; + GtkWidget* eel_editable_label_new (const char *str); + void eel_editable_label_set_text (EelEditableLabel *label, + const char *str); + const gchar* eel_editable_label_get_text(EelEditableLabel* label); + void eel_editable_label_set_justify (EelEditableLabel *label, + GtkJustification jtype); + GtkJustification eel_editable_label_get_justify (EelEditableLabel *label); + void eel_editable_label_set_line_wrap (EelEditableLabel *label, + gboolean wrap); + void eel_editable_label_set_line_wrap_mode (EelEditableLabel *label, + PangoWrapMode mode); + gboolean eel_editable_label_get_line_wrap (EelEditableLabel *label); + void eel_editable_label_set_draw_outline (EelEditableLabel *label, + gboolean wrap); + void eel_editable_label_select_region (EelEditableLabel *label, + gint start_offset, + gint end_offset); + gboolean eel_editable_label_get_selection_bounds (EelEditableLabel *label, + gint *start, + gint *end); + PangoLayout * eel_editable_label_get_layout (EelEditableLabel *label); + void eel_editable_label_get_layout_offsets (EelEditableLabel *label, + gint *x, + gint *y); + PangoFontDescription *eel_editable_label_get_font_description (EelEditableLabel *label); + void eel_editable_label_set_font_description (EelEditableLabel *label, + const PangoFontDescription *desc); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + + +#endif /* __EEL_EDITABLE_LABEL_H__ */ diff --git a/eel/eel-enumeration.c b/eel/eel-enumeration.c new file mode 100644 index 00000000..b9cd3bc3 --- /dev/null +++ b/eel/eel-enumeration.c @@ -0,0 +1,555 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- + + eel-enumeration.c: Enumeration data structure. + + Copyright (C) 2000 Eazel, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this program; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Ramiro Estrugo +*/ + +#include +#include "eel-enumeration.h" + +#include "eel-debug.h" +#include "eel-glib-extensions.h" +#include "eel-lib-self-check-functions.h" +#include "eel-string.h" +#include "eel-i18n.h" + +static gboolean suppress_duplicate_registration_warning; + +struct EelEnumeration +{ + char *id; + GPtrArray *entries; /* array of EelEnumerationEntry */ +}; + +static EelEnumeration * +eel_enumeration_new (const char *id) +{ + EelEnumeration *enumeration; + + g_assert (id != NULL); + g_assert (id[0] != '\0'); + + enumeration = g_new0 (EelEnumeration, 1); + + enumeration->id = g_strdup (id); + enumeration->entries = g_ptr_array_new (); + + return enumeration; +} + +static void +free_entry (EelEnumerationEntry *entry) +{ + g_free (entry->name); + g_free (entry->description); + g_free (entry); +} + +static void +eel_enumeration_free (EelEnumeration *enumeration) +{ + if (enumeration == NULL) + { + return; + } + + g_free (enumeration->id); + g_ptr_array_foreach (enumeration->entries, (GFunc) free_entry, NULL); + g_ptr_array_free (enumeration->entries, TRUE); + g_free (enumeration); +} + +char * +eel_enumeration_get_id (const EelEnumeration *enumeration) +{ + g_return_val_if_fail (enumeration != NULL, NULL); + + return g_strdup (enumeration->id); +} + +guint +eel_enumeration_get_length (const EelEnumeration *enumeration) +{ + g_return_val_if_fail (enumeration != NULL, 0); + + return enumeration->entries->len; +} + +const EelEnumerationEntry * +eel_enumeration_get_nth_entry (const EelEnumeration *enumeration, + guint n) +{ + g_return_val_if_fail (enumeration != NULL, NULL); + g_return_val_if_fail (n < enumeration->entries->len, NULL); + + return (EelEnumerationEntry *) g_ptr_array_index (enumeration->entries, n); +} + +int +eel_enumeration_get_name_position (const EelEnumeration *enumeration, + const char *name) +{ + int i; + + g_return_val_if_fail (enumeration != NULL, -1); + g_return_val_if_fail (name != NULL, -1); + + for (i = 0; i < enumeration->entries->len; ++i) + { + EelEnumerationEntry *entry = enumeration->entries->pdata[i]; + if (strcmp (name, entry->name) == 0) + { + return i; + } + } + + return -1; +} + +gboolean +eel_enumeration_contains_name (const EelEnumeration *enumeration, + const char *name) +{ + g_return_val_if_fail (enumeration != NULL, FALSE); + g_return_val_if_fail (name != NULL, FALSE); + + return eel_enumeration_get_name_position (enumeration, name) != -1; +} + +guint +eel_enumeration_get_value_for_name (const EelEnumeration *enumeration, + const char *name) +{ + int i; + + g_return_val_if_fail (enumeration != NULL, 0); + g_return_val_if_fail (name != NULL, 0); + + for (i = 0; i < enumeration->entries->len; ++i) + { + EelEnumerationEntry *entry = enumeration->entries->pdata[i]; + if (strcmp (name, entry->name) == 0) + { + return entry->value; + } + } + + g_warning ("No name '%s' in enumeration '%s'", name, enumeration->id); + + return 0; +} + +const char * +eel_enumeration_get_name_for_value (const EelEnumeration *enumeration, + int value) +{ + int i; + + g_return_val_if_fail (enumeration != NULL, 0); + + for (i = 0; i < enumeration->entries->len; ++i) + { + EelEnumerationEntry *entry = enumeration->entries->pdata[i]; + if (value == entry->value) + { + return entry->name; + } + } + + g_warning ("No value '%d' in enumeration '%s'", value, enumeration->id); + + return NULL; +} + +char ** +eel_enumeration_get_names (const EelEnumeration *enumeration) +{ + GPtrArray *names; + int i; + + g_return_val_if_fail (enumeration != NULL, NULL); + + if (enumeration->entries->len == 0) + { + return NULL; + } + + names = g_ptr_array_sized_new (enumeration->entries->len + 1); + for (i = 0; i < enumeration->entries->len; ++i) + { + EelEnumerationEntry *entry = enumeration->entries->pdata[i]; + g_ptr_array_add (names, g_strdup (entry->name)); + } + g_ptr_array_add (names, NULL); + + return (char **) g_ptr_array_free (names, FALSE); +} + +static EelEnumeration * +eel_enumeration_new_from_tokens (const char *id, + const char *names, + const char *descriptions, + const char *values, + const char *delimiter) +{ + EelEnumeration *enumeration; + char **namev; + char **descriptionv; + char **valuev; + int length; + guint i; + + g_return_val_if_fail (id != NULL, NULL); + g_return_val_if_fail (id[0] != '\0', NULL); + g_return_val_if_fail (names != NULL, NULL); + g_return_val_if_fail (names[0] != '\0', NULL); + g_return_val_if_fail (values != NULL, NULL); + g_return_val_if_fail (values[0] != '\0', NULL); + g_return_val_if_fail (delimiter != NULL, NULL); + g_return_val_if_fail (delimiter[0] != '\0', NULL); + + enumeration = eel_enumeration_new (id); + + namev = g_strsplit (names, delimiter, -1); + valuev = g_strsplit (values, delimiter, -1); + + length = g_strv_length (namev); + if (g_strv_length (valuev) != length) + { + g_warning ("names and values have different lengths."); + g_strfreev (namev); + g_strfreev (valuev); + return NULL; + } + + descriptionv = descriptions != NULL ? + g_strsplit (descriptions, delimiter, -1) : NULL; + + if (descriptionv != NULL) + { + if (g_strv_length (descriptionv) != length) + { + g_warning ("names and descriptions have different lengths."); + g_strfreev (namev); + g_strfreev (descriptionv); + g_strfreev (valuev); + return NULL; + } + } + + for (i = 0; i < length; i++) + { + EelEnumerationEntry *entry; + int value; + + if (!eel_str_to_int (valuev[i], &value)) + { + g_warning ("Could not convert value '%d' to an integer. Using 0.", i); + value = 0; + } + + entry = g_new0 (EelEnumerationEntry, 1); + entry->name = namev[i]; + entry->description = descriptionv ? descriptionv[i] : NULL; + entry->value = value; + + g_ptr_array_add (enumeration->entries, entry); + } + + return enumeration; +} + +static EelEnumerationEntry * +dup_entry (const EelEnumerationEntry *entry) +{ + EelEnumerationEntry *res; + + res = g_new0 (EelEnumerationEntry, 1); + res->name = g_strdup (entry->name); + res->description = g_strdup (entry->description); + res->value = entry->value; + + return res; +} + +static EelEnumeration * +eel_enumeration_new_from_entries (const char *id, + const EelEnumerationEntry entries[], + guint n_entries) +{ + EelEnumeration *enumeration; + guint i; + + g_assert (id != NULL); + g_assert (id[0] != '\0'); + g_assert (entries != NULL); + + enumeration = eel_enumeration_new (id); + + for (i = 0; i < n_entries; i++) + { + g_ptr_array_add (enumeration->entries, dup_entry (&entries[i])); + } + + return enumeration; +} + +static GHashTable *enumeration_table = NULL; + +static void +enumeration_table_free (void) +{ + if (enumeration_table != NULL) + { + g_hash_table_destroy (enumeration_table); + enumeration_table = NULL; + } +} + +static GHashTable * +enumeration_table_get (void) +{ + if (enumeration_table != NULL) + { + return enumeration_table; + } + + enumeration_table = g_hash_table_new_full (g_str_hash, + g_str_equal, + (GDestroyNotify) g_free, + (GDestroyNotify) eel_enumeration_free); + + eel_debug_call_at_shutdown (enumeration_table_free); + + return enumeration_table; +} + +const EelEnumeration * +eel_enumeration_lookup (const char *id) +{ + GHashTable *table; + + g_return_val_if_fail (id != NULL, NULL); + g_return_val_if_fail (id[0] != '\0', NULL); + + table = enumeration_table_get (); + g_return_val_if_fail (table != NULL, NULL); + + return g_hash_table_lookup (table, id); +} + +void +eel_enumeration_register (const char *id, + const EelEnumerationEntry entries[], + guint n_entries) +{ + GHashTable *table; + EelEnumeration *enumeration; + + g_return_if_fail (id != NULL); + g_return_if_fail (id[0] != '\0'); + g_return_if_fail (entries != NULL); + + table = enumeration_table_get (); + g_return_if_fail (table != NULL); + + if (eel_enumeration_lookup (id) != NULL) + { + if (!suppress_duplicate_registration_warning) + { + g_warning ("Trying to register duplicate enumeration '%s'.", id); + } + + return; + } + + enumeration = eel_enumeration_new_from_entries (id, entries, n_entries); + + g_hash_table_insert (table, g_strdup (id), enumeration); +} + + +#if !defined (EEL_OMIT_SELF_CHECK) + +#define CHECK_ENUMERATION_ENTRY(enumeration, i, name, description, value) \ + EEL_CHECK_INTEGER_RESULT (eel_enumeration_get_name_position (enumeration, name), i); \ + EEL_CHECK_INTEGER_RESULT (eel_enumeration_get_value_for_name (enumeration, name), value); \ + EEL_CHECK_STRING_RESULT (g_strdup (eel_enumeration_get_name_for_value (enumeration, value)), name); + +static EelEnumerationEntry speed_tradeoff_enum_entries[] = +{ + { "always", "Always", 10 }, + { "local_only", "Local Files Only", 20 }, + { "never", "Never", 30 } +}; + +static EelEnumerationEntry standard_zoom_levels_enum_entries[] = +{ + { "smallest", "25%", 25 }, + { "smaller", "50%", 50 }, + { "small", "75%", 75 }, + { "standard", "100%", 100 }, + { "large", "150%", 150 }, + { "larger", "200%", 200 }, + { "largest", "400%", 400 } +}; + +static EelEnumerationEntry file_size_enum_entries[] = +{ + { "102400", "100 K", 102400 }, + { "512000", "500 K", 512000 }, + { "1048576", "1 MB", 1048576 }, + { "3145728", "3 MB", 3145728 }, + { "5242880", "5 MB", 5242880 }, + { "10485760", "10 MB", 10485760 }, + { "104857600", "100 MB", 104857600 } +}; + +#define CHECK_REGISTERED_ENUMERATION(enumname) \ +G_STMT_START { \ + const EelEnumeration *e; \ + int i; \ + e = eel_enumeration_lookup (#enumname); \ + g_return_if_fail (e != NULL); \ + for (i = 0; i < G_N_ELEMENTS (enumname##_enum_entries); i++) { \ + CHECK_ENUMERATION_ENTRY (e, \ + i, \ + enumname##_enum_entries[i].name, \ + enumname##_enum_entries[i].description, \ + enumname##_enum_entries[i].value); \ + } \ + EEL_CHECK_INTEGER_RESULT (eel_enumeration_get_length (e), i); \ +} G_STMT_END + +void +eel_self_check_enumeration (void) +{ + EelEnumeration *e; + char **names; + + /***/ + e = eel_enumeration_new_from_tokens ("id", + "single", + NULL, + "1", + ","); + + CHECK_ENUMERATION_ENTRY (e, 0, "single", "", 1); + EEL_CHECK_STRING_RESULT (eel_enumeration_get_id (e), "id"); + EEL_CHECK_INTEGER_RESULT (eel_enumeration_get_length (e), 1); + eel_enumeration_free (e); + + /***/ + e = eel_enumeration_new_from_tokens ("id", + "apple,orange,banana", + NULL, + "1,2,3", + ","); + + CHECK_ENUMERATION_ENTRY (e, 0, "apple", "", 1); + CHECK_ENUMERATION_ENTRY (e, 1, "orange", "", 2); + CHECK_ENUMERATION_ENTRY (e, 2, "banana", "", 3); + EEL_CHECK_STRING_RESULT (eel_enumeration_get_id (e), "id"); + EEL_CHECK_INTEGER_RESULT (eel_enumeration_get_length (e), 3); + eel_enumeration_free (e); + + /***/ + e = eel_enumeration_new_from_tokens ("id", + "foo", + NULL, + "666", + ","); + CHECK_ENUMERATION_ENTRY (e, 0, "foo", "", 666); + EEL_CHECK_STRING_RESULT (eel_enumeration_get_id (e), "id"); + EEL_CHECK_INTEGER_RESULT (eel_enumeration_get_length (e), 1); + eel_enumeration_free (e); + + /***/ + e = eel_enumeration_new_from_tokens ("id", + "one,two,---,three", + "One,Two,---,Three", + "1,2,0,3", + ","); + CHECK_ENUMERATION_ENTRY (e, 0, "one", "One", 1); + CHECK_ENUMERATION_ENTRY (e, 1, "two", "Two", 2); + CHECK_ENUMERATION_ENTRY (e, 2, "---", "---", 0); + CHECK_ENUMERATION_ENTRY (e, 3, "three", "Three", 3); + EEL_CHECK_INTEGER_RESULT (eel_enumeration_get_length (e), 4); + eel_enumeration_free (e); + + /***/ + e = eel_enumeration_new_from_tokens ("id", + "red,green,blue", + "Red Desc,Green Desc,Blue Desc", + "10,20,30", + ","); + + CHECK_ENUMERATION_ENTRY (e, 0, "red", "Red Desc", 10); + CHECK_ENUMERATION_ENTRY (e, 1, "green", "Green Desc", 20); + CHECK_ENUMERATION_ENTRY (e, 2, "blue", "Blue Desc", 30); + EEL_CHECK_STRING_RESULT (eel_enumeration_get_id (e), "id"); + EEL_CHECK_INTEGER_RESULT (eel_enumeration_get_length (e), 3); + + EEL_CHECK_BOOLEAN_RESULT (eel_enumeration_contains_name (e, "red"), TRUE); + EEL_CHECK_BOOLEAN_RESULT (eel_enumeration_contains_name (e, "green"), TRUE); + EEL_CHECK_BOOLEAN_RESULT (eel_enumeration_contains_name (e, "blue"), TRUE); + EEL_CHECK_BOOLEAN_RESULT (eel_enumeration_contains_name (e, "pink"), FALSE); + + eel_enumeration_free (e); + + /***/ + e = eel_enumeration_new_from_tokens ("id", + "red,foo:green,bar:blue,baz", + "Red,Desc:Green,Desc:Blue,Desc", + "10:20:30", + ":"); + + CHECK_ENUMERATION_ENTRY (e, 0, "red,foo", "Red,Desc", 10); + CHECK_ENUMERATION_ENTRY (e, 1, "green,bar", "Green,Desc", 20); + CHECK_ENUMERATION_ENTRY (e, 2, "blue,baz", "Blue,Desc", 30); + EEL_CHECK_STRING_RESULT (eel_enumeration_get_id (e), "id"); + EEL_CHECK_INTEGER_RESULT (eel_enumeration_get_length (e), 3); + EEL_CHECK_BOOLEAN_RESULT (eel_enumeration_contains_name (e, "black"), FALSE); + + names = eel_enumeration_get_names (e); + EEL_CHECK_INTEGER_RESULT (strcmp(names[2], "blue,baz"), 0); + g_strfreev (names); + eel_enumeration_free (e); + + /***/ + suppress_duplicate_registration_warning = TRUE; + eel_enumeration_register ("speed_tradeoff", + speed_tradeoff_enum_entries, + G_N_ELEMENTS (speed_tradeoff_enum_entries)); + eel_enumeration_register ("standard_zoom_levels", + standard_zoom_levels_enum_entries, + G_N_ELEMENTS (standard_zoom_levels_enum_entries)); + eel_enumeration_register ("file_size", + file_size_enum_entries, + G_N_ELEMENTS (file_size_enum_entries)); + suppress_duplicate_registration_warning = FALSE; + + CHECK_REGISTERED_ENUMERATION(speed_tradeoff); + CHECK_REGISTERED_ENUMERATION(standard_zoom_levels); + CHECK_REGISTERED_ENUMERATION(file_size); +} + +#endif /* !EEL_OMIT_SELF_CHECK */ diff --git a/eel/eel-enumeration.h b/eel/eel-enumeration.h new file mode 100644 index 00000000..8b08aaa0 --- /dev/null +++ b/eel/eel-enumeration.h @@ -0,0 +1,63 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- + + eel-enumeration.h: Enumeration data structure. + + Copyright (C) 2000 Eazel, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this program; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Ramiro Estrugo +*/ + +#ifndef EEL_ENUMERATION_H +#define EEL_ENUMERATION_H + +#include + +/* Opaque EelEnumeration declaration. */ +typedef struct EelEnumeration EelEnumeration; + +typedef struct +{ + char *name; + char *description; + guint value; +} EelEnumerationEntry; + +char * eel_enumeration_get_id (const EelEnumeration *enumeration); + +guint eel_enumeration_get_length (const EelEnumeration *enumeration); +const EelEnumerationEntry * +eel_enumeration_get_nth_entry (const EelEnumeration *enumeration, + guint n); +int eel_enumeration_get_name_position (const EelEnumeration *enumeration, + const char *name); +gboolean eel_enumeration_contains_name (const EelEnumeration *enumeration, + const char *name); +guint eel_enumeration_get_value_for_name (const EelEnumeration *enumeration, + const char *name); +const char * eel_enumeration_get_name_for_value (const EelEnumeration *enumeration, + int value); +char ** eel_enumeration_get_names (const EelEnumeration *enumeration); + +void eel_enumeration_register (const char *id, + const EelEnumerationEntry entries[], + guint n_entries); +const EelEnumeration * +eel_enumeration_lookup (const char *id); + +#endif /* EEL_ENUMERATION_H */ + diff --git a/eel/eel-gdk-extensions.c b/eel/eel-gdk-extensions.c new file mode 100644 index 00000000..acd85af5 --- /dev/null +++ b/eel/eel-gdk-extensions.c @@ -0,0 +1,971 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* eel-gdk-extensions.c: Graphics routines to augment what's in gdk. + + Copyright (C) 1999, 2000 Eazel, Inc. + + The Mate Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Mate Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Mate Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Authors: Darin Adler , + Pavel Cisler , + Ramiro Estrugo +*/ + +#include +#include "eel-gdk-extensions.h" + +#include "eel-glib-extensions.h" +#include "eel-lib-self-check-functions.h" +#include "eel-string.h" +#include +#include +#include +#include +#include +#include + +#define GRADIENT_BAND_SIZE 4 + +/** + * eel_gdk_rectangle_contains_rectangle: + * @outer: Rectangle possibly containing another rectangle. + * @inner: Rectangle that might be inside. + * + * Retun TRUE if inner rectangle is contained inside outer rectangle + */ +gboolean +eel_gdk_rectangle_contains_rectangle (GdkRectangle outer, GdkRectangle inner) +{ + return outer.x <= inner.x && outer.x + outer.width >= inner.x + inner.width + && outer.y <= inner.y && outer.y + outer.height >= inner.y + inner.height; +} + +/** + * eel_interpolate_color: + * @ratio: Place on line between colors to interpolate. + * @start_color: Color for one end. + * @end_color: Color for the other end + * @interpolated_color: Result. + * + * Compute a color between @start_color and @end_color in color space. + * Currently, the color space used is RGB, but a future version could + * instead do the interpolation in the best color space for expressing + * human perception. + */ +guint32 +eel_interpolate_color (gdouble ratio, + guint32 start_rgb, + guint32 end_rgb) +{ + guchar red, green, blue; + + g_return_val_if_fail (ratio >= 0.0, 0); + g_return_val_if_fail (ratio <= 1.0, 0); + + red = ((start_rgb >> 16) & 0xFF) * (1.0 - ratio) + ((end_rgb >> 16) & 0xFF) * ratio; + green = ((start_rgb >> 8) & 0xFF) * (1.0 - ratio) + ((end_rgb >> 8) & 0xFF) * ratio; + blue = (start_rgb & 0xFF) * (1.0 - ratio) + (end_rgb & 0xFF) * ratio; + return (((red << 8) | green) << 8) | blue; +} + +/** + * eel_gradient_new + * @start_color: Color for the top or left. + * @end_color: Color for the bottom or right. + * @is_horizontal: Direction of the gradient. + * + * Create a string that combines the start and end colors along + * with the direction of the gradient in a standard format. + */ +char * +eel_gradient_new (const char *start_color, + const char *end_color, + gboolean is_horizontal) +{ + /* Handle the special case where the start and end colors are identical. + Handle the special case where the end color is an empty string. + */ + if (eel_strcmp(start_color, end_color) == 0 || end_color == NULL || end_color[0] == '\0') + { + return g_strdup (start_color); + } + + /* Handle the special case where the start color is an empty string. */ + if (start_color == NULL || start_color[0] == '\0') + { + return g_strdup (end_color); + } + + /* Handle the general case. */ + return g_strconcat (start_color, "-", end_color, is_horizontal ? ":h" : NULL, NULL); +} + +/** + * eel_gradient_is_gradient + * @gradient_spec: A gradient spec. string. + * + * Return true if the spec. specifies a gradient instead of a solid color. + */ +gboolean +eel_gradient_is_gradient (const char *gradient_spec) +{ + return eel_strchr (gradient_spec, '-') != NULL; +} + +/** + * eel_gradient_is_horizontal + * @gradient_spec: A gradient spec. string. + * + * Return true if the spec. specifies a horizontal gradient. + */ +gboolean +eel_gradient_is_horizontal (const char *gradient_spec) +{ + size_t length; + + length = eel_strlen (gradient_spec); + return length >= 2 && gradient_spec[length - 2] == ':' && gradient_spec[length - 1] == 'h'; +} + +static char * +eel_gradient_strip_trailing_direction_if_any (const char *gradient_spec) +{ + size_t length; + + length = eel_strlen (gradient_spec); + if (length >= 2 && gradient_spec[length - 2] == ':' + && (gradient_spec[length - 1] == 'v' || gradient_spec[length - 1] == 'h')) + { + length -= 2; + } + + return g_strndup (gradient_spec, length); +} + +/* For parsing n-point gradients. Successive calls should pass the next_spec value + * set by the previous call as their first argument - to continue parsing where the + * previous call left off. + */ +char * +eel_gradient_parse_one_color_spec (const char *spec, int *percent, const char **next_spec) +{ + char *result; + const char *rgb_end_ptr; + const char *percent_ptr; + const char *separator_ptr; + + percent_ptr = eel_strchr (spec, '%'); + separator_ptr = eel_strchr (spec, '-'); + + if (percent_ptr != NULL && (separator_ptr == NULL || percent_ptr < separator_ptr)) + { + if (percent != NULL) + { + *percent = (int) strtol (percent_ptr + 1, NULL, 10); + } + rgb_end_ptr = percent_ptr; + } + else + { + if (percent != NULL) + { + *percent = 100; + } + rgb_end_ptr = separator_ptr; + } + + if (rgb_end_ptr != NULL) + { + result = g_strndup (spec, rgb_end_ptr - spec); + } + else + { + result = eel_gradient_strip_trailing_direction_if_any (spec); + } + + /* It's important not to use spec after setting *next_spec because it's + * likely that *next_spec == spec. + */ + if (next_spec != NULL) + { + *next_spec = (separator_ptr != NULL) ? separator_ptr + 1 : NULL; + } + + return result; +} + +/* FIXME bugzilla.eazel.com 5076: + * anyone using eel_gradient_get_start_color_spec or + * eel_gradient_get_end_color_spec is assuming the gradient + * is 2 colors which is questionable. + * + * Callers should be rewritten and these fns eliminated. + */ + +/** + * eel_gradient_get_start_color_spec + * @gradient_spec: A gradient spec. string. + * + * Return the start color. + * This may be the entire gradient_spec if it's a solid color. + */ +char * +eel_gradient_get_start_color_spec (const char *gradient_spec) +{ + return eel_gradient_parse_one_color_spec (gradient_spec, NULL, NULL); +} + +/** + * eel_gradient_get_end_color_spec + * @gradient_spec: A gradient spec. string. + * + * Return the end color. + * This may be the entire gradient_spec if it's a solid color. + */ +char * +eel_gradient_get_end_color_spec (const char *gradient_spec) +{ + char* color = NULL; + + do + { + g_free (color); + color = eel_gradient_parse_one_color_spec (gradient_spec, NULL, &gradient_spec); + } + while (gradient_spec != NULL); + + return color; +} + +/* Do the work shared by all the set_color_spec functions below. */ +static char * +eel_gradient_set_edge_color (const char *gradient_spec, + const char *edge_color, + gboolean is_horizontal, + gboolean change_end) +{ + char *opposite_color; + char *result; + + g_assert (edge_color != NULL); + + /* Get the color from the existing gradient spec. for the opposite + edge. This will parse away all the stuff we don't want from the + old gradient spec. + */ + opposite_color = change_end + ? eel_gradient_get_start_color_spec (gradient_spec) + : eel_gradient_get_end_color_spec (gradient_spec); + + /* Create a new gradient spec. The eel_gradient_new function handles + some special cases, so we don't have to bother with them here. + */ + result = eel_gradient_new (change_end ? opposite_color : edge_color, + change_end ? edge_color : opposite_color, + is_horizontal); + + g_free (opposite_color); + + return result; +} + +/** + * eel_gradient_set_left_color_spec + * @gradient_spec: A gradient spec. string. + * @left_color: Color spec. to replace left color with. + * + * Changes the left color to what's passed in. + * This creates a horizontal gradient. + */ +char * +eel_gradient_set_left_color_spec (const char *gradient_spec, + const char *left_color) +{ + g_return_val_if_fail (gradient_spec != NULL, NULL); + g_return_val_if_fail (left_color != NULL, NULL); + + return eel_gradient_set_edge_color (gradient_spec, left_color, TRUE, FALSE); +} + +/** + * eel_gradient_set_top_color_spec + * @gradient_spec: A gradient spec. string. + * @top_color: Color spec. to replace top color with. + * + * Changes the top color to what's passed in. + * This creates a vertical gradient. + */ +char * +eel_gradient_set_top_color_spec (const char *gradient_spec, + const char *top_color) +{ + g_return_val_if_fail (gradient_spec != NULL, NULL); + g_return_val_if_fail (top_color != NULL, NULL); + + return eel_gradient_set_edge_color (gradient_spec, top_color, FALSE, FALSE); +} + +/** + * eel_gradient_set_right_color_spec + * @gradient_spec: A gradient spec. string. + * @right_color: Color spec. to replace right color with. + * + * Changes the right color to what's passed in. + * This creates a horizontal gradient. + */ +char * +eel_gradient_set_right_color_spec (const char *gradient_spec, + const char *right_color) +{ + g_return_val_if_fail (gradient_spec != NULL, NULL); + g_return_val_if_fail (right_color != NULL, NULL); + + return eel_gradient_set_edge_color (gradient_spec, right_color, TRUE, TRUE); +} + +/** + * eel_gradient_set_bottom_color_spec + * @gradient_spec: A gradient spec. string. + * @bottom_color: Color spec. to replace bottom color with. + * + * Changes the bottom color to what's passed in. + * This creates a vertical gradient. + */ +char * +eel_gradient_set_bottom_color_spec (const char *gradient_spec, + const char *bottom_color) +{ + g_return_val_if_fail (gradient_spec != NULL, NULL); + g_return_val_if_fail (bottom_color != NULL, NULL); + + return eel_gradient_set_edge_color (gradient_spec, bottom_color, FALSE, TRUE); +} + +/** + * eel_gdk_color_parse_with_white_default + * @color_spec: A color spec, or NULL. + * @color: Pointer to place to put resulting color. + * + * The same as gdk_color_parse, except sets the color to white if + * the spec. can't be parsed, instead of returning a boolean flag. + */ +void +eel_gdk_color_parse_with_white_default (const char *color_spec, + GdkColor *color) +{ + gboolean got_color; + + g_return_if_fail (color != NULL); + + got_color = FALSE; + if (color_spec != NULL) + { + if (gdk_color_parse (color_spec, color)) + { + got_color = TRUE; + } + } + + if (!got_color) + { + color->red = 0xFFFF; + color->green = 0xFFFF; + color->blue = 0xFFFF; + } +} + +/** + * eel_parse_rgb_with_white_default + * @color_spec: A color spec, or NULL. + * Returns: An rgb value. + * + * The same as gdk_color_parse, except sets the color to white if + * the spec. can't be parsed instead of returning a boolean flag + * and returns a guint32 rgb value instead of a GdkColor. + */ +guint32 +eel_parse_rgb_with_white_default (const char *color_spec) +{ + GdkColor color; + + eel_gdk_color_parse_with_white_default (color_spec, &color); + return ((color.red << 8) & EEL_RGB_COLOR_RED) + | (color.green & EEL_RGB_COLOR_GREEN) + | ((color.blue >> 8) & EEL_RGB_COLOR_BLUE); +} + +guint32 +eel_rgb16_to_rgb (gushort r, gushort g, gushort b) +{ + guint32 result; + + result = (0xff0000 | (r & 0xff00)); + result <<= 8; + result |= ((g & 0xff00) | (b >> 8)); + + return result; +} + +guint32 +eel_rgb8_to_rgb (guchar r, guchar g, guchar b) +{ + return eel_rgb16_to_rgb (r << 8, g << 8, b << 8); +} + +/** + * eel_gdk_color_to_rgb + * @color: A GdkColor style color. + * Returns: An rgb value. + * + * Converts from a GdkColor stlye color to a gdk_rgb one. + * Alpha gets set to fully opaque + */ +guint32 +eel_gdk_color_to_rgb (const GdkColor *color) +{ + return eel_rgb16_to_rgb (color->red, color->green, color->blue); +} + +/** + * eel_gdk_rgb_to_color + * @color: a gdk_rgb style value. + * + * Converts from a gdk_rgb value style to a GdkColor one. + * The gdk_rgb color alpha channel is ignored. + * + * Return value: A GdkColor structure version of the given RGB color. + */ +GdkColor +eel_gdk_rgb_to_color (guint32 color) +{ + GdkColor result; + + result.red = ((color >> 16) & 0xFF) * 0x101; + result.green = ((color >> 8) & 0xFF) * 0x101; + result.blue = (color & 0xff) * 0x101; + result.pixel = 0; + + return result; +} + +/** + * eel_gdk_rgb_to_color_spec + * @color: a gdk_rgb style value. + * + * Converts from a gdk_rgb value style to a string color spec. + * The gdk_rgb color alpha channel is ignored. + * + * Return value: a newly allocated color spec. + */ +char * +eel_gdk_rgb_to_color_spec (const guint32 color) +{ + return g_strdup_printf ("#%06X", (guint) (color & 0xFFFFFF)); +} + +static guint32 +eel_shift_color_component (guchar component, float shift_by) +{ + guint32 result; + if (shift_by > 1.0) + { + result = component * (2 - shift_by); + } + else + { + result = 0xff - shift_by * (0xff - component); + } + + return result & 0xff; +} + +/** + * eel_rgb_shift_color + * @color: A color. + * @shift_by: darken or lighten factor. + * Returns: An darkened or lightened rgb value. + * + * Darkens (@shift_by > 1) or lightens (@shift_by < 1) + * @color. + */ +guint32 +eel_rgb_shift_color (guint32 color, float shift_by) +{ + guint32 result; + + /* shift red by shift_by */ + result = eel_shift_color_component((color & 0x00ff0000) >> 16, shift_by); + result <<= 8; + /* shift green by shift_by */ + result |= eel_shift_color_component((color & 0x0000ff00) >> 8, shift_by); + result <<= 8; + /* shift blue by shift_by */ + result |= eel_shift_color_component((color & 0x000000ff), shift_by); + + /* alpha doesn't change */ + result |= (0xff000000 & color); + + return result; +} + +/** + * eel_gdk_color_is_dark: + * + * Return true if the given color is `dark' + */ +gboolean +eel_gdk_color_is_dark (GdkColor *color) +{ + int intensity; + + intensity = (((color->red >> 8) * 77) + + ((color->green >> 8) * 150) + + ((color->blue >> 8) * 28)) >> 8; + + return intensity < 128; +} + +/** + * eel_stipple_bitmap_for_screen: + * + * Get pointer to 50% stippled bitmap suitable for use + * on @screen. This is a global object; do not free. + */ +GdkBitmap * +eel_stipple_bitmap_for_screen (GdkScreen *screen) +{ + static char stipple_bits[] = { 0x02, 0x01 }; + static GPtrArray *stipples = NULL; + int screen_num, n_screens, i; + + if (stipples == NULL) + { + n_screens = gdk_display_get_n_screens ( + gdk_screen_get_display (screen)); + stipples = g_ptr_array_sized_new (n_screens); + + for (i = 0; i < n_screens; i++) + { + g_ptr_array_index (stipples, i) = NULL; + } + } + + screen_num = gdk_screen_get_number (screen); + + if (g_ptr_array_index (stipples, screen_num) == NULL) + { + g_ptr_array_index (stipples, screen_num) = + gdk_bitmap_create_from_data ( + gdk_screen_get_root_window (screen), + stipple_bits, 2, 2); + } + + return g_ptr_array_index (stipples, screen_num); +} + +/** + * eel_stipple_bitmap: + * + * Get pointer to 50% stippled bitmap suitable for use + * on the default screen. This is a global object; do + * not free. + * + * This method is not multiscreen safe. Do not use it. + */ +GdkBitmap * +eel_stipple_bitmap (void) +{ + return eel_stipple_bitmap_for_screen (gdk_screen_get_default ()); +} + +/** + * eel_gdk_window_bring_to_front: + * + * Raise window and give it focus. + */ +void +eel_gdk_window_bring_to_front (GdkWindow *window) +{ + /* This takes care of un-iconifying the window and + * raising it if needed. + */ + gdk_window_show (window); + + /* If the window was already showing, it would not have + * the focus at this point. Do a little X trickery to + * ensure it is focused. + */ + eel_gdk_window_focus (window, GDK_CURRENT_TIME); +} + +void +eel_gdk_window_focus (GdkWindow *window, guint32 timestamp) +{ + gdk_error_trap_push (); + XSetInputFocus (GDK_DISPLAY (), + GDK_WINDOW_XWINDOW (window), + RevertToParent, + timestamp); + gdk_flush(); + gdk_error_trap_pop (); +} + +void +eel_gdk_window_set_wm_protocols (GdkWindow *window, + GdkAtom *protocols, + int nprotocols) +{ + Atom *atoms; + int i; + + atoms = g_new (Atom, nprotocols); + for (i = 0; i < nprotocols; i++) + { + atoms[i] = gdk_x11_atom_to_xatom (protocols[i]); + } + + XSetWMProtocols (GDK_WINDOW_XDISPLAY (window), + GDK_WINDOW_XWINDOW (window), + atoms, nprotocols); + + g_free (atoms); +} + +/** + * eel_gdk_window_set_wm_hints_input: + * + * Set the WM_HINTS.input flag to the passed in value + */ +void +eel_gdk_window_set_wm_hints_input (GdkWindow *window, gboolean status) +{ + Display *dpy; + Window id; + XWMHints *wm_hints; + + g_return_if_fail (window != NULL); + + dpy = GDK_WINDOW_XDISPLAY (window); + id = GDK_WINDOW_XWINDOW (window); + + wm_hints = XGetWMHints (dpy, id); + if (wm_hints == 0) + { + wm_hints = XAllocWMHints (); + } + + wm_hints->flags |= InputHint; + wm_hints->input = (status == FALSE) ? False : True; + + XSetWMHints (dpy, id, wm_hints); + XFree (wm_hints); +} + +void +eel_gdk_window_set_invisible_cursor (GdkWindow *window) +{ + GdkBitmap *empty_bitmap; + GdkCursor *cursor; + GdkColor useless; + char invisible_cursor_bits[] = { 0x0 }; + + useless.red = useless.green = useless.blue = 0; + useless.pixel = 0; + + empty_bitmap = gdk_bitmap_create_from_data (window, + invisible_cursor_bits, + 1, 1); + + cursor = gdk_cursor_new_from_pixmap (empty_bitmap, + empty_bitmap, + &useless, + &useless, 0, 0); + + gdk_window_set_cursor (window, cursor); + + gdk_cursor_unref (cursor); + + g_object_unref (empty_bitmap); +} + +EelGdkGeometryFlags +eel_gdk_parse_geometry (const char *string, int *x_return, int *y_return, + guint *width_return, guint *height_return) +{ + int x11_flags; + EelGdkGeometryFlags gdk_flags; + + g_return_val_if_fail (string != NULL, EEL_GDK_NO_VALUE); + g_return_val_if_fail (x_return != NULL, EEL_GDK_NO_VALUE); + g_return_val_if_fail (y_return != NULL, EEL_GDK_NO_VALUE); + g_return_val_if_fail (width_return != NULL, EEL_GDK_NO_VALUE); + g_return_val_if_fail (height_return != NULL, EEL_GDK_NO_VALUE); + + x11_flags = XParseGeometry (string, x_return, y_return, + width_return, height_return); + + gdk_flags = EEL_GDK_NO_VALUE; + if (x11_flags & XValue) + { + gdk_flags |= EEL_GDK_X_VALUE; + } + if (x11_flags & YValue) + { + gdk_flags |= EEL_GDK_Y_VALUE; + } + if (x11_flags & WidthValue) + { + gdk_flags |= EEL_GDK_WIDTH_VALUE; + } + if (x11_flags & HeightValue) + { + gdk_flags |= EEL_GDK_HEIGHT_VALUE; + } + if (x11_flags & XNegative) + { + gdk_flags |= EEL_GDK_X_NEGATIVE; + } + if (x11_flags & YNegative) + { + gdk_flags |= EEL_GDK_Y_NEGATIVE; + } + + return gdk_flags; +} + +void +eel_gdk_draw_layout_with_drop_shadow (GdkDrawable *drawable, + GdkGC *gc, + GdkColor *text_color, + GdkColor *shadow_color, + int x, + int y, + PangoLayout *layout) +{ + gdk_draw_layout_with_colors (drawable, gc, + x+1, y+1, + layout, + shadow_color, NULL); + + gdk_draw_layout_with_colors (drawable, gc, + x, y, + layout, + text_color, NULL); +} + +#if ! defined (EEL_OMIT_SELF_CHECK) + +static char * +eel_gdk_color_as_hex_string (GdkColor color) +{ + return g_strdup_printf ("%04X%04X%04X", + color.red, color.green, color.blue); +} + +static char * +eel_self_check_parse (const char *color_spec) +{ + GdkColor color; + + eel_gdk_color_parse_with_white_default (color_spec, &color); + return eel_gdk_color_as_hex_string (color); +} + +static char * +eel_self_check_gdk_rgb_to_color (guint32 color) +{ + GdkColor result; + + result = eel_gdk_rgb_to_color (color); + + return eel_gdk_color_as_hex_string (result); +} + +void +eel_self_check_gdk_extensions (void) +{ + /* eel_interpolate_color */ + EEL_CHECK_INTEGER_RESULT (eel_interpolate_color (0.0, 0, 0), 0); + EEL_CHECK_INTEGER_RESULT (eel_interpolate_color (0.0, 0, 0xFFFFFF), 0); + EEL_CHECK_INTEGER_RESULT (eel_interpolate_color (0.5, 0, 0xFFFFFF), 0x7F7F7F); + EEL_CHECK_INTEGER_RESULT (eel_interpolate_color (1.0, 0, 0xFFFFFF), 0xFFFFFF); + + /* eel_gradient_new */ + EEL_CHECK_STRING_RESULT (eel_gradient_new ("", "", FALSE), ""); + EEL_CHECK_STRING_RESULT (eel_gradient_new ("a", "b", FALSE), "a-b"); + EEL_CHECK_STRING_RESULT (eel_gradient_new ("a", "b", TRUE), "a-b:h"); + EEL_CHECK_STRING_RESULT (eel_gradient_new ("a", "a", FALSE), "a"); + EEL_CHECK_STRING_RESULT (eel_gradient_new ("a", "a", TRUE), "a"); + + /* eel_gradient_is_gradient */ + EEL_CHECK_BOOLEAN_RESULT (eel_gradient_is_gradient (""), FALSE); + EEL_CHECK_BOOLEAN_RESULT (eel_gradient_is_gradient ("-"), TRUE); + EEL_CHECK_BOOLEAN_RESULT (eel_gradient_is_gradient ("a"), FALSE); + EEL_CHECK_BOOLEAN_RESULT (eel_gradient_is_gradient ("a-b"), TRUE); + EEL_CHECK_BOOLEAN_RESULT (eel_gradient_is_gradient ("a-b:h"), TRUE); + + /* eel_gradient_get_start_color_spec */ + EEL_CHECK_STRING_RESULT (eel_gradient_get_start_color_spec (""), ""); + EEL_CHECK_STRING_RESULT (eel_gradient_get_start_color_spec ("-"), ""); + EEL_CHECK_STRING_RESULT (eel_gradient_get_start_color_spec ("a"), "a"); + EEL_CHECK_STRING_RESULT (eel_gradient_get_start_color_spec ("a-b"), "a"); + EEL_CHECK_STRING_RESULT (eel_gradient_get_start_color_spec ("a-"), "a"); + EEL_CHECK_STRING_RESULT (eel_gradient_get_start_color_spec ("-b"), ""); + EEL_CHECK_STRING_RESULT (eel_gradient_get_start_color_spec ("a:h"), "a"); + EEL_CHECK_STRING_RESULT (eel_gradient_get_start_color_spec ("a:v"), "a"); + EEL_CHECK_STRING_RESULT (eel_gradient_get_start_color_spec ("a:c"), "a:c"); + EEL_CHECK_STRING_RESULT (eel_gradient_get_start_color_spec ("a:-b"), "a:"); + EEL_CHECK_STRING_RESULT (eel_gradient_get_start_color_spec ("a:-b:v"), "a:"); + + /* eel_gradient_get_end_color_spec */ + EEL_CHECK_STRING_RESULT (eel_gradient_get_end_color_spec (""), ""); + EEL_CHECK_STRING_RESULT (eel_gradient_get_end_color_spec ("-"), ""); + EEL_CHECK_STRING_RESULT (eel_gradient_get_end_color_spec ("a"), "a"); + EEL_CHECK_STRING_RESULT (eel_gradient_get_end_color_spec ("a-b"), "b"); + EEL_CHECK_STRING_RESULT (eel_gradient_get_end_color_spec ("a-"), ""); + EEL_CHECK_STRING_RESULT (eel_gradient_get_end_color_spec ("-b"), "b"); + EEL_CHECK_STRING_RESULT (eel_gradient_get_end_color_spec ("a:h"), "a"); + EEL_CHECK_STRING_RESULT (eel_gradient_get_end_color_spec ("a:v"), "a"); + EEL_CHECK_STRING_RESULT (eel_gradient_get_end_color_spec ("a:c"), "a:c"); + EEL_CHECK_STRING_RESULT (eel_gradient_get_end_color_spec ("a:-b"), "b"); + EEL_CHECK_STRING_RESULT (eel_gradient_get_end_color_spec ("a:-b:v"), "b"); + + /* eel_gradient_set_left_color_spec */ + EEL_CHECK_STRING_RESULT (eel_gradient_set_left_color_spec ("", ""), ""); + EEL_CHECK_STRING_RESULT (eel_gradient_set_left_color_spec ("", "a"), "a"); + EEL_CHECK_STRING_RESULT (eel_gradient_set_left_color_spec ("a", ""), "a"); + EEL_CHECK_STRING_RESULT (eel_gradient_set_left_color_spec ("a", "a"), "a"); + EEL_CHECK_STRING_RESULT (eel_gradient_set_left_color_spec ("a", "b"), "b-a:h"); + EEL_CHECK_STRING_RESULT (eel_gradient_set_left_color_spec ("a-c:v", "b"), "b-c:h"); + EEL_CHECK_STRING_RESULT (eel_gradient_set_left_color_spec ("a-c:v", "c"), "c"); + EEL_CHECK_STRING_RESULT (eel_gradient_set_left_color_spec ("a:-b:v", "d"), "d-b:h"); + + /* eel_gradient_set_top_color_spec */ + EEL_CHECK_STRING_RESULT (eel_gradient_set_top_color_spec ("", ""), ""); + EEL_CHECK_STRING_RESULT (eel_gradient_set_top_color_spec ("", "a"), "a"); + EEL_CHECK_STRING_RESULT (eel_gradient_set_top_color_spec ("a", ""), "a"); + EEL_CHECK_STRING_RESULT (eel_gradient_set_top_color_spec ("a", "a"), "a"); + EEL_CHECK_STRING_RESULT (eel_gradient_set_top_color_spec ("a", "b"), "b-a"); + EEL_CHECK_STRING_RESULT (eel_gradient_set_top_color_spec ("a-c:v", "b"), "b-c"); + EEL_CHECK_STRING_RESULT (eel_gradient_set_top_color_spec ("a-c:v", "c"), "c"); + EEL_CHECK_STRING_RESULT (eel_gradient_set_top_color_spec ("a:-b:h", "d"), "d-b"); + + /* eel_gradient_set_right_color_spec */ + EEL_CHECK_STRING_RESULT (eel_gradient_set_right_color_spec ("", ""), ""); + EEL_CHECK_STRING_RESULT (eel_gradient_set_right_color_spec ("", "a"), "a"); + EEL_CHECK_STRING_RESULT (eel_gradient_set_right_color_spec ("a", ""), "a"); + EEL_CHECK_STRING_RESULT (eel_gradient_set_right_color_spec ("a", "a"), "a"); + EEL_CHECK_STRING_RESULT (eel_gradient_set_right_color_spec ("a", "b"), "a-b:h"); + EEL_CHECK_STRING_RESULT (eel_gradient_set_right_color_spec ("a-c:v", "b"), "a-b:h"); + EEL_CHECK_STRING_RESULT (eel_gradient_set_right_color_spec ("a-c:v", "c"), "a-c:h"); + EEL_CHECK_STRING_RESULT (eel_gradient_set_right_color_spec ("a:-b:v", "d"), "a:-d:h"); + + /* eel_gradient_set_bottom_color_spec */ + EEL_CHECK_STRING_RESULT (eel_gradient_set_bottom_color_spec ("", ""), ""); + EEL_CHECK_STRING_RESULT (eel_gradient_set_bottom_color_spec ("", "a"), "a"); + EEL_CHECK_STRING_RESULT (eel_gradient_set_bottom_color_spec ("a", ""), "a"); + EEL_CHECK_STRING_RESULT (eel_gradient_set_bottom_color_spec ("a", "a"), "a"); + EEL_CHECK_STRING_RESULT (eel_gradient_set_bottom_color_spec ("a", "b"), "a-b"); + EEL_CHECK_STRING_RESULT (eel_gradient_set_bottom_color_spec ("a-c:v", "b"), "a-b"); + EEL_CHECK_STRING_RESULT (eel_gradient_set_bottom_color_spec ("a-c:v", "c"), "a-c"); + EEL_CHECK_STRING_RESULT (eel_gradient_set_bottom_color_spec ("a:-b:h", "d"), "a:-d"); + + /* eel_gdk_color_parse_with_white_default */ + EEL_CHECK_STRING_RESULT (eel_self_check_parse (""), "FFFFFFFFFFFF"); + EEL_CHECK_STRING_RESULT (eel_self_check_parse ("a"), "FFFFFFFFFFFF"); + EEL_CHECK_STRING_RESULT (eel_self_check_parse ("white"), "FFFFFFFFFFFF"); + EEL_CHECK_STRING_RESULT (eel_self_check_parse ("black"), "000000000000"); + EEL_CHECK_STRING_RESULT (eel_self_check_parse ("red"), "FFFF00000000"); + EEL_CHECK_STRING_RESULT (eel_self_check_parse ("#012345"), "010123234545"); + /* EEL_CHECK_STRING_RESULT (eel_self_check_parse ("rgb:0123/4567/89AB"), "#014589"); */ + + /* eel_gdk_rgb_to_color */ + EEL_CHECK_STRING_RESULT (eel_self_check_gdk_rgb_to_color (EEL_RGB_COLOR_RED), "FFFF00000000"); + EEL_CHECK_STRING_RESULT (eel_self_check_gdk_rgb_to_color (EEL_RGB_COLOR_BLACK), "000000000000"); + EEL_CHECK_STRING_RESULT (eel_self_check_gdk_rgb_to_color (EEL_RGB_COLOR_WHITE), "FFFFFFFFFFFF"); + EEL_CHECK_STRING_RESULT (eel_self_check_gdk_rgb_to_color (EEL_RGB_COLOR_PACK (0x01, 0x23, 0x45)), "010123234545"); + + /* EEL_RGBA_COLOR_PACK */ + EEL_CHECK_INTEGER_RESULT (EEL_RGBA_COLOR_PACK (0xFF, 0x00, 0x00, 00), EEL_RGB_COLOR_RED); + EEL_CHECK_INTEGER_RESULT (EEL_RGBA_COLOR_PACK (0x00, 0xFF, 0x00, 00), EEL_RGB_COLOR_GREEN); + EEL_CHECK_INTEGER_RESULT (EEL_RGBA_COLOR_PACK (0x00, 0x00, 0xFF, 00), EEL_RGB_COLOR_BLUE); + EEL_CHECK_INTEGER_RESULT (EEL_RGBA_COLOR_PACK (0xFF, 0xFF, 0xFF, 00), EEL_RGB_COLOR_WHITE); + EEL_CHECK_INTEGER_RESULT (EEL_RGBA_COLOR_PACK (0x00, 0x00, 0x00, 00), EEL_RGB_COLOR_BLACK); + + EEL_CHECK_INTEGER_RESULT (EEL_RGBA_COLOR_PACK (0xFF, 0x00, 0x00, 0xFF), EEL_RGBA_COLOR_OPAQUE_RED); + EEL_CHECK_INTEGER_RESULT (EEL_RGBA_COLOR_PACK (0x00, 0xFF, 0x00, 0xFF), EEL_RGBA_COLOR_OPAQUE_GREEN); + EEL_CHECK_INTEGER_RESULT (EEL_RGBA_COLOR_PACK (0x00, 0x00, 0xFF, 0xFF), EEL_RGBA_COLOR_OPAQUE_BLUE); + EEL_CHECK_INTEGER_RESULT (EEL_RGBA_COLOR_PACK (0xFF, 0xFF, 0xFF, 0xFF), EEL_RGBA_COLOR_OPAQUE_WHITE); + EEL_CHECK_INTEGER_RESULT (EEL_RGBA_COLOR_PACK (0x00, 0x00, 0x00, 0xFF), EEL_RGBA_COLOR_OPAQUE_BLACK); + + /* EEL_RGB_COLOR_PACK */ + EEL_CHECK_INTEGER_RESULT (EEL_RGB_COLOR_PACK (0xFF, 0x00, 0x00), EEL_RGBA_COLOR_OPAQUE_RED); + EEL_CHECK_INTEGER_RESULT (EEL_RGB_COLOR_PACK (0x00, 0xFF, 0x00), EEL_RGBA_COLOR_OPAQUE_GREEN); + EEL_CHECK_INTEGER_RESULT (EEL_RGB_COLOR_PACK (0x00, 0x00, 0xFF), EEL_RGBA_COLOR_OPAQUE_BLUE); + EEL_CHECK_INTEGER_RESULT (EEL_RGB_COLOR_PACK (0xFF, 0xFF, 0xFF), EEL_RGBA_COLOR_OPAQUE_WHITE); + EEL_CHECK_INTEGER_RESULT (EEL_RGB_COLOR_PACK (0x00, 0x00, 0x00), EEL_RGBA_COLOR_OPAQUE_BLACK); + + /* EEL_RGBA_COLOR_GET_R */ + EEL_CHECK_INTEGER_RESULT (EEL_RGBA_COLOR_GET_R (EEL_RGBA_COLOR_OPAQUE_RED), 0xFF); + EEL_CHECK_INTEGER_RESULT (EEL_RGBA_COLOR_GET_R (EEL_RGBA_COLOR_OPAQUE_GREEN), 0x00); + EEL_CHECK_INTEGER_RESULT (EEL_RGBA_COLOR_GET_R (EEL_RGBA_COLOR_OPAQUE_BLUE), 0x00); + EEL_CHECK_INTEGER_RESULT (EEL_RGBA_COLOR_GET_R (EEL_RGBA_COLOR_OPAQUE_WHITE), 0xFF); + EEL_CHECK_INTEGER_RESULT (EEL_RGBA_COLOR_GET_R (EEL_RGBA_COLOR_OPAQUE_BLACK), 0x00); + EEL_CHECK_INTEGER_RESULT (EEL_RGBA_COLOR_GET_R (EEL_RGB_COLOR_RED), 0xFF); + EEL_CHECK_INTEGER_RESULT (EEL_RGBA_COLOR_GET_R (EEL_RGB_COLOR_GREEN), 0x00); + EEL_CHECK_INTEGER_RESULT (EEL_RGBA_COLOR_GET_R (EEL_RGB_COLOR_BLUE), 0x00); + EEL_CHECK_INTEGER_RESULT (EEL_RGBA_COLOR_GET_R (EEL_RGB_COLOR_WHITE), 0xFF); + EEL_CHECK_INTEGER_RESULT (EEL_RGBA_COLOR_GET_R (EEL_RGB_COLOR_BLACK), 0x00); + + /* EEL_RGBA_COLOR_GET_G */ + EEL_CHECK_INTEGER_RESULT (EEL_RGBA_COLOR_GET_G (EEL_RGBA_COLOR_OPAQUE_RED), 0x00); + EEL_CHECK_INTEGER_RESULT (EEL_RGBA_COLOR_GET_G (EEL_RGBA_COLOR_OPAQUE_GREEN), 0xFF); + EEL_CHECK_INTEGER_RESULT (EEL_RGBA_COLOR_GET_G (EEL_RGBA_COLOR_OPAQUE_BLUE), 0x00); + EEL_CHECK_INTEGER_RESULT (EEL_RGBA_COLOR_GET_G (EEL_RGBA_COLOR_OPAQUE_WHITE), 0xFF); + EEL_CHECK_INTEGER_RESULT (EEL_RGBA_COLOR_GET_G (EEL_RGBA_COLOR_OPAQUE_BLACK), 0x00); + EEL_CHECK_INTEGER_RESULT (EEL_RGBA_COLOR_GET_G (EEL_RGB_COLOR_RED), 0x00); + EEL_CHECK_INTEGER_RESULT (EEL_RGBA_COLOR_GET_G (EEL_RGB_COLOR_GREEN), 0xFF); + EEL_CHECK_INTEGER_RESULT (EEL_RGBA_COLOR_GET_G (EEL_RGB_COLOR_BLUE), 0x00); + EEL_CHECK_INTEGER_RESULT (EEL_RGBA_COLOR_GET_G (EEL_RGB_COLOR_WHITE), 0xFF); + EEL_CHECK_INTEGER_RESULT (EEL_RGBA_COLOR_GET_G (EEL_RGB_COLOR_BLACK), 0x00); + + /* EEL_RGBA_COLOR_GET_B */ + EEL_CHECK_INTEGER_RESULT (EEL_RGBA_COLOR_GET_B (EEL_RGBA_COLOR_OPAQUE_RED), 0x00); + EEL_CHECK_INTEGER_RESULT (EEL_RGBA_COLOR_GET_B (EEL_RGBA_COLOR_OPAQUE_GREEN), 0x00); + EEL_CHECK_INTEGER_RESULT (EEL_RGBA_COLOR_GET_B (EEL_RGBA_COLOR_OPAQUE_BLUE), 0xFF); + EEL_CHECK_INTEGER_RESULT (EEL_RGBA_COLOR_GET_B (EEL_RGBA_COLOR_OPAQUE_WHITE), 0xFF); + EEL_CHECK_INTEGER_RESULT (EEL_RGBA_COLOR_GET_B (EEL_RGBA_COLOR_OPAQUE_BLACK), 0x00); + EEL_CHECK_INTEGER_RESULT (EEL_RGBA_COLOR_GET_B (EEL_RGB_COLOR_RED), 0x00); + EEL_CHECK_INTEGER_RESULT (EEL_RGBA_COLOR_GET_B (EEL_RGB_COLOR_GREEN), 0x00); + EEL_CHECK_INTEGER_RESULT (EEL_RGBA_COLOR_GET_B (EEL_RGB_COLOR_BLUE), 0xFF); + EEL_CHECK_INTEGER_RESULT (EEL_RGBA_COLOR_GET_B (EEL_RGB_COLOR_WHITE), 0xFF); + EEL_CHECK_INTEGER_RESULT (EEL_RGBA_COLOR_GET_B (EEL_RGB_COLOR_BLACK), 0x00); + + /* EEL_RGBA_COLOR_GET_A */ + EEL_CHECK_INTEGER_RESULT (EEL_RGBA_COLOR_GET_A (EEL_RGBA_COLOR_OPAQUE_RED), 0xFF); + EEL_CHECK_INTEGER_RESULT (EEL_RGBA_COLOR_GET_A (EEL_RGBA_COLOR_OPAQUE_GREEN), 0xFF); + EEL_CHECK_INTEGER_RESULT (EEL_RGBA_COLOR_GET_A (EEL_RGBA_COLOR_OPAQUE_BLUE), 0xFF); + EEL_CHECK_INTEGER_RESULT (EEL_RGBA_COLOR_GET_A (EEL_RGBA_COLOR_OPAQUE_WHITE), 0xFF); + EEL_CHECK_INTEGER_RESULT (EEL_RGBA_COLOR_GET_A (EEL_RGBA_COLOR_OPAQUE_BLACK), 0xFF); + EEL_CHECK_INTEGER_RESULT (EEL_RGBA_COLOR_GET_A (EEL_RGB_COLOR_RED), 0x00); + EEL_CHECK_INTEGER_RESULT (EEL_RGBA_COLOR_GET_A (EEL_RGB_COLOR_GREEN), 0x00); + EEL_CHECK_INTEGER_RESULT (EEL_RGBA_COLOR_GET_A (EEL_RGB_COLOR_BLUE), 0x00); + EEL_CHECK_INTEGER_RESULT (EEL_RGBA_COLOR_GET_A (EEL_RGB_COLOR_WHITE), 0x00); + EEL_CHECK_INTEGER_RESULT (EEL_RGBA_COLOR_GET_A (EEL_RGB_COLOR_BLACK), 0x00); + +} + +#endif /* ! EEL_OMIT_SELF_CHECK */ diff --git a/eel/eel-gdk-extensions.h b/eel/eel-gdk-extensions.h new file mode 100644 index 00000000..d5e041c5 --- /dev/null +++ b/eel/eel-gdk-extensions.h @@ -0,0 +1,164 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* eel-gdk-extensions.h: Graphics routines to augment what's in gdk. + + Copyright (C) 1999, 2000 Eazel, Inc. + + The Mate Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Mate Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Mate Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Authors: Darin Adler , + Ramiro Estrugo +*/ + +#ifndef EEL_GDK_EXTENSIONS_H +#define EEL_GDK_EXTENSIONS_H + +#include + +#define EEL_RGB_COLOR_RED 0xFF0000 +#define EEL_RGB_COLOR_GREEN 0x00FF00 +#define EEL_RGB_COLOR_BLUE 0x0000FF +#define EEL_RGB_COLOR_WHITE 0xFFFFFF +#define EEL_RGB_COLOR_BLACK 0x000000 + +#define EEL_RGBA_COLOR_OPAQUE_RED 0xFFFF0000 +#define EEL_RGBA_COLOR_OPAQUE_GREEN 0xFF00FF00 +#define EEL_RGBA_COLOR_OPAQUE_BLUE 0xFF0000FF +#define EEL_RGBA_COLOR_OPAQUE_WHITE 0xFFFFFFFF +#define EEL_RGBA_COLOR_OPAQUE_BLACK 0xFF000000 + +/* Pack RGBA values into 32 bits */ +#define EEL_RGBA_COLOR_PACK(r, g, b, a) \ +( (((guint32)a) << 24) | \ + (((guint32)r) << 16) | \ + (((guint32)g) << 8) | \ + (((guint32)b) << 0) ) + +/* Pack opaque RGBA values into 32 bits */ +#define EEL_RGB_COLOR_PACK(r, g, b) \ +EEL_RGBA_COLOR_PACK((r), (g), (b), 0xFF) + +/* Access the individual RGBA components */ +#define EEL_RGBA_COLOR_GET_R(color) (((color) >> 16) & 0xff) +#define EEL_RGBA_COLOR_GET_G(color) (((color) >> 8) & 0xff) +#define EEL_RGBA_COLOR_GET_B(color) (((color) >> 0) & 0xff) +#define EEL_RGBA_COLOR_GET_A(color) (((color) >> 24) & 0xff) + +/* Bits returned by eel_gdk_parse_geometry */ +typedef enum +{ + EEL_GDK_NO_VALUE = 0x00, + EEL_GDK_X_VALUE = 0x01, + EEL_GDK_Y_VALUE = 0x02, + EEL_GDK_WIDTH_VALUE = 0x04, + EEL_GDK_HEIGHT_VALUE = 0x08, + EEL_GDK_ALL_VALUES = 0x0f, + EEL_GDK_X_NEGATIVE = 0x10, + EEL_GDK_Y_NEGATIVE = 0x20 +} EelGdkGeometryFlags; + +/* A gradient spec. is a string that contains a specifier for either a + color or a gradient. If the string has a "-" in it, then it's a gradient. + The gradient is vertical by default and the spec. can end with ":v" to indicate that. + If the gradient ends with ":h", the gradient is horizontal. +*/ +char * eel_gradient_new (const char *start_color, + const char *end_color, + gboolean is_horizontal); +char * eel_gradient_parse_one_color_spec (const char *spec, + int *percent, + const char **next_spec); +gboolean eel_gradient_is_gradient (const char *gradient_spec); +char * eel_gradient_get_start_color_spec (const char *gradient_spec); +char * eel_gradient_get_end_color_spec (const char *gradient_spec); +gboolean eel_gradient_is_horizontal (const char *gradient_spec); +char * eel_gradient_set_left_color_spec (const char *gradient_spec, + const char *left_color); +char * eel_gradient_set_top_color_spec (const char *gradient_spec, + const char *top_color); +char * eel_gradient_set_right_color_spec (const char *gradient_spec, + const char *right_color); +char * eel_gradient_set_bottom_color_spec (const char *gradient_spec, + const char *bottom_color); + + +/* A version of parse_color that substitutes a default color instead of returning + a boolean to indicate it cannot be parsed. +*/ +void eel_gdk_color_parse_with_default (const char *color_spec, + const GdkColor *default_color, + GdkColor *parsed_color); +void eel_gdk_color_parse_with_white_default (const char *color_spec, + GdkColor *parsed_color); +guint32 eel_parse_rgb_with_default (const char *color_spec, + guint32 default_rgb); +guint32 eel_parse_rgb_with_white_default (const char *color_spec); +guint32 eel_rgb_shift_color (guint32 color, + float shift_by); +guint32 eel_rgb16_to_rgb (gushort r, + gushort g, + gushort b); +guint32 eel_rgb8_to_rgb (guchar r, + guchar g, + guchar b); +guint32 eel_gdk_color_to_rgb (const GdkColor *color); +GdkColor eel_gdk_rgb_to_color (guint32 color); +char * eel_gdk_rgb_to_color_spec (guint32 color); + +gboolean eel_gdk_color_is_dark (GdkColor *color); + +/* A routine to get a 50% gray stippled bitmap for use in some types of highlighting. */ +GdkBitmap * eel_stipple_bitmap_for_screen (GdkScreen *screen); +GdkBitmap * eel_stipple_bitmap (void); + + +/* Misc GdkRectangle helper functions */ +gboolean eel_gdk_rectangle_contains_rectangle (GdkRectangle outer, + GdkRectangle inner); + + +/* A basic operation we use for drawing gradients is interpolating two colors.*/ +guint32 eel_interpolate_color (gdouble ratio, + guint32 start_rgb, + guint32 end_rgb); + +/* Misc GdkWindow helper functions */ +void eel_gdk_window_bring_to_front (GdkWindow *window); +void eel_gdk_window_set_invisible_cursor (GdkWindow *window); +void eel_gdk_window_focus (GdkWindow *window, + guint32 timestamp); +void eel_gdk_window_set_wm_protocols (GdkWindow *window, + GdkAtom *protocols, + int nprotocols); + + +void eel_gdk_window_set_wm_hints_input (GdkWindow *w, + gboolean status); + +/* Wrapper for XParseGeometry */ +EelGdkGeometryFlags eel_gdk_parse_geometry (const char *string, + int *x_return, + int *y_return, + guint *width_return, + guint *height_return); +void eel_gdk_draw_layout_with_drop_shadow (GdkDrawable *drawable, + GdkGC *gc, + GdkColor *text_color, + GdkColor *shadow_color, + int x, + int y, + PangoLayout *layout); +#endif /* EEL_GDK_EXTENSIONS_H */ diff --git a/eel/eel-gdk-pixbuf-extensions.c b/eel/eel-gdk-pixbuf-extensions.c new file mode 100644 index 00000000..a58ef4c5 --- /dev/null +++ b/eel/eel-gdk-pixbuf-extensions.c @@ -0,0 +1,1510 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* eel-gdk-pixbuf-extensions.c: Routines to augment what's in gdk-pixbuf. + + Copyright (C) 2000 Eazel, Inc. + + The Mate Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Mate Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Mate Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Authors: Darin Adler + Ramiro Estrugo +*/ + +#include +#include "eel-gdk-pixbuf-extensions.h" + +#include "eel-art-gtk-extensions.h" +#include "eel-debug-drawing.h" +#include "eel-debug.h" +#include "eel-gdk-extensions.h" +#include "eel-glib-extensions.h" +#include "eel-graphic-effects.h" +#include "eel-lib-self-check-functions.h" +#include "eel-string.h" +#include +#include +#include +#include +#include +#include +#include + +#define LOAD_BUFFER_SIZE 65536 + +const EelIRect eel_gdk_pixbuf_whole_pixbuf = { G_MININT, G_MININT, G_MAXINT, G_MAXINT }; + +struct EelPixbufLoadHandle +{ + GCancellable *cancellable; + GInputStream *stream; + EelPixbufLoadCallback callback; + gpointer callback_data; + GdkPixbufLoader *loader; + char buffer[LOAD_BUFFER_SIZE]; +}; + +/** + * eel_gdk_pixbuf_list_ref + * @pixbuf_list: A list of GdkPixbuf objects. + * + * Refs all the pixbufs. + **/ +void +eel_gdk_pixbuf_list_ref (GList *pixbuf_list) +{ + g_list_foreach (pixbuf_list, (GFunc) g_object_ref, NULL); +} + +/** + * eel_gdk_pixbuf_list_free + * @pixbuf_list: A list of GdkPixbuf objects. + * + * Unrefs all the pixbufs, then frees the list. + **/ +void +eel_gdk_pixbuf_list_free (GList *pixbuf_list) +{ + eel_g_list_free_deep_custom (pixbuf_list, (GFunc) g_object_unref, NULL); +} + +GdkPixbuf * +eel_gdk_pixbuf_load (const char *uri) +{ + GdkPixbuf *pixbuf; + GFile *file; + GFileInputStream *stream; + + g_return_val_if_fail (uri != NULL, NULL); + + file = g_file_new_for_uri (uri); + + stream = g_file_read (file, NULL, NULL); + + g_object_unref (file); + + if (stream == NULL) + { + return NULL; + } + + pixbuf = eel_gdk_pixbuf_load_from_stream (G_INPUT_STREAM (stream)); + + g_object_unref (stream); + + return pixbuf; +} + +GdkPixbuf * +eel_gdk_pixbuf_load_from_stream (GInputStream *stream) +{ + return eel_gdk_pixbuf_load_from_stream_at_size (stream, -1); +} + +static void +pixbuf_loader_size_prepared (GdkPixbufLoader *loader, + int width, + int height, + gpointer desired_size_ptr) +{ + int size, desired_size; + float scale; + + size = MAX (width, height); + desired_size = GPOINTER_TO_INT (desired_size_ptr); + + if (size != desired_size) + { + scale = (float) desired_size / size; + gdk_pixbuf_loader_set_size (loader, + floor (scale * width + 0.5), + floor (scale * height + 0.5)); + } +} + +GdkPixbuf * +eel_gdk_pixbuf_load_from_stream_at_size (GInputStream *stream, + int size) +{ + char buffer[LOAD_BUFFER_SIZE]; + gssize bytes_read; + GdkPixbufLoader *loader; + GdkPixbuf *pixbuf; + gboolean got_eos; + + + g_return_val_if_fail (stream != NULL, NULL); + + got_eos = FALSE; + loader = gdk_pixbuf_loader_new (); + + if (size > 0) + { + g_signal_connect (loader, "size-prepared", + G_CALLBACK (pixbuf_loader_size_prepared), + GINT_TO_POINTER (size)); + } + + while (1) + { + bytes_read = g_input_stream_read (stream, buffer, sizeof (buffer), + NULL, NULL); + + if (bytes_read < 0) + { + break; + } + if (bytes_read == 0) + { + got_eos = TRUE; + break; + } + if (!gdk_pixbuf_loader_write (loader, + buffer, + bytes_read, + NULL)) + { + break; + } + } + + g_input_stream_close (stream, NULL, NULL); + gdk_pixbuf_loader_close (loader, NULL); + + pixbuf = NULL; + if (got_eos) + { + pixbuf = gdk_pixbuf_loader_get_pixbuf (loader); + if (pixbuf != NULL) + { + g_object_ref (pixbuf); + } + } + + g_object_unref (loader); + + return pixbuf; +} + +static void +free_pixbuf_load_handle (EelPixbufLoadHandle *handle) +{ + g_object_unref (handle->cancellable); + if (handle->loader != NULL) + { + g_object_unref (handle->loader); + } + if (handle->stream) + { + g_input_stream_close_async (handle->stream, 0, NULL, NULL, NULL); + g_object_unref (handle->stream); + } + g_free (handle); +} + +static void +load_done (EelPixbufLoadHandle *handle, GError *error, gboolean get_pixbuf) +{ + GdkPixbuf *pixbuf; + + if (handle->loader != NULL) + { + gdk_pixbuf_loader_close (handle->loader, NULL); + } + + pixbuf = get_pixbuf ? gdk_pixbuf_loader_get_pixbuf (handle->loader) : NULL; + + handle->callback (error, pixbuf, handle->callback_data); + + free_pixbuf_load_handle (handle); +} + +static void +file_read_callback (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + EelPixbufLoadHandle *handle; + gssize bytes_read; + GError *error; + + handle = user_data; + + if (g_cancellable_is_cancelled (handle->cancellable)) + { + free_pixbuf_load_handle (handle); + return; + } + + error = NULL; + bytes_read = g_input_stream_read_finish (G_INPUT_STREAM (source_object), + res, &error); + + if (bytes_read > 0) + { + if (!gdk_pixbuf_loader_write (handle->loader, + handle->buffer, + bytes_read, + &error)) + { + bytes_read = -1; + } + else + { + g_input_stream_read_async (handle->stream, + handle->buffer, + sizeof (handle->buffer), + 0, + handle->cancellable, + file_read_callback, handle); + return; + } + } + + load_done (handle, error, bytes_read == 0); + + if (error != NULL) + { + g_error_free (error); + } +} + +static void +file_opened_callback (GObject *source_object, + GAsyncResult *res, + gpointer user_data) +{ + EelPixbufLoadHandle *handle; + GFileInputStream *stream; + GError *error; + + handle = user_data; + + if (g_cancellable_is_cancelled (handle->cancellable)) + { + free_pixbuf_load_handle (handle); + return; + } + + error = NULL; + stream = g_file_read_finish (G_FILE (source_object), res, &error); + + if (stream == NULL) + { + load_done (handle, error, FALSE); + g_error_free (error); + return; + } + + handle->stream = G_INPUT_STREAM (stream); + handle->loader = gdk_pixbuf_loader_new (); + + + g_input_stream_read_async (handle->stream, + handle->buffer, + sizeof (handle->buffer), + 0, + handle->cancellable, + file_read_callback, handle); +} + +EelPixbufLoadHandle * +eel_gdk_pixbuf_load_async (const char *uri, + int priority, + EelPixbufLoadCallback callback, + gpointer callback_data) +{ + EelPixbufLoadHandle *handle; + GFile *file; + + handle = g_new0 (EelPixbufLoadHandle, 1); + handle->cancellable = g_cancellable_new (); + handle->callback = callback; + handle->callback_data = callback_data; + + file = g_file_new_for_uri (uri); + + g_file_read_async (file, priority, handle->cancellable, + file_opened_callback, handle); + + return handle; +} + +void +eel_cancel_gdk_pixbuf_load (EelPixbufLoadHandle *handle) +{ + if (handle == NULL) + { + return; + } + + g_cancellable_cancel (handle->cancellable); +} + +/* return the average value of each component */ +guint32 +eel_gdk_pixbuf_average_value (GdkPixbuf *pixbuf) +{ + guint64 a_total, r_total, g_total, b_total; + guint row, column; + int row_stride; + const guchar *pixels, *p; + int r, g, b, a; + guint64 dividend; + guint width, height; + + width = gdk_pixbuf_get_width (pixbuf); + height = gdk_pixbuf_get_height (pixbuf); + row_stride = gdk_pixbuf_get_rowstride (pixbuf); + pixels = gdk_pixbuf_get_pixels (pixbuf); + + /* iterate through the pixbuf, counting up each component */ + a_total = 0; + r_total = 0; + g_total = 0; + b_total = 0; + + if (gdk_pixbuf_get_has_alpha (pixbuf)) + { + for (row = 0; row < height; row++) + { + p = pixels + (row * row_stride); + for (column = 0; column < width; column++) + { + r = *p++; + g = *p++; + b = *p++; + a = *p++; + + a_total += a; + r_total += r * a; + g_total += g * a; + b_total += b * a; + } + } + dividend = height * width * 0xFF; + a_total *= 0xFF; + } + else + { + for (row = 0; row < height; row++) + { + p = pixels + (row * row_stride); + for (column = 0; column < width; column++) + { + r = *p++; + g = *p++; + b = *p++; + + r_total += r; + g_total += g; + b_total += b; + } + } + dividend = height * width; + a_total = dividend * 0xFF; + } + + return ((a_total + dividend / 2) / dividend) << 24 + | ((r_total + dividend / 2) / dividend) << 16 + | ((g_total + dividend / 2) / dividend) << 8 + | ((b_total + dividend / 2) / dividend); +} + +double +eel_gdk_scale_to_fit_factor (int width, int height, + int max_width, int max_height, + int *scaled_width, int *scaled_height) +{ + double scale_factor; + + scale_factor = MIN (max_width / (double) width, max_height / (double) height); + + *scaled_width = floor (width * scale_factor + .5); + *scaled_height = floor (height * scale_factor + .5); + + return scale_factor; +} + +/* Returns a scaled copy of pixbuf, preserving aspect ratio. The copy will + * be scaled as large as possible without exceeding the specified width and height. + */ +GdkPixbuf * +eel_gdk_pixbuf_scale_to_fit (GdkPixbuf *pixbuf, int max_width, int max_height) +{ + int scaled_width; + int scaled_height; + + eel_gdk_scale_to_fit_factor (gdk_pixbuf_get_width(pixbuf), gdk_pixbuf_get_height(pixbuf), + max_width, max_height, + &scaled_width, &scaled_height); + + return gdk_pixbuf_scale_simple (pixbuf, scaled_width, scaled_height, GDK_INTERP_BILINEAR); +} + +/* Returns a copy of pixbuf scaled down, preserving aspect ratio, to fit + * within the specified width and height. If it already fits, a copy of + * the original, without scaling, is returned. + */ +GdkPixbuf * +eel_gdk_pixbuf_scale_down_to_fit (GdkPixbuf *pixbuf, int max_width, int max_height) +{ + int scaled_width; + int scaled_height; + + double scale_factor; + + scale_factor = eel_gdk_scale_to_fit_factor (gdk_pixbuf_get_width(pixbuf), gdk_pixbuf_get_height(pixbuf), + max_width, max_height, + &scaled_width, &scaled_height); + + if (scale_factor >= 1.0) + { + return gdk_pixbuf_copy (pixbuf); + } + else + { + return eel_gdk_pixbuf_scale_down (pixbuf, scaled_width, scaled_height); + } +} + +double +eel_gdk_scale_to_min_factor (int width, int height, + int min_width, int min_height, + int *scaled_width, int *scaled_height) +{ + double scale_factor; + + scale_factor = MAX (min_width / (double) width, min_height / (double) height); + + *scaled_width = floor (width * scale_factor + .5); + *scaled_height = floor (height * scale_factor + .5); + + return scale_factor; +} + +/* Returns a scaled copy of pixbuf, preserving aspect ratio. The copy will + * be scaled as small as possible without going under the specified width and height. + */ +GdkPixbuf * +eel_gdk_pixbuf_scale_to_min (GdkPixbuf *pixbuf, int min_width, int min_height) +{ + int scaled_width; + int scaled_height; + + eel_gdk_scale_to_min_factor (gdk_pixbuf_get_width(pixbuf), gdk_pixbuf_get_height(pixbuf), + min_width, min_height, + &scaled_width, &scaled_height); + + return gdk_pixbuf_scale_simple (pixbuf, scaled_width, scaled_height, GDK_INTERP_BILINEAR); +} + +/** + * eel_gdk_pixbuf_is_valid: + * @pixbuf: A GdkPixbuf + * + * Return value: A boolean indicating whether the given pixbuf is valid. + * + * A pixbuf is valid if: + * + * 1. It is non NULL + * 2. It is has non NULL pixel data. + * 3. It has width and height greater than 0. + */ +gboolean +eel_gdk_pixbuf_is_valid (const GdkPixbuf *pixbuf) +{ + return ((pixbuf != NULL) + && (gdk_pixbuf_get_pixels (pixbuf) != NULL) + && (gdk_pixbuf_get_width (pixbuf) > 0) + && (gdk_pixbuf_get_height (pixbuf) > 0)); +} + +/** + * eel_gdk_pixbuf_get_dimensions: + * @pixbuf: A GdkPixbuf + * + * Return value: The dimensions of the pixbuf as a EelDimensions. + * + * This function is useful in code that uses libart rect + * intersection routines. + */ +EelDimensions +eel_gdk_pixbuf_get_dimensions (const GdkPixbuf *pixbuf) +{ + EelDimensions dimensions; + + g_return_val_if_fail (eel_gdk_pixbuf_is_valid (pixbuf), eel_dimensions_empty); + + dimensions.width = gdk_pixbuf_get_width (pixbuf); + dimensions.height = gdk_pixbuf_get_height (pixbuf); + + return dimensions; +} + +/** + * eel_gdk_pixbuf_fill_rectangle_with_color: + * @pixbuf: Target pixbuf to fill into. + * @area: Rectangle to fill. + * @color: The color to use. + * + * Fill the rectangle with the the given color. + */ +void +eel_gdk_pixbuf_fill_rectangle_with_color (GdkPixbuf *pixbuf, + EelIRect area, + guint32 color) +{ + EelIRect target; + guchar red; + guchar green; + guchar blue; + guchar alpha; + guchar *pixels; + gboolean has_alpha; + guint pixel_offset; + guint rowstride; + guchar *row_offset; + int x; + int y; + + g_return_if_fail (eel_gdk_pixbuf_is_valid (pixbuf)); + + target = eel_gdk_pixbuf_intersect (pixbuf, 0, 0, area); + if (eel_irect_is_empty (&target)) + { + return; + } + + pixels = gdk_pixbuf_get_pixels (pixbuf); + rowstride = gdk_pixbuf_get_rowstride (pixbuf); + has_alpha = gdk_pixbuf_get_has_alpha (pixbuf); + pixel_offset = has_alpha ? 4 : 3; + red = EEL_RGBA_COLOR_GET_R (color); + green = EEL_RGBA_COLOR_GET_G (color); + blue = EEL_RGBA_COLOR_GET_B (color); + alpha = EEL_RGBA_COLOR_GET_A (color); + + row_offset = pixels + target.y0 * rowstride; + + for (y = target.y0; y < target.y1; y++) + { + guchar *offset = row_offset + (target.x0 * pixel_offset); + + for (x = target.x0; x < target.x1; x++) + { + *(offset++) = red; + *(offset++) = green; + *(offset++) = blue; + + if (has_alpha) + { + *(offset++) = alpha; + } + + } + + row_offset += rowstride; + } +} + +gboolean +eel_gdk_pixbuf_save_to_file (const GdkPixbuf *pixbuf, + const char *file_name) +{ + return gdk_pixbuf_save ((GdkPixbuf *) pixbuf, + file_name, "png", NULL, NULL); +} + +void +eel_gdk_pixbuf_ref_if_not_null (GdkPixbuf *pixbuf_or_null) +{ + if (pixbuf_or_null != NULL) + { + g_object_ref (pixbuf_or_null); + } +} + +void +eel_gdk_pixbuf_unref_if_not_null (GdkPixbuf *pixbuf_or_null) +{ + if (pixbuf_or_null != NULL) + { + g_object_unref (pixbuf_or_null); + } +} + +void +eel_gdk_pixbuf_draw_to_drawable (const GdkPixbuf *pixbuf, + GdkDrawable *drawable, + GdkGC *gc, + int source_x, + int source_y, + EelIRect destination_area, + GdkRgbDither dither, + GdkPixbufAlphaMode alpha_compositing_mode, + int alpha_threshold) +{ + EelDimensions dimensions; + EelIRect target; + EelIRect source; + int target_width; + int target_height; + int source_width; + int source_height; + + g_return_if_fail (eel_gdk_pixbuf_is_valid (pixbuf)); + g_return_if_fail (drawable != NULL); + g_return_if_fail (gc != NULL); + g_return_if_fail (!eel_irect_is_empty (&destination_area)); + g_return_if_fail (alpha_threshold > EEL_OPACITY_FULLY_TRANSPARENT); + g_return_if_fail (alpha_threshold <= EEL_OPACITY_FULLY_OPAQUE); + g_return_if_fail (alpha_compositing_mode >= GDK_PIXBUF_ALPHA_BILEVEL); + g_return_if_fail (alpha_compositing_mode <= GDK_PIXBUF_ALPHA_FULL); + + dimensions = eel_gdk_pixbuf_get_dimensions (pixbuf); + + g_return_if_fail (source_x >= 0); + g_return_if_fail (source_y >= 0); + g_return_if_fail (source_x < dimensions.width); + g_return_if_fail (source_y < dimensions.height); + + /* Clip the destination area to the pixbuf dimensions; bail if no work */ + target = eel_gdk_pixbuf_intersect (pixbuf, + destination_area.x0, + destination_area.y0, + destination_area); + if (eel_irect_is_empty (&target)) + { + return; + } + + /* Assign the source area */ + source = eel_irect_assign (source_x, + source_y, + dimensions.width - source_x, + dimensions.height - source_y); + + /* Adjust the target width if the source area is smaller than the + * source pixbuf dimensions */ + target_width = target.x1 - target.x0; + target_height = target.y1 - target.y0; + source_width = source.x1 - source.x0; + source_height = source.y1 - source.y0; + + target.x1 = target.x0 + MIN (target_width, source_width); + target.y1 = target.y0 + MIN (target_height, source_height); + + gdk_draw_pixbuf (drawable, gc, (GdkPixbuf *) pixbuf, + source.x0, + source.y0, + target.x0, + target.y0, + target.x1 - target.x0, + target.y1 - target.y0, + dither, + 0, + 0); +} + +/** + * eel_gdk_pixbuf_draw_to_pixbuf: + * @pixbuf: The source pixbuf to draw. + * @destination_pixbuf: The destination pixbuf. + * @source_x: The source pixbuf x coordiate to composite from. + * @source_y: The source pixbuf y coordiate to composite from. + * @destination_area: The destination area within the destination pixbuf. + * This area will be clipped if invalid in any way. + * + * Copy one pixbuf onto another another.. This function has some advantages + * over plain gdk_pixbuf_copy_area(): + * + * Composition paramters (source coordinate, destination area) are + * given in a way that is consistent with the rest of the extensions + * in this file. That is, it matches the declaration of + * eel_gdk_pixbuf_draw_to_pixbuf_alpha() and + * eel_gdk_pixbuf_draw_to_drawable() very closely. + * + * All values are clipped to make sure they are valid. + * + */ +void +eel_gdk_pixbuf_draw_to_pixbuf (const GdkPixbuf *pixbuf, + GdkPixbuf *destination_pixbuf, + int source_x, + int source_y, + EelIRect destination_area) +{ + EelDimensions dimensions; + EelIRect target; + EelIRect source; + int target_width; + int target_height; + int source_width; + int source_height; + + g_return_if_fail (eel_gdk_pixbuf_is_valid (pixbuf)); + g_return_if_fail (eel_gdk_pixbuf_is_valid (destination_pixbuf)); + g_return_if_fail (!eel_irect_is_empty (&destination_area)); + + dimensions = eel_gdk_pixbuf_get_dimensions (pixbuf); + + g_return_if_fail (source_x >= 0); + g_return_if_fail (source_y >= 0); + g_return_if_fail (source_x < dimensions.width); + g_return_if_fail (source_y < dimensions.height); + + /* Clip the destination area to the pixbuf dimensions; bail if no work */ + target = eel_gdk_pixbuf_intersect (destination_pixbuf, 0, 0, destination_area); + if (eel_irect_is_empty (&target)) + { + return; + } + + /* Assign the source area */ + source = eel_irect_assign (source_x, + source_y, + dimensions.width - source_x, + dimensions.height - source_y); + + /* Adjust the target width if the source area is smaller than the + * source pixbuf dimensions */ + target_width = target.x1 - target.x0; + target_height = target.y1 - target.y0; + source_width = source.x1 - source.x0; + source_height = source.y1 - source.y0; + + target.x1 = target.x0 + MIN (target_width, source_width); + target.y1 = target.y0 + MIN (target_height, source_height); + + gdk_pixbuf_copy_area (pixbuf, + source.x0, + source.y0, + target.x1 - target.x0, + target.y1 - target.y0, + destination_pixbuf, + target.x0, + target.y0); +} + +/** + * eel_gdk_pixbuf_draw_to_pixbuf_alpha: + * @pixbuf: The source pixbuf to draw. + * @destination_pixbuf: The destination pixbuf. + * @source_x: The source pixbuf x coordiate to composite from. + * @source_y: The source pixbuf y coordiate to composite from. + * @destination_area: The destination area within the destination pixbuf. + * This area will be clipped if invalid in any way. + * @opacity: The opacity of the drawn tiles where 0 <= opacity <= 255. + * @interpolation_mode: The interpolation mode. See + * + * Composite one pixbuf over another. This function has some advantages + * over plain gdk_pixbuf_composite(): + * + * Composition paramters (source coordinate, destination area) are + * given in a way that is consistent with the rest of the extensions + * in this file. That is, it matches the declaration of + * eel_gdk_pixbuf_draw_to_pixbuf() and + * eel_gdk_pixbuf_draw_to_drawable() very closely. + * + * All values are clipped to make sure they are valid. + * + * Workaround a limitation in gdk_pixbuf_composite() that does not allow + * the source (x,y) to be greater than (0,0) + * + */ +void +eel_gdk_pixbuf_draw_to_pixbuf_alpha (const GdkPixbuf *pixbuf, + GdkPixbuf *destination_pixbuf, + int source_x, + int source_y, + EelIRect destination_area, + int opacity, + GdkInterpType interpolation_mode) +{ + EelDimensions dimensions; + EelIRect target; + EelIRect source; + int target_width; + int target_height; + int source_width; + int source_height; + + g_return_if_fail (eel_gdk_pixbuf_is_valid (pixbuf)); + g_return_if_fail (eel_gdk_pixbuf_is_valid (destination_pixbuf)); + g_return_if_fail (!eel_irect_is_empty (&destination_area)); + g_return_if_fail (opacity >= EEL_OPACITY_FULLY_TRANSPARENT); + g_return_if_fail (opacity <= EEL_OPACITY_FULLY_OPAQUE); + g_return_if_fail (interpolation_mode >= GDK_INTERP_NEAREST); + g_return_if_fail (interpolation_mode <= GDK_INTERP_HYPER); + + dimensions = eel_gdk_pixbuf_get_dimensions (pixbuf); + + g_return_if_fail (source_x >= 0); + g_return_if_fail (source_y >= 0); + g_return_if_fail (source_x < dimensions.width); + g_return_if_fail (source_y < dimensions.height); + + /* Clip the destination area to the pixbuf dimensions; bail if no work */ + target = eel_gdk_pixbuf_intersect (destination_pixbuf, 0, 0, destination_area); + if (eel_irect_is_empty (&target)) + { + return; + } + + /* Assign the source area */ + source = eel_irect_assign (source_x, + source_y, + dimensions.width - source_x, + dimensions.height - source_y); + + /* Adjust the target width if the source area is smaller than the + * source pixbuf dimensions */ + target_width = target.x1 - target.x0; + target_height = target.y1 - target.y0; + source_width = source.x1 - source.x0; + source_height = source.y1 - source.y0; + + target.x1 = target.x0 + MIN (target_width, source_width); + target.y1 = target.y0 + MIN (target_height, source_height); + + /* If the source point is not (0,0), then we need to create a sub pixbuf + * with only the source area. This is needed to work around a limitation + * in gdk_pixbuf_composite() that requires the source area to be (0,0). */ + if (source.x0 != 0 || source.y0 != 0) + { + EelIRect area; + int width; + int height; + + width = dimensions.width - source.x0; + height = dimensions.height - source.y0; + + area.x0 = source.x0; + area.y0 = source.y0; + area.x1 = area.x0 + width; + area.y1 = area.y0 + height; + + pixbuf = eel_gdk_pixbuf_new_from_pixbuf_sub_area ((GdkPixbuf *) pixbuf, area); + } + else + { + g_object_ref (G_OBJECT (pixbuf)); + } + + gdk_pixbuf_composite (pixbuf, + destination_pixbuf, + target.x0, + target.y0, + target.x1 - target.x0, + target.y1 - target.y0, + target.x0, + target.y0, + 1.0, + 1.0, + interpolation_mode, + opacity); + + g_object_unref (G_OBJECT (pixbuf)); +} + +static void +pixbuf_destroy_callback (guchar *pixels, + gpointer callback_data) +{ + g_assert (pixels != NULL); + g_assert (callback_data != NULL); + + g_object_unref (callback_data); +} + +/** + * eel_gdk_pixbuf_new_from_pixbuf_sub_area: + * @pixbuf: The source pixbuf. + * @area: The area within the source pixbuf to use for the sub pixbuf. + * This area needs to be contained within the bounds of the + * source pixbuf, otherwise it will be clipped to that. + * + * Return value: A newly allocated pixbuf that shares the pixel data + * of the source pixbuf in order to represent a sub area. + * + * Create a pixbuf from a sub area of another pixbuf. The resulting pixbuf + * will share the pixel data of the source pixbuf. Memory bookeeping is + * all taken care for the caller. All you need to do is g_object_unref() + * the resulting pixbuf to properly free resources. + */ +GdkPixbuf * +eel_gdk_pixbuf_new_from_pixbuf_sub_area (GdkPixbuf *pixbuf, + EelIRect area) +{ + GdkPixbuf *sub_pixbuf; + EelIRect target; + guchar *pixels; + + g_return_val_if_fail (eel_gdk_pixbuf_is_valid (pixbuf), NULL); + g_return_val_if_fail (!eel_irect_is_empty (&area), NULL); + + /* Clip the pixbuf by the given area; bail if no work */ + target = eel_gdk_pixbuf_intersect (pixbuf, 0, 0, area); + if (eel_irect_is_empty (&target)) + { + return NULL; + } + + /* Since we are going to be sharing the given pixbuf's data, we need + * to ref it. It will be unreffed in the destroy function above */ + g_object_ref (pixbuf); + + /* Compute the offset into the pixel data */ + pixels = + gdk_pixbuf_get_pixels (pixbuf) + + (target.y0 * gdk_pixbuf_get_rowstride (pixbuf)) + + (target.x0 * (gdk_pixbuf_get_has_alpha (pixbuf) ? 4 : 3)); + + /* Make a pixbuf pretending its real estate is the sub area */ + sub_pixbuf = gdk_pixbuf_new_from_data (pixels, + GDK_COLORSPACE_RGB, + gdk_pixbuf_get_has_alpha (pixbuf), + 8, + eel_irect_get_width (target), + eel_irect_get_height (target), + gdk_pixbuf_get_rowstride (pixbuf), + pixbuf_destroy_callback, + pixbuf); + + return sub_pixbuf; +} + +/** + * eel_gdk_pixbuf_new_from_existing_buffer: + * @buffer: The existing buffer. + * @buffer_rowstride: The existing buffer's rowstride. + * @buffer_has_alpha: A boolean value indicating whether the buffer has alpha. + * @area: The area within the existing buffer to use for the pixbuf. + * This area needs to be contained within the bounds of the + * buffer, otherwise memory will be trashed. + * + * Return value: A newly allocated pixbuf that uses the existing buffer + * for its pixel data. + * + * Create a pixbuf from an existing buffer. + * + * The resulting pixbuf is only valid for as long as &buffer is valid. It is + * up to the caller to make sure they both exist in the same scope. + * Also, it is up to the caller to make sure that the given area is fully + * contained in the buffer, otherwise memory trashing will happen. + */ +GdkPixbuf * +eel_gdk_pixbuf_new_from_existing_buffer (guchar *buffer, + int buffer_rowstride, + gboolean buffer_has_alpha, + EelIRect area) +{ + GdkPixbuf *pixbuf; + guchar *pixels; + + g_return_val_if_fail (buffer != NULL, NULL); + g_return_val_if_fail (buffer_rowstride > 0, NULL); + g_return_val_if_fail (!eel_irect_is_empty (&area), NULL); + + /* Compute the offset into the buffer */ + pixels = + buffer + + (area.y0 * buffer_rowstride) + + (area.x0 * (buffer_has_alpha ? 4 : 3)); + + pixbuf = gdk_pixbuf_new_from_data (pixels, + GDK_COLORSPACE_RGB, + buffer_has_alpha, + 8, + eel_irect_get_width (area), + eel_irect_get_height (area), + buffer_rowstride, + NULL, + NULL); + + return pixbuf; +} + +/** + * eel_gdk_pixbuf_intersect: + * @pixbuf: A GdkPixbuf. + * @pixbuf_x: X coordinate of pixbuf. + * @pixbuf_y: Y coordinate of pixbuf. + * @rectangle: An EelIRect. + * + * Return value: The intersection of the pixbuf and the given rectangle. + * + */ +EelIRect +eel_gdk_pixbuf_intersect (const GdkPixbuf *pixbuf, + int pixbuf_x, + int pixbuf_y, + EelIRect rectangle) +{ + EelIRect intersection; + EelIRect bounds; + EelDimensions dimensions; + + g_return_val_if_fail (eel_gdk_pixbuf_is_valid (pixbuf), eel_irect_empty); + + dimensions = eel_gdk_pixbuf_get_dimensions (pixbuf); + bounds = eel_irect_assign_dimensions (pixbuf_x, pixbuf_y, dimensions); + + eel_irect_intersect (&intersection, &rectangle, &bounds); + + /* In theory, this is not needed because a rectangle is empty + * regardless of how MUCH negative the dimensions are. + * However, to make debugging and self checks simpler, we + * consistenly return a standard empty rectangle. + */ + if (eel_irect_is_empty (&intersection)) + { + return eel_irect_empty; + } + + return intersection; +} + +GdkPixbuf * +eel_gdk_pixbuf_scale_down (GdkPixbuf *pixbuf, + int dest_width, + int dest_height) +{ + int source_width, source_height; + int s_x1, s_y1, s_x2, s_y2; + int s_xfrac, s_yfrac; + int dx, dx_frac, dy, dy_frac; + div_t ddx, ddy; + int x, y; + int r, g, b, a; + int n_pixels; + gboolean has_alpha; + guchar *dest, *src, *xsrc, *src_pixels; + GdkPixbuf *dest_pixbuf; + int pixel_stride; + int source_rowstride, dest_rowstride; + + if (dest_width == 0 || dest_height == 0) + { + return NULL; + } + + source_width = gdk_pixbuf_get_width (pixbuf); + source_height = gdk_pixbuf_get_height (pixbuf); + + g_assert (source_width >= dest_width); + g_assert (source_height >= dest_height); + + ddx = div (source_width, dest_width); + dx = ddx.quot; + dx_frac = ddx.rem; + + ddy = div (source_height, dest_height); + dy = ddy.quot; + dy_frac = ddy.rem; + + has_alpha = gdk_pixbuf_get_has_alpha (pixbuf); + source_rowstride = gdk_pixbuf_get_rowstride (pixbuf); + src_pixels = gdk_pixbuf_get_pixels (pixbuf); + + dest_pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, has_alpha, 8, + dest_width, dest_height); + dest = gdk_pixbuf_get_pixels (dest_pixbuf); + dest_rowstride = gdk_pixbuf_get_rowstride (dest_pixbuf); + + pixel_stride = (has_alpha)?4:3; + + s_y1 = 0; + s_yfrac = -dest_height/2; + while (s_y1 < source_height) + { + s_y2 = s_y1 + dy; + s_yfrac += dy_frac; + if (s_yfrac > 0) + { + s_y2++; + s_yfrac -= dest_height; + } + + s_x1 = 0; + s_xfrac = -dest_width/2; + while (s_x1 < source_width) + { + s_x2 = s_x1 + dx; + s_xfrac += dx_frac; + if (s_xfrac > 0) + { + s_x2++; + s_xfrac -= dest_width; + } + + /* Average block of [x1,x2[ x [y1,y2[ and store in dest */ + r = g = b = a = 0; + n_pixels = 0; + + src = src_pixels + s_y1 * source_rowstride + s_x1 * pixel_stride; + for (y = s_y1; y < s_y2; y++) + { + xsrc = src; + if (has_alpha) + { + for (x = 0; x < s_x2-s_x1; x++) + { + n_pixels++; + + r += xsrc[3] * xsrc[0]; + g += xsrc[3] * xsrc[1]; + b += xsrc[3] * xsrc[2]; + a += xsrc[3]; + xsrc += 4; + } + } + else + { + for (x = 0; x < s_x2-s_x1; x++) + { + n_pixels++; + r += *xsrc++; + g += *xsrc++; + b += *xsrc++; + } + } + src += source_rowstride; + } + + if (has_alpha) + { + if (a != 0) + { + *dest++ = r / a; + *dest++ = g / a; + *dest++ = b / a; + *dest++ = a / n_pixels; + } + else + { + *dest++ = 0; + *dest++ = 0; + *dest++ = 0; + *dest++ = 0; + } + } + else + { + *dest++ = r / n_pixels; + *dest++ = g / n_pixels; + *dest++ = b / n_pixels; + } + + s_x1 = s_x2; + } + s_y1 = s_y2; + dest += dest_rowstride - dest_width * pixel_stride; + } + + return dest_pixbuf; +} + +static guchar +eel_gdk_pixbuf_lighten_pixbuf_component (guchar cur_value, + guint lighten_value) +{ + int new_value = cur_value; + if (lighten_value > 0) + { + new_value += lighten_value + (new_value >> 3); + if (new_value > 255) + { + new_value = 255; + } + } + return (guchar) new_value; +} + +static GdkPixbuf * +eel_gdk_pixbuf_lighten (GdkPixbuf* src, + guint lighten_value) +{ + GdkPixbuf *dest; + int i, j; + int width, height, has_alpha, src_row_stride, dst_row_stride; + guchar *target_pixels, *original_pixels; + guchar *pixsrc, *pixdest; + + g_assert (gdk_pixbuf_get_colorspace (src) == GDK_COLORSPACE_RGB); + g_assert ((!gdk_pixbuf_get_has_alpha (src) + && gdk_pixbuf_get_n_channels (src) == 3) + || (gdk_pixbuf_get_has_alpha (src) + && gdk_pixbuf_get_n_channels (src) == 4)); + g_assert (gdk_pixbuf_get_bits_per_sample (src) == 8); + + dest = gdk_pixbuf_new (gdk_pixbuf_get_colorspace (src), + gdk_pixbuf_get_has_alpha (src), + gdk_pixbuf_get_bits_per_sample (src), + gdk_pixbuf_get_width (src), + gdk_pixbuf_get_height (src)); + + has_alpha = gdk_pixbuf_get_has_alpha (src); + width = gdk_pixbuf_get_width (src); + height = gdk_pixbuf_get_height (src); + dst_row_stride = gdk_pixbuf_get_rowstride (dest); + src_row_stride = gdk_pixbuf_get_rowstride (src); + target_pixels = gdk_pixbuf_get_pixels (dest); + original_pixels = gdk_pixbuf_get_pixels (src); + + for (i = 0; i < height; i++) + { + pixdest = target_pixels + i * dst_row_stride; + pixsrc = original_pixels + i * src_row_stride; + for (j = 0; j < width; j++) + { + *pixdest++ = eel_gdk_pixbuf_lighten_pixbuf_component (*pixsrc++, lighten_value); + *pixdest++ = eel_gdk_pixbuf_lighten_pixbuf_component (*pixsrc++, lighten_value); + *pixdest++ = eel_gdk_pixbuf_lighten_pixbuf_component (*pixsrc++, lighten_value); + if (has_alpha) + { + *pixdest++ = *pixsrc++; + } + } + } + return dest; +} + +GdkPixbuf * +eel_gdk_pixbuf_render (GdkPixbuf *pixbuf, + guint render_mode, + guint saturation, + guint brightness, + guint lighten_value, + guint color) +{ + GdkPixbuf *temp_pixbuf, *old_pixbuf; + + if (render_mode == 1) + { + /* lighten icon */ + temp_pixbuf = eel_create_spotlight_pixbuf (pixbuf); + } + else if (render_mode == 2) + { + /* colorize icon */ + temp_pixbuf = eel_create_colorized_pixbuf (pixbuf, + EEL_RGBA_COLOR_GET_R (color), + EEL_RGBA_COLOR_GET_G (color), + EEL_RGBA_COLOR_GET_B (color)); + } + else if (render_mode == 3) + { + /* monochromely colorize icon */ + old_pixbuf = eel_create_darkened_pixbuf (pixbuf, 0, 255); + temp_pixbuf = eel_create_colorized_pixbuf (old_pixbuf, + EEL_RGBA_COLOR_GET_R (color), + EEL_RGBA_COLOR_GET_G (color), + EEL_RGBA_COLOR_GET_B (color)); + g_object_unref (old_pixbuf); + } + else + { + temp_pixbuf = NULL; + } + + if (saturation < 255 || brightness < 255 || temp_pixbuf == NULL) // temp_pixbuf == NULL just for safer code (return copy) + { + old_pixbuf = temp_pixbuf; + temp_pixbuf = eel_create_darkened_pixbuf (temp_pixbuf ? temp_pixbuf : pixbuf, saturation, brightness); + if (old_pixbuf) + { + g_object_unref (old_pixbuf); + } + } + + if (lighten_value > 0) + { + old_pixbuf = temp_pixbuf; + temp_pixbuf = eel_gdk_pixbuf_lighten (temp_pixbuf ? temp_pixbuf : pixbuf, lighten_value); + if (old_pixbuf) + { + g_object_unref (old_pixbuf); + } + } + + return temp_pixbuf; +} + + +#if !defined (EEL_OMIT_SELF_CHECK) + +static char * +check_average_value (int width, int height, const char* fill) +{ + char c; + guint r, g, b, a; + gboolean alpha, gray; + int gray_tweak; + GdkPixbuf *pixbuf; + int x, y, rowstride, n_channels; + guchar *pixels; + guint32 average; + guchar v; + + r = g = b = a = 0; + alpha = FALSE; + gray = FALSE; + gray_tweak = 0; + if (sscanf (fill, " %x,%x,%x,%x %c", &r, &g, &b, &a, &c) == 4) + { + alpha = TRUE; + } + else if (sscanf (fill, " %x,%x,%x %c", &r, &g, &b, &c) == 3) + { + } + else if (sscanf (fill, " gray%d %c", &gray_tweak, &c) == 1) + { + gray = TRUE; + } + else + { + return g_strdup ("bad fill string format"); + } + + pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, alpha, 8, width, height); + + pixels = gdk_pixbuf_get_pixels (pixbuf); + rowstride = gdk_pixbuf_get_rowstride (pixbuf); + n_channels = gdk_pixbuf_get_n_channels (pixbuf); + + if (!gray) + { + for (y = 0; y < height; y++) + { + for (x = 0; x < width; x++) + { + pixels [y * rowstride + x * n_channels + 0] = r; + pixels [y * rowstride + x * n_channels + 1] = g; + pixels [y * rowstride + x * n_channels + 2] = b; + if (alpha) + { + pixels [y * rowstride + x * n_channels + 3] = a; + } + } + } + } + else + { + for (y = 0; y < height; y++) + { + for (x = 0; x < width; x++) + { + v = ((x + y) & 1) ? 0x80 : 0x7F; + if (((x + y) & 0xFF) == 0) + v += gray_tweak; + pixels [y * rowstride + x * n_channels + 0] = v; + pixels [y * rowstride + x * n_channels + 1] = v; + pixels [y * rowstride + x * n_channels + 2] = v; + } + } + pixels [0] += gray_tweak; + pixels [1] += gray_tweak; + pixels [2] += gray_tweak; + } + + average = eel_gdk_pixbuf_average_value (pixbuf); + g_object_unref (pixbuf); + + return g_strdup_printf ("%02X,%02X,%02X,%02X", + (average >> 16) & 0xFF, + (average >> 8) & 0xFF, + average & 0xFF, + average >> 24); +} + +void +eel_self_check_gdk_pixbuf_extensions (void) +{ + GdkPixbuf *pixbuf; + EelIRect clip_area; + + pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, 100, 100); + + EEL_CHECK_BOOLEAN_RESULT (eel_gdk_pixbuf_is_valid (pixbuf), TRUE); + EEL_CHECK_BOOLEAN_RESULT (eel_gdk_pixbuf_is_valid (NULL), FALSE); + + EEL_CHECK_DIMENSIONS_RESULT (eel_gdk_pixbuf_get_dimensions (pixbuf), 100, 100); + + EEL_CHECK_RECTANGLE_RESULT (eel_gdk_pixbuf_intersect (pixbuf, 0, 0, eel_gdk_pixbuf_whole_pixbuf), 0, 0, 100, 100); + + clip_area = eel_irect_assign (0, 0, 0, 0); + EEL_CHECK_RECTANGLE_RESULT (eel_gdk_pixbuf_intersect (pixbuf, 0, 0, clip_area), 0, 0, 0, 0); + + clip_area = eel_irect_assign (0, 0, 0, 0); + EEL_CHECK_RECTANGLE_RESULT (eel_gdk_pixbuf_intersect (pixbuf, 0, 0, clip_area), 0, 0, 0, 0); + + clip_area = eel_irect_assign (0, 0, 100, 100); + EEL_CHECK_RECTANGLE_RESULT (eel_gdk_pixbuf_intersect (pixbuf, 0, 0, clip_area), 0, 0, 100, 100); + + clip_area = eel_irect_assign (-10, -10, 100, 100); + EEL_CHECK_RECTANGLE_RESULT (eel_gdk_pixbuf_intersect (pixbuf, 0, 0, clip_area), 0, 0, 90, 90); + + clip_area = eel_irect_assign (-10, -10, 110, 110); + EEL_CHECK_RECTANGLE_RESULT (eel_gdk_pixbuf_intersect (pixbuf, 0, 0, clip_area), 0, 0, 100, 100); + + clip_area = eel_irect_assign (0, 0, 99, 99); + EEL_CHECK_RECTANGLE_RESULT (eel_gdk_pixbuf_intersect (pixbuf, 0, 0, clip_area), 0, 0, 99, 99); + + clip_area = eel_irect_assign (0, 0, 1, 1); + EEL_CHECK_RECTANGLE_RESULT (eel_gdk_pixbuf_intersect (pixbuf, 0, 0, clip_area), 0, 0, 1, 1); + + clip_area = eel_irect_assign (-1, -1, 1, 1); + EEL_CHECK_RECTANGLE_RESULT (eel_gdk_pixbuf_intersect (pixbuf, 0, 0, clip_area), 0, 0, 0, 0); + + clip_area = eel_irect_assign (-1, -1, 2, 2); + EEL_CHECK_RECTANGLE_RESULT (eel_gdk_pixbuf_intersect (pixbuf, 0, 0, clip_area), 0, 0, 1, 1); + + clip_area = eel_irect_assign (100, 100, 1, 1); + EEL_CHECK_RECTANGLE_RESULT (eel_gdk_pixbuf_intersect (pixbuf, 0, 0, clip_area), 0, 0, 0, 0); + + clip_area = eel_irect_assign (101, 101, 1, 1); + EEL_CHECK_RECTANGLE_RESULT (eel_gdk_pixbuf_intersect (pixbuf, 0, 0, clip_area), 0, 0, 0, 0); + + clip_area = eel_irect_assign (80, 0, 100, 100); + EEL_CHECK_RECTANGLE_RESULT (eel_gdk_pixbuf_intersect (pixbuf, 0, 0, clip_area), 80, 0, 100, 100); + + g_object_unref (pixbuf); + + /* No checks for empty pixbufs because GdkPixbuf doesn't seem to allow them. */ + EEL_CHECK_STRING_RESULT (check_average_value (1, 1, "00,00,00"), "00,00,00,FF"); + EEL_CHECK_STRING_RESULT (check_average_value (1, 1, "00,00,00,00"), "00,00,00,00"); + EEL_CHECK_STRING_RESULT (check_average_value (1, 1, "00,00,00,FF"), "00,00,00,FF"); + EEL_CHECK_STRING_RESULT (check_average_value (1, 1, "01,01,01"), "01,01,01,FF"); + EEL_CHECK_STRING_RESULT (check_average_value (1, 1, "FE,FE,FE"), "FE,FE,FE,FF"); + EEL_CHECK_STRING_RESULT (check_average_value (1, 1, "FF,FF,FF"), "FF,FF,FF,FF"); + EEL_CHECK_STRING_RESULT (check_average_value (1, 1, "FF,FF,FF,00"), "00,00,00,00"); + EEL_CHECK_STRING_RESULT (check_average_value (1, 1, "11,22,33"), "11,22,33,FF"); + EEL_CHECK_STRING_RESULT (check_average_value (1000, 1000, "00,00,00"), "00,00,00,FF"); + EEL_CHECK_STRING_RESULT (check_average_value (1000, 1000, "00,00,00,00"), "00,00,00,00"); + EEL_CHECK_STRING_RESULT (check_average_value (1000, 1000, "00,00,00,FF"), "00,00,00,FF"); + EEL_CHECK_STRING_RESULT (check_average_value (1000, 1000, "01,01,01"), "01,01,01,FF"); + EEL_CHECK_STRING_RESULT (check_average_value (1000, 1000, "FE,FE,FE"), "FE,FE,FE,FF"); + EEL_CHECK_STRING_RESULT (check_average_value (1000, 1000, "FF,FF,FF"), "FF,FF,FF,FF"); + EEL_CHECK_STRING_RESULT (check_average_value (1000, 1000, "FF,FF,FF,00"), "00,00,00,00"); + EEL_CHECK_STRING_RESULT (check_average_value (1000, 1000, "11,22,33"), "11,22,33,FF"); + EEL_CHECK_STRING_RESULT (check_average_value (1000, 1000, "gray -1"), "7F,7F,7F,FF"); + EEL_CHECK_STRING_RESULT (check_average_value (1000, 1000, "gray 0"), "80,80,80,FF"); + EEL_CHECK_STRING_RESULT (check_average_value (1000, 1000, "gray 1"), "80,80,80,FF"); +} + +#endif /* !EEL_OMIT_SELF_CHECK */ + diff --git a/eel/eel-gdk-pixbuf-extensions.h b/eel/eel-gdk-pixbuf-extensions.h new file mode 100644 index 00000000..cb66348c --- /dev/null +++ b/eel/eel-gdk-pixbuf-extensions.h @@ -0,0 +1,162 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* eel-gdk-pixbuf-extensions.h: Routines to augment what's in gdk-pixbuf. + + Copyright (C) 2000 Eazel, Inc. + + The Mate Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Mate Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Mate Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Authors: Darin Adler + Ramiro Estrugo +*/ + +#ifndef EEL_GDK_PIXBUF_EXTENSIONS_H +#define EEL_GDK_PIXBUF_EXTENSIONS_H + +#include +#include +#include +#include + +#define EEL_STANDARD_ALPHA_THRESHHOLD 128 +#define EEL_OPACITY_FULLY_TRANSPARENT 0 +#define EEL_OPACITY_FULLY_OPAQUE 255 + +extern const EelIRect eel_gdk_pixbuf_whole_pixbuf; + +typedef struct EelPixbufLoadHandle EelPixbufLoadHandle; +typedef void (* EelPixbufLoadCallback) (GError *error, + GdkPixbuf *pixbuf, + gpointer callback_data); + +/* Convenience functions for lists of GdkPixbuf objects. */ +void eel_gdk_pixbuf_list_ref (GList *pixbuf_list); +void eel_gdk_pixbuf_list_unref (GList *pixbuf_list); +void eel_gdk_pixbuf_list_free (GList *pixbuf_list); + + +/* Loading a GdkPixbuf with a URI. */ +GdkPixbuf * eel_gdk_pixbuf_load (const char *uri); +GdkPixbuf * eel_gdk_pixbuf_load_from_stream (GInputStream *stream); +GdkPixbuf * eel_gdk_pixbuf_load_from_stream_at_size (GInputStream *stream, + int size); + + +/* Same thing async. */ +EelPixbufLoadHandle *eel_gdk_pixbuf_load_async (const char *uri, + int priority, + EelPixbufLoadCallback callback, + gpointer callback_data); +void eel_cancel_gdk_pixbuf_load (EelPixbufLoadHandle *handle); +GdkPixbuf * eel_gdk_pixbuf_scale_down_to_fit (GdkPixbuf *pixbuf, + int max_width, + int max_height); +GdkPixbuf * eel_gdk_pixbuf_scale_to_fit (GdkPixbuf *pixbuf, + int max_width, + int max_height); +double eel_gdk_scale_to_fit_factor (int width, + int height, + int max_width, + int max_height, + int *scaled_width, + int *scaled_height); +GdkPixbuf * eel_gdk_pixbuf_scale_to_min (GdkPixbuf *pixbuf, + int min_width, + int min_height); +double eel_gdk_scale_to_min_factor (int width, + int height, + int min_width, + int min_height, + int *scaled_width, + int *scaled_height); + +/* return average color values for each component (argb) */ +guint32 eel_gdk_pixbuf_average_value (GdkPixbuf *pixbuf); +void eel_gdk_pixbuf_fill_rectangle_with_color (GdkPixbuf *pixbuf, + EelIRect area, + guint32 color); + + +/* Save a pixbuf to a png file. Return value indicates succss/TRUE or failure/FALSE */ +gboolean eel_gdk_pixbuf_save_to_file (const GdkPixbuf *pixbuf, + const char *file_name); +void eel_gdk_pixbuf_ref_if_not_null (GdkPixbuf *pixbuf_or_null); +void eel_gdk_pixbuf_unref_if_not_null (GdkPixbuf *pixbuf_or_null); + + +/* Copy a pixbuf to an area of a GdkDrawable */ +void eel_gdk_pixbuf_draw_to_drawable (const GdkPixbuf *pixbuf, + GdkDrawable *drawable, + GdkGC *gc, + int source_x, + int source_y, + EelIRect destination_area, + GdkRgbDither dither, + GdkPixbufAlphaMode alpha_compositing_mode, + int alpha_threshold); + +/* Copy a pixbuf to an area of another pixbuf */ +void eel_gdk_pixbuf_draw_to_pixbuf (const GdkPixbuf *pixbuf, + GdkPixbuf *destination_pixbuf, + int source_x, + int source_y, + EelIRect destination_area); + + +/* Composite one pixbuf over another with the given opacity */ +void eel_gdk_pixbuf_draw_to_pixbuf_alpha (const GdkPixbuf *pixbuf, + GdkPixbuf *destination_pixbuf, + int source_x, + int source_y, + EelIRect destination_area, + int opacity, + GdkInterpType interpolation_mode); + + +/* Create a pixbuf from a sub area of another pixbuf */ +GdkPixbuf * eel_gdk_pixbuf_new_from_pixbuf_sub_area (GdkPixbuf *pixbuf, + EelIRect area); +/* Create a pixbuf from an existing buffer. */ +GdkPixbuf * eel_gdk_pixbuf_new_from_existing_buffer (guchar *buffer, + int buffer_rowstride, + gboolean buffer_has_alpha, + EelIRect area); + +/* Determine whether a pixbuf is valid or not */ +gboolean eel_gdk_pixbuf_is_valid (const GdkPixbuf *pixbuf); + +/* Access the dimensions of a pixbuf. */ +EelDimensions eel_gdk_pixbuf_get_dimensions (const GdkPixbuf *pixbuf); + +/* Return the intersection of the pixbuf with the given rectangle. */ +EelIRect eel_gdk_pixbuf_intersect (const GdkPixbuf *pixbuf, + int pixbuf_x, + int pixbuf_y, + EelIRect rectangle); + +/* Scales large pixbufs down fast */ +GdkPixbuf * eel_gdk_pixbuf_scale_down (GdkPixbuf *pixbuf, + int dest_width, + int dest_height); + +GdkPixbuf * eel_gdk_pixbuf_render (GdkPixbuf *pixbuf, + guint render_mode, + guint saturation, + guint brightness, + guint lighten_value, + guint color); + +#endif /* EEL_GDK_PIXBUF_EXTENSIONS_H */ diff --git a/eel/eel-glib-extensions.c b/eel/eel-glib-extensions.c new file mode 100644 index 00000000..b72029fd --- /dev/null +++ b/eel/eel-glib-extensions.c @@ -0,0 +1,1231 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* eel-glib-extensions.c - implementation of new functions that conceptually + belong in glib. Perhaps some of these will be + actually rolled into glib someday. + + Copyright (C) 2000 Eazel, Inc. + + The Mate Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Mate Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Mate Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Authors: John Sullivan +*/ + +#include +#include "eel-glib-extensions.h" + +#include "eel-debug.h" +#include "eel-lib-self-check-functions.h" +#include "eel-string.h" +#include "eel-i18n.h" +#include +#include +#include +#include +#include +#include +#include + +/* Legal conversion specifiers, as specified in the C standard. */ +#define C_STANDARD_STRFTIME_CHARACTERS "aAbBcdHIjmMpSUwWxXyYZ" +#define C_STANDARD_NUMERIC_STRFTIME_CHARACTERS "dHIjmMSUwWyY" +#define SUS_EXTENDED_STRFTIME_MODIFIERS "EO" + +#define SAFE_SHELL_CHARACTERS "-_0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + +typedef struct +{ + GHashTable *hash_table; + char *display_name; + gboolean keys_known_to_be_strings; +} HashTableToFree; + +static GList *hash_tables_to_free_at_exit; + +/** + * eel_g_date_new_tm: + * + * Get a new GDate * for the date represented by a tm struct. + * The caller is responsible for g_free-ing the result. + * @time_pieces: Pointer to a tm struct representing the date to be converted. + * + * Returns: Newly allocated date. + * + **/ +GDate * +eel_g_date_new_tm (struct tm *time_pieces) +{ + /* tm uses 0-based months; GDate uses 1-based months. + * tm_year needs 1900 added to get the full year. + */ + return g_date_new_dmy (time_pieces->tm_mday, + time_pieces->tm_mon + 1, + time_pieces->tm_year + 1900); +} + +/** + * eel_strdup_strftime: + * + * Cover for standard date-and-time-formatting routine strftime that returns + * a newly-allocated string of the correct size. The caller is responsible + * for g_free-ing the returned string. + * + * Besides the buffer management, there are two differences between this + * and the library strftime: + * + * 1) The modifiers "-" and "_" between a "%" and a numeric directive + * are defined as for the GNU version of strftime. "-" means "do not + * pad the field" and "_" means "pad with spaces instead of zeroes". + * 2) Non-ANSI extensions to strftime are flagged at runtime with a + * warning, so it's easy to notice use of the extensions without + * testing with multiple versions of the library. + * + * @format: format string to pass to strftime. See strftime documentation + * for details. + * @time_pieces: date/time, in struct format. + * + * Return value: Newly allocated string containing the formatted time. + **/ +char * +eel_strdup_strftime (const char *format, struct tm *time_pieces) +{ + GString *string; + const char *remainder, *percent; + char code[4], buffer[512]; + char *piece, *result, *converted; + size_t string_length; + gboolean strip_leading_zeros, turn_leading_zeros_to_spaces; + char modifier; + int i; + + /* Format could be translated, and contain UTF-8 chars, + * so convert to locale encoding which strftime uses */ + converted = g_locale_from_utf8 (format, -1, NULL, NULL, NULL); + g_return_val_if_fail (converted != NULL, NULL); + + string = g_string_new (""); + remainder = converted; + + /* Walk from % character to % character. */ + for (;;) + { + percent = strchr (remainder, '%'); + if (percent == NULL) + { + g_string_append (string, remainder); + break; + } + g_string_append_len (string, remainder, + percent - remainder); + + /* Handle the "%" character. */ + remainder = percent + 1; + switch (*remainder) + { + case '-': + strip_leading_zeros = TRUE; + turn_leading_zeros_to_spaces = FALSE; + remainder++; + break; + case '_': + strip_leading_zeros = FALSE; + turn_leading_zeros_to_spaces = TRUE; + remainder++; + break; + case '%': + g_string_append_c (string, '%'); + remainder++; + continue; + case '\0': + g_warning ("Trailing %% passed to eel_strdup_strftime"); + g_string_append_c (string, '%'); + continue; + default: + strip_leading_zeros = FALSE; + turn_leading_zeros_to_spaces = FALSE; + break; + } + + modifier = 0; + if (strchr (SUS_EXTENDED_STRFTIME_MODIFIERS, *remainder) != NULL) + { + modifier = *remainder; + remainder++; + + if (*remainder == 0) + { + g_warning ("Unfinished %%%c modifier passed to eel_strdup_strftime", modifier); + break; + } + } + + if (strchr (C_STANDARD_STRFTIME_CHARACTERS, *remainder) == NULL) + { + g_warning ("eel_strdup_strftime does not support " + "non-standard escape code %%%c", + *remainder); + } + + /* Convert code to strftime format. We have a fixed + * limit here that each code can expand to a maximum + * of 512 bytes, which is probably OK. There's no + * limit on the total size of the result string. + */ + i = 0; + code[i++] = '%'; + if (modifier != 0) + { +#ifdef HAVE_STRFTIME_EXTENSION + code[i++] = modifier; +#endif + } + code[i++] = *remainder; + code[i++] = '\0'; + string_length = strftime (buffer, sizeof (buffer), + code, time_pieces); + if (string_length == 0) + { + /* We could put a warning here, but there's no + * way to tell a successful conversion to + * empty string from a failure. + */ + buffer[0] = '\0'; + } + + /* Strip leading zeros if requested. */ + piece = buffer; + if (strip_leading_zeros || turn_leading_zeros_to_spaces) + { + if (strchr (C_STANDARD_NUMERIC_STRFTIME_CHARACTERS, *remainder) == NULL) + { + g_warning ("eel_strdup_strftime does not support " + "modifier for non-numeric escape code %%%c%c", + remainder[-1], + *remainder); + } + if (*piece == '0') + { + do + { + piece++; + } + while (*piece == '0'); + if (!g_ascii_isdigit (*piece)) + { + piece--; + } + } + if (turn_leading_zeros_to_spaces) + { + memset (buffer, ' ', piece - buffer); + piece = buffer; + } + } + remainder++; + + /* Add this piece. */ + g_string_append (string, piece); + } + + /* Convert the string back into utf-8. */ + result = g_locale_to_utf8 (string->str, -1, NULL, NULL, NULL); + + g_string_free (string, TRUE); + g_free (converted); + + return result; +} + +/** + * eel_g_list_exactly_one_item + * + * Like g_list_length (list) == 1, only O(1) instead of O(n). + * @list: List. + * + * Return value: TRUE if the list has exactly one item. + **/ +gboolean +eel_g_list_exactly_one_item (GList *list) +{ + return list != NULL && list->next == NULL; +} + +/** + * eel_g_list_more_than_one_item + * + * Like g_list_length (list) > 1, only O(1) instead of O(n). + * @list: List. + * + * Return value: TRUE if the list has more than one item. + **/ +gboolean +eel_g_list_more_than_one_item (GList *list) +{ + return list != NULL && list->next != NULL; +} + +/** + * eel_g_list_equal + * + * Compares two lists to see if they are equal. + * @list_a: First list. + * @list_b: Second list. + * + * Return value: TRUE if the lists are the same length with the same elements. + **/ +gboolean +eel_g_list_equal (GList *list_a, GList *list_b) +{ + GList *p, *q; + + for (p = list_a, q = list_b; p != NULL && q != NULL; p = p->next, q = q->next) + { + if (p->data != q->data) + { + return FALSE; + } + } + return p == NULL && q == NULL; +} + +/** + * eel_g_str_list_equal + * + * Compares two lists of C strings to see if they are equal. + * @list_a: First list. + * @list_b: Second list. + * + * Return value: TRUE if the lists contain the same strings. + **/ +gboolean +eel_g_str_list_equal (GList *list_a, GList *list_b) +{ + GList *p, *q; + + for (p = list_a, q = list_b; p != NULL && q != NULL; p = p->next, q = q->next) + { + if (eel_strcmp (p->data, q->data) != 0) + { + return FALSE; + } + } + return p == NULL && q == NULL; +} + +/** + * eel_g_str_list_copy + * + * @list: List of strings and/or NULLs to copy. + * Return value: Deep copy of @list. + **/ +GList * +eel_g_str_list_copy (GList *list) +{ + GList *node, *result; + + result = NULL; + + for (node = g_list_last (list); node != NULL; node = node->prev) + { + result = g_list_prepend (result, g_strdup (node->data)); + } + return result; +} + +/** + * eel_g_str_list_alphabetize + * + * Sort a list of strings using locale-sensitive rules. + * + * @list: List of strings and/or NULLs. + * + * Return value: @list, sorted. + **/ +GList * +eel_g_str_list_alphabetize (GList *list) +{ + return g_list_sort (list, (GCompareFunc) g_utf8_collate); +} + +int +eel_g_str_list_index (GList *str_list, + const char *str) +{ + int i; + GList *l; + for (i = 0, l = str_list; l != NULL; l = l->next, i++) + { + if (!strcmp (str, (const char*)l->data)) + { + return i; + } + } + return -1; +} + +/** + * eel_g_list_free_deep_custom + * + * Frees the elements of a list and then the list, using a custom free function. + * + * @list: List of elements that can be freed with the provided free function. + * @element_free_func: function to call with the data pointer and user_data to free it. + * @user_data: User data to pass to element_free_func + **/ +void +eel_g_list_free_deep_custom (GList *list, GFunc element_free_func, gpointer user_data) +{ + g_list_foreach (list, element_free_func, user_data); + g_list_free (list); +} + +/** + * eel_g_list_free_deep + * + * Frees the elements of a list and then the list. + * @list: List of elements that can be freed with g_free. + **/ +void +eel_g_list_free_deep (GList *list) +{ + eel_g_list_free_deep_custom (list, (GFunc) g_free, NULL); +} + +/** + * eel_g_list_free_deep_custom + * + * Frees the elements of a list and then the list, using a custom free function. + * + * @list: List of elements that can be freed with the provided free function. + * @element_free_func: function to call with the data pointer and user_data to free it. + * @user_data: User data to pass to element_free_func + **/ +void +eel_g_slist_free_deep_custom (GSList *list, GFunc element_free_func, gpointer user_data) +{ + g_slist_foreach (list, element_free_func, user_data); + g_slist_free (list); +} + +/** + * eel_g_slist_free_deep + * + * Frees the elements of a list and then the list. + * @list: List of elements that can be freed with g_free. + **/ +void +eel_g_slist_free_deep (GSList *list) +{ + eel_g_slist_free_deep_custom (list, (GFunc) g_free, NULL); +} + + +/** + * eel_g_strv_find + * + * Get index of string in array of strings. + * + * @strv: NULL-terminated array of strings. + * @find_me: string to search for. + * + * Return value: index of array entry in @strv that + * matches @find_me, or -1 if no matching entry. + */ +int +eel_g_strv_find (char **strv, const char *find_me) +{ + int index; + + g_return_val_if_fail (find_me != NULL, -1); + + for (index = 0; strv[index] != NULL; ++index) + { + if (strcmp (strv[index], find_me) == 0) + { + return index; + } + } + + return -1; +} + +gboolean +eel_g_strv_equal (char **a, char **b) +{ + int i; + + if (g_strv_length (a) != g_strv_length (b)) + { + return FALSE; + } + + for (i = 0; a[i] != NULL; i++) + { + if (strcmp (a[i], b[i]) != 0) + { + return FALSE; + } + } + return TRUE; +} + +static int +compare_pointers (gconstpointer pointer_1, gconstpointer pointer_2) +{ + if ((const char *) pointer_1 < (const char *) pointer_2) + { + return -1; + } + if ((const char *) pointer_1 > (const char *) pointer_2) + { + return +1; + } + return 0; +} + +gboolean +eel_g_lists_sort_and_check_for_intersection (GList **list_1, + GList **list_2) + +{ + GList *node_1, *node_2; + int compare_result; + + *list_1 = g_list_sort (*list_1, compare_pointers); + *list_2 = g_list_sort (*list_2, compare_pointers); + + node_1 = *list_1; + node_2 = *list_2; + + while (node_1 != NULL && node_2 != NULL) + { + compare_result = compare_pointers (node_1->data, node_2->data); + if (compare_result == 0) + { + return TRUE; + } + if (compare_result <= 0) + { + node_1 = node_1->next; + } + if (compare_result >= 0) + { + node_2 = node_2->next; + } + } + + return FALSE; +} + + +/** + * eel_g_list_partition + * + * Parition a list into two parts depending on whether the data + * elements satisfy a provided predicate. Order is preserved in both + * of the resulting lists, and the original list is consumed. A list + * of the items that satisfy the predicate is returned, and the list + * of items not satisfying the predicate is returned via the failed + * out argument. + * + * @list: List to partition. + * @predicate: Function to call on each element. + * @user_data: Data to pass to function. + * @failed: The GList * variable pointed to by this argument will be + * set to the list of elements for which the predicate returned + * false. */ + +GList * +eel_g_list_partition (GList *list, + EelPredicateFunction predicate, + gpointer user_data, + GList **failed) +{ + GList *predicate_true; + GList *predicate_false; + GList *reverse; + GList *p; + GList *next; + + predicate_true = NULL; + predicate_false = NULL; + + reverse = g_list_reverse (list); + + for (p = reverse; p != NULL; p = next) + { + next = p->next; + + if (next != NULL) + { + next->prev = NULL; + } + + if (predicate (p->data, user_data)) + { + p->next = predicate_true; + if (predicate_true != NULL) + { + predicate_true->prev = p; + } + predicate_true = p; + } + else + { + p->next = predicate_false; + if (predicate_false != NULL) + { + predicate_false->prev = p; + } + predicate_false = p; + } + } + + *failed = predicate_false; + return predicate_true; +} + +/** + * eel_get_system_time + * + * Return value: number of microseconds since the machine was turned on + */ +gint64 +eel_get_system_time (void) +{ + struct timeval tmp; + + gettimeofday (&tmp, NULL); + return (gint64)tmp.tv_usec + (gint64)tmp.tv_sec * G_GINT64_CONSTANT (1000000); +} + +static void +print_key_string (gpointer key, gpointer value, gpointer callback_data) +{ + g_assert (callback_data == NULL); + + g_print ("--> %s\n", (char *) key); +} + +static void +free_hash_tables_at_exit (void) +{ + GList *p; + HashTableToFree *hash_table_to_free; + guint size; + + for (p = hash_tables_to_free_at_exit; p != NULL; p = p->next) + { + hash_table_to_free = p->data; + + size = g_hash_table_size (hash_table_to_free->hash_table); + if (size != 0) + { + if (hash_table_to_free->keys_known_to_be_strings) + { + g_print ("\n--- Hash table keys for warning below:\n"); + g_hash_table_foreach (hash_table_to_free->hash_table, + print_key_string, + NULL); + } + g_warning ("\"%s\" hash table still has %u element%s at quit time%s", + hash_table_to_free->display_name, size, + size == 1 ? "" : "s", + hash_table_to_free->keys_known_to_be_strings + ? " (keys above)" : ""); + } + + g_hash_table_destroy (hash_table_to_free->hash_table); + g_free (hash_table_to_free->display_name); + g_free (hash_table_to_free); + } + g_list_free (hash_tables_to_free_at_exit); + hash_tables_to_free_at_exit = NULL; +} + +GHashTable * +eel_g_hash_table_new_free_at_exit (GHashFunc hash_func, + GCompareFunc key_compare_func, + const char *display_name) +{ + GHashTable *hash_table; + HashTableToFree *hash_table_to_free; + + /* FIXME: We can take out the CAJA_DEBUG check once we + * have fixed more of the leaks. For now, it's a bit too noisy + * for the general public. + */ + if (hash_tables_to_free_at_exit == NULL) + { + eel_debug_call_at_shutdown (free_hash_tables_at_exit); + } + + hash_table = g_hash_table_new (hash_func, key_compare_func); + + hash_table_to_free = g_new (HashTableToFree, 1); + hash_table_to_free->hash_table = hash_table; + hash_table_to_free->display_name = g_strdup (display_name); + hash_table_to_free->keys_known_to_be_strings = + hash_func == g_str_hash; + + hash_tables_to_free_at_exit = g_list_prepend + (hash_tables_to_free_at_exit, hash_table_to_free); + + return hash_table; +} + +typedef struct +{ + GList *keys; + GList *values; +} FlattenedHashTable; + +static void +flatten_hash_table_element (gpointer key, gpointer value, gpointer callback_data) +{ + FlattenedHashTable *flattened_table; + + flattened_table = callback_data; + flattened_table->keys = g_list_prepend + (flattened_table->keys, key); + flattened_table->values = g_list_prepend + (flattened_table->values, value); +} + +void +eel_g_hash_table_safe_for_each (GHashTable *hash_table, + GHFunc callback, + gpointer callback_data) +{ + FlattenedHashTable flattened; + GList *p, *q; + + flattened.keys = NULL; + flattened.values = NULL; + + g_hash_table_foreach (hash_table, + flatten_hash_table_element, + &flattened); + + for (p = flattened.keys, q = flattened.values; + p != NULL; + p = p->next, q = q->next) + { + (* callback) (p->data, q->data, callback_data); + } + + g_list_free (flattened.keys); + g_list_free (flattened.values); +} + +int +eel_round (double d) +{ + double val; + + val = floor (d + .5); + + /* The tests are needed because the result of floating-point to integral + * conversion is undefined if the floating point value is not representable + * in the new type. E.g. the magnititude is too large or a negative + * floating-point value being converted to an unsigned. + */ + g_return_val_if_fail (val <= INT_MAX, INT_MAX); + g_return_val_if_fail (val >= INT_MIN, INT_MIN); + + return val; +} + +GList * +eel_g_list_from_g_slist (GSList *slist) +{ + GList *list; + GSList *node; + + list = NULL; + for (node = slist; node != NULL; node = node->next) + { + list = g_list_prepend (list, node->data); + } + return g_list_reverse (list); +} + +GSList * +eel_g_slist_from_g_list (GList *list) +{ + GSList *slist; + GList *node; + + slist = NULL; + for (node = list; node != NULL; node = node->next) + { + slist = g_slist_prepend (slist, node->data); + } + return g_slist_reverse (slist); +} + +/* Return the operating system name: Linux, Solaris, etc. */ +char * +eel_get_operating_system_name (void) +{ + struct utsname buffer; + + if (uname (&buffer) != -1) + { + /* Check for special sysnames for which there is + * more accepted names. + */ + if (eel_str_is_equal (buffer.sysname, "SunOS")) + { + return g_strdup ("Solaris"); + } + + return g_strdup (buffer.sysname); + } + + return g_strdup ("Unix"); +} + +int +eel_compare_integer (gconstpointer a, + gconstpointer b) +{ + int int_a; + int int_b; + + int_a = GPOINTER_TO_INT (a); + int_b = GPOINTER_TO_INT (b); + + if (int_a == int_b) + { + return 0; + } + + return int_a < int_b ? -1 : 1; +} + +/** + * eel_g_object_list_ref + * + * Ref all the objects in a list. + * @list: GList of objects. + **/ +GList * +eel_g_object_list_ref (GList *list) +{ + g_list_foreach (list, (GFunc) g_object_ref, NULL); + return list; +} + +/** + * eel_g_object_list_unref + * + * Unref all the objects in a list. + * @list: GList of objects. + **/ +void +eel_g_object_list_unref (GList *list) +{ + g_list_foreach (list, (GFunc) g_object_unref, NULL); +} + +/** + * eel_g_object_list_free + * + * Free a list of objects after unrefing them. + * @list: GList of objects. + **/ +void +eel_g_object_list_free (GList *list) +{ + eel_g_object_list_unref (list); + g_list_free (list); +} + +/** + * eel_g_object_list_copy + * + * Copy the list of objects, ref'ing each one. + * @list: GList of objects. + **/ +GList * +eel_g_object_list_copy (GList *list) +{ + return g_list_copy (eel_g_object_list_ref (list)); +} + +/** + * eel_add_weak_pointer + * + * Nulls out a saved reference to an object when the object gets destroyed. + * + * @pointer_location: Address of the saved pointer. + **/ +void +eel_add_weak_pointer (gpointer pointer_location) +{ + gpointer *object_location; + + g_return_if_fail (pointer_location != NULL); + + object_location = (gpointer *) pointer_location; + if (*object_location == NULL) + { + /* The reference is NULL, nothing to do. */ + return; + } + + g_return_if_fail (G_IS_OBJECT (*object_location)); + + g_object_add_weak_pointer (G_OBJECT (*object_location), + object_location); +} + +/** + * eel_remove_weak_pointer + * + * Removes the weak pointer that was added by eel_add_weak_pointer. + * Also nulls out the pointer. + * + * @pointer_location: Pointer that was passed to eel_add_weak_pointer. + **/ +void +eel_remove_weak_pointer (gpointer pointer_location) +{ + gpointer *object_location; + + g_return_if_fail (pointer_location != NULL); + + object_location = (gpointer *) pointer_location; + if (*object_location == NULL) + { + /* The object was already destroyed and the reference + * nulled out, nothing to do. + */ + return; + } + + g_return_if_fail (G_IS_OBJECT (*object_location)); + + g_object_remove_weak_pointer (G_OBJECT (*object_location), + object_location); + + *object_location = NULL; +} + +/* Get the filename encoding, returns TRUE if utf8 */ + +typedef struct _EelFilenameCharsetCache EelFilenameCharsetCache; + +struct _EelFilenameCharsetCache +{ + gboolean is_utf8; + gchar *charset; + gchar *filename_charset; +}; + +static void +filename_charset_cache_free (gpointer data) +{ + EelFilenameCharsetCache *cache = data; + g_free (cache->charset); + g_free (cache->filename_charset); + g_free (cache); +} + +/* + * eel_get_filename_charset: + * @charset: return location for the name of the filename encoding + * + * Determines the character set used for filenames by consulting the + * environment variables G_FILENAME_ENCODING and G_BROKEN_FILENAMES. + * + * G_FILENAME_ENCODING may be set to a comma-separated list of character + * set names. The special token "@locale" is taken to mean the character set + * for the current locale. The first character set from the list is taken + * as the filename encoding. + * If G_FILENAME_ENCODING is not set, but G_BROKEN_FILENAMES is, the + * character set of the current locale is taken as the filename encoding. + * + * The returned @charset belongs to Eel and must not be freed. + * + * Return value: %TRUE if the charset used for filename is UTF-8. + */ +gboolean +eel_get_filename_charset (const gchar **filename_charset) +{ + static GStaticPrivate cache_private = G_STATIC_PRIVATE_INIT; + EelFilenameCharsetCache *cache = g_static_private_get (&cache_private); + const gchar *charset; + + if (!cache) + { + cache = g_new0 (EelFilenameCharsetCache, 1); + g_static_private_set (&cache_private, cache, filename_charset_cache_free); + } + + g_get_charset (&charset); + + if (!(cache->charset && strcmp (cache->charset, charset) == 0)) + { + const gchar *new_charset; + gchar *p, *q; + + g_free (cache->charset); + g_free (cache->filename_charset); + cache->charset = g_strdup (charset); + + p = getenv ("G_FILENAME_ENCODING"); + if (p != NULL) + { + q = strchr (p, ','); + if (!q) + q = p + strlen (p); + + if (strncmp ("@locale", p, q - p) == 0) + { + cache->is_utf8 = g_get_charset (&new_charset); + cache->filename_charset = g_strdup (new_charset); + } + else + { + cache->filename_charset = g_strndup (p, q - p); + cache->is_utf8 = (strcmp (cache->filename_charset, "UTF-8") == 0); + } + } + else if (getenv ("G_BROKEN_FILENAMES") != NULL) + { + cache->is_utf8 = g_get_charset (&new_charset); + cache->filename_charset = g_strdup (new_charset); + } + else + { + cache->filename_charset = g_strdup ("UTF-8"); + cache->is_utf8 = TRUE; + } + } + + if (filename_charset) + *filename_charset = cache->filename_charset; + + return cache->is_utf8; +} + +#if !defined (EEL_OMIT_SELF_CHECK) + +static void +check_tm_to_g_date (time_t time) +{ + struct tm *before_conversion; + struct tm after_conversion; + GDate *date; + + before_conversion = localtime (&time); + date = eel_g_date_new_tm (before_conversion); + + g_date_to_struct_tm (date, &after_conversion); + + g_date_free (date); + + EEL_CHECK_INTEGER_RESULT (after_conversion.tm_mday, + before_conversion->tm_mday); + EEL_CHECK_INTEGER_RESULT (after_conversion.tm_mon, + before_conversion->tm_mon); + EEL_CHECK_INTEGER_RESULT (after_conversion.tm_year, + before_conversion->tm_year); +} + +static gboolean +eel_test_predicate (gpointer data, + gpointer callback_data) +{ + return g_ascii_strcasecmp (data, callback_data) <= 0; +} + +static char * +test_strftime (const char *format, + int year, + int month, + int day, + int hour, + int minute, + int second) +{ + struct tm time_pieces; + + time_pieces.tm_sec = second; + time_pieces.tm_min = minute; + time_pieces.tm_hour = hour; + time_pieces.tm_mday = day; + time_pieces.tm_mon = month - 1; + time_pieces.tm_year = year - 1900; + time_pieces.tm_isdst = -1; + mktime (&time_pieces); + + return eel_strdup_strftime (format, &time_pieces); +} + +void +eel_self_check_glib_extensions (void) +{ + char **strv; + GList *compare_list_1; + GList *compare_list_2; + GList *compare_list_3; + GList *compare_list_4; + GList *compare_list_5; + gint64 time1, time2; + GList *list_to_partition; + GList *expected_passed; + GList *expected_failed; + GList *actual_passed; + GList *actual_failed; + char *huge_string; + + check_tm_to_g_date (0); /* lower limit */ + check_tm_to_g_date ((time_t) -1); /* upper limit */ + check_tm_to_g_date (time (NULL)); /* current time */ + + strv = g_strsplit ("zero|one|two|three|four", "|", 0); + EEL_CHECK_INTEGER_RESULT (eel_g_strv_find (strv, "zero"), 0); + EEL_CHECK_INTEGER_RESULT (eel_g_strv_find (strv, "one"), 1); + EEL_CHECK_INTEGER_RESULT (eel_g_strv_find (strv, "four"), 4); + EEL_CHECK_INTEGER_RESULT (eel_g_strv_find (strv, "five"), -1); + EEL_CHECK_INTEGER_RESULT (eel_g_strv_find (strv, ""), -1); + EEL_CHECK_INTEGER_RESULT (eel_g_strv_find (strv, "o"), -1); + g_strfreev (strv); + + /* eel_get_system_time */ + time1 = eel_get_system_time (); + time2 = eel_get_system_time (); + EEL_CHECK_BOOLEAN_RESULT (time1 - time2 > -1000, TRUE); + EEL_CHECK_BOOLEAN_RESULT (time1 - time2 <= 0, TRUE); + + /* eel_g_str_list_equal */ + + /* We g_strdup because identical string constants can be shared. */ + + compare_list_1 = NULL; + compare_list_1 = g_list_append (compare_list_1, g_strdup ("Apple")); + compare_list_1 = g_list_append (compare_list_1, g_strdup ("zebra")); + compare_list_1 = g_list_append (compare_list_1, g_strdup ("!@#!@$#@$!")); + + compare_list_2 = NULL; + compare_list_2 = g_list_append (compare_list_2, g_strdup ("Apple")); + compare_list_2 = g_list_append (compare_list_2, g_strdup ("zebra")); + compare_list_2 = g_list_append (compare_list_2, g_strdup ("!@#!@$#@$!")); + + compare_list_3 = NULL; + compare_list_3 = g_list_append (compare_list_3, g_strdup ("Apple")); + compare_list_3 = g_list_append (compare_list_3, g_strdup ("zebra")); + + compare_list_4 = NULL; + compare_list_4 = g_list_append (compare_list_4, g_strdup ("Apple")); + compare_list_4 = g_list_append (compare_list_4, g_strdup ("zebra")); + compare_list_4 = g_list_append (compare_list_4, g_strdup ("!@#!@$#@$!")); + compare_list_4 = g_list_append (compare_list_4, g_strdup ("foobar")); + + compare_list_5 = NULL; + compare_list_5 = g_list_append (compare_list_5, g_strdup ("Apple")); + compare_list_5 = g_list_append (compare_list_5, g_strdup ("zzzzzebraaaaaa")); + compare_list_5 = g_list_append (compare_list_5, g_strdup ("!@#!@$#@$!")); + + EEL_CHECK_BOOLEAN_RESULT (eel_g_str_list_equal (compare_list_1, compare_list_2), TRUE); + EEL_CHECK_BOOLEAN_RESULT (eel_g_str_list_equal (compare_list_1, compare_list_3), FALSE); + EEL_CHECK_BOOLEAN_RESULT (eel_g_str_list_equal (compare_list_1, compare_list_4), FALSE); + EEL_CHECK_BOOLEAN_RESULT (eel_g_str_list_equal (compare_list_1, compare_list_5), FALSE); + + eel_g_list_free_deep (compare_list_1); + eel_g_list_free_deep (compare_list_2); + eel_g_list_free_deep (compare_list_3); + eel_g_list_free_deep (compare_list_4); + eel_g_list_free_deep (compare_list_5); + + /* eel_g_list_partition */ + + list_to_partition = NULL; + list_to_partition = g_list_append (list_to_partition, "Cadillac"); + list_to_partition = g_list_append (list_to_partition, "Pontiac"); + list_to_partition = g_list_append (list_to_partition, "Ford"); + list_to_partition = g_list_append (list_to_partition, "Range Rover"); + + expected_passed = NULL; + expected_passed = g_list_append (expected_passed, "Cadillac"); + expected_passed = g_list_append (expected_passed, "Ford"); + + expected_failed = NULL; + expected_failed = g_list_append (expected_failed, "Pontiac"); + expected_failed = g_list_append (expected_failed, "Range Rover"); + + actual_passed = eel_g_list_partition (list_to_partition, + eel_test_predicate, + "m", + &actual_failed); + + EEL_CHECK_BOOLEAN_RESULT (eel_g_str_list_equal (expected_passed, actual_passed), TRUE); + EEL_CHECK_BOOLEAN_RESULT (eel_g_str_list_equal (expected_failed, actual_failed), TRUE); + + /* Don't free "list_to_partition", since it is consumed + * by eel_g_list_partition. + */ + + g_list_free (expected_passed); + g_list_free (actual_passed); + g_list_free (expected_failed); + g_list_free (actual_failed); + + /* eel_strdup_strftime */ + huge_string = g_new (char, 10000+1); + memset (huge_string, 'a', 10000); + huge_string[10000] = '\0'; + + setlocale (LC_TIME, "C"); + + EEL_CHECK_STRING_RESULT (test_strftime ("", 2000, 1, 1, 0, 0, 0), ""); + EEL_CHECK_STRING_RESULT (test_strftime (huge_string, 2000, 1, 1, 0, 0, 0), huge_string); + EEL_CHECK_STRING_RESULT (test_strftime ("%%", 2000, 1, 1, 1, 0, 0), "%"); + EEL_CHECK_STRING_RESULT (test_strftime ("%%%%", 2000, 1, 1, 1, 0, 0), "%%"); + EEL_CHECK_STRING_RESULT (test_strftime ("%m/%d/%y, %I:%M %p", 2000, 1, 1, 1, 0, 0), "01/01/00, 01:00 AM"); + EEL_CHECK_STRING_RESULT (test_strftime ("%-m/%-d/%y, %-I:%M %p", 2000, 1, 1, 1, 0, 0), "1/1/00, 1:00 AM"); + EEL_CHECK_STRING_RESULT (test_strftime ("%_m/%_d/%y, %_I:%M %p", 2000, 1, 1, 1, 0, 0), " 1/ 1/00, 1:00 AM"); + + setlocale (LC_TIME, ""); + + g_free (huge_string); + + /* eel_shell_quote */ + EEL_CHECK_STRING_RESULT (g_shell_quote (""), "''"); + EEL_CHECK_STRING_RESULT (g_shell_quote ("a"), "'a'"); + EEL_CHECK_STRING_RESULT (g_shell_quote ("("), "'('"); + EEL_CHECK_STRING_RESULT (g_shell_quote ("'"), "''\\'''"); + EEL_CHECK_STRING_RESULT (g_shell_quote ("'a"), "''\\''a'"); + EEL_CHECK_STRING_RESULT (g_shell_quote ("a'"), "'a'\\'''"); + EEL_CHECK_STRING_RESULT (g_shell_quote ("a'a"), "'a'\\''a'"); + + /* eel_compare_integer */ + EEL_CHECK_INTEGER_RESULT (eel_compare_integer (GINT_TO_POINTER (0), GINT_TO_POINTER (0)), 0); + EEL_CHECK_INTEGER_RESULT (eel_compare_integer (GINT_TO_POINTER (0), GINT_TO_POINTER (1)), -1); + EEL_CHECK_INTEGER_RESULT (eel_compare_integer (GINT_TO_POINTER (1), GINT_TO_POINTER (0)), 1); + EEL_CHECK_INTEGER_RESULT (eel_compare_integer (GINT_TO_POINTER (-1), GINT_TO_POINTER (0)), -1); + EEL_CHECK_INTEGER_RESULT (eel_compare_integer (GINT_TO_POINTER (0), GINT_TO_POINTER (-1)), 1); + EEL_CHECK_INTEGER_RESULT (eel_compare_integer (GINT_TO_POINTER (-1), GINT_TO_POINTER (-1)), 0); + +#ifdef __linux__ + EEL_CHECK_STRING_RESULT (eel_get_operating_system_name (), "Linux"); +#endif +} + +#endif /* !EEL_OMIT_SELF_CHECK */ diff --git a/eel/eel-glib-extensions.h b/eel/eel-glib-extensions.h new file mode 100644 index 00000000..ac36fe7e --- /dev/null +++ b/eel/eel-glib-extensions.h @@ -0,0 +1,128 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* eel-glib-extensions.h - interface for new functions that conceptually + belong in glib. Perhaps some of these will be + actually rolled into glib someday. + + Copyright (C) 2000 Eazel, Inc. + + The Mate Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Mate Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Mate Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Authors: John Sullivan +*/ + +#ifndef EEL_GLIB_EXTENSIONS_H +#define EEL_GLIB_EXTENSIONS_H + +#include + +/* A gboolean variant for bit fields. */ +typedef guint eel_boolean_bit; + +/* Callback functions that have user data. */ +typedef int (* EelCompareFunction) (gconstpointer a, + gconstpointer b, + gpointer callback_data); +typedef int (* EelSearchFunction) (gconstpointer item, + gpointer callback_data); + +/* Predicate. */ +typedef gboolean (* EelPredicateFunction) (gpointer data, + gpointer callback_data); + +/* Date & time functions. */ +GDate * eel_g_date_new_tm (struct tm *time_pieces); +char * eel_strdup_strftime (const char *format, + struct tm *time_pieces); + +/* GList functions. */ +gboolean eel_g_list_exactly_one_item (GList *list); +gboolean eel_g_list_more_than_one_item (GList *list); +gboolean eel_g_list_equal (GList *list_a, + GList *list_b); +gboolean eel_g_lists_sort_and_check_for_intersection (GList **list_a, + GList **list_b); +GList * eel_g_list_partition (GList *list, + EelPredicateFunction predicate, + gpointer user_data, + GList **removed); + +/* List functions for lists of g_free'able objects. */ +void eel_g_list_free_deep (GList *list); +void eel_g_list_free_deep_custom (GList *list, + GFunc element_free_func, + gpointer user_data); + +/* GSList functions. */ +GList * eel_g_list_from_g_slist (GSList *list); +GSList * eel_g_slist_from_g_list (GList *list); + +/* List functions for slists of g_free'able objects. */ +void eel_g_slist_free_deep (GSList *list); +void eel_g_slist_free_deep_custom (GSList *list, + GFunc element_free_func, + gpointer user_data); + +/* List functions for lists of C strings. */ +gboolean eel_g_str_list_equal (GList *str_list_a, + GList *str_list_b); +GList * eel_g_str_list_copy (GList *str_list); +GList * eel_g_str_list_alphabetize (GList *str_list); +int eel_g_str_list_index (GList *str_list, + const char *str); + +/* List functions for lists of objects */ +GList * eel_g_object_list_ref (GList *list); +void eel_g_object_list_unref (GList *list); +void eel_g_object_list_free (GList *list); +GList * eel_g_object_list_copy (GList *list); + +/* GHashTable functions */ +GHashTable *eel_g_hash_table_new_free_at_exit (GHashFunc hash_function, + GCompareFunc key_compare_function, + const char *display_name); +void eel_g_hash_table_safe_for_each (GHashTable *hash_table, + GHFunc callback, + gpointer callback_data); + +/* NULL terminated string arrays (strv). */ +int eel_g_strv_find (char **strv, + const char *find_me); +gboolean eel_g_strv_equal (char **a, + char **b); + +/* return the time in microseconds since the machine was started */ +gint64 eel_get_system_time (void); + +/* math */ +int eel_round (double d); + +/* A GCompareFunc for integers */ +int eel_compare_integer (gconstpointer a, + gconstpointer b); + +/* Return the operating system name: Linux, Solaris, etc. */ +char * eel_get_operating_system_name (void); + +/* Better weak pointer functions */ +void eel_add_weak_pointer (gpointer pointer_location); +void eel_remove_weak_pointer (gpointer pointer_location); + +/* Get the filename encoding, returns TRUE if utf8 */ +gboolean eel_get_filename_charset (const gchar **filename_charset); + + +#endif /* EEL_GLIB_EXTENSIONS_H */ diff --git a/eel/eel-graphic-effects.c b/eel/eel-graphic-effects.c new file mode 100644 index 00000000..c96135d8 --- /dev/null +++ b/eel/eel-graphic-effects.c @@ -0,0 +1,421 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* Eel - pixbuf manipulation routines for graphical effects. + * + * Copyright (C) 2000 Eazel, Inc + * + * Author: Andy Hertzfeld + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* This file contains pixbuf manipulation routines used for graphical effects like pre-lighting + and selection hilighting */ + +#include +#include "eel-graphic-effects.h" +#include + +/* shared utility to create a new pixbuf from the passed-in one */ + +static GdkPixbuf * +create_new_pixbuf (GdkPixbuf *src) +{ + g_assert (gdk_pixbuf_get_colorspace (src) == GDK_COLORSPACE_RGB); + g_assert ((!gdk_pixbuf_get_has_alpha (src) + && gdk_pixbuf_get_n_channels (src) == 3) + || (gdk_pixbuf_get_has_alpha (src) + && gdk_pixbuf_get_n_channels (src) == 4)); + + return gdk_pixbuf_new (gdk_pixbuf_get_colorspace (src), + gdk_pixbuf_get_has_alpha (src), + gdk_pixbuf_get_bits_per_sample (src), + gdk_pixbuf_get_width (src), + gdk_pixbuf_get_height (src)); +} + +static GdkPixbuf * +create_new_pixbuf_with_alpha (GdkPixbuf *src) +{ + g_assert (gdk_pixbuf_get_colorspace (src) == GDK_COLORSPACE_RGB); + g_assert ((!gdk_pixbuf_get_has_alpha (src) + && gdk_pixbuf_get_n_channels (src) == 3) + || (gdk_pixbuf_get_has_alpha (src) + && gdk_pixbuf_get_n_channels (src) == 4)); + + return gdk_pixbuf_new (gdk_pixbuf_get_colorspace (src), + TRUE, + gdk_pixbuf_get_bits_per_sample (src), + gdk_pixbuf_get_width (src), + gdk_pixbuf_get_height (src)); +} + +/* utility routine to bump the level of a color component with pinning */ + +static guchar +lighten_component (guchar cur_value) +{ + int new_value = cur_value; + new_value += 24 + (new_value >> 3); + if (new_value > 255) + { + new_value = 255; + } + return (guchar) new_value; +} + +GdkPixbuf * +eel_create_spotlight_pixbuf (GdkPixbuf* src) +{ + GdkPixbuf *dest; + int i, j; + int width, height, has_alpha, src_row_stride, dst_row_stride; + guchar *target_pixels, *original_pixels; + guchar *pixsrc, *pixdest; + + g_return_val_if_fail (gdk_pixbuf_get_colorspace (src) == GDK_COLORSPACE_RGB, NULL); + g_return_val_if_fail ((!gdk_pixbuf_get_has_alpha (src) + && gdk_pixbuf_get_n_channels (src) == 3) + || (gdk_pixbuf_get_has_alpha (src) + && gdk_pixbuf_get_n_channels (src) == 4), NULL); + g_return_val_if_fail (gdk_pixbuf_get_bits_per_sample (src) == 8, NULL); + + dest = create_new_pixbuf (src); + + has_alpha = gdk_pixbuf_get_has_alpha (src); + width = gdk_pixbuf_get_width (src); + height = gdk_pixbuf_get_height (src); + dst_row_stride = gdk_pixbuf_get_rowstride (dest); + src_row_stride = gdk_pixbuf_get_rowstride (src); + target_pixels = gdk_pixbuf_get_pixels (dest); + original_pixels = gdk_pixbuf_get_pixels (src); + + for (i = 0; i < height; i++) + { + pixdest = target_pixels + i * dst_row_stride; + pixsrc = original_pixels + i * src_row_stride; + for (j = 0; j < width; j++) + { + *pixdest++ = lighten_component (*pixsrc++); + *pixdest++ = lighten_component (*pixsrc++); + *pixdest++ = lighten_component (*pixsrc++); + if (has_alpha) + { + *pixdest++ = *pixsrc++; + } + } + } + return dest; +} + + +/* the following routine was stolen from the panel to darken a pixbuf, by manipulating the saturation */ + +/* saturation is 0-255, darken is 0-255 */ + +GdkPixbuf * +eel_create_darkened_pixbuf (GdkPixbuf *src, int saturation, int darken) +{ + gint i, j; + gint width, height, src_row_stride, dest_row_stride; + gboolean has_alpha; + guchar *target_pixels, *original_pixels; + guchar *pixsrc, *pixdest; + guchar intensity; + guchar alpha; + guchar negalpha; + guchar r, g, b; + GdkPixbuf *dest; + + g_return_val_if_fail (gdk_pixbuf_get_colorspace (src) == GDK_COLORSPACE_RGB, NULL); + g_return_val_if_fail ((!gdk_pixbuf_get_has_alpha (src) + && gdk_pixbuf_get_n_channels (src) == 3) + || (gdk_pixbuf_get_has_alpha (src) + && gdk_pixbuf_get_n_channels (src) == 4), NULL); + g_return_val_if_fail (gdk_pixbuf_get_bits_per_sample (src) == 8, NULL); + + dest = create_new_pixbuf (src); + + has_alpha = gdk_pixbuf_get_has_alpha (src); + width = gdk_pixbuf_get_width (src); + height = gdk_pixbuf_get_height (src); + dest_row_stride = gdk_pixbuf_get_rowstride (dest); + src_row_stride = gdk_pixbuf_get_rowstride (src); + target_pixels = gdk_pixbuf_get_pixels (dest); + original_pixels = gdk_pixbuf_get_pixels (src); + + for (i = 0; i < height; i++) + { + pixdest = target_pixels + i * dest_row_stride; + pixsrc = original_pixels + i * src_row_stride; + for (j = 0; j < width; j++) + { + r = *pixsrc++; + g = *pixsrc++; + b = *pixsrc++; + intensity = (r * 77 + g * 150 + b * 28) >> 8; + negalpha = ((255 - saturation) * darken) >> 8; + alpha = (saturation * darken) >> 8; + *pixdest++ = (negalpha * intensity + alpha * r) >> 8; + *pixdest++ = (negalpha * intensity + alpha * g) >> 8; + *pixdest++ = (negalpha * intensity + alpha * b) >> 8; + if (has_alpha) + { + *pixdest++ = *pixsrc++; + } + } + } + return dest; +} + +/* this routine colorizes the passed-in pixbuf by multiplying each pixel with the passed in color */ + +GdkPixbuf * +eel_create_colorized_pixbuf (GdkPixbuf *src, + int red_value, + int green_value, + int blue_value) +{ + int i, j; + int width, height, has_alpha, src_row_stride, dst_row_stride; + guchar *target_pixels; + guchar *original_pixels; + guchar *pixsrc; + guchar *pixdest; + GdkPixbuf *dest; + + g_return_val_if_fail (gdk_pixbuf_get_colorspace (src) == GDK_COLORSPACE_RGB, NULL); + g_return_val_if_fail ((!gdk_pixbuf_get_has_alpha (src) + && gdk_pixbuf_get_n_channels (src) == 3) + || (gdk_pixbuf_get_has_alpha (src) + && gdk_pixbuf_get_n_channels (src) == 4), NULL); + g_return_val_if_fail (gdk_pixbuf_get_bits_per_sample (src) == 8, NULL); + + dest = create_new_pixbuf (src); + + has_alpha = gdk_pixbuf_get_has_alpha (src); + width = gdk_pixbuf_get_width (src); + height = gdk_pixbuf_get_height (src); + src_row_stride = gdk_pixbuf_get_rowstride (src); + dst_row_stride = gdk_pixbuf_get_rowstride (dest); + target_pixels = gdk_pixbuf_get_pixels (dest); + original_pixels = gdk_pixbuf_get_pixels (src); + + for (i = 0; i < height; i++) + { + pixdest = target_pixels + i*dst_row_stride; + pixsrc = original_pixels + i*src_row_stride; + for (j = 0; j < width; j++) + { + *pixdest++ = (*pixsrc++ * red_value) >> 8; + *pixdest++ = (*pixsrc++ * green_value) >> 8; + *pixdest++ = (*pixsrc++ * blue_value) >> 8; + if (has_alpha) + { + *pixdest++ = *pixsrc++; + } + } + } + return dest; +} + +/* utility to stretch a frame to the desired size */ + +static void +draw_frame_row (GdkPixbuf *frame_image, int target_width, int source_width, int source_v_position, int dest_v_position, GdkPixbuf *result_pixbuf, int left_offset, int height) +{ + int remaining_width, h_offset, slab_width; + + remaining_width = target_width; + h_offset = 0; + while (remaining_width > 0) + { + slab_width = remaining_width > source_width ? source_width : remaining_width; + gdk_pixbuf_copy_area (frame_image, left_offset, source_v_position, slab_width, height, result_pixbuf, left_offset + h_offset, dest_v_position); + remaining_width -= slab_width; + h_offset += slab_width; + } +} + +/* utility to draw the middle section of the frame in a loop */ +static void +draw_frame_column (GdkPixbuf *frame_image, int target_height, int source_height, int source_h_position, int dest_h_position, GdkPixbuf *result_pixbuf, int top_offset, int width) +{ + int remaining_height, v_offset, slab_height; + + remaining_height = target_height; + v_offset = 0; + while (remaining_height > 0) + { + slab_height = remaining_height > source_height ? source_height : remaining_height; + gdk_pixbuf_copy_area (frame_image, source_h_position, top_offset, width, slab_height, result_pixbuf, dest_h_position, top_offset + v_offset); + remaining_height -= slab_height; + v_offset += slab_height; + } +} + +GdkPixbuf * +eel_stretch_frame_image (GdkPixbuf *frame_image, int left_offset, int top_offset, int right_offset, int bottom_offset, + int dest_width, int dest_height, gboolean fill_flag) +{ + GdkPixbuf *result_pixbuf; + guchar *pixels_ptr; + int frame_width, frame_height; + int y, row_stride; + int target_width, target_frame_width; + int target_height, target_frame_height; + + frame_width = gdk_pixbuf_get_width (frame_image); + frame_height = gdk_pixbuf_get_height (frame_image ); + + if (fill_flag) + { + result_pixbuf = gdk_pixbuf_scale_simple (frame_image, dest_width, dest_height, GDK_INTERP_NEAREST); + } + else + { + result_pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, dest_width, dest_height); + } + row_stride = gdk_pixbuf_get_rowstride (result_pixbuf); + pixels_ptr = gdk_pixbuf_get_pixels (result_pixbuf); + + /* clear the new pixbuf */ + if (!fill_flag) + { + for (y = 0; y < dest_height; y++) + { + memset (pixels_ptr, 255, row_stride); + pixels_ptr += row_stride; + } + } + + target_width = dest_width - left_offset - right_offset; + target_frame_width = frame_width - left_offset - right_offset; + + target_height = dest_height - top_offset - bottom_offset; + target_frame_height = frame_height - top_offset - bottom_offset; + + /* draw the left top corner and top row */ + gdk_pixbuf_copy_area (frame_image, 0, 0, left_offset, top_offset, result_pixbuf, 0, 0); + draw_frame_row (frame_image, target_width, target_frame_width, 0, 0, result_pixbuf, left_offset, top_offset); + + /* draw the right top corner and left column */ + gdk_pixbuf_copy_area (frame_image, frame_width - right_offset, 0, right_offset, top_offset, result_pixbuf, dest_width - right_offset, 0); + draw_frame_column (frame_image, target_height, target_frame_height, 0, 0, result_pixbuf, top_offset, left_offset); + + /* draw the bottom right corner and bottom row */ + gdk_pixbuf_copy_area (frame_image, frame_width - right_offset, frame_height - bottom_offset, right_offset, bottom_offset, result_pixbuf, dest_width - right_offset, dest_height - bottom_offset); + draw_frame_row (frame_image, target_width, target_frame_width, frame_height - bottom_offset, dest_height - bottom_offset, result_pixbuf, left_offset, bottom_offset); + + /* draw the bottom left corner and the right column */ + gdk_pixbuf_copy_area (frame_image, 0, frame_height - bottom_offset, left_offset, bottom_offset, result_pixbuf, 0, dest_height - bottom_offset); + draw_frame_column (frame_image, target_height, target_frame_height, frame_width - right_offset, dest_width - right_offset, result_pixbuf, top_offset, right_offset); + + return result_pixbuf; +} + + +/* draw an arbitrary frame around an image, with the result passed back in a newly allocated pixbuf */ +GdkPixbuf * +eel_embed_image_in_frame (GdkPixbuf *source_image, GdkPixbuf *frame_image, int left_offset, int top_offset, int right_offset, int bottom_offset) +{ + GdkPixbuf *result_pixbuf; + int source_width, source_height; + int dest_width, dest_height; + + source_width = gdk_pixbuf_get_width (source_image); + source_height = gdk_pixbuf_get_height (source_image); + + dest_width = source_width + left_offset + right_offset; + dest_height = source_height + top_offset + bottom_offset; + + result_pixbuf = eel_stretch_frame_image (frame_image, left_offset, top_offset, right_offset, bottom_offset, + dest_width, dest_height, FALSE); + + /* Finally, copy the source image into the framed area */ + gdk_pixbuf_copy_area (source_image, 0, 0, source_width, source_height, result_pixbuf, left_offset, top_offset); + + return result_pixbuf; +} + + +/* this routine takes the source pixbuf and returns a new one that's semi-transparent, by + clearing every other pixel's alpha value in a checkerboard grip. We have to do the + checkerboard instead of reducing the alpha since it will be turned into an alpha-less + gdkpixmap and mask for the actual dragging */ + +GdkPixbuf * +eel_make_semi_transparent (GdkPixbuf *src) +{ + gint i, j, temp_alpha; + gint width, height, has_alpha, src_row_stride, dst_row_stride; + guchar *target_pixels, *original_pixels; + guchar *pixsrc, *pixdest; + guchar alpha_value; + GdkPixbuf *dest_pixbuf; + guchar start_alpha_value; + + g_return_val_if_fail (gdk_pixbuf_get_colorspace (src) == GDK_COLORSPACE_RGB, NULL); + g_return_val_if_fail ((!gdk_pixbuf_get_has_alpha (src) + && gdk_pixbuf_get_n_channels (src) == 3) + || (gdk_pixbuf_get_has_alpha (src) + && gdk_pixbuf_get_n_channels (src) == 4), NULL); + g_return_val_if_fail (gdk_pixbuf_get_bits_per_sample (src) == 8, NULL); + + dest_pixbuf = create_new_pixbuf_with_alpha (src); + + has_alpha = gdk_pixbuf_get_has_alpha (src); + width = gdk_pixbuf_get_width (src); + height = gdk_pixbuf_get_height (src); + src_row_stride = gdk_pixbuf_get_rowstride (src); + dst_row_stride = gdk_pixbuf_get_rowstride (dest_pixbuf); + + /* set up pointers to the actual pixels */ + target_pixels = gdk_pixbuf_get_pixels (dest_pixbuf); + original_pixels = gdk_pixbuf_get_pixels (src); + + /* loop through the pixels to do the actual work, copying from the source to the destination */ + start_alpha_value = ~0; + for (i = 0; i < height; i++) + { + pixdest = target_pixels + i * dst_row_stride; + pixsrc = original_pixels + i * src_row_stride; + alpha_value = start_alpha_value; + for (j = 0; j < width; j++) + { + *pixdest++ = *pixsrc++; /* red */ + *pixdest++ = *pixsrc++; /* green */ + *pixdest++ = *pixsrc++; /* blue */ + + if (has_alpha) + { + temp_alpha = *pixsrc++; + } + else + { + temp_alpha = ~0; + } + *pixdest++ = temp_alpha & alpha_value; + + alpha_value = ~alpha_value; + } + + start_alpha_value = ~start_alpha_value; + } + + return dest_pixbuf; +} + diff --git a/eel/eel-graphic-effects.h b/eel/eel-graphic-effects.h new file mode 100644 index 00000000..5f174c83 --- /dev/null +++ b/eel/eel-graphic-effects.h @@ -0,0 +1,66 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- + + eel-graphic-effects.h: Pixmap manipulation routines for graphical effects. + + Copyright (C) 2000 Eazel, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this program; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Authors: Andy Hertzfeld + */ + +#ifndef EEL_GRAPHIC_EFFECTS_H +#define EEL_GRAPHIC_EFFECTS_H + +#include + +/* return a lightened pixbuf for pre-lighting */ +GdkPixbuf *eel_create_spotlight_pixbuf (GdkPixbuf *source_pixbuf); + +/* return a darkened pixbuf for selection hiliting */ +GdkPixbuf *eel_create_darkened_pixbuf (GdkPixbuf *source_pixbuf, + int saturation, + int darken); + +/* return a pixbuf colorized with the color specified by the parameters */ +GdkPixbuf* eel_create_colorized_pixbuf (GdkPixbuf *source_pixbuf, + int red_value, + int green_value, + int blue_value); + +/* stretch a image frame */ +GdkPixbuf *eel_stretch_frame_image (GdkPixbuf *frame_image, + int left_offset, + int top_offset, + int right_offset, + int bottom_offset, + int dest_width, + int dest_height, + gboolean fill_flag); + +/* embed in image in a frame */ +GdkPixbuf *eel_embed_image_in_frame (GdkPixbuf *source_image, + GdkPixbuf *frame_image, + int left_offset, + int top_offset, + int right_offset, + int bottom_offset); + +/* return a semi-transparent pixbuf from the source pixbuf using a checkboard + stipple in the alpha channel (so it can be converted to an alpha-less pixmap) */ +GdkPixbuf *eel_make_semi_transparent (GdkPixbuf *source_pixbuf); + +#endif /* EEL_GRAPHIC_EFFECTS_H */ diff --git a/eel/eel-gtk-container.c b/eel/eel-gtk-container.c new file mode 100644 index 00000000..033579c5 --- /dev/null +++ b/eel/eel-gtk-container.c @@ -0,0 +1,225 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* eel-gtk-container.c - Functions to simplify the implementations of + GtkContainer widgets. + + Copyright (C) 2001 Ramiro Estrugo. + + The Mate Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Mate Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Mate Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Authors: Ramiro Estrugo +*/ + +#include +#include "eel-gtk-container.h" +#include "eel-art-extensions.h" + +/** + * eel_gtk_container_child_expose_event: + * + * @container: A GtkContainer widget. + * @child: A child of @container or NULL; + * @event: The expose event. + * + * Forward an expose event to a child if needed. It is valid to give a NULL @child. + * In that case this function is a noop. Proper clipping is done to ensure that the @child + * does indeed need to be forwarded the exposure event. Finally, the forwarding + * only occurs if the child is a NO_WINDOW widget. Of course, it is valid to feed + * non NO_WINDOW widgets to this function, in which case this function is a noop. + */ +void +eel_gtk_container_child_expose_event (GtkContainer *container, + GtkWidget *child, + GdkEventExpose *event) +{ + g_return_if_fail (GTK_IS_CONTAINER (container)); + + if (child == NULL) + { + return; + } + + g_return_if_fail (GTK_IS_WIDGET (child)); + + gtk_container_propagate_expose (container, child, event); +} + +/** + * eel_gtk_container_child_map: + * + * @container: A GtkContainer widget. + * @child: A child of @container or NULL; + * + * Map a child if needed. This is usually called from the "GtkWidget::map" + * method of the @container widget. If @child is NULL, then this function is a noop. + */ +void +eel_gtk_container_child_map (GtkContainer *container, + GtkWidget *child) +{ + g_return_if_fail (GTK_IS_CONTAINER (container)); + + if (child == NULL) + { + return; + } + + g_return_if_fail (gtk_widget_get_parent (child) == GTK_WIDGET (container)); + + if (gtk_widget_get_visible (child) && !gtk_widget_get_mapped (child)) + { + gtk_widget_map (child); + } +} + +/** + * eel_gtk_container_child_unmap: + * + * @container: A GtkContainer widget. + * @child: A child of @container or NULL; + * + * Unmap a child if needed. This is usually called from the "GtkWidget::unmap" + * method of the @container widget. If @child is NULL, then this function is a noop. + */ +void +eel_gtk_container_child_unmap (GtkContainer *container, + GtkWidget *child) +{ + g_return_if_fail (GTK_IS_CONTAINER (container)); + + if (child == NULL) + { + return; + } + + g_return_if_fail (gtk_widget_get_parent (child) == GTK_WIDGET (container)); + + if (gtk_widget_get_visible (child) && gtk_widget_get_mapped (child)) + { + gtk_widget_unmap (child); + } +} + +/** + * eel_gtk_container_child_add: + * + * @container: A GtkContainer widget. + * @child: A non NULL unparented child. + * + * Add a @child to a @container. The @child is realized, mapped + * and resized if needed. This is usually called from the "GtkContainer::add" + * method of the @container. The @child cannot be NULL. + */ +void +eel_gtk_container_child_add (GtkContainer *container, + GtkWidget *child) +{ + GtkWidget *widget; + + g_return_if_fail (GTK_IS_CONTAINER (container)); + g_return_if_fail (GTK_IS_WIDGET (child)); + + widget = GTK_WIDGET (container); + + gtk_widget_set_parent (child, widget); + + if (gtk_widget_get_realized (widget)) + { + gtk_widget_realize (child); + } + + if (gtk_widget_get_mapped (widget) + && gtk_widget_get_visible (child)) + { + if (gtk_widget_get_mapped (widget)) + { + gtk_widget_map (child); + } + + gtk_widget_queue_resize (child); + } +} + +/** + * eel_gtk_container_child_remove: + * + * @container: A GtkContainer widget. + * @child: A non NULL child of @container. + * + * Remove @child from @container. The @container is resized if needed. + * This is usually called from the "GtkContainer::remove" method of the + * @container. The child cannot be NULL. + */ +void +eel_gtk_container_child_remove (GtkContainer *container, + GtkWidget *child) +{ + gboolean child_was_visible; + + g_return_if_fail (GTK_IS_CONTAINER (container)); + g_return_if_fail (GTK_IS_WIDGET (child)); + g_return_if_fail (gtk_widget_get_parent (child) == GTK_WIDGET (container)); + + child_was_visible = gtk_widget_get_visible (child); + + gtk_widget_unparent (child); + + if (child_was_visible) + { + gtk_widget_queue_resize (GTK_WIDGET (container)); + } +} + +/** + * eel_gtk_container_child_size_allocate: + * + * @container: A GtkContainer widget. + * @child: A child of @container or NULL; + * + * Invoke the "GtkWidget::size_allocate" method of @child. + * This function is usually called from the "GtkWidget::size_allocate" + * method of @container. The child can be NULL, in which case this + * function is a noop. + */ +void +eel_gtk_container_child_size_allocate (GtkContainer *container, + GtkWidget *child, + EelIRect child_geometry) +{ + GtkAllocation child_allocation; + + g_return_if_fail (GTK_IS_CONTAINER (container)); + + if (child == NULL) + { + return; + } + + g_return_if_fail (GTK_IS_WIDGET (child)); + g_return_if_fail (gtk_widget_get_parent (child) == GTK_WIDGET (container)); + + if (eel_irect_is_empty (&child_geometry)) + { + return; + } + + child_allocation.x = child_geometry.x0; + child_allocation.y = child_geometry.y0; + child_allocation.width = eel_irect_get_width (child_geometry); + child_allocation.height = eel_irect_get_height (child_geometry); + + gtk_widget_size_allocate (child, &child_allocation); +} diff --git a/eel/eel-gtk-container.h b/eel/eel-gtk-container.h new file mode 100644 index 00000000..6b2dd0fa --- /dev/null +++ b/eel/eel-gtk-container.h @@ -0,0 +1,47 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* eel-gtk-container.h - Functions to simplify the implementations of + GtkContainer widgets. + + Copyright (C) 2001 Ramiro Estrugo. + + The Mate Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Mate Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Mate Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Authors: Ramiro Estrugo +*/ + +#ifndef EEL_GTK_CONTAINER_H +#define EEL_GTK_CONTAINER_H + +#include +#include + +void eel_gtk_container_child_expose_event (GtkContainer *container, + GtkWidget *child, + GdkEventExpose *event); +void eel_gtk_container_child_map (GtkContainer *container, + GtkWidget *child); +void eel_gtk_container_child_unmap (GtkContainer *container, + GtkWidget *child); +void eel_gtk_container_child_add (GtkContainer *container, + GtkWidget *child); +void eel_gtk_container_child_remove (GtkContainer *container, + GtkWidget *child); +void eel_gtk_container_child_size_allocate (GtkContainer *container, + GtkWidget *child, + EelIRect child_geometry); + +#endif /* EEL_GTK_CONTAINER_H */ diff --git a/eel/eel-gtk-extensions.c b/eel/eel-gtk-extensions.c new file mode 100644 index 00000000..da78a532 --- /dev/null +++ b/eel/eel-gtk-extensions.c @@ -0,0 +1,1247 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* eel-gtk-extensions.c - implementation of new functions that operate on + gtk classes. Perhaps some of these should be + rolled into gtk someday. + + Copyright (C) 1999, 2000, 2001 Eazel, Inc. + + The Mate Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Mate Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Mate Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Authors: John Sullivan + Ramiro Estrugo + Darin Adler +*/ + +#include +#include "eel-gtk-extensions.h" + +#include "eel-gdk-pixbuf-extensions.h" +#include "eel-glib-extensions.h" +#include "eel-mate-extensions.h" +#include "eel-pango-extensions.h" +#include "eel-string.h" +#include +#include +#include +#include +#include +#include +#include +#include "eel-marshal.h" +#include "eel-marshal.c" + +/* This number is fairly arbitrary. Long enough to show a pretty long + * menu title, but not so long to make a menu grotesquely wide. + */ +#define MAXIMUM_MENU_TITLE_LENGTH 48 + +/* Used for window position & size sanity-checking. The sizes are big enough to prevent + * at least normal-sized mate panels from obscuring the window at the screen edges. + */ +#define MINIMUM_ON_SCREEN_WIDTH 100 +#define MINIMUM_ON_SCREEN_HEIGHT 100 + + +/** + * eel_gtk_window_get_geometry_string: + * @window: a #GtkWindow + * + * Obtains the geometry string for this window, suitable for + * set_geometry_string(); assumes the window has NorthWest gravity + * + * Return value: geometry string, must be freed + **/ +char* +eel_gtk_window_get_geometry_string (GtkWindow *window) +{ + char *str; + int w, h, x, y; + + g_return_val_if_fail (GTK_IS_WINDOW (window), NULL); + g_return_val_if_fail (gtk_window_get_gravity (window) == + GDK_GRAVITY_NORTH_WEST, NULL); + + gtk_window_get_position (window, &x, &y); + gtk_window_get_size (window, &w, &h); + + str = g_strdup_printf ("%dx%d+%d+%d", w, h, x, y); + + return str; +} + +static void +send_delete_event (GtkWindow *window) +{ + /* Synthesize delete_event to close window. */ + + GdkEvent event; + GtkWidget *widget; + + widget = GTK_WIDGET (window); + + event.any.type = GDK_DELETE; + event.any.window = gtk_widget_get_window (widget); + event.any.send_event = TRUE; + + g_object_ref (event.any.window); + gtk_main_do_event (&event); + g_object_unref (event.any.window); +} + +static int +handle_standard_close_accelerator (GtkWindow *window, + GdkEventKey *event, + gpointer user_data) +{ + g_assert (GTK_IS_WINDOW (window)); + g_assert (event != NULL); + g_assert (user_data == NULL); + + if (eel_gtk_window_event_is_close_accelerator (window, event)) + { + send_delete_event (window); + g_signal_stop_emission_by_name ( + G_OBJECT (window), "key_press_event"); + return TRUE; + } + + return FALSE; +} + +/** + * eel_gtk_window_event_is_close_accelerator: + * + * Tests whether a key event is a standard window close accelerator. + * Not needed for clients that use eel_gtk_window_set_up_close_accelerator; + * use only if you must set up your own key_event handler for your own reasons. + **/ +gboolean +eel_gtk_window_event_is_close_accelerator (GtkWindow *window, GdkEventKey *event) +{ + g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE); + g_return_val_if_fail (event != NULL, FALSE); + + if (event->state & GDK_CONTROL_MASK) + { + /* Note: menu item equivalents are case-sensitive, so we will + * be case-sensitive here too. + */ + if (event->keyval == EEL_STANDARD_CLOSE_WINDOW_CONTROL_KEY) + { + return TRUE; + } + } + + + return FALSE; +} + +/** + * eel_gtk_window_set_up_close_accelerator: + * + * Sets up the standard keyboard equivalent to close the window. + * Call this for windows that don't set up a keyboard equivalent to + * close the window some other way, e.g. via a menu item accelerator. + * + * NOTE: do not use for GtkDialog, it already sets up the right + * stuff here. + * + * @window: The GtkWindow that should be hidden when the standard + * keyboard equivalent is typed. + **/ +void +eel_gtk_window_set_up_close_accelerator (GtkWindow *window) +{ + g_return_if_fail (GTK_IS_WINDOW (window)); + + if (GTK_IS_DIALOG (window)) + { + g_warning ("eel_gtk_window_set_up_close_accelerator: Should not mess with close accelerator on GtkDialogs"); + return; + } + + g_signal_connect (window, + "key_press_event", + G_CALLBACK (handle_standard_close_accelerator), + NULL); +} + +static void +sanity_check_window_position (int *left, int *top) +{ + g_assert (left != NULL); + g_assert (top != NULL); + + /* Make sure the top of the window is on screen, for + * draggability (might not be necessary with all window managers, + * but seems reasonable anyway). Make sure the top of the window + * isn't off the bottom of the screen, or so close to the bottom + * that it might be obscured by the panel. + */ + *top = CLAMP (*top, 0, gdk_screen_height() - MINIMUM_ON_SCREEN_HEIGHT); + + /* FIXME bugzilla.eazel.com 669: + * If window has negative left coordinate, set_uposition sends it + * somewhere else entirely. Not sure what level contains this bug (XWindows?). + * Hacked around by pinning the left edge to zero, which just means you + * can't set a window to be partly off the left of the screen using + * this routine. + */ + /* Make sure the left edge of the window isn't off the right edge of + * the screen, or so close to the right edge that it might be + * obscured by the panel. + */ + *left = CLAMP (*left, 0, gdk_screen_width() - MINIMUM_ON_SCREEN_WIDTH); +} + +static void +sanity_check_window_dimensions (guint *width, guint *height) +{ + g_assert (width != NULL); + g_assert (height != NULL); + + /* Pin the size of the window to the screen, so we don't end up in + * a state where the window is so big essential parts of it can't + * be reached (might not be necessary with all window managers, + * but seems reasonable anyway). + */ + *width = MIN (*width, gdk_screen_width()); + *height = MIN (*height, gdk_screen_height()); +} + +/** + * eel_gtk_window_set_initial_geometry: + * + * Sets the position and size of a GtkWindow before the + * GtkWindow is shown. It is an error to call this on a window that + * is already on-screen. Takes into account screen size, and does + * some sanity-checking on the passed-in values. + * + * @window: A non-visible GtkWindow + * @geometry_flags: A EelGdkGeometryFlags value defining which of + * the following parameters have defined values + * @left: pixel coordinate for left of window + * @top: pixel coordinate for top of window + * @width: width of window in pixels + * @height: height of window in pixels + */ +void +eel_gtk_window_set_initial_geometry (GtkWindow *window, + EelGdkGeometryFlags geometry_flags, + int left, + int top, + guint width, + guint height) +{ + GdkScreen *screen; + int real_left, real_top; + int screen_width, screen_height; + + g_return_if_fail (GTK_IS_WINDOW (window)); + + /* Setting the default size doesn't work when the window is already showing. + * Someday we could make this move an already-showing window, but we don't + * need that functionality yet. + */ + g_return_if_fail (!gtk_widget_get_visible (GTK_WIDGET (window))); + + if ((geometry_flags & EEL_GDK_X_VALUE) && (geometry_flags & EEL_GDK_Y_VALUE)) + { + real_left = left; + real_top = top; + + screen = gtk_window_get_screen (window); + screen_width = gdk_screen_get_width (screen); + screen_height = gdk_screen_get_height (screen); + + /* This is sub-optimal. GDK doesn't allow us to set win_gravity + * to South/East types, which should be done if using negative + * positions (so that the right or bottom edge of the window + * appears at the specified position, not the left or top). + * However it does seem to be consistent with other MATE apps. + */ + if (geometry_flags & EEL_GDK_X_NEGATIVE) + { + real_left = screen_width - real_left; + } + if (geometry_flags & EEL_GDK_Y_NEGATIVE) + { + real_top = screen_height - real_top; + } + + sanity_check_window_position (&real_left, &real_top); + gtk_window_move (window, real_left, real_top); + } + + if ((geometry_flags & EEL_GDK_WIDTH_VALUE) && (geometry_flags & EEL_GDK_HEIGHT_VALUE)) + { + sanity_check_window_dimensions (&width, &height); + gtk_window_set_default_size (GTK_WINDOW (window), (int)width, (int)height); + } +} + +/** + * eel_gtk_window_set_initial_geometry_from_string: + * + * Sets the position and size of a GtkWindow before the + * GtkWindow is shown. The geometry is passed in as a string. + * It is an error to call this on a window that + * is already on-screen. Takes into account screen size, and does + * some sanity-checking on the passed-in values. + * + * @window: A non-visible GtkWindow + * @geometry_string: A string suitable for use with eel_gdk_parse_geometry + * @minimum_width: If the width from the string is smaller than this, + * use this for the width. + * @minimum_height: If the height from the string is smaller than this, + * use this for the height. + * @ignore_position: If true position data from string will be ignored. + */ +void +eel_gtk_window_set_initial_geometry_from_string (GtkWindow *window, + const char *geometry_string, + guint minimum_width, + guint minimum_height, + gboolean ignore_position) +{ + int left, top; + guint width, height; + EelGdkGeometryFlags geometry_flags; + + g_return_if_fail (GTK_IS_WINDOW (window)); + g_return_if_fail (geometry_string != NULL); + + /* Setting the default size doesn't work when the window is already showing. + * Someday we could make this move an already-showing window, but we don't + * need that functionality yet. + */ + g_return_if_fail (!gtk_widget_get_visible (GTK_WIDGET (window))); + + geometry_flags = eel_gdk_parse_geometry (geometry_string, &left, &top, &width, &height); + + /* Make sure the window isn't smaller than makes sense for this window. + * Other sanity checks are performed in set_initial_geometry. + */ + if (geometry_flags & EEL_GDK_WIDTH_VALUE) + { + width = MAX (width, minimum_width); + } + if (geometry_flags & EEL_GDK_HEIGHT_VALUE) + { + height = MAX (height, minimum_height); + } + + /* Ignore saved window position if requested. */ + if (ignore_position) + { + geometry_flags &= ~(EEL_GDK_X_VALUE | EEL_GDK_Y_VALUE); + } + + eel_gtk_window_set_initial_geometry (window, geometry_flags, left, top, width, height); +} + +/** + * eel_pop_up_context_menu: + * + * Pop up a context menu under the mouse. + * The menu is sunk after use, so it will be destroyed unless the + * caller first ref'ed it. + * + * This function is more of a helper function than a gtk extension, + * so perhaps it belongs in a different file. + * + * @menu: The menu to pop up under the mouse. + * @offset_x: Number of pixels to displace the popup menu vertically + * @offset_y: Number of pixels to displace the popup menu horizontally + * @event: The event that invoked this popup menu. + **/ +void +eel_pop_up_context_menu (GtkMenu *menu, + gint16 offset_x, + gint16 offset_y, + GdkEventButton *event) +{ + GdkPoint offset; + int button; + + g_return_if_fail (GTK_IS_MENU (menu)); + + offset.x = offset_x; + offset.y = offset_y; + + /* The event button needs to be 0 if we're popping up this menu from + * a button release, else a 2nd click outside the menu with any button + * other than the one that invoked the menu will be ignored (instead + * of dismissing the menu). This is a subtle fragility of the GTK menu code. + */ + + if (event) + { + button = event->type == GDK_BUTTON_RELEASE + ? 0 + : event->button; + } + else + { + button = 0; + } + + gtk_menu_popup (menu, /* menu */ + NULL, /* parent_menu_shell */ + NULL, /* parent_menu_item */ + NULL, + &offset, /* data */ + button, /* button */ + event ? event->time : GDK_CURRENT_TIME); /* activate_time */ + + g_object_ref_sink (menu); + g_object_unref (menu); +} + +GtkMenuItem * +eel_gtk_menu_append_separator (GtkMenu *menu) +{ + return eel_gtk_menu_insert_separator (menu, -1); +} + +GtkMenuItem * +eel_gtk_menu_insert_separator (GtkMenu *menu, int index) +{ + GtkWidget *menu_item; + + menu_item = gtk_separator_menu_item_new (); + gtk_widget_show (menu_item); + gtk_menu_shell_insert (GTK_MENU_SHELL (menu), menu_item, index); + + return GTK_MENU_ITEM (menu_item); +} + +void +eel_gtk_menu_set_item_visibility (GtkMenu *menu, int index, gboolean visible) +{ + GList *children; + GtkWidget *menu_item; + + g_return_if_fail (GTK_IS_MENU (menu)); + + children = gtk_container_get_children (GTK_CONTAINER (menu)); + g_return_if_fail (index >= 0 && index < (int) g_list_length (children)); + + menu_item = GTK_WIDGET (g_list_nth_data (children, index)); + if (visible) + { + gtk_widget_show (menu_item); + } + else + { + gtk_widget_hide (menu_item); + } + + g_list_free (children); +} + +GtkWidget * +eel_gtk_menu_tool_button_get_button (GtkMenuToolButton *tool_button) +{ + GtkContainer *container; + GList *children; + GtkWidget *button; + + g_return_val_if_fail (GTK_IS_MENU_TOOL_BUTTON (tool_button), NULL); + + /* The menu tool button's button is the first child + * of the child hbox. */ + container = GTK_CONTAINER (gtk_bin_get_child (GTK_BIN (tool_button))); + children = gtk_container_get_children (container); + button = GTK_WIDGET (children->data); + + g_list_free (children); + + return button; +} + +gboolean +eel_point_in_allocation (const GtkAllocation *allocation, + int x, int y) +{ + g_return_val_if_fail (allocation != NULL, FALSE); + return x >= allocation->x + && y >= allocation->y + && x < allocation->x + allocation->width + && y < allocation->y + allocation->height; +} + +/* FIXME this function is dangerous, because gtk_widget_get_window (widget) coords (or + * other window-belonging-to-widget coords) do not need to be in the + * same coordinate system as widget->allocation. + * If you use this function, be aware of that. Someone should probably + * audit all uses, too. + */ +gboolean +eel_point_in_widget (GtkWidget *widget, + int x, int y) +{ + GtkAllocation allocation; + if (widget == NULL) + { + return FALSE; + } + g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE); + gtk_widget_get_allocation (widget, &allocation); + return eel_point_in_allocation (&allocation, x, y); +} + +/** + * eel_gtk_widget_set_shown + * + * Show or hide a widget. + * @widget: The widget. + * @shown: Boolean value indicating whether the widget should be shown or hidden. + **/ +void +eel_gtk_widget_set_shown (GtkWidget *widget, gboolean shown) +{ + g_return_if_fail (GTK_IS_WIDGET (widget)); + + if (shown) + { + gtk_widget_show (widget); + } + else + { + gtk_widget_hide (widget); + } +} + +/* This stuff is stolen from Gtk. */ + +typedef struct DisconnectInfo +{ + GtkObject *object1; + guint disconnect_handler1; + guint signal_handler; + GtkObject *object2; + guint disconnect_handler2; +} DisconnectInfo; + +static void +alive_disconnecter (GtkObject *object, DisconnectInfo *info) +{ + g_assert (info != NULL); + g_assert (GTK_IS_OBJECT (info->object1)); + g_assert (info->disconnect_handler1 != 0); + g_assert (info->signal_handler != 0); + g_assert (GTK_IS_OBJECT (info->object2)); + g_assert (info->disconnect_handler2 != 0); + g_assert (object == info->object1 || object == info->object2); + + g_signal_handler_disconnect (info->object1, info->disconnect_handler1); + g_signal_handler_disconnect (info->object1, info->signal_handler); + g_signal_handler_disconnect (info->object2, info->disconnect_handler2); + + g_free (info); +} + +/** + * eel_gtk_signal_connect_full_while_alive + * + * Like gtk_signal_connect_while_alive, but works with full parameters. + **/ +void +eel_gtk_signal_connect_full_while_alive (GtkObject *object, + const gchar *name, + GCallback func, + GtkCallbackMarshal marshal, + gpointer data, + GDestroyNotify destroy_func, + gboolean object_signal, + gboolean after, + GtkObject *alive_object) +{ + DisconnectInfo *info; + + g_return_if_fail (GTK_IS_OBJECT (object)); + g_return_if_fail (name != NULL); + g_return_if_fail (func != NULL || marshal != NULL); + g_return_if_fail (object_signal == FALSE || object_signal == TRUE); + g_return_if_fail (after == FALSE || after == TRUE); + g_return_if_fail (GTK_IS_OBJECT (alive_object)); + + info = g_new (DisconnectInfo, 1); + info->object1 = object; + info->object2 = alive_object; + + + info->signal_handler = g_signal_connect_closure ( + object, name, + (object_signal + ? g_cclosure_new_swap + : g_cclosure_new) (func, data, (GClosureNotify) destroy_func), + after); + + info->disconnect_handler1 = g_signal_connect (G_OBJECT (object), + "destroy", + G_CALLBACK (alive_disconnecter), + info); + info->disconnect_handler2 = g_signal_connect (G_OBJECT (alive_object), + "destroy", + G_CALLBACK (alive_disconnecter), + info); +} + +typedef struct +{ + GtkObject *object; + guint object_destroy_handler; + + GtkWidget *realized_widget; + guint realized_widget_destroy_handler; + guint realized_widget_unrealized_handler; + + guint signal_handler; +} RealizeDisconnectInfo; + +static void +while_realized_disconnecter (GtkObject *object, + RealizeDisconnectInfo *info) +{ + g_assert (GTK_IS_OBJECT (object)); + g_assert (info != NULL); + g_assert (GTK_IS_OBJECT (info->object)); + g_assert (info->object_destroy_handler != 0); + g_assert (info->object_destroy_handler != 0); + g_assert (info->realized_widget_destroy_handler != 0); + g_assert (info->realized_widget_unrealized_handler != 0); + + g_signal_handler_disconnect (info->object, info->object_destroy_handler); + g_signal_handler_disconnect (info->object, info->signal_handler); + g_signal_handler_disconnect (info->realized_widget, info->realized_widget_destroy_handler); + g_signal_handler_disconnect (info->realized_widget, info->realized_widget_unrealized_handler); + g_free (info); +} + +/** + * eel_gtk_signal_connect_while_realized: + * + * @object: Object to connect to. + * @name: Name of signal to connect to. + * @callback: Caller's callback. + * @callback_data: Caller's callback_data. + * @realized_widget: Widget to monitor for realized state. Signal is connected + * while this wigget is realized. + * + * Connect to a signal of an object while another widget is realized. This is + * useful for non windowed widgets that need to monitor events in their ancestored + * windowed widget. The signal is automatically disconnected when &widget is + * unrealized. Also, the signal is automatically disconnected when either &object + * or &widget are destroyed. + **/ +void +eel_gtk_signal_connect_while_realized (GtkObject *object, + const char *name, + GCallback callback, + gpointer callback_data, + GtkWidget *realized_widget) +{ + RealizeDisconnectInfo *info; + + g_return_if_fail (GTK_IS_OBJECT (object)); + g_return_if_fail (name != NULL); + g_return_if_fail (name[0] != '\0'); + g_return_if_fail (callback != NULL); + g_return_if_fail (GTK_IS_WIDGET (realized_widget)); + g_return_if_fail (gtk_widget_get_realized (realized_widget)); + + info = g_new0 (RealizeDisconnectInfo, 1); + + info->object = object; + info->object_destroy_handler = + g_signal_connect (G_OBJECT (info->object), + "destroy", + G_CALLBACK (while_realized_disconnecter), + info); + + info->realized_widget = realized_widget; + info->realized_widget_destroy_handler = + g_signal_connect (G_OBJECT (info->realized_widget), + "destroy", + G_CALLBACK (while_realized_disconnecter), + info); + info->realized_widget_unrealized_handler = + g_signal_connect_after (G_OBJECT (info->realized_widget), + "unrealize", + G_CALLBACK (while_realized_disconnecter), + info); + + info->signal_handler = g_signal_connect (G_OBJECT (info->object), + name, callback, callback_data); +} + +/** + * eel_gtk_container_get_first_child. + * + * Returns the first child of a container. + * @container: The container. + **/ + +static void +get_first_callback (GtkWidget *widget, gpointer callback_data) +{ + GtkWidget **first_child_slot; + + g_assert (GTK_IS_WIDGET (widget)); + g_assert (callback_data != NULL); + + first_child_slot = callback_data; + + if (*first_child_slot == NULL) + { + *first_child_slot = widget; + /* We'd stop the iterating now if we could. */ + } + else + { + g_assert (GTK_IS_WIDGET (*first_child_slot)); + } +} + +GtkWidget * +eel_gtk_container_get_first_child (GtkContainer *container) +{ + GtkWidget *first_child; + + g_return_val_if_fail (GTK_IS_CONTAINER (container), NULL); + + first_child = NULL; + gtk_container_foreach (container, get_first_callback, &first_child); + g_assert (first_child == NULL || GTK_IS_WIDGET (first_child)); + return first_child; +} + +typedef struct +{ + GtkCallback callback; + gpointer callback_data; +} container_foreach_deep_callback_data; + +static void +container_foreach_deep_callback (GtkWidget *child, gpointer data) +{ + container_foreach_deep_callback_data *deep_data; + + deep_data = (container_foreach_deep_callback_data *) data; + + deep_data->callback (child, deep_data->callback_data); + + if (GTK_IS_CONTAINER (child)) + { + gtk_container_foreach (GTK_CONTAINER (child), container_foreach_deep_callback, data); + } +} + +void +eel_gtk_container_foreach_deep (GtkContainer *container, + GtkCallback callback, + gpointer callback_data) +{ + container_foreach_deep_callback_data deep_data; + deep_data.callback = callback; + deep_data.callback_data = callback_data; + gtk_container_foreach (container, container_foreach_deep_callback, &deep_data); +} + +/* The standard gtk_adjustment_set_value ignores page size, which + * disagrees with the logic used by scroll bars, for example. + */ +void +eel_gtk_adjustment_set_value (GtkAdjustment *adjustment, + float value) +{ + float upper_page_start, clamped_value; + + g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment)); + + upper_page_start = MAX (gtk_adjustment_get_upper (adjustment) - + gtk_adjustment_get_page_size (adjustment), + gtk_adjustment_get_lower (adjustment)); + clamped_value = CLAMP (value, gtk_adjustment_get_lower (adjustment), upper_page_start); + if (clamped_value != gtk_adjustment_get_value (adjustment)) + { + gtk_adjustment_set_value (adjustment, clamped_value); + gtk_adjustment_value_changed (adjustment); + } +} + +/* Clamp a value if the minimum or maximum has changed. */ +void +eel_gtk_adjustment_clamp_value (GtkAdjustment *adjustment) +{ + g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment)); + + eel_gtk_adjustment_set_value (adjustment, + gtk_adjustment_get_value (adjustment)); +} + +/** + * eel_gtk_label_make_bold. + * + * Switches the font of label to a bold equivalent. + * @label: The label. + **/ +void +eel_gtk_label_make_bold (GtkLabel *label) +{ + PangoFontDescription *font_desc; + + font_desc = pango_font_description_new (); + + pango_font_description_set_weight (font_desc, + PANGO_WEIGHT_BOLD); + + /* This will only affect the weight of the font, the rest is + * from the current state of the widget, which comes from the + * theme or user prefs, since the font desc only has the + * weight flag turned on. + */ + gtk_widget_modify_font (GTK_WIDGET (label), font_desc); + + pango_font_description_free (font_desc); +} + +/** + * eel_gtk_label_set_scale: + * @label: + * @num_steps: + * + * Function is broken, see eel_gtk_label_make_larger() for explanation + * + **/ +void +eel_gtk_label_set_scale (GtkLabel *label, + double scale_factor) +{ + PangoAttrList *old_attr_list; + PangoAttrList *attr_list; + + g_return_if_fail (GTK_IS_LABEL (label)); + g_return_if_fail (scale_factor > 0); + + old_attr_list = gtk_label_get_attributes (label); + attr_list = eel_pango_attr_list_apply_global_attribute (old_attr_list, + pango_attr_scale_new (scale_factor)); + gtk_label_set_attributes (label, attr_list); + pango_attr_list_unref (attr_list); +} + +static void +get_layout_location (GtkLabel *label, + gint *xp, + gint *yp) +{ + GtkMisc *misc; + GtkWidget *widget; + float xalign, yalign; + int x, y, xpad, ypad; + int shadow_offset; + GtkAllocation allocation; + GtkRequisition req; + + shadow_offset = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (label), + "eel-label-shadow-offset")); + + misc = GTK_MISC (label); + widget = GTK_WIDGET (label); + gtk_misc_get_alignment (misc, &xalign, &yalign); + gtk_misc_get_padding (misc, &xpad, &ypad); + + if (gtk_widget_get_direction (widget) != GTK_TEXT_DIR_LTR) + xalign = 1.0 - xalign; + + gtk_widget_get_allocation (widget, &allocation); + gtk_widget_get_requisition (widget, &req); + x = floor (allocation.x + xpad + + ((allocation.width - req.width - shadow_offset) * xalign) + + 0.5); + + y = floor (allocation.y + ypad + + ((allocation.height - req.height - shadow_offset) * yalign) + + 0.5); + + + if (xp) + *xp = x; + + if (yp) + *yp = y; +} + +static gboolean +eel_gtk_label_expose_event (GtkLabel *label, GdkEventExpose *event, gpointer user_data) +{ + int x, y; + GdkColor color; + GtkWidget *widget; + GdkGC *gc; + guint32 shadow_color; + int shadow_offset; + + shadow_color = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (label), + "eel-label-shadow-color")); + shadow_offset = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (label), + "eel-label-shadow-offset")); + + color = eel_gdk_rgb_to_color (shadow_color); + + get_layout_location (label, &x, &y); + + widget = GTK_WIDGET (label); + if (shadow_offset > 0) + { + gc = gdk_gc_new (gtk_widget_get_window (widget)); + gdk_gc_set_rgb_fg_color (gc, &color); + gdk_gc_set_clip_rectangle (gc, &event->area); + + gdk_draw_layout (gtk_widget_get_window (widget), + gc, + x + shadow_offset, y + shadow_offset, + gtk_label_get_layout (label)); + g_object_unref (gc); + } + + gtk_paint_layout (gtk_widget_get_style (widget), + gtk_widget_get_window (widget), + gtk_widget_get_state (widget), + FALSE, + &event->area, + widget, + "label", + x, y, + gtk_label_get_layout (label)); + + return TRUE; +} + +static void +eel_gtk_label_size_request (GtkLabel *label, GtkRequisition *requisition, gpointer user_data) +{ + gint shadow_offset; + + shadow_offset = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (label), + "eel-label-shadow-offset")); + + requisition->width += shadow_offset; + requisition->height += shadow_offset; +} + +static void +set_up_label (GtkLabel *label) +{ + + if (g_object_get_data (G_OBJECT (label), "eel-label-set-up") != NULL) + { + return; + } + + g_signal_connect (label, "expose_event", + G_CALLBACK (eel_gtk_label_expose_event), NULL); + g_signal_connect_after (label, "size_request", + G_CALLBACK (eel_gtk_label_size_request), NULL); + + g_object_set_data (G_OBJECT (label), "eel-label-set-up", "eel-label-set-up"); +} + +void +eel_gtk_label_set_drop_shadow_color (GtkLabel *label, + guint32 color) +{ + set_up_label (label); + + g_object_set_data (G_OBJECT (label), "eel-label-shadow-color", + GINT_TO_POINTER (color)); + + gtk_widget_queue_draw (GTK_WIDGET (label)); +} + +void +eel_gtk_label_set_drop_shadow_offset (GtkLabel *label, + gint offset) +{ + set_up_label (label); + + g_object_set_data (G_OBJECT (label), "eel-label-shadow-offset", + GINT_TO_POINTER (offset)); + + gtk_widget_queue_draw (GTK_WIDGET (label)); +} + +void +eel_gtk_widget_set_background_color (GtkWidget *widget, + const char *color_spec) +{ + GdkColor color; + + g_return_if_fail (GTK_IS_WIDGET (widget)); + + eel_gdk_color_parse_with_white_default (color_spec, &color); + + gtk_widget_modify_bg (widget, GTK_STATE_NORMAL, &color); + gtk_widget_modify_base (widget, GTK_STATE_NORMAL, &color); + gtk_widget_modify_bg (widget, GTK_STATE_ACTIVE, &color); + gtk_widget_modify_base (widget, GTK_STATE_ACTIVE, &color); +} + +void +eel_gtk_widget_set_foreground_color (GtkWidget *widget, + const char *color_spec) +{ + GdkColor color; + + g_return_if_fail (GTK_IS_WIDGET (widget)); + + eel_gdk_color_parse_with_white_default (color_spec, &color); + + gtk_widget_modify_fg (widget, GTK_STATE_NORMAL, &color); + gtk_widget_modify_text (widget, GTK_STATE_NORMAL, &color); + gtk_widget_modify_fg (widget, GTK_STATE_ACTIVE, &color); + gtk_widget_modify_text (widget, GTK_STATE_ACTIVE, &color); +} + +GtkWidget * +eel_gtk_widget_find_windowed_ancestor (GtkWidget *widget) +{ + g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL); + + while (widget && !gtk_widget_get_has_window (widget)) + { + widget = gtk_widget_get_parent (widget); + } + + return widget; +} + +/* eel_gtk_get_system_font: + * + * Return the system font as selected in the control center. Need to + * g_object_unref() the result when done with it. + * + * Perhaps there is a better way to figure out what that font is, but + * the following is simple enough and it works. + */ +PangoFontDescription * +eel_gtk_get_system_font (void) +{ + GtkWidget *label; + PangoFontDescription *font; + + label = gtk_label_new (""); + + gtk_widget_ensure_style (label); + + font = pango_font_description_copy (gtk_widget_get_style (label)->font_desc); + + g_object_ref_sink (label); + g_object_unref (label); + + return font; +} + +void +eel_gtk_widget_get_button_event_location (GtkWidget *widget, + const GdkEventButton *event, + int *x, + int *y) +{ + int window_x, window_y; + GtkAllocation allocation; + + g_return_if_fail (GTK_IS_WIDGET (widget)); + g_return_if_fail (event != NULL); + + gdk_window_get_position (event->window, &window_x, &window_y); + gtk_widget_get_allocation (widget, &allocation); + if (x != NULL) + { + *x = event->x + window_x - allocation.x; + } + if (y != NULL) + { + *y = event->y + window_y - allocation.y; + } +} + +void +eel_gtk_widget_get_motion_event_location (GtkWidget *widget, + const GdkEventMotion *event, + int *x, + int *y) +{ + eel_gtk_widget_get_button_event_location (widget, (const GdkEventButton *) event, x, y); +} + +static gboolean +tree_view_button_press_callback (GtkWidget *tree_view, + GdkEventButton *event, + gpointer data) +{ + GtkTreePath *path; + GtkTreeViewColumn *column; + + if (event->button == 1 && event->type == GDK_BUTTON_PRESS) + { + if (gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (tree_view), + event->x, event->y, + &path, + &column, + NULL, + NULL)) + { + gtk_tree_view_row_activated + (GTK_TREE_VIEW (tree_view), path, column); + } + } + + return FALSE; +} + +void +eel_gtk_tree_view_set_activate_on_single_click (GtkTreeView *tree_view, + gboolean should_activate) +{ + guint button_press_id; + + button_press_id = GPOINTER_TO_UINT + (g_object_get_data (G_OBJECT (tree_view), + "eel-tree-view-activate")); + + if (button_press_id && !should_activate) + { + g_signal_handler_disconnect (tree_view, button_press_id); + g_object_set_data (G_OBJECT (tree_view), + "eel-tree-view-activate", + NULL); + } + else if (!button_press_id && should_activate) + { + button_press_id = g_signal_connect + (tree_view, + "button_press_event", + G_CALLBACK (tree_view_button_press_callback), + NULL); + g_object_set_data (G_OBJECT (tree_view), + "eel-tree-view-activate", + GUINT_TO_POINTER (button_press_id)); + } +} + +gboolean +eel_gtk_viewport_get_visible_rect (GtkViewport *viewport, + GdkRectangle *rect) +{ + GdkRectangle viewport_rect; + GdkRectangle child_rect; + gboolean return_val; + + g_return_val_if_fail (GTK_IS_VIEWPORT (viewport), FALSE); + g_return_val_if_fail (rect != NULL, FALSE); + + if (gtk_widget_get_realized (GTK_WIDGET (viewport))) + { + viewport_rect.x = 0; + viewport_rect.y = 0; + +#if GTK_CHECK_VERSION(3, 0, 0) + viewport_rect.width = gdk_window_get_width(GDK_WINDOW(gtk_viewport_get_view_window(viewport))); + viewport_rect.height = gdk_window_get_height(GDK_WINDOW(gtk_viewport_get_view_window(viewport))); +#else + gdk_drawable_get_size(gtk_viewport_get_view_window(viewport), &viewport_rect.width, &viewport_rect.height); +#endif + + gdk_window_get_position (gtk_viewport_get_bin_window (viewport), + &child_rect.x, + &child_rect.y); + +#if GTK_CHECK_VERSION(3, 0, 0) + child_rect.width = gdk_window_get_width(GDK_WINDOW(gtk_viewport_get_view_window(viewport))); + child_rect.height = gdk_window_get_height(GDK_WINDOW(gtk_viewport_get_view_window(viewport))); +#else + gdk_drawable_get_size(gtk_viewport_get_bin_window(viewport), &child_rect.width, &child_rect.height); +#endif + + return_val = gdk_rectangle_intersect (&viewport_rect, + &child_rect, + rect); + rect->x -= child_rect.x; + rect->y -= child_rect.y; + + return return_val; + } + + rect->x = rect->y = rect->width = rect->height = 0; + return FALSE; +} + +void +eel_gtk_viewport_scroll_to_rect (GtkViewport *viewport, + GdkRectangle *rect) +{ + GdkRectangle visible_rect; + int scroll_x; + int scroll_y; + GtkAdjustment *adjustment; + + g_return_if_fail (GTK_IS_VIEWPORT (viewport)); + g_return_if_fail (rect != NULL); + + if (eel_gtk_viewport_get_visible_rect (viewport, &visible_rect)) + { + scroll_x = -1; + scroll_y = -1; + + if (rect->x + rect->width > visible_rect.x + visible_rect.width) + { + scroll_x = rect->x - (visible_rect.width - rect->width); + } + if (rect->y + rect->height > visible_rect.y + visible_rect.height) + { + scroll_y = rect->y - (visible_rect.height - rect->height); + } + + if (rect->x < visible_rect.x) + { + scroll_x = rect->x; + } + + if (rect->y < visible_rect.y) + { + scroll_y = rect->y; + } + + adjustment = gtk_viewport_get_hadjustment (viewport); + if (adjustment && scroll_x != -1) + { + eel_gtk_adjustment_set_value (adjustment, + (double)scroll_x); + } + + adjustment = gtk_viewport_get_vadjustment (viewport); + if (adjustment && scroll_y != -1) + { + eel_gtk_adjustment_set_value (adjustment, + (double)scroll_y); + } + } +} diff --git a/eel/eel-gtk-extensions.h b/eel/eel-gtk-extensions.h new file mode 100644 index 00000000..21ab382d --- /dev/null +++ b/eel/eel-gtk-extensions.h @@ -0,0 +1,141 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* eel-gtk-extensions.h - interface for new functions that operate on + gtk classes. Perhaps some of these should be + rolled into gtk someday. + + Copyright (C) 1999, 2000, 2001 Eazel, Inc. + + The Mate Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Mate Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Mate Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Authors: John Sullivan + Ramiro Estrugo +*/ + +#ifndef EEL_GTK_EXTENSIONS_H +#define EEL_GTK_EXTENSIONS_H + +#include +#include +#include + +#define EEL_DEFAULT_POPUP_MENU_DISPLACEMENT 2 +#define EEL_STANDARD_CLOSE_WINDOW_CONTROL_KEY 'w' + +/* signals */ +void eel_gtk_signal_connect_full_while_alive (GtkObject *object, + const gchar *name, + GCallback func, + GtkCallbackMarshal marshal, + gpointer data, + GDestroyNotify destroy_func, + gboolean object_signal, + gboolean after, + GtkObject *alive_object); +void eel_gtk_signal_connect_while_realized (GtkObject *object, + const char *name, + GCallback callback, + gpointer callback_data, + GtkWidget *realized_widget); + +/* GtkWidget */ +void eel_gtk_widget_set_shown (GtkWidget *widget, + gboolean shown); +gboolean eel_point_in_allocation (const GtkAllocation *allocation, + int x, + int y); +gboolean eel_point_in_widget (GtkWidget *widget, + int x, + int y); +void eel_gtk_widget_set_background_color (GtkWidget *widget, + const char *color_spec); +void eel_gtk_widget_set_foreground_color (GtkWidget *widget, + const char *color_spec); +GtkWidget * eel_gtk_widget_find_windowed_ancestor (GtkWidget *widget); +PangoFontDescription *eel_gtk_get_system_font (void); +void eel_gtk_widget_get_button_event_location (GtkWidget *widget, + const GdkEventButton *event, + int *x, + int *y); +void eel_gtk_widget_get_motion_event_location (GtkWidget *widget, + const GdkEventMotion *event, + int *x, + int *y); + +/* GtkContainer */ +GtkWidget * eel_gtk_container_get_first_child (GtkContainer *container); +void eel_gtk_container_foreach_deep (GtkContainer *container, + GtkCallback callback, + gpointer callback_data); + +/* GtkWindow */ +void eel_gtk_window_set_initial_geometry (GtkWindow *window, + EelGdkGeometryFlags geometry_flags, + int left, + int top, + guint width, + guint height); +void eel_gtk_window_set_initial_geometry_from_string (GtkWindow *window, + const char *geometry_string, + guint minimum_width, + guint minimum_height, + gboolean ignore_position); +void eel_gtk_window_set_up_close_accelerator (GtkWindow *window); +gboolean eel_gtk_window_event_is_close_accelerator (GtkWindow *window, + GdkEventKey *event); +char * eel_gtk_window_get_geometry_string (GtkWindow *window); + + +/* GtkMenu and GtkMenuItem */ +void eel_pop_up_context_menu (GtkMenu *menu, + gint16 offset_x, + gint16 offset_y, + GdkEventButton *event); +GtkMenuItem * eel_gtk_menu_append_separator (GtkMenu *menu); +GtkMenuItem * eel_gtk_menu_insert_separator (GtkMenu *menu, + int index); +void eel_gtk_menu_set_item_visibility (GtkMenu *menu, + int index, + gboolean visible); + +/* GtkMenuToolButton */ +GtkWidget * eel_gtk_menu_tool_button_get_button (GtkMenuToolButton *tool_button); + +/* GtkLabel */ +void eel_gtk_label_make_bold (GtkLabel *label); +void eel_gtk_label_set_scale (GtkLabel *label, + double scale_factor); +void eel_gtk_label_set_drop_shadow_color (GtkLabel *label, + guint32 color); +void eel_gtk_label_set_drop_shadow_offset (GtkLabel *label, + gint offset); +/* GtkAdjustment */ +void eel_gtk_adjustment_set_value (GtkAdjustment *adjustment, + float value); +void eel_gtk_adjustment_clamp_value (GtkAdjustment *adjustment); + +/* GtkTreeView */ +void eel_gtk_tree_view_set_activate_on_single_click (GtkTreeView *tree_view, + gboolean should_activate); + +/* GtkViewport */ +gboolean eel_gtk_viewport_get_visible_rect (GtkViewport *viewport, + GdkRectangle *rect); + +void eel_gtk_viewport_scroll_to_rect (GtkViewport *viewport, + GdkRectangle *rect); + +#endif /* EEL_GTK_EXTENSIONS_H */ diff --git a/eel/eel-gtk-macros.h b/eel/eel-gtk-macros.h new file mode 100644 index 00000000..996d75f8 --- /dev/null +++ b/eel/eel-gtk-macros.h @@ -0,0 +1,178 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- + + eel-gtk-macros.h: Macros to reduce boilerplate when using GTK. + + Copyright (C) 1999, 2000, 2001 Eazel, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this program; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Authors: Darin Adler + Ramiro Estrugo +*/ + +#ifndef EEL_GTK_MACROS_H +#define EEL_GTK_MACROS_H + +#ifndef EEL_DISABLE_DEPRECATED + +/* Define a parent_class global and a get_type function for a GTK class. + Since this is boilerplate, it's better not to repeat it over and over again. + Called like this: + + EEL_CLASS_BOILERPLATE (EelBookmark, eel_bookmark, GTK_TYPE_OBJECT) + + The parent_class_type parameter is guaranteed to be evaluated only once + so it can be an expression, even an expression that contains a function call. +*/ + +#define EEL_CLASS_BOILERPLATE(class_name, prefix, parent_class_type) \ + EEL_BOILERPLATE (class_name, class_name, prefix, parent_class_type, \ + EEL_REGISTER_TYPE) +#define EEL_REGISTER_TYPE(class_name, corba_name) \ + g_type_register_static (parent_type, #class_name, &info, 0) + +#define EEL_BOILERPLATE(class_name, corba_name, prefix, parent_class_type, \ + register_type) \ + \ +static gpointer parent_class; \ + \ +GType \ +prefix##_get_type (void) \ +{ \ + GType parent_type; \ + static GType type; \ + \ + if (type == 0) { \ + static GTypeInfo info = { \ + sizeof (class_name##Class), \ + NULL, NULL, \ + (GClassInitFunc) prefix##_class_init, \ + NULL, NULL, \ + sizeof (class_name), 0, \ + (GInstanceInitFunc) prefix##_init, \ + NULL \ + }; \ + \ + parent_type = (parent_class_type); \ + type = register_type (class_name, corba_name); \ + parent_class = g_type_class_ref (parent_type); \ + } \ + \ + return type; \ +} + +/* Call a parent class version of a virtual function (or default + * signal handler since that's the same thing). Nice because it + * documents what it's doing and there is less chance for a + * typo. Depends on the parent class pointer having the conventional + * name "parent_class" as the boilerplate macro above does it. + */ +#define EEL_CALL_PARENT(parent_class_cast_macro, signal, parameters) \ + \ +G_STMT_START { \ + if (parent_class_cast_macro (parent_class)->signal != NULL) { \ + (* parent_class_cast_macro (parent_class)->signal) parameters;\ + } \ +} G_STMT_END + +/* Same thing, for functions with a return value. */ +#define EEL_CALL_PARENT_WITH_RETURN_VALUE(parent_class_cast_macro, signal, \ + parameters) \ + \ +(parent_class_cast_macro (parent_class)->signal == NULL) \ + ? 0 \ + : ((* parent_class_cast_macro (parent_class)->signal) parameters) + +#endif /* EEL_DISABLE_DEPRECATED */ + +/* Call a virtual function. Useful when the virtual function is not a + * signal, otherwise you want to gtk_signal emit. Nice because it + * documents what it's doing and there is less chance for a typo. + */ +#define EEL_CALL_METHOD(class_cast_macro, object, signal, parameters) \ + \ +G_STMT_START { \ + if (class_cast_macro (G_OBJECT_GET_CLASS (object))->signal != NULL) { \ + (* class_cast_macro (G_OBJECT_GET_CLASS (object))->signal) \ + parameters; \ + } \ +} G_STMT_END + +/* Same thing, for functions with a return value. */ +#define EEL_CALL_METHOD_WITH_RETURN_VALUE(class_cast_macro, object, signal, \ + parameters) \ + \ +(class_cast_macro (G_OBJECT_GET_CLASS (object))->signal == NULL) \ + ? 0 \ + : ((* class_cast_macro (G_OBJECT_GET_CLASS (object))->signal) \ + parameters) \ + +#ifndef G_DISABLE_ASSERT + +/* Define a signal that is not implemented by this class but must be + * implemented by subclasses. This macro should be used inside the + * class initialization function. The companion macro EEL_IMPLEMENT_MUST_OVERRIDE_SIGNAL + * must be used earlier in the file. Called like this: + * + * EEL_ASSIGN_MUST_OVERRIDE_SIGNAL (klass, + * fm_directory_view, + * clear); + */ +#define EEL_ASSIGN_MUST_OVERRIDE_SIGNAL(class_pointer, prefix, signal) \ + \ +* (void (**)(void)) & (class_pointer)->signal = prefix##_unimplemented_##signal + +/* Provide a debug-only implementation of a signal that must be implemented + * by subclasses. The debug-only implementation fires a warning if it is called. + * This macro should be placed as if it were a function, earlier in the file + * than the class initialization function. Called like this: + * + * EEL_IMPLEMENT_MUST_OVERRIDE_SIGNAL (fm_directory_view, clear); + */ +#define EEL_IMPLEMENT_MUST_OVERRIDE_SIGNAL(prefix, signal) \ + \ +static void \ +prefix##_unimplemented_##signal (void) \ +{ \ + g_warning ("failed to override signal " #prefix "->" #signal); \ +} + +#else /* G_DISABLE_ASSERT */ + +#define EEL_DEFINE_MUST_OVERRIDE_SIGNAL(class_cast_macro, class_pointer, prefix, signal) +#define EEL_IMPLEMENT_MUST_OVERRIDE_SIGNAL(prefix, signal) +#define EEL_ASSIGN_MUST_OVERRIDE_SIGNAL(class_pointer, prefix, signal) + +#endif /* G_DISABLE_ASSERT */ + +/* Access a method. */ +#define EEL_ACCESS_METHOD(class_cast_macro, object, method) \ +(class_cast_macro (G_OBJECT_GET_CLASS (object))->method) + +/* Invoke a method for a given object. */ +#define EEL_INVOKE_METHOD(class_cast_macro, object, method, parameters) \ +((* EEL_ACCESS_METHOD (class_cast_macro, object, method)) parameters) + +/* Assert the non-nullness of a method for a given object. */ +#define EEL_ASSERT_METHOD(class_cast_macro, object, method) \ +g_assert (EEL_ACCESS_METHOD (class_cast_macro, object, method) != NULL) + +/* Invoke a method if it ain't null. */ +#define EEL_INVOKE_METHOD_IF(class_cast_macro, object, method, parameters) \ +(EEL_ACCESS_METHOD (class_cast_macro, object, method) ? 0 : \ + EEL_INVOKE_METHOD (class_cast_macro, object, method, parameters)) + +#endif /* EEL_GTK_MACROS_H */ diff --git a/eel/eel-i18n.c b/eel/eel-i18n.c new file mode 100644 index 00000000..b43163e3 --- /dev/null +++ b/eel/eel-i18n.c @@ -0,0 +1,52 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* eel-i18n.c: I18n stuff for Eel. + + Copyright (C) 2002 MandrakeSoft. + + The Mate Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Mate Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Mate Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Authors: Frederic Crozat +*/ + +#include +#include + +#include "eel-i18n.h" + +#ifdef ENABLE_NLS + +#include + +const char* _eel_gettext(const char* str) +{ + static gboolean _eel_gettext_initialized = FALSE; + + if (!_eel_gettext_initialized) + { + bindtextdomain(GETTEXT_PACKAGE, MATELOCALEDIR); + +#ifdef HAVE_BIND_TEXTDOMAIN_CODESET + bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8"); +#endif + + _eel_gettext_initialized = TRUE; + } + + return dgettext(GETTEXT_PACKAGE, str); +} + +#endif /* ENABLE_NLS */ diff --git a/eel/eel-i18n.h b/eel/eel-i18n.h new file mode 100644 index 00000000..827539d8 --- /dev/null +++ b/eel/eel-i18n.h @@ -0,0 +1,55 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* eel-i18n.h: I18n stuff for Eel. + + Copyright (C) 2002 MandrakeSoft + + The Mate Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Mate Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Mate Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Authors: Frederic Crozat +*/ + +#ifndef EEL_I18N_H +#define EEL_I18N_H + +#ifdef ENABLE_NLS + +#include + + +const char* _eel_gettext(const char* str) G_GNUC_FORMAT(1); + +#include +#define _(String) _eel_gettext(String) + +#ifdef gettext_noop +#define N_(String) gettext_noop(String) +#else +#define N_(String) (String) +#endif + +#else /* NLS is disabled */ +#define _(String) (String) +#define N_(String) (String) +#define textdomain(String) (String) +#define gettext(String) (String) +#define dgettext(Domain,String) (String) +#define dcgettext(Domain,String,Type) (String) +#define bindtextdomain(Domain,Directory) (Domain) +#endif + + +#endif /* EEL_I18N_H */ diff --git a/eel/eel-image-table.c b/eel/eel-image-table.c new file mode 100644 index 00000000..25f67a0a --- /dev/null +++ b/eel/eel-image-table.c @@ -0,0 +1,601 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* eel-image-table.c - An image table. + + Copyright (C) 2000 Eazel, Inc. + + The Mate Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Mate Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Mate Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Authors: Ramiro Estrugo +*/ + +#include +#include "eel-image-table.h" + +#include "eel-art-extensions.h" +#include "eel-art-gtk-extensions.h" +#include "eel-debug-drawing.h" +#include "eel-gtk-extensions.h" +#include "eel-gtk-macros.h" +#include "eel-labeled-image.h" +#include "eel-marshal.h" +#include + +/* Arguments */ +enum +{ + ARG_0, + ARG_CHILD_UNDER_POINTER +}; + +/* Detail member struct */ +struct EelImageTableDetails +{ + GtkWidget *child_under_pointer; + GtkWidget *child_being_pressed; + GdkGC *clear_gc; +}; + +/* Signals */ +typedef enum +{ + CHILD_ENTER, + CHILD_LEAVE, + CHILD_PRESSED, + CHILD_RELEASED, + CHILD_CLICKED, + LAST_SIGNAL +} ImageTableSignals; + +/* Signals */ +static guint image_table_signals[LAST_SIGNAL] = { 0 }; + +static void eel_image_table_class_init (EelImageTableClass *image_table_class); +static void eel_image_table_init (EelImageTable *image); + +/* GObjectClass methods */ +static void eel_image_table_finalize (GObject *object); + +/* GtkWidgetClass methods */ +static void eel_image_table_realize (GtkWidget *widget); +static void eel_image_table_unrealize (GtkWidget *widget); + +/* GtkContainerClass methods */ +static void eel_image_table_remove (GtkContainer *container, + GtkWidget *widget); +static GType eel_image_table_child_type (GtkContainer *container); + +/* Private EelImageTable methods */ +static void image_table_emit_signal (EelImageTable *image_table, + GtkWidget *child, + guint signal_index, + int x, + int y, + int button, + guint state, + GdkEvent *event); + +/* Ancestor callbacks */ +static int ancestor_enter_notify_event (GtkWidget *widget, + GdkEventCrossing *event, + gpointer event_data); +static int ancestor_leave_notify_event (GtkWidget *widget, + GdkEventCrossing *event, + gpointer event_data); +static int ancestor_motion_notify_event (GtkWidget *widget, + GdkEventMotion *event, + gpointer event_data); +static int ancestor_button_press_event (GtkWidget *widget, + GdkEventButton *event, + gpointer event_data); +static int ancestor_button_release_event (GtkWidget *widget, + GdkEventButton *event, + gpointer event_data); + +EEL_CLASS_BOILERPLATE (EelImageTable, eel_image_table, EEL_TYPE_WRAP_TABLE) + +static void +eel_image_table_class_init (EelImageTableClass *image_table_class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (image_table_class); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (image_table_class); + GtkContainerClass *container_class = GTK_CONTAINER_CLASS (image_table_class); + + /* GObjectClass */ + object_class->finalize = eel_image_table_finalize; + + /* GtkWidgetClass */ + widget_class->realize = eel_image_table_realize; + widget_class->unrealize = eel_image_table_unrealize; + + /* GtkContainerClass */ + container_class->remove = eel_image_table_remove; + container_class->child_type = eel_image_table_child_type; + + /* Signals */ + image_table_signals[CHILD_ENTER] = g_signal_new ("child_enter", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (EelImageTableClass, child_enter), + NULL, NULL, + eel_marshal_VOID__OBJECT_POINTER, + G_TYPE_NONE, + 2, + GTK_TYPE_WIDGET, + G_TYPE_POINTER); + image_table_signals[CHILD_LEAVE] = g_signal_new ("child_leave", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (EelImageTableClass, child_leave), + NULL, NULL, + eel_marshal_VOID__OBJECT_POINTER, + G_TYPE_NONE, + 2, + GTK_TYPE_WIDGET, + G_TYPE_POINTER); + image_table_signals[CHILD_PRESSED] = g_signal_new ("child_pressed", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (EelImageTableClass, child_pressed), + NULL, NULL, + eel_marshal_VOID__OBJECT_POINTER, + G_TYPE_NONE, + 2, + GTK_TYPE_WIDGET, + G_TYPE_POINTER); + image_table_signals[CHILD_RELEASED] = g_signal_new ("child_released", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (EelImageTableClass, child_released), + NULL, NULL, + eel_marshal_VOID__OBJECT_POINTER, + G_TYPE_NONE, + 2, + GTK_TYPE_WIDGET, + G_TYPE_POINTER); + image_table_signals[CHILD_CLICKED] = g_signal_new ("child_clicked", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (EelImageTableClass, child_clicked), + NULL, NULL, + eel_marshal_VOID__OBJECT_POINTER, + G_TYPE_NONE, + 2, + GTK_TYPE_WIDGET, + G_TYPE_POINTER); +} + +static void +eel_image_table_init (EelImageTable *image_table) +{ + gtk_widget_set_has_window (GTK_WIDGET (image_table), FALSE); + + image_table->details = g_new0 (EelImageTableDetails, 1); +} + +/* GObjectClass methods */ +static void +eel_image_table_finalize (GObject *object) +{ + EelImageTable *image_table; + + image_table = EEL_IMAGE_TABLE (object); + + g_free (image_table->details); + + EEL_CALL_PARENT (G_OBJECT_CLASS, finalize, (object)); +} + +static void +eel_image_table_realize (GtkWidget *widget) +{ + GtkWidget *windowed_ancestor; + + g_assert (EEL_IS_IMAGE_TABLE (widget)); + + /* Chain realize */ + EEL_CALL_PARENT (GTK_WIDGET_CLASS, realize, (widget)); + + windowed_ancestor = eel_gtk_widget_find_windowed_ancestor (widget); + g_assert (GTK_IS_WIDGET (windowed_ancestor)); + + gtk_widget_add_events (windowed_ancestor, + GDK_BUTTON_PRESS_MASK + | GDK_BUTTON_RELEASE_MASK + | GDK_BUTTON_MOTION_MASK + | GDK_ENTER_NOTIFY_MASK + | GDK_LEAVE_NOTIFY_MASK + | GDK_POINTER_MOTION_MASK); + + eel_gtk_signal_connect_while_realized (GTK_OBJECT (windowed_ancestor), + "enter_notify_event", + G_CALLBACK (ancestor_enter_notify_event), + widget, + widget); + + eel_gtk_signal_connect_while_realized (GTK_OBJECT (windowed_ancestor), + "leave_notify_event", + G_CALLBACK (ancestor_leave_notify_event), + widget, + widget); + + eel_gtk_signal_connect_while_realized (GTK_OBJECT (windowed_ancestor), + "motion_notify_event", + G_CALLBACK (ancestor_motion_notify_event), + widget, + widget); + + eel_gtk_signal_connect_while_realized (GTK_OBJECT (windowed_ancestor), + "button_press_event", + G_CALLBACK (ancestor_button_press_event), + widget, + widget); + + eel_gtk_signal_connect_while_realized (GTK_OBJECT (windowed_ancestor), + "button_release_event", + G_CALLBACK (ancestor_button_release_event), + widget, + widget); +} + +static void +eel_image_table_unrealize (GtkWidget *widget) +{ + EelImageTable *image_table; + + g_assert (EEL_IS_IMAGE_TABLE (widget)); + + image_table = EEL_IMAGE_TABLE (widget); + + if (image_table->details->clear_gc != NULL) + { + g_object_unref (image_table->details->clear_gc); + image_table->details->clear_gc = NULL; + } + + /* Chain unrealize */ + EEL_CALL_PARENT (GTK_WIDGET_CLASS, unrealize, (widget)); +} + +/* GtkContainerClass methods */ +static void +eel_image_table_remove (GtkContainer *container, + GtkWidget *child) +{ + EelImageTable *image_table; + + g_assert (EEL_IS_IMAGE_TABLE (container)); + g_assert (EEL_IS_LABELED_IMAGE (child)); + + image_table = EEL_IMAGE_TABLE (container); + + if (child == image_table->details->child_under_pointer) + { + image_table->details->child_under_pointer = NULL; + } + + if (child == image_table->details->child_being_pressed) + { + image_table->details->child_being_pressed = NULL; + } + + EEL_CALL_PARENT (GTK_CONTAINER_CLASS, remove, (container, child)); +} + +static GType +eel_image_table_child_type (GtkContainer *container) +{ + return EEL_TYPE_LABELED_IMAGE; +} + +/* Private EelImageTable methods */ + +static void +image_table_emit_signal (EelImageTable *image_table, + GtkWidget *child, + guint signal_index, + int x, + int y, + int button, + guint state, + GdkEvent *gdk_event) +{ + EelImageTableEvent event; + + g_assert (EEL_IS_IMAGE_TABLE (image_table)); + g_assert (GTK_IS_WIDGET (child)); + g_assert (signal_index < LAST_SIGNAL); + + event.x = x; + event.y = y; + event.button = button; + event.state = state; + event.event = gdk_event; + + g_signal_emit (image_table, + image_table_signals[signal_index], + 0, + child, + &event); +} + +static void +image_table_handle_motion (EelImageTable *image_table, + int x, + int y, + GdkEvent *event) +{ + GtkWidget *child; + GtkWidget *leave_emit_child = NULL; + GtkWidget *enter_emit_child = NULL; + + g_assert (EEL_IS_IMAGE_TABLE (image_table)); + + child = eel_wrap_table_find_child_at_event_point (EEL_WRAP_TABLE (image_table), x, y); + + if (child && !gtk_widget_get_sensitive (child)) + { + return; + } + + if (child == image_table->details->child_under_pointer) + { + return; + } + + if (child != NULL) + { + if (image_table->details->child_under_pointer != NULL) + { + leave_emit_child = image_table->details->child_under_pointer; + } + + image_table->details->child_under_pointer = child; + enter_emit_child = image_table->details->child_under_pointer; + } + else + { + if (image_table->details->child_under_pointer != NULL) + { + leave_emit_child = image_table->details->child_under_pointer; + } + + image_table->details->child_under_pointer = NULL; + } + + if (leave_emit_child != NULL) + { + image_table_emit_signal (image_table, + leave_emit_child, + CHILD_LEAVE, + x, + y, + 0, + 0, + (GdkEvent *)event); + } + + if (enter_emit_child != NULL) + { + image_table_emit_signal (image_table, + enter_emit_child, + CHILD_ENTER, + x, + y, + 0, + 0, + (GdkEvent *)event); + } +} + +static int +ancestor_enter_notify_event (GtkWidget *widget, + GdkEventCrossing *event, + gpointer event_data) +{ + g_assert (GTK_IS_WIDGET (widget)); + g_assert (EEL_IS_IMAGE_TABLE (event_data)); + g_assert (event != NULL); + + image_table_handle_motion (EEL_IMAGE_TABLE (event_data), event->x, event->y, (GdkEvent *) event); + + return FALSE; +} + +static int +ancestor_leave_notify_event (GtkWidget *widget, + GdkEventCrossing *event, + gpointer event_data) +{ + EelIRect bounds; + int x = -1; + int y = -1; + + g_assert (GTK_IS_WIDGET (widget)); + g_assert (EEL_IS_IMAGE_TABLE (event_data)); + g_assert (event != NULL); + + bounds = eel_gtk_widget_get_bounds (GTK_WIDGET (event_data)); + + if (eel_irect_contains_point (bounds, event->x, event->y)) + { + x = event->x; + y = event->y; + } + + image_table_handle_motion (EEL_IMAGE_TABLE (event_data), x, y, (GdkEvent *) event); + + return FALSE; +} + +static int +ancestor_motion_notify_event (GtkWidget *widget, + GdkEventMotion *event, + gpointer event_data) +{ + g_assert (GTK_IS_WIDGET (widget)); + g_assert (EEL_IS_IMAGE_TABLE (event_data)); + g_assert (event != NULL); + + image_table_handle_motion (EEL_IMAGE_TABLE (event_data), (int) event->x, (int) event->y, (GdkEvent *) event); + + return FALSE; +} + +static int +ancestor_button_press_event (GtkWidget *widget, + GdkEventButton *event, + gpointer event_data) +{ + EelImageTable *image_table; + GtkWidget *child; + + g_assert (GTK_IS_WIDGET (widget)); + g_assert (EEL_IS_IMAGE_TABLE (event_data)); + g_assert (event != NULL); + + image_table = EEL_IMAGE_TABLE (event_data); + + child = eel_wrap_table_find_child_at_event_point (EEL_WRAP_TABLE (image_table), event->x, event->y); + + if (child && !gtk_widget_get_sensitive (child)) + { + return FALSE; + } + + if (child != NULL) + { + if (child == image_table->details->child_under_pointer) + { + image_table->details->child_being_pressed = child; + image_table_emit_signal (image_table, + child, + CHILD_PRESSED, + event->x, + event->y, + event->button, + event->state, + (GdkEvent *)event); + } + } + + return FALSE; +} + +static int +ancestor_button_release_event (GtkWidget *widget, + GdkEventButton *event, + gpointer event_data) +{ + EelImageTable *image_table; + GtkWidget *child; + GtkWidget *released_emit_child = NULL; + GtkWidget *clicked_emit_child = NULL; + + g_assert (GTK_IS_WIDGET (widget)); + g_assert (EEL_IS_IMAGE_TABLE (event_data)); + g_assert (event != NULL); + + image_table = EEL_IMAGE_TABLE (event_data); + + child = eel_wrap_table_find_child_at_event_point (EEL_WRAP_TABLE (image_table), event->x, event->y); + + if (child && !gtk_widget_get_sensitive (child)) + { + return FALSE; + } + + if (image_table->details->child_being_pressed != NULL) + { + released_emit_child = image_table->details->child_being_pressed; + } + + if (child != NULL) + { + if (child == image_table->details->child_being_pressed) + { + clicked_emit_child = child; + } + } + + image_table->details->child_being_pressed = NULL; + + if (released_emit_child != NULL) + { + image_table_emit_signal (image_table, + released_emit_child, + CHILD_RELEASED, + event->x, + event->y, + event->button, + event->state, + (GdkEvent *)event); + } + + if (clicked_emit_child != NULL) + { + + image_table_emit_signal (image_table, + clicked_emit_child, + CHILD_CLICKED, + event->x, + event->y, + event->button, + event->state, + (GdkEvent *)event); + } + + return FALSE; +} + +/** + * eel_image_table_new: + */ +GtkWidget* +eel_image_table_new (gboolean homogeneous) +{ + EelImageTable *image_table; + + image_table = EEL_IMAGE_TABLE (gtk_widget_new (eel_image_table_get_type (), NULL)); + + eel_wrap_table_set_homogeneous (EEL_WRAP_TABLE (image_table), homogeneous); + + return GTK_WIDGET (image_table); +} + +/** + * eel_image_table_add_empty_child: + * @image_table: A EelImageTable. + * + * Add a "empty" child to the table. Useful when you want to have + * empty space between 2 children. + * + * Returns: The empty child - A EelLabeledImage widget with no label + * or pixbuf. + */ +GtkWidget * +eel_image_table_add_empty_image (EelImageTable *image_table) +{ + GtkWidget *empty; + + g_return_val_if_fail (EEL_IS_IMAGE_TABLE (image_table), NULL); + + empty = eel_labeled_image_new (NULL, NULL); + gtk_container_add (GTK_CONTAINER (image_table), empty); + gtk_widget_set_sensitive (empty, FALSE); + + return empty; +} diff --git a/eel/eel-image-table.h b/eel/eel-image-table.h new file mode 100644 index 00000000..90602a76 --- /dev/null +++ b/eel/eel-image-table.h @@ -0,0 +1,99 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* eel-image-table.h - An image table. + + Copyright (C) 2000 Eazel, Inc. + + The Mate Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Mate Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Mate Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Authors: Ramiro Estrugo +*/ + +#ifndef EEL_IMAGE_TABLE_H +#define EEL_IMAGE_TABLE_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define EEL_TYPE_IMAGE_TABLE eel_image_table_get_type() +#define EEL_IMAGE_TABLE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), EEL_TYPE_IMAGE_TABLE, EelImageTable)) +#define EEL_IMAGE_TABLE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), EEL_TYPE_IMAGE_TABLE, EelImageTableClass)) +#define EEL_IS_IMAGE_TABLE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EEL_TYPE_IMAGE_TABLE)) +#define EEL_IS_IMAGE_TABLE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), EEL_TYPE_IMAGE_TABLE)) +#define EEL_IMAGE_TABLE_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), EEL_TYPE_IMAGE_TABLE, EelImageTableClass)) + + typedef struct EelImageTable EelImageTable; + typedef struct EelImageTableClass EelImageTableClass; + typedef struct EelImageTableDetails EelImageTableDetails; + + typedef struct + { + int x; + int y; + int button; + guint state; + GdkEvent *event; + } EelImageTableEvent; + + struct EelImageTable + { + /* Superclass */ + EelWrapTable wrap_table; + + /* Private things */ + EelImageTableDetails *details; + }; + + struct EelImageTableClass + { + EelWrapTableClass parent_class; + + /* Signals */ + void (* child_enter) (EelImageTable *image_table, + GtkWidget *child, + const EelImageTableEvent *event); + void (* child_leave) (EelImageTable *image_table, + GtkWidget *child, + const EelImageTableEvent *event); + void (* child_pressed) (EelImageTable *image_table, + GtkWidget *child, + const EelImageTableEvent *event); + void (* child_released) (EelImageTable *image_table, + GtkWidget *child, + const EelImageTableEvent *event); + void (* child_clicked) (EelImageTable *image_table, + GtkWidget *child, + const EelImageTableEvent *event); + }; + + /* Public GtkImageTable methods */ + GType eel_image_table_get_type (void); + GtkWidget *eel_image_table_new (gboolean homogeneous); + GtkWidget *eel_image_table_add_empty_image (EelImageTable *image_table); + +#ifdef __cplusplus +} +#endif + +#endif /* EEL_IMAGE_TABLE_H */ diff --git a/eel/eel-labeled-image.c b/eel/eel-labeled-image.c new file mode 100644 index 00000000..76a23876 --- /dev/null +++ b/eel/eel-labeled-image.c @@ -0,0 +1,2493 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* eel-labeled-image.c - A labeled image. + + Copyright (C) 2000 Eazel, Inc. + + The Mate Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Mate Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Mate Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Authors: Ramiro Estrugo +*/ + +#include +#include "eel-labeled-image.h" + +#include "eel-art-extensions.h" +#include "eel-art-gtk-extensions.h" +#include "eel-debug-drawing.h" +#include "eel-gtk-container.h" +#include "eel-gtk-extensions.h" +#include "eel-gtk-macros.h" +#include "eel-accessibility.h" +#include +#include +#include + +#define DEFAULT_SPACING 0 +#define DEFAULT_X_PADDING 0 +#define DEFAULT_Y_PADDING 0 +#define DEFAULT_X_ALIGNMENT 0.5 +#define DEFAULT_Y_ALIGNMENT 0.5 + +/* Signals */ +enum +{ + ACTIVATE, + LAST_SIGNAL +}; + +/* Arguments */ +enum +{ + PROP_0, + PROP_FILL, + PROP_LABEL, + PROP_LABEL_POSITION, + PROP_PIXBUF, + PROP_SHOW_IMAGE, + PROP_SHOW_LABEL, + PROP_SPACING, + PROP_X_ALIGNMENT, + PROP_X_PADDING, + PROP_Y_ALIGNMENT, + PROP_Y_PADDING +}; + +/* Detail member struct */ +struct EelLabeledImageDetails +{ + GtkWidget *image; + GtkWidget *label; + GtkPositionType label_position; + gboolean show_label; + gboolean show_image; + guint spacing; + float x_alignment; + float y_alignment; + int x_padding; + int y_padding; + int fixed_image_height; + gboolean fill; +}; + +/* derived types so we can add our accessibility interfaces */ +static GType eel_labeled_image_button_get_type (void); +static GType eel_labeled_image_check_button_get_type (void); +static GType eel_labeled_image_radio_button_get_type (void); +static GType eel_labeled_image_toggle_button_get_type (void); + + +static void eel_labeled_image_class_init (EelLabeledImageClass *labeled_image_class); +static void eel_labeled_image_init (EelLabeledImage *image); +static void eel_labeled_image_finalize (GObject *object); + + + +/* GObjectClass methods */ +static void eel_labeled_image_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec); +static void eel_labeled_image_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec); + +/* GtkObjectClass methods */ +static void eel_labeled_image_destroy (GtkObject *object); + +/* GtkWidgetClass methods */ +static void eel_labeled_image_size_request (GtkWidget *widget, + GtkRequisition *requisition); +static int eel_labeled_image_expose_event (GtkWidget *widget, + GdkEventExpose *event); +static void eel_labeled_image_size_allocate (GtkWidget *widget, + GtkAllocation *allocation); +static void eel_labeled_image_map (GtkWidget *widget); +static void eel_labeled_image_unmap (GtkWidget *widget); +static AtkObject *eel_labeled_image_get_accessible (GtkWidget *widget); + +/* GtkContainerClass methods */ +static void eel_labeled_image_add (GtkContainer *container, + GtkWidget *widget); +static void eel_labeled_image_remove (GtkContainer *container, + GtkWidget *widget); +static void eel_labeled_image_forall (GtkContainer *container, + gboolean include_internals, + GtkCallback callback, + gpointer callback_data); + +/* Private EelLabeledImage methods */ +static EelDimensions labeled_image_get_image_dimensions (const EelLabeledImage *labeled_image); +static EelDimensions labeled_image_get_label_dimensions (const EelLabeledImage *labeled_image); +static void labeled_image_ensure_label (EelLabeledImage *labeled_image); +static void labeled_image_ensure_image (EelLabeledImage *labeled_image); +static EelIRect labeled_image_get_content_bounds (const EelLabeledImage *labeled_image); +static EelDimensions labeled_image_get_content_dimensions (const EelLabeledImage *labeled_image); +static void labeled_image_update_alignments (EelLabeledImage *labeled_image); +static gboolean labeled_image_show_label (const EelLabeledImage *labeled_image); +static gboolean labeled_image_show_image (const EelLabeledImage *labeled_image); + +static guint labeled_image_signals[LAST_SIGNAL] = { 0 }; + +EEL_CLASS_BOILERPLATE (EelLabeledImage, eel_labeled_image, GTK_TYPE_CONTAINER) + +/* Class init methods */ +static void +eel_labeled_image_class_init (EelLabeledImageClass *labeled_image_class) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (labeled_image_class); + GtkObjectClass *object_class = GTK_OBJECT_CLASS (labeled_image_class); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (labeled_image_class); + GtkContainerClass *container_class = GTK_CONTAINER_CLASS (labeled_image_class); + GtkBindingSet *binding_set; + + gobject_class->finalize = eel_labeled_image_finalize; + + /* GObjectClass */ + gobject_class->set_property = eel_labeled_image_set_property; + gobject_class->get_property = eel_labeled_image_get_property; + + /* GtkObjectClass */ + object_class->destroy = eel_labeled_image_destroy; + + /* GtkWidgetClass */ + widget_class->size_request = eel_labeled_image_size_request; + widget_class->size_allocate = eel_labeled_image_size_allocate; + widget_class->expose_event = eel_labeled_image_expose_event; + widget_class->map = eel_labeled_image_map; + widget_class->unmap = eel_labeled_image_unmap; + widget_class->get_accessible = eel_labeled_image_get_accessible; + + /* GtkContainerClass */ + container_class->add = eel_labeled_image_add; + container_class->remove = eel_labeled_image_remove; + container_class->forall = eel_labeled_image_forall; + + labeled_image_signals[ACTIVATE] = + g_signal_new ("activate", + G_TYPE_FROM_CLASS (labeled_image_class), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (EelLabeledImageClass, + activate), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + widget_class->activate_signal = labeled_image_signals[ACTIVATE]; + + binding_set = gtk_binding_set_by_class (gobject_class); + + gtk_binding_entry_add_signal (binding_set, + GDK_Return, 0, + "activate", 0); + gtk_binding_entry_add_signal (binding_set, + GDK_KP_Enter, 0, + "activate", 0); + gtk_binding_entry_add_signal (binding_set, + GDK_space, 0, + "activate", 0); + + + /* Properties */ + g_object_class_install_property ( + gobject_class, + PROP_PIXBUF, + g_param_spec_object ("pixbuf", NULL, NULL, + GDK_TYPE_PIXBUF, G_PARAM_READWRITE)); + + g_object_class_install_property ( + gobject_class, + PROP_LABEL, + g_param_spec_string ("label", NULL, NULL, + "", G_PARAM_READWRITE)); + + + g_object_class_install_property ( + gobject_class, + PROP_LABEL_POSITION, + g_param_spec_enum ("label_position", NULL, NULL, + GTK_TYPE_POSITION_TYPE, + GTK_POS_BOTTOM, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + gobject_class, + PROP_SHOW_LABEL, + g_param_spec_boolean ("show_label", NULL, NULL, + TRUE, G_PARAM_READWRITE)); + + g_object_class_install_property ( + gobject_class, + PROP_SHOW_IMAGE, + g_param_spec_boolean ("show_image", NULL, NULL, + TRUE, G_PARAM_READWRITE)); + + + g_object_class_install_property ( + gobject_class, + PROP_SPACING, + g_param_spec_uint ("spacing", NULL, NULL, + 0, + G_MAXINT, + DEFAULT_SPACING, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + gobject_class, + PROP_X_PADDING, + g_param_spec_int ("x_padding", NULL, NULL, + 0, + G_MAXINT, + DEFAULT_X_PADDING, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + gobject_class, + PROP_Y_PADDING, + g_param_spec_int ("y_padding", NULL, NULL, + 0, + G_MAXINT, + DEFAULT_Y_PADDING, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + gobject_class, + PROP_X_ALIGNMENT, + g_param_spec_float ("x_alignment", NULL, NULL, + 0.0, + 1.0, + DEFAULT_X_ALIGNMENT, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + gobject_class, + PROP_Y_ALIGNMENT, + g_param_spec_float ("y_alignment", NULL, NULL, + 0.0, + 1.0, + DEFAULT_Y_ALIGNMENT, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + gobject_class, + PROP_FILL, + g_param_spec_boolean ("fill", NULL, NULL, + FALSE, + G_PARAM_READWRITE)); +} + +static void +eel_labeled_image_init (EelLabeledImage *labeled_image) +{ + gtk_widget_set_has_window (GTK_WIDGET (labeled_image), FALSE); + + labeled_image->details = g_new0 (EelLabeledImageDetails, 1); + labeled_image->details->show_label = TRUE; + labeled_image->details->show_image = TRUE; + labeled_image->details->label_position = GTK_POS_BOTTOM; + labeled_image->details->spacing = DEFAULT_SPACING; + labeled_image->details->x_padding = DEFAULT_X_PADDING; + labeled_image->details->y_padding = DEFAULT_Y_PADDING; + labeled_image->details->x_alignment = DEFAULT_X_ALIGNMENT; + labeled_image->details->y_alignment = DEFAULT_Y_ALIGNMENT; + labeled_image->details->fixed_image_height = 0; + + eel_labeled_image_set_fill (labeled_image, FALSE); +} + +static void +eel_labeled_image_finalize (GObject *object) +{ + EelLabeledImage *labeled_image; + + labeled_image = EEL_LABELED_IMAGE (object); + + g_free (labeled_image->details); + + EEL_CALL_PARENT (G_OBJECT_CLASS, finalize, (object)); +} + + +static void +eel_labeled_image_destroy (GtkObject *object) +{ + EelLabeledImage *labeled_image; + + labeled_image = EEL_LABELED_IMAGE (object); + + if (labeled_image->details->image != NULL) + { + gtk_widget_destroy (labeled_image->details->image); + } + + if (labeled_image->details->label != NULL) + { + gtk_widget_destroy (labeled_image->details->label); + } + + EEL_CALL_PARENT (GTK_OBJECT_CLASS, destroy, (object)); +} + +/* GObjectClass methods */ +static void +eel_labeled_image_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + EelLabeledImage *labeled_image; + + g_assert (EEL_IS_LABELED_IMAGE (object)); + + labeled_image = EEL_LABELED_IMAGE (object); + + switch (property_id) + { + case PROP_PIXBUF: + eel_labeled_image_set_pixbuf (labeled_image, + g_value_get_object (value)); + break; + + case PROP_LABEL: + eel_labeled_image_set_text (labeled_image, g_value_get_string (value)); + break; + + case PROP_LABEL_POSITION: + eel_labeled_image_set_label_position (labeled_image, + g_value_get_enum (value)); + break; + + case PROP_SHOW_LABEL: + eel_labeled_image_set_show_label (labeled_image, + g_value_get_boolean (value)); + break; + + case PROP_SHOW_IMAGE: + eel_labeled_image_set_show_image (labeled_image, + g_value_get_boolean (value)); + break; + + case PROP_SPACING: + eel_labeled_image_set_spacing (labeled_image, + g_value_get_uint (value)); + break; + + case PROP_X_PADDING: + eel_labeled_image_set_x_padding (labeled_image, + g_value_get_int (value)); + break; + + case PROP_Y_PADDING: + eel_labeled_image_set_y_padding (labeled_image, + g_value_get_int (value)); + break; + + case PROP_X_ALIGNMENT: + eel_labeled_image_set_x_alignment (labeled_image, + g_value_get_float (value)); + break; + + case PROP_Y_ALIGNMENT: + eel_labeled_image_set_y_alignment (labeled_image, + g_value_get_float (value)); + break; + + case PROP_FILL: + eel_labeled_image_set_fill (labeled_image, + g_value_get_boolean (value)); + break; + default: + g_assert_not_reached (); + } +} + +static void +eel_labeled_image_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + EelLabeledImage *labeled_image; + + g_assert (EEL_IS_LABELED_IMAGE (object)); + + labeled_image = EEL_LABELED_IMAGE (object); + + switch (property_id) + { + case PROP_LABEL: + if (labeled_image->details->label == NULL) + { + g_value_set_string (value, NULL); + } + else + { + g_value_set_string (value, + gtk_label_get_text (GTK_LABEL ( + labeled_image->details->label))); + } + break; + + case PROP_LABEL_POSITION: + g_value_set_enum (value, eel_labeled_image_get_label_position (labeled_image)); + break; + + case PROP_SHOW_LABEL: + g_value_set_boolean (value, eel_labeled_image_get_show_label (labeled_image)); + break; + + case PROP_SHOW_IMAGE: + g_value_set_boolean (value, eel_labeled_image_get_show_image (labeled_image)); + break; + + case PROP_SPACING: + g_value_set_uint (value, eel_labeled_image_get_spacing (labeled_image)); + break; + + case PROP_X_PADDING: + g_value_set_int (value, eel_labeled_image_get_x_padding (labeled_image)); + break; + + case PROP_Y_PADDING: + g_value_set_int (value, eel_labeled_image_get_y_padding (labeled_image)); + break; + + case PROP_X_ALIGNMENT: + g_value_set_float (value, eel_labeled_image_get_x_alignment (labeled_image)); + break; + + case PROP_Y_ALIGNMENT: + g_value_set_float (value, eel_labeled_image_get_y_alignment (labeled_image)); + break; + + case PROP_FILL: + g_value_set_boolean (value, eel_labeled_image_get_fill (labeled_image)); + break; + + default: + g_assert_not_reached (); + } +} + +/* GtkWidgetClass methods */ +static void +eel_labeled_image_size_request (GtkWidget *widget, + GtkRequisition *requisition) +{ + EelLabeledImage *labeled_image; + EelDimensions content_dimensions; + + g_assert (EEL_IS_LABELED_IMAGE (widget)); + g_assert (requisition != NULL); + + labeled_image = EEL_LABELED_IMAGE (widget); + + content_dimensions = labeled_image_get_content_dimensions (labeled_image); + + requisition->width = + MAX (1, content_dimensions.width) + + 2 * labeled_image->details->x_padding; + + requisition->height = + MAX (1, content_dimensions.height) + + 2 * labeled_image->details->y_padding; +} + +static void +eel_labeled_image_size_allocate (GtkWidget *widget, + GtkAllocation *allocation) +{ + EelLabeledImage *labeled_image; + EelIRect image_bounds; + EelIRect label_bounds; + + g_assert (EEL_IS_LABELED_IMAGE (widget)); + g_assert (allocation != NULL); + + labeled_image = EEL_LABELED_IMAGE (widget); + + gtk_widget_set_allocation (widget, allocation); + + label_bounds = eel_labeled_image_get_label_bounds (labeled_image); + eel_gtk_container_child_size_allocate (GTK_CONTAINER (widget), + labeled_image->details->label, + label_bounds); + + image_bounds = eel_labeled_image_get_image_bounds (labeled_image); + eel_gtk_container_child_size_allocate (GTK_CONTAINER (widget), + labeled_image->details->image, + image_bounds); +} + +static int +eel_labeled_image_expose_event (GtkWidget *widget, + GdkEventExpose *event) +{ + EelLabeledImage *labeled_image; + EelIRect label_bounds; + GtkStyle *style; + GdkWindow *window; + + g_assert (EEL_IS_LABELED_IMAGE (widget)); + g_assert (gtk_widget_get_realized (widget)); + g_assert (event != NULL); + + labeled_image = EEL_LABELED_IMAGE (widget); + + style = gtk_widget_get_style (widget); + window = gtk_widget_get_window (widget); + if (gtk_widget_get_state (widget) == GTK_STATE_SELECTED || + gtk_widget_get_state (widget) == GTK_STATE_ACTIVE) + { + label_bounds = eel_labeled_image_get_label_bounds (EEL_LABELED_IMAGE (widget)); + + gtk_paint_flat_box (style, + window, + gtk_widget_get_state (widget), + GTK_SHADOW_NONE, + &event->area, + widget, + "eel-labeled-image", + label_bounds.x0, label_bounds.y0, + label_bounds.x1 - label_bounds.x0, + label_bounds.y1 - label_bounds.y0); + } + + if (labeled_image_show_label (labeled_image)) + { + eel_gtk_container_child_expose_event (GTK_CONTAINER (widget), + labeled_image->details->label, + event); + } + + if (labeled_image_show_image (labeled_image)) + { + eel_gtk_container_child_expose_event (GTK_CONTAINER (widget), + labeled_image->details->image, + event); + } + + if (gtk_widget_has_focus (widget)) + { + label_bounds = eel_labeled_image_get_image_bounds (EEL_LABELED_IMAGE (widget)); + gtk_paint_focus (style, window, + GTK_STATE_NORMAL, + &event->area, widget, + "eel-focusable-labeled-image", + label_bounds.x0, label_bounds.y0, + label_bounds.x1 - label_bounds.x0, + label_bounds.y1 - label_bounds.y0); + } + + return FALSE; +} + +static void +eel_labeled_image_map (GtkWidget *widget) +{ + EelLabeledImage *labeled_image; + + g_assert (EEL_IS_LABELED_IMAGE (widget)); + + labeled_image = EEL_LABELED_IMAGE (widget); + + gtk_widget_set_mapped (widget, TRUE); + + if (labeled_image_show_label (labeled_image)) + { + eel_gtk_container_child_map (GTK_CONTAINER (widget), labeled_image->details->label); + } + + if (labeled_image_show_image (labeled_image)) + { + eel_gtk_container_child_map (GTK_CONTAINER (widget), labeled_image->details->image); + } +} + +static void +eel_labeled_image_unmap (GtkWidget *widget) +{ + EelLabeledImage *labeled_image; + + g_assert (EEL_IS_LABELED_IMAGE (widget)); + + labeled_image = EEL_LABELED_IMAGE (widget); + + gtk_widget_set_mapped (widget, FALSE); + + eel_gtk_container_child_unmap (GTK_CONTAINER (widget), labeled_image->details->label); + eel_gtk_container_child_unmap (GTK_CONTAINER (widget), labeled_image->details->image); +} + +/* GtkContainerClass methods */ +static void +eel_labeled_image_add (GtkContainer *container, + GtkWidget *child) +{ + g_assert (GTK_IS_LABEL (child) || GTK_IS_IMAGE (child)); + + eel_gtk_container_child_add (container, child); +} + +static void +eel_labeled_image_remove (GtkContainer *container, + GtkWidget *child) +{ + EelLabeledImage *labeled_image; + + g_assert (GTK_IS_LABEL (child) || GTK_IS_IMAGE (child)); + + labeled_image = EEL_LABELED_IMAGE (container);; + + g_assert (child == labeled_image->details->image || child == labeled_image->details->label); + + eel_gtk_container_child_remove (container, child); + + if (labeled_image->details->image == child) + { + labeled_image->details->image = NULL; + } + + if (labeled_image->details->label == child) + { + labeled_image->details->label = NULL; + } +} + +static void +eel_labeled_image_forall (GtkContainer *container, + gboolean include_internals, + GtkCallback callback, + gpointer callback_data) +{ + EelLabeledImage *labeled_image; + + g_assert (EEL_IS_LABELED_IMAGE (container)); + g_assert (callback != NULL); + + labeled_image = EEL_LABELED_IMAGE (container); + + if (include_internals) + { + if (labeled_image->details->image != NULL) + { + (* callback) (labeled_image->details->image, callback_data); + } + + if (labeled_image->details->label != NULL) + { + (* callback) (labeled_image->details->label, callback_data); + } + } +} + +/* Private EelLabeledImage methods */ +static gboolean +is_fixed_height (const EelLabeledImage *labeled_image) +{ + return labeled_image->details->fixed_image_height > 0; +} + +static EelDimensions +labeled_image_get_image_dimensions (const EelLabeledImage *labeled_image) +{ + EelDimensions image_dimensions; + GtkRequisition image_requisition; + + g_assert (EEL_IS_LABELED_IMAGE (labeled_image)); + + if (!labeled_image_show_image (labeled_image)) + { + return eel_dimensions_empty; + } + + gtk_widget_size_request (labeled_image->details->image, &image_requisition); + + image_dimensions.width = (int) image_requisition.width; + image_dimensions.height = (int) image_requisition.height; + + if (is_fixed_height (labeled_image)) + { + image_dimensions.height = labeled_image->details->fixed_image_height; + } + + return image_dimensions; +} + +static EelDimensions +labeled_image_get_label_dimensions (const EelLabeledImage *labeled_image) +{ + EelDimensions label_dimensions; + GtkRequisition label_requisition; + + g_assert (EEL_IS_LABELED_IMAGE (labeled_image)); + + if (!labeled_image_show_label (labeled_image)) + { + return eel_dimensions_empty; + } + + gtk_widget_size_request (labeled_image->details->label, &label_requisition); + + label_dimensions.width = (int) label_requisition.width; + label_dimensions.height = (int) label_requisition.height; + + return label_dimensions; +} + +static EelIRect +labeled_image_get_image_bounds_fill (const EelLabeledImage *labeled_image) +{ + EelIRect image_bounds; + EelDimensions image_dimensions; + EelIRect content_bounds; + EelIRect bounds; + + g_assert (EEL_IS_LABELED_IMAGE (labeled_image)); + + image_dimensions = labeled_image_get_image_dimensions (labeled_image); + + if (eel_dimensions_are_empty (image_dimensions)) + { + return eel_irect_empty; + } + + content_bounds = labeled_image_get_content_bounds (labeled_image); + bounds = eel_gtk_widget_get_bounds (GTK_WIDGET (labeled_image)); + + if (!labeled_image_show_label (labeled_image)) + { + image_bounds = bounds; + } + else + { + switch (labeled_image->details->label_position) + { + case GTK_POS_LEFT: + image_bounds.y0 = bounds.y0; + image_bounds.x0 = content_bounds.x1 - image_dimensions.width; + image_bounds.y1 = bounds.y1; + image_bounds.x1 = bounds.x1; + break; + + case GTK_POS_RIGHT: + image_bounds.y0 = bounds.y0; + image_bounds.x0 = bounds.x0; + image_bounds.y1 = bounds.y1; + image_bounds.x1 = content_bounds.x0 + image_dimensions.width; + break; + + case GTK_POS_TOP: + image_bounds.x0 = bounds.x0; + image_bounds.y0 = content_bounds.y1 - image_dimensions.height; + image_bounds.x1 = bounds.x1; + image_bounds.y1 = bounds.y1; + break; + + case GTK_POS_BOTTOM: + image_bounds.x0 = bounds.x0; + image_bounds.y0 = bounds.y0; + image_bounds.x1 = bounds.x1; + image_bounds.y1 = content_bounds.y0 + image_dimensions.height; + break; + + default: + image_bounds.x0 = 0; + image_bounds.y0 = 0; + image_bounds.x1 = 0; + image_bounds.y1 = 0; + g_assert_not_reached (); + } + } + + return image_bounds; +} + +EelIRect +eel_labeled_image_get_image_bounds (const EelLabeledImage *labeled_image) +{ + EelDimensions image_dimensions; + EelDimensions label_dimensions; + GtkRequisition image_requisition; + EelIRect image_bounds; + EelIRect content_bounds; + + g_return_val_if_fail (EEL_IS_LABELED_IMAGE (labeled_image), eel_irect_empty); + + if (labeled_image->details->fill) + { + return labeled_image_get_image_bounds_fill (labeled_image); + } + + /* get true real dimensions if we're in fixed height mode */ + if (is_fixed_height (labeled_image) && labeled_image_show_image (labeled_image)) + { + gtk_widget_size_request (labeled_image->details->image, &image_requisition); + image_dimensions.width = (int) image_requisition.width; + image_dimensions.height = (int) image_requisition.height; + } + else + { + image_dimensions = labeled_image_get_image_dimensions (labeled_image); + } + + label_dimensions = labeled_image_get_label_dimensions (labeled_image); + + if (eel_dimensions_are_empty (image_dimensions)) + { + return eel_irect_empty; + } + + content_bounds = labeled_image_get_content_bounds (labeled_image); + + if (!labeled_image_show_label (labeled_image)) + { + image_bounds.x0 = + content_bounds.x0 + + (eel_irect_get_width (content_bounds) - image_dimensions.width) / 2; + image_bounds.y0 = + content_bounds.y0 + + (eel_irect_get_height (content_bounds) - image_dimensions.height) / 2; + } + else + { + switch (labeled_image->details->label_position) + { + case GTK_POS_LEFT: + image_bounds.x0 = content_bounds.x1 - image_dimensions.width; + image_bounds.y0 = + content_bounds.y0 + + (eel_irect_get_height (content_bounds) - image_dimensions.height) / 2; + break; + + case GTK_POS_RIGHT: + image_bounds.x0 = content_bounds.x0; + image_bounds.y0 = + content_bounds.y0 + + (eel_irect_get_height (content_bounds) - image_dimensions.height) / 2; + break; + + case GTK_POS_TOP: + image_bounds.x0 = + content_bounds.x0 + + (eel_irect_get_width (content_bounds) - image_dimensions.width) / 2; + image_bounds.y0 = content_bounds.y1 - image_dimensions.height; + break; + + case GTK_POS_BOTTOM: + image_bounds.x0 = + content_bounds.x0 + + (eel_irect_get_width (content_bounds) - image_dimensions.width) / 2; + + if (is_fixed_height (labeled_image)) + { + image_bounds.y0 = content_bounds.y0 + eel_irect_get_height (content_bounds) + - image_dimensions.height + - label_dimensions.height + - labeled_image->details->spacing; + } + else + { + image_bounds.y0 = content_bounds.y0; + } + + break; + + default: + image_bounds.x0 = 0; + image_bounds.y0 = 0; + g_assert_not_reached (); + } + } + + image_bounds.x1 = image_bounds.x0 + image_dimensions.width; + image_bounds.y1 = image_bounds.y0 + image_dimensions.height; + + return image_bounds; +} + +static EelIRect +labeled_image_get_label_bounds_fill (const EelLabeledImage *labeled_image) +{ + EelIRect label_bounds; + EelDimensions label_dimensions; + EelIRect content_bounds; + EelIRect bounds; + + g_assert (EEL_IS_LABELED_IMAGE (labeled_image)); + + label_dimensions = labeled_image_get_label_dimensions (labeled_image); + + if (eel_dimensions_are_empty (label_dimensions)) + { + return eel_irect_empty; + } + + content_bounds = labeled_image_get_content_bounds (labeled_image); + bounds = eel_gtk_widget_get_bounds (GTK_WIDGET (labeled_image)); + + /* Only the label is shown */ + if (!labeled_image_show_image (labeled_image)) + { + label_bounds = bounds; + /* Both label and image are shown */ + } + else + { + switch (labeled_image->details->label_position) + { + case GTK_POS_LEFT: + label_bounds.y0 = bounds.y0; + label_bounds.x0 = bounds.x0; + label_bounds.y1 = bounds.y1; + label_bounds.x1 = content_bounds.x0 + label_dimensions.width; + break; + + case GTK_POS_RIGHT: + label_bounds.y0 = bounds.y0; + label_bounds.x0 = content_bounds.x1 - label_dimensions.width; + label_bounds.y1 = bounds.y1; + label_bounds.x1 = bounds.x1; + break; + + case GTK_POS_TOP: + label_bounds.x0 = bounds.x0; + label_bounds.y0 = bounds.y0; + label_bounds.x1 = bounds.x1; + label_bounds.y1 = content_bounds.y0 + label_dimensions.height; + break; + + case GTK_POS_BOTTOM: + label_bounds.x0 = bounds.x0; + label_bounds.y0 = content_bounds.y1 - label_dimensions.height; + label_bounds.x1 = bounds.x1; + label_bounds.y1 = bounds.y1; + break; + + default: + label_bounds.x0 = 0; + label_bounds.y0 = 0; + label_bounds.x1 = 0; + label_bounds.y1 = 0; + g_assert_not_reached (); + } + } + + return label_bounds; +} + +EelIRect +eel_labeled_image_get_label_bounds (const EelLabeledImage *labeled_image) +{ + EelIRect label_bounds; + EelDimensions label_dimensions; + EelIRect content_bounds; + + g_return_val_if_fail (EEL_IS_LABELED_IMAGE (labeled_image), eel_irect_empty); + + if (labeled_image->details->fill) + { + return labeled_image_get_label_bounds_fill (labeled_image); + } + + label_dimensions = labeled_image_get_label_dimensions (labeled_image); + + if (eel_dimensions_are_empty (label_dimensions)) + { + return eel_irect_empty; + } + + content_bounds = labeled_image_get_content_bounds (labeled_image); + + /* Only the label is shown */ + if (!labeled_image_show_image (labeled_image)) + { + label_bounds.x0 = + content_bounds.x0 + + (eel_irect_get_width (content_bounds) - label_dimensions.width) / 2; + label_bounds.y0 = + content_bounds.y0 + + (eel_irect_get_height (content_bounds) - label_dimensions.height) / 2; + /* Both label and image are shown */ + } + else + { + switch (labeled_image->details->label_position) + { + case GTK_POS_LEFT: + label_bounds.x0 = content_bounds.x0; + label_bounds.y0 = + content_bounds.y0 + + (eel_irect_get_height (content_bounds) - label_dimensions.height) / 2; + break; + + case GTK_POS_RIGHT: + label_bounds.x0 = content_bounds.x1 - label_dimensions.width; + label_bounds.y0 = + content_bounds.y0 + + (eel_irect_get_height (content_bounds) - label_dimensions.height) / 2; + break; + + case GTK_POS_TOP: + label_bounds.x0 = + content_bounds.x0 + + (eel_irect_get_width (content_bounds) - label_dimensions.width) / 2; + label_bounds.y0 = content_bounds.y0; + break; + + case GTK_POS_BOTTOM: + label_bounds.x0 = + content_bounds.x0 + + (eel_irect_get_width (content_bounds) - label_dimensions.width) / 2; + label_bounds.y0 = content_bounds.y1 - label_dimensions.height; + break; + + default: + label_bounds.x0 = 0; + label_bounds.y0 = 0; + g_assert_not_reached (); + } + } + + label_bounds.x1 = label_bounds.x0 + label_dimensions.width; + label_bounds.y1 = label_bounds.y0 + label_dimensions.height; + + return label_bounds; +} + +static void +labeled_image_update_alignments (EelLabeledImage *labeled_image) +{ + + g_assert (EEL_IS_LABELED_IMAGE (labeled_image)); + + if (labeled_image->details->label != NULL) + { + float x_alignment; + float y_alignment; + + if (labeled_image->details->fill) + { + gtk_misc_get_alignment (GTK_MISC (labeled_image->details->label), + &x_alignment, &y_alignment); + + /* Only the label is shown */ + if (!labeled_image_show_image (labeled_image)) + { + x_alignment = 0.5; + y_alignment = 0.5; + /* Both label and image are shown */ + } + else + { + switch (labeled_image->details->label_position) + { + case GTK_POS_LEFT: + x_alignment = 1.0; + y_alignment = 0.5; + break; + + case GTK_POS_RIGHT: + x_alignment = 0.0; + y_alignment = 0.5; + break; + + case GTK_POS_TOP: + x_alignment = 0.5; + y_alignment = 1.0; + break; + + case GTK_POS_BOTTOM: + x_alignment = 0.5; + y_alignment = 0.0; + break; + } + + } + + gtk_misc_set_alignment (GTK_MISC (labeled_image->details->label), + x_alignment, + y_alignment); + } + } + + if (labeled_image->details->image != NULL) + { + float x_alignment; + float y_alignment; + + if (labeled_image->details->fill) + { + gtk_misc_get_alignment (GTK_MISC (labeled_image->details->image), + &x_alignment, &y_alignment); + + /* Only the image is shown */ + if (!labeled_image_show_label (labeled_image)) + { + x_alignment = 0.5; + y_alignment = 0.5; + /* Both label and image are shown */ + } + else + { + switch (labeled_image->details->label_position) + { + case GTK_POS_LEFT: + x_alignment = 0.0; + y_alignment = 0.5; + break; + + case GTK_POS_RIGHT: + x_alignment = 1.0; + y_alignment = 0.5; + break; + + case GTK_POS_TOP: + x_alignment = 0.5; + y_alignment = 0.0; + break; + + case GTK_POS_BOTTOM: + x_alignment = 0.5; + y_alignment = 1.0; + break; + } + } + + gtk_misc_set_alignment (GTK_MISC (labeled_image->details->image), + x_alignment, + y_alignment); + } + } +} + +static EelDimensions +labeled_image_get_content_dimensions (const EelLabeledImage *labeled_image) +{ + EelDimensions image_dimensions; + EelDimensions label_dimensions; + EelDimensions content_dimensions; + + g_assert (EEL_IS_LABELED_IMAGE (labeled_image)); + + image_dimensions = labeled_image_get_image_dimensions (labeled_image); + label_dimensions = labeled_image_get_label_dimensions (labeled_image); + + content_dimensions = eel_dimensions_empty; + + /* Both shown */ + if (!eel_dimensions_are_empty (image_dimensions) && !eel_dimensions_are_empty (label_dimensions)) + { + content_dimensions.width = + image_dimensions.width + labeled_image->details->spacing + label_dimensions.width; + switch (labeled_image->details->label_position) + { + case GTK_POS_LEFT: + case GTK_POS_RIGHT: + content_dimensions.width = + image_dimensions.width + labeled_image->details->spacing + label_dimensions.width; + content_dimensions.height = MAX (image_dimensions.height, label_dimensions.height); + break; + + case GTK_POS_TOP: + case GTK_POS_BOTTOM: + content_dimensions.width = MAX (image_dimensions.width, label_dimensions.width); + content_dimensions.height = + image_dimensions.height + labeled_image->details->spacing + label_dimensions.height; + break; + } + /* Only image shown */ + } + else if (!eel_dimensions_are_empty (image_dimensions)) + { + content_dimensions.width = image_dimensions.width; + content_dimensions.height = image_dimensions.height; + /* Only label shown */ + } + else + { + content_dimensions.width = label_dimensions.width; + content_dimensions.height = label_dimensions.height; + } + + return content_dimensions; +} + +static EelIRect +labeled_image_get_content_bounds (const EelLabeledImage *labeled_image) +{ + EelDimensions content_dimensions; + EelIRect content_bounds; + EelIRect bounds; + + g_assert (EEL_IS_LABELED_IMAGE (labeled_image)); + + bounds = eel_gtk_widget_get_bounds (GTK_WIDGET (labeled_image)); + + content_dimensions = labeled_image_get_content_dimensions (labeled_image); + content_bounds = eel_irect_align (bounds, + content_dimensions.width, + content_dimensions.height, + labeled_image->details->x_alignment, + labeled_image->details->y_alignment); + + return content_bounds; +} + +static void +labeled_image_ensure_label (EelLabeledImage *labeled_image) +{ + g_assert (EEL_IS_LABELED_IMAGE (labeled_image)); + + if (labeled_image->details->label != NULL) + { + return; + } + + labeled_image->details->label = gtk_label_new (NULL); + gtk_container_add (GTK_CONTAINER (labeled_image), labeled_image->details->label); + gtk_widget_show (labeled_image->details->label); +} + +static void +labeled_image_ensure_image (EelLabeledImage *labeled_image) +{ + g_assert (EEL_IS_LABELED_IMAGE (labeled_image)); + + if (labeled_image->details->image != NULL) + { + return; + } + + labeled_image->details->image = gtk_image_new (); + gtk_container_add (GTK_CONTAINER (labeled_image), labeled_image->details->image); + gtk_widget_show (labeled_image->details->image); +} + +static gboolean +labeled_image_show_image (const EelLabeledImage *labeled_image) +{ + g_assert (EEL_IS_LABELED_IMAGE (labeled_image)); + + return labeled_image->details->image != NULL && labeled_image->details->show_image; +} + +static gboolean +labeled_image_show_label (const EelLabeledImage *labeled_image) +{ + g_assert (EEL_IS_LABELED_IMAGE (labeled_image)); + + return labeled_image->details->label != NULL && labeled_image->details->show_label; +} + +/** + * eel_labeled_image_new: + * @text: Text to use for label or NULL. + * @pixbuf: Pixbuf to use for image or NULL. + * + * Returns A newly allocated EelLabeledImage. If the &text parameter is not + * NULL then the LabeledImage will show a label. If the &pixbuf parameter is not + * NULL then the LabeledImage will show a pixbuf. Either of these can be NULL at + * creation time. + * + * Later in the lifetime of the widget you can invoke methods that affect the + * label and/or the image. If at creation time these were NULL, then they will + * be created as neeeded. + * + * Thus, using this widget in place of EelImage or EelLabel is "free" with + * only the GtkObject and function call overhead. + * + */ +GtkWidget* +eel_labeled_image_new (const char *text, + GdkPixbuf *pixbuf) +{ + EelLabeledImage *labeled_image; + + labeled_image = EEL_LABELED_IMAGE (gtk_widget_new (eel_labeled_image_get_type (), NULL)); + + if (text != NULL) + { + eel_labeled_image_set_text (labeled_image, text); + } + + if (pixbuf != NULL) + { + eel_labeled_image_set_pixbuf (labeled_image, pixbuf); + } + + labeled_image_update_alignments (labeled_image); + + return GTK_WIDGET (labeled_image); +} + +/** + * eel_labeled_image_new_from_file_name: + * @text: Text to use for label or NULL. + * @file_name: File name of picture to use for pixbuf. Cannot be NULL. + * + * Returns A newly allocated EelLabeledImage. If the &text parameter is not + * NULL then the LabeledImage will show a label. + * + */ +GtkWidget* +eel_labeled_image_new_from_file_name (const char *text, + const char *pixbuf_file_name) +{ + EelLabeledImage *labeled_image; + + g_return_val_if_fail (pixbuf_file_name != NULL, NULL); + + labeled_image = EEL_LABELED_IMAGE (eel_labeled_image_new (text, NULL)); + eel_labeled_image_set_pixbuf_from_file_name (labeled_image, pixbuf_file_name); + return GTK_WIDGET (labeled_image); +} + +/** + * eel_labeled_image_set_label_position: + * @labeled_image: A EelLabeledImage. + * @label_position: The position of the label with respect to the image. + * + * Set the position of the label with respect to the image as follows: + * + * GTK_POS_LEFT: + * [