From ad51c7c2bad954dfd59f4771a1ba959cee5fc920 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Wed, 13 Dec 2023 06:45:00 +0100 Subject: [PATCH] Localize stripped down gtk2 This is intended mainly for GNU/Linux distros who will remove GTK2 support in the near future. --- .gitignore | 2 + gtk2_ardour/ardev_common.sh.in | 6 +- gtk2_ardour/ui_config.cc | 2 +- gtk2_ardour/wscript | 27 +- headless/wscript | 5 +- libs/ardour/wscript | 7 +- libs/canvas/wscript | 8 +- libs/clearlooks-newer/wscript | 7 +- libs/gtkmm2ext/wscript | 12 +- libs/surfaces/cc121/wscript | 7 +- libs/surfaces/console1/wscript | 10 +- libs/surfaces/contourdesign/wscript | 7 +- libs/surfaces/faderport/wscript | 7 +- libs/surfaces/faderport8/wscript | 21 +- libs/surfaces/generic_midi/wscript | 7 +- libs/surfaces/launch_control_xl/wscript | 7 +- libs/surfaces/launchpad_pro/wscript | 10 +- libs/surfaces/launchpad_x/wscript | 17 +- libs/surfaces/mackie/wscript | 14 +- libs/surfaces/maschine2/wscript | 7 +- libs/surfaces/osc/wscript | 7 +- libs/surfaces/push2/wscript | 7 +- libs/surfaces/us2400/wscript | 7 +- libs/surfaces/wiimote/wscript | 7 +- libs/tk/suil/cocoa_in_gtk2.mm | 439 + libs/tk/suil/dylib.h | 78 + libs/tk/suil/host.c | 98 + libs/tk/suil/instance.c | 409 + libs/tk/suil/suil/suil.h | 299 + libs/tk/suil/suil_config.h | 2 + libs/tk/suil/suil_internal.h | 175 + libs/tk/suil/win_in_gtk2.cpp | 258 + libs/tk/suil/wscript | 83 + libs/tk/suil/x11_in_gtk2.c | 589 + libs/tk/ydk-pixbuf/config.h | 42 + libs/tk/ydk-pixbuf/gdk-pixbuf-animation.c | 1001 + libs/tk/ydk-pixbuf/gdk-pixbuf-data.c | 125 + libs/tk/ydk-pixbuf/gdk-pixbuf-enum-types.c | 97 + libs/tk/ydk-pixbuf/gdk-pixbuf-io.c | 3308 ++ libs/tk/ydk-pixbuf/gdk-pixbuf-loader.c | 879 + libs/tk/ydk-pixbuf/gdk-pixbuf-marshal.c | 133 + libs/tk/ydk-pixbuf/gdk-pixbuf-scale.c | 563 + libs/tk/ydk-pixbuf/gdk-pixbuf-scaled-anim.c | 280 + libs/tk/ydk-pixbuf/gdk-pixbuf-simple-anim.c | 546 + libs/tk/ydk-pixbuf/gdk-pixbuf-util.c | 392 + libs/tk/ydk-pixbuf/gdk-pixbuf.c | 1064 + libs/tk/ydk-pixbuf/gdk-pixdata.c | 914 + libs/tk/ydk-pixbuf/io-pixdata.c | 190 + libs/tk/ydk-pixbuf/io-png.c | 1122 + libs/tk/ydk-pixbuf/io-xbm.c | 504 + libs/tk/ydk-pixbuf/io-xpm.c | 820 + libs/tk/ydk-pixbuf/pixops/DETAILS | 355 + libs/tk/ydk-pixbuf/pixops/README | 163 + .../pixops/composite_line_22_4a4_mmx.S | 239 + .../pixops/composite_line_color_22_4a4_mmx.S | 251 + libs/tk/ydk-pixbuf/pixops/have_mmx.S | 74 + .../pixops/pixbuf-transform-math.ltx | 112 + libs/tk/ydk-pixbuf/pixops/pixops-internal.h | 23 + libs/tk/ydk-pixbuf/pixops/pixops.c | 2558 ++ libs/tk/ydk-pixbuf/pixops/pixops.h | 118 + .../ydk-pixbuf/pixops/scale_line_22_33_mmx.S | 204 + libs/tk/ydk-pixbuf/pixops/timescale | Bin 0 -> 84472 bytes libs/tk/ydk-pixbuf/pixops/timescale.c | 265 + libs/tk/ydk-pixbuf/wscript | 65 + .../gdk-pixbuf/gdk-pixbuf-animation.h | 204 + .../ydk-pixbuf/gdk-pixbuf/gdk-pixbuf-core.h | 473 + .../gdk-pixbuf/gdk-pixbuf-enum-types.h | 33 + .../gdk-pixbuf/gdk-pixbuf-features.h | 120 + .../ydk-pixbuf/gdk-pixbuf/gdk-pixbuf-i18n.h | 36 + .../ydk-pixbuf/gdk-pixbuf/gdk-pixbuf-io.h | 351 + .../ydk-pixbuf/gdk-pixbuf/gdk-pixbuf-loader.h | 108 + .../gdk-pixbuf/gdk-pixbuf-marshal.h | 38 + .../gdk-pixbuf/gdk-pixbuf-private.h | 112 + .../gdk-pixbuf/gdk-pixbuf-scaled-anim.h | 45 + .../gdk-pixbuf/gdk-pixbuf-simple-anim.h | 64 + .../gdk-pixbuf/gdk-pixbuf-transform.h | 158 + .../ydk-pixbuf/gdk-pixbuf/gdk-pixbuf.h | 43 + .../ydk-pixbuf/gdk-pixbuf/gdk-pixdata.h | 168 + .../ydk-pixbuf/gdk-pixbuf/xpm-color-table.h | 1347 + libs/tk/ydk/config.h | 153 + libs/tk/ydk/gdk.c | 838 + libs/tk/ydk/gdkaliasdef.c | 2918 ++ libs/tk/ydk/gdkapplaunchcontext.c | 292 + libs/tk/ydk/gdkcairo.c | 353 + libs/tk/ydk/gdkcolor.c | 398 + libs/tk/ydk/gdkcursor.c | 119 + libs/tk/ydk/gdkdisplay.c | 1307 + libs/tk/ydk/gdkdisplaymanager.c | 264 + libs/tk/ydk/gdkdnd.c | 212 + libs/tk/ydk/gdkdraw.c | 1979 + libs/tk/ydk/gdkenumtypes.c | 962 + libs/tk/ydk/gdkevents.c | 1412 + libs/tk/ydk/gdkfont.c | 359 + libs/tk/ydk/gdkgc.c | 1599 + libs/tk/ydk/gdkglobals.c | 48 + libs/tk/ydk/gdkimage.c | 659 + libs/tk/ydk/gdkkeynames.c | 133 + libs/tk/ydk/gdkkeys.c | 316 + libs/tk/ydk/gdkkeyuni.c | 1713 + libs/tk/ydk/gdkmarshalers.c | 208 + libs/tk/ydk/gdkmedialib.c | 120 + libs/tk/ydk/gdkoffscreenwindow.c | 1308 + libs/tk/ydk/gdkpango.c | 1500 + libs/tk/ydk/gdkpixbuf-drawable.c | 1418 + libs/tk/ydk/gdkpixbuf-render.c | 350 + libs/tk/ydk/gdkpixmap.c | 869 + libs/tk/ydk/gdkpolyreg-generic.c | 627 + libs/tk/ydk/gdkrectangle.c | 139 + libs/tk/ydk/gdkregion-generic.c | 1909 + libs/tk/ydk/gdkrgb.c | 3770 ++ libs/tk/ydk/gdkscreen.c | 545 + libs/tk/ydk/gdkselection.c | 139 + libs/tk/ydk/gdkvisual.c | 254 + libs/tk/ydk/gdkwindow.c | 11413 +++++ libs/tk/ydk/gdkwindowimpl.c | 52 + libs/tk/ydk/quartz/GdkQuartzView.c | 767 + libs/tk/ydk/quartz/GdkQuartzWindow.c | 667 + .../ydk/quartz/gdkapplaunchcontext-quartz.c | 42 + libs/tk/ydk/quartz/gdkcolor-quartz.c | 258 + libs/tk/ydk/quartz/gdkcursor-quartz.c | 498 + libs/tk/ydk/quartz/gdkdisplay-quartz.c | 182 + libs/tk/ydk/quartz/gdkdnd-quartz.c | 224 + libs/tk/ydk/quartz/gdkdrawable-quartz.c | 874 + libs/tk/ydk/quartz/gdkeventloop-quartz.c | 1049 + libs/tk/ydk/quartz/gdkevents-quartz.c | 1893 + libs/tk/ydk/quartz/gdkfont-quartz.c | 134 + libs/tk/ydk/quartz/gdkgc-quartz.c | 738 + libs/tk/ydk/quartz/gdkgeometry-quartz.c | 65 + libs/tk/ydk/quartz/gdkglobals-quartz.c | 55 + libs/tk/ydk/quartz/gdkim-quartz.c | 73 + libs/tk/ydk/quartz/gdkimage-quartz.c | 390 + libs/tk/ydk/quartz/gdkinput.c | 755 + libs/tk/ydk/quartz/gdkkeys-quartz.c | 820 + libs/tk/ydk/quartz/gdkmain-quartz.c | 101 + libs/tk/ydk/quartz/gdkpixmap-quartz.c | 406 + libs/tk/ydk/quartz/gdkproperty-quartz.c | 211 + libs/tk/ydk/quartz/gdkscreen-quartz.c | 495 + libs/tk/ydk/quartz/gdkselection-quartz.c | 273 + libs/tk/ydk/quartz/gdkspawn-quartz.c | 106 + libs/tk/ydk/quartz/gdktestutils-quartz.c | 125 + libs/tk/ydk/quartz/gdkvisual-quartz.c | 264 + libs/tk/ydk/quartz/gdkwindow-quartz.c | 3099 ++ libs/tk/ydk/win32/bdfcursor.c | 408 + libs/tk/ydk/win32/gdkapplaunchcontext-win32.c | 42 + libs/tk/ydk/win32/gdkcolor-win32.c | 1311 + libs/tk/ydk/win32/gdkcursor-win32.c | 994 + libs/tk/ydk/win32/gdkdisplay-win32.c | 572 + libs/tk/ydk/win32/gdkdnd-win32.c | 2461 ++ libs/tk/ydk/win32/gdkdrawable-win32.c | 2054 + libs/tk/ydk/win32/gdkevents-win32.c | 3797 ++ libs/tk/ydk/win32/gdkfont-win32.c | 1722 + libs/tk/ydk/win32/gdkgc-win32.c | 1153 + libs/tk/ydk/win32/gdkgeometry-win32.c | 285 + libs/tk/ydk/win32/gdkglobals-win32.c | 86 + libs/tk/ydk/win32/gdkim-win32.c | 77 + libs/tk/ydk/win32/gdkimage-win32.c | 431 + libs/tk/ydk/win32/gdkinput-win32.c | 1347 + libs/tk/ydk/win32/gdkinput.c | 523 + libs/tk/ydk/win32/gdkkeys-win32.c | 1675 + libs/tk/ydk/win32/gdkmain-win32.c | 1200 + libs/tk/ydk/win32/gdkpixmap-win32.c | 544 + libs/tk/ydk/win32/gdkprivate-win32.h | 519 + libs/tk/ydk/win32/gdkproperty-win32.c | 460 + libs/tk/ydk/win32/gdkscreen-win32.c | 184 + libs/tk/ydk/win32/gdkselection-win32.c | 1311 + libs/tk/ydk/win32/gdkspawn-win32.c | 106 + libs/tk/ydk/win32/gdktestutils-win32.c | 132 + libs/tk/ydk/win32/gdkvisual-win32.c | 401 + libs/tk/ydk/win32/gdkwin32id.c | 83 + libs/tk/ydk/win32/gdkwindow-win32.c | 4171 ++ libs/tk/ydk/win32/rc/Makefile.am | 15 + libs/tk/ydk/win32/rc/gdk.rc | 32 + libs/tk/ydk/win32/rc/gdk.rc.in | 32 + libs/tk/ydk/win32/rc/gtk.ico | Bin 0 -> 25214 bytes libs/tk/ydk/wscript | 209 + libs/tk/ydk/x11/checksettings.c | 44 + libs/tk/ydk/x11/gdkapplaunchcontext-x11.c | 446 + libs/tk/ydk/x11/gdkasync.c | 845 + libs/tk/ydk/x11/gdkcolor-x11.c | 1510 + libs/tk/ydk/x11/gdkcursor-x11.c | 1094 + libs/tk/ydk/x11/gdkdisplay-x11.c | 1491 + libs/tk/ydk/x11/gdkdnd-x11.c | 4045 ++ libs/tk/ydk/x11/gdkdrawable-x11.c | 1602 + libs/tk/ydk/x11/gdkevents-x11.c | 3181 ++ libs/tk/ydk/x11/gdkfont-x11.c | 848 + libs/tk/ydk/x11/gdkgc-x11.c | 713 + libs/tk/ydk/x11/gdkgeometry-x11.c | 323 + libs/tk/ydk/x11/gdkglobals-x11.c | 37 + libs/tk/ydk/x11/gdkim-x11.c | 252 + libs/tk/ydk/x11/gdkimage-x11.c | 814 + libs/tk/ydk/x11/gdkinput-none.c | 126 + libs/tk/ydk/x11/gdkinput-x11.c | 975 + libs/tk/ydk/x11/gdkinput-xfree.c | 451 + libs/tk/ydk/x11/gdkinput.c | 679 + libs/tk/ydk/x11/gdkkeys-x11.c | 1857 + libs/tk/ydk/x11/gdkmain-x11.c | 758 + libs/tk/ydk/x11/gdkpixmap-x11.c | 462 + libs/tk/ydk/x11/gdkproperty-x11.c | 762 + libs/tk/ydk/x11/gdkscreen-x11.c | 1513 + libs/tk/ydk/x11/gdkselection-x11.c | 947 + libs/tk/ydk/x11/gdksettings.c | 137 + libs/tk/ydk/x11/gdkspawn-x11.c | 228 + libs/tk/ydk/x11/gdktestutils-x11.c | 252 + libs/tk/ydk/x11/gdkvisual-x11.c | 679 + libs/tk/ydk/x11/gdkwindow-x11.c | 5690 +++ libs/tk/ydk/x11/gdkxftdefaults.c | 300 + libs/tk/ydk/x11/gdkxid.c | 150 + libs/tk/ydk/x11/xsettings-client.c | 609 + libs/tk/ydk/x11/xsettings-common.c | 265 + libs/tk/ydk/ydk/gdk/gdk.h | 244 + libs/tk/ydk/ydk/gdk/gdkalias.h | 2915 ++ libs/tk/ydk/ydk/gdk/gdkapplaunchcontext.h | 76 + libs/tk/ydk/ydk/gdk/gdkcairo.h | 59 + libs/tk/ydk/ydk/gdk/gdkcolor.h | 176 + libs/tk/ydk/ydk/gdk/gdkcursor.h | 168 + libs/tk/ydk/ydk/gdk/gdkdisplay.h | 229 + libs/tk/ydk/ydk/gdk/gdkdisplaymanager.h | 67 + libs/tk/ydk/ydk/gdk/gdkdnd.h | 186 + libs/tk/ydk/ydk/gdk/gdkdrawable.h | 436 + libs/tk/ydk/ydk/gdk/gdkenumtypes.h | 137 + libs/tk/ydk/ydk/gdk/gdkevents.h | 572 + libs/tk/ydk/ydk/gdk/gdkfont.h | 138 + libs/tk/ydk/ydk/gdk/gdkgc.h | 298 + libs/tk/ydk/ydk/gdk/gdki18n.h | 59 + libs/tk/ydk/ydk/gdk/gdkimage.h | 145 + libs/tk/ydk/ydk/gdk/gdkinput.h | 192 + libs/tk/ydk/ydk/gdk/gdkinternals.h | 714 + libs/tk/ydk/ydk/gdk/gdkintl.h | 38 + libs/tk/ydk/ydk/gdk/gdkkeys.h | 134 + libs/tk/ydk/ydk/gdk/gdkkeysyms-compat.h | 2208 + libs/tk/ydk/ydk/gdk/gdkkeysyms.h | 2221 + libs/tk/ydk/ydk/gdk/gdkmarshalers.h | 54 + libs/tk/ydk/ydk/gdk/gdkmedialib.h | 45 + libs/tk/ydk/ydk/gdk/gdkpango.h | 166 + libs/tk/ydk/ydk/gdk/gdkpixbuf.h | 115 + libs/tk/ydk/ydk/gdk/gdkpixmap.h | 136 + libs/tk/ydk/ydk/gdk/gdkpoly-generic.h | 291 + libs/tk/ydk/ydk/gdk/gdkprivate.h | 60 + libs/tk/ydk/ydk/gdk/gdkproperty.h | 128 + libs/tk/ydk/ydk/gdk/gdkregion-generic.h | 177 + libs/tk/ydk/ydk/gdk/gdkregion.h | 127 + libs/tk/ydk/ydk/gdk/gdkrgb.h | 149 + libs/tk/ydk/ydk/gdk/gdkscreen.h | 132 + libs/tk/ydk/ydk/gdk/gdkselection.h | 111 + libs/tk/ydk/ydk/gdk/gdkspawn.h | 64 + libs/tk/ydk/ydk/gdk/gdktestutils.h | 49 + libs/tk/ydk/ydk/gdk/gdktypes.h | 226 + libs/tk/ydk/ydk/gdk/gdkvisual.h | 147 + libs/tk/ydk/ydk/gdk/gdkwindow.h | 743 + libs/tk/ydk/ydk/gdk/gdkwindowimpl.h | 175 + libs/tk/ydk/ydk/gdk/keyname-table.h | 3978 ++ libs/tk/ydk/ydk/gdk/quartz/GdkQuartzView.h | 51 + libs/tk/ydk/ydk/gdk/quartz/GdkQuartzWindow.h | 52 + .../ydk/ydk/gdk/quartz/gdkdrawable-quartz.h | 69 + libs/tk/ydk/ydk/gdk/quartz/gdkinputprivate.h | 160 + libs/tk/ydk/ydk/gdk/quartz/gdkpixmap-quartz.h | 63 + .../tk/ydk/ydk/gdk/quartz/gdkprivate-quartz.h | 221 + libs/tk/ydk/ydk/gdk/quartz/gdkscreen-quartz.h | 68 + libs/tk/ydk/ydk/gdk/quartz/gdkwindow-quartz.h | 78 + libs/tk/ydk/ydk/gdk/quartz/xcursors.h | 156 + libs/tk/ydk/ydk/gdk/stamp-gdkenumtypes.h | 1 + libs/tk/ydk/ydk/gdk/x11/gdkdisplay-x11.h | 171 + libs/tk/ydk/ydk/gdk/x11/gdkdrawable-x11.h | 98 + libs/tk/ydk/ydk/gdk/x11/gdkpixmap-x11.h | 68 + libs/tk/ydk/ydk/gdk/x11/gdkwindow-x11.h | 162 + libs/tk/ydk/ydk/gdkconfig.h | 41 + libs/tk/ydk/ydk/gdkscreen-x11.h | 135 + libs/tk/ydk/ydk/quartz/gdk/gdkquartz.h | 78 + libs/tk/ydk/ydk/win32/gdk/gdkdrawable-win32.h | 74 + libs/tk/ydk/ydk/win32/gdk/gdkinput-win32.h | 140 + libs/tk/ydk/ydk/win32/gdk/gdkpixmap-win32.h | 68 + libs/tk/ydk/ydk/win32/gdk/gdkwin32.h | 129 + libs/tk/ydk/ydk/win32/gdk/gdkwin32keys.h | 68 + libs/tk/ydk/ydk/win32/gdk/gdkwindow-win32.h | 127 + libs/tk/ydk/ydk/win32/gdk/pktdef.h | 233 + libs/tk/ydk/ydk/win32/gdk/wintab.h | 863 + libs/tk/ydk/ydk/win32/gdk/xcursors.h | 363 + libs/tk/ydk/ydk/x11/gdk/MwmUtil.h | 136 + libs/tk/ydk/ydk/x11/gdk/gdkasync.h | 75 + libs/tk/ydk/ydk/x11/gdk/gdkinputprivate.h | 189 + libs/tk/ydk/ydk/x11/gdk/gdkprivate-x11.h | 219 + libs/tk/ydk/ydk/x11/gdk/gdkx.h | 256 + libs/tk/ydk/ydk/x11/gdk/xsettings-client.h | 79 + libs/tk/ydk/ydk/x11/gdk/xsettings-common.h | 130 + libs/tk/ydkmm/bitmap.cc | 76 + libs/tk/ydkmm/color.cc | 329 + libs/tk/ydkmm/colormap.cc | 215 + libs/tk/ydkmm/cursor.cc | 177 + libs/tk/ydkmm/device.cc | 235 + libs/tk/ydkmm/display.cc | 625 + libs/tk/ydkmm/displaymanager.cc | 274 + libs/tk/ydkmm/dragcontext.cc | 293 + libs/tk/ydkmm/drawable.cc | 488 + libs/tk/ydkmm/event.cc | 226 + libs/tk/ydkmm/gc.cc | 341 + libs/tk/ydkmm/general.cc | 119 + libs/tk/ydkmm/image.cc | 279 + libs/tk/ydkmm/pixbuf.cc | 655 + libs/tk/ydkmm/pixbufanimation.cc | 182 + libs/tk/ydkmm/pixbufanimationiter.cc | 173 + libs/tk/ydkmm/pixbufformat.cc | 122 + libs/tk/ydkmm/pixbufloader.cc | 487 + libs/tk/ydkmm/pixmap.cc | 336 + libs/tk/ydkmm/rectangle.cc | 165 + libs/tk/ydkmm/region.cc | 233 + libs/tk/ydkmm/rgb.cc | 44 + libs/tk/ydkmm/rgbcmap.cc | 80 + libs/tk/ydkmm/screen.cc | 520 + libs/tk/ydkmm/types.cc | 119 + libs/tk/ydkmm/visual.cc | 267 + libs/tk/ydkmm/window.cc | 1072 + libs/tk/ydkmm/wrap_init.cc | 133 + libs/tk/ydkmm/wscript | 70 + libs/tk/ydkmm/ydkmm/gdkmm.h | 47 + libs/tk/ydkmm/ydkmm/gdkmm/bitmap.h | 80 + libs/tk/ydkmm/ydkmm/gdkmm/color.h | 305 + libs/tk/ydkmm/ydkmm/gdkmm/colormap.h | 240 + libs/tk/ydkmm/ydkmm/gdkmm/cursor.h | 297 + libs/tk/ydkmm/ydkmm/gdkmm/device.h | 317 + libs/tk/ydkmm/ydkmm/gdkmm/display.h | 823 + libs/tk/ydkmm/ydkmm/gdkmm/displaymanager.h | 214 + libs/tk/ydkmm/ydkmm/gdkmm/dragcontext.h | 442 + libs/tk/ydkmm/ydkmm/gdkmm/drawable.h | 853 + libs/tk/ydkmm/ydkmm/gdkmm/event.h | 431 + libs/tk/ydkmm/ydkmm/gdkmm/gc.h | 747 + libs/tk/ydkmm/ydkmm/gdkmm/general.h | 161 + libs/tk/ydkmm/ydkmm/gdkmm/image.h | 405 + libs/tk/ydkmm/ydkmm/gdkmm/list.h | 157 + libs/tk/ydkmm/ydkmm/gdkmm/pixbuf.h | 925 + libs/tk/ydkmm/ydkmm/gdkmm/pixbufanimation.h | 158 + .../ydkmm/ydkmm/gdkmm/pixbufanimationiter.h | 239 + libs/tk/ydkmm/ydkmm/gdkmm/pixbufformat.h | 94 + libs/tk/ydkmm/ydkmm/gdkmm/pixbufloader.h | 305 + libs/tk/ydkmm/ydkmm/gdkmm/pixmap.h | 215 + libs/tk/ydkmm/ydkmm/gdkmm/private/bitmap_p.h | 11 + libs/tk/ydkmm/ydkmm/gdkmm/private/color_p.h | 8 + .../tk/ydkmm/ydkmm/gdkmm/private/colormap_p.h | 48 + libs/tk/ydkmm/ydkmm/gdkmm/private/cursor_p.h | 11 + libs/tk/ydkmm/ydkmm/gdkmm/private/device_p.h | 48 + libs/tk/ydkmm/ydkmm/gdkmm/private/display_p.h | 49 + .../ydkmm/gdkmm/private/displaymanager_p.h | 49 + .../ydkmm/ydkmm/gdkmm/private/dragcontext_p.h | 48 + .../tk/ydkmm/ydkmm/gdkmm/private/drawable_p.h | 48 + libs/tk/ydkmm/ydkmm/gdkmm/private/event_p.h | 8 + libs/tk/ydkmm/ydkmm/gdkmm/private/gc_p.h | 48 + libs/tk/ydkmm/ydkmm/gdkmm/private/image_p.h | 48 + libs/tk/ydkmm/ydkmm/gdkmm/private/pixbuf_p.h | 48 + .../ydkmm/gdkmm/private/pixbufanimation_p.h | 48 + .../gdkmm/private/pixbufanimationiter_p.h | 48 + .../ydkmm/gdkmm/private/pixbufformat_p.h | 8 + .../ydkmm/gdkmm/private/pixbufloader_p.h | 51 + libs/tk/ydkmm/ydkmm/gdkmm/private/pixmap_p.h | 48 + .../ydkmm/ydkmm/gdkmm/private/rectangle_p.h | 8 + libs/tk/ydkmm/ydkmm/gdkmm/private/region_p.h | 8 + libs/tk/ydkmm/ydkmm/gdkmm/private/rgbcmap_p.h | 8 + libs/tk/ydkmm/ydkmm/gdkmm/private/screen_p.h | 49 + libs/tk/ydkmm/ydkmm/gdkmm/private/types_p.h | 8 + libs/tk/ydkmm/ydkmm/gdkmm/private/visual_p.h | 48 + libs/tk/ydkmm/ydkmm/gdkmm/private/window_p.h | 48 + libs/tk/ydkmm/ydkmm/gdkmm/rectangle.h | 155 + libs/tk/ydkmm/ydkmm/gdkmm/region.h | 333 + libs/tk/ydkmm/ydkmm/gdkmm/rgb.h | 55 + libs/tk/ydkmm/ydkmm/gdkmm/rgbcmap.h | 88 + libs/tk/ydkmm/ydkmm/gdkmm/screen.h | 771 + libs/tk/ydkmm/ydkmm/gdkmm/types.h | 406 + libs/tk/ydkmm/ydkmm/gdkmm/visual.h | 358 + libs/tk/ydkmm/ydkmm/gdkmm/window.h | 2729 ++ libs/tk/ydkmm/ydkmm/gdkmm/wrap_init.h | 32 + libs/tk/ydkmm/ydkmm/gdkmmconfig.h | 9 + libs/tk/ytk/config.h | 150 + libs/tk/ytk/fnmatch.c | 364 + libs/tk/ytk/gtkaboutdialog.c | 2504 ++ libs/tk/ytk/gtkaccelgroup.c | 1492 + libs/tk/ytk/gtkaccellabel.c | 874 + libs/tk/ytk/gtkaccelmap.c | 1037 + libs/tk/ytk/gtkaccessible.c | 121 + libs/tk/ytk/gtkaction.c | 1964 + libs/tk/ytk/gtkactiongroup.c | 1441 + libs/tk/ytk/gtkactivatable.c | 564 + libs/tk/ytk/gtkadjustment.c | 702 + libs/tk/ytk/gtkaliasdef.c | 13137 ++++++ libs/tk/ytk/gtkalignment.c | 651 + libs/tk/ytk/gtkarrow.c | 308 + libs/tk/ytk/gtkaspectframe.c | 355 + libs/tk/ytk/gtkassistant.c | 2553 ++ libs/tk/ytk/gtkbbox.c | 823 + libs/tk/ytk/gtkbin.c | 163 + libs/tk/ytk/gtkbindings.c | 1729 + libs/tk/ytk/gtkbox.c | 1266 + libs/tk/ytk/gtkbuildable.c | 362 + libs/tk/ytk/gtkbuilder.c | 1635 + libs/tk/ytk/gtkbuilderparser.c | 1204 + libs/tk/ytk/gtkbutton.c | 2336 + libs/tk/ytk/gtkcelleditable.c | 142 + libs/tk/ytk/gtkcelllayout.c | 447 + libs/tk/ytk/gtkcellrenderer.c | 994 + libs/tk/ytk/gtkcellrendereraccel.c | 682 + libs/tk/ytk/gtkcellrenderercombo.c | 493 + libs/tk/ytk/gtkcellrendererpixbuf.c | 780 + libs/tk/ytk/gtkcellrendererprogress.c | 678 + libs/tk/ytk/gtkcellrendererspin.c | 356 + libs/tk/ytk/gtkcellrendererspinner.c | 392 + libs/tk/ytk/gtkcellrenderertext.c | 1934 + libs/tk/ytk/gtkcellrenderertoggle.c | 527 + libs/tk/ytk/gtkcellview.c | 1127 + libs/tk/ytk/gtkcheckbutton.c | 429 + libs/tk/ytk/gtkcheckmenuitem.c | 565 + libs/tk/ytk/gtkclipboard-quartz.c | 1125 + libs/tk/ytk/gtkclipboard.c | 2089 + libs/tk/ytk/gtkcolorbutton.c | 873 + libs/tk/ytk/gtkcolorsel.c | 2947 ++ libs/tk/ytk/gtkcolorseldialog.c | 234 + libs/tk/ytk/gtkcombobox.c | 6376 +++ libs/tk/ytk/gtkcomboboxentry.c | 477 + libs/tk/ytk/gtkcomboboxtext.c | 524 + libs/tk/ytk/gtkcontainer.c | 2764 ++ libs/tk/ytk/gtkdialog.c | 1566 + libs/tk/ytk/gtkdnd-quartz.c | 2019 + libs/tk/ytk/gtkdnd.c | 4405 ++ libs/tk/ytk/gtkdrawingarea.c | 153 + libs/tk/ytk/gtkeditable.c | 429 + libs/tk/ytk/gtkentry.c | 10187 +++++ libs/tk/ytk/gtkentrybuffer.c | 754 + libs/tk/ytk/gtkentrycompletion.c | 2003 + libs/tk/ytk/gtkeventbox.c | 575 + libs/tk/ytk/gtkexpander.c | 1830 + libs/tk/ytk/gtkfilechooser.c | 2907 ++ libs/tk/ytk/gtkfilechooserbutton.c | 3157 ++ libs/tk/ytk/gtkfilechooserdefault.c | 10357 +++++ libs/tk/ytk/gtkfilechooserdialog.c | 490 + libs/tk/ytk/gtkfilechooserembed.c | 197 + libs/tk/ytk/gtkfilechooserentry.c | 963 + libs/tk/ytk/gtkfilechoosersettings.c | 533 + libs/tk/ytk/gtkfilechooserutils.c | 421 + libs/tk/ytk/gtkfilechooserwidget.c | 196 + libs/tk/ytk/gtkfilefilter.c | 437 + libs/tk/ytk/gtkfilesystem.c | 1726 + libs/tk/ytk/gtkfilesystemmodel.c | 2180 + libs/tk/ytk/gtkfixed.c | 506 + libs/tk/ytk/gtkfontbutton.c | 919 + libs/tk/ytk/gtkfontsel.c | 1876 + libs/tk/ytk/gtkframe.c | 734 + libs/tk/ytk/gtkgc.c | 420 + libs/tk/ytk/gtkhandlebox.c | 1437 + libs/tk/ytk/gtkhbbox.c | 102 + libs/tk/ytk/gtkhbox.c | 85 + libs/tk/ytk/gtkhpaned.c | 54 + libs/tk/ytk/gtkhruler.c | 56 + libs/tk/ytk/gtkhscale.c | 116 + libs/tk/ytk/gtkhscrollbar.c | 70 + libs/tk/ytk/gtkhseparator.c | 54 + libs/tk/ytk/gtkhsv.c | 1693 + libs/tk/ytk/gtkiconcache.c | 594 + libs/tk/ytk/gtkiconcachevalidator.c | 405 + libs/tk/ytk/gtkiconfactory.c | 2990 ++ libs/tk/ytk/gtkicontheme.c | 3688 ++ libs/tk/ytk/gtkiconview.c | 10022 +++++ libs/tk/ytk/gtkimage.c | 2516 ++ libs/tk/ytk/gtkimagemenuitem.c | 1056 + libs/tk/ytk/gtkimcontext.c | 714 + libs/tk/ytk/gtkimcontextsimple.c | 1244 + libs/tk/ytk/gtkimmodule.c | 768 + libs/tk/ytk/gtkimmulticontext.c | 712 + libs/tk/ytk/gtkinfobar.c | 1265 + libs/tk/ytk/gtkinvisible.c | 325 + libs/tk/ytk/gtkitem.c | 179 + libs/tk/ytk/gtkkeyhash.c | 580 + libs/tk/ytk/gtklabel.c | 6031 +++ libs/tk/ytk/gtklayout.c | 1119 + libs/tk/ytk/gtklinkbutton.c | 793 + libs/tk/ytk/gtkliststore.c | 2389 ++ libs/tk/ytk/gtkmain.c | 2715 ++ libs/tk/ytk/gtkmarshal.c | 1097 + libs/tk/ytk/gtkmarshalers.c | 3162 ++ libs/tk/ytk/gtkmenu.c | 5375 +++ libs/tk/ytk/gtkmenubar.c | 934 + libs/tk/ytk/gtkmenuitem.c | 2226 + libs/tk/ytk/gtkmenushell.c | 1841 + libs/tk/ytk/gtkmenutoolbutton.c | 695 + libs/tk/ytk/gtkmessagedialog.c | 1044 + libs/tk/ytk/gtkmisc.c | 375 + libs/tk/ytk/gtkmnemonichash.c | 200 + libs/tk/ytk/gtkmodules.c | 580 + libs/tk/ytk/gtkmountoperation-stub.c | 68 + libs/tk/ytk/gtkmountoperation-x11.c | 979 + libs/tk/ytk/gtkmountoperation.c | 1533 + libs/tk/ytk/gtknotebook.c | 8149 ++++ libs/tk/ytk/gtkobject.c | 780 + libs/tk/ytk/gtkoffscreenwindow.c | 320 + libs/tk/ytk/gtkoptionmenu.c | 1036 + libs/tk/ytk/gtkorientable.c | 100 + libs/tk/ytk/gtkpaned.c | 2256 + libs/tk/ytk/gtkpango.c | 233 + libs/tk/ytk/gtkpathbar.c | 1823 + libs/tk/ytk/gtkplug-stub.c | 84 + libs/tk/ytk/gtkplug-win32.c | 307 + libs/tk/ytk/gtkplug-x11.c | 332 + libs/tk/ytk/gtkplug.c | 1070 + libs/tk/ytk/gtkprogress.c | 714 + libs/tk/ytk/gtkprogressbar.c | 1399 + libs/tk/ytk/gtkquartz.c | 382 + libs/tk/ytk/gtkquery.c | 142 + libs/tk/ytk/gtkradioaction.c | 532 + libs/tk/ytk/gtkradiobutton.c | 809 + libs/tk/ytk/gtkradiomenuitem.c | 503 + libs/tk/ytk/gtkradiotoolbutton.c | 257 + libs/tk/ytk/gtkrange.c | 4048 ++ libs/tk/ytk/gtkrbtree.c | 1752 + libs/tk/ytk/gtkrc.c | 4954 +++ libs/tk/ytk/gtkrecentaction.c | 770 + libs/tk/ytk/gtkrecentchooser.c | 1203 + libs/tk/ytk/gtkrecentchooserdefault.c | 1997 + libs/tk/ytk/gtkrecentchooserdialog.c | 354 + libs/tk/ytk/gtkrecentchoosermenu.c | 1297 + libs/tk/ytk/gtkrecentchooserutils.c | 534 + libs/tk/ytk/gtkrecentchooserwidget.c | 194 + libs/tk/ytk/gtkrecentfilter.c | 579 + libs/tk/ytk/gtkrecentmanager.c | 2596 ++ libs/tk/ytk/gtkrelocation.c | 303 + libs/tk/ytk/gtkruler.c | 898 + libs/tk/ytk/gtkscale.c | 1729 + libs/tk/ytk/gtkscalebutton.c | 1580 + libs/tk/ytk/gtkscrollbar.c | 156 + libs/tk/ytk/gtkscrolledwindow.c | 1841 + libs/tk/ytk/gtksearchengine.c | 203 + libs/tk/ytk/gtksearchenginequartz.c | 274 + libs/tk/ytk/gtksearchenginesimple.c | 382 + libs/tk/ytk/gtkselection.c | 3180 ++ libs/tk/ytk/gtkseparator.c | 262 + libs/tk/ytk/gtkseparatormenuitem.c | 51 + libs/tk/ytk/gtkseparatortoolitem.c | 285 + libs/tk/ytk/gtksettings.c | 2670 ++ libs/tk/ytk/gtkshow.c | 83 + libs/tk/ytk/gtksizegroup.c | 946 + libs/tk/ytk/gtksocket-stub.c | 121 + libs/tk/ytk/gtksocket-win32.c | 307 + libs/tk/ytk/gtksocket-x11.c | 657 + libs/tk/ytk/gtksocket.c | 1077 + libs/tk/ytk/gtkspinbutton.c | 2353 + libs/tk/ytk/gtkspinner.c | 630 + libs/tk/ytk/gtkstatusbar.c | 1066 + libs/tk/ytk/gtkstock.c | 559 + libs/tk/ytk/gtkstyle.c | 7209 ++++ libs/tk/ytk/gtktable.c | 1644 + libs/tk/ytk/gtktearoffmenuitem.c | 255 + libs/tk/ytk/gtktextbtree.c | 7294 ++++ libs/tk/ytk/gtktextbuffer.c | 4413 ++ libs/tk/ytk/gtktextbufferrichtext.c | 828 + libs/tk/ytk/gtktextbufferserialize.c | 1873 + libs/tk/ytk/gtktextchild.c | 515 + libs/tk/ytk/gtktextdisplay.c | 923 + libs/tk/ytk/gtktextiter.c | 5579 +++ libs/tk/ytk/gtktextlayout.c | 3737 ++ libs/tk/ytk/gtktextmark.c | 495 + libs/tk/ytk/gtktextsegment.c | 643 + libs/tk/ytk/gtktexttag.c | 2357 + libs/tk/ytk/gtktexttagtable.c | 474 + libs/tk/ytk/gtktexttypes.c | 49 + libs/tk/ytk/gtktextutil.c | 519 + libs/tk/ytk/gtktextview.c | 9354 ++++ libs/tk/ytk/gtkthemes.c | 196 + libs/tk/ytk/gtktoggleaction.c | 347 + libs/tk/ytk/gtktogglebutton.c | 536 + libs/tk/ytk/gtktoggletoolbutton.c | 451 + libs/tk/ytk/gtktoolbar.c | 5039 +++ libs/tk/ytk/gtktoolbutton.c | 1302 + libs/tk/ytk/gtktoolitem.c | 1491 + libs/tk/ytk/gtktoolitemgroup.c | 2431 ++ libs/tk/ytk/gtktoolpalette.c | 1931 + libs/tk/ytk/gtktoolshell.c | 252 + libs/tk/ytk/gtktooltip.c | 1640 + libs/tk/ytk/gtktooltips.c | 338 + libs/tk/ytk/gtktreedatalist.c | 557 + libs/tk/ytk/gtktreednd.c | 336 + libs/tk/ytk/gtktreemodel.c | 2194 + libs/tk/ytk/gtktreemodelfilter.c | 3506 ++ libs/tk/ytk/gtktreemodelsort.c | 2524 ++ libs/tk/ytk/gtktreeselection.c | 1471 + libs/tk/ytk/gtktreesortable.c | 262 + libs/tk/ytk/gtktreestore.c | 3335 ++ libs/tk/ytk/gtktreeview.c | 15775 +++++++ libs/tk/ytk/gtktreeviewcolumn.c | 3789 ++ libs/tk/ytk/gtktypebuiltins.c | 1831 + libs/tk/ytk/gtktypeutils.c | 218 + libs/tk/ytk/gtkuimanager.c | 3081 ++ libs/tk/ytk/gtkvbbox.c | 159 + libs/tk/ytk/gtkvbox.c | 83 + libs/tk/ytk/gtkviewport.c | 890 + libs/tk/ytk/gtkvpaned.c | 72 + libs/tk/ytk/gtkvruler.c | 86 + libs/tk/ytk/gtkvscale.c | 134 + libs/tk/ytk/gtkvscrollbar.c | 84 + libs/tk/ytk/gtkvseparator.c | 72 + libs/tk/ytk/gtkwidget.c | 11457 +++++ libs/tk/ytk/gtkwin32embed.c | 134 + libs/tk/ytk/gtkwin32embedwidget.c | 391 + libs/tk/ytk/gtkwindow-decorate.c | 836 + libs/tk/ytk/gtkwindow.c | 8616 ++++ libs/tk/ytk/gtkxembed.c | 244 + libs/tk/ytk/line-arrow.xbm | 4 + libs/tk/ytk/line-wrap.xbm | 4 + libs/tk/ytk/po/ca.po | 4984 +++ libs/tk/ytk/po/cs.po | 3415 ++ libs/tk/ytk/po/de.po | 5063 +++ libs/tk/ytk/po/el.po | 4124 ++ libs/tk/ytk/po/en_GB.po | 4856 +++ libs/tk/ytk/po/es.po | 4750 +++ libs/tk/ytk/po/eu.po | 4059 ++ libs/tk/ytk/po/fr.po | 3448 ++ libs/tk/ytk/po/ja.po | 4078 ++ libs/tk/ytk/po/ko.po | 4071 ++ libs/tk/ytk/po/nn.po | 5249 +++ libs/tk/ytk/po/pl.po | 3386 ++ libs/tk/ytk/po/pt.po | 4926 +++ libs/tk/ytk/po/pt_BR.po | 4500 ++ libs/tk/ytk/po/ru.po | 4162 ++ libs/tk/ytk/po/sv.po | 4977 +++ libs/tk/ytk/po/zh.po | 4035 ++ libs/tk/ytk/tree_minus.xpm | 18 + libs/tk/ytk/tree_plus.xpm | 18 + libs/tk/ytk/wscript | 329 + libs/tk/ytk/ximian-icons.h | 825 + libs/tk/ytk/ytk/gtk/gtk.h | 219 + libs/tk/ytk/ytk/gtk/gtkaboutdialog.h | 157 + libs/tk/ytk/ytk/gtk/gtkaccelgroup.h | 216 + libs/tk/ytk/ytk/gtk/gtkaccellabel.h | 114 + libs/tk/ytk/ytk/gtk/gtkaccelmap.h | 101 + libs/tk/ytk/ytk/gtk/gtkaccessible.h | 80 + libs/tk/ytk/ytk/gtk/gtkaction.h | 180 + libs/tk/ytk/ytk/gtk/gtkactiongroup.h | 184 + libs/tk/ytk/ytk/gtk/gtkactivatable.h | 88 + libs/tk/ytk/ytk/gtk/gtkadjustment.h | 121 + libs/tk/ytk/ytk/gtk/gtkalias.h | 13134 ++++++ libs/tk/ytk/ytk/gtk/gtkalignment.h | 94 + libs/tk/ytk/ytk/gtk/gtkarrow.h | 77 + libs/tk/ytk/ytk/gtk/gtkaspectframe.h | 84 + libs/tk/ytk/ytk/gtk/gtkassistant.h | 176 + libs/tk/ytk/ytk/gtk/gtkbbox.h | 105 + libs/tk/ytk/ytk/gtk/gtkbin.h | 70 + libs/tk/ytk/ytk/gtk/gtkbindings.h | 158 + libs/tk/ytk/ytk/gtk/gtkbox.h | 159 + libs/tk/ytk/ytk/gtk/gtkbuildable.h | 176 + libs/tk/ytk/ytk/gtk/gtkbuilder.h | 143 + libs/tk/ytk/ytk/gtk/gtkbuilderprivate.h | 146 + libs/tk/ytk/ytk/gtk/gtkbuiltincache.h | 35408 ++++++++++++++++ libs/tk/ytk/ytk/gtk/gtkbutton.h | 147 + libs/tk/ytk/ytk/gtk/gtkcelleditable.h | 64 + libs/tk/ytk/ytk/gtk/gtkcelllayout.h | 122 + libs/tk/ytk/ytk/gtk/gtkcellrenderer.h | 195 + libs/tk/ytk/ytk/gtk/gtkcellrendereraccel.h | 92 + libs/tk/ytk/ytk/gtk/gtkcellrenderercombo.h | 64 + libs/tk/ytk/ytk/gtk/gtkcellrendererpixbuf.h | 71 + libs/tk/ytk/ytk/gtk/gtkcellrendererprogress.h | 74 + libs/tk/ytk/ytk/gtk/gtkcellrendererspin.h | 57 + libs/tk/ytk/ytk/gtk/gtkcellrendererspinner.h | 67 + libs/tk/ytk/ytk/gtk/gtkcellrenderertext.h | 105 + libs/tk/ytk/ytk/gtk/gtkcellrenderertoggle.h | 85 + libs/tk/ytk/ytk/gtk/gtkcellview.h | 81 + libs/tk/ytk/ytk/gtk/gtkcheckbutton.h | 82 + libs/tk/ytk/ytk/gtk/gtkcheckmenuitem.h | 102 + libs/tk/ytk/ytk/gtk/gtkclipboard.h | 157 + libs/tk/ytk/ytk/gtk/gtkcolorbutton.h | 103 + libs/tk/ytk/ytk/gtk/gtkcolorsel.h | 135 + libs/tk/ytk/ytk/gtk/gtkcolorseldialog.h | 82 + libs/tk/ytk/ytk/gtk/gtkcombobox.h | 153 + libs/tk/ytk/ytk/gtk/gtkcomboboxentry.h | 81 + libs/tk/ytk/ytk/gtk/gtkcomboboxtext.h | 77 + libs/tk/ytk/ytk/gtk/gtkcontainer.h | 230 + libs/tk/ytk/ytk/gtk/gtkdebug.h | 79 + libs/tk/ytk/ytk/gtk/gtkdialog.h | 186 + libs/tk/ytk/ytk/gtk/gtkdnd.h | 188 + libs/tk/ytk/ytk/gtk/gtkdndcursors.h | 347 + libs/tk/ytk/ytk/gtk/gtkdrawingarea.h | 82 + libs/tk/ytk/ytk/gtk/gtkeditable.h | 117 + libs/tk/ytk/ytk/gtk/gtkentry.h | 334 + libs/tk/ytk/ytk/gtk/gtkentrybuffer.h | 133 + libs/tk/ytk/ytk/gtk/gtkentrycompletion.h | 132 + libs/tk/ytk/ytk/gtk/gtkentryprivate.h | 88 + libs/tk/ytk/ytk/gtk/gtkenums.h | 584 + libs/tk/ytk/ytk/gtk/gtkeventbox.h | 71 + libs/tk/ytk/ytk/gtk/gtkexpander.h | 98 + libs/tk/ytk/ytk/gtk/gtkfilechooser.h | 264 + libs/tk/ytk/ytk/gtk/gtkfilechooserbutton.h | 92 + libs/tk/ytk/ytk/gtk/gtkfilechooserdefault.h | 40 + libs/tk/ytk/ytk/gtk/gtkfilechooserdialog.h | 74 + libs/tk/ytk/ytk/gtk/gtkfilechooserembed.h | 71 + libs/tk/ytk/ytk/gtk/gtkfilechooserentry.h | 53 + libs/tk/ytk/ytk/gtk/gtkfilechooserprivate.h | 310 + libs/tk/ytk/ytk/gtk/gtkfilechoosersettings.h | 118 + libs/tk/ytk/ytk/gtk/gtkfilechooserutils.h | 60 + libs/tk/ytk/ytk/gtk/gtkfilechooserwidget.h | 67 + libs/tk/ytk/ytk/gtk/gtkfilefilter.h | 83 + libs/tk/ytk/ytk/gtk/gtkfilesystem.h | 171 + libs/tk/ytk/ytk/gtk/gtkfilesystemmodel.h | 98 + libs/tk/ytk/ytk/gtk/gtkfixed.h | 90 + libs/tk/ytk/ytk/gtk/gtkfontbutton.h | 100 + libs/tk/ytk/ytk/gtk/gtkfontsel.h | 220 + libs/tk/ytk/ytk/gtk/gtkframe.h | 96 + libs/tk/ytk/ytk/gtk/gtkgc.h | 49 + libs/tk/ytk/ytk/gtk/gtkhandlebox.h | 112 + libs/tk/ytk/ytk/gtk/gtkhbbox.h | 80 + libs/tk/ytk/ytk/gtk/gtkhbox.h | 68 + libs/tk/ytk/ytk/gtk/gtkhpaned.h | 65 + libs/tk/ytk/ytk/gtk/gtkhruler.h | 84 + libs/tk/ytk/ytk/gtk/gtkhscale.h | 71 + libs/tk/ytk/ytk/gtk/gtkhscrollbar.h | 70 + libs/tk/ytk/ytk/gtk/gtkhseparator.h | 68 + libs/tk/ytk/ytk/gtk/gtkhsv.h | 115 + libs/tk/ytk/ytk/gtk/gtkiconcache.h | 66 + libs/tk/ytk/ytk/gtk/gtkiconcachevalidator.h | 44 + libs/tk/ytk/ytk/gtk/gtkiconfactory.h | 189 + libs/tk/ytk/ytk/gtk/gtkicontheme.h | 198 + libs/tk/ytk/ytk/gtk/gtkiconview.h | 242 + libs/tk/ytk/ytk/gtk/gtkimage.h | 274 + libs/tk/ytk/ytk/gtk/gtkimagemenuitem.h | 86 + libs/tk/ytk/ytk/gtk/gtkimcontext.h | 132 + libs/tk/ytk/ytk/gtk/gtkimcontextsimple.h | 77 + libs/tk/ytk/ytk/gtk/gtkimcontextsimpleseqs.h | 4484 ++ libs/tk/ytk/ytk/gtk/gtkimmodule.h | 58 + libs/tk/ytk/ytk/gtk/gtkimmulticontext.h | 78 + libs/tk/ytk/ytk/gtk/gtkinfobar.h | 120 + libs/tk/ytk/ytk/gtk/gtkintl.h | 15 + libs/tk/ytk/ytk/gtk/gtkinvisible.h | 78 + libs/tk/ytk/ytk/gtk/gtkitem.h | 81 + libs/tk/ytk/ytk/gtk/gtkkeyhash.h | 51 + libs/tk/ytk/ytk/gtk/gtklabel.h | 207 + libs/tk/ytk/ytk/gtk/gtklayout.h | 138 + libs/tk/ytk/ytk/gtk/gtklinkbutton.h | 91 + libs/tk/ytk/ytk/gtk/gtkliststore.h | 147 + libs/tk/ytk/ytk/gtk/gtkmain.h | 233 + libs/tk/ytk/ytk/gtk/gtkmarshal.h | 339 + libs/tk/ytk/ytk/gtk/gtkmarshalers.h | 753 + libs/tk/ytk/ytk/gtk/gtkmenu.h | 219 + libs/tk/ytk/ytk/gtk/gtkmenubar.h | 92 + libs/tk/ytk/ytk/gtk/gtkmenuitem.h | 145 + libs/tk/ytk/ytk/gtk/gtkmenushell.h | 140 + libs/tk/ytk/ytk/gtk/gtkmenutoolbutton.h | 89 + libs/tk/ytk/ytk/gtk/gtkmessagedialog.h | 135 + libs/tk/ytk/ytk/gtk/gtkmisc.h | 85 + libs/tk/ytk/ytk/gtk/gtkmnemonichash.h | 54 + libs/tk/ytk/ytk/gtk/gtkmodules.h | 54 + libs/tk/ytk/ytk/gtk/gtkmountoperation.h | 83 + .../tk/ytk/ytk/gtk/gtkmountoperationprivate.h | 53 + libs/tk/ytk/ytk/gtk/gtknotebook.h | 317 + libs/tk/ytk/ytk/gtk/gtkobject.h | 250 + libs/tk/ytk/ytk/gtk/gtkoffscreenwindow.h | 60 + libs/tk/ytk/ytk/gtk/gtkoptionmenu.h | 88 + libs/tk/ytk/ytk/gtk/gtkorientable.h | 60 + libs/tk/ytk/ytk/gtk/gtkpagesetupunixdialog.h | 76 + libs/tk/ytk/ytk/gtk/gtkpaned.h | 144 + libs/tk/ytk/ytk/gtk/gtkpango.h | 47 + libs/tk/ytk/ytk/gtk/gtkpathbar.h | 96 + libs/tk/ytk/ytk/gtk/gtkplug.h | 105 + libs/tk/ytk/ytk/gtk/gtkplugprivate.h | 141 + libs/tk/ytk/ytk/gtk/gtkprivate.h | 157 + libs/tk/ytk/ytk/gtk/gtkprogress.h | 120 + libs/tk/ytk/ytk/gtk/gtkprogressbar.h | 172 + libs/tk/ytk/ytk/gtk/gtkquartz.h | 46 + libs/tk/ytk/ytk/gtk/gtkquery.h | 74 + libs/tk/ytk/ytk/gtk/gtkradioaction.h | 90 + libs/tk/ytk/ytk/gtk/gtkradiobutton.h | 94 + libs/tk/ytk/ytk/gtk/gtkradiomenuitem.h | 94 + libs/tk/ytk/ytk/gtk/gtkradiotoolbutton.h | 74 + libs/tk/ytk/ytk/gtk/gtkrange.h | 215 + libs/tk/ytk/ytk/gtk/gtkrbtree.h | 184 + libs/tk/ytk/ytk/gtk/gtkrc.h | 271 + libs/tk/ytk/ytk/gtk/gtkrecentaction.h | 74 + libs/tk/ytk/ytk/gtk/gtkrecentchooser.h | 191 + libs/tk/ytk/ytk/gtk/gtkrecentchooserdefault.h | 42 + libs/tk/ytk/ytk/gtk/gtkrecentchooserdialog.h | 74 + libs/tk/ytk/ytk/gtk/gtkrecentchoosermenu.h | 74 + libs/tk/ytk/ytk/gtk/gtkrecentchooserprivate.h | 55 + libs/tk/ytk/ytk/gtk/gtkrecentchooserutils.h | 62 + libs/tk/ytk/ytk/gtk/gtkrecentchooserwidget.h | 64 + libs/tk/ytk/ytk/gtk/gtkrecentfilter.h | 94 + libs/tk/ytk/ytk/gtk/gtkrecentmanager.h | 216 + libs/tk/ytk/ytk/gtk/gtkruler.h | 136 + libs/tk/ytk/ytk/gtk/gtkscale.h | 111 + libs/tk/ytk/ytk/gtk/gtkscalebutton.h | 112 + libs/tk/ytk/ytk/gtk/gtkscrollbar.h | 72 + libs/tk/ytk/ytk/gtk/gtkscrolledwindow.h | 136 + libs/tk/ytk/ytk/gtk/gtksearchengine.h | 90 + libs/tk/ytk/ytk/gtk/gtksearchenginequartz.h | 54 + libs/tk/ytk/ytk/gtk/gtksearchenginesimple.h | 59 + libs/tk/ytk/ytk/gtk/gtkselection.h | 221 + libs/tk/ytk/ytk/gtk/gtkseparator.h | 66 + libs/tk/ytk/ytk/gtk/gtkseparatormenuitem.h | 68 + libs/tk/ytk/ytk/gtk/gtkseparatortoolitem.h | 72 + libs/tk/ytk/ytk/gtk/gtksettings.h | 139 + libs/tk/ytk/ytk/gtk/gtkshow.h | 39 + libs/tk/ytk/ytk/gtk/gtksizegroup.h | 111 + libs/tk/ytk/ytk/gtk/gtksocket.h | 102 + libs/tk/ytk/ytk/gtk/gtksocketprivate.h | 171 + libs/tk/ytk/ytk/gtk/gtkspinbutton.h | 196 + libs/tk/ytk/ytk/gtk/gtkspinner.h | 65 + libs/tk/ytk/ytk/gtk/gtkstatusbar.h | 117 + libs/tk/ytk/ytk/gtk/gtkstock.h | 1016 + libs/tk/ytk/ytk/gtk/gtkstyle.h | 945 + libs/tk/ytk/ytk/gtk/gtktable.h | 151 + libs/tk/ytk/ytk/gtk/gtktearoffmenuitem.h | 75 + libs/tk/ytk/ytk/gtk/gtktestutils.h | 71 + libs/tk/ytk/ytk/gtk/gtktextbtree.h | 348 + libs/tk/ytk/ytk/gtk/gtktextbuffer.h | 409 + libs/tk/ytk/ytk/gtk/gtktextbufferrichtext.h | 96 + libs/tk/ytk/ytk/gtk/gtktextbufferserialize.h | 43 + libs/tk/ytk/ytk/gtk/gtktextchild.h | 82 + libs/tk/ytk/ytk/gtk/gtktextchildprivate.h | 88 + libs/tk/ytk/ytk/gtk/gtktextdisplay.h | 112 + libs/tk/ytk/ytk/gtk/gtktextiter.h | 307 + libs/tk/ytk/ytk/gtk/gtktextiterprivate.h | 54 + libs/tk/ytk/ytk/gtk/gtktextlayout.h | 439 + libs/tk/ytk/ytk/gtk/gtktextmark.h | 106 + libs/tk/ytk/ytk/gtk/gtktextmarkprivate.h | 60 + libs/tk/ytk/ytk/gtk/gtktextsegment.h | 173 + libs/tk/ytk/ytk/gtk/gtktexttag.h | 289 + libs/tk/ytk/ytk/gtk/gtktexttagprivate.h | 57 + libs/tk/ytk/ytk/gtk/gtktexttagtable.h | 101 + libs/tk/ytk/ytk/gtk/gtktexttypes.h | 80 + libs/tk/ytk/ytk/gtk/gtktextutil.h | 58 + libs/tk/ytk/ytk/gtk/gtktextview.h | 376 + libs/tk/ytk/ytk/gtk/gtkthemes.h | 48 + libs/tk/ytk/ytk/gtk/gtktoggleaction.h | 91 + libs/tk/ytk/ytk/gtk/gtktoggleactionprivate.h | 43 + libs/tk/ytk/ytk/gtk/gtktogglebutton.h | 97 + libs/tk/ytk/ytk/gtk/gtktoggletoolbutton.h | 77 + libs/tk/ytk/ytk/gtk/gtktoolbar.h | 280 + libs/tk/ytk/ytk/gtk/gtktoolbutton.h | 99 + libs/tk/ytk/ytk/gtk/gtktoolitem.h | 142 + libs/tk/ytk/ytk/gtk/gtktoolitemgroup.h | 99 + libs/tk/ytk/ytk/gtk/gtktoolpalette.h | 144 + libs/tk/ytk/ytk/gtk/gtktoolpaletteprivate.h | 55 + libs/tk/ytk/ytk/gtk/gtktoolshell.h | 91 + libs/tk/ytk/ytk/gtk/gtktooltip.h | 77 + libs/tk/ytk/ytk/gtk/gtktooltips.h | 109 + libs/tk/ytk/ytk/gtk/gtktrayicon.h | 75 + libs/tk/ytk/ytk/gtk/gtktreedatalist.h | 82 + libs/tk/ytk/ytk/gtk/gtktreednd.h | 125 + libs/tk/ytk/ytk/gtk/gtktreemodel.h | 270 + libs/tk/ytk/ytk/gtk/gtktreemodelfilter.h | 109 + libs/tk/ytk/ytk/gtk/gtktreemodelsort.h | 106 + libs/tk/ytk/ytk/gtk/gtktreeprivate.h | 472 + libs/tk/ytk/ytk/gtk/gtktreeselection.h | 125 + libs/tk/ytk/ytk/gtk/gtktreesortable.h | 103 + libs/tk/ytk/ytk/gtk/gtktreestore.h | 159 + libs/tk/ytk/ytk/gtk/gtktreeview.h | 431 + libs/tk/ytk/ytk/gtk/gtktreeviewcolumn.h | 245 + libs/tk/ytk/ytk/gtk/gtktypebuiltins.h | 299 + libs/tk/ytk/ytk/gtk/gtktypeutils.h | 264 + libs/tk/ytk/ytk/gtk/gtkuimanager.h | 153 + libs/tk/ytk/ytk/gtk/gtkvbbox.h | 82 + libs/tk/ytk/ytk/gtk/gtkvbox.h | 68 + libs/tk/ytk/ytk/gtk/gtkversion.h | 51 + libs/tk/ytk/ytk/gtk/gtkviewport.h | 93 + libs/tk/ytk/ytk/gtk/gtkvpaned.h | 65 + libs/tk/ytk/ytk/gtk/gtkvruler.h | 84 + libs/tk/ytk/ytk/gtk/gtkvscale.h | 79 + libs/tk/ytk/ytk/gtk/gtkvscrollbar.h | 76 + libs/tk/ytk/ytk/gtk/gtkvseparator.h | 76 + libs/tk/ytk/ytk/gtk/gtkwidget.h | 1351 + libs/tk/ytk/ytk/gtk/gtkwin32embed.h | 95 + libs/tk/ytk/ytk/gtk/gtkwin32embedwidget.h | 76 + libs/tk/ytk/ytk/gtk/gtkwindow-decorate.h | 41 + libs/tk/ytk/ytk/gtk/gtkwindow.h | 452 + libs/tk/ytk/ytk/gtk/gtkxembed.h | 49 + libs/tk/ytk/ytk/gtk/stamp-gtkmarshal.h | 1 + libs/tk/ytk/ytk/gtk/stamp-gtkmarshalers.h | 1 + libs/tk/ytk/ytk/gtk/stamp-gtktypebuiltins.h | 1 + libs/tk/ytk/ytk/gtk/xembed.h | 31 + libs/tk/ytkmm/aboutdialog.cc | 514 + libs/tk/ytkmm/accelgroup.cc | 392 + libs/tk/ytkmm/accelkey.cc | 96 + libs/tk/ytkmm/accellabel.cc | 200 + libs/tk/ytkmm/accelmap.cc | 91 + libs/tk/ytkmm/action.cc | 868 + libs/tk/ytkmm/actiongroup.cc | 469 + libs/tk/ytkmm/activatable.cc | 303 + libs/tk/ytkmm/adjustment.cc | 412 + libs/tk/ytkmm/alignment.cc | 257 + libs/tk/ytkmm/arrow.cc | 188 + libs/tk/ytkmm/aspectframe.cc | 200 + libs/tk/ytkmm/assistant.cc | 575 + libs/tk/ytkmm/bin.cc | 257 + libs/tk/ytkmm/box.cc | 603 + libs/tk/ytkmm/builder.cc | 442 + libs/tk/ytkmm/button.cc | 751 + libs/tk/ytkmm/buttonbox.cc | 423 + libs/tk/ytkmm/celleditable.cc | 342 + libs/tk/ytkmm/celllayout.cc | 555 + libs/tk/ytkmm/cellrenderer.cc | 735 + libs/tk/ytkmm/cellrenderer_generation.cc | 63 + libs/tk/ytkmm/cellrendereraccel.cc | 371 + libs/tk/ytkmm/cellrenderercombo.cc | 230 + libs/tk/ytkmm/cellrendererpixbuf.cc | 239 + libs/tk/ytkmm/cellrendererprogress.cc | 212 + libs/tk/ytkmm/cellrendererspin.cc | 175 + libs/tk/ytkmm/cellrendererspinner.cc | 168 + libs/tk/ytkmm/cellrenderertext.cc | 666 + libs/tk/ytkmm/cellrenderertoggle.cc | 319 + libs/tk/ytkmm/cellview.cc | 280 + libs/tk/ytkmm/checkbutton.cc | 206 + libs/tk/ytkmm/checkmenuitem.cc | 340 + libs/tk/ytkmm/clipboard.cc | 582 + libs/tk/ytkmm/colorbutton.cc | 306 + libs/tk/ytkmm/colorselection.cc | 592 + libs/tk/ytkmm/combobox.cc | 573 + libs/tk/ytkmm/comboboxentry.cc | 218 + libs/tk/ytkmm/comboboxentrytext.cc | 187 + libs/tk/ytkmm/comboboxtext.cc | 206 + libs/tk/ytkmm/container.cc | 1009 + libs/tk/ytkmm/dialog.cc | 365 + libs/tk/ytkmm/drawingarea.cc | 140 + libs/tk/ytkmm/editable.cc | 834 + libs/tk/ytkmm/entry.cc | 1223 + libs/tk/ytkmm/entrybuffer.cc | 410 + libs/tk/ytkmm/entrycompletion.cc | 810 + libs/tk/ytkmm/enums.cc | 307 + libs/tk/ytkmm/eventbox.cc | 180 + libs/tk/ytkmm/expander.cc | 298 + libs/tk/ytkmm/filechooser.cc | 751 + libs/tk/ytkmm/filechooserbutton.cc | 252 + libs/tk/ytkmm/filechooserdialog.cc | 170 + libs/tk/ytkmm/filechooserwidget.cc | 167 + libs/tk/ytkmm/filefilter.cc | 220 + libs/tk/ytkmm/fixed.cc | 175 + libs/tk/ytkmm/fontbutton.cc | 343 + libs/tk/ytkmm/fontselection.cc | 480 + libs/tk/ytkmm/frame.cc | 314 + libs/tk/ytkmm/handlebox.cc | 461 + libs/tk/ytkmm/iconfactory.cc | 212 + libs/tk/ytkmm/iconinfo.cc | 190 + libs/tk/ytkmm/iconset.cc | 150 + libs/tk/ytkmm/iconsource.cc | 205 + libs/tk/ytkmm/icontheme.cc | 365 + libs/tk/ytkmm/iconview.cc | 1021 + libs/tk/ytkmm/image.cc | 523 + libs/tk/ytkmm/imagemenuitem.cc | 267 + libs/tk/ytkmm/infobar.cc | 305 + libs/tk/ytkmm/invisible.cc | 174 + libs/tk/ytkmm/item.cc | 343 + libs/tk/ytkmm/label.cc | 718 + libs/tk/ytkmm/layout.cc | 380 + libs/tk/ytkmm/linkbutton.cc | 247 + libs/tk/ytkmm/liststore.cc | 280 + libs/tk/ytkmm/listviewtext.cc | 200 + libs/tk/ytkmm/main.cc | 572 + libs/tk/ytkmm/menu.cc | 415 + libs/tk/ytkmm/menu_elems.cc | 285 + libs/tk/ytkmm/menubar.cc | 204 + libs/tk/ytkmm/menuitem.cc | 663 + libs/tk/ytkmm/menushell.cc | 596 + libs/tk/ytkmm/menutoolbutton.cc | 282 + libs/tk/ytkmm/messagedialog.cc | 286 + libs/tk/ytkmm/misc.cc | 211 + libs/tk/ytkmm/notebook.cc | 1229 + libs/tk/ytkmm/object.cc | 415 + libs/tk/ytkmm/offscreenwindow.cc | 168 + libs/tk/ytkmm/optionmenu.cc | 272 + libs/tk/ytkmm/orientable.cc | 153 + libs/tk/ytkmm/paned.cc | 455 + libs/tk/ytkmm/plug.cc | 262 + libs/tk/ytkmm/progressbar.cc | 303 + libs/tk/ytkmm/radioaction.cc | 325 + libs/tk/ytkmm/radiobutton.cc | 253 + libs/tk/ytkmm/radiobuttongroup.cc | 83 + libs/tk/ytkmm/radiomenuitem.cc | 243 + libs/tk/ytkmm/radiotoolbutton.cc | 194 + libs/tk/ytkmm/range.cc | 739 + libs/tk/ytkmm/rc.cc | 371 + libs/tk/ytkmm/recentaction.cc | 214 + libs/tk/ytkmm/recentchooser.cc | 898 + libs/tk/ytkmm/recentchooserdialog.cc | 165 + libs/tk/ytkmm/recentchoosermenu.cc | 171 + libs/tk/ytkmm/recentchooserwidget.cc | 150 + libs/tk/ytkmm/recentfilter.cc | 252 + libs/tk/ytkmm/recentinfo.cc | 268 + libs/tk/ytkmm/recentmanager.cc | 399 + libs/tk/ytkmm/ruler.cc | 558 + libs/tk/ytkmm/scale.cc | 682 + libs/tk/ytkmm/scalebutton.cc | 365 + libs/tk/ytkmm/scrollbar.cc | 359 + libs/tk/ytkmm/scrolledwindow.cc | 356 + libs/tk/ytkmm/selectiondata.cc | 257 + libs/tk/ytkmm/selectiondata_private.cc | 41 + libs/tk/ytkmm/separator.cc | 339 + libs/tk/ytkmm/separatormenuitem.cc | 139 + libs/tk/ytkmm/separatortoolitem.cc | 166 + libs/tk/ytkmm/settings.cc | 717 + libs/tk/ytkmm/sizegroup.cc | 222 + libs/tk/ytkmm/socket.cc | 340 + libs/tk/ytkmm/spinbutton.cc | 693 + libs/tk/ytkmm/spinner.cc | 158 + libs/tk/ytkmm/statusbar.cc | 373 + libs/tk/ytkmm/stock.cc | 172 + libs/tk/ytkmm/stockid.cc | 85 + libs/tk/ytkmm/stockitem.cc | 171 + libs/tk/ytkmm/style.cc | 2443 ++ libs/tk/ytkmm/table.cc | 441 + libs/tk/ytkmm/targetentry.cc | 115 + libs/tk/ytkmm/targetlist.cc | 133 + libs/tk/ytkmm/tearoffmenuitem.cc | 153 + libs/tk/ytkmm/textattributes.cc | 107 + libs/tk/ytkmm/textbuffer.cc | 1970 + libs/tk/ytkmm/textchildanchor.cc | 166 + libs/tk/ytkmm/textiter.cc | 634 + libs/tk/ytkmm/textmark.cc | 229 + libs/tk/ytkmm/texttag.cc | 939 + libs/tk/ytkmm/texttagtable.cc | 461 + libs/tk/ytkmm/textview.cc | 974 + libs/tk/ytkmm/toggleaction.cc | 302 + libs/tk/ytkmm/togglebutton.cc | 291 + libs/tk/ytkmm/toggletoolbutton.cc | 256 + libs/tk/ytkmm/toolbar.cc | 677 + libs/tk/ytkmm/toolbutton.cc | 369 + libs/tk/ytkmm/toolitem.cc | 529 + libs/tk/ytkmm/toolitemgroup.cc | 297 + libs/tk/ytkmm/toolpalette.cc | 315 + libs/tk/ytkmm/toolshell.cc | 477 + libs/tk/ytkmm/tooltip.cc | 183 + libs/tk/ytkmm/tooltips.cc | 185 + libs/tk/ytkmm/treedragdest.cc | 269 + libs/tk/ytkmm/treedragsource.cc | 334 + libs/tk/ytkmm/treeiter.cc | 398 + libs/tk/ytkmm/treemodel.cc | 1697 + libs/tk/ytkmm/treemodelcolumn.cc | 68 + libs/tk/ytkmm/treemodelfilter.cc | 349 + libs/tk/ytkmm/treemodelsort.cc | 244 + libs/tk/ytkmm/treepath.cc | 345 + libs/tk/ytkmm/treerowreference.cc | 145 + libs/tk/ytkmm/treeselection.cc | 443 + libs/tk/ytkmm/treesortable.cc | 630 + libs/tk/ytkmm/treestore.cc | 299 + libs/tk/ytkmm/treeview.cc | 2025 + libs/tk/ytkmm/treeview_private.cc | 87 + libs/tk/ytkmm/treeviewcolumn.cc | 758 + libs/tk/ytkmm/uimanager.cc | 603 + libs/tk/ytkmm/viewport.cc | 339 + libs/tk/ytkmm/widget.cc | 7969 ++++ libs/tk/ytkmm/window.cc | 1476 + libs/tk/ytkmm/wrap_init.cc | 868 + libs/tk/ytkmm/wscript | 213 + libs/tk/ytkmm/ytkmm/gtkmm.h | 238 + libs/tk/ytkmm/ytkmm/gtkmm/aboutdialog.h | 709 + libs/tk/ytkmm/ytkmm/gtkmm/accelgroup.h | 323 + libs/tk/ytkmm/ytkmm/gtkmm/accelkey.h | 94 + libs/tk/ytkmm/ytkmm/gtkmm/accellabel.h | 192 + libs/tk/ytkmm/ytkmm/gtkmm/accelmap.h | 147 + libs/tk/ytkmm/ytkmm/gtkmm/action.h | 947 + libs/tk/ytkmm/ytkmm/gtkmm/actiongroup.h | 373 + libs/tk/ytkmm/ytkmm/gtkmm/activatable.h | 280 + libs/tk/ytkmm/ytkmm/gtkmm/adjustment.h | 426 + libs/tk/ytkmm/ytkmm/gtkmm/alignment.h | 316 + libs/tk/ytkmm/ytkmm/gtkmm/arrow.h | 186 + libs/tk/ytkmm/ytkmm/gtkmm/aspectframe.h | 242 + libs/tk/ytkmm/ytkmm/gtkmm/assistant.h | 466 + libs/tk/ytkmm/ytkmm/gtkmm/base.h | 53 + libs/tk/ytkmm/ytkmm/gtkmm/bin.h | 234 + libs/tk/ytkmm/ytkmm/gtkmm/border.h | 62 + libs/tk/ytkmm/ytkmm/gtkmm/box.h | 700 + libs/tk/ytkmm/ytkmm/gtkmm/builder.h | 593 + libs/tk/ytkmm/ytkmm/gtkmm/button.h | 543 + libs/tk/ytkmm/ytkmm/gtkmm/buttonbox.h | 400 + libs/tk/ytkmm/ytkmm/gtkmm/celleditable.h | 217 + libs/tk/ytkmm/ytkmm/gtkmm/celllayout.h | 294 + libs/tk/ytkmm/ytkmm/gtkmm/cellrenderer.h | 716 + .../ytkmm/gtkmm/cellrenderer_generation.h | 67 + libs/tk/ytkmm/ytkmm/gtkmm/cellrendereraccel.h | 255 + libs/tk/ytkmm/ytkmm/gtkmm/cellrenderercombo.h | 193 + .../tk/ytkmm/ytkmm/gtkmm/cellrendererpixbuf.h | 266 + .../ytkmm/ytkmm/gtkmm/cellrendererprogress.h | 214 + libs/tk/ytkmm/ytkmm/gtkmm/cellrendererspin.h | 185 + .../ytkmm/ytkmm/gtkmm/cellrendererspinner.h | 176 + libs/tk/ytkmm/ytkmm/gtkmm/cellrenderertext.h | 746 + .../tk/ytkmm/ytkmm/gtkmm/cellrenderertoggle.h | 270 + libs/tk/ytkmm/ytkmm/gtkmm/cellview.h | 323 + libs/tk/ytkmm/ytkmm/gtkmm/checkbutton.h | 163 + libs/tk/ytkmm/ytkmm/gtkmm/checkmenuitem.h | 250 + libs/tk/ytkmm/ytkmm/gtkmm/clipboard.h | 608 + libs/tk/ytkmm/ytkmm/gtkmm/colorbutton.h | 298 + libs/tk/ytkmm/ytkmm/gtkmm/colorselection.h | 460 + libs/tk/ytkmm/ytkmm/gtkmm/combobox.h | 705 + libs/tk/ytkmm/ytkmm/gtkmm/comboboxentry.h | 243 + libs/tk/ytkmm/ytkmm/gtkmm/comboboxentrytext.h | 139 + libs/tk/ytkmm/ytkmm/gtkmm/comboboxtext.h | 163 + libs/tk/ytkmm/ytkmm/gtkmm/container.h | 495 + libs/tk/ytkmm/ytkmm/gtkmm/dialog.h | 457 + libs/tk/ytkmm/ytkmm/gtkmm/drawingarea.h | 129 + libs/tk/ytkmm/ytkmm/gtkmm/editable.h | 337 + libs/tk/ytkmm/ytkmm/gtkmm/entry.h | 1605 + libs/tk/ytkmm/ytkmm/gtkmm/entrybuffer.h | 340 + libs/tk/ytkmm/ytkmm/gtkmm/entrycompletion.h | 668 + libs/tk/ytkmm/ytkmm/gtkmm/enums.h | 1781 + libs/tk/ytkmm/ytkmm/gtkmm/eventbox.h | 241 + libs/tk/ytkmm/ytkmm/gtkmm/expander.h | 435 + libs/tk/ytkmm/ytkmm/gtkmm/filechooser.h | 1361 + libs/tk/ytkmm/ytkmm/gtkmm/filechooserbutton.h | 288 + libs/tk/ytkmm/ytkmm/gtkmm/filechooserdialog.h | 141 + libs/tk/ytkmm/ytkmm/gtkmm/filechooserwidget.h | 150 + libs/tk/ytkmm/ytkmm/gtkmm/filefilter.h | 295 + libs/tk/ytkmm/ytkmm/gtkmm/fixed.h | 175 + libs/tk/ytkmm/ytkmm/gtkmm/fontbutton.h | 338 + libs/tk/ytkmm/ytkmm/gtkmm/fontselection.h | 582 + libs/tk/ytkmm/ytkmm/gtkmm/frame.h | 303 + libs/tk/ytkmm/ytkmm/gtkmm/handlebox.h | 286 + libs/tk/ytkmm/ytkmm/gtkmm/iconfactory.h | 174 + libs/tk/ytkmm/ytkmm/gtkmm/iconinfo.h | 264 + libs/tk/ytkmm/ytkmm/gtkmm/iconset.h | 213 + libs/tk/ytkmm/ytkmm/gtkmm/iconsource.h | 315 + libs/tk/ytkmm/ytkmm/gtkmm/icontheme.h | 496 + libs/tk/ytkmm/ytkmm/gtkmm/iconview.h | 1236 + libs/tk/ytkmm/ytkmm/gtkmm/image.h | 633 + libs/tk/ytkmm/ytkmm/gtkmm/imagemenuitem.h | 268 + libs/tk/ytkmm/ytkmm/gtkmm/infobar.h | 305 + libs/tk/ytkmm/ytkmm/gtkmm/invisible.h | 154 + libs/tk/ytkmm/ytkmm/gtkmm/item.h | 172 + libs/tk/ytkmm/ytkmm/gtkmm/label.h | 855 + libs/tk/ytkmm/ytkmm/gtkmm/layout.h | 331 + libs/tk/ytkmm/ytkmm/gtkmm/linkbutton.h | 245 + libs/tk/ytkmm/ytkmm/gtkmm/liststore.h | 261 + libs/tk/ytkmm/ytkmm/gtkmm/listviewtext.h | 161 + libs/tk/ytkmm/ytkmm/gtkmm/main.h | 309 + libs/tk/ytkmm/ytkmm/gtkmm/menu.h | 505 + libs/tk/ytkmm/ytkmm/gtkmm/menu_elems.h | 266 + libs/tk/ytkmm/ytkmm/gtkmm/menubar.h | 241 + libs/tk/ytkmm/ytkmm/gtkmm/menuitem.h | 411 + libs/tk/ytkmm/ytkmm/gtkmm/menushell.h | 377 + libs/tk/ytkmm/ytkmm/gtkmm/menutoolbutton.h | 255 + libs/tk/ytkmm/ytkmm/gtkmm/messagedialog.h | 360 + libs/tk/ytkmm/ytkmm/gtkmm/misc.h | 216 + libs/tk/ytkmm/ytkmm/gtkmm/notebook.h | 1296 + libs/tk/ytkmm/ytkmm/gtkmm/object.h | 207 + libs/tk/ytkmm/ytkmm/gtkmm/offscreenwindow.h | 196 + libs/tk/ytkmm/ytkmm/gtkmm/optionmenu.h | 180 + libs/tk/ytkmm/ytkmm/gtkmm/orientable.h | 195 + libs/tk/ytkmm/ytkmm/gtkmm/paned.h | 465 + libs/tk/ytkmm/ytkmm/gtkmm/plug.h | 191 + .../ytkmm/ytkmm/gtkmm/private/aboutdialog_p.h | 48 + .../ytkmm/ytkmm/gtkmm/private/accelgroup_p.h | 49 + .../ytkmm/ytkmm/gtkmm/private/accellabel_p.h | 48 + libs/tk/ytkmm/ytkmm/gtkmm/private/action_p.h | 53 + .../ytkmm/ytkmm/gtkmm/private/actiongroup_p.h | 48 + .../ytkmm/ytkmm/gtkmm/private/activatable_p.h | 46 + .../ytkmm/ytkmm/gtkmm/private/adjustment_p.h | 50 + .../ytkmm/ytkmm/gtkmm/private/alignment_p.h | 48 + libs/tk/ytkmm/ytkmm/gtkmm/private/arrow_p.h | 48 + .../ytkmm/ytkmm/gtkmm/private/aspectframe_p.h | 48 + .../ytkmm/ytkmm/gtkmm/private/assistant_p.h | 52 + libs/tk/ytkmm/ytkmm/gtkmm/private/bin_p.h | 48 + libs/tk/ytkmm/ytkmm/gtkmm/private/box_p.h | 124 + libs/tk/ytkmm/ytkmm/gtkmm/private/builder_p.h | 48 + libs/tk/ytkmm/ytkmm/gtkmm/private/button_p.h | 54 + .../ytkmm/ytkmm/gtkmm/private/buttonbox_p.h | 124 + .../ytkmm/gtkmm/private/celleditable_p.h | 47 + .../ytkmm/ytkmm/gtkmm/private/celllayout_p.h | 50 + .../ytkmm/gtkmm/private/cellrenderer_p.h | 54 + .../ytkmm/gtkmm/private/cellrendereraccel_p.h | 50 + .../ytkmm/gtkmm/private/cellrenderercombo_p.h | 48 + .../gtkmm/private/cellrendererpixbuf_p.h | 48 + .../gtkmm/private/cellrendererprogress_p.h | 48 + .../ytkmm/gtkmm/private/cellrendererspin_p.h | 48 + .../gtkmm/private/cellrendererspinner_p.h | 48 + .../ytkmm/gtkmm/private/cellrenderertext_p.h | 49 + .../gtkmm/private/cellrenderertoggle_p.h | 49 + .../tk/ytkmm/ytkmm/gtkmm/private/cellview_p.h | 48 + .../ytkmm/ytkmm/gtkmm/private/checkbutton_p.h | 49 + .../ytkmm/gtkmm/private/checkmenuitem_p.h | 50 + .../ytkmm/ytkmm/gtkmm/private/clipboard_p.h | 48 + .../ytkmm/ytkmm/gtkmm/private/colorbutton_p.h | 49 + .../ytkmm/gtkmm/private/colorselection_p.h | 88 + libs/tk/ytkmm/ytkmm/gtkmm/private/combo_p.h | 133 + .../tk/ytkmm/ytkmm/gtkmm/private/combobox_p.h | 49 + .../ytkmm/gtkmm/private/comboboxentry_p.h | 51 + .../ytkmm/ytkmm/gtkmm/private/container_p.h | 59 + libs/tk/ytkmm/ytkmm/gtkmm/private/dialog_p.h | 49 + .../ytkmm/ytkmm/gtkmm/private/drawingarea_p.h | 48 + .../tk/ytkmm/ytkmm/gtkmm/private/editable_p.h | 54 + libs/tk/ytkmm/ytkmm/gtkmm/private/entry_p.h | 51 + .../ytkmm/ytkmm/gtkmm/private/entrybuffer_p.h | 50 + .../ytkmm/gtkmm/private/entrycompletion_p.h | 50 + libs/tk/ytkmm/ytkmm/gtkmm/private/enums_p.h | 8 + .../tk/ytkmm/ytkmm/gtkmm/private/eventbox_p.h | 48 + .../tk/ytkmm/ytkmm/gtkmm/private/expander_p.h | 48 + .../ytkmm/ytkmm/gtkmm/private/filechooser_p.h | 44 + .../ytkmm/gtkmm/private/filechooserbutton_p.h | 48 + .../ytkmm/gtkmm/private/filechooserdialog_p.h | 48 + .../ytkmm/gtkmm/private/filechooserwidget_p.h | 48 + .../ytkmm/ytkmm/gtkmm/private/filefilter_p.h | 48 + libs/tk/ytkmm/ytkmm/gtkmm/private/fixed_p.h | 48 + .../ytkmm/ytkmm/gtkmm/private/fontbutton_p.h | 49 + .../ytkmm/gtkmm/private/fontselection_p.h | 87 + libs/tk/ytkmm/ytkmm/gtkmm/private/frame_p.h | 49 + .../ytkmm/ytkmm/gtkmm/private/handlebox_p.h | 50 + .../ytkmm/ytkmm/gtkmm/private/iconfactory_p.h | 48 + .../tk/ytkmm/ytkmm/gtkmm/private/iconinfo_p.h | 8 + libs/tk/ytkmm/ytkmm/gtkmm/private/iconset_p.h | 8 + .../ytkmm/ytkmm/gtkmm/private/iconsource_p.h | 8 + .../ytkmm/ytkmm/gtkmm/private/icontheme_p.h | 49 + .../tk/ytkmm/ytkmm/gtkmm/private/iconview_p.h | 51 + libs/tk/ytkmm/ytkmm/gtkmm/private/image_p.h | 48 + .../ytkmm/gtkmm/private/imagemenuitem_p.h | 48 + libs/tk/ytkmm/ytkmm/gtkmm/private/infobar_p.h | 49 + .../ytkmm/ytkmm/gtkmm/private/invisible_p.h | 48 + libs/tk/ytkmm/ytkmm/gtkmm/private/item_p.h | 51 + libs/tk/ytkmm/ytkmm/gtkmm/private/label_p.h | 50 + libs/tk/ytkmm/ytkmm/gtkmm/private/layout_p.h | 49 + .../ytkmm/ytkmm/gtkmm/private/linkbutton_p.h | 48 + .../ytkmm/ytkmm/gtkmm/private/liststore_p.h | 48 + libs/tk/ytkmm/ytkmm/gtkmm/private/main_p.h | 8 + libs/tk/ytkmm/ytkmm/gtkmm/private/menu_p.h | 48 + libs/tk/ytkmm/ytkmm/gtkmm/private/menubar_p.h | 48 + .../tk/ytkmm/ytkmm/gtkmm/private/menuitem_p.h | 52 + .../ytkmm/ytkmm/gtkmm/private/menushell_p.h | 54 + .../ytkmm/gtkmm/private/menutoolbutton_p.h | 49 + .../ytkmm/gtkmm/private/messagedialog_p.h | 48 + libs/tk/ytkmm/ytkmm/gtkmm/private/misc_p.h | 48 + .../tk/ytkmm/ytkmm/gtkmm/private/notebook_p.h | 49 + libs/tk/ytkmm/ytkmm/gtkmm/private/object_p.h | 48 + .../ytkmm/gtkmm/private/offscreenwindow_p.h | 48 + .../ytkmm/ytkmm/gtkmm/private/optionmenu_p.h | 52 + .../ytkmm/ytkmm/gtkmm/private/orientable_p.h | 44 + .../ytkmm/ytkmm/gtkmm/private/pagesetup_p.h | 48 + .../gtkmm/private/pagesetupunixdialog_p.h | 48 + libs/tk/ytkmm/ytkmm/gtkmm/private/paned_p.h | 124 + .../ytkmm/ytkmm/gtkmm/private/papersize_p.h | 8 + libs/tk/ytkmm/ytkmm/gtkmm/private/plug_p.h | 49 + .../ytkmm/gtkmm/private/printcontext_p.h | 48 + libs/tk/ytkmm/ytkmm/gtkmm/private/printer_p.h | 49 + .../tk/ytkmm/ytkmm/gtkmm/private/printjob_p.h | 49 + .../ytkmm/gtkmm/private/printoperation_p.h | 59 + .../gtkmm/private/printoperationpreview_p.h | 49 + .../ytkmm/gtkmm/private/printsettings_p.h | 48 + .../ytkmm/gtkmm/private/printunixdialog_p.h | 48 + .../ytkmm/ytkmm/gtkmm/private/progressbar_p.h | 49 + .../ytkmm/ytkmm/gtkmm/private/radioaction_p.h | 49 + .../ytkmm/ytkmm/gtkmm/private/radiobutton_p.h | 49 + .../ytkmm/gtkmm/private/radiomenuitem_p.h | 49 + .../ytkmm/gtkmm/private/radiotoolbutton_p.h | 48 + libs/tk/ytkmm/ytkmm/gtkmm/private/range_p.h | 52 + libs/tk/ytkmm/ytkmm/gtkmm/private/rc_p.h | 48 + .../ytkmm/gtkmm/private/recentaction_p.h | 48 + .../ytkmm/gtkmm/private/recentchooser_p.h | 51 + .../gtkmm/private/recentchooserdialog_p.h | 48 + .../ytkmm/gtkmm/private/recentchoosermenu_p.h | 48 + .../gtkmm/private/recentchooserwidget_p.h | 48 + .../ytkmm/gtkmm/private/recentfilter_p.h | 48 + .../ytkmm/ytkmm/gtkmm/private/recentinfo_p.h | 8 + .../ytkmm/gtkmm/private/recentmanager_p.h | 49 + libs/tk/ytkmm/ytkmm/gtkmm/private/ruler_p.h | 129 + libs/tk/ytkmm/ytkmm/gtkmm/private/scale_p.h | 126 + .../ytkmm/ytkmm/gtkmm/private/scalebutton_p.h | 49 + .../ytkmm/ytkmm/gtkmm/private/scrollbar_p.h | 124 + .../ytkmm/gtkmm/private/scrolledwindow_p.h | 48 + .../ytkmm/gtkmm/private/selectiondata_p.h | 8 + .../ytkmm/ytkmm/gtkmm/private/separator_p.h | 124 + .../ytkmm/gtkmm/private/separatormenuitem_p.h | 48 + .../ytkmm/gtkmm/private/separatortoolitem_p.h | 48 + .../tk/ytkmm/ytkmm/gtkmm/private/settings_p.h | 48 + .../ytkmm/ytkmm/gtkmm/private/sizegroup_p.h | 48 + libs/tk/ytkmm/ytkmm/gtkmm/private/socket_p.h | 50 + .../ytkmm/ytkmm/gtkmm/private/spinbutton_p.h | 51 + libs/tk/ytkmm/ytkmm/gtkmm/private/spinner_p.h | 48 + .../ytkmm/ytkmm/gtkmm/private/statusbar_p.h | 50 + .../ytkmm/ytkmm/gtkmm/private/stockitem_p.h | 8 + libs/tk/ytkmm/ytkmm/gtkmm/private/style_p.h | 79 + libs/tk/ytkmm/ytkmm/gtkmm/private/table_p.h | 48 + .../ytkmm/ytkmm/gtkmm/private/targetlist_p.h | 8 + .../ytkmm/gtkmm/private/tearoffmenuitem_p.h | 48 + .../ytkmm/gtkmm/private/textattributes_p.h | 8 + .../ytkmm/ytkmm/gtkmm/private/textbuffer_p.h | 60 + .../ytkmm/gtkmm/private/textchildanchor_p.h | 48 + .../tk/ytkmm/ytkmm/gtkmm/private/textiter_p.h | 8 + .../tk/ytkmm/ytkmm/gtkmm/private/textmark_p.h | 48 + libs/tk/ytkmm/ytkmm/gtkmm/private/texttag_p.h | 50 + .../ytkmm/gtkmm/private/texttagtable_p.h | 51 + .../tk/ytkmm/ytkmm/gtkmm/private/textview_p.h | 52 + .../ytkmm/gtkmm/private/toggleaction_p.h | 49 + .../ytkmm/gtkmm/private/togglebutton_p.h | 49 + .../ytkmm/gtkmm/private/toggletoolbutton_p.h | 49 + libs/tk/ytkmm/ytkmm/gtkmm/private/toolbar_p.h | 51 + .../ytkmm/ytkmm/gtkmm/private/toolbutton_p.h | 49 + .../tk/ytkmm/ytkmm/gtkmm/private/toolitem_p.h | 50 + .../ytkmm/gtkmm/private/toolitemgroup_p.h | 48 + .../ytkmm/ytkmm/gtkmm/private/toolpalette_p.h | 48 + .../ytkmm/ytkmm/gtkmm/private/toolshell_p.h | 49 + libs/tk/ytkmm/ytkmm/gtkmm/private/tooltip_p.h | 48 + .../tk/ytkmm/ytkmm/gtkmm/private/tooltips_p.h | 51 + .../ytkmm/gtkmm/private/treedragdest_p.h | 46 + .../ytkmm/gtkmm/private/treedragsource_p.h | 47 + .../tk/ytkmm/ytkmm/gtkmm/private/treeiter_p.h | 8 + .../ytkmm/ytkmm/gtkmm/private/treemodel_p.h | 63 + .../ytkmm/gtkmm/private/treemodelfilter_p.h | 48 + .../ytkmm/gtkmm/private/treemodelsort_p.h | 48 + .../tk/ytkmm/ytkmm/gtkmm/private/treepath_p.h | 8 + .../ytkmm/gtkmm/private/treerowreference_p.h | 8 + .../ytkmm/gtkmm/private/treeselection_p.h | 49 + .../ytkmm/gtkmm/private/treesortable_p.h | 51 + .../ytkmm/ytkmm/gtkmm/private/treestore_p.h | 48 + .../tk/ytkmm/ytkmm/gtkmm/private/treeview_p.h | 56 + .../ytkmm/gtkmm/private/treeviewcolumn_p.h | 49 + .../ytkmm/ytkmm/gtkmm/private/uimanager_p.h | 50 + .../tk/ytkmm/ytkmm/gtkmm/private/viewport_p.h | 49 + libs/tk/ytkmm/ytkmm/gtkmm/private/widget_p.h | 119 + libs/tk/ytkmm/ytkmm/gtkmm/private/window_p.h | 89 + libs/tk/ytkmm/ytkmm/gtkmm/progressbar.h | 415 + libs/tk/ytkmm/ytkmm/gtkmm/radioaction.h | 296 + libs/tk/ytkmm/ytkmm/gtkmm/radiobutton.h | 187 + libs/tk/ytkmm/ytkmm/gtkmm/radiobuttongroup.h | 80 + libs/tk/ytkmm/ytkmm/gtkmm/radiomenuitem.h | 174 + libs/tk/ytkmm/ytkmm/gtkmm/radiotoolbutton.h | 208 + libs/tk/ytkmm/ytkmm/gtkmm/range.h | 626 + libs/tk/ytkmm/ytkmm/gtkmm/rc.h | 367 + libs/tk/ytkmm/ytkmm/gtkmm/recentaction.h | 212 + libs/tk/ytkmm/ytkmm/gtkmm/recentchooser.h | 756 + .../ytkmm/ytkmm/gtkmm/recentchooserdialog.h | 148 + libs/tk/ytkmm/ytkmm/gtkmm/recentchoosermenu.h | 175 + .../ytkmm/ytkmm/gtkmm/recentchooserwidget.h | 138 + libs/tk/ytkmm/ytkmm/gtkmm/recentfilter.h | 338 + libs/tk/ytkmm/ytkmm/gtkmm/recentinfo.h | 413 + libs/tk/ytkmm/ytkmm/gtkmm/recentmanager.h | 479 + libs/tk/ytkmm/ytkmm/gtkmm/ruler.h | 487 + libs/tk/ytkmm/ytkmm/gtkmm/scale.h | 521 + libs/tk/ytkmm/ytkmm/gtkmm/scalebutton.h | 362 + libs/tk/ytkmm/ytkmm/gtkmm/scrollbar.h | 338 + libs/tk/ytkmm/ytkmm/gtkmm/scrolledwindow.h | 434 + libs/tk/ytkmm/ytkmm/gtkmm/selectiondata.h | 341 + .../ytkmm/ytkmm/gtkmm/selectiondata_private.h | 49 + libs/tk/ytkmm/ytkmm/gtkmm/separator.h | 320 + libs/tk/ytkmm/ytkmm/gtkmm/separatormenuitem.h | 130 + libs/tk/ytkmm/ytkmm/gtkmm/separatortoolitem.h | 168 + libs/tk/ytkmm/ytkmm/gtkmm/settings.h | 952 + libs/tk/ytkmm/ytkmm/gtkmm/sizegroup.h | 297 + libs/tk/ytkmm/ytkmm/gtkmm/socket.h | 244 + libs/tk/ytkmm/ytkmm/gtkmm/spinbutton.h | 554 + libs/tk/ytkmm/ytkmm/gtkmm/spinner.h | 156 + libs/tk/ytkmm/ytkmm/gtkmm/statusbar.h | 257 + libs/tk/ytkmm/ytkmm/gtkmm/stock.h | 227 + libs/tk/ytkmm/ytkmm/gtkmm/stockid.h | 142 + libs/tk/ytkmm/ytkmm/gtkmm/stockitem.h | 113 + libs/tk/ytkmm/ytkmm/gtkmm/style.h | 837 + libs/tk/ytkmm/ytkmm/gtkmm/table.h | 432 + libs/tk/ytkmm/ytkmm/gtkmm/targetentry.h | 97 + libs/tk/ytkmm/ytkmm/gtkmm/targetlist.h | 126 + libs/tk/ytkmm/ytkmm/gtkmm/tearoffmenuitem.h | 138 + libs/tk/ytkmm/ytkmm/gtkmm/textattributes.h | 124 + libs/tk/ytkmm/ytkmm/gtkmm/textbuffer.h | 1285 + libs/tk/ytkmm/ytkmm/gtkmm/textchildanchor.h | 177 + libs/tk/ytkmm/ytkmm/gtkmm/textiter.h | 1344 + libs/tk/ytkmm/ytkmm/gtkmm/textmark.h | 301 + libs/tk/ytkmm/ytkmm/gtkmm/texttag.h | 1099 + libs/tk/ytkmm/ytkmm/gtkmm/texttagtable.h | 225 + libs/tk/ytkmm/ytkmm/gtkmm/textview.h | 1118 + libs/tk/ytkmm/ytkmm/gtkmm/toggleaction.h | 292 + libs/tk/ytkmm/ytkmm/gtkmm/togglebutton.h | 256 + libs/tk/ytkmm/ytkmm/gtkmm/toggletoolbutton.h | 208 + libs/tk/ytkmm/ytkmm/gtkmm/toolbar.h | 519 + libs/tk/ytkmm/ytkmm/gtkmm/toolbutton.h | 407 + libs/tk/ytkmm/ytkmm/gtkmm/toolitem.h | 620 + libs/tk/ytkmm/ytkmm/gtkmm/toolitemgroup.h | 391 + libs/tk/ytkmm/ytkmm/gtkmm/toolpalette.h | 519 + libs/tk/ytkmm/ytkmm/gtkmm/toolshell.h | 277 + libs/tk/ytkmm/ytkmm/gtkmm/tooltip.h | 275 + libs/tk/ytkmm/ytkmm/gtkmm/tooltips.h | 174 + libs/tk/ytkmm/ytkmm/gtkmm/treedragdest.h | 195 + libs/tk/ytkmm/ytkmm/gtkmm/treedragsource.h | 206 + libs/tk/ytkmm/ytkmm/gtkmm/treeiter.h | 520 + libs/tk/ytkmm/ytkmm/gtkmm/treemodel.h | 703 + libs/tk/ytkmm/ytkmm/gtkmm/treemodelcolumn.h | 141 + libs/tk/ytkmm/ytkmm/gtkmm/treemodelfilter.h | 354 + libs/tk/ytkmm/ytkmm/gtkmm/treemodelsort.h | 254 + libs/tk/ytkmm/ytkmm/gtkmm/treepath.h | 441 + libs/tk/ytkmm/ytkmm/gtkmm/treerowreference.h | 164 + libs/tk/ytkmm/ytkmm/gtkmm/treeselection.h | 405 + libs/tk/ytkmm/ytkmm/gtkmm/treesortable.h | 313 + libs/tk/ytkmm/ytkmm/gtkmm/treestore.h | 294 + libs/tk/ytkmm/ytkmm/gtkmm/treeview.h | 2571 ++ libs/tk/ytkmm/ytkmm/gtkmm/treeview_private.h | 49 + libs/tk/ytkmm/ytkmm/gtkmm/treeviewcolumn.h | 1043 + libs/tk/ytkmm/ytkmm/gtkmm/uimanager.h | 755 + libs/tk/ytkmm/ytkmm/gtkmm/viewport.h | 285 + libs/tk/ytkmm/ytkmm/gtkmm/widget.h | 4246 ++ libs/tk/ytkmm/ytkmm/gtkmm/window.h | 2024 + libs/tk/ytkmm/ytkmm/gtkmm/wrap_init.h | 32 + libs/tk/ytkmm/ytkmm/gtkmmconfig.h | 29 + libs/tk/ztk/atk-enum-types.c | 420 + libs/tk/ztk/atkaction.c | 286 + libs/tk/ztk/atkcomponent.c | 660 + libs/tk/ztk/atkdocument.c | 416 + libs/tk/ztk/atkeditabletext.c | 237 + libs/tk/ztk/atkgobjectaccessible.c | 184 + libs/tk/ztk/atkhyperlink.c | 423 + libs/tk/ztk/atkhyperlinkimpl.c | 108 + libs/tk/ztk/atkhypertext.c | 181 + libs/tk/ztk/atkimage.c | 238 + libs/tk/ztk/atkmarshal.c | 240 + libs/tk/ztk/atkmisc.c | 149 + libs/tk/ztk/atknoopobject.c | 208 + libs/tk/ztk/atknoopobjectfactory.c | 116 + libs/tk/ztk/atkobject.c | 1715 + libs/tk/ztk/atkobjectfactory.c | 147 + libs/tk/ztk/atkplug.c | 102 + libs/tk/ztk/atkprivate.c | 131 + libs/tk/ztk/atkrange.c | 169 + libs/tk/ztk/atkregistry.c | 288 + libs/tk/ztk/atkrelation.c | 501 + libs/tk/ztk/atkrelationset.c | 409 + libs/tk/ztk/atkselection.c | 289 + libs/tk/ztk/atksocket.c | 160 + libs/tk/ztk/atkstate.c | 141 + libs/tk/ztk/atkstateset.c | 368 + libs/tk/ztk/atkstreamablecontent.c | 181 + libs/tk/ztk/atktable.c | 983 + libs/tk/ztk/atktablecell.c | 276 + libs/tk/ztk/atktext.c | 1515 + libs/tk/ztk/atkutil.c | 599 + libs/tk/ztk/atkvalue.c | 744 + libs/tk/ztk/atkversion.c | 129 + libs/tk/ztk/atkwindow.c | 168 + libs/tk/ztk/config.h | 14 + libs/tk/ztk/wscript | 78 + libs/tk/ztk/ztk/atk/atk-enum-types.h | 63 + libs/tk/ztk/ztk/atk/atk.h | 61 + libs/tk/ztk/ztk/atk/atkaction.h | 117 + libs/tk/ztk/ztk/atk/atkcomponent.h | 225 + libs/tk/ztk/ztk/atk/atkdocument.h | 113 + libs/tk/ztk/ztk/atk/atkeditabletext.h | 109 + libs/tk/ztk/ztk/atk/atkgobjectaccessible.h | 68 + libs/tk/ztk/ztk/atk/atkhyperlink.h | 114 + libs/tk/ztk/ztk/atk/atkhyperlinkimpl.h | 68 + libs/tk/ztk/ztk/atk/atkhypertext.h | 78 + libs/tk/ztk/ztk/atk/atkimage.h | 90 + libs/tk/ztk/ztk/atk/atkmarshal.h | 57 + libs/tk/ztk/ztk/atk/atkmisc.h | 112 + libs/tk/ztk/ztk/atk/atknoopobject.h | 59 + libs/tk/ztk/ztk/atk/atknoopobjectfactory.h | 59 + libs/tk/ztk/ztk/atk/atkobject.h | 751 + libs/tk/ztk/ztk/atk/atkobjectfactory.h | 72 + libs/tk/ztk/ztk/atk/atkplug.h | 66 + libs/tk/ztk/ztk/atk/atkprivate.h | 36 + libs/tk/ztk/ztk/atk/atkrange.h | 59 + libs/tk/ztk/ztk/atk/atkregistry.h | 74 + libs/tk/ztk/ztk/atk/atkrelation.h | 99 + libs/tk/ztk/ztk/atk/atkrelationset.h | 91 + libs/tk/ztk/ztk/atk/atkrelationtype.h | 83 + libs/tk/ztk/ztk/atk/atkselection.h | 100 + libs/tk/ztk/ztk/atk/atksocket.h | 71 + libs/tk/ztk/ztk/atk/atkstate.h | 190 + libs/tk/ztk/ztk/atk/atkstateset.h | 92 + libs/tk/ztk/ztk/atk/atkstreamablecontent.h | 110 + libs/tk/ztk/ztk/atk/atktable.h | 233 + libs/tk/ztk/ztk/atk/atktablecell.h | 104 + libs/tk/ztk/ztk/atk/atktext.h | 453 + libs/tk/ztk/ztk/atk/atkutil.h | 357 + libs/tk/ztk/ztk/atk/atkvalue.h | 163 + libs/tk/ztk/ztk/atk/atkversion.h | 394 + libs/tk/ztk/ztk/atk/atkwindow.h | 53 + libs/tk/ztk/ztk/atk/stamp-atkmarshal.h | 1 + libs/tk/ztkmm/Makefile.am | 39 + libs/tk/ztkmm/action.cc | 560 + libs/tk/ztkmm/component.cc | 1044 + libs/tk/ztkmm/document.cc | 281 + libs/tk/ztkmm/editabletext.cc | 590 + libs/tk/ztkmm/filelist.am | 9 + libs/tk/ztkmm/hyperlink.cc | 785 + libs/tk/ztkmm/hypertext.cc | 453 + libs/tk/ztkmm/image.cc | 404 + libs/tk/ztkmm/implementor.cc | 199 + libs/tk/ztkmm/init.cc | 34 + libs/tk/ztkmm/noopobject.cc | 143 + libs/tk/ztkmm/object.cc | 948 + libs/tk/ztkmm/objectaccessible.cc | 167 + libs/tk/ztkmm/relation.cc | 189 + libs/tk/ztkmm/relationset.cc | 192 + libs/tk/ztkmm/selection.cc | 693 + libs/tk/ztkmm/stateset.cc | 215 + libs/tk/ztkmm/streamablecontent.cc | 352 + libs/tk/ztkmm/table.cc | 2751 ++ libs/tk/ztkmm/text.cc | 1795 + libs/tk/ztkmm/value.cc | 394 + libs/tk/ztkmm/wrap_init.cc | 88 + libs/tk/ztkmm/wscript | 60 + libs/tk/ztkmm/ztkmm/atkmm.h | 73 + libs/tk/ztkmm/ztkmm/atkmm/action.h | 229 + libs/tk/ztkmm/ztkmm/atkmm/component.h | 376 + libs/tk/ztkmm/ztkmm/atkmm/document.h | 176 + libs/tk/ztkmm/ztkmm/atkmm/editabletext.h | 229 + libs/tk/ztkmm/ztkmm/atkmm/hyperlink.h | 269 + libs/tk/ztkmm/ztkmm/atkmm/hypertext.h | 204 + libs/tk/ztkmm/ztkmm/atkmm/image.h | 205 + libs/tk/ztkmm/ztkmm/atkmm/implementor.h | 155 + libs/tk/ztkmm/ztkmm/atkmm/init.h | 40 + libs/tk/ztkmm/ztkmm/atkmm/noopobject.h | 153 + libs/tk/ztkmm/ztkmm/atkmm/object.h | 672 + libs/tk/ztkmm/ztkmm/atkmm/objectaccessible.h | 155 + libs/tk/ztkmm/ztkmm/atkmm/private/action_p.h | 50 + .../ztkmm/ztkmm/atkmm/private/component_p.h | 57 + .../tk/ztkmm/ztkmm/atkmm/private/document_p.h | 46 + .../ztkmm/atkmm/private/editabletext_p.h | 49 + .../ztkmm/ztkmm/atkmm/private/hyperlink_p.h | 58 + .../ztkmm/ztkmm/atkmm/private/hypertext_p.h | 48 + libs/tk/ztkmm/ztkmm/atkmm/private/image_p.h | 48 + .../ztkmm/ztkmm/atkmm/private/implementor_p.h | 43 + .../ztkmm/ztkmm/atkmm/private/noopobject_p.h | 48 + libs/tk/ztkmm/ztkmm/atkmm/private/object_p.h | 54 + .../ztkmm/atkmm/private/objectaccessible_p.h | 48 + .../tk/ztkmm/ztkmm/atkmm/private/relation_p.h | 48 + .../ztkmm/ztkmm/atkmm/private/relationset_p.h | 48 + .../ztkmm/ztkmm/atkmm/private/selection_p.h | 52 + .../tk/ztkmm/ztkmm/atkmm/private/stateset_p.h | 48 + .../ztkmm/atkmm/private/streamablecontent_p.h | 47 + libs/tk/ztkmm/ztkmm/atkmm/private/table_p.h | 80 + libs/tk/ztkmm/ztkmm/atkmm/private/text_p.h | 63 + libs/tk/ztkmm/ztkmm/atkmm/private/value_p.h | 46 + libs/tk/ztkmm/ztkmm/atkmm/relation.h | 208 + libs/tk/ztkmm/ztkmm/atkmm/relationset.h | 190 + libs/tk/ztkmm/ztkmm/atkmm/selection.h | 251 + libs/tk/ztkmm/ztkmm/atkmm/stateset.h | 263 + libs/tk/ztkmm/ztkmm/atkmm/streamablecontent.h | 187 + libs/tk/ztkmm/ztkmm/atkmm/table.h | 537 + libs/tk/ztkmm/ztkmm/atkmm/text.h | 770 + libs/tk/ztkmm/ztkmm/atkmm/value.h | 190 + libs/tk/ztkmm/ztkmm/atkmm/wrap_init.h | 32 + libs/waveview/wscript | 8 +- libs/widgets/wscript | 7 +- luasession/wscript | 5 +- session_utils/wscript | 5 +- tools/linux_packaging/build | 10 +- tools/osx_packaging/osx_build | 6 +- tools/x-win/package.sh | 16 +- wscript | 22 + 1528 files changed, 915658 insertions(+), 57 deletions(-) create mode 100644 libs/tk/suil/cocoa_in_gtk2.mm create mode 100644 libs/tk/suil/dylib.h create mode 100644 libs/tk/suil/host.c create mode 100644 libs/tk/suil/instance.c create mode 100644 libs/tk/suil/suil/suil.h create mode 100644 libs/tk/suil/suil_config.h create mode 100644 libs/tk/suil/suil_internal.h create mode 100644 libs/tk/suil/win_in_gtk2.cpp create mode 100644 libs/tk/suil/wscript create mode 100644 libs/tk/suil/x11_in_gtk2.c create mode 100644 libs/tk/ydk-pixbuf/config.h create mode 100644 libs/tk/ydk-pixbuf/gdk-pixbuf-animation.c create mode 100644 libs/tk/ydk-pixbuf/gdk-pixbuf-data.c create mode 100644 libs/tk/ydk-pixbuf/gdk-pixbuf-enum-types.c create mode 100644 libs/tk/ydk-pixbuf/gdk-pixbuf-io.c create mode 100644 libs/tk/ydk-pixbuf/gdk-pixbuf-loader.c create mode 100644 libs/tk/ydk-pixbuf/gdk-pixbuf-marshal.c create mode 100644 libs/tk/ydk-pixbuf/gdk-pixbuf-scale.c create mode 100644 libs/tk/ydk-pixbuf/gdk-pixbuf-scaled-anim.c create mode 100644 libs/tk/ydk-pixbuf/gdk-pixbuf-simple-anim.c create mode 100644 libs/tk/ydk-pixbuf/gdk-pixbuf-util.c create mode 100644 libs/tk/ydk-pixbuf/gdk-pixbuf.c create mode 100644 libs/tk/ydk-pixbuf/gdk-pixdata.c create mode 100644 libs/tk/ydk-pixbuf/io-pixdata.c create mode 100644 libs/tk/ydk-pixbuf/io-png.c create mode 100644 libs/tk/ydk-pixbuf/io-xbm.c create mode 100644 libs/tk/ydk-pixbuf/io-xpm.c create mode 100644 libs/tk/ydk-pixbuf/pixops/DETAILS create mode 100644 libs/tk/ydk-pixbuf/pixops/README create mode 100644 libs/tk/ydk-pixbuf/pixops/composite_line_22_4a4_mmx.S create mode 100644 libs/tk/ydk-pixbuf/pixops/composite_line_color_22_4a4_mmx.S create mode 100644 libs/tk/ydk-pixbuf/pixops/have_mmx.S create mode 100644 libs/tk/ydk-pixbuf/pixops/pixbuf-transform-math.ltx create mode 100644 libs/tk/ydk-pixbuf/pixops/pixops-internal.h create mode 100644 libs/tk/ydk-pixbuf/pixops/pixops.c create mode 100644 libs/tk/ydk-pixbuf/pixops/pixops.h create mode 100644 libs/tk/ydk-pixbuf/pixops/scale_line_22_33_mmx.S create mode 100755 libs/tk/ydk-pixbuf/pixops/timescale create mode 100644 libs/tk/ydk-pixbuf/pixops/timescale.c create mode 100644 libs/tk/ydk-pixbuf/wscript create mode 100644 libs/tk/ydk-pixbuf/ydk-pixbuf/gdk-pixbuf/gdk-pixbuf-animation.h create mode 100644 libs/tk/ydk-pixbuf/ydk-pixbuf/gdk-pixbuf/gdk-pixbuf-core.h create mode 100644 libs/tk/ydk-pixbuf/ydk-pixbuf/gdk-pixbuf/gdk-pixbuf-enum-types.h create mode 100644 libs/tk/ydk-pixbuf/ydk-pixbuf/gdk-pixbuf/gdk-pixbuf-features.h create mode 100644 libs/tk/ydk-pixbuf/ydk-pixbuf/gdk-pixbuf/gdk-pixbuf-i18n.h create mode 100644 libs/tk/ydk-pixbuf/ydk-pixbuf/gdk-pixbuf/gdk-pixbuf-io.h create mode 100644 libs/tk/ydk-pixbuf/ydk-pixbuf/gdk-pixbuf/gdk-pixbuf-loader.h create mode 100644 libs/tk/ydk-pixbuf/ydk-pixbuf/gdk-pixbuf/gdk-pixbuf-marshal.h create mode 100644 libs/tk/ydk-pixbuf/ydk-pixbuf/gdk-pixbuf/gdk-pixbuf-private.h create mode 100644 libs/tk/ydk-pixbuf/ydk-pixbuf/gdk-pixbuf/gdk-pixbuf-scaled-anim.h create mode 100644 libs/tk/ydk-pixbuf/ydk-pixbuf/gdk-pixbuf/gdk-pixbuf-simple-anim.h create mode 100644 libs/tk/ydk-pixbuf/ydk-pixbuf/gdk-pixbuf/gdk-pixbuf-transform.h create mode 100644 libs/tk/ydk-pixbuf/ydk-pixbuf/gdk-pixbuf/gdk-pixbuf.h create mode 100644 libs/tk/ydk-pixbuf/ydk-pixbuf/gdk-pixbuf/gdk-pixdata.h create mode 100644 libs/tk/ydk-pixbuf/ydk-pixbuf/gdk-pixbuf/xpm-color-table.h create mode 100644 libs/tk/ydk/config.h create mode 100644 libs/tk/ydk/gdk.c create mode 100644 libs/tk/ydk/gdkaliasdef.c create mode 100644 libs/tk/ydk/gdkapplaunchcontext.c create mode 100644 libs/tk/ydk/gdkcairo.c create mode 100644 libs/tk/ydk/gdkcolor.c create mode 100644 libs/tk/ydk/gdkcursor.c create mode 100644 libs/tk/ydk/gdkdisplay.c create mode 100644 libs/tk/ydk/gdkdisplaymanager.c create mode 100644 libs/tk/ydk/gdkdnd.c create mode 100644 libs/tk/ydk/gdkdraw.c create mode 100644 libs/tk/ydk/gdkenumtypes.c create mode 100644 libs/tk/ydk/gdkevents.c create mode 100644 libs/tk/ydk/gdkfont.c create mode 100644 libs/tk/ydk/gdkgc.c create mode 100644 libs/tk/ydk/gdkglobals.c create mode 100644 libs/tk/ydk/gdkimage.c create mode 100644 libs/tk/ydk/gdkkeynames.c create mode 100644 libs/tk/ydk/gdkkeys.c create mode 100644 libs/tk/ydk/gdkkeyuni.c create mode 100644 libs/tk/ydk/gdkmarshalers.c create mode 100644 libs/tk/ydk/gdkmedialib.c create mode 100644 libs/tk/ydk/gdkoffscreenwindow.c create mode 100644 libs/tk/ydk/gdkpango.c create mode 100644 libs/tk/ydk/gdkpixbuf-drawable.c create mode 100644 libs/tk/ydk/gdkpixbuf-render.c create mode 100644 libs/tk/ydk/gdkpixmap.c create mode 100644 libs/tk/ydk/gdkpolyreg-generic.c create mode 100644 libs/tk/ydk/gdkrectangle.c create mode 100644 libs/tk/ydk/gdkregion-generic.c create mode 100644 libs/tk/ydk/gdkrgb.c create mode 100644 libs/tk/ydk/gdkscreen.c create mode 100644 libs/tk/ydk/gdkselection.c create mode 100644 libs/tk/ydk/gdkvisual.c create mode 100644 libs/tk/ydk/gdkwindow.c create mode 100644 libs/tk/ydk/gdkwindowimpl.c create mode 100644 libs/tk/ydk/quartz/GdkQuartzView.c create mode 100644 libs/tk/ydk/quartz/GdkQuartzWindow.c create mode 100644 libs/tk/ydk/quartz/gdkapplaunchcontext-quartz.c create mode 100644 libs/tk/ydk/quartz/gdkcolor-quartz.c create mode 100644 libs/tk/ydk/quartz/gdkcursor-quartz.c create mode 100644 libs/tk/ydk/quartz/gdkdisplay-quartz.c create mode 100644 libs/tk/ydk/quartz/gdkdnd-quartz.c create mode 100644 libs/tk/ydk/quartz/gdkdrawable-quartz.c create mode 100644 libs/tk/ydk/quartz/gdkeventloop-quartz.c create mode 100644 libs/tk/ydk/quartz/gdkevents-quartz.c create mode 100644 libs/tk/ydk/quartz/gdkfont-quartz.c create mode 100644 libs/tk/ydk/quartz/gdkgc-quartz.c create mode 100644 libs/tk/ydk/quartz/gdkgeometry-quartz.c create mode 100644 libs/tk/ydk/quartz/gdkglobals-quartz.c create mode 100644 libs/tk/ydk/quartz/gdkim-quartz.c create mode 100644 libs/tk/ydk/quartz/gdkimage-quartz.c create mode 100644 libs/tk/ydk/quartz/gdkinput.c create mode 100644 libs/tk/ydk/quartz/gdkkeys-quartz.c create mode 100644 libs/tk/ydk/quartz/gdkmain-quartz.c create mode 100644 libs/tk/ydk/quartz/gdkpixmap-quartz.c create mode 100644 libs/tk/ydk/quartz/gdkproperty-quartz.c create mode 100644 libs/tk/ydk/quartz/gdkscreen-quartz.c create mode 100644 libs/tk/ydk/quartz/gdkselection-quartz.c create mode 100644 libs/tk/ydk/quartz/gdkspawn-quartz.c create mode 100644 libs/tk/ydk/quartz/gdktestutils-quartz.c create mode 100644 libs/tk/ydk/quartz/gdkvisual-quartz.c create mode 100644 libs/tk/ydk/quartz/gdkwindow-quartz.c create mode 100644 libs/tk/ydk/win32/bdfcursor.c create mode 100644 libs/tk/ydk/win32/gdkapplaunchcontext-win32.c create mode 100644 libs/tk/ydk/win32/gdkcolor-win32.c create mode 100644 libs/tk/ydk/win32/gdkcursor-win32.c create mode 100644 libs/tk/ydk/win32/gdkdisplay-win32.c create mode 100644 libs/tk/ydk/win32/gdkdnd-win32.c create mode 100644 libs/tk/ydk/win32/gdkdrawable-win32.c create mode 100644 libs/tk/ydk/win32/gdkevents-win32.c create mode 100644 libs/tk/ydk/win32/gdkfont-win32.c create mode 100644 libs/tk/ydk/win32/gdkgc-win32.c create mode 100644 libs/tk/ydk/win32/gdkgeometry-win32.c create mode 100644 libs/tk/ydk/win32/gdkglobals-win32.c create mode 100644 libs/tk/ydk/win32/gdkim-win32.c create mode 100644 libs/tk/ydk/win32/gdkimage-win32.c create mode 100644 libs/tk/ydk/win32/gdkinput-win32.c create mode 100644 libs/tk/ydk/win32/gdkinput.c create mode 100644 libs/tk/ydk/win32/gdkkeys-win32.c create mode 100644 libs/tk/ydk/win32/gdkmain-win32.c create mode 100644 libs/tk/ydk/win32/gdkpixmap-win32.c create mode 100644 libs/tk/ydk/win32/gdkprivate-win32.h create mode 100644 libs/tk/ydk/win32/gdkproperty-win32.c create mode 100644 libs/tk/ydk/win32/gdkscreen-win32.c create mode 100644 libs/tk/ydk/win32/gdkselection-win32.c create mode 100644 libs/tk/ydk/win32/gdkspawn-win32.c create mode 100644 libs/tk/ydk/win32/gdktestutils-win32.c create mode 100644 libs/tk/ydk/win32/gdkvisual-win32.c create mode 100644 libs/tk/ydk/win32/gdkwin32id.c create mode 100644 libs/tk/ydk/win32/gdkwindow-win32.c create mode 100644 libs/tk/ydk/win32/rc/Makefile.am create mode 100644 libs/tk/ydk/win32/rc/gdk.rc create mode 100644 libs/tk/ydk/win32/rc/gdk.rc.in create mode 100644 libs/tk/ydk/win32/rc/gtk.ico create mode 100644 libs/tk/ydk/wscript create mode 100644 libs/tk/ydk/x11/checksettings.c create mode 100644 libs/tk/ydk/x11/gdkapplaunchcontext-x11.c create mode 100644 libs/tk/ydk/x11/gdkasync.c create mode 100644 libs/tk/ydk/x11/gdkcolor-x11.c create mode 100644 libs/tk/ydk/x11/gdkcursor-x11.c create mode 100644 libs/tk/ydk/x11/gdkdisplay-x11.c create mode 100644 libs/tk/ydk/x11/gdkdnd-x11.c create mode 100644 libs/tk/ydk/x11/gdkdrawable-x11.c create mode 100644 libs/tk/ydk/x11/gdkevents-x11.c create mode 100644 libs/tk/ydk/x11/gdkfont-x11.c create mode 100644 libs/tk/ydk/x11/gdkgc-x11.c create mode 100644 libs/tk/ydk/x11/gdkgeometry-x11.c create mode 100644 libs/tk/ydk/x11/gdkglobals-x11.c create mode 100644 libs/tk/ydk/x11/gdkim-x11.c create mode 100644 libs/tk/ydk/x11/gdkimage-x11.c create mode 100644 libs/tk/ydk/x11/gdkinput-none.c create mode 100644 libs/tk/ydk/x11/gdkinput-x11.c create mode 100644 libs/tk/ydk/x11/gdkinput-xfree.c create mode 100644 libs/tk/ydk/x11/gdkinput.c create mode 100644 libs/tk/ydk/x11/gdkkeys-x11.c create mode 100644 libs/tk/ydk/x11/gdkmain-x11.c create mode 100644 libs/tk/ydk/x11/gdkpixmap-x11.c create mode 100644 libs/tk/ydk/x11/gdkproperty-x11.c create mode 100644 libs/tk/ydk/x11/gdkscreen-x11.c create mode 100644 libs/tk/ydk/x11/gdkselection-x11.c create mode 100644 libs/tk/ydk/x11/gdksettings.c create mode 100644 libs/tk/ydk/x11/gdkspawn-x11.c create mode 100644 libs/tk/ydk/x11/gdktestutils-x11.c create mode 100644 libs/tk/ydk/x11/gdkvisual-x11.c create mode 100644 libs/tk/ydk/x11/gdkwindow-x11.c create mode 100644 libs/tk/ydk/x11/gdkxftdefaults.c create mode 100644 libs/tk/ydk/x11/gdkxid.c create mode 100644 libs/tk/ydk/x11/xsettings-client.c create mode 100644 libs/tk/ydk/x11/xsettings-common.c create mode 100644 libs/tk/ydk/ydk/gdk/gdk.h create mode 100644 libs/tk/ydk/ydk/gdk/gdkalias.h create mode 100644 libs/tk/ydk/ydk/gdk/gdkapplaunchcontext.h create mode 100644 libs/tk/ydk/ydk/gdk/gdkcairo.h create mode 100644 libs/tk/ydk/ydk/gdk/gdkcolor.h create mode 100644 libs/tk/ydk/ydk/gdk/gdkcursor.h create mode 100644 libs/tk/ydk/ydk/gdk/gdkdisplay.h create mode 100644 libs/tk/ydk/ydk/gdk/gdkdisplaymanager.h create mode 100644 libs/tk/ydk/ydk/gdk/gdkdnd.h create mode 100644 libs/tk/ydk/ydk/gdk/gdkdrawable.h create mode 100644 libs/tk/ydk/ydk/gdk/gdkenumtypes.h create mode 100644 libs/tk/ydk/ydk/gdk/gdkevents.h create mode 100644 libs/tk/ydk/ydk/gdk/gdkfont.h create mode 100644 libs/tk/ydk/ydk/gdk/gdkgc.h create mode 100644 libs/tk/ydk/ydk/gdk/gdki18n.h create mode 100644 libs/tk/ydk/ydk/gdk/gdkimage.h create mode 100644 libs/tk/ydk/ydk/gdk/gdkinput.h create mode 100644 libs/tk/ydk/ydk/gdk/gdkinternals.h create mode 100644 libs/tk/ydk/ydk/gdk/gdkintl.h create mode 100644 libs/tk/ydk/ydk/gdk/gdkkeys.h create mode 100644 libs/tk/ydk/ydk/gdk/gdkkeysyms-compat.h create mode 100644 libs/tk/ydk/ydk/gdk/gdkkeysyms.h create mode 100644 libs/tk/ydk/ydk/gdk/gdkmarshalers.h create mode 100644 libs/tk/ydk/ydk/gdk/gdkmedialib.h create mode 100644 libs/tk/ydk/ydk/gdk/gdkpango.h create mode 100644 libs/tk/ydk/ydk/gdk/gdkpixbuf.h create mode 100644 libs/tk/ydk/ydk/gdk/gdkpixmap.h create mode 100644 libs/tk/ydk/ydk/gdk/gdkpoly-generic.h create mode 100644 libs/tk/ydk/ydk/gdk/gdkprivate.h create mode 100644 libs/tk/ydk/ydk/gdk/gdkproperty.h create mode 100644 libs/tk/ydk/ydk/gdk/gdkregion-generic.h create mode 100644 libs/tk/ydk/ydk/gdk/gdkregion.h create mode 100644 libs/tk/ydk/ydk/gdk/gdkrgb.h create mode 100644 libs/tk/ydk/ydk/gdk/gdkscreen.h create mode 100644 libs/tk/ydk/ydk/gdk/gdkselection.h create mode 100644 libs/tk/ydk/ydk/gdk/gdkspawn.h create mode 100644 libs/tk/ydk/ydk/gdk/gdktestutils.h create mode 100644 libs/tk/ydk/ydk/gdk/gdktypes.h create mode 100644 libs/tk/ydk/ydk/gdk/gdkvisual.h create mode 100644 libs/tk/ydk/ydk/gdk/gdkwindow.h create mode 100644 libs/tk/ydk/ydk/gdk/gdkwindowimpl.h create mode 100644 libs/tk/ydk/ydk/gdk/keyname-table.h create mode 100644 libs/tk/ydk/ydk/gdk/quartz/GdkQuartzView.h create mode 100644 libs/tk/ydk/ydk/gdk/quartz/GdkQuartzWindow.h create mode 100644 libs/tk/ydk/ydk/gdk/quartz/gdkdrawable-quartz.h create mode 100644 libs/tk/ydk/ydk/gdk/quartz/gdkinputprivate.h create mode 100644 libs/tk/ydk/ydk/gdk/quartz/gdkpixmap-quartz.h create mode 100644 libs/tk/ydk/ydk/gdk/quartz/gdkprivate-quartz.h create mode 100644 libs/tk/ydk/ydk/gdk/quartz/gdkscreen-quartz.h create mode 100644 libs/tk/ydk/ydk/gdk/quartz/gdkwindow-quartz.h create mode 100644 libs/tk/ydk/ydk/gdk/quartz/xcursors.h create mode 100644 libs/tk/ydk/ydk/gdk/stamp-gdkenumtypes.h create mode 100644 libs/tk/ydk/ydk/gdk/x11/gdkdisplay-x11.h create mode 100644 libs/tk/ydk/ydk/gdk/x11/gdkdrawable-x11.h create mode 100644 libs/tk/ydk/ydk/gdk/x11/gdkpixmap-x11.h create mode 100644 libs/tk/ydk/ydk/gdk/x11/gdkwindow-x11.h create mode 100644 libs/tk/ydk/ydk/gdkconfig.h create mode 100644 libs/tk/ydk/ydk/gdkscreen-x11.h create mode 100644 libs/tk/ydk/ydk/quartz/gdk/gdkquartz.h create mode 100644 libs/tk/ydk/ydk/win32/gdk/gdkdrawable-win32.h create mode 100644 libs/tk/ydk/ydk/win32/gdk/gdkinput-win32.h create mode 100644 libs/tk/ydk/ydk/win32/gdk/gdkpixmap-win32.h create mode 100644 libs/tk/ydk/ydk/win32/gdk/gdkwin32.h create mode 100644 libs/tk/ydk/ydk/win32/gdk/gdkwin32keys.h create mode 100644 libs/tk/ydk/ydk/win32/gdk/gdkwindow-win32.h create mode 100644 libs/tk/ydk/ydk/win32/gdk/pktdef.h create mode 100644 libs/tk/ydk/ydk/win32/gdk/wintab.h create mode 100644 libs/tk/ydk/ydk/win32/gdk/xcursors.h create mode 100644 libs/tk/ydk/ydk/x11/gdk/MwmUtil.h create mode 100644 libs/tk/ydk/ydk/x11/gdk/gdkasync.h create mode 100644 libs/tk/ydk/ydk/x11/gdk/gdkinputprivate.h create mode 100644 libs/tk/ydk/ydk/x11/gdk/gdkprivate-x11.h create mode 100644 libs/tk/ydk/ydk/x11/gdk/gdkx.h create mode 100644 libs/tk/ydk/ydk/x11/gdk/xsettings-client.h create mode 100644 libs/tk/ydk/ydk/x11/gdk/xsettings-common.h create mode 100644 libs/tk/ydkmm/bitmap.cc create mode 100644 libs/tk/ydkmm/color.cc create mode 100644 libs/tk/ydkmm/colormap.cc create mode 100644 libs/tk/ydkmm/cursor.cc create mode 100644 libs/tk/ydkmm/device.cc create mode 100644 libs/tk/ydkmm/display.cc create mode 100644 libs/tk/ydkmm/displaymanager.cc create mode 100644 libs/tk/ydkmm/dragcontext.cc create mode 100644 libs/tk/ydkmm/drawable.cc create mode 100644 libs/tk/ydkmm/event.cc create mode 100644 libs/tk/ydkmm/gc.cc create mode 100644 libs/tk/ydkmm/general.cc create mode 100644 libs/tk/ydkmm/image.cc create mode 100644 libs/tk/ydkmm/pixbuf.cc create mode 100644 libs/tk/ydkmm/pixbufanimation.cc create mode 100644 libs/tk/ydkmm/pixbufanimationiter.cc create mode 100644 libs/tk/ydkmm/pixbufformat.cc create mode 100644 libs/tk/ydkmm/pixbufloader.cc create mode 100644 libs/tk/ydkmm/pixmap.cc create mode 100644 libs/tk/ydkmm/rectangle.cc create mode 100644 libs/tk/ydkmm/region.cc create mode 100644 libs/tk/ydkmm/rgb.cc create mode 100644 libs/tk/ydkmm/rgbcmap.cc create mode 100644 libs/tk/ydkmm/screen.cc create mode 100644 libs/tk/ydkmm/types.cc create mode 100644 libs/tk/ydkmm/visual.cc create mode 100644 libs/tk/ydkmm/window.cc create mode 100644 libs/tk/ydkmm/wrap_init.cc create mode 100644 libs/tk/ydkmm/wscript create mode 100644 libs/tk/ydkmm/ydkmm/gdkmm.h create mode 100644 libs/tk/ydkmm/ydkmm/gdkmm/bitmap.h create mode 100644 libs/tk/ydkmm/ydkmm/gdkmm/color.h create mode 100644 libs/tk/ydkmm/ydkmm/gdkmm/colormap.h create mode 100644 libs/tk/ydkmm/ydkmm/gdkmm/cursor.h create mode 100644 libs/tk/ydkmm/ydkmm/gdkmm/device.h create mode 100644 libs/tk/ydkmm/ydkmm/gdkmm/display.h create mode 100644 libs/tk/ydkmm/ydkmm/gdkmm/displaymanager.h create mode 100644 libs/tk/ydkmm/ydkmm/gdkmm/dragcontext.h create mode 100644 libs/tk/ydkmm/ydkmm/gdkmm/drawable.h create mode 100644 libs/tk/ydkmm/ydkmm/gdkmm/event.h create mode 100644 libs/tk/ydkmm/ydkmm/gdkmm/gc.h create mode 100644 libs/tk/ydkmm/ydkmm/gdkmm/general.h create mode 100644 libs/tk/ydkmm/ydkmm/gdkmm/image.h create mode 100644 libs/tk/ydkmm/ydkmm/gdkmm/list.h create mode 100644 libs/tk/ydkmm/ydkmm/gdkmm/pixbuf.h create mode 100644 libs/tk/ydkmm/ydkmm/gdkmm/pixbufanimation.h create mode 100644 libs/tk/ydkmm/ydkmm/gdkmm/pixbufanimationiter.h create mode 100644 libs/tk/ydkmm/ydkmm/gdkmm/pixbufformat.h create mode 100644 libs/tk/ydkmm/ydkmm/gdkmm/pixbufloader.h create mode 100644 libs/tk/ydkmm/ydkmm/gdkmm/pixmap.h create mode 100644 libs/tk/ydkmm/ydkmm/gdkmm/private/bitmap_p.h create mode 100644 libs/tk/ydkmm/ydkmm/gdkmm/private/color_p.h create mode 100644 libs/tk/ydkmm/ydkmm/gdkmm/private/colormap_p.h create mode 100644 libs/tk/ydkmm/ydkmm/gdkmm/private/cursor_p.h create mode 100644 libs/tk/ydkmm/ydkmm/gdkmm/private/device_p.h create mode 100644 libs/tk/ydkmm/ydkmm/gdkmm/private/display_p.h create mode 100644 libs/tk/ydkmm/ydkmm/gdkmm/private/displaymanager_p.h create mode 100644 libs/tk/ydkmm/ydkmm/gdkmm/private/dragcontext_p.h create mode 100644 libs/tk/ydkmm/ydkmm/gdkmm/private/drawable_p.h create mode 100644 libs/tk/ydkmm/ydkmm/gdkmm/private/event_p.h create mode 100644 libs/tk/ydkmm/ydkmm/gdkmm/private/gc_p.h create mode 100644 libs/tk/ydkmm/ydkmm/gdkmm/private/image_p.h create mode 100644 libs/tk/ydkmm/ydkmm/gdkmm/private/pixbuf_p.h create mode 100644 libs/tk/ydkmm/ydkmm/gdkmm/private/pixbufanimation_p.h create mode 100644 libs/tk/ydkmm/ydkmm/gdkmm/private/pixbufanimationiter_p.h create mode 100644 libs/tk/ydkmm/ydkmm/gdkmm/private/pixbufformat_p.h create mode 100644 libs/tk/ydkmm/ydkmm/gdkmm/private/pixbufloader_p.h create mode 100644 libs/tk/ydkmm/ydkmm/gdkmm/private/pixmap_p.h create mode 100644 libs/tk/ydkmm/ydkmm/gdkmm/private/rectangle_p.h create mode 100644 libs/tk/ydkmm/ydkmm/gdkmm/private/region_p.h create mode 100644 libs/tk/ydkmm/ydkmm/gdkmm/private/rgbcmap_p.h create mode 100644 libs/tk/ydkmm/ydkmm/gdkmm/private/screen_p.h create mode 100644 libs/tk/ydkmm/ydkmm/gdkmm/private/types_p.h create mode 100644 libs/tk/ydkmm/ydkmm/gdkmm/private/visual_p.h create mode 100644 libs/tk/ydkmm/ydkmm/gdkmm/private/window_p.h create mode 100644 libs/tk/ydkmm/ydkmm/gdkmm/rectangle.h create mode 100644 libs/tk/ydkmm/ydkmm/gdkmm/region.h create mode 100644 libs/tk/ydkmm/ydkmm/gdkmm/rgb.h create mode 100644 libs/tk/ydkmm/ydkmm/gdkmm/rgbcmap.h create mode 100644 libs/tk/ydkmm/ydkmm/gdkmm/screen.h create mode 100644 libs/tk/ydkmm/ydkmm/gdkmm/types.h create mode 100644 libs/tk/ydkmm/ydkmm/gdkmm/visual.h create mode 100644 libs/tk/ydkmm/ydkmm/gdkmm/window.h create mode 100644 libs/tk/ydkmm/ydkmm/gdkmm/wrap_init.h create mode 100644 libs/tk/ydkmm/ydkmm/gdkmmconfig.h create mode 100644 libs/tk/ytk/config.h create mode 100644 libs/tk/ytk/fnmatch.c create mode 100644 libs/tk/ytk/gtkaboutdialog.c create mode 100644 libs/tk/ytk/gtkaccelgroup.c create mode 100644 libs/tk/ytk/gtkaccellabel.c create mode 100644 libs/tk/ytk/gtkaccelmap.c create mode 100644 libs/tk/ytk/gtkaccessible.c create mode 100644 libs/tk/ytk/gtkaction.c create mode 100644 libs/tk/ytk/gtkactiongroup.c create mode 100644 libs/tk/ytk/gtkactivatable.c create mode 100644 libs/tk/ytk/gtkadjustment.c create mode 100644 libs/tk/ytk/gtkaliasdef.c create mode 100644 libs/tk/ytk/gtkalignment.c create mode 100644 libs/tk/ytk/gtkarrow.c create mode 100644 libs/tk/ytk/gtkaspectframe.c create mode 100644 libs/tk/ytk/gtkassistant.c create mode 100644 libs/tk/ytk/gtkbbox.c create mode 100644 libs/tk/ytk/gtkbin.c create mode 100644 libs/tk/ytk/gtkbindings.c create mode 100644 libs/tk/ytk/gtkbox.c create mode 100644 libs/tk/ytk/gtkbuildable.c create mode 100644 libs/tk/ytk/gtkbuilder.c create mode 100644 libs/tk/ytk/gtkbuilderparser.c create mode 100644 libs/tk/ytk/gtkbutton.c create mode 100644 libs/tk/ytk/gtkcelleditable.c create mode 100644 libs/tk/ytk/gtkcelllayout.c create mode 100644 libs/tk/ytk/gtkcellrenderer.c create mode 100644 libs/tk/ytk/gtkcellrendereraccel.c create mode 100644 libs/tk/ytk/gtkcellrenderercombo.c create mode 100644 libs/tk/ytk/gtkcellrendererpixbuf.c create mode 100644 libs/tk/ytk/gtkcellrendererprogress.c create mode 100644 libs/tk/ytk/gtkcellrendererspin.c create mode 100644 libs/tk/ytk/gtkcellrendererspinner.c create mode 100644 libs/tk/ytk/gtkcellrenderertext.c create mode 100644 libs/tk/ytk/gtkcellrenderertoggle.c create mode 100644 libs/tk/ytk/gtkcellview.c create mode 100644 libs/tk/ytk/gtkcheckbutton.c create mode 100644 libs/tk/ytk/gtkcheckmenuitem.c create mode 100644 libs/tk/ytk/gtkclipboard-quartz.c create mode 100644 libs/tk/ytk/gtkclipboard.c create mode 100644 libs/tk/ytk/gtkcolorbutton.c create mode 100644 libs/tk/ytk/gtkcolorsel.c create mode 100644 libs/tk/ytk/gtkcolorseldialog.c create mode 100644 libs/tk/ytk/gtkcombobox.c create mode 100644 libs/tk/ytk/gtkcomboboxentry.c create mode 100644 libs/tk/ytk/gtkcomboboxtext.c create mode 100644 libs/tk/ytk/gtkcontainer.c create mode 100644 libs/tk/ytk/gtkdialog.c create mode 100644 libs/tk/ytk/gtkdnd-quartz.c create mode 100644 libs/tk/ytk/gtkdnd.c create mode 100644 libs/tk/ytk/gtkdrawingarea.c create mode 100644 libs/tk/ytk/gtkeditable.c create mode 100644 libs/tk/ytk/gtkentry.c create mode 100644 libs/tk/ytk/gtkentrybuffer.c create mode 100644 libs/tk/ytk/gtkentrycompletion.c create mode 100644 libs/tk/ytk/gtkeventbox.c create mode 100644 libs/tk/ytk/gtkexpander.c create mode 100644 libs/tk/ytk/gtkfilechooser.c create mode 100644 libs/tk/ytk/gtkfilechooserbutton.c create mode 100644 libs/tk/ytk/gtkfilechooserdefault.c create mode 100644 libs/tk/ytk/gtkfilechooserdialog.c create mode 100644 libs/tk/ytk/gtkfilechooserembed.c create mode 100644 libs/tk/ytk/gtkfilechooserentry.c create mode 100644 libs/tk/ytk/gtkfilechoosersettings.c create mode 100644 libs/tk/ytk/gtkfilechooserutils.c create mode 100644 libs/tk/ytk/gtkfilechooserwidget.c create mode 100644 libs/tk/ytk/gtkfilefilter.c create mode 100644 libs/tk/ytk/gtkfilesystem.c create mode 100644 libs/tk/ytk/gtkfilesystemmodel.c create mode 100644 libs/tk/ytk/gtkfixed.c create mode 100644 libs/tk/ytk/gtkfontbutton.c create mode 100644 libs/tk/ytk/gtkfontsel.c create mode 100644 libs/tk/ytk/gtkframe.c create mode 100644 libs/tk/ytk/gtkgc.c create mode 100644 libs/tk/ytk/gtkhandlebox.c create mode 100644 libs/tk/ytk/gtkhbbox.c create mode 100644 libs/tk/ytk/gtkhbox.c create mode 100644 libs/tk/ytk/gtkhpaned.c create mode 100644 libs/tk/ytk/gtkhruler.c create mode 100644 libs/tk/ytk/gtkhscale.c create mode 100644 libs/tk/ytk/gtkhscrollbar.c create mode 100644 libs/tk/ytk/gtkhseparator.c create mode 100644 libs/tk/ytk/gtkhsv.c create mode 100644 libs/tk/ytk/gtkiconcache.c create mode 100644 libs/tk/ytk/gtkiconcachevalidator.c create mode 100644 libs/tk/ytk/gtkiconfactory.c create mode 100644 libs/tk/ytk/gtkicontheme.c create mode 100644 libs/tk/ytk/gtkiconview.c create mode 100644 libs/tk/ytk/gtkimage.c create mode 100644 libs/tk/ytk/gtkimagemenuitem.c create mode 100644 libs/tk/ytk/gtkimcontext.c create mode 100644 libs/tk/ytk/gtkimcontextsimple.c create mode 100644 libs/tk/ytk/gtkimmodule.c create mode 100644 libs/tk/ytk/gtkimmulticontext.c create mode 100644 libs/tk/ytk/gtkinfobar.c create mode 100644 libs/tk/ytk/gtkinvisible.c create mode 100644 libs/tk/ytk/gtkitem.c create mode 100644 libs/tk/ytk/gtkkeyhash.c create mode 100644 libs/tk/ytk/gtklabel.c create mode 100644 libs/tk/ytk/gtklayout.c create mode 100644 libs/tk/ytk/gtklinkbutton.c create mode 100644 libs/tk/ytk/gtkliststore.c create mode 100644 libs/tk/ytk/gtkmain.c create mode 100644 libs/tk/ytk/gtkmarshal.c create mode 100644 libs/tk/ytk/gtkmarshalers.c create mode 100644 libs/tk/ytk/gtkmenu.c create mode 100644 libs/tk/ytk/gtkmenubar.c create mode 100644 libs/tk/ytk/gtkmenuitem.c create mode 100644 libs/tk/ytk/gtkmenushell.c create mode 100644 libs/tk/ytk/gtkmenutoolbutton.c create mode 100644 libs/tk/ytk/gtkmessagedialog.c create mode 100644 libs/tk/ytk/gtkmisc.c create mode 100644 libs/tk/ytk/gtkmnemonichash.c create mode 100644 libs/tk/ytk/gtkmodules.c create mode 100644 libs/tk/ytk/gtkmountoperation-stub.c create mode 100644 libs/tk/ytk/gtkmountoperation-x11.c create mode 100644 libs/tk/ytk/gtkmountoperation.c create mode 100644 libs/tk/ytk/gtknotebook.c create mode 100644 libs/tk/ytk/gtkobject.c create mode 100644 libs/tk/ytk/gtkoffscreenwindow.c create mode 100644 libs/tk/ytk/gtkoptionmenu.c create mode 100644 libs/tk/ytk/gtkorientable.c create mode 100644 libs/tk/ytk/gtkpaned.c create mode 100644 libs/tk/ytk/gtkpango.c create mode 100644 libs/tk/ytk/gtkpathbar.c create mode 100644 libs/tk/ytk/gtkplug-stub.c create mode 100644 libs/tk/ytk/gtkplug-win32.c create mode 100644 libs/tk/ytk/gtkplug-x11.c create mode 100644 libs/tk/ytk/gtkplug.c create mode 100644 libs/tk/ytk/gtkprogress.c create mode 100644 libs/tk/ytk/gtkprogressbar.c create mode 100644 libs/tk/ytk/gtkquartz.c create mode 100644 libs/tk/ytk/gtkquery.c create mode 100644 libs/tk/ytk/gtkradioaction.c create mode 100644 libs/tk/ytk/gtkradiobutton.c create mode 100644 libs/tk/ytk/gtkradiomenuitem.c create mode 100644 libs/tk/ytk/gtkradiotoolbutton.c create mode 100644 libs/tk/ytk/gtkrange.c create mode 100644 libs/tk/ytk/gtkrbtree.c create mode 100644 libs/tk/ytk/gtkrc.c create mode 100644 libs/tk/ytk/gtkrecentaction.c create mode 100644 libs/tk/ytk/gtkrecentchooser.c create mode 100644 libs/tk/ytk/gtkrecentchooserdefault.c create mode 100644 libs/tk/ytk/gtkrecentchooserdialog.c create mode 100644 libs/tk/ytk/gtkrecentchoosermenu.c create mode 100644 libs/tk/ytk/gtkrecentchooserutils.c create mode 100644 libs/tk/ytk/gtkrecentchooserwidget.c create mode 100644 libs/tk/ytk/gtkrecentfilter.c create mode 100644 libs/tk/ytk/gtkrecentmanager.c create mode 100644 libs/tk/ytk/gtkrelocation.c create mode 100644 libs/tk/ytk/gtkruler.c create mode 100644 libs/tk/ytk/gtkscale.c create mode 100644 libs/tk/ytk/gtkscalebutton.c create mode 100644 libs/tk/ytk/gtkscrollbar.c create mode 100644 libs/tk/ytk/gtkscrolledwindow.c create mode 100644 libs/tk/ytk/gtksearchengine.c create mode 100644 libs/tk/ytk/gtksearchenginequartz.c create mode 100644 libs/tk/ytk/gtksearchenginesimple.c create mode 100644 libs/tk/ytk/gtkselection.c create mode 100644 libs/tk/ytk/gtkseparator.c create mode 100644 libs/tk/ytk/gtkseparatormenuitem.c create mode 100644 libs/tk/ytk/gtkseparatortoolitem.c create mode 100644 libs/tk/ytk/gtksettings.c create mode 100644 libs/tk/ytk/gtkshow.c create mode 100644 libs/tk/ytk/gtksizegroup.c create mode 100644 libs/tk/ytk/gtksocket-stub.c create mode 100644 libs/tk/ytk/gtksocket-win32.c create mode 100644 libs/tk/ytk/gtksocket-x11.c create mode 100644 libs/tk/ytk/gtksocket.c create mode 100644 libs/tk/ytk/gtkspinbutton.c create mode 100644 libs/tk/ytk/gtkspinner.c create mode 100644 libs/tk/ytk/gtkstatusbar.c create mode 100644 libs/tk/ytk/gtkstock.c create mode 100644 libs/tk/ytk/gtkstyle.c create mode 100644 libs/tk/ytk/gtktable.c create mode 100644 libs/tk/ytk/gtktearoffmenuitem.c create mode 100644 libs/tk/ytk/gtktextbtree.c create mode 100644 libs/tk/ytk/gtktextbuffer.c create mode 100644 libs/tk/ytk/gtktextbufferrichtext.c create mode 100644 libs/tk/ytk/gtktextbufferserialize.c create mode 100644 libs/tk/ytk/gtktextchild.c create mode 100644 libs/tk/ytk/gtktextdisplay.c create mode 100644 libs/tk/ytk/gtktextiter.c create mode 100644 libs/tk/ytk/gtktextlayout.c create mode 100644 libs/tk/ytk/gtktextmark.c create mode 100644 libs/tk/ytk/gtktextsegment.c create mode 100644 libs/tk/ytk/gtktexttag.c create mode 100644 libs/tk/ytk/gtktexttagtable.c create mode 100644 libs/tk/ytk/gtktexttypes.c create mode 100644 libs/tk/ytk/gtktextutil.c create mode 100644 libs/tk/ytk/gtktextview.c create mode 100644 libs/tk/ytk/gtkthemes.c create mode 100644 libs/tk/ytk/gtktoggleaction.c create mode 100644 libs/tk/ytk/gtktogglebutton.c create mode 100644 libs/tk/ytk/gtktoggletoolbutton.c create mode 100644 libs/tk/ytk/gtktoolbar.c create mode 100644 libs/tk/ytk/gtktoolbutton.c create mode 100644 libs/tk/ytk/gtktoolitem.c create mode 100644 libs/tk/ytk/gtktoolitemgroup.c create mode 100644 libs/tk/ytk/gtktoolpalette.c create mode 100644 libs/tk/ytk/gtktoolshell.c create mode 100644 libs/tk/ytk/gtktooltip.c create mode 100644 libs/tk/ytk/gtktooltips.c create mode 100644 libs/tk/ytk/gtktreedatalist.c create mode 100644 libs/tk/ytk/gtktreednd.c create mode 100644 libs/tk/ytk/gtktreemodel.c create mode 100644 libs/tk/ytk/gtktreemodelfilter.c create mode 100644 libs/tk/ytk/gtktreemodelsort.c create mode 100644 libs/tk/ytk/gtktreeselection.c create mode 100644 libs/tk/ytk/gtktreesortable.c create mode 100644 libs/tk/ytk/gtktreestore.c create mode 100644 libs/tk/ytk/gtktreeview.c create mode 100644 libs/tk/ytk/gtktreeviewcolumn.c create mode 100644 libs/tk/ytk/gtktypebuiltins.c create mode 100644 libs/tk/ytk/gtktypeutils.c create mode 100644 libs/tk/ytk/gtkuimanager.c create mode 100644 libs/tk/ytk/gtkvbbox.c create mode 100644 libs/tk/ytk/gtkvbox.c create mode 100644 libs/tk/ytk/gtkviewport.c create mode 100644 libs/tk/ytk/gtkvpaned.c create mode 100644 libs/tk/ytk/gtkvruler.c create mode 100644 libs/tk/ytk/gtkvscale.c create mode 100644 libs/tk/ytk/gtkvscrollbar.c create mode 100644 libs/tk/ytk/gtkvseparator.c create mode 100644 libs/tk/ytk/gtkwidget.c create mode 100644 libs/tk/ytk/gtkwin32embed.c create mode 100644 libs/tk/ytk/gtkwin32embedwidget.c create mode 100644 libs/tk/ytk/gtkwindow-decorate.c create mode 100644 libs/tk/ytk/gtkwindow.c create mode 100644 libs/tk/ytk/gtkxembed.c create mode 100644 libs/tk/ytk/line-arrow.xbm create mode 100644 libs/tk/ytk/line-wrap.xbm create mode 100644 libs/tk/ytk/po/ca.po create mode 100644 libs/tk/ytk/po/cs.po create mode 100644 libs/tk/ytk/po/de.po create mode 100644 libs/tk/ytk/po/el.po create mode 100644 libs/tk/ytk/po/en_GB.po create mode 100644 libs/tk/ytk/po/es.po create mode 100644 libs/tk/ytk/po/eu.po create mode 100644 libs/tk/ytk/po/fr.po create mode 100644 libs/tk/ytk/po/ja.po create mode 100644 libs/tk/ytk/po/ko.po create mode 100644 libs/tk/ytk/po/nn.po create mode 100644 libs/tk/ytk/po/pl.po create mode 100644 libs/tk/ytk/po/pt.po create mode 100644 libs/tk/ytk/po/pt_BR.po create mode 100644 libs/tk/ytk/po/ru.po create mode 100644 libs/tk/ytk/po/sv.po create mode 100644 libs/tk/ytk/po/zh.po create mode 100644 libs/tk/ytk/tree_minus.xpm create mode 100644 libs/tk/ytk/tree_plus.xpm create mode 100644 libs/tk/ytk/wscript create mode 100644 libs/tk/ytk/ximian-icons.h create mode 100644 libs/tk/ytk/ytk/gtk/gtk.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkaboutdialog.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkaccelgroup.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkaccellabel.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkaccelmap.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkaccessible.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkaction.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkactiongroup.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkactivatable.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkadjustment.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkalias.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkalignment.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkarrow.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkaspectframe.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkassistant.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkbbox.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkbin.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkbindings.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkbox.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkbuildable.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkbuilder.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkbuilderprivate.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkbuiltincache.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkbutton.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkcelleditable.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkcelllayout.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkcellrenderer.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkcellrendereraccel.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkcellrenderercombo.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkcellrendererpixbuf.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkcellrendererprogress.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkcellrendererspin.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkcellrendererspinner.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkcellrenderertext.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkcellrenderertoggle.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkcellview.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkcheckbutton.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkcheckmenuitem.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkclipboard.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkcolorbutton.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkcolorsel.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkcolorseldialog.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkcombobox.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkcomboboxentry.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkcomboboxtext.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkcontainer.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkdebug.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkdialog.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkdnd.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkdndcursors.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkdrawingarea.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkeditable.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkentry.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkentrybuffer.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkentrycompletion.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkentryprivate.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkenums.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkeventbox.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkexpander.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkfilechooser.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkfilechooserbutton.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkfilechooserdefault.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkfilechooserdialog.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkfilechooserembed.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkfilechooserentry.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkfilechooserprivate.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkfilechoosersettings.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkfilechooserutils.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkfilechooserwidget.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkfilefilter.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkfilesystem.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkfilesystemmodel.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkfixed.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkfontbutton.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkfontsel.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkframe.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkgc.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkhandlebox.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkhbbox.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkhbox.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkhpaned.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkhruler.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkhscale.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkhscrollbar.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkhseparator.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkhsv.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkiconcache.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkiconcachevalidator.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkiconfactory.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkicontheme.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkiconview.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkimage.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkimagemenuitem.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkimcontext.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkimcontextsimple.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkimcontextsimpleseqs.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkimmodule.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkimmulticontext.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkinfobar.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkintl.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkinvisible.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkitem.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkkeyhash.h create mode 100644 libs/tk/ytk/ytk/gtk/gtklabel.h create mode 100644 libs/tk/ytk/ytk/gtk/gtklayout.h create mode 100644 libs/tk/ytk/ytk/gtk/gtklinkbutton.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkliststore.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkmain.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkmarshal.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkmarshalers.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkmenu.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkmenubar.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkmenuitem.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkmenushell.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkmenutoolbutton.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkmessagedialog.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkmisc.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkmnemonichash.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkmodules.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkmountoperation.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkmountoperationprivate.h create mode 100644 libs/tk/ytk/ytk/gtk/gtknotebook.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkobject.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkoffscreenwindow.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkoptionmenu.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkorientable.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkpagesetupunixdialog.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkpaned.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkpango.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkpathbar.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkplug.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkplugprivate.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkprivate.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkprogress.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkprogressbar.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkquartz.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkquery.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkradioaction.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkradiobutton.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkradiomenuitem.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkradiotoolbutton.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkrange.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkrbtree.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkrc.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkrecentaction.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkrecentchooser.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkrecentchooserdefault.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkrecentchooserdialog.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkrecentchoosermenu.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkrecentchooserprivate.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkrecentchooserutils.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkrecentchooserwidget.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkrecentfilter.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkrecentmanager.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkruler.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkscale.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkscalebutton.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkscrollbar.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkscrolledwindow.h create mode 100644 libs/tk/ytk/ytk/gtk/gtksearchengine.h create mode 100644 libs/tk/ytk/ytk/gtk/gtksearchenginequartz.h create mode 100644 libs/tk/ytk/ytk/gtk/gtksearchenginesimple.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkselection.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkseparator.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkseparatormenuitem.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkseparatortoolitem.h create mode 100644 libs/tk/ytk/ytk/gtk/gtksettings.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkshow.h create mode 100644 libs/tk/ytk/ytk/gtk/gtksizegroup.h create mode 100644 libs/tk/ytk/ytk/gtk/gtksocket.h create mode 100644 libs/tk/ytk/ytk/gtk/gtksocketprivate.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkspinbutton.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkspinner.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkstatusbar.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkstock.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkstyle.h create mode 100644 libs/tk/ytk/ytk/gtk/gtktable.h create mode 100644 libs/tk/ytk/ytk/gtk/gtktearoffmenuitem.h create mode 100644 libs/tk/ytk/ytk/gtk/gtktestutils.h create mode 100644 libs/tk/ytk/ytk/gtk/gtktextbtree.h create mode 100644 libs/tk/ytk/ytk/gtk/gtktextbuffer.h create mode 100644 libs/tk/ytk/ytk/gtk/gtktextbufferrichtext.h create mode 100644 libs/tk/ytk/ytk/gtk/gtktextbufferserialize.h create mode 100644 libs/tk/ytk/ytk/gtk/gtktextchild.h create mode 100644 libs/tk/ytk/ytk/gtk/gtktextchildprivate.h create mode 100644 libs/tk/ytk/ytk/gtk/gtktextdisplay.h create mode 100644 libs/tk/ytk/ytk/gtk/gtktextiter.h create mode 100644 libs/tk/ytk/ytk/gtk/gtktextiterprivate.h create mode 100644 libs/tk/ytk/ytk/gtk/gtktextlayout.h create mode 100644 libs/tk/ytk/ytk/gtk/gtktextmark.h create mode 100644 libs/tk/ytk/ytk/gtk/gtktextmarkprivate.h create mode 100644 libs/tk/ytk/ytk/gtk/gtktextsegment.h create mode 100644 libs/tk/ytk/ytk/gtk/gtktexttag.h create mode 100644 libs/tk/ytk/ytk/gtk/gtktexttagprivate.h create mode 100644 libs/tk/ytk/ytk/gtk/gtktexttagtable.h create mode 100644 libs/tk/ytk/ytk/gtk/gtktexttypes.h create mode 100644 libs/tk/ytk/ytk/gtk/gtktextutil.h create mode 100644 libs/tk/ytk/ytk/gtk/gtktextview.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkthemes.h create mode 100644 libs/tk/ytk/ytk/gtk/gtktoggleaction.h create mode 100644 libs/tk/ytk/ytk/gtk/gtktoggleactionprivate.h create mode 100644 libs/tk/ytk/ytk/gtk/gtktogglebutton.h create mode 100644 libs/tk/ytk/ytk/gtk/gtktoggletoolbutton.h create mode 100644 libs/tk/ytk/ytk/gtk/gtktoolbar.h create mode 100644 libs/tk/ytk/ytk/gtk/gtktoolbutton.h create mode 100644 libs/tk/ytk/ytk/gtk/gtktoolitem.h create mode 100644 libs/tk/ytk/ytk/gtk/gtktoolitemgroup.h create mode 100644 libs/tk/ytk/ytk/gtk/gtktoolpalette.h create mode 100644 libs/tk/ytk/ytk/gtk/gtktoolpaletteprivate.h create mode 100644 libs/tk/ytk/ytk/gtk/gtktoolshell.h create mode 100644 libs/tk/ytk/ytk/gtk/gtktooltip.h create mode 100644 libs/tk/ytk/ytk/gtk/gtktooltips.h create mode 100644 libs/tk/ytk/ytk/gtk/gtktrayicon.h create mode 100644 libs/tk/ytk/ytk/gtk/gtktreedatalist.h create mode 100644 libs/tk/ytk/ytk/gtk/gtktreednd.h create mode 100644 libs/tk/ytk/ytk/gtk/gtktreemodel.h create mode 100644 libs/tk/ytk/ytk/gtk/gtktreemodelfilter.h create mode 100644 libs/tk/ytk/ytk/gtk/gtktreemodelsort.h create mode 100644 libs/tk/ytk/ytk/gtk/gtktreeprivate.h create mode 100644 libs/tk/ytk/ytk/gtk/gtktreeselection.h create mode 100644 libs/tk/ytk/ytk/gtk/gtktreesortable.h create mode 100644 libs/tk/ytk/ytk/gtk/gtktreestore.h create mode 100644 libs/tk/ytk/ytk/gtk/gtktreeview.h create mode 100644 libs/tk/ytk/ytk/gtk/gtktreeviewcolumn.h create mode 100644 libs/tk/ytk/ytk/gtk/gtktypebuiltins.h create mode 100644 libs/tk/ytk/ytk/gtk/gtktypeutils.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkuimanager.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkvbbox.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkvbox.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkversion.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkviewport.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkvpaned.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkvruler.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkvscale.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkvscrollbar.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkvseparator.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkwidget.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkwin32embed.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkwin32embedwidget.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkwindow-decorate.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkwindow.h create mode 100644 libs/tk/ytk/ytk/gtk/gtkxembed.h create mode 100644 libs/tk/ytk/ytk/gtk/stamp-gtkmarshal.h create mode 100644 libs/tk/ytk/ytk/gtk/stamp-gtkmarshalers.h create mode 100644 libs/tk/ytk/ytk/gtk/stamp-gtktypebuiltins.h create mode 100644 libs/tk/ytk/ytk/gtk/xembed.h create mode 100644 libs/tk/ytkmm/aboutdialog.cc create mode 100644 libs/tk/ytkmm/accelgroup.cc create mode 100644 libs/tk/ytkmm/accelkey.cc create mode 100644 libs/tk/ytkmm/accellabel.cc create mode 100644 libs/tk/ytkmm/accelmap.cc create mode 100644 libs/tk/ytkmm/action.cc create mode 100644 libs/tk/ytkmm/actiongroup.cc create mode 100644 libs/tk/ytkmm/activatable.cc create mode 100644 libs/tk/ytkmm/adjustment.cc create mode 100644 libs/tk/ytkmm/alignment.cc create mode 100644 libs/tk/ytkmm/arrow.cc create mode 100644 libs/tk/ytkmm/aspectframe.cc create mode 100644 libs/tk/ytkmm/assistant.cc create mode 100644 libs/tk/ytkmm/bin.cc create mode 100644 libs/tk/ytkmm/box.cc create mode 100644 libs/tk/ytkmm/builder.cc create mode 100644 libs/tk/ytkmm/button.cc create mode 100644 libs/tk/ytkmm/buttonbox.cc create mode 100644 libs/tk/ytkmm/celleditable.cc create mode 100644 libs/tk/ytkmm/celllayout.cc create mode 100644 libs/tk/ytkmm/cellrenderer.cc create mode 100644 libs/tk/ytkmm/cellrenderer_generation.cc create mode 100644 libs/tk/ytkmm/cellrendereraccel.cc create mode 100644 libs/tk/ytkmm/cellrenderercombo.cc create mode 100644 libs/tk/ytkmm/cellrendererpixbuf.cc create mode 100644 libs/tk/ytkmm/cellrendererprogress.cc create mode 100644 libs/tk/ytkmm/cellrendererspin.cc create mode 100644 libs/tk/ytkmm/cellrendererspinner.cc create mode 100644 libs/tk/ytkmm/cellrenderertext.cc create mode 100644 libs/tk/ytkmm/cellrenderertoggle.cc create mode 100644 libs/tk/ytkmm/cellview.cc create mode 100644 libs/tk/ytkmm/checkbutton.cc create mode 100644 libs/tk/ytkmm/checkmenuitem.cc create mode 100644 libs/tk/ytkmm/clipboard.cc create mode 100644 libs/tk/ytkmm/colorbutton.cc create mode 100644 libs/tk/ytkmm/colorselection.cc create mode 100644 libs/tk/ytkmm/combobox.cc create mode 100644 libs/tk/ytkmm/comboboxentry.cc create mode 100644 libs/tk/ytkmm/comboboxentrytext.cc create mode 100644 libs/tk/ytkmm/comboboxtext.cc create mode 100644 libs/tk/ytkmm/container.cc create mode 100644 libs/tk/ytkmm/dialog.cc create mode 100644 libs/tk/ytkmm/drawingarea.cc create mode 100644 libs/tk/ytkmm/editable.cc create mode 100644 libs/tk/ytkmm/entry.cc create mode 100644 libs/tk/ytkmm/entrybuffer.cc create mode 100644 libs/tk/ytkmm/entrycompletion.cc create mode 100644 libs/tk/ytkmm/enums.cc create mode 100644 libs/tk/ytkmm/eventbox.cc create mode 100644 libs/tk/ytkmm/expander.cc create mode 100644 libs/tk/ytkmm/filechooser.cc create mode 100644 libs/tk/ytkmm/filechooserbutton.cc create mode 100644 libs/tk/ytkmm/filechooserdialog.cc create mode 100644 libs/tk/ytkmm/filechooserwidget.cc create mode 100644 libs/tk/ytkmm/filefilter.cc create mode 100644 libs/tk/ytkmm/fixed.cc create mode 100644 libs/tk/ytkmm/fontbutton.cc create mode 100644 libs/tk/ytkmm/fontselection.cc create mode 100644 libs/tk/ytkmm/frame.cc create mode 100644 libs/tk/ytkmm/handlebox.cc create mode 100644 libs/tk/ytkmm/iconfactory.cc create mode 100644 libs/tk/ytkmm/iconinfo.cc create mode 100644 libs/tk/ytkmm/iconset.cc create mode 100644 libs/tk/ytkmm/iconsource.cc create mode 100644 libs/tk/ytkmm/icontheme.cc create mode 100644 libs/tk/ytkmm/iconview.cc create mode 100644 libs/tk/ytkmm/image.cc create mode 100644 libs/tk/ytkmm/imagemenuitem.cc create mode 100644 libs/tk/ytkmm/infobar.cc create mode 100644 libs/tk/ytkmm/invisible.cc create mode 100644 libs/tk/ytkmm/item.cc create mode 100644 libs/tk/ytkmm/label.cc create mode 100644 libs/tk/ytkmm/layout.cc create mode 100644 libs/tk/ytkmm/linkbutton.cc create mode 100644 libs/tk/ytkmm/liststore.cc create mode 100644 libs/tk/ytkmm/listviewtext.cc create mode 100644 libs/tk/ytkmm/main.cc create mode 100644 libs/tk/ytkmm/menu.cc create mode 100644 libs/tk/ytkmm/menu_elems.cc create mode 100644 libs/tk/ytkmm/menubar.cc create mode 100644 libs/tk/ytkmm/menuitem.cc create mode 100644 libs/tk/ytkmm/menushell.cc create mode 100644 libs/tk/ytkmm/menutoolbutton.cc create mode 100644 libs/tk/ytkmm/messagedialog.cc create mode 100644 libs/tk/ytkmm/misc.cc create mode 100644 libs/tk/ytkmm/notebook.cc create mode 100644 libs/tk/ytkmm/object.cc create mode 100644 libs/tk/ytkmm/offscreenwindow.cc create mode 100644 libs/tk/ytkmm/optionmenu.cc create mode 100644 libs/tk/ytkmm/orientable.cc create mode 100644 libs/tk/ytkmm/paned.cc create mode 100644 libs/tk/ytkmm/plug.cc create mode 100644 libs/tk/ytkmm/progressbar.cc create mode 100644 libs/tk/ytkmm/radioaction.cc create mode 100644 libs/tk/ytkmm/radiobutton.cc create mode 100644 libs/tk/ytkmm/radiobuttongroup.cc create mode 100644 libs/tk/ytkmm/radiomenuitem.cc create mode 100644 libs/tk/ytkmm/radiotoolbutton.cc create mode 100644 libs/tk/ytkmm/range.cc create mode 100644 libs/tk/ytkmm/rc.cc create mode 100644 libs/tk/ytkmm/recentaction.cc create mode 100644 libs/tk/ytkmm/recentchooser.cc create mode 100644 libs/tk/ytkmm/recentchooserdialog.cc create mode 100644 libs/tk/ytkmm/recentchoosermenu.cc create mode 100644 libs/tk/ytkmm/recentchooserwidget.cc create mode 100644 libs/tk/ytkmm/recentfilter.cc create mode 100644 libs/tk/ytkmm/recentinfo.cc create mode 100644 libs/tk/ytkmm/recentmanager.cc create mode 100644 libs/tk/ytkmm/ruler.cc create mode 100644 libs/tk/ytkmm/scale.cc create mode 100644 libs/tk/ytkmm/scalebutton.cc create mode 100644 libs/tk/ytkmm/scrollbar.cc create mode 100644 libs/tk/ytkmm/scrolledwindow.cc create mode 100644 libs/tk/ytkmm/selectiondata.cc create mode 100644 libs/tk/ytkmm/selectiondata_private.cc create mode 100644 libs/tk/ytkmm/separator.cc create mode 100644 libs/tk/ytkmm/separatormenuitem.cc create mode 100644 libs/tk/ytkmm/separatortoolitem.cc create mode 100644 libs/tk/ytkmm/settings.cc create mode 100644 libs/tk/ytkmm/sizegroup.cc create mode 100644 libs/tk/ytkmm/socket.cc create mode 100644 libs/tk/ytkmm/spinbutton.cc create mode 100644 libs/tk/ytkmm/spinner.cc create mode 100644 libs/tk/ytkmm/statusbar.cc create mode 100644 libs/tk/ytkmm/stock.cc create mode 100644 libs/tk/ytkmm/stockid.cc create mode 100644 libs/tk/ytkmm/stockitem.cc create mode 100644 libs/tk/ytkmm/style.cc create mode 100644 libs/tk/ytkmm/table.cc create mode 100644 libs/tk/ytkmm/targetentry.cc create mode 100644 libs/tk/ytkmm/targetlist.cc create mode 100644 libs/tk/ytkmm/tearoffmenuitem.cc create mode 100644 libs/tk/ytkmm/textattributes.cc create mode 100644 libs/tk/ytkmm/textbuffer.cc create mode 100644 libs/tk/ytkmm/textchildanchor.cc create mode 100644 libs/tk/ytkmm/textiter.cc create mode 100644 libs/tk/ytkmm/textmark.cc create mode 100644 libs/tk/ytkmm/texttag.cc create mode 100644 libs/tk/ytkmm/texttagtable.cc create mode 100644 libs/tk/ytkmm/textview.cc create mode 100644 libs/tk/ytkmm/toggleaction.cc create mode 100644 libs/tk/ytkmm/togglebutton.cc create mode 100644 libs/tk/ytkmm/toggletoolbutton.cc create mode 100644 libs/tk/ytkmm/toolbar.cc create mode 100644 libs/tk/ytkmm/toolbutton.cc create mode 100644 libs/tk/ytkmm/toolitem.cc create mode 100644 libs/tk/ytkmm/toolitemgroup.cc create mode 100644 libs/tk/ytkmm/toolpalette.cc create mode 100644 libs/tk/ytkmm/toolshell.cc create mode 100644 libs/tk/ytkmm/tooltip.cc create mode 100644 libs/tk/ytkmm/tooltips.cc create mode 100644 libs/tk/ytkmm/treedragdest.cc create mode 100644 libs/tk/ytkmm/treedragsource.cc create mode 100644 libs/tk/ytkmm/treeiter.cc create mode 100644 libs/tk/ytkmm/treemodel.cc create mode 100644 libs/tk/ytkmm/treemodelcolumn.cc create mode 100644 libs/tk/ytkmm/treemodelfilter.cc create mode 100644 libs/tk/ytkmm/treemodelsort.cc create mode 100644 libs/tk/ytkmm/treepath.cc create mode 100644 libs/tk/ytkmm/treerowreference.cc create mode 100644 libs/tk/ytkmm/treeselection.cc create mode 100644 libs/tk/ytkmm/treesortable.cc create mode 100644 libs/tk/ytkmm/treestore.cc create mode 100644 libs/tk/ytkmm/treeview.cc create mode 100644 libs/tk/ytkmm/treeview_private.cc create mode 100644 libs/tk/ytkmm/treeviewcolumn.cc create mode 100644 libs/tk/ytkmm/uimanager.cc create mode 100644 libs/tk/ytkmm/viewport.cc create mode 100644 libs/tk/ytkmm/widget.cc create mode 100644 libs/tk/ytkmm/window.cc create mode 100644 libs/tk/ytkmm/wrap_init.cc create mode 100644 libs/tk/ytkmm/wscript create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/aboutdialog.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/accelgroup.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/accelkey.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/accellabel.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/accelmap.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/action.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/actiongroup.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/activatable.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/adjustment.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/alignment.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/arrow.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/aspectframe.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/assistant.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/base.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/bin.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/border.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/box.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/builder.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/button.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/buttonbox.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/celleditable.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/celllayout.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/cellrenderer.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/cellrenderer_generation.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/cellrendereraccel.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/cellrenderercombo.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/cellrendererpixbuf.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/cellrendererprogress.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/cellrendererspin.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/cellrendererspinner.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/cellrenderertext.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/cellrenderertoggle.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/cellview.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/checkbutton.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/checkmenuitem.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/clipboard.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/colorbutton.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/colorselection.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/combobox.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/comboboxentry.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/comboboxentrytext.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/comboboxtext.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/container.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/dialog.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/drawingarea.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/editable.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/entry.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/entrybuffer.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/entrycompletion.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/enums.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/eventbox.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/expander.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/filechooser.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/filechooserbutton.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/filechooserdialog.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/filechooserwidget.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/filefilter.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/fixed.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/fontbutton.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/fontselection.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/frame.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/handlebox.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/iconfactory.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/iconinfo.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/iconset.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/iconsource.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/icontheme.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/iconview.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/image.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/imagemenuitem.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/infobar.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/invisible.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/item.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/label.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/layout.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/linkbutton.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/liststore.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/listviewtext.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/main.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/menu.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/menu_elems.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/menubar.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/menuitem.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/menushell.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/menutoolbutton.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/messagedialog.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/misc.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/notebook.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/object.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/offscreenwindow.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/optionmenu.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/orientable.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/paned.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/plug.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/aboutdialog_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/accelgroup_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/accellabel_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/action_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/actiongroup_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/activatable_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/adjustment_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/alignment_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/arrow_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/aspectframe_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/assistant_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/bin_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/box_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/builder_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/button_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/buttonbox_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/celleditable_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/celllayout_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/cellrenderer_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/cellrendereraccel_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/cellrenderercombo_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/cellrendererpixbuf_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/cellrendererprogress_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/cellrendererspin_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/cellrendererspinner_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/cellrenderertext_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/cellrenderertoggle_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/cellview_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/checkbutton_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/checkmenuitem_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/clipboard_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/colorbutton_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/colorselection_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/combo_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/combobox_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/comboboxentry_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/container_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/dialog_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/drawingarea_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/editable_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/entry_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/entrybuffer_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/entrycompletion_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/enums_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/eventbox_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/expander_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/filechooser_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/filechooserbutton_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/filechooserdialog_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/filechooserwidget_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/filefilter_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/fixed_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/fontbutton_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/fontselection_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/frame_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/handlebox_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/iconfactory_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/iconinfo_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/iconset_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/iconsource_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/icontheme_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/iconview_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/image_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/imagemenuitem_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/infobar_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/invisible_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/item_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/label_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/layout_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/linkbutton_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/liststore_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/main_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/menu_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/menubar_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/menuitem_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/menushell_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/menutoolbutton_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/messagedialog_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/misc_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/notebook_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/object_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/offscreenwindow_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/optionmenu_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/orientable_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/pagesetup_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/pagesetupunixdialog_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/paned_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/papersize_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/plug_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/printcontext_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/printer_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/printjob_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/printoperation_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/printoperationpreview_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/printsettings_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/printunixdialog_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/progressbar_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/radioaction_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/radiobutton_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/radiomenuitem_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/radiotoolbutton_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/range_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/rc_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/recentaction_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/recentchooser_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/recentchooserdialog_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/recentchoosermenu_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/recentchooserwidget_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/recentfilter_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/recentinfo_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/recentmanager_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/ruler_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/scale_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/scalebutton_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/scrollbar_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/scrolledwindow_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/selectiondata_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/separator_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/separatormenuitem_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/separatortoolitem_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/settings_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/sizegroup_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/socket_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/spinbutton_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/spinner_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/statusbar_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/stockitem_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/style_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/table_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/targetlist_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/tearoffmenuitem_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/textattributes_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/textbuffer_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/textchildanchor_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/textiter_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/textmark_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/texttag_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/texttagtable_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/textview_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/toggleaction_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/togglebutton_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/toggletoolbutton_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/toolbar_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/toolbutton_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/toolitem_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/toolitemgroup_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/toolpalette_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/toolshell_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/tooltip_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/tooltips_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/treedragdest_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/treedragsource_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/treeiter_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/treemodel_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/treemodelfilter_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/treemodelsort_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/treepath_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/treerowreference_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/treeselection_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/treesortable_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/treestore_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/treeview_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/treeviewcolumn_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/uimanager_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/viewport_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/widget_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/private/window_p.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/progressbar.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/radioaction.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/radiobutton.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/radiobuttongroup.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/radiomenuitem.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/radiotoolbutton.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/range.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/rc.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/recentaction.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/recentchooser.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/recentchooserdialog.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/recentchoosermenu.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/recentchooserwidget.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/recentfilter.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/recentinfo.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/recentmanager.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/ruler.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/scale.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/scalebutton.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/scrollbar.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/scrolledwindow.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/selectiondata.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/selectiondata_private.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/separator.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/separatormenuitem.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/separatortoolitem.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/settings.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/sizegroup.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/socket.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/spinbutton.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/spinner.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/statusbar.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/stock.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/stockid.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/stockitem.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/style.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/table.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/targetentry.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/targetlist.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/tearoffmenuitem.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/textattributes.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/textbuffer.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/textchildanchor.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/textiter.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/textmark.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/texttag.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/texttagtable.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/textview.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/toggleaction.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/togglebutton.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/toggletoolbutton.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/toolbar.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/toolbutton.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/toolitem.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/toolitemgroup.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/toolpalette.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/toolshell.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/tooltip.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/tooltips.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/treedragdest.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/treedragsource.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/treeiter.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/treemodel.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/treemodelcolumn.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/treemodelfilter.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/treemodelsort.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/treepath.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/treerowreference.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/treeselection.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/treesortable.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/treestore.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/treeview.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/treeview_private.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/treeviewcolumn.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/uimanager.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/viewport.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/widget.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/window.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmm/wrap_init.h create mode 100644 libs/tk/ytkmm/ytkmm/gtkmmconfig.h create mode 100644 libs/tk/ztk/atk-enum-types.c create mode 100644 libs/tk/ztk/atkaction.c create mode 100644 libs/tk/ztk/atkcomponent.c create mode 100644 libs/tk/ztk/atkdocument.c create mode 100644 libs/tk/ztk/atkeditabletext.c create mode 100644 libs/tk/ztk/atkgobjectaccessible.c create mode 100644 libs/tk/ztk/atkhyperlink.c create mode 100644 libs/tk/ztk/atkhyperlinkimpl.c create mode 100644 libs/tk/ztk/atkhypertext.c create mode 100644 libs/tk/ztk/atkimage.c create mode 100644 libs/tk/ztk/atkmarshal.c create mode 100644 libs/tk/ztk/atkmisc.c create mode 100644 libs/tk/ztk/atknoopobject.c create mode 100644 libs/tk/ztk/atknoopobjectfactory.c create mode 100644 libs/tk/ztk/atkobject.c create mode 100644 libs/tk/ztk/atkobjectfactory.c create mode 100644 libs/tk/ztk/atkplug.c create mode 100644 libs/tk/ztk/atkprivate.c create mode 100644 libs/tk/ztk/atkrange.c create mode 100644 libs/tk/ztk/atkregistry.c create mode 100644 libs/tk/ztk/atkrelation.c create mode 100644 libs/tk/ztk/atkrelationset.c create mode 100644 libs/tk/ztk/atkselection.c create mode 100644 libs/tk/ztk/atksocket.c create mode 100644 libs/tk/ztk/atkstate.c create mode 100644 libs/tk/ztk/atkstateset.c create mode 100644 libs/tk/ztk/atkstreamablecontent.c create mode 100644 libs/tk/ztk/atktable.c create mode 100644 libs/tk/ztk/atktablecell.c create mode 100644 libs/tk/ztk/atktext.c create mode 100644 libs/tk/ztk/atkutil.c create mode 100644 libs/tk/ztk/atkvalue.c create mode 100644 libs/tk/ztk/atkversion.c create mode 100644 libs/tk/ztk/atkwindow.c create mode 100644 libs/tk/ztk/config.h create mode 100644 libs/tk/ztk/wscript create mode 100644 libs/tk/ztk/ztk/atk/atk-enum-types.h create mode 100755 libs/tk/ztk/ztk/atk/atk.h create mode 100755 libs/tk/ztk/ztk/atk/atkaction.h create mode 100755 libs/tk/ztk/ztk/atk/atkcomponent.h create mode 100755 libs/tk/ztk/ztk/atk/atkdocument.h create mode 100755 libs/tk/ztk/ztk/atk/atkeditabletext.h create mode 100644 libs/tk/ztk/ztk/atk/atkgobjectaccessible.h create mode 100755 libs/tk/ztk/ztk/atk/atkhyperlink.h create mode 100644 libs/tk/ztk/ztk/atk/atkhyperlinkimpl.h create mode 100755 libs/tk/ztk/ztk/atk/atkhypertext.h create mode 100755 libs/tk/ztk/ztk/atk/atkimage.h create mode 100644 libs/tk/ztk/ztk/atk/atkmarshal.h create mode 100755 libs/tk/ztk/ztk/atk/atkmisc.h create mode 100644 libs/tk/ztk/ztk/atk/atknoopobject.h create mode 100755 libs/tk/ztk/ztk/atk/atknoopobjectfactory.h create mode 100755 libs/tk/ztk/ztk/atk/atkobject.h create mode 100755 libs/tk/ztk/ztk/atk/atkobjectfactory.h create mode 100644 libs/tk/ztk/ztk/atk/atkplug.h create mode 100644 libs/tk/ztk/ztk/atk/atkprivate.h create mode 100644 libs/tk/ztk/ztk/atk/atkrange.h create mode 100644 libs/tk/ztk/ztk/atk/atkregistry.h create mode 100755 libs/tk/ztk/ztk/atk/atkrelation.h create mode 100755 libs/tk/ztk/ztk/atk/atkrelationset.h create mode 100755 libs/tk/ztk/ztk/atk/atkrelationtype.h create mode 100755 libs/tk/ztk/ztk/atk/atkselection.h create mode 100644 libs/tk/ztk/ztk/atk/atksocket.h create mode 100755 libs/tk/ztk/ztk/atk/atkstate.h create mode 100755 libs/tk/ztk/ztk/atk/atkstateset.h create mode 100755 libs/tk/ztk/ztk/atk/atkstreamablecontent.h create mode 100755 libs/tk/ztk/ztk/atk/atktable.h create mode 100755 libs/tk/ztk/ztk/atk/atktablecell.h create mode 100755 libs/tk/ztk/ztk/atk/atktext.h create mode 100755 libs/tk/ztk/ztk/atk/atkutil.h create mode 100755 libs/tk/ztk/ztk/atk/atkvalue.h create mode 100644 libs/tk/ztk/ztk/atk/atkversion.h create mode 100644 libs/tk/ztk/ztk/atk/atkwindow.h create mode 100644 libs/tk/ztk/ztk/atk/stamp-atkmarshal.h create mode 100644 libs/tk/ztkmm/Makefile.am create mode 100644 libs/tk/ztkmm/action.cc create mode 100644 libs/tk/ztkmm/component.cc create mode 100644 libs/tk/ztkmm/document.cc create mode 100644 libs/tk/ztkmm/editabletext.cc create mode 100644 libs/tk/ztkmm/filelist.am create mode 100644 libs/tk/ztkmm/hyperlink.cc create mode 100644 libs/tk/ztkmm/hypertext.cc create mode 100644 libs/tk/ztkmm/image.cc create mode 100644 libs/tk/ztkmm/implementor.cc create mode 100644 libs/tk/ztkmm/init.cc create mode 100644 libs/tk/ztkmm/noopobject.cc create mode 100644 libs/tk/ztkmm/object.cc create mode 100644 libs/tk/ztkmm/objectaccessible.cc create mode 100644 libs/tk/ztkmm/relation.cc create mode 100644 libs/tk/ztkmm/relationset.cc create mode 100644 libs/tk/ztkmm/selection.cc create mode 100644 libs/tk/ztkmm/stateset.cc create mode 100644 libs/tk/ztkmm/streamablecontent.cc create mode 100644 libs/tk/ztkmm/table.cc create mode 100644 libs/tk/ztkmm/text.cc create mode 100644 libs/tk/ztkmm/value.cc create mode 100644 libs/tk/ztkmm/wrap_init.cc create mode 100644 libs/tk/ztkmm/wscript create mode 100644 libs/tk/ztkmm/ztkmm/atkmm.h create mode 100644 libs/tk/ztkmm/ztkmm/atkmm/action.h create mode 100644 libs/tk/ztkmm/ztkmm/atkmm/component.h create mode 100644 libs/tk/ztkmm/ztkmm/atkmm/document.h create mode 100644 libs/tk/ztkmm/ztkmm/atkmm/editabletext.h create mode 100644 libs/tk/ztkmm/ztkmm/atkmm/hyperlink.h create mode 100644 libs/tk/ztkmm/ztkmm/atkmm/hypertext.h create mode 100644 libs/tk/ztkmm/ztkmm/atkmm/image.h create mode 100644 libs/tk/ztkmm/ztkmm/atkmm/implementor.h create mode 100644 libs/tk/ztkmm/ztkmm/atkmm/init.h create mode 100644 libs/tk/ztkmm/ztkmm/atkmm/noopobject.h create mode 100644 libs/tk/ztkmm/ztkmm/atkmm/object.h create mode 100644 libs/tk/ztkmm/ztkmm/atkmm/objectaccessible.h create mode 100644 libs/tk/ztkmm/ztkmm/atkmm/private/action_p.h create mode 100644 libs/tk/ztkmm/ztkmm/atkmm/private/component_p.h create mode 100644 libs/tk/ztkmm/ztkmm/atkmm/private/document_p.h create mode 100644 libs/tk/ztkmm/ztkmm/atkmm/private/editabletext_p.h create mode 100644 libs/tk/ztkmm/ztkmm/atkmm/private/hyperlink_p.h create mode 100644 libs/tk/ztkmm/ztkmm/atkmm/private/hypertext_p.h create mode 100644 libs/tk/ztkmm/ztkmm/atkmm/private/image_p.h create mode 100644 libs/tk/ztkmm/ztkmm/atkmm/private/implementor_p.h create mode 100644 libs/tk/ztkmm/ztkmm/atkmm/private/noopobject_p.h create mode 100644 libs/tk/ztkmm/ztkmm/atkmm/private/object_p.h create mode 100644 libs/tk/ztkmm/ztkmm/atkmm/private/objectaccessible_p.h create mode 100644 libs/tk/ztkmm/ztkmm/atkmm/private/relation_p.h create mode 100644 libs/tk/ztkmm/ztkmm/atkmm/private/relationset_p.h create mode 100644 libs/tk/ztkmm/ztkmm/atkmm/private/selection_p.h create mode 100644 libs/tk/ztkmm/ztkmm/atkmm/private/stateset_p.h create mode 100644 libs/tk/ztkmm/ztkmm/atkmm/private/streamablecontent_p.h create mode 100644 libs/tk/ztkmm/ztkmm/atkmm/private/table_p.h create mode 100644 libs/tk/ztkmm/ztkmm/atkmm/private/text_p.h create mode 100644 libs/tk/ztkmm/ztkmm/atkmm/private/value_p.h create mode 100644 libs/tk/ztkmm/ztkmm/atkmm/relation.h create mode 100644 libs/tk/ztkmm/ztkmm/atkmm/relationset.h create mode 100644 libs/tk/ztkmm/ztkmm/atkmm/selection.h create mode 100644 libs/tk/ztkmm/ztkmm/atkmm/stateset.h create mode 100644 libs/tk/ztkmm/ztkmm/atkmm/streamablecontent.h create mode 100644 libs/tk/ztkmm/ztkmm/atkmm/table.h create mode 100644 libs/tk/ztkmm/ztkmm/atkmm/text.h create mode 100644 libs/tk/ztkmm/ztkmm/atkmm/value.h create mode 100644 libs/tk/ztkmm/ztkmm/atkmm/wrap_init.h diff --git a/.gitignore b/.gitignore index 4e5dfcf2c2..d143afedb7 100644 --- a/.gitignore +++ b/.gitignore @@ -59,6 +59,8 @@ tags /libs/ardour/libardour.pot /libs/gtkmm2ext/po/*.mo /libs/gtkmm2ext/libgtkmm2ext.pot +/libs/tk/ytk/po/*.mo +/libs/tk/ytk/*.pot /gtk2_ardour/appdata/po/*.mo /gtk2_ardour/appdata/*.pot /gtk2_ardour/ardour.appdata.xml.in diff --git a/gtk2_ardour/ardev_common.sh.in b/gtk2_ardour/ardev_common.sh.in index 4ab7c149a0..e6b78e5279 100644 --- a/gtk2_ardour/ardev_common.sh.in +++ b/gtk2_ardour/ardev_common.sh.in @@ -32,6 +32,10 @@ export PBD_TEST_PATH=$TOP/libs/pbd/test export EVORAL_TEST_PATH=$TOP/libs/evoral/test/testdata export MIDIPP_TEST_PATH=$TOP/share/patchfiles +if test -d $libs/tk/suil; then + export SUIL_MODULE_DIR=$libs/tk/suil +fi + # # even though we set the above variables, ardour requires that these # two also be set. the above settings will override them. @@ -43,7 +47,7 @@ export ARDOUR_DLL_PATH=$libs export GTK_PATH=~/.ardour3:$libs/clearlooks-newer export VAMP_PATH=$libs/vamp-plugins:$libs/vamp-pyin${VAMP_PATH:+:$VAMP_PATH} -export LD_LIBRARY_PATH=$libs/ptformat:$libs/qm-dsp:$libs/vamp-sdk:$libs/surfaces:$libs/ctrl-interface/control_protocol:$libs/ctrl-interface/midi_surface:$libs/ardour:$libs/midi++2:$libs/pbd:$libs/rubberband:$libs/soundtouch:$libs/aaf:$libs/gtkmm2ext:$libs/widgets:$libs/appleutility:$libs/taglib:$libs/evoral:$libs/evoral/src/libsmf:$libs/audiographer:$libs/temporal:$libs/libltc:$libs/canvas:$libs/waveview:$libs/ardouralsautil${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH} +export LD_LIBRARY_PATH=$libs/tk/ydk-pixbuf:$libs/tk/ztk::$libs/tk/ydk:$libs/tk/ytk:$libs/tk/ztkmm:$libs/tk/ydkmm:$libs/tk/ytkmm:$libs/tk/suil:$libs/ptformat:$libs/qm-dsp:$libs/vamp-sdk:$libs/surfaces:$libs/ctrl-interface/control_protocol:$libs/ctrl-interface/midi_surface:$libs/ardour:$libs/midi++2:$libs/pbd:$libs/rubberband:$libs/soundtouch:$libs/aaf:$libs/gtkmm2ext:$libs/widgets:$libs/appleutility:$libs/taglib:$libs/evoral:$libs/evoral/src/libsmf:$libs/audiographer:$libs/temporal:$libs/libltc:$libs/canvas:$libs/waveview:$libs/ardouralsautil${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH} # DYLD_LIBRARY_PATH is for darwin. export DYLD_FALLBACK_LIBRARY_PATH=$LD_LIBRARY_PATH diff --git a/gtk2_ardour/ui_config.cc b/gtk2_ardour/ui_config.cc index a8ea99fd3e..34305f9f83 100644 --- a/gtk2_ardour/ui_config.cc +++ b/gtk2_ardour/ui_config.cc @@ -196,7 +196,7 @@ UIConfiguration::reset_dpi () /* FT2 rendering - used by GnomeCanvas, sigh */ -#ifndef PLATFORM_WINDOWS +#ifndef PLATFORM_WINDOWS // HAVE_PANGOFT2 pango_ft2_font_map_set_resolution ((PangoFT2FontMap*) pango_ft2_font_map_new(), val/1024, val/1024); // XXX pango_ft2_font_map_new leaks #endif diff --git a/gtk2_ardour/wscript b/gtk2_ardour/wscript index 9f30a29515..1831fe83d8 100644 --- a/gtk2_ardour/wscript +++ b/gtk2_ardour/wscript @@ -445,15 +445,15 @@ def configure(conf): atleast_version='1.2.1') autowaf.check_pkg(conf, 'gthread-2.0', uselib_store='GTHREAD', atleast_version='2.10.1') - autowaf.check_pkg(conf, 'gtk+-2.0', uselib_store='GTK', - atleast_version='2.18') - autowaf.check_pkg(conf, 'gtkmm-2.4', uselib_store='GTKMM', - atleast_version='2.18') autowaf.check_pkg(conf, 'ogg', uselib_store='OGG', atleast_version='1.1.2') autowaf.check_pkg(conf, 'x11', uselib_store='X11', atleast_version='1.1', mandatory=False) autowaf.check_pkg(conf, 'pangoft2', uselib_store='PANGOFT2', atleast_version='1.36.8', mandatory=False) autowaf.check_pkg(conf, 'fontconfig', uselib_store='FONTCONFIG') + if not conf.is_defined('YTK'): + autowaf.check_pkg(conf, 'gtk+-2.0', uselib_store='GTK', atleast_version='2.18') + autowaf.check_pkg(conf, 'gtkmm-2.4', uselib_store='GTKMM', atleast_version='2.18', mandatory=True) + if conf.env.CC_NAME == 'gcc' and Options.options.strict: conf.define('GLIB_DISABLE_DEPRECATION_WARNINGS', 1) for var in ['CFLAGS', 'CXXFLAGS']: @@ -516,14 +516,22 @@ def build(bld): 'LOCALEDIR="' + os.path.normpath(bld.env['LOCALEDIR']) + '"', ] obj.linkflags = '' - obj.uselib = 'UUID FLAC FONTCONFIG GLIBMM GTHREAD GTK OGG CURL DL GTKMM CANVAS FFTW3F LO TAGLIB XML LILV RUBBERBAND AUBIO LRDF ARCHIVE VAMPSDK VAMPHOSTSDK' + obj.uselib = 'UUID FLAC FONTCONFIG GTHREAD GTK OGG PANGOMM CURL DL CANVAS FFTW3F LO TAGLIB XML LILV RUBBERBAND AUBIO LRDF ARCHIVE VAMPSDK VAMPHOSTSDK' obj.source += [ 'luadoc.cc', 'bundle_env_linux.cc' ] obj.use += [ 'X11' ] + if bld.is_defined('YTK'): + obj.use += [ 'libytk', 'libytkmm' ] + obj.uselib += ' GLIBMM GIOMM PANGOMM PANGOFT2 LIBPNG' + else: + obj.uselib += ' GTKMM' if bld.is_defined('HAVE_USB'): obj.uselib += ' USB' if bld.is_defined('HAVE_SUIL'): obj.source += [ 'lv2_plugin_ui.cc' ] - obj.use += [ 'SUIL' ] + if bld.is_defined('YTK'): + obj.use += [ 'libsuil' ] + else: + obj.uselib += ' SUIL' if bld.is_defined('LXVST_SUPPORT'): obj.source += [ 'vst_plugin_ui.cc' ] obj.source += [ 'linux_vst_gui_support.cc', 'lxvst_plugin_ui.cc' ] @@ -605,8 +613,13 @@ def build(bld): ] obj.install_path = bld.env['DLLDIR'] obj.linkflags = '' - obj.uselib = 'UUID FLAC FONTCONFIG GLIBMM GTHREAD GTK OGG CURL DL GTKMM CANVAS FFTW3F LO TAGLIB XML LILV RUBBERBAND AUBIO LRDF ARCHIVE VAMPSDK VAMPHOSTSDK' + obj.uselib = 'UUID FLAC FONTCONFIG GTHREAD OGG PANGOMM CURL DL CANVAS FFTW3F LO TAGLIB XML LILV RUBBERBAND AUBIO LRDF ARCHIVE VAMPSDK VAMPHOSTSDK' + if bld.is_defined('YTK'): + obj.use += [ 'libytk', 'libytkmm' ] + obj.uselib += ' GLIBMM GIOMM PANGOFT2 LIBPNG' + else: + obj.uselib += ' GTKMM GTK' if bld.is_defined('HAVE_USB'): obj.uselib += ' USB' if sys.platform == 'darwin': diff --git a/headless/wscript b/headless/wscript index 77b39b6877..a22c589cb3 100644 --- a/headless/wscript +++ b/headless/wscript @@ -40,7 +40,10 @@ def build(bld): obj.uselib += ' FFTW3F LO TAGLIB LILV RUBBERBAND AUBIO LRDF ARCHIVE VAMPSDK VAMPHOSTSDK' if bld.is_defined('HAVE_SUIL'): - obj.uselib += ' SUIL' + if bld.is_defined('YTK'): + obj.use += [ 'libsuil' ] + else: + obj.uselib += ' SUIL' if bld.is_defined('HAVE_USB'): obj.uselib += ' USB' diff --git a/libs/ardour/wscript b/libs/ardour/wscript index 0d0b7bdca1..479d2cb196 100644 --- a/libs/ardour/wscript +++ b/libs/ardour/wscript @@ -317,8 +317,6 @@ def configure(conf): atleast_version='0.2.0', mandatory=True) autowaf.check_pkg(conf, 'lilv-0', uselib_store='LILV', atleast_version='0.24.2', mandatory=True) - autowaf.check_pkg(conf, 'suil-0', uselib_store='SUIL', - atleast_version='0.6.0', mandatory=False) conf.define ('LV2_SUPPORT', 1) # non-standard LV2 extention -- TODO: add option to disable?? @@ -427,7 +425,10 @@ def build(bld): obj.source += ['lv2_plugin.cc', 'lv2_evbuf.c', 'uri_map.cc'] obj.uselib += ['LILV'] if bld.is_defined('HAVE_SUIL'): - obj.uselib += ['SUIL'] + if bld.is_defined('YTK'): + obj.use += [ 'libsuil' ] + else: + obj.uselib += ['SUIL'] if bld.is_defined('WINDOWS_VST_SUPPORT'): obj.source += [ 'windows_vst_plugin.cc'] diff --git a/libs/canvas/wscript b/libs/canvas/wscript index 2edf3b61bd..9716882c66 100644 --- a/libs/canvas/wscript +++ b/libs/canvas/wscript @@ -76,7 +76,7 @@ def build(bld): obj.export_includes = ['.'] obj.includes = ['.'] - obj.uselib = 'SIGCPP CAIROMM GTKMM BOOST XML OSX' + obj.uselib = 'SIGCPP CAIROMM PANGOMM BOOST XML OSX' obj.use = [ 'libpbd', 'libgtkmm2ext' ] obj.name = 'libcanvas' obj.target = 'canvas' @@ -84,6 +84,12 @@ def build(bld): obj.install_path = bld.env['LIBDIR'] obj.defines += [ 'PACKAGE="' + I18N_PACKAGE + '"' ] + if bld.is_defined('YTK'): + obj.use += [ 'libytkmm' ] + obj.uselib += ' GLIBMM GIOMM' + else: + obj.uselib += ' GTKMM' + # canvas unit-tests are outdated if False and bld.env['BUILD_TESTS'] and bld.is_defined('HAVE_CPPUNIT'): unit_testobj = bld(features = 'cxx cxxprogram') diff --git a/libs/clearlooks-newer/wscript b/libs/clearlooks-newer/wscript index 4e64d2f60f..42553726d0 100644 --- a/libs/clearlooks-newer/wscript +++ b/libs/clearlooks-newer/wscript @@ -27,11 +27,16 @@ def build(bld): obj.name = 'clearlooks-newer' obj.target = 'clearlooks' - obj.uselib = 'GTK' obj.includes = '.' obj.install_path = os.path.join(bld.env['LIBDIR'], 'engines') autowaf.ensure_visible_symbols (obj, True) + if bld.is_defined('YTK'): + obj.use = [ 'libztk', 'libytk', 'libydk-pixbuf' ] + obj.uselib = ' CAIRO PANGO' + else: + obj.uselib = 'GTK' + if sys.platform == 'darwin': # Bit of a hack: make a symlink to the .dylib that meets GTK's criteria for finding it (namely that the library must be a *.so # and that it must reside in a directory called `engines') diff --git a/libs/gtkmm2ext/wscript b/libs/gtkmm2ext/wscript index 93256f001f..67e4cade26 100644 --- a/libs/gtkmm2ext/wscript +++ b/libs/gtkmm2ext/wscript @@ -51,8 +51,9 @@ def options(opt): pass def configure(conf): - autowaf.check_pkg(conf, 'gtkmm-2.4', uselib_store='GTKMM', atleast_version='2.8') - autowaf.check_pkg(conf, 'gtk+-2.0', uselib_store='GTK', atleast_version='2.12.1') + if not conf.is_defined('YTK'): + autowaf.check_pkg(conf, 'gtkmm-2.4', uselib_store='GTKMM', atleast_version='2.8') + autowaf.check_pkg(conf, 'gtk+-2.0', uselib_store='GTK', atleast_version='2.12.1') def build(bld): # operate on copy to avoid adding sources twice @@ -71,7 +72,7 @@ def build(bld): obj.includes = ['.'] obj.name = 'libgtkmm2ext' obj.target = 'gtkmm2ext' - obj.uselib = 'GTKMM GTK XML' + obj.uselib = 'XML CAIROMM PANGOMM' obj.use = [ 'libpbd' ] obj.vnum = GTKMM2EXT_LIB_VERSION obj.install_path = bld.env['LIBDIR'] @@ -79,6 +80,11 @@ def build(bld): 'PACKAGE="' + I18N_PACKAGE + '"', 'LOCALEDIR="' + os.path.join( os.path.normpath(bld.env['DATADIR']), 'locale') + '"'] + if bld.is_defined('YTK'): + obj.use += [ 'libydk', 'libydkmm', 'libytkmm' ] + obj.uselib += ' GLIBMM GIOMM' + else: + obj.uselib += ' GTKMM GTK' if sys.platform == 'darwin': obj.source += ['gtkapplication_quartz.mm', 'nsglview.mm'] obj.uselib += ' OSX' diff --git a/libs/surfaces/cc121/wscript b/libs/surfaces/cc121/wscript index 8195463142..26edf8121b 100644 --- a/libs/surfaces/cc121/wscript +++ b/libs/surfaces/cc121/wscript @@ -20,6 +20,11 @@ def build(bld): obj.includes = [ '.', './cc121'] obj.name = 'libardour_cc121' obj.target = 'ardour_cc121' - obj.uselib = 'GTKMM GTK GDK XML OSX' + obj.uselib = 'XML OSX' obj.use = 'libardour libardour_cp libgtkmm2ext libpbd' obj.install_path = os.path.join(bld.env['LIBDIR'], 'surfaces') + if bld.is_defined('YTK'): + obj.use += ' libytkmm' + obj.uselib += ' GLIBMM GIOMM PANGOMM' + else: + obj.uselib += ' GTKMM' diff --git a/libs/surfaces/console1/wscript b/libs/surfaces/console1/wscript index 0df65151e0..ac26bf386f 100644 --- a/libs/surfaces/console1/wscript +++ b/libs/surfaces/console1/wscript @@ -22,9 +22,11 @@ def build(bld): obj.includes = [ '.', './console1'] obj.name = 'libardour_console1' obj.target = 'ardour_console1' - obj.uselib = 'GTKMM SIGCPP XML OSX' + obj.uselib = 'SIGCPP XML OSX' obj.use = 'libardour libardour_cp libardour_midisurface libgtkmm2ext libpbd libevoral libtemporal' obj.install_path = os.path.join(bld.env['LIBDIR'], 'surfaces') - -def shutdown(): - autowaf.shutdown() + if bld.is_defined('YTK'): + obj.use += ' libytkmm' + obj.uselib += ' GLIBMM GIOMM PANGOMM' + else: + obj.uselib += ' GTKMM' diff --git a/libs/surfaces/contourdesign/wscript b/libs/surfaces/contourdesign/wscript index 81645ff40a..54a10755c4 100644 --- a/libs/surfaces/contourdesign/wscript +++ b/libs/surfaces/contourdesign/wscript @@ -21,6 +21,11 @@ def build(bld): obj.includes = ['.', '../libs', '../../widgets'] obj.name = 'libardour_contourdesign' obj.target = 'ardour_contourdesign' - obj.uselib = 'GTKMM USB XML OSX' + obj.uselib = 'USB XML OSX PANGOMM' obj.use = 'libardour libardour_cp libgtkmm2ext libpbd libwidgets' obj.install_path = os.path.join(bld.env['LIBDIR'], 'surfaces') + if bld.is_defined('YTK'): + obj.use += ' libytkmm' + obj.uselib += ' GLIBMM GIOMM' + else: + obj.uselib += ' GTKMM' diff --git a/libs/surfaces/faderport/wscript b/libs/surfaces/faderport/wscript index 6532c7376e..78408979ed 100644 --- a/libs/surfaces/faderport/wscript +++ b/libs/surfaces/faderport/wscript @@ -20,6 +20,11 @@ def build(bld): obj.includes = [ '.', './faderport'] obj.name = 'libardour_faderport' obj.target = 'ardour_faderport' - obj.uselib = 'GTKMM GTK GDK XML OSX' + obj.uselib = 'XML OSX PANGOMM' obj.use = 'libardour libardour_cp libardour_midisurface libgtkmm2ext libpbd' obj.install_path = os.path.join(bld.env['LIBDIR'], 'surfaces') + if bld.is_defined('YTK'): + obj.use += ' libytkmm' + obj.uselib += ' GLIBMM GIOMM' + else: + obj.uselib += ' GTKMM' diff --git a/libs/surfaces/faderport8/wscript b/libs/surfaces/faderport8/wscript index a2a438d76f..6b2c49fedf 100644 --- a/libs/surfaces/faderport8/wscript +++ b/libs/surfaces/faderport8/wscript @@ -25,9 +25,14 @@ def build(bld): obj.includes = [ '.' ] obj.name = 'libardour_faderport8' obj.target = 'ardour_faderport8' - obj.uselib = 'GTKMM GTK GDK XML OSX' + obj.uselib = 'XML OSX CAIROMM PANGOMM' obj.use = 'libardour libardour_cp libgtkmm2ext libpbd' obj.install_path = os.path.join(bld.env['LIBDIR'], 'surfaces') + if bld.is_defined('YTK'): + obj.use += ' libytkmm' + obj.uselib += ' GLIBMM GIOMM' + else: + obj.uselib += ' GTKMM' obj = bld(features = 'cxx cxxshlib') obj.source = list(fp8_16_sources) @@ -38,9 +43,14 @@ def build(bld): obj.includes = [ '.' ] obj.name = 'libardour_faderport16' obj.target = 'ardour_faderport16' - obj.uselib = 'GTKMM GTK GDK XML OSX' + obj.uselib = 'XML OSX CAIROMM PANGOMM' obj.use = 'libardour libardour_cp libgtkmm2ext libpbd' obj.install_path = os.path.join(bld.env['LIBDIR'], 'surfaces') + if bld.is_defined('YTK'): + obj.use += ' libytkmm' + obj.uselib += ' GLIBMM GIOMM' + else: + obj.uselib += ' GTKMM' obj = bld(features = 'cxx cxxshlib') obj.source = list(fp8_16_sources) @@ -51,6 +61,11 @@ def build(bld): obj.includes = [ '.' ] obj.name = 'libardour_faderport2' obj.target = 'ardour_faderport2' - obj.uselib = 'GTKMM GTK GDK XML OSX' + obj.uselib = 'XML OSX CAIROMM PANGOMM' obj.use = 'libardour libardour_cp libgtkmm2ext libpbd' obj.install_path = os.path.join(bld.env['LIBDIR'], 'surfaces') + if bld.is_defined('YTK'): + obj.use += ' libytkmm' + obj.uselib += ' GLIBMM GIOMM' + else: + obj.uselib += ' GTKMM' diff --git a/libs/surfaces/generic_midi/wscript b/libs/surfaces/generic_midi/wscript index 854a773063..c9f6b88544 100644 --- a/libs/surfaces/generic_midi/wscript +++ b/libs/surfaces/generic_midi/wscript @@ -24,6 +24,11 @@ def build(bld): obj.includes = [ '.', './generic_midi'] obj.name = 'libardour_generic_midi' obj.target = 'ardour_generic_midi' - obj.uselib = 'GTKMM GTK GDK XML OSX' + obj.uselib = 'XML OSX' obj.use = 'libardour libardour_cp libgtkmm2ext libpbd' obj.install_path = os.path.join(bld.env['LIBDIR'], 'surfaces') + if bld.is_defined('YTK'): + obj.use += ' libytkmm' + obj.uselib += ' GLIBMM GIOMM PANGOMM' + else: + obj.uselib += ' GTKMM' diff --git a/libs/surfaces/launch_control_xl/wscript b/libs/surfaces/launch_control_xl/wscript index 6069b6810f..a6321d4ae7 100644 --- a/libs/surfaces/launch_control_xl/wscript +++ b/libs/surfaces/launch_control_xl/wscript @@ -23,6 +23,11 @@ def build(bld): obj.includes = ['.', './launch_control_xl'] obj.name = 'libardour_launch_control_xl' obj.target = 'ardour_launch_control_xl' - obj.uselib = 'GTKMM SIGCPP XML OSX' + obj.uselib = 'SIGCPP XML OSX PANGOMM' obj.use = 'libardour libardour_cp libpbd libevoral libcanvas libtemporal' obj.install_path = os.path.join(bld.env['LIBDIR'], 'surfaces') + if bld.is_defined('YTK'): + obj.use += ' libytkmm' + obj.uselib += ' GLIBMM GIOMM' + else: + obj.uselib += ' GTKMM' diff --git a/libs/surfaces/launchpad_pro/wscript b/libs/surfaces/launchpad_pro/wscript index d465920eca..4586eca48c 100644 --- a/libs/surfaces/launchpad_pro/wscript +++ b/libs/surfaces/launchpad_pro/wscript @@ -22,9 +22,11 @@ def build(bld): obj.includes = ['.', '..', './launchpad_pro'] obj.name = 'libardour_launchpad_pro' obj.target = 'ardour_launchpad_pro' - obj.uselib = 'CAIROMM PANGOMM USB GTKMM SIGCPP XML OSX' + obj.uselib = 'CAIROMM PANGOMM USB SIGCPP XML OSX' obj.use = 'libardour libardour_cp libardour_midisurface libgtkmm2ext libpbd libevoral libcanvas libtemporal' obj.install_path = os.path.join(bld.env['LIBDIR'], 'surfaces') - -def shutdown(): - autowaf.shutdown() + if bld.is_defined('YTK'): + obj.use += ' libytkmm' + obj.uselib += ' GLIBMM GIOMM' + else: + obj.uselib += ' GTKMM' diff --git a/libs/surfaces/launchpad_x/wscript b/libs/surfaces/launchpad_x/wscript index 5d16922e55..f5588ce632 100644 --- a/libs/surfaces/launchpad_x/wscript +++ b/libs/surfaces/launchpad_x/wscript @@ -25,9 +25,14 @@ def build(bld): obj.includes = ['.', ] obj.name = 'libardour_launchpad_mini' obj.target = 'ardour_launchpad_mini' - obj.uselib = 'CAIROMM PANGOMM USB GTKMM SIGCPP XML OSX' + obj.uselib = 'CAIROMM PANGOMM USB SIGCPP XML OSX' obj.use = 'libardour libardour_cp libardour_midisurface libgtkmm2ext libpbd libevoral libcanvas libtemporal' obj.install_path = os.path.join(bld.env['LIBDIR'], 'surfaces') + if bld.is_defined('YTK'): + obj.use += ' libytkmm' + obj.uselib += ' GLIBMM GIOMM' + else: + obj.uselib += ' GTKMM' obj = bld(features = 'cxx cxxshlib') obj.source = list(lpxm_sources) @@ -37,9 +42,11 @@ def build(bld): obj.includes = ['.', ] obj.name = 'libardour_launchpad_x' obj.target = 'ardour_launchpad_x' - obj.uselib = 'CAIROMM PANGOMM USB GTKMM SIGCPP XML OSX' + obj.uselib = 'CAIROMM PANGOMM USB SIGCPP XML OSX' obj.use = 'libardour libardour_cp libardour_midisurface libgtkmm2ext libpbd libevoral libcanvas libtemporal' obj.install_path = os.path.join(bld.env['LIBDIR'], 'surfaces') - -def shutdown(): - autowaf.shutdown() + if bld.is_defined('YTK'): + obj.use += ' libytkmm' + obj.uselib += ' GLIBMM GIOMM' + else: + obj.uselib += ' GTKMM' diff --git a/libs/surfaces/mackie/wscript b/libs/surfaces/mackie/wscript index 73bd629e3f..2345d04a66 100644 --- a/libs/surfaces/mackie/wscript +++ b/libs/surfaces/mackie/wscript @@ -38,9 +38,14 @@ def build(bld): obj.includes = [ '.' ] obj.name = 'libardour_mcp' obj.target = 'ardour_mcp' - obj.uselib = 'GTKMM XML OSX' + obj.uselib = 'XML OSX PANGOMM' obj.use = 'libardour libardour_cp libgtkmm2ext' obj.install_path = os.path.join(bld.env['LIBDIR'], 'surfaces') + if bld.is_defined('YTK'): + obj.use += ' libytkmm' + obj.uselib += ' GLIBMM GIOMM' + else: + obj.uselib += ' GTKMM' obj = bld(features = 'cxx cxxshlib') obj.source = list(mackie_sources) @@ -51,6 +56,11 @@ def build(bld): obj.includes = [ '.' ] obj.name = 'libardour_ssl_uf8' obj.target = 'ardour_ssl_uf8' - obj.uselib = 'GTKMM XML OSX' + obj.uselib = 'XML OSX PANGOMM' obj.use = 'libardour libardour_cp libgtkmm2ext' obj.install_path = os.path.join(bld.env['LIBDIR'], 'surfaces') + if bld.is_defined('YTK'): + obj.use += ' libytkmm' + obj.uselib += ' GLIBMM GIOMM' + else: + obj.uselib += ' GTKMM' diff --git a/libs/surfaces/maschine2/wscript b/libs/surfaces/maschine2/wscript index ede8bd041b..f2e37b9e76 100644 --- a/libs/surfaces/maschine2/wscript +++ b/libs/surfaces/maschine2/wscript @@ -30,6 +30,11 @@ def build(bld): obj.includes = [ '.', './maschine2'] obj.name = 'libardour_maschine2' obj.target = 'ardour_maschine2' - obj.uselib = 'CAIROMM PANGOMM GTKMM GTK XML OSX' + obj.uselib = 'CAIROMM PANGOMM XML OSX' obj.use = 'libardour libardour_cp libpbd libcanvas hidapi libgtkmm2ext' obj.install_path = os.path.join(bld.env['LIBDIR'], 'surfaces') + if bld.is_defined('YTK'): + obj.use += ' libytkmm' + obj.uselib += ' GLIBMM GIOMM' + else: + obj.uselib += ' GTKMM' diff --git a/libs/surfaces/osc/wscript b/libs/surfaces/osc/wscript index 89649e0dc7..859dc700c7 100644 --- a/libs/surfaces/osc/wscript +++ b/libs/surfaces/osc/wscript @@ -24,6 +24,11 @@ def build(bld): obj.includes = ['.', './osc'] obj.name = 'libardour_osc' obj.target = 'ardour_osc' - obj.uselib = 'LO GTKMM GTK GDK XML OSX' + obj.uselib = 'LO XML OSX' obj.use = 'libardour libardour_cp libgtkmm2ext libpbd' obj.install_path = os.path.join(bld.env['LIBDIR'], 'surfaces') + if bld.is_defined('YTK'): + obj.use += ' libytkmm' + obj.uselib += ' GLIBMM GIOMM PANGOMM' + else: + obj.uselib += ' GTKMM' diff --git a/libs/surfaces/push2/wscript b/libs/surfaces/push2/wscript index 395770a7c9..6c7b8ff9c9 100644 --- a/libs/surfaces/push2/wscript +++ b/libs/surfaces/push2/wscript @@ -36,6 +36,11 @@ def build(bld): obj.includes = ['.', '..', './push2'] obj.name = 'libardour_push2' obj.target = 'ardour_push2' - obj.uselib = 'CAIROMM PANGOMM USB GTKMM SIGCPP XML OSX' + obj.uselib = 'CAIROMM PANGOMM USB SIGCPP XML OSX' obj.use = 'libardour libardour_cp libardour_midisurface libgtkmm2ext libpbd libevoral libcanvas libtemporal' obj.install_path = os.path.join(bld.env['LIBDIR'], 'surfaces') + if bld.is_defined('YTK'): + obj.use += ' libytkmm' + obj.uselib += ' GLIBMM GIOMM' + else: + obj.uselib += ' GTKMM' diff --git a/libs/surfaces/us2400/wscript b/libs/surfaces/us2400/wscript index f5827264fe..a876c15394 100644 --- a/libs/surfaces/us2400/wscript +++ b/libs/surfaces/us2400/wscript @@ -35,6 +35,11 @@ def build(bld): obj.includes = [ '.' ] obj.name = 'libardour_us2400' obj.target = 'ardour_us2400' - obj.uselib = 'GTKMM XML OSX' + obj.uselib = 'XML OSX PANGOMM' obj.use = 'libardour libardour_cp libgtkmm2ext' obj.install_path = os.path.join(bld.env['LIBDIR'], 'surfaces') + if bld.is_defined('YTK'): + obj.use += ' libytkmm' + obj.uselib += ' GLIBMM GIOMM' + else: + obj.uselib += ' GTKMM' diff --git a/libs/surfaces/wiimote/wscript b/libs/surfaces/wiimote/wscript index 99a8f160ae..76b4c424c1 100644 --- a/libs/surfaces/wiimote/wscript +++ b/libs/surfaces/wiimote/wscript @@ -18,6 +18,11 @@ def build(bld): obj.includes = ['.', '../libs'] obj.name = 'libardour_wiimote' obj.target = 'ardour_wiimote' - obj.uselib = 'GTKMM CWIID XML' + obj.uselib = 'CWIID XML' obj.use = 'libardour libardour_cp libgtkmm2ext' obj.install_path = os.path.join(bld.env['LIBDIR'], 'surfaces') + if bld.is_defined('YTK'): + obj.use += 'libytkmm' + obj.uselib += ' GLIBMM GIOMM PANGOMM' + else: + obj.uselib += ' GTKMM' diff --git a/libs/tk/suil/cocoa_in_gtk2.mm b/libs/tk/suil/cocoa_in_gtk2.mm new file mode 100644 index 0000000000..4d3d4be3c1 --- /dev/null +++ b/libs/tk/suil/cocoa_in_gtk2.mm @@ -0,0 +1,439 @@ +/* + Copyright 2011-2017 David Robillard + Copyright 2014 Robin Gareus + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#include "suil_internal.h" + +#include "lv2/options/options.h" +#include "lv2/urid/urid.h" + +#include +#include + +#include + +#ifndef MAC_OS_X_VERSION_10_12 +#define MAC_OS_X_VERSION_10_12 101200 +#endif + +#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_12 +#define NSEventTypeFlagsChanged NSFlagsChanged +#define NSEventTypeLeftMouseDown NSLeftMouseDown +#define NSEventTypeLeftMouseDragged NSLeftMouseDragged +#define NSEventTypeLeftMouseUp NSLeftMouseUp +#define NSEventTypeMouseEntered NSMouseEntered +#define NSEventTypeMouseExited NSMouseExited +#define NSEventTypeMouseMoved NSMouseMoved +#define NSEventTypeRightMouseDown NSRightMouseDown +#define NSEventTypeRightMouseUp NSRightMouseUp +#define NSEventTypeScrollWheel NSScrollWheel +#endif + +extern "C" { + +#define SUIL_TYPE_COCOA_WRAPPER (suil_cocoa_wrapper_get_type()) +#define SUIL_COCOA_WRAPPER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), SUIL_TYPE_COCOA_WRAPPER, SuilCocoaWrapper)) + +typedef struct _SuilCocoaWrapper SuilCocoaWrapper; +typedef struct _SuilCocoaWrapperClass SuilCocoaWrapperClass; + +struct _SuilCocoaWrapper { + GtkWidget widget; + SuilWrapper* wrapper; + SuilInstance* instance; + + GdkWindow* flt_win; + bool custom_size; + bool mapped; + int req_width; + int req_height; + int alo_width; + int alo_height; + + const LV2UI_Idle_Interface* idle_iface; + guint idle_id; + guint idle_ms; +}; + +struct _SuilCocoaWrapperClass { + GtkWidgetClass parent_class; +}; + +GType suil_cocoa_wrapper_get_type(void); // Accessor for SUIL_TYPE_COCOA_WRAPPER + +G_DEFINE_TYPE(SuilCocoaWrapper, suil_cocoa_wrapper, GTK_TYPE_WIDGET) + +static void +suil_cocoa_wrapper_finalize(GObject* gobject) +{ + SuilCocoaWrapper* const self = SUIL_COCOA_WRAPPER(gobject); + + self->wrapper->impl = NULL; + + G_OBJECT_CLASS(suil_cocoa_wrapper_parent_class)->finalize(gobject); +} + +static void +suil_cocoa_realize(GtkWidget* widget) +{ + SuilCocoaWrapper* const self = SUIL_COCOA_WRAPPER(widget); + g_return_if_fail(self != NULL); + + GTK_WIDGET_SET_FLAGS(widget, GTK_REALIZED); + + GdkWindowAttr attrs; + attrs.x = widget->allocation.x; + attrs.y = widget->allocation.y; + attrs.width = widget->allocation.width; + attrs.height = widget->allocation.height; + attrs.wclass = GDK_INPUT_OUTPUT; + attrs.window_type = GDK_WINDOW_CHILD; + attrs.visual = gtk_widget_get_visual(widget); + attrs.colormap = gtk_widget_get_colormap(widget); + attrs.event_mask = gtk_widget_get_events(widget) | + GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | + GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK | + GDK_POINTER_MOTION_HINT_MASK; + + widget->window = gdk_window_new( + widget->parent->window, + &attrs, + GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP); + + widget->style = gtk_style_attach(widget->style, widget->window); + + gdk_window_set_user_data(widget->window, widget); + gtk_style_set_background(widget->style, widget->window, GTK_STATE_ACTIVE); + gtk_widget_queue_resize(widget); +} + +static void +suil_cocoa_size_request(GtkWidget* widget, GtkRequisition* requisition) +{ + SuilCocoaWrapper* const self = SUIL_COCOA_WRAPPER(widget); + if (self->custom_size) { + requisition->width = self->req_width; + requisition->height = self->req_height; + } else { + NSView* view = (NSView*)self->instance->ui_widget; + NSRect frame = [view frame]; + requisition->width = CGRectGetWidth(NSRectToCGRect(frame)); + requisition->height = CGRectGetHeight(NSRectToCGRect(frame)); + } +} + +static void +suil_cocoa_size_allocate(GtkWidget* widget, GtkAllocation* allocation) +{ + SuilCocoaWrapper* const self = SUIL_COCOA_WRAPPER(widget); + self->alo_width = allocation->width; + self->alo_height = allocation->height; + + if (!self->mapped) { + return; + } + + gint xx, yy; + gtk_widget_translate_coordinates( + gtk_widget_get_parent(widget), widget, 0, 0, &xx, &yy); + + NSView* view = (NSView*)self->instance->ui_widget; + [view setFrame:NSMakeRect(xx, yy, self->alo_width, self->alo_height)]; +} + +static void +suil_cocoa_map(GtkWidget* widget) +{ + SuilCocoaWrapper* const self = SUIL_COCOA_WRAPPER(widget); + self->mapped = true; + + if (self->alo_width == 0 || self->alo_height ==0) { + return; + } + + gint xx, yy; + gtk_widget_translate_coordinates( + gtk_widget_get_parent(widget), widget, 0, 0, &xx, &yy); + + NSView* view = (NSView*)self->instance->ui_widget; + [view setHidden:NO]; + [view setFrame:NSMakeRect(xx, yy, self->alo_width, self->alo_height)]; +} + +static void +suil_cocoa_unmap(GtkWidget* widget) +{ + SuilCocoaWrapper* const self = SUIL_COCOA_WRAPPER(widget); + NSView* view = (NSView*)self->instance->ui_widget; + + self->mapped = false; + [view setHidden:YES]; +} + +static gboolean +suil_cocoa_key_press(GtkWidget* widget, GdkEventKey* event) +{ + SuilCocoaWrapper* const self = SUIL_COCOA_WRAPPER(widget); + if (!self->instance || !self->wrapper || !self->wrapper->impl) { + return FALSE; + } + NSEvent* nsevent = gdk_quartz_event_get_nsevent((GdkEvent*)event); + NSView* view = (NSView*)self->instance->ui_widget; + [view keyDown:nsevent]; + return TRUE; +} + +static gboolean +suil_cocoa_key_release(GtkWidget* widget, GdkEventKey* event) +{ + SuilCocoaWrapper* const self = SUIL_COCOA_WRAPPER(widget); + if (!self->instance || !self->wrapper || !self->wrapper->impl) { + return FALSE; + } + NSEvent* nsevent = gdk_quartz_event_get_nsevent((GdkEvent*)event); + NSView* view = (NSView*)self->instance->ui_widget; + [view keyUp:nsevent]; + return TRUE; +} + +static gboolean +suil_cocoa_expose(GtkWidget* widget, GdkEventExpose* event) +{ + SuilCocoaWrapper* const self = SUIL_COCOA_WRAPPER(widget); + NSView* view = (NSView*)self->instance->ui_widget; + [view drawRect:NSMakeRect(event->area.x, + event->area.y, + event->area.width, + event->area.height)]; + return TRUE; +} + +static void +suil_cocoa_wrapper_class_init(SuilCocoaWrapperClass* klass) +{ + GObjectClass* const gobject_class = G_OBJECT_CLASS(klass); + GtkWidgetClass* const widget_class = (GtkWidgetClass*)(klass); + + gobject_class->finalize = suil_cocoa_wrapper_finalize; + + widget_class->realize = suil_cocoa_realize; + widget_class->expose_event = suil_cocoa_expose; + widget_class->size_request = suil_cocoa_size_request; + widget_class->size_allocate = suil_cocoa_size_allocate; + widget_class->map = suil_cocoa_map; + widget_class->unmap = suil_cocoa_unmap; + widget_class->key_press_event = suil_cocoa_key_press; + widget_class->key_release_event = suil_cocoa_key_release; +} + +static void +suil_cocoa_wrapper_init(SuilCocoaWrapper* self) +{ + self->wrapper = NULL; + self->instance = NULL; + self->flt_win = NULL; + self->custom_size = false; + self->mapped = false; + self->req_width = self->req_height = 0; + self->alo_width = self->alo_height = 0; + self->idle_iface = NULL; + self->idle_ms = 1000 / 30; // 30 Hz default +} + +static int +wrapper_resize(LV2UI_Feature_Handle handle, int width, int height) +{ + SuilCocoaWrapper* const wrap = SUIL_COCOA_WRAPPER(handle); + wrap->req_width = width; + wrap->req_height = height; + wrap->custom_size = true; + gtk_widget_queue_resize(GTK_WIDGET(handle)); + return 0; +} + +static gboolean +suil_cocoa_wrapper_idle(void* data) +{ + SuilCocoaWrapper* const wrap = SUIL_COCOA_WRAPPER(data); + wrap->idle_iface->idle(wrap->instance->handle); + return TRUE; // Continue calling +} + +static GdkFilterReturn +event_filter(GdkXEvent* xevent, GdkEvent* event, gpointer data) +{ + SuilCocoaWrapper* wrap = (SuilCocoaWrapper*)data; + if (!wrap->instance || !wrap->wrapper || !wrap->wrapper->impl) { + return GDK_FILTER_CONTINUE; + } + + NSEvent* nsevent = (NSEvent*)xevent; + NSView* view = (NSView*)wrap->instance->ui_widget; + if (view && nsevent) { + switch([nsevent type]) { + case NSEventTypeFlagsChanged: + [view flagsChanged:nsevent]; + return GDK_FILTER_REMOVE; +#if 0 + case NSEventTypeMouseEntered: + [view mouseEntered:nsevent]; + return GDK_FILTER_REMOVE; + case NSEventTypeMouseExited: + [view mouseExited:nsevent]; + return GDK_FILTER_REMOVE; + + /* Explicitly pass though mouse events. Needed for mouse-drags leaving + the window, and mouse-up after that. */ + case NSEventTypeMouseMoved: + [view mouseMoved:nsevent]; + break; + case NSEventTypeLeftMouseDragged: + [view mouseDragged:nsevent]; + break; + case NSEventTypeLeftMouseDown: + [view mouseDown:nsevent]; + break; + case NSEventTypeLeftMouseUp: + [view mouseUp:nsevent]; + break; + case NSEventTypeRightMouseDown: + [view rightMouseDown:nsevent]; + break; + case NSEventTypeRightMouseUp: + [view rightMouseUp:nsevent]; + break; + case NSEventTypeScrollWheel: + [view scrollWheel:nsevent]; + break; +#endif + default: + break; + } + } + return GDK_FILTER_CONTINUE; +} + +static int +wrapper_wrap(SuilWrapper* wrapper, SuilInstance* instance) +{ + SuilCocoaWrapper* const wrap = SUIL_COCOA_WRAPPER(wrapper->impl); + + instance->host_widget = GTK_WIDGET(wrap); + wrap->wrapper = wrapper; + wrap->instance = instance; + + const LV2UI_Idle_Interface* idle_iface = NULL; + if (instance->descriptor->extension_data) { + idle_iface = (const LV2UI_Idle_Interface*) + instance->descriptor->extension_data(LV2_UI__idleInterface); + } + if (idle_iface) { + wrap->idle_iface = idle_iface; + wrap->idle_id = g_timeout_add( + wrap->idle_ms, suil_cocoa_wrapper_idle, wrap); + } + + return 0; +} + +static void +wrapper_free(SuilWrapper* wrapper) +{ + if (wrapper->impl) { + SuilCocoaWrapper* const wrap = SUIL_COCOA_WRAPPER(wrapper->impl); + if (wrap->idle_id) { + g_source_remove(wrap->idle_id); + wrap->idle_id = 0; + } + + gdk_window_remove_filter(wrap->flt_win, event_filter, wrapper->impl); + gtk_object_destroy(GTK_OBJECT(wrap)); + } +} + + +SUIL_LIB_EXPORT +SuilWrapper* +suil_wrapper_new(SuilHost* host, + const char* host_type_uri, + const char* ui_type_uri, + LV2_Feature*** features, + unsigned n_features) +{ + GtkWidget* parent = NULL; + for (unsigned i = 0; i < n_features; ++i) { + if (!strcmp((*features)[i]->URI, LV2_UI__parent)) { + parent = (GtkWidget*)(*features)[i]->data; + } + } + + if (!GTK_CONTAINER(parent)) { + SUIL_ERRORF("No GtkContainer parent given for %s UI\n", + ui_type_uri); + return NULL; + } + + SuilWrapper* wrapper = (SuilWrapper*)calloc(1, sizeof(SuilWrapper)); + wrapper->wrap = wrapper_wrap; + wrapper->free = wrapper_free; + + SuilCocoaWrapper* const wrap = SUIL_COCOA_WRAPPER( + g_object_new(SUIL_TYPE_COCOA_WRAPPER, NULL)); + + wrapper->impl = wrap; + wrapper->resize.handle = wrap; + wrapper->resize.ui_resize = wrapper_resize; + + gtk_container_add(GTK_CONTAINER(parent), GTK_WIDGET(wrap)); + gtk_widget_set_can_focus(GTK_WIDGET(wrap), TRUE); + gtk_widget_set_sensitive(GTK_WIDGET(wrap), TRUE); + gtk_widget_realize(GTK_WIDGET(wrap)); + + GdkWindow* window = gtk_widget_get_window(GTK_WIDGET(wrap)); + wrap->flt_win = gtk_widget_get_window(parent); + gdk_window_add_filter(wrap->flt_win, event_filter, wrap); + + NSView* parent_view = gdk_quartz_window_get_nsview(window); + suil_add_feature(features, &n_features, LV2_UI__parent, parent_view); + suil_add_feature(features, &n_features, LV2_UI__resize, &wrapper->resize); + suil_add_feature(features, &n_features, LV2_UI__idleInterface, NULL); + + // Scan for URID map and options + LV2_URID_Map* map = NULL; + LV2_Options_Option* options = NULL; + for (LV2_Feature** f = *features; *f && (!map || !options); ++f) { + if (!strcmp((*f)->URI, LV2_OPTIONS__options)) { + options = (LV2_Options_Option*)(*f)->data; + } else if (!strcmp((*f)->URI, LV2_URID__map)) { + map = (LV2_URID_Map*)(*f)->data; + } + } + + if (map && options) { + // Set UI update rate if given + LV2_URID ui_updateRate = map->map(map->handle, LV2_UI__updateRate); + for (LV2_Options_Option* o = options; o->key; ++o) { + if (o->key == ui_updateRate) { + wrap->idle_ms = 1000.0f / *(const float*)o->value; + break; + } + } + } + + return wrapper; +} + +} // extern "C" diff --git a/libs/tk/suil/dylib.h b/libs/tk/suil/dylib.h new file mode 100644 index 0000000000..246693c5e3 --- /dev/null +++ b/libs/tk/suil/dylib.h @@ -0,0 +1,78 @@ +/* + Copyright 2020 David Robillard + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#ifndef SUIL_DYLIB_H +#define SUIL_DYLIB_H + +#ifdef _WIN32 + +#include + +enum DylibFlags { + DYLIB_GLOBAL = 0, + DYLIB_LAZY = 1, + DYLIB_NOW = 2, +}; + +static inline void* +dylib_open(const char* const filename, const int flags) +{ + return LoadLibrary(filename); +} + +static inline int +dylib_close(void* const handle) +{ + return !FreeLibrary((HMODULE)handle); +} + +static inline const char* +dylib_error(void) +{ + return "Unknown error"; +} + +#else + +#include + +enum DylibFlags { + DYLIB_GLOBAL = RTLD_GLOBAL, + DYLIB_LAZY = RTLD_LAZY, + DYLIB_NOW = RTLD_NOW, +}; + +static inline void* +dylib_open(const char* const filename, const int flags) +{ + return dlopen(filename, flags); +} + +static inline int +dylib_close(void* const handle) +{ + return dlclose(handle); +} + +static inline const char* +dylib_error(void) +{ + return dlerror(); +} + +#endif + +#endif // SUIL_DYLIB_H diff --git a/libs/tk/suil/host.c b/libs/tk/suil/host.c new file mode 100644 index 0000000000..90efceb6d5 --- /dev/null +++ b/libs/tk/suil/host.c @@ -0,0 +1,98 @@ +/* + Copyright 2011-2017 David Robillard + Copyright 2017 Stefan Westerfeld + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#include "dylib.h" +#include "suil_config.h" +#include "suil_internal.h" + +#include "suil/suil.h" + +#include + +int suil_argc = 0; +char** suil_argv = NULL; + +SUIL_API +SuilHost* +suil_host_new(SuilPortWriteFunc write_func, + SuilPortIndexFunc index_func, + SuilPortSubscribeFunc subscribe_func, + SuilPortUnsubscribeFunc unsubscribe_func) +{ + SuilHost* host = (SuilHost*)calloc(1, sizeof(struct SuilHostImpl)); + host->write_func = write_func; + host->index_func = index_func; + host->subscribe_func = subscribe_func; + host->unsubscribe_func = unsubscribe_func; + host->argc = suil_argc; + host->argv = suil_argv; + return host; +} + +SUIL_API +void +suil_host_set_touch_func(SuilHost* host, + SuilTouchFunc touch_func) +{ + host->touch_func = touch_func; +} + +SUIL_API +void +suil_host_free(SuilHost* host) +{ + if (host) { + if (host->gtk_lib) { + dylib_close(host->gtk_lib); + } + free(host); + } +} + +#ifdef SUIL_WITH_X11 +static void +suil_load_init_module(const char* module_name) +{ + void* const lib = suil_open_module(module_name); + if (!lib) { + return; + } + + SuilVoidFunc init_func = suil_dlfunc(lib, "suil_host_init"); + if (init_func) { + (*init_func)(); + } else { + SUIL_ERRORF("Corrupt init module %s\n", module_name); + } + + dylib_close(lib); +} +#endif + +SUIL_API +void +suil_init(int* argc, char*** argv, SuilArg key, ...) +{ + (void)key; + + suil_argc = argc ? *argc : 0; + suil_argv = argv ? *argv : NULL; + +#ifdef SUIL_WITH_X11 + suil_load_init_module("suil_x11"); +#endif +} diff --git a/libs/tk/suil/instance.c b/libs/tk/suil/instance.c new file mode 100644 index 0000000000..3cf5e06fce --- /dev/null +++ b/libs/tk/suil/instance.c @@ -0,0 +1,409 @@ +/* + Copyright 2007-2017 David Robillard + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#include "dylib.h" +#include "suil_config.h" +#include "suil_internal.h" + +#include "lv2/core/lv2.h" +#include "lv2/ui/ui.h" +#include "suil/suil.h" + +#include +#include +#include +#include +#include + +#define GTK2_UI_URI LV2_UI__GtkUI +#define GTK3_UI_URI LV2_UI__Gtk3UI +#define QT4_UI_URI LV2_UI__Qt4UI +#define QT5_UI_URI LV2_UI__Qt5UI +#define X11_UI_URI LV2_UI__X11UI +#define WIN_UI_URI LV2_UI_PREFIX "WindowsUI" +#define COCOA_UI_URI LV2_UI__CocoaUI + +SUIL_API +unsigned +suil_ui_supported(const char* host_type_uri, + const char* ui_type_uri) +{ + enum { + SUIL_WRAPPING_UNSUPPORTED = 0, + SUIL_WRAPPING_NATIVE = 1, + SUIL_WRAPPING_EMBEDDED = 2 + }; + + if (!strcmp(host_type_uri, ui_type_uri)) { + return SUIL_WRAPPING_NATIVE; + } + + if ((!strcmp(host_type_uri, GTK2_UI_URI) + && !strcmp(ui_type_uri, QT4_UI_URI)) + || (!strcmp(host_type_uri, GTK2_UI_URI) + && !strcmp(ui_type_uri, QT5_UI_URI)) + || (!strcmp(host_type_uri, QT4_UI_URI) + && !strcmp(ui_type_uri, GTK2_UI_URI)) + || (!strcmp(host_type_uri, QT5_UI_URI) + && !strcmp(ui_type_uri, GTK2_UI_URI)) + || (!strcmp(host_type_uri, GTK2_UI_URI) + && !strcmp(ui_type_uri, X11_UI_URI)) + || (!strcmp(host_type_uri, GTK3_UI_URI) + && !strcmp(ui_type_uri, X11_UI_URI)) + || (!strcmp(host_type_uri, GTK3_UI_URI) + && !strcmp(ui_type_uri, QT5_UI_URI)) + || (!strcmp(host_type_uri, GTK2_UI_URI) + && !strcmp(ui_type_uri, WIN_UI_URI)) + || (!strcmp(host_type_uri, GTK2_UI_URI) + && !strcmp(ui_type_uri, COCOA_UI_URI)) + || (!strcmp(host_type_uri, QT4_UI_URI) + && !strcmp(ui_type_uri, X11_UI_URI)) + || (!strcmp(host_type_uri, QT5_UI_URI) + && !strcmp(ui_type_uri, X11_UI_URI)) + || (!strcmp(host_type_uri, QT5_UI_URI) + && !strcmp(ui_type_uri, COCOA_UI_URI))) { + return SUIL_WRAPPING_EMBEDDED; + } + + return SUIL_WRAPPING_UNSUPPORTED; +} + +static SuilWrapper* +open_wrapper(SuilHost* host, + const char* container_type_uri, + const char* ui_type_uri, + LV2_Feature*** features, + unsigned n_features) +{ + const char* module_name = NULL; +#ifdef SUIL_WITH_GTK2_IN_QT4 + if (!strcmp(container_type_uri, QT4_UI_URI) + && !strcmp(ui_type_uri, GTK2_UI_URI)) { + module_name = "suil_gtk2_in_qt4"; + } +#endif +#ifdef SUIL_WITH_GTK2_IN_QT5 + if (!strcmp(container_type_uri, QT5_UI_URI) + && !strcmp(ui_type_uri, GTK2_UI_URI)) { + module_name = "suil_gtk2_in_qt5"; + } +#endif +#ifdef SUIL_WITH_QT4_IN_GTK2 + if (!strcmp(container_type_uri, GTK2_UI_URI) + && !strcmp(ui_type_uri, QT4_UI_URI)) { + module_name = "suil_qt4_in_gtk2"; + } +#endif +#ifdef SUIL_WITH_QT5_IN_GTK2 + if (!strcmp(container_type_uri, GTK2_UI_URI) + && !strcmp(ui_type_uri, QT5_UI_URI)) { + module_name = "suil_qt5_in_gtk2"; + } +#endif +#ifdef SUIL_WITH_X11_IN_GTK2 + if (!strcmp(container_type_uri, GTK2_UI_URI) + && !strcmp(ui_type_uri, X11_UI_URI)) { + module_name = "suil_x11_in_gtk2"; + } +#endif +#ifdef SUIL_WITH_X11_IN_GTK3 + if (!strcmp(container_type_uri, GTK3_UI_URI) + && !strcmp(ui_type_uri, X11_UI_URI)) { + module_name = "suil_x11_in_gtk3"; + } +#endif +#ifdef SUIL_WITH_QT5_IN_GTK3 + if (!strcmp(container_type_uri, GTK3_UI_URI) + && !strcmp(ui_type_uri, QT5_UI_URI)) { + module_name = "suil_qt5_in_gtk3"; + } +#endif +#ifdef SUIL_WITH_WIN_IN_GTK2 + if (!strcmp(container_type_uri, GTK2_UI_URI) + && !strcmp(ui_type_uri, WIN_UI_URI)) { + module_name = "suil_win_in_gtk2"; + } +#endif +#ifdef SUIL_WITH_COCOA_IN_GTK2 + if (!strcmp(container_type_uri, GTK2_UI_URI) + && !strcmp(ui_type_uri, COCOA_UI_URI)) { + module_name = "suil_cocoa_in_gtk2"; + } +#endif +#ifdef SUIL_WITH_X11_IN_QT4 + if (!strcmp(container_type_uri, QT4_UI_URI) + && !strcmp(ui_type_uri, X11_UI_URI)) { + module_name = "suil_x11_in_qt4"; + } +#endif +#ifdef SUIL_WITH_X11_IN_QT5 + if (!strcmp(container_type_uri, QT5_UI_URI) + && !strcmp(ui_type_uri, X11_UI_URI)) { + module_name = "suil_x11_in_qt5"; + } +#endif +#ifdef SUIL_WITH_COCOA_IN_QT5 + if (!strcmp(container_type_uri, QT5_UI_URI) + && !strcmp(ui_type_uri, COCOA_UI_URI)) { + module_name = "suil_cocoa_in_qt5"; + } +#endif + + if (!module_name) { + SUIL_ERRORF("Unable to wrap UI type <%s> as type <%s>\n", + ui_type_uri, container_type_uri); + return NULL; + } + + void* const lib = suil_open_module(module_name); + if (!lib) { + return NULL; + } + + SuilWrapperNewFunc wrapper_new = (SuilWrapperNewFunc)suil_dlfunc( + lib, "suil_wrapper_new"); + + SuilWrapper* wrapper = wrapper_new + ? wrapper_new(host, + container_type_uri, + ui_type_uri, + features, + n_features) + : NULL; + + if (wrapper) { + wrapper->lib = lib; + } else { + SUIL_ERRORF("Corrupt wrap module %s\n", module_name); + dylib_close(lib); + } + + return wrapper; +} + +SUIL_API +SuilInstance* +suil_instance_new(SuilHost* host, + SuilController controller, + const char* container_type_uri, + const char* plugin_uri, + const char* ui_uri, + const char* ui_type_uri, + const char* ui_bundle_path, + const char* ui_binary_path, + const LV2_Feature* const* features) +{ + // Open UI library + dylib_error(); + void* lib = dylib_open(ui_binary_path, DYLIB_NOW); + if (!lib) { + SUIL_ERRORF("Unable to open UI library %s (%s)\n", + ui_binary_path, dylib_error()); + return NULL; + } + + // Get discovery function + LV2UI_DescriptorFunction df = (LV2UI_DescriptorFunction) + suil_dlfunc(lib, "lv2ui_descriptor"); + if (!df) { + SUIL_ERRORF("Broken LV2 UI %s (no lv2ui_descriptor symbol found)\n", + ui_binary_path); + dylib_close(lib); + return NULL; + } + + // Get UI descriptor + const LV2UI_Descriptor* descriptor = NULL; + for (uint32_t i = 0; true; ++i) { + const LV2UI_Descriptor* ld = df(i); + if (!ld) { + break; + } + + if (!strcmp(ld->URI, ui_uri)) { + descriptor = ld; + break; + } + } + if (!descriptor) { + SUIL_ERRORF("Failed to find descriptor for <%s> in %s\n", + ui_uri, ui_binary_path); + dylib_close(lib); + return NULL; + } + + // Create SuilInstance + SuilInstance* instance = (SuilInstance*)calloc(1, sizeof(SuilInstance)); + if (!instance) { + SUIL_ERRORF("Failed to allocate memory for <%s> instance\n", ui_uri); + dylib_close(lib); + return NULL; + } + + instance->lib_handle = lib; + instance->descriptor = descriptor; + + // Make UI features array + instance->features = (LV2_Feature**)malloc(sizeof(LV2_Feature*)); + instance->features[0] = NULL; + + // Copy user provided features + const LV2_Feature* const* fi = features; + unsigned n_features = 0; + while (fi && *fi) { + const LV2_Feature* f = *fi++; + suil_add_feature(&instance->features, &n_features, f->URI, f->data); + } + + // Add additional features implemented by SuilHost functions + if (host->index_func) { + instance->port_map.handle = controller; + instance->port_map.port_index = host->index_func; + suil_add_feature(&instance->features, &n_features, + LV2_UI__portMap, &instance->port_map); + } + if (host->subscribe_func && host->unsubscribe_func) { + instance->port_subscribe.handle = controller; + instance->port_subscribe.subscribe = host->subscribe_func; + instance->port_subscribe.unsubscribe = host->unsubscribe_func; + suil_add_feature(&instance->features, &n_features, + LV2_UI__portSubscribe, &instance->port_subscribe); + } + if (host->touch_func) { + instance->touch.handle = controller; + instance->touch.touch = host->touch_func; + suil_add_feature(&instance->features, &n_features, + LV2_UI__touch, &instance->touch); + } + + // Open wrapper (this may add additional features) + if (container_type_uri && strcmp(container_type_uri, ui_type_uri)) { + instance->wrapper = open_wrapper(host, + container_type_uri, ui_type_uri, + &instance->features, n_features); + if (!instance->wrapper) { + suil_instance_free(instance); + return NULL; + } + } + + // Instantiate UI + instance->handle = descriptor->instantiate( + descriptor, + plugin_uri, + ui_bundle_path, + host->write_func, + controller, + &instance->ui_widget, + (const LV2_Feature* const*)instance->features); + + // Failed to instantiate UI + if (!instance->handle) { + SUIL_ERRORF("Failed to instantiate UI <%s> in %s\n", + ui_uri, ui_binary_path); + suil_instance_free(instance); + return NULL; + } + + if (instance->wrapper) { + if (instance->wrapper->wrap(instance->wrapper, instance)) { + SUIL_ERRORF("Failed to wrap UI <%s> in type <%s>\n", + ui_uri, container_type_uri); + suil_instance_free(instance); + return NULL; + } + } else { + instance->host_widget = instance->ui_widget; + } + + return instance; +} + +SUIL_API +void +suil_instance_free(SuilInstance* instance) +{ + if (instance) { + for (unsigned i = 0; instance->features[i]; ++i) { + free(instance->features[i]); + } + free(instance->features); + + // Call wrapper free function to destroy widgets and drop references + if (instance->wrapper && instance->wrapper->free) { + instance->wrapper->free(instance->wrapper); + } + + // Call cleanup to destroy UI (if it still exists at this point) + if (instance->handle) { + instance->descriptor->cleanup(instance->handle); + } + + dylib_close(instance->lib_handle); + + // Close libraries and free everything + if (instance->wrapper) { +#ifndef _WIN32 + // Never unload modules on windows, causes mysterious segfaults + dylib_close(instance->wrapper->lib); +#endif + free(instance->wrapper); + } + free(instance); + } +} + +SUIL_API +SuilHandle +suil_instance_get_handle(SuilInstance* instance) +{ + return instance->handle; +} + +SUIL_API +LV2UI_Widget +suil_instance_get_widget(SuilInstance* instance) +{ + return instance->host_widget; +} + +SUIL_API +void +suil_instance_port_event(SuilInstance* instance, + uint32_t port_index, + uint32_t buffer_size, + uint32_t format, + const void* buffer) +{ + if (instance->descriptor->port_event) { + instance->descriptor->port_event(instance->handle, + port_index, + buffer_size, + format, + buffer); + } +} + +SUIL_API +const void* +suil_instance_extension_data(SuilInstance* instance, + const char* uri) +{ + if (instance->descriptor->extension_data) { + return instance->descriptor->extension_data(uri); + } + return NULL; +} diff --git a/libs/tk/suil/suil/suil.h b/libs/tk/suil/suil/suil.h new file mode 100644 index 0000000000..48b418edd3 --- /dev/null +++ b/libs/tk/suil/suil/suil.h @@ -0,0 +1,299 @@ +/* + Copyright 2011-2017 David Robillard + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +/** + @file suil.h API for Suil, an LV2 UI wrapper library. +*/ + +#ifndef SUIL_SUIL_H +#define SUIL_SUIL_H + +#include "lv2/core/lv2.h" + +#include + +#ifdef _WIN32 +# define SUIL_LIB_IMPORT __declspec(dllimport) +# define SUIL_LIB_EXPORT __declspec(dllexport) +#else +# define SUIL_LIB_IMPORT __attribute__((visibility("default"))) +# define SUIL_LIB_EXPORT __attribute__((visibility("default"))) +#endif + +#ifdef SUIL_SHARED +# ifdef SUIL_INTERNAL +# define SUIL_API SUIL_LIB_EXPORT +# else +# define SUIL_API SUIL_LIB_IMPORT +# endif +#else +# define SUIL_API +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/** + @defgroup suil Suil + + A library for loading and wrapping LV2 plugin UIs. + + With Suil, a host written in one supported toolkit can embed a plugin UI + written in a different supported toolkit. Suil insulates hosts from toolkit + libraries used by plugin UIs. For example, a Gtk host can embed a Qt UI + without linking against Qt at compile time. + + Visit for more information. + + @{ +*/ + +/** + UI host descriptor. + + This contains the various functions that a plugin UI may use to communicate + with the plugin. It is passed to suil_instance_new() to provide these + functions to the UI. +*/ +typedef struct SuilHostImpl SuilHost; + +/** An instance of an LV2 plugin UI. */ +typedef struct SuilInstanceImpl SuilInstance; + +/** Opaque pointer to a UI handle. */ +typedef void* SuilHandle; + +/** Opaque pointer to a UI widget. */ +typedef void* SuilWidget; + +/** + UI controller. + + This is an opaque pointer passed by the user which is passed to the various + UI control functions (e.g. SuilPortWriteFunc). It is typically used to pass + a pointer to some controller object the host uses to communicate with + plugins. +*/ +typedef void* SuilController; + +/** Function to write/send a value to a port. */ +typedef void (*SuilPortWriteFunc)( + SuilController controller, + uint32_t port_index, + uint32_t buffer_size, + uint32_t protocol, + void const* buffer); + +/** Function to return the index for a port by symbol. */ +typedef uint32_t (*SuilPortIndexFunc)( + SuilController controller, + const char* port_symbol); + +/** Function to subscribe to notifications for a port. */ +typedef uint32_t (*SuilPortSubscribeFunc)( + SuilController controller, + uint32_t port_index, + uint32_t protocol, + const LV2_Feature* const* features); + +/** Function to unsubscribe from notifications for a port. */ +typedef uint32_t (*SuilPortUnsubscribeFunc)( + SuilController controller, + uint32_t port_index, + uint32_t protocol, + const LV2_Feature* const* features); + +/** Function called when a control is grabbed or released. */ +typedef void (*SuilTouchFunc)( + SuilController controller, + uint32_t port_index, + bool grabbed); + +/** Initialization argument. */ +typedef enum { + SUIL_ARG_NONE +} SuilArg; + +/** + Initialize suil. + + This function should be called as early as possible, before any other GUI + toolkit functions. The variable argument list is a sequence of SuilArg keys + and corresponding value pairs for passing any necessary platform-specific + information. It must be terminated with SUIL_ARG_NONE. +*/ +SUIL_API +void +suil_init(int* argc, char*** argv, SuilArg key, ...); + +/** + Create a new UI host descriptor. + @param write_func Function to send a value to a plugin port. + @param index_func Function to get the index for a port by symbol. + @param subscribe_func Function to subscribe to port updates. + @param unsubscribe_func Function to unsubscribe from port updates. +*/ +SUIL_API +SuilHost* +suil_host_new(SuilPortWriteFunc write_func, + SuilPortIndexFunc index_func, + SuilPortSubscribeFunc subscribe_func, + SuilPortUnsubscribeFunc unsubscribe_func); + +/** + Set a touch function for a host descriptor. + + Note this function will only be called if the UI supports it. +*/ +SUIL_API +void +suil_host_set_touch_func(SuilHost* host, + SuilTouchFunc touch_func); + +/** + Free `host`. +*/ +SUIL_API +void +suil_host_free(SuilHost* host); + +/** + Check if suil can wrap a UI type. + @param host_type_uri The URI of the desired widget type of the host, + corresponding to the `type_uri` parameter of suil_instance_new(). + @param ui_type_uri The URI of the UI widget type. + @return 0 if wrapping is unsupported, otherwise the quality of the wrapping + where 1 is the highest quality (direct native embedding with no wrapping) + and increasing values are of a progressively lower quality and/or stability. +*/ +SUIL_API +unsigned +suil_ui_supported(const char* host_type_uri, + const char* ui_type_uri); + +/** + Instantiate a UI for an LV2 plugin. + + This funcion may load a suil module to adapt the UI to the desired toolkit. + Suil is configured at compile time to load modules from the appropriate + place, but this can be changed at run-time via the environment variable + SUIL_MODULE_DIR. This makes it possible to bundle suil with an application. + + Note that some situations (Gtk in Qt, Windows in Gtk) require a parent + container to be passed as a feature with URI LV2_UI__parent + (http://lv2plug.in/ns/extensions/ui#ui) in order to work correctly. The + data must point to a single child container of the host widget set. + + @param host Host descriptor. + @param controller Opaque host controller pointer. + @param container_type_uri URI of the desired host container widget type. + @param plugin_uri URI of the plugin to instantiate this UI for. + @param ui_uri URI of the specifically desired UI. + @param ui_type_uri URI of the actual UI widget type. + @param ui_bundle_path Path of the UI bundle. + @param ui_binary_path Path of the UI binary. + @param features NULL-terminated array of supported features, or NULL. + @return A new UI instance, or NULL if instantiation failed. +*/ +SUIL_API +SuilInstance* +suil_instance_new(SuilHost* host, + SuilController controller, + const char* container_type_uri, + const char* plugin_uri, + const char* ui_uri, + const char* ui_type_uri, + const char* ui_bundle_path, + const char* ui_binary_path, + const LV2_Feature* const* features); + +/** + Free a plugin UI instance. + + The caller must ensure all references to the UI have been dropped before + calling this function (e.g. it has been removed from its parent). +*/ +SUIL_API +void +suil_instance_free(SuilInstance* instance); + +/** + Get the handle for a UI instance. + + Returns the handle to the UI instance. The returned handle has opaque type + to insulate the Suil API from LV2 extensions, but in pactice it is currently + of type `LV2UI_Handle`. This should not normally be needed. + + The returned handle is shared and must not be deleted. +*/ +SUIL_API +SuilHandle +suil_instance_get_handle(SuilInstance* instance); + +/** + Get the widget for a UI instance. + + Returns an opaque pointer to a widget, the type of which matches the + `container_type_uri` parameter of suil_instance_new(). Note this may be a + wrapper widget created by Suil, and not necessarily the widget directly + implemented by the UI. +*/ +SUIL_API +SuilWidget +suil_instance_get_widget(SuilInstance* instance); + +/** + Notify the UI about a change in a plugin port. + @param instance UI instance. + @param port_index Index of the port which has changed. + @param buffer_size Size of `buffer` in bytes. + @param format Format of `buffer` (mapped URI, or 0 for float). + @param buffer Change data, e.g. the new port value. + + This function can be used to notify the UI about any port change, but in the + simplest case is used to set the value of lv2:ControlPort ports. For + simplicity, this is a special case where `format` is 0, `buffer_size` is 4, + and `buffer` should point to a single float. + + The `buffer` must be valid only for the duration of this call, the UI must + not keep a reference to it. +*/ +SUIL_API +void +suil_instance_port_event(SuilInstance* instance, + uint32_t port_index, + uint32_t buffer_size, + uint32_t format, + const void* buffer); + +/** + Return a data structure defined by some LV2 extension URI. +*/ +SUIL_API +const void* +suil_instance_extension_data(SuilInstance* instance, + const char* uri); + +/** + @} +*/ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* SUIL_SUIL_H */ diff --git a/libs/tk/suil/suil_config.h b/libs/tk/suil/suil_config.h new file mode 100644 index 0000000000..f1629c62cb --- /dev/null +++ b/libs/tk/suil/suil_config.h @@ -0,0 +1,2 @@ +#pragma once +#define SUIL_VERSION "0.10.8" diff --git a/libs/tk/suil/suil_internal.h b/libs/tk/suil/suil_internal.h new file mode 100644 index 0000000000..c55e2eecb7 --- /dev/null +++ b/libs/tk/suil/suil_internal.h @@ -0,0 +1,175 @@ +/* + Copyright 2007-2017 David Robillard + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#ifndef SUIL_INTERNAL_H +#define SUIL_INTERNAL_H + +#include "dylib.h" +#include "suil_config.h" + +#include "lv2/ui/ui.h" +#include "suil/suil.h" + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define SUIL_ERRORF(fmt, ...) fprintf(stderr, "suil error: " fmt, __VA_ARGS__) + +struct SuilHostImpl { + SuilPortWriteFunc write_func; + SuilPortIndexFunc index_func; + SuilPortSubscribeFunc subscribe_func; + SuilPortUnsubscribeFunc unsubscribe_func; + SuilTouchFunc touch_func; + void* gtk_lib; + int argc; + char** argv; +}; + +struct _SuilWrapper; + +typedef void (*SuilWrapperFreeFunc)(struct _SuilWrapper*); + +typedef int (*SuilWrapperWrapFunc)(struct _SuilWrapper* wrapper, + SuilInstance* instance); + +typedef struct _SuilWrapper { + SuilWrapperWrapFunc wrap; + SuilWrapperFreeFunc free; + void* lib; + void* impl; + LV2UI_Resize resize; +} SuilWrapper; + +struct SuilInstanceImpl { + void* lib_handle; + const LV2UI_Descriptor* descriptor; + LV2UI_Handle handle; + SuilWrapper* wrapper; + LV2_Feature** features; + LV2UI_Port_Map port_map; + LV2UI_Port_Subscribe port_subscribe; + LV2UI_Touch touch; + SuilWidget ui_widget; + SuilWidget host_widget; +}; + +/** + The type of the suil_wrapper_new entry point in a wrapper module. + + This constructs a SuilWrapper which contains everything necessary + to wrap a widget, including a possibly extended features array to + be used for instantiating the UI. +*/ +typedef SuilWrapper* (*SuilWrapperNewFunc)(SuilHost* host, + const char* host_type_uri, + const char* ui_type_uri, + LV2_Feature*** features, + unsigned n_features); + +/** Prototype for suil_wrapper_new in each wrapper module. */ +SUIL_LIB_EXPORT +SuilWrapper* +suil_wrapper_new(SuilHost* host, + const char* host_type_uri, + const char* ui_type_uri, + LV2_Feature*** features, + unsigned n_features); + +/** Prototype for suil_host_init in each init module. */ +SUIL_LIB_EXPORT +void +suil_host_init(void); + +/** Dynamically load the suil module with the given name. */ +static inline void* +suil_open_module(const char* module_name) +{ + const char* const env_dir = getenv("SUIL_MODULE_DIR"); + const char* const mod_dir = env_dir ? env_dir : SUIL_MODULE_DIR; + const size_t path_len = strlen(mod_dir) + + strlen(SUIL_DIR_SEP SUIL_MODULE_PREFIX SUIL_MODULE_EXT) + + strlen(module_name) + + 2; + + char* const path = (char*)calloc(path_len, 1); + snprintf(path, path_len, "%s%s%s%s%s", + mod_dir, SUIL_DIR_SEP, + SUIL_MODULE_PREFIX, module_name, SUIL_MODULE_EXT); + + dylib_error(); + void* lib = dylib_open(path, DYLIB_NOW); + if (!lib) { + SUIL_ERRORF("Failed to open module %s (%s)\n", path, dylib_error()); + } + + free(path); + return lib; +} + +typedef void (*SuilVoidFunc)(void); + +/** dlsym wrapper to return a function pointer (without annoying warning) */ +static inline SuilVoidFunc +suil_dlfunc(void* handle, const char* symbol) +{ +#ifdef _WIN32 + return (SuilVoidFunc)GetProcAddress((HMODULE)handle, symbol); +#else + typedef SuilVoidFunc (*VoidFuncGetter)(void*, const char*); + VoidFuncGetter dlfunc = (VoidFuncGetter)dlsym; + return dlfunc(handle, symbol); +#endif +} + +/** Add a feature to a (mutable) LV2 feature array. */ +static inline void +suil_add_feature(LV2_Feature*** features, + unsigned* n, + const char* uri, + void* data) +{ + for (unsigned i = 0; i < *n && (*features)[i]; ++i) { + if (!strcmp((*features)[i]->URI, uri)) { + (*features)[i]->data = data; + return; + } + } + + *features = (LV2_Feature**)realloc(*features, + sizeof(LV2_Feature*) * (*n + 2)); + + (*features)[*n] = (LV2_Feature*)malloc(sizeof(LV2_Feature)); + (*features)[*n]->URI = uri; + (*features)[*n]->data = data; + (*features)[*n + 1] = NULL; + *n += 1; +} + +extern int suil_argc; +extern char** suil_argv; + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif // SUIL_INTERNAL_H diff --git a/libs/tk/suil/win_in_gtk2.cpp b/libs/tk/suil/win_in_gtk2.cpp new file mode 100644 index 0000000000..147586208b --- /dev/null +++ b/libs/tk/suil/win_in_gtk2.cpp @@ -0,0 +1,258 @@ +/* + Copyright 2011-2015 David Robillard + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#include "suil_internal.h" + +#include "lv2/options/options.h" +#include "lv2/urid/urid.h" + +#include +#include + +#ifndef WM_MOUSEWHEEL +# define WM_MOUSEWHEEL 0x020A +#endif +#ifndef WM_MOUSEHWHEEL +# define WM_MOUSEHWHEEL 0x020E +#endif + +#include + +extern "C" { + +#define SUIL_TYPE_WIN_WRAPPER (suil_win_wrapper_get_type()) +#define SUIL_WIN_WRAPPER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), SUIL_TYPE_WIN_WRAPPER, SuilWinWrapper)) + +typedef struct _SuilWinWrapper SuilWinWrapper; +typedef struct _SuilWinWrapperClass SuilWinWrapperClass; + +struct _SuilWinWrapper { + GtkDrawingArea area; + SuilWrapper* wrapper; + SuilInstance* instance; + GdkWindow* flt_win; + const LV2UI_Idle_Interface* idle_iface; + guint idle_id; + guint idle_ms; +}; + +struct _SuilWinWrapperClass { + GtkDrawingAreaClass parent_class; +}; + +GType suil_win_wrapper_get_type(void); // Accessor for SUIL_TYPE_WIN_WRAPPER + +G_DEFINE_TYPE(SuilWinWrapper, suil_win_wrapper, GTK_TYPE_DRAWING_AREA) + +static void +suil_win_wrapper_finalize(GObject* gobject) +{ + SuilWinWrapper* const self = SUIL_WIN_WRAPPER(gobject); + + self->wrapper->impl = NULL; + self->instance = NULL; + + G_OBJECT_CLASS(suil_win_wrapper_parent_class)->finalize(gobject); +} + +static void +suil_win_size_allocate(GtkWidget* widget, GtkAllocation* allocation) +{ + SuilWinWrapper* const self = SUIL_WIN_WRAPPER(widget); + g_return_if_fail(self != NULL); + + widget->allocation = *allocation; + if (gtk_widget_get_realized(widget)) { + gdk_window_move_resize(widget->window, + allocation->x, allocation->y, + allocation->width, allocation->height); + + RECT wr = { 0, 0, (long)allocation->width, (long)allocation->height }; + AdjustWindowRectEx(&wr, WS_CHILD, FALSE, WS_EX_TOPMOST); + + SetWindowPos((HWND)self->instance->ui_widget, HWND_NOTOPMOST, + 0, 0, wr.right - wr.left, wr.bottom - wr.top, + SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOOWNERZORDER|SWP_NOZORDER); + UpdateWindow((HWND)self->instance->ui_widget); + PostMessage((HWND)self->instance->ui_widget, WM_PAINT, 0, 0); + } +} + +static void +suil_win_wrapper_class_init(SuilWinWrapperClass* klass) +{ + GObjectClass* const gobject_class = G_OBJECT_CLASS(klass); + GtkWidgetClass* const widget_class = (GtkWidgetClass*)(klass); + + widget_class->size_allocate = suil_win_size_allocate; + gobject_class->finalize = suil_win_wrapper_finalize; +} + +static void +suil_win_wrapper_init(SuilWinWrapper* self) +{ + self->instance = NULL; + self->flt_win = NULL; + self->idle_iface = NULL; + self->idle_ms = 1000 / 30; // 30 Hz default +} + +static gboolean +suil_win_wrapper_idle(void* data) +{ + SuilWinWrapper* const wrap = SUIL_WIN_WRAPPER(data); + wrap->idle_iface->idle(wrap->instance->handle); + return TRUE; // Continue calling +} + +static int +wrapper_resize(LV2UI_Feature_Handle handle, int width, int height) +{ + gtk_drawing_area_size(GTK_DRAWING_AREA(handle), width, height); + return 0; +} + +static int +wrapper_wrap(SuilWrapper* wrapper, + SuilInstance* instance) +{ + SuilWinWrapper* const wrap = SUIL_WIN_WRAPPER(wrapper->impl); + + instance->host_widget = GTK_WIDGET(wrap); + wrap->wrapper = wrapper; + wrap->instance = instance; + + const LV2UI_Idle_Interface* idle_iface = NULL; + if (instance->descriptor->extension_data) { + idle_iface = (const LV2UI_Idle_Interface*) + instance->descriptor->extension_data(LV2_UI__idleInterface); + } + if (idle_iface) { + wrap->idle_iface = idle_iface; + wrap->idle_id = g_timeout_add (wrap->idle_ms, suil_win_wrapper_idle, wrap); + } + + return 0; +} + +static GdkFilterReturn +event_filter(GdkXEvent* xevent, GdkEvent* event, gpointer data) +{ + SuilWinWrapper* wrap = (SuilWinWrapper*)data; + MSG* msg = (MSG*)xevent; + if (msg->message == WM_KEYDOWN || msg->message == WM_KEYUP) { + // Forward keyboard events to UI window + PostMessage((HWND)wrap->instance->ui_widget, + msg->message, msg->wParam, msg->lParam); + return GDK_FILTER_REMOVE; + } else if (msg->message == WM_MOUSEWHEEL || msg->message == WM_MOUSEHWHEEL) { + PostMessage((HWND)wrap->instance->ui_widget, + msg->message, msg->wParam, msg->lParam); + return GDK_FILTER_REMOVE; + } + return GDK_FILTER_CONTINUE; +} + +static void +wrapper_free(SuilWrapper* wrapper) +{ + if (wrapper->impl) { + SuilWinWrapper* const wrap = SUIL_WIN_WRAPPER(wrapper->impl); + if (wrap->idle_id) { + g_source_remove(wrap->idle_id); + wrap->idle_id = 0; + } + + gdk_window_remove_filter(wrap->flt_win, event_filter, wrapper->impl); + gtk_object_destroy(GTK_OBJECT(wrap)); + } +} + +SUIL_LIB_EXPORT +SuilWrapper* +suil_wrapper_new(SuilHost* host, + const char* host_type_uri, + const char* ui_type_uri, + LV2_Feature*** features, + unsigned n_features) +{ + GtkWidget* parent = NULL; + for (unsigned i = 0; i < n_features; ++i) { + if (!strcmp((*features)[i]->URI, LV2_UI__parent)) { + parent = (GtkWidget*)(*features)[i]->data; + } + } + + if (!GTK_CONTAINER(parent)) { + SUIL_ERRORF("No GtkContainer parent given for %s UI\n", + ui_type_uri); + return NULL; + } + + SuilWrapper* wrapper = (SuilWrapper*)calloc(1, sizeof(SuilWrapper)); + wrapper->wrap = wrapper_wrap; + wrapper->free = wrapper_free; + + SuilWinWrapper* const wrap = SUIL_WIN_WRAPPER( + g_object_new(SUIL_TYPE_WIN_WRAPPER, NULL)); + + wrap->wrapper = NULL; + + wrapper->impl = wrap; + wrapper->resize.handle = wrap; + wrapper->resize.ui_resize = wrapper_resize; + + gtk_container_add(GTK_CONTAINER(parent), GTK_WIDGET(wrap)); + gtk_widget_set_can_focus(GTK_WIDGET(wrap), TRUE); + gtk_widget_set_sensitive(GTK_WIDGET(wrap), TRUE); + gtk_widget_realize(GTK_WIDGET(wrap)); + + GdkWindow* window = gtk_widget_get_window(GTK_WIDGET(wrap)); + + wrap->flt_win = gtk_widget_get_window(parent); + gdk_window_add_filter(wrap->flt_win, event_filter, wrap); + + HWND parent_window = (HWND)GDK_WINDOW_HWND(window); + suil_add_feature(features, &n_features, LV2_UI__parent, parent_window); + suil_add_feature(features, &n_features, LV2_UI__resize, &wrapper->resize); + suil_add_feature(features, &n_features, LV2_UI__idleInterface, NULL); + + // Scan for URID map and options + LV2_URID_Map* map = NULL; + LV2_Options_Option* options = NULL; + for (LV2_Feature** f = *features; *f && (!map || !options); ++f) { + if (!strcmp((*f)->URI, LV2_OPTIONS__options)) { + options = (LV2_Options_Option *)(*f)->data; + } else if (!strcmp((*f)->URI, LV2_URID__map)) { + map = (LV2_URID_Map *)(*f)->data; + } + } + + if (map && options) { + // Set UI update rate if given + LV2_URID ui_updateRate = map->map(map->handle, LV2_UI__updateRate); + for (LV2_Options_Option* o = options; o->key; ++o) { + if (o->key == ui_updateRate) { + wrap->idle_ms = 1000.0f / *(const float*)o->value; + break; + } + } + } + + return wrapper; +} + +} // extern "C" diff --git a/libs/tk/suil/wscript b/libs/tk/suil/wscript new file mode 100644 index 0000000000..c5659c1310 --- /dev/null +++ b/libs/tk/suil/wscript @@ -0,0 +1,83 @@ +#!/usr/bin/env python +from waflib.extras import autowaf as autowaf +import sys + +SUIL_VERSION = '0.10.8' + +def options(ctx): + pass + +def configure(conf): + if not conf.is_defined('YTK'): + return + + autowaf.check_pkg(conf, 'glib-2.0', uselib_store='GLIB', atleast_version='2.28', mandatory=True) + autowaf.check_pkg(conf, 'lv2', uselib_store='LV2_1_16_0', atleast_version='1.16.0', mandatory=False) + if conf.env['build_target'] != 'mingw' and sys.platform != 'darwin': # Linux + autowaf.check_pkg(conf, 'x11', uselib_store='X11', system=True, mandatory=True) + +def build(bld): + if not bld.is_defined('YTK') or not bld.is_defined('HAVE_LV2_1_16_0'): + return + + module_dir = bld.env['LIBDIR'] + cflags = [ bld.env['compiler_flags_dict']['pic'], bld.env['compiler_flags_dict']['c99'] ] + defines = [ 'SUIL_DIR_SEP="/"', 'SUIL_MODULE_DIR="' + module_dir +'"', 'SUIL_SHARED', 'SUIL_INTERNAL'] + + if sys.platform == 'darwin': + cflags += ['-fvisibility=hidden'] + defines += ['SUIL_WITH_COCOA_IN_GTK2', 'SUIL_MODULE_PREFIX="lib"', 'SUIL_MODULE_EXT=".dylib"'] + elif bld.env['build_target'] == 'mingw': + defines += ['SUIL_WITH_WIN_IN_GTK2', 'SUIL_MODULE_PREFIX=""', 'SUIL_MODULE_EXT=".dll"'] + else: + defines += ['SUIL_WITH_X11_IN_GTK2', 'SUIL_MODULE_PREFIX="lib"', 'SUIL_MODULE_EXT=".so"'] + cflags += ['-fvisibility=hidden'] + + obj = bld.shlib (features = 'c cshlib') + obj.cflags = cflags + obj.includes = ['.'] + obj.export_includes = ['.'] + obj.source = 'host.c instance.c' + obj.target = 'suil' + obj.name = 'libsuil' + obj.vnum = SUIL_VERSION + obj.uselib = [ 'LV2' ] + obj.defines = defines + obj.install_path = module_dir + + if sys.platform == 'darwin': + obj.uselib += ['DL'] + + bld(features = 'cxx cshlib', + source = 'cocoa_in_gtk2.mm', + target = 'suil_cocoa_in_gtk2', + includes = ['.'], + defines = defines, + install_path = module_dir, + cflags = cflags, + use = [ 'libydk', 'libytk' ], + uselib = 'LV2 DL GLIB PANGOCAIRO', + linkflags = ['-framework', 'Cocoa']) + + elif bld.env['build_target'] == 'mingw': + bld(features = 'cxx cxxshlib', + source = 'win_in_gtk2.cpp', + target = 'suil_win_in_gtk2', + includes = ['.'], + defines = defines, + install_path = module_dir, + cflags = cflags, + use = 'libytk', + uselib = 'GTK2 LV2 GLIB PANGOCAIRO') + else: + obj.uselib += ['DL'] + bld(features = 'c cshlib', + source = 'x11_in_gtk2.c', + target = 'suil_x11_in_gtk2', + includes = ['.'], + defines = defines, + install_path = module_dir, + cflags = cflags, + use = 'libytk', + uselib = 'X11 LV2 DL GLIB PANGOCAIRO', + linkflags = '-Wl,-z,nodelete') diff --git a/libs/tk/suil/x11_in_gtk2.c b/libs/tk/suil/x11_in_gtk2.c new file mode 100644 index 0000000000..1364a40f50 --- /dev/null +++ b/libs/tk/suil/x11_in_gtk2.c @@ -0,0 +1,589 @@ +/* + Copyright 2011-2020 David Robillard + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#include "suil_internal.h" + +#include "lv2/core/lv2.h" +#include "lv2/options/options.h" +#include "lv2/ui/ui.h" +#include "lv2/urid/urid.h" +#include "suil/suil.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +typedef struct { + bool is_set; + int width; + int height; +} SuilX11SizeHints; + +typedef struct { + GtkSocket socket; + GtkPlug* plug; + SuilWrapper* wrapper; + SuilInstance* instance; + const LV2UI_Idle_Interface* idle_iface; + guint idle_id; + guint idle_ms; + SuilX11SizeHints max_size; + SuilX11SizeHints custom_size; + SuilX11SizeHints base_size; + SuilX11SizeHints min_size; + bool query_wm; +} SuilX11Wrapper; + +typedef struct { + GtkSocketClass parent_class; +} SuilX11WrapperClass; + +GType suil_x11_wrapper_get_type(void); // Accessor for SUIL_TYPE_X11_WRAPPER + +#define SUIL_TYPE_X11_WRAPPER (suil_x11_wrapper_get_type()) +#define SUIL_X11_WRAPPER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), SUIL_TYPE_X11_WRAPPER, SuilX11Wrapper)) + +G_DEFINE_TYPE(SuilX11Wrapper, suil_x11_wrapper, GTK_TYPE_SOCKET) + +/** + Check if 'swallowed' subwindow is known to the X server. + + Gdk/GTK can mark the window as realized, mapped and visible even though + there is no window-ID on the X server for it yet. Then, + suil_x11_on_size_allocate() will cause a "BadWinow" X error. +*/ +static bool +x_window_is_valid(SuilX11Wrapper* socket) +{ + GdkWindow* window = gtk_widget_get_window(GTK_WIDGET(socket->plug)); + Window root = 0; + Window parent = 0; + Window* children = NULL; + unsigned childcount = 0; + + XQueryTree(GDK_WINDOW_XDISPLAY(window), + GDK_WINDOW_XID(window), + &root, &parent, &children, &childcount); + for (unsigned i = 0; i < childcount; ++i) { + if (children[i] == (Window)socket->instance->ui_widget) { + XFree(children); + return true; + } + } + if (children) { + XFree(children); + } + return false; +} + +static Window +get_parent_window(Display* display, Window child) +{ + Window root = 0; + Window parent = 0; + Window* children = NULL; + unsigned count = 0; + + if (child) { + if (XQueryTree(display, child, &root, &parent, &children, &count)) { + if (children) { + XFree(children); + } + } + } + + return (parent == root) ? 0 : parent; +} + +static gboolean +on_plug_removed(GtkSocket* sock, gpointer data) +{ + (void)data; + + SuilX11Wrapper* const self = SUIL_X11_WRAPPER(sock); + + if (self->idle_id) { + g_source_remove(self->idle_id); + self->idle_id = 0; + } + + if (self->instance->handle) { + self->instance->descriptor->cleanup(self->instance->handle); + self->instance->handle = NULL; + } + + self->plug = NULL; + return TRUE; +} + +static void +suil_x11_wrapper_finalize(GObject* gobject) +{ + SuilX11Wrapper* const self = SUIL_X11_WRAPPER(gobject); + + self->wrapper->impl = NULL; + + G_OBJECT_CLASS(suil_x11_wrapper_parent_class)->finalize(gobject); +} + +static void +suil_x11_wrapper_realize(GtkWidget* w) +{ + SuilX11Wrapper* const wrap = SUIL_X11_WRAPPER(w); + GtkSocket* const socket = GTK_SOCKET(w); + + if (GTK_WIDGET_CLASS(suil_x11_wrapper_parent_class)->realize) { + GTK_WIDGET_CLASS(suil_x11_wrapper_parent_class)->realize(w); + } + + gtk_socket_add_id(socket, gtk_plug_get_id(wrap->plug)); + + gtk_widget_set_sensitive(GTK_WIDGET(wrap->plug), TRUE); + gtk_widget_set_can_focus(GTK_WIDGET(wrap->plug), TRUE); + gtk_widget_grab_focus(GTK_WIDGET(wrap->plug)); + + // Setup drag/drop proxy from parent/grandparent window + GdkWindow* gwindow = gtk_widget_get_window(GTK_WIDGET(wrap->plug)); + Window xwindow = GDK_WINDOW_XID(gwindow); + Atom xdnd_proxy_atom = gdk_x11_get_xatom_by_name("XdndProxy"); + Window plugin = (Window)wrap->instance->ui_widget; + + while (xwindow) { + XChangeProperty(GDK_WINDOW_XDISPLAY(gwindow), + xwindow, + xdnd_proxy_atom, + XA_WINDOW, + 32, + PropModeReplace, + (unsigned char*)&plugin, + 1); + + xwindow = get_parent_window(GDK_WINDOW_XDISPLAY(gwindow), xwindow); + } +} + +static void +suil_x11_wrapper_show(GtkWidget* w) +{ + SuilX11Wrapper* const wrap = SUIL_X11_WRAPPER(w); + + if (GTK_WIDGET_CLASS(suil_x11_wrapper_parent_class)->show) { + GTK_WIDGET_CLASS(suil_x11_wrapper_parent_class)->show(w); + } + + gtk_widget_show(GTK_WIDGET(wrap->plug)); +} + +static gboolean +forward_key_event(SuilX11Wrapper* socket, + GdkEvent* gdk_event) +{ + GdkWindow* window = gtk_widget_get_window(GTK_WIDGET(socket->plug)); + GdkScreen* screen = gdk_visual_get_screen(gdk_window_get_visual(window)); + + Window target_window = 0; + if (gdk_event->any.window == window) { + // Event sent up to the plug window, forward it up to the parent + GtkWidget* widget = GTK_WIDGET(socket->instance->host_widget); + GdkWindow* parent = gtk_widget_get_parent_window(widget); + if (parent) { + target_window = GDK_WINDOW_XID(parent); + } else { + return FALSE; // Wrapper is a top-level window, do nothing + } + } else { + // Event sent anywhere else, send to the plugin + target_window = (Window)socket->instance->ui_widget; + } + + XKeyEvent xev; + memset(&xev, 0, sizeof(xev)); + xev.type = (gdk_event->type == GDK_KEY_PRESS) ? KeyPress : KeyRelease; + xev.root = GDK_WINDOW_XID(gdk_screen_get_root_window(screen)); + xev.window = target_window; + xev.subwindow = None; + xev.time = gdk_event->key.time; + xev.state = gdk_event->key.state; + xev.keycode = gdk_event->key.hardware_keycode; + + XSendEvent(GDK_WINDOW_XDISPLAY(window), + target_window, + False, + NoEventMask, + (XEvent*)&xev); + + return (gdk_event->any.window != window); +} + +static gboolean +idle_size_request(gpointer user_data) +{ + GtkWidget* w = GTK_WIDGET(user_data); + gtk_widget_queue_resize(w); + return FALSE; +} + +/// Read XSizeHints and store the values for later use +static void +query_wm_hints(SuilX11Wrapper* wrap) +{ + GdkWindow* window = gtk_widget_get_window(GTK_WIDGET(wrap->plug)); + XSizeHints hints = {0}; + long supplied = 0; + + XGetWMNormalHints(GDK_WINDOW_XDISPLAY(window), + (Window)wrap->instance->ui_widget, + &hints, + &supplied); + + if (hints.flags & PMaxSize) { + wrap->max_size.width = hints.max_width; + wrap->max_size.height = hints.max_height; + wrap->max_size.is_set = true; + } + if (hints.flags & PBaseSize) { + wrap->base_size.width = hints.base_width; + wrap->base_size.height = hints.base_height; + wrap->base_size.is_set = true; + } + if (hints.flags & PMinSize) { + wrap->min_size.width = hints.min_width; + wrap->min_size.height = hints.min_height; + wrap->min_size.is_set = true; + } + + wrap->query_wm = false; +} + +static void +forward_size_request(SuilX11Wrapper* socket, + GtkAllocation* allocation) +{ + GdkWindow* window = gtk_widget_get_window(GTK_WIDGET(socket->plug)); + if (x_window_is_valid(socket)) { + // Calculate allocation size constrained to X11 limits for widget + int width = allocation->width; + int height = allocation->height; + + if (socket->query_wm) { + query_wm_hints(socket); + } + + if (socket->max_size.is_set) { + width = MIN(width, socket->max_size.width); + height = MIN(height, socket->max_size.height); + } + if (socket->min_size.is_set) { + width = MAX(width, socket->min_size.width); + height = MAX(height, socket->min_size.height); + } + + // Resize widget window + XResizeWindow(GDK_WINDOW_XDISPLAY(window), + (Window)socket->instance->ui_widget, + (unsigned)width, (unsigned)height); + + // Get actual widget geometry + Window root = 0; + int wx = 0; + int wy = 0; + unsigned int ww = 0; + unsigned int wh = 0; + unsigned int ignored = 0; + XGetGeometry(GDK_WINDOW_XDISPLAY(window), + (Window)socket->instance->ui_widget, + &root, + &wx, &wy, &ww, &wh, + &ignored, &ignored); + + // Center widget in allocation + wx = (allocation->width - (int)ww) / 2; + wy = (allocation->height - (int)wh) / 2; + XMoveWindow(GDK_WINDOW_XDISPLAY(window), + (Window)socket->instance->ui_widget, + wx, wy); + } else { + /* Child has not been realized, so unable to resize now. + Queue an idle resize. */ + g_idle_add(idle_size_request, socket->plug); + } +} + +static gboolean +suil_x11_wrapper_key_event(GtkWidget* widget, + GdkEventKey* event) +{ + SuilX11Wrapper* const self = SUIL_X11_WRAPPER(widget); + + if (self->plug) { + return forward_key_event(self, (GdkEvent*)event); + } + + return FALSE; +} + +static void +suil_x11_on_size_request(GtkWidget* widget, + GtkRequisition* requisition) +{ + SuilX11Wrapper* const self = SUIL_X11_WRAPPER(widget); + + if (self->custom_size.is_set) { + requisition->width = self->custom_size.width; + requisition->height = self->custom_size.height; + } else if (self->base_size.is_set) { + requisition->width = self->base_size.width; + requisition->height = self->base_size.height; + } else if (self->min_size.is_set) { + requisition->width = self->min_size.width; + requisition->height = self->min_size.height; + } +} + +static void +suil_x11_on_size_allocate(GtkWidget* widget, + GtkAllocation* a) +{ + SuilX11Wrapper* const self = SUIL_X11_WRAPPER(widget); + + if (self->plug + && GTK_WIDGET_REALIZED(widget) + && GTK_WIDGET_MAPPED(widget) + && GTK_WIDGET_VISIBLE(widget)) { + forward_size_request(self, a); + } +} + +static void +suil_x11_on_map_event(GtkWidget* widget, GdkEvent* event) +{ + (void)event; + + SuilX11Wrapper* const self = SUIL_X11_WRAPPER(widget); + + /* Reset the size request to the minimum sizes. This is called after the + initial size negotiation, where Gtk called suil_x11_on_size_request() to + get the size request, which might be bigger than the minimum size. + However, the Gtk2 size model has no proper way to handle minimum and + default sizes, so hack around this by setting the size request + properties (which really mean minimum size) back to the minimum after + the widget is mapped. This makes it possible for the initial mapping to + use the default size, but still allow the user to resize the widget + smaller, down to the minimum size. */ + + if ((self->custom_size.is_set || self->base_size.is_set) && + self->min_size.is_set) { + g_object_set(G_OBJECT(GTK_WIDGET(self)), + "width-request", self->min_size.width, + "height-request", self->min_size.height, + NULL); + } +} + +static void +suil_x11_wrapper_class_init(SuilX11WrapperClass* klass) +{ + GObjectClass* const gobject_class = G_OBJECT_CLASS(klass); + GtkWidgetClass* const widget_class = GTK_WIDGET_CLASS(klass); + + gobject_class->finalize = suil_x11_wrapper_finalize; + widget_class->realize = suil_x11_wrapper_realize; + widget_class->show = suil_x11_wrapper_show; + widget_class->key_press_event = suil_x11_wrapper_key_event; + widget_class->key_release_event = suil_x11_wrapper_key_event; +} + +static void +suil_x11_wrapper_init(SuilX11Wrapper* self) +{ + self->plug = GTK_PLUG(gtk_plug_new(0)); + self->wrapper = NULL; + self->instance = NULL; + self->idle_iface = NULL; + self->idle_ms = 1000 / 30; // 30 Hz default + self->max_size = (SuilX11SizeHints){false, 0, 0}; + self->custom_size = (SuilX11SizeHints){false, 0, 0}; + self->base_size = (SuilX11SizeHints){false, 0, 0}; + self->min_size = (SuilX11SizeHints){false, 0, 0}; + self->query_wm = true; +} + +static int +wrapper_resize(LV2UI_Feature_Handle handle, int width, int height) +{ + SuilX11Wrapper* const wrap = SUIL_X11_WRAPPER(handle); + + wrap->custom_size.width = width; + wrap->custom_size.height = height; + wrap->custom_size.is_set = width > 0 && height > 0; + + // Assume the plugin has also updated min/max size constraints + wrap->query_wm = true; + + gtk_widget_queue_resize(GTK_WIDGET(handle)); + return 0; +} + +static gboolean +suil_x11_wrapper_idle(void* data) +{ + SuilX11Wrapper* const wrap = SUIL_X11_WRAPPER(data); + + wrap->idle_iface->idle(wrap->instance->handle); + + return TRUE; // Continue calling +} + +static int +wrapper_wrap(SuilWrapper* wrapper, + SuilInstance* instance) +{ + SuilX11Wrapper* const wrap = SUIL_X11_WRAPPER(wrapper->impl); + + instance->host_widget = GTK_WIDGET(wrap); + wrap->wrapper = wrapper; + wrap->instance = instance; + + GdkWindow* window = gtk_widget_get_window(GTK_WIDGET(wrap->plug)); + GdkDisplay* display = gdk_window_get_display(window); + Display* xdisplay = GDK_WINDOW_XDISPLAY(window); + Window xwindow = (Window)instance->ui_widget; + + gdk_display_sync(display); + if (x_window_is_valid(wrap)) { + XWindowAttributes attrs; + XGetWindowAttributes(xdisplay, xwindow, &attrs); + + query_wm_hints(wrap); + + if (!wrap->base_size.is_set) { + // Fall back to using initial size as base size + wrap->base_size.is_set = true; + wrap->base_size.width = attrs.width; + wrap->base_size.height = attrs.height; + } + } + + const LV2UI_Idle_Interface* idle_iface = NULL; + if (instance->descriptor->extension_data) { + idle_iface = (const LV2UI_Idle_Interface*) + instance->descriptor->extension_data(LV2_UI__idleInterface); + } + if (idle_iface) { + wrap->idle_iface = idle_iface; + wrap->idle_id = g_timeout_add( + wrap->idle_ms, suil_x11_wrapper_idle, wrap); + } + + g_signal_connect(G_OBJECT(wrap), + "plug-removed", + G_CALLBACK(on_plug_removed), + NULL); + + g_signal_connect(G_OBJECT(wrap), + "size-request", + G_CALLBACK(suil_x11_on_size_request), + NULL); + + g_signal_connect(G_OBJECT(wrap), + "size-allocate", + G_CALLBACK(suil_x11_on_size_allocate), + NULL); + + g_signal_connect(G_OBJECT(wrap), + "map-event", + G_CALLBACK(suil_x11_on_map_event), + NULL); + + return 0; +} + +static void +wrapper_free(SuilWrapper* wrapper) +{ + if (wrapper->impl) { + SuilX11Wrapper* const wrap = SUIL_X11_WRAPPER(wrapper->impl); + gtk_object_destroy(GTK_OBJECT(wrap)); + } +} + +SUIL_LIB_EXPORT +SuilWrapper* +suil_wrapper_new(SuilHost* host, + const char* host_type_uri, + const char* ui_type_uri, + LV2_Feature*** features, + unsigned n_features) +{ + (void)host; + (void)host_type_uri; + (void)ui_type_uri; + + SuilWrapper* wrapper = (SuilWrapper*)calloc(1, sizeof(SuilWrapper)); + wrapper->wrap = wrapper_wrap; + wrapper->free = wrapper_free; + + SuilX11Wrapper* const wrap = SUIL_X11_WRAPPER( + g_object_new(SUIL_TYPE_X11_WRAPPER, NULL)); + + wrapper->impl = wrap; + wrapper->resize.handle = wrap; + wrapper->resize.ui_resize = wrapper_resize; + + gtk_widget_set_sensitive(GTK_WIDGET(wrap), TRUE); + gtk_widget_set_can_focus(GTK_WIDGET(wrap), TRUE); + + const intptr_t parent_id = (intptr_t)gtk_plug_get_id(wrap->plug); + suil_add_feature(features, &n_features, LV2_UI__parent, (void*)parent_id); + suil_add_feature(features, &n_features, LV2_UI__resize, &wrapper->resize); + suil_add_feature(features, &n_features, LV2_UI__idleInterface, NULL); + + // Scan for URID map and options + LV2_URID_Map* map = NULL; + LV2_Options_Option* options = NULL; + for (LV2_Feature** f = *features; *f && (!map || !options); ++f) { + if (!strcmp((*f)->URI, LV2_OPTIONS__options)) { + options = (LV2_Options_Option*)(*f)->data; + } else if (!strcmp((*f)->URI, LV2_URID__map)) { + map = (LV2_URID_Map*)(*f)->data; + } + } + + if (map && options) { + // Set UI update rate if given + LV2_URID ui_updateRate = map->map(map->handle, LV2_UI__updateRate); + for (LV2_Options_Option* o = options; o->key; ++o) { + if (o->key == ui_updateRate) { + wrap->idle_ms = (guint)(1000.0f / *(const float*)o->value); + break; + } + } + } + + return wrapper; +} diff --git a/libs/tk/ydk-pixbuf/config.h b/libs/tk/ydk-pixbuf/config.h new file mode 100644 index 0000000000..6544fb2828 --- /dev/null +++ b/libs/tk/ydk-pixbuf/config.h @@ -0,0 +1,42 @@ +/* Define to 1 if translation of program messages to the user's native + language is requested. */ +#undef ENABLE_NLS + +/* Define if gio can sniff image data */ +/* #undef GDK_PIXBUF_USE_GIO_MIME */ + +/* The prefix for our gettext translation domains. */ +#define GETTEXT_PACKAGE "gdk-pixbuf" + +/* Define to 1 if you have the `bind_textdomain_codeset' function. */ +/* #undef HAVE_BIND_TEXTDOMAIN_CODESET */ + +/* Define to 1 if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if sys/sysinfo.h is available */ +/* #undef HAVE_SYS_SYSINFO_H */ + +/* Define to 1 if sys/systeminfo.h is available */ +/* #undef HAVE_SYS_SYSTEMINFO_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "2.31.1" + +/* Define to 1 if gmodule works and should be used */ +//#define USE_GMODULE 1 + +/* Define to 1 if medialib is available and should be used */ +/* #undef USE_MEDIALIB */ + +/* Define to 1 if XXM is available and should be used */ +/* #undef USE_MMX */ + +/* Define to empty if `const' does not conform to ANSI C. */ +/* #undef const */ diff --git a/libs/tk/ydk-pixbuf/gdk-pixbuf-animation.c b/libs/tk/ydk-pixbuf/gdk-pixbuf-animation.c new file mode 100644 index 0000000000..a684b8776f --- /dev/null +++ b/libs/tk/ydk-pixbuf/gdk-pixbuf-animation.c @@ -0,0 +1,1001 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ +/* GdkPixbuf library - Simple animation support + * + * Copyright (C) 1999 The Free Software Foundation + * + * Authors: Jonathan Blandford + * Havoc Pennington + * + * 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, see . + */ + +#include "config.h" +#include +#include "gdk-pixbuf-private.h" +#include "gdk-pixbuf-animation.h" +#include "gdk-pixbuf-loader.h" + +#include + +/** + * SECTION:animation + * @Short_description: Animated images. + * @Title: Animations + * @See_also: #GdkPixbufLoader. + * + * The GdkPixBuf library provides a simple mechanism to load and + * represent animations. An animation is conceptually a series of + * frames to be displayed over time. The animation may not be + * represented as a series of frames internally; for example, it may + * be stored as a sprite and instructions for moving the sprite around + * a background. To display an animation you don't need to understand + * its representation, however; you just ask GdkPixBuf what should + * be displayed at a given point in time. + * + */ + +typedef struct _GdkPixbufNonAnim GdkPixbufNonAnim; +typedef struct _GdkPixbufNonAnimClass GdkPixbufNonAnimClass; + +#define GDK_TYPE_PIXBUF_NON_ANIM (gdk_pixbuf_non_anim_get_type ()) +#define GDK_PIXBUF_NON_ANIM(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_PIXBUF_NON_ANIM, GdkPixbufNonAnim)) +#define GDK_IS_PIXBUF_NON_ANIM(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_PIXBUF_NON_ANIM)) + +#define GDK_PIXBUF_NON_ANIM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_PIXBUF_NON_ANIM, GdkPixbufNonAnimClass)) +#define GDK_IS_PIXBUF_NON_ANIM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_PIXBUF_NON_ANIM)) +#define GDK_PIXBUF_NON_ANIM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_PIXBUF_NON_ANIM, GdkPixbufNonAnimClass)) + +/* Private part of the GdkPixbufNonAnim structure */ +struct _GdkPixbufNonAnim { + GdkPixbufAnimation parent_instance; + + GdkPixbuf *pixbuf; +}; + +struct _GdkPixbufNonAnimClass { + GdkPixbufAnimationClass parent_class; + +}; + + +typedef struct _GdkPixbufNonAnimIter GdkPixbufNonAnimIter; +typedef struct _GdkPixbufNonAnimIterClass GdkPixbufNonAnimIterClass; + + +#define GDK_TYPE_PIXBUF_NON_ANIM_ITER (gdk_pixbuf_non_anim_iter_get_type ()) +#define GDK_PIXBUF_NON_ANIM_ITER(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_PIXBUF_NON_ANIM_ITER, GdkPixbufNonAnimIter)) +#define GDK_IS_PIXBUF_NON_ANIM_ITER(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_PIXBUF_NON_ANIM_ITER)) + +#define GDK_PIXBUF_NON_ANIM_ITER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_PIXBUF_NON_ANIM_ITER, GdkPixbufNonAnimIterClass)) +#define GDK_IS_PIXBUF_NON_ANIM_ITER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_PIXBUF_NON_ANIM_ITER)) +#define GDK_PIXBUF_NON_ANIM_ITER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_PIXBUF_NON_ANIM_ITER, GdkPixbufNonAnimIterClass)) + +struct _GdkPixbufNonAnimIter { + GdkPixbufAnimationIter parent_instance; + + GdkPixbufNonAnim *non_anim; +}; + +struct _GdkPixbufNonAnimIterClass { + GdkPixbufAnimationIterClass parent_class; + +}; + +static GType gdk_pixbuf_non_anim_iter_get_type (void) G_GNUC_CONST; + +G_DEFINE_TYPE (GdkPixbufAnimation, gdk_pixbuf_animation, G_TYPE_OBJECT); + +static void +gdk_pixbuf_animation_class_init (GdkPixbufAnimationClass *klass) +{ +} + +static void +gdk_pixbuf_animation_init (GdkPixbufAnimation *animation) +{ +} + +static void +prepared_notify (GdkPixbuf *pixbuf, + GdkPixbufAnimation *anim, + gpointer user_data) +{ + if (anim != NULL) + g_object_ref (anim); + else + anim = gdk_pixbuf_non_anim_new (pixbuf); + + *((GdkPixbufAnimation **)user_data) = anim; +} + +/** + * gdk_pixbuf_animation_new_from_file: + * @filename: Name of file to load, in the GLib file name encoding + * @error: return location for error + * + * Creates a new animation by loading it from a file. The file format is + * detected automatically. If the file's format does not support multi-frame + * images, then an animation with a single frame will be created. Possible errors + * are in the #GDK_PIXBUF_ERROR and #G_FILE_ERROR domains. + * + * Return value: A newly-created animation with a reference count of 1, or %NULL + * if any of several error conditions ocurred: the file could not be opened, + * there was no loader for the file's format, there was not enough memory to + * allocate the image buffer, or the image file contained invalid data. + **/ +GdkPixbufAnimation * +gdk_pixbuf_animation_new_from_file (const char *filename, + GError **error) +{ + GdkPixbufAnimation *animation; + int size; + FILE *f; + guchar buffer [SNIFF_BUFFER_SIZE]; + GdkPixbufModule *image_module; + gchar *display_name; + + g_return_val_if_fail (filename != NULL, NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + display_name = g_filename_display_name (filename); + f = g_fopen (filename, "rb"); + if (!f) { + gint save_errno = errno; + g_set_error (error, + G_FILE_ERROR, + g_file_error_from_errno (save_errno), + _("Failed to open file '%s': %s"), + display_name, + g_strerror (save_errno)); + g_free (display_name); + return NULL; + } + + size = fread (&buffer, 1, sizeof (buffer), f); + + if (size == 0) { + g_set_error (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_CORRUPT_IMAGE, + _("Image file '%s' contains no data"), + display_name); + g_free (display_name); + fclose (f); + return NULL; + } + + image_module = _gdk_pixbuf_get_module (buffer, size, filename, error); + if (!image_module) { + g_free (display_name); + fclose (f); + return NULL; + } + + if (image_module->module == NULL) + if (!_gdk_pixbuf_load_module (image_module, error)) { + g_free (display_name); + fclose (f); + return NULL; + } + + if (image_module->load_animation != NULL) { + fseek (f, 0, SEEK_SET); + animation = (* image_module->load_animation) (f, error); + + if (animation == NULL && error != NULL && *error == NULL) { + /* I don't trust these crufty longjmp()'ing + * image libs to maintain proper error + * invariants, and I don't want user code to + * segfault as a result. We need to maintain + * the invariant that error gets set if NULL + * is returned. + */ + + g_warning ("Bug! gdk-pixbuf loader '%s' didn't set an error on failure.", + image_module->module_name); + g_set_error (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_FAILED, + _("Failed to load animation '%s': reason not known, probably a corrupt animation file"), + display_name); + } + + fclose (f); + } else if (image_module->begin_load != NULL) { + guchar buffer[4096]; + size_t length; + gpointer context; + gboolean success; + + success = FALSE; + animation = NULL; + fseek (f, 0, SEEK_SET); + + context = image_module->begin_load (NULL, prepared_notify, NULL, &animation, error); + if (!context) + goto fail_begin_load; + + while (!feof (f) && !ferror (f)) { + length = fread (buffer, 1, sizeof (buffer), f); + if (length > 0) { + if (!image_module->load_increment (context, buffer, length, error)) { + error = NULL; + goto fail_load_increment; + } + } + } + + success = TRUE; + +fail_load_increment: + if (!image_module->stop_load (context, error)) + success = FALSE; + +fail_begin_load: + fclose (f); + + if (success) { + /* If there was no error, there must be an animation that was successfully loaded */ + g_assert (animation); + } else { + if (animation) { + g_object_unref (animation); + animation = NULL; + } + } + } else { + GdkPixbuf *pixbuf; + + /* Keep this logic in sync with gdk_pixbuf_new_from_file() */ + + fseek (f, 0, SEEK_SET); + pixbuf = _gdk_pixbuf_generic_image_load (image_module, f, error); + fclose (f); + + if (pixbuf == NULL && error != NULL && *error == NULL) { + /* I don't trust these crufty longjmp()'ing image libs + * to maintain proper error invariants, and I don't + * want user code to segfault as a result. We need to maintain + * the invariant that error gets set if NULL is returned. + */ + + g_warning ("Bug! gdk-pixbuf loader '%s' didn't set an error on failure.", + image_module->module_name); + g_set_error (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_FAILED, + _("Failed to load image '%s': reason not known, probably a corrupt image file"), + display_name); + } + + if (pixbuf == NULL) { + g_free (display_name); + animation = NULL; + goto out; + } + + animation = gdk_pixbuf_non_anim_new (pixbuf); + + g_object_unref (pixbuf); + } + + g_free (display_name); + + out: + return animation; +} + +#ifdef G_OS_WIN32 + +#undef gdk_pixbuf_animation_new_from_file + +GdkPixbufAnimation * +gdk_pixbuf_animation_new_from_file (const char *filename, + GError **error) +{ + gchar *utf8_filename = + g_locale_to_utf8 (filename, -1, NULL, NULL, error); + GdkPixbufAnimation *retval; + + if (utf8_filename == NULL) + return NULL; + + retval = gdk_pixbuf_animation_new_from_file_utf8 (utf8_filename, error); + + g_free (utf8_filename); + + return retval; +} + +#endif + +/** + * gdk_pixbuf_animation_new_from_stream: + * @stream: a #GInputStream to load the pixbuf from + * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore + * @error: Return location for an error + * + * Creates a new animation by loading it from an input stream. + * + * The file format is detected automatically. If %NULL is returned, then + * @error will be set. The @cancellable can be used to abort the operation + * from another thread. If the operation was cancelled, the error + * %G_IO_ERROR_CANCELLED will be returned. Other possible errors are in + * the #GDK_PIXBUF_ERROR and %G_IO_ERROR domains. + * + * The stream is not closed. + * + * Return value: A newly-created pixbuf, or %NULL if any of several error + * conditions occurred: the file could not be opened, the image format is + * not supported, there was not enough memory to allocate the image buffer, + * the stream contained invalid data, or the operation was cancelled. + * + * Since: 2.28 + **/ +GdkPixbufAnimation * +gdk_pixbuf_animation_new_from_stream (GInputStream *stream, + GCancellable *cancellable, + GError **error) +{ + GdkPixbufAnimation *animation; + GdkPixbufLoader *loader; + gssize n_read; + guchar buffer[LOAD_BUFFER_SIZE]; + gboolean res; + + g_return_val_if_fail (G_IS_INPUT_STREAM (stream), NULL); + g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + loader = gdk_pixbuf_loader_new (); + + res = TRUE; + while (1) { + n_read = g_input_stream_read (stream, + buffer, + sizeof (buffer), + cancellable, + error); + if (n_read < 0) { + res = FALSE; + error = NULL; /* Ignore further errors */ + break; + } + + if (n_read == 0) + break; + + if (!gdk_pixbuf_loader_write (loader, + buffer, + n_read, + error)) { + res = FALSE; + error = NULL; + break; + } + } + + if (!gdk_pixbuf_loader_close (loader, error)) { + res = FALSE; + error = NULL; + } + + if (res) { + animation = gdk_pixbuf_loader_get_animation (loader); + if (animation) + g_object_ref (animation); + } else { + animation = NULL; + } + + g_object_unref (loader); + + return animation; +} + +static void +animation_new_from_stream_thread (GSimpleAsyncResult *result, + GInputStream *stream, + GCancellable *cancellable) +{ + GdkPixbufAnimation *animation; + GError *error = NULL; + + animation = gdk_pixbuf_animation_new_from_stream (stream, cancellable, &error); + + /* Set the new pixbuf as the result, or error out */ + if (animation == NULL) { + g_simple_async_result_take_error (result, error); + } else { + g_simple_async_result_set_op_res_gpointer (result, g_object_ref (animation), g_object_unref); + } +} + +/** + * gdk_pixbuf_animation_new_from_stream_async: + * @stream: a #GInputStream from which to load the animation + * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore + * @callback: a #GAsyncReadyCallback to call when the the pixbuf is loaded + * @user_data: the data to pass to the callback function + * + * Creates a new animation by asynchronously loading an image from an input stream. + * + * For more details see gdk_pixbuf_new_from_stream(), which is the synchronous + * version of this function. + * + * When the operation is finished, @callback will be called in the main thread. + * You can then call gdk_pixbuf_animation_new_from_stream_finish() to get the + * result of the operation. + * + * Since: 2.28 + **/ +void +gdk_pixbuf_animation_new_from_stream_async (GInputStream *stream, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GSimpleAsyncResult *result; + + g_return_if_fail (G_IS_INPUT_STREAM (stream)); + g_return_if_fail (callback != NULL); + g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable)); + + result = g_simple_async_result_new (G_OBJECT (stream), callback, user_data, gdk_pixbuf_animation_new_from_stream_async); + g_simple_async_result_run_in_thread (result, (GSimpleAsyncThreadFunc) animation_new_from_stream_thread, G_PRIORITY_DEFAULT, cancellable); + g_object_unref (result); +} + +/** + * gdk_pixbuf_animation_new_from_stream_finish: + * @async_result: a #GAsyncResult + * @error: a #GError, or %NULL + * + * Finishes an asynchronous pixbuf animation creation operation started with + * gdk_pixbuf_animation_new_from_stream_async(). + * + * Return value: a #GdkPixbufAnimation or %NULL on error. Free the returned + * object with g_object_unref(). + * + * Since: 2.28 + **/ +GdkPixbufAnimation * +gdk_pixbuf_animation_new_from_stream_finish (GAsyncResult *async_result, + GError **error) +{ + GSimpleAsyncResult *result = G_SIMPLE_ASYNC_RESULT (async_result); + + g_return_val_if_fail (G_IS_ASYNC_RESULT (async_result), NULL); + g_return_val_if_fail (!error || (error && !*error), NULL); + g_warn_if_fail (g_simple_async_result_get_source_tag (result) == gdk_pixbuf_animation_new_from_stream_async); + + if (g_simple_async_result_propagate_error (result, error)) + return NULL; + + return g_simple_async_result_get_op_res_gpointer (result); +} + +/** + * gdk_pixbuf_animation_new_from_resource: + * @resource_path: the path of the resource file + * @error: Return location for an error + * + * Creates a new pixbuf animation by loading an image from an resource. + * + * The file format is detected automatically. If %NULL is returned, then + * @error will be set. + * + * Return value: A newly-created animation, or %NULL if any of several error + * conditions occurred: the file could not be opened, the image format is + * not supported, there was not enough memory to allocate the image buffer, + * the stream contained invalid data, or the operation was cancelled. + * + * Since: 2.28 + **/ +GdkPixbufAnimation * +gdk_pixbuf_animation_new_from_resource (const char *resource_path, + GError **error) +{ + GInputStream *stream; + GdkPixbufAnimation *anim; + GdkPixbuf *pixbuf; + + pixbuf = _gdk_pixbuf_new_from_resource_try_mmap (resource_path); + if (pixbuf) { + anim = gdk_pixbuf_non_anim_new (pixbuf); + g_object_unref (pixbuf); + return anim; + } + + stream = g_resources_open_stream (resource_path, 0, error); + if (stream == NULL) + return NULL; + + anim = gdk_pixbuf_animation_new_from_stream (stream, NULL, error); + g_object_unref (stream); + return anim; +} + +/** + * gdk_pixbuf_animation_ref: (skip) + * @animation: An animation. + * + * Adds a reference to an animation. + * + * Return value: The same as the @animation argument. + * + * Deprecated: 2.0: Use g_object_ref(). + **/ +GdkPixbufAnimation * +gdk_pixbuf_animation_ref (GdkPixbufAnimation *animation) +{ + return (GdkPixbufAnimation*) g_object_ref (animation); +} + +/** + * gdk_pixbuf_animation_unref: (skip) + * @animation: An animation. + * + * Removes a reference from an animation. + * + * Deprecated: 2.0: Use g_object_unref(). + **/ +void +gdk_pixbuf_animation_unref (GdkPixbufAnimation *animation) +{ + g_object_unref (animation); +} + +/** + * gdk_pixbuf_animation_is_static_image: + * @animation: a #GdkPixbufAnimation + * + * If you load a file with gdk_pixbuf_animation_new_from_file() and it turns + * out to be a plain, unanimated image, then this function will return + * %TRUE. Use gdk_pixbuf_animation_get_static_image() to retrieve + * the image. + * + * Return value: %TRUE if the "animation" was really just an image + **/ +gboolean +gdk_pixbuf_animation_is_static_image (GdkPixbufAnimation *animation) +{ + g_return_val_if_fail (GDK_IS_PIXBUF_ANIMATION (animation), FALSE); + + return GDK_PIXBUF_ANIMATION_GET_CLASS (animation)->is_static_image (animation); +} + +/** + * gdk_pixbuf_animation_get_static_image: + * @animation: a #GdkPixbufAnimation + * + * If an animation is really just a plain image (has only one frame), + * this function returns that image. If the animation is an animation, + * this function returns a reasonable thing to display as a static + * unanimated image, which might be the first frame, or something more + * sophisticated. If an animation hasn't loaded any frames yet, this + * function will return %NULL. + * + * Return value: (transfer none): unanimated image representing the animation + **/ +GdkPixbuf* +gdk_pixbuf_animation_get_static_image (GdkPixbufAnimation *animation) +{ + g_return_val_if_fail (GDK_IS_PIXBUF_ANIMATION (animation), NULL); + + return GDK_PIXBUF_ANIMATION_GET_CLASS (animation)->get_static_image (animation); +} + +/** + * gdk_pixbuf_animation_get_width: + * @animation: An animation. + * + * Queries the width of the bounding box of a pixbuf animation. + * + * Return value: Width of the bounding box of the animation. + **/ +int +gdk_pixbuf_animation_get_width (GdkPixbufAnimation *animation) +{ + int width; + + g_return_val_if_fail (GDK_IS_PIXBUF_ANIMATION (animation), 0); + + width = 0; + GDK_PIXBUF_ANIMATION_GET_CLASS (animation)->get_size (animation, + &width, NULL); + + + return width; +} + +/** + * gdk_pixbuf_animation_get_height: + * @animation: An animation. + * + * Queries the height of the bounding box of a pixbuf animation. + * + * Return value: Height of the bounding box of the animation. + **/ +int +gdk_pixbuf_animation_get_height (GdkPixbufAnimation *animation) +{ + int height; + + g_return_val_if_fail (GDK_IS_PIXBUF_ANIMATION (animation), 0); + + height = 0; + GDK_PIXBUF_ANIMATION_GET_CLASS (animation)->get_size (animation, + NULL, &height); + + + return height; +} + + +/** + * gdk_pixbuf_animation_get_iter: + * @animation: a #GdkPixbufAnimation + * @start_time: (allow-none): time when the animation starts playing + * + * Get an iterator for displaying an animation. The iterator provides + * the frames that should be displayed at a given time. + * It should be freed after use with g_object_unref(). + * + * @start_time would normally come from g_get_current_time(), and + * marks the beginning of animation playback. After creating an + * iterator, you should immediately display the pixbuf returned by + * gdk_pixbuf_animation_iter_get_pixbuf(). Then, you should install a + * timeout (with g_timeout_add()) or by some other mechanism ensure + * that you'll update the image after + * gdk_pixbuf_animation_iter_get_delay_time() milliseconds. Each time + * the image is updated, you should reinstall the timeout with the new, + * possibly-changed delay time. + * + * As a shortcut, if @start_time is %NULL, the result of + * g_get_current_time() will be used automatically. + * + * To update the image (i.e. possibly change the result of + * gdk_pixbuf_animation_iter_get_pixbuf() to a new frame of the animation), + * call gdk_pixbuf_animation_iter_advance(). + * + * If you're using #GdkPixbufLoader, in addition to updating the image + * after the delay time, you should also update it whenever you + * receive the area_updated signal and + * gdk_pixbuf_animation_iter_on_currently_loading_frame() returns + * %TRUE. In this case, the frame currently being fed into the loader + * has received new data, so needs to be refreshed. The delay time for + * a frame may also be modified after an area_updated signal, for + * example if the delay time for a frame is encoded in the data after + * the frame itself. So your timeout should be reinstalled after any + * area_updated signal. + * + * A delay time of -1 is possible, indicating "infinite." + * + * Return value: (transfer full): an iterator to move over the animation + **/ +GdkPixbufAnimationIter* +gdk_pixbuf_animation_get_iter (GdkPixbufAnimation *animation, + const GTimeVal *start_time) +{ + GTimeVal val; + + g_return_val_if_fail (GDK_IS_PIXBUF_ANIMATION (animation), NULL); + + + if (start_time) + val = *start_time; + else + g_get_current_time (&val); + + return GDK_PIXBUF_ANIMATION_GET_CLASS (animation)->get_iter (animation, &val); +} + +G_DEFINE_TYPE (GdkPixbufAnimationIter, gdk_pixbuf_animation_iter, G_TYPE_OBJECT); + +static void +gdk_pixbuf_animation_iter_class_init (GdkPixbufAnimationIterClass *klass) +{ +} + +static void +gdk_pixbuf_animation_iter_init (GdkPixbufAnimationIter *iter) +{ +} + +/** + * gdk_pixbuf_animation_iter_get_delay_time: + * @iter: an animation iterator + * + * Gets the number of milliseconds the current pixbuf should be displayed, + * or -1 if the current pixbuf should be displayed forever. g_timeout_add() + * conveniently takes a timeout in milliseconds, so you can use a timeout + * to schedule the next update. + * + * Return value: delay time in milliseconds (thousandths of a second) + **/ +int +gdk_pixbuf_animation_iter_get_delay_time (GdkPixbufAnimationIter *iter) +{ + g_return_val_if_fail (GDK_IS_PIXBUF_ANIMATION_ITER (iter), -1); + g_return_val_if_fail (GDK_PIXBUF_ANIMATION_ITER_GET_CLASS (iter)->get_delay_time, -1); + + return GDK_PIXBUF_ANIMATION_ITER_GET_CLASS (iter)->get_delay_time (iter); +} + +/** + * gdk_pixbuf_animation_iter_get_pixbuf: + * @iter: an animation iterator + * + * Gets the current pixbuf which should be displayed; the pixbuf might not + * be the same size as the animation itself + * (gdk_pixbuf_animation_get_width(), gdk_pixbuf_animation_get_height()). + * This pixbuf should be displayed for + * gdk_pixbuf_animation_iter_get_delay_time() milliseconds. The caller + * of this function does not own a reference to the returned pixbuf; + * the returned pixbuf will become invalid when the iterator advances + * to the next frame, which may happen anytime you call + * gdk_pixbuf_animation_iter_advance(). Copy the pixbuf to keep it + * (don't just add a reference), as it may get recycled as you advance + * the iterator. + * + * Return value: (transfer none): the pixbuf to be displayed + **/ +GdkPixbuf* +gdk_pixbuf_animation_iter_get_pixbuf (GdkPixbufAnimationIter *iter) +{ + g_return_val_if_fail (GDK_IS_PIXBUF_ANIMATION_ITER (iter), NULL); + g_return_val_if_fail (GDK_PIXBUF_ANIMATION_ITER_GET_CLASS (iter)->get_pixbuf, NULL); + + return GDK_PIXBUF_ANIMATION_ITER_GET_CLASS (iter)->get_pixbuf (iter); +} + +/** + * gdk_pixbuf_animation_iter_on_currently_loading_frame: + * @iter: a #GdkPixbufAnimationIter + * + * Used to determine how to respond to the area_updated signal on + * #GdkPixbufLoader when loading an animation. area_updated is emitted + * for an area of the frame currently streaming in to the loader. So if + * you're on the currently loading frame, you need to redraw the screen for + * the updated area. + * + * Return value: %TRUE if the frame we're on is partially loaded, or the last frame + **/ +gboolean +gdk_pixbuf_animation_iter_on_currently_loading_frame (GdkPixbufAnimationIter *iter) +{ + g_return_val_if_fail (GDK_IS_PIXBUF_ANIMATION_ITER (iter), FALSE); + g_return_val_if_fail (GDK_PIXBUF_ANIMATION_ITER_GET_CLASS (iter)->on_currently_loading_frame, FALSE); + + return GDK_PIXBUF_ANIMATION_ITER_GET_CLASS (iter)->on_currently_loading_frame (iter); +} + +/** + * gdk_pixbuf_animation_iter_advance: + * @iter: a #GdkPixbufAnimationIter + * @current_time: (allow-none): current time + * + * Possibly advances an animation to a new frame. Chooses the frame based + * on the start time passed to gdk_pixbuf_animation_get_iter(). + * + * @current_time would normally come from g_get_current_time(), and + * must be greater than or equal to the time passed to + * gdk_pixbuf_animation_get_iter(), and must increase or remain + * unchanged each time gdk_pixbuf_animation_iter_get_pixbuf() is + * called. That is, you can't go backward in time; animations only + * play forward. + * + * As a shortcut, pass %NULL for the current time and g_get_current_time() + * will be invoked on your behalf. So you only need to explicitly pass + * @current_time if you're doing something odd like playing the animation + * at double speed. + * + * If this function returns %FALSE, there's no need to update the animation + * display, assuming the display had been rendered prior to advancing; + * if %TRUE, you need to call gdk_pixbuf_animation_iter_get_pixbuf() + * and update the display with the new pixbuf. + * + * Returns: %TRUE if the image may need updating + * + **/ +gboolean +gdk_pixbuf_animation_iter_advance (GdkPixbufAnimationIter *iter, + const GTimeVal *current_time) +{ + GTimeVal val; + + g_return_val_if_fail (GDK_IS_PIXBUF_ANIMATION_ITER (iter), FALSE); + g_return_val_if_fail (GDK_PIXBUF_ANIMATION_ITER_GET_CLASS (iter)->advance, FALSE); + + if (current_time) + val = *current_time; + else + g_get_current_time (&val); + + return GDK_PIXBUF_ANIMATION_ITER_GET_CLASS (iter)->advance (iter, &val); +} + +static void gdk_pixbuf_non_anim_finalize (GObject *object); +static gboolean gdk_pixbuf_non_anim_is_static_image (GdkPixbufAnimation *animation); +static GdkPixbuf* gdk_pixbuf_non_anim_get_static_image (GdkPixbufAnimation *animation); +static void gdk_pixbuf_non_anim_get_size (GdkPixbufAnimation *anim, + int *width, + int *height); +static GdkPixbufAnimationIter* gdk_pixbuf_non_anim_get_iter (GdkPixbufAnimation *anim, + const GTimeVal *start_time); + +G_DEFINE_TYPE (GdkPixbufNonAnim, gdk_pixbuf_non_anim, GDK_TYPE_PIXBUF_ANIMATION); + +static void +gdk_pixbuf_non_anim_class_init (GdkPixbufNonAnimClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GdkPixbufAnimationClass *anim_class = GDK_PIXBUF_ANIMATION_CLASS (klass); + + object_class->finalize = gdk_pixbuf_non_anim_finalize; + + anim_class->is_static_image = gdk_pixbuf_non_anim_is_static_image; + anim_class->get_static_image = gdk_pixbuf_non_anim_get_static_image; + anim_class->get_size = gdk_pixbuf_non_anim_get_size; + anim_class->get_iter = gdk_pixbuf_non_anim_get_iter; +} + +static void +gdk_pixbuf_non_anim_init (GdkPixbufNonAnim *non_anim) +{ +} + +static void +gdk_pixbuf_non_anim_finalize (GObject *object) +{ + GdkPixbufNonAnim *non_anim = GDK_PIXBUF_NON_ANIM (object); + + if (non_anim->pixbuf) + g_object_unref (non_anim->pixbuf); + + G_OBJECT_CLASS (gdk_pixbuf_non_anim_parent_class)->finalize (object); +} + +GdkPixbufAnimation* +gdk_pixbuf_non_anim_new (GdkPixbuf *pixbuf) +{ + GdkPixbufNonAnim *non_anim; + + non_anim = g_object_new (GDK_TYPE_PIXBUF_NON_ANIM, NULL); + + non_anim->pixbuf = pixbuf; + + if (pixbuf) + g_object_ref (pixbuf); + + return GDK_PIXBUF_ANIMATION (non_anim); +} + +static gboolean +gdk_pixbuf_non_anim_is_static_image (GdkPixbufAnimation *animation) +{ + + return TRUE; +} + +static GdkPixbuf* +gdk_pixbuf_non_anim_get_static_image (GdkPixbufAnimation *animation) +{ + GdkPixbufNonAnim *non_anim; + + non_anim = GDK_PIXBUF_NON_ANIM (animation); + + return non_anim->pixbuf; +} + +static void +gdk_pixbuf_non_anim_get_size (GdkPixbufAnimation *anim, + int *width, + int *height) +{ + GdkPixbufNonAnim *non_anim; + + non_anim = GDK_PIXBUF_NON_ANIM (anim); + + if (width) + *width = gdk_pixbuf_get_width (non_anim->pixbuf); + + if (height) + *height = gdk_pixbuf_get_height (non_anim->pixbuf); +} + +static GdkPixbufAnimationIter* +gdk_pixbuf_non_anim_get_iter (GdkPixbufAnimation *anim, + const GTimeVal *start_time) +{ + GdkPixbufNonAnimIter *iter; + + iter = g_object_new (GDK_TYPE_PIXBUF_NON_ANIM_ITER, NULL); + + iter->non_anim = GDK_PIXBUF_NON_ANIM (anim); + + g_object_ref (iter->non_anim); + + return GDK_PIXBUF_ANIMATION_ITER (iter); +} + +static void gdk_pixbuf_non_anim_iter_finalize (GObject *object); +static int gdk_pixbuf_non_anim_iter_get_delay_time (GdkPixbufAnimationIter *iter); +static GdkPixbuf* gdk_pixbuf_non_anim_iter_get_pixbuf (GdkPixbufAnimationIter *iter); +static gboolean gdk_pixbuf_non_anim_iter_on_currently_loading_frame (GdkPixbufAnimationIter *iter); +static gboolean gdk_pixbuf_non_anim_iter_advance (GdkPixbufAnimationIter *iter, + const GTimeVal *current_time); + +G_DEFINE_TYPE (GdkPixbufNonAnimIter, + gdk_pixbuf_non_anim_iter, + GDK_TYPE_PIXBUF_ANIMATION_ITER); + +static void +gdk_pixbuf_non_anim_iter_class_init (GdkPixbufNonAnimIterClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GdkPixbufAnimationIterClass *anim_iter_class = + GDK_PIXBUF_ANIMATION_ITER_CLASS (klass); + + object_class->finalize = gdk_pixbuf_non_anim_iter_finalize; + + anim_iter_class->get_delay_time = gdk_pixbuf_non_anim_iter_get_delay_time; + anim_iter_class->get_pixbuf = gdk_pixbuf_non_anim_iter_get_pixbuf; + anim_iter_class->on_currently_loading_frame = gdk_pixbuf_non_anim_iter_on_currently_loading_frame; + anim_iter_class->advance = gdk_pixbuf_non_anim_iter_advance; +} + +static void +gdk_pixbuf_non_anim_iter_init (GdkPixbufNonAnimIter *non_iter) +{ +} + +static void +gdk_pixbuf_non_anim_iter_finalize (GObject *object) +{ + GdkPixbufNonAnimIter *iter = GDK_PIXBUF_NON_ANIM_ITER (object); + + g_object_unref (iter->non_anim); + + G_OBJECT_CLASS (gdk_pixbuf_non_anim_iter_parent_class)->finalize (object); +} + +static int +gdk_pixbuf_non_anim_iter_get_delay_time (GdkPixbufAnimationIter *iter) +{ + return -1; /* show only frame forever */ +} + +static GdkPixbuf* +gdk_pixbuf_non_anim_iter_get_pixbuf (GdkPixbufAnimationIter *iter) +{ + return GDK_PIXBUF_NON_ANIM_ITER (iter)->non_anim->pixbuf; +} + + +static gboolean +gdk_pixbuf_non_anim_iter_on_currently_loading_frame (GdkPixbufAnimationIter *iter) +{ + return TRUE; +} + +static gboolean +gdk_pixbuf_non_anim_iter_advance (GdkPixbufAnimationIter *iter, + const GTimeVal *current_time) +{ + + /* Advancing never requires a refresh */ + return FALSE; +} diff --git a/libs/tk/ydk-pixbuf/gdk-pixbuf-data.c b/libs/tk/ydk-pixbuf/gdk-pixbuf-data.c new file mode 100644 index 0000000000..769ead3374 --- /dev/null +++ b/libs/tk/ydk-pixbuf/gdk-pixbuf-data.c @@ -0,0 +1,125 @@ +/* GdkPixbuf library - Image creation from in-memory buffers + * + * Copyright (C) 1999 The Free Software Foundation + * + * Author: Federico Mena-Quintero + * + * 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, see . + */ + +#include "config.h" +#include "gdk-pixbuf.h" +#include "gdk-pixbuf-private.h" +#include +#include + + + +/** + * gdk_pixbuf_new_from_data: + * @data: (array): Image data in 8-bit/sample packed format + * @colorspace: Colorspace for the image data + * @has_alpha: Whether the data has an opacity channel + * @bits_per_sample: Number of bits per sample + * @width: Width of the image in pixels, must be > 0 + * @height: Height of the image in pixels, must be > 0 + * @rowstride: Distance in bytes between row starts + * @destroy_fn: (scope async) (allow-none): Function used to free the data when the pixbuf's reference count + * drops to zero, or %NULL if the data should not be freed + * @destroy_fn_data: (closure): Closure data to pass to the destroy notification function + * + * Creates a new #GdkPixbuf out of in-memory image data. Currently only RGB + * images with 8 bits per sample are supported. + * + * Since you are providing a pre-allocated pixel buffer, you must also + * specify a way to free that data. This is done with a function of + * type #GdkPixbufDestroyNotify. When a pixbuf created with is + * finalized, your destroy notification function will be called, and + * it is its responsibility to free the pixel array. + * + * See also gdk_pixbuf_new_from_bytes(). + * + * Return value: (transfer full): A newly-created #GdkPixbuf structure with a reference count of 1. + **/ +GdkPixbuf * +gdk_pixbuf_new_from_data (const guchar *data, GdkColorspace colorspace, gboolean has_alpha, + int bits_per_sample, int width, int height, int rowstride, + GdkPixbufDestroyNotify destroy_fn, gpointer destroy_fn_data) +{ + GdkPixbuf *pixbuf; + + /* Only 8-bit/sample RGB buffers are supported for now */ + + g_return_val_if_fail (data != NULL, NULL); + g_return_val_if_fail (colorspace == GDK_COLORSPACE_RGB, NULL); + g_return_val_if_fail (bits_per_sample == 8, NULL); + g_return_val_if_fail (width > 0, NULL); + g_return_val_if_fail (height > 0, NULL); + + pixbuf = g_object_new (GDK_TYPE_PIXBUF, + "colorspace", colorspace, + "n-channels", has_alpha ? 4 : 3, + "bits-per-sample", bits_per_sample, + "has-alpha", has_alpha ? TRUE : FALSE, + "width", width, + "height", height, + "rowstride", rowstride, + "pixels", data, + NULL); + + pixbuf->destroy_fn = destroy_fn; + pixbuf->destroy_fn_data = destroy_fn_data; + + return pixbuf; +} + +/** + * gdk_pixbuf_new_from_bytes: + * @data: Image data in 8-bit/sample packed format inside a #GBytes + * @colorspace: Colorspace for the image data + * @has_alpha: Whether the data has an opacity channel + * @bits_per_sample: Number of bits per sample + * @width: Width of the image in pixels, must be > 0 + * @height: Height of the image in pixels, must be > 0 + * @rowstride: Distance in bytes between row starts + * + * Creates a new #GdkPixbuf out of in-memory readonly image data. + * Currently only RGB images with 8 bits per sample are supported. + * This is the #GBytes variant of gdk_pixbuf_new_from_data(). + * + * Return value: (transfer full): A newly-created #GdkPixbuf structure with a reference count of 1. + * Since: 2.32 + **/ +GdkPixbuf * +gdk_pixbuf_new_from_bytes (GBytes *data, GdkColorspace colorspace, gboolean has_alpha, + int bits_per_sample, int width, int height, int rowstride) +{ + g_return_val_if_fail (data != NULL, NULL); + g_return_val_if_fail (colorspace == GDK_COLORSPACE_RGB, NULL); + g_return_val_if_fail (bits_per_sample == 8, NULL); + g_return_val_if_fail (width > 0, NULL); + g_return_val_if_fail (height > 0, NULL); + g_return_val_if_fail (g_bytes_get_size (data) >= width * height * (has_alpha ? 4 : 3), NULL); + + return (GdkPixbuf*) g_object_new (GDK_TYPE_PIXBUF, + "pixel-bytes", data, + "colorspace", colorspace, + "n-channels", has_alpha ? 4 : 3, + "bits-per-sample", bits_per_sample, + "has-alpha", has_alpha ? TRUE : FALSE, + "width", width, + "height", height, + "rowstride", rowstride, + NULL); +} diff --git a/libs/tk/ydk-pixbuf/gdk-pixbuf-enum-types.c b/libs/tk/ydk-pixbuf/gdk-pixbuf-enum-types.c new file mode 100644 index 0000000000..b056e7582a --- /dev/null +++ b/libs/tk/ydk-pixbuf/gdk-pixbuf-enum-types.c @@ -0,0 +1,97 @@ + +/* Generated data (by glib-mkenums) */ + +#include + +/* enumerations from "gdk-pixbuf-core.h" */ +GType +gdk_pixbuf_alpha_mode_get_type (void) +{ + static GType etype = 0; + + if (G_UNLIKELY(etype == 0)) { + static const GEnumValue values[] = { + { GDK_PIXBUF_ALPHA_BILEVEL, "GDK_PIXBUF_ALPHA_BILEVEL", "bilevel" }, + { GDK_PIXBUF_ALPHA_FULL, "GDK_PIXBUF_ALPHA_FULL", "full" }, + { 0, NULL, NULL } + }; + etype = g_enum_register_static (g_intern_static_string ("GdkPixbufAlphaMode"), values); + } + return etype; +} + +GType +gdk_colorspace_get_type (void) +{ + static GType etype = 0; + + if (G_UNLIKELY(etype == 0)) { + static const GEnumValue values[] = { + { GDK_COLORSPACE_RGB, "GDK_COLORSPACE_RGB", "rgb" }, + { 0, NULL, NULL } + }; + etype = g_enum_register_static (g_intern_static_string ("GdkColorspace"), values); + } + return etype; +} + +GType +gdk_pixbuf_error_get_type (void) +{ + static GType etype = 0; + + if (G_UNLIKELY(etype == 0)) { + static const GEnumValue values[] = { + { GDK_PIXBUF_ERROR_CORRUPT_IMAGE, "GDK_PIXBUF_ERROR_CORRUPT_IMAGE", "corrupt-image" }, + { GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY, "GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY", "insufficient-memory" }, + { GDK_PIXBUF_ERROR_BAD_OPTION, "GDK_PIXBUF_ERROR_BAD_OPTION", "bad-option" }, + { GDK_PIXBUF_ERROR_UNKNOWN_TYPE, "GDK_PIXBUF_ERROR_UNKNOWN_TYPE", "unknown-type" }, + { GDK_PIXBUF_ERROR_UNSUPPORTED_OPERATION, "GDK_PIXBUF_ERROR_UNSUPPORTED_OPERATION", "unsupported-operation" }, + { GDK_PIXBUF_ERROR_FAILED, "GDK_PIXBUF_ERROR_FAILED", "failed" }, + { 0, NULL, NULL } + }; + etype = g_enum_register_static (g_intern_static_string ("GdkPixbufError"), values); + } + return etype; +} + +/* enumerations from "gdk-pixbuf-transform.h" */ +GType +gdk_interp_type_get_type (void) +{ + static GType etype = 0; + + if (G_UNLIKELY(etype == 0)) { + static const GEnumValue values[] = { + { GDK_INTERP_NEAREST, "GDK_INTERP_NEAREST", "nearest" }, + { GDK_INTERP_TILES, "GDK_INTERP_TILES", "tiles" }, + { GDK_INTERP_BILINEAR, "GDK_INTERP_BILINEAR", "bilinear" }, + { GDK_INTERP_HYPER, "GDK_INTERP_HYPER", "hyper" }, + { 0, NULL, NULL } + }; + etype = g_enum_register_static (g_intern_static_string ("GdkInterpType"), values); + } + return etype; +} + +GType +gdk_pixbuf_rotation_get_type (void) +{ + static GType etype = 0; + + if (G_UNLIKELY(etype == 0)) { + static const GEnumValue values[] = { + { GDK_PIXBUF_ROTATE_NONE, "GDK_PIXBUF_ROTATE_NONE", "none" }, + { GDK_PIXBUF_ROTATE_COUNTERCLOCKWISE, "GDK_PIXBUF_ROTATE_COUNTERCLOCKWISE", "counterclockwise" }, + { GDK_PIXBUF_ROTATE_UPSIDEDOWN, "GDK_PIXBUF_ROTATE_UPSIDEDOWN", "upsidedown" }, + { GDK_PIXBUF_ROTATE_CLOCKWISE, "GDK_PIXBUF_ROTATE_CLOCKWISE", "clockwise" }, + { 0, NULL, NULL } + }; + etype = g_enum_register_static (g_intern_static_string ("GdkPixbufRotation"), values); + } + return etype; +} + + +/* Generated data ends here */ + diff --git a/libs/tk/ydk-pixbuf/gdk-pixbuf-io.c b/libs/tk/ydk-pixbuf/gdk-pixbuf-io.c new file mode 100644 index 0000000000..7c50b87460 --- /dev/null +++ b/libs/tk/ydk-pixbuf/gdk-pixbuf-io.c @@ -0,0 +1,3308 @@ +/* -*- mode: C; c-file-style: "linux" -*- */ +/* GdkPixbuf library - Main loading interface. + * + * Copyright (C) 1999 The Free Software Foundation + * + * Authors: Miguel de Icaza + * Federico Mena-Quintero + * + * 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, see . + */ + +#include "config.h" + +#include +#include +#include +#include +#ifdef HAVE_UNISTD_H +#include +#endif + +#include +#include + +#include "gdk-pixbuf-private.h" +#include "gdk-pixbuf-loader.h" +#include "gdk-pixdata.h" + +#include + +#ifdef G_OS_WIN32 +#define STRICT +#include +#undef STRICT +#endif + +/** + * SECTION:file-loading + * @Short_description: Loading a pixbuf from a file. + * @Title: File Loading + * @See_also: #GdkPixbufLoader. + * + * The GdkPixBuf library provides a simple mechanism for loading + * an image from a file in synchronous fashion. This means that the + * library takes control of the application while the file is being + * loaded; from the user's point of view, the application will block + * until the image is done loading. + * + * + * This interface can be used by applications in which blocking is + * acceptable while an image is being loaded. It can also be used to + * load small images in general. Applications that need progressive + * loading can use the #GdkPixbufLoader functionality instead. + */ + +/** + * SECTION:file-saving + * @Short_description: Saving a pixbuf to a file. + * @Title: File saving + * + * These functions allow to save a #GdkPixbuf in a number of + * file formats. The formatted data can be written to a file + * or to a memory buffer. GdkPixBuf can also call a user-defined + * callback on the data, which allows to e.g. write the image + * to a socket or store it in a database. + */ + +/** + * SECTION:module_interface + * @Short_description: Extending GdkPixBuf + * @Title: Module Interface + * + * If GdkPixBuf has been compiled with GModule support, it can be extended by + * modules which can load (and perhaps also save) new image and animation + * formats. Each loadable module must export a + * #GdkPixbufModuleFillInfoFunc function named `fill_info` and + * a #GdkPixbufModuleFillVtableFunc function named + * `fill_vtable`. + * + * In order to make format-checking work before actually loading the modules + * (which may require dlopening image libraries), modules export their + * signatures (and other information) via the `fill_info` function. An + * external utility, gdk-pixbuf-query-loaders, uses this to create a text + * file containing a list of all available loaders and their signatures. + * This file is then read at runtime by GdkPixBuf to obtain the list of + * available loaders and their signatures. + * + * Modules may only implement a subset of the functionality available via + * #GdkPixbufModule. If a particular functionality is not implemented, the + * `fill_vtable` function will simply not set the corresponding + * function pointers of the #GdkPixbufModule structure. If a module supports + * incremental loading (i.e. provides #begin_load, #stop_load and + * #load_increment), it doesn't have to implement #load, since GdkPixBuf can + * supply a generic #load implementation wrapping the incremental loading. + * + * Installing a module is a two-step process: + * - copy the module file(s) to the loader directory (normally + * `$libdir/gdk-pixbuf-2.0/$version/loaders`, unless overridden by the + * environment variable `GDK_PIXBUF_MODULEDIR`) + * - call gdk-pixbuf-query-loaders to update the module file (normally + * `$libdir/gdk-pixbuf-2.0/$version/loaders.cache`, unless overridden by the + * environment variable `GDK_PIXBUF_MODULE_FILE`) + * + * The GdkPixBuf interfaces needed for implementing modules are contained in + * `gdk-pixbuf-io.h` (and `gdk-pixbuf-animation.h` if the module supports + * animations). They are not covered by the same stability guarantees as the + * regular GdkPixBuf API. To underline this fact, they are protected by + * `#ifdef GDK_PIXBUF_ENABLE_BACKEND`. + */ + + +static gint +format_check (GdkPixbufModule *module, guchar *buffer, int size) +{ + int i, j; + gchar m; + GdkPixbufModulePattern *pattern; + gboolean anchored; + guchar *prefix; + gchar *mask; + + for (pattern = module->info->signature; pattern->prefix; pattern++) { + if (pattern->mask && pattern->mask[0] == '*') { + prefix = (guchar *)pattern->prefix + 1; + mask = pattern->mask + 1; + anchored = FALSE; + } + else { + prefix = (guchar *)pattern->prefix; + mask = pattern->mask; + anchored = TRUE; + } + for (i = 0; i < size; i++) { + for (j = 0; i + j < size && prefix[j] != 0; j++) { + m = mask ? mask[j] : ' '; + if (m == ' ') { + if (buffer[i + j] != prefix[j]) + break; + } + else if (m == '!') { + if (buffer[i + j] == prefix[j]) + break; + } + else if (m == 'z') { + if (buffer[i + j] != 0) + break; + } + else if (m == 'n') { + if (buffer[i + j] == 0) + break; + } + } + + if (prefix[j] == 0) + return pattern->relevance; + + if (anchored) + break; + } + } + return 0; +} + +G_LOCK_DEFINE_STATIC (init_lock); + +static GSList *file_formats = NULL; + +static void gdk_pixbuf_io_init (void); + +static GSList * +get_file_formats (void) +{ + G_LOCK (init_lock); + if (file_formats == NULL) + gdk_pixbuf_io_init (); + G_UNLOCK (init_lock); + + return file_formats; +} + +#ifdef G_OS_WIN32 + +/* DllMain function needed to tuck away the gdk-pixbuf DLL handle */ + +static HMODULE gdk_pixbuf_dll; + +BOOL WINAPI +DllMain (HINSTANCE hinstDLL, + DWORD fdwReason, + LPVOID lpvReserved) +{ + switch (fdwReason) { + case DLL_PROCESS_ATTACH: + gdk_pixbuf_dll = (HMODULE) hinstDLL; + break; + } + + return TRUE; +} + +char * +_gdk_pixbuf_win32_get_toplevel (void) +{ + static char *toplevel = NULL; + + if (toplevel == NULL) + toplevel = g_win32_get_package_installation_directory_of_module (gdk_pixbuf_dll); + + return toplevel; +} +#endif + + +#ifdef USE_GMODULE + +static gboolean +scan_string (const char **pos, GString *out) +{ + const char *p = *pos, *q = *pos; + char *tmp, *tmp2; + gboolean quoted; + + while (g_ascii_isspace (*p)) + p++; + + if (!*p) + return FALSE; + else if (*p == '"') { + p++; + quoted = FALSE; + for (q = p; (*q != '"') || quoted; q++) { + if (!*q) + return FALSE; + quoted = (*q == '\\') && !quoted; + } + + tmp = g_strndup (p, q - p); + tmp2 = g_strcompress (tmp); + g_string_truncate (out, 0); + g_string_append (out, tmp2); + g_free (tmp); + g_free (tmp2); + } + + q++; + *pos = q; + + return TRUE; +} + +static gboolean +scan_int (const char **pos, int *out) +{ + int i = 0; + char buf[32]; + const char *p = *pos; + + while (g_ascii_isspace (*p)) + p++; + + if (*p < '0' || *p > '9') + return FALSE; + + while ((*p >= '0') && (*p <= '9') && i < sizeof (buf)) { + buf[i] = *p; + i++; + p++; + } + + if (i == sizeof (buf)) + return FALSE; + else + buf[i] = '\0'; + + *out = atoi (buf); + + *pos = p; + + return TRUE; +} + +static gboolean +skip_space (const char **pos) +{ + const char *p = *pos; + + while (g_ascii_isspace (*p)) + p++; + + *pos = p; + + return !(*p == '\0'); +} + +#ifdef G_OS_WIN32 + +static char * +get_libdir (void) +{ + static char *libdir = NULL; + + if (libdir == NULL) + libdir = g_build_filename (_gdk_pixbuf_win32_get_toplevel (), "lib", NULL); + + return libdir; +} + +#undef GDK_PIXBUF_LIBDIR +#define GDK_PIXBUF_LIBDIR get_libdir() + +static void +correct_prefix (gchar **path) +{ + if (strncmp (*path, GDK_PIXBUF_PREFIX "/", strlen (GDK_PIXBUF_PREFIX "/")) == 0 || + strncmp (*path, GDK_PIXBUF_PREFIX "\\", strlen (GDK_PIXBUF_PREFIX "\\")) == 0) + { + gchar *tem = NULL; + if (strlen(*path) > 5 && strncmp (*path - 5, ".libs", 5) == 0) + { + /* We are being run from inside the build tree, and shouldn't mess about. */ + return; + } + + /* This is an entry put there by gdk-pixbuf-query-loaders on the + * packager's system. On Windows a prebuilt gdk-pixbuf package can be + * installed in a random location. The loaders.cache file + * distributed in such a package contains paths from the package + * builder's machine. Replace the build-time prefix with the + * installation prefix on this machine. + */ + tem = *path; + *path = g_strconcat (_gdk_pixbuf_win32_get_toplevel (), tem + strlen (GDK_PIXBUF_PREFIX), NULL); + g_free (tem); + } +} + +#endif /* G_OS_WIN32 */ + +static gchar * +gdk_pixbuf_get_module_file (void) +{ + gchar *result = g_strdup (g_getenv ("GDK_PIXBUF_MODULE_FILE")); + + if (!result) + result = g_build_filename (GDK_PIXBUF_LIBDIR, "gdk-pixbuf-2.0", GDK_PIXBUF_BINARY_VERSION, "loaders.cache", NULL); + + return result; +} + +#endif /* USE_GMODULE */ + + +static gboolean +gdk_pixbuf_load_module_unlocked (GdkPixbufModule *image_module, + GError **error); + +static void +gdk_pixbuf_io_init (void) +{ +#ifdef USE_GMODULE + GIOChannel *channel; + gchar *line_buf; + gsize term; + GString *tmp_buf = g_string_new (NULL); + gboolean have_error = FALSE; + GdkPixbufModule *module = NULL; + gchar *filename = gdk_pixbuf_get_module_file (); + int flags; + int n_patterns = 0; + GdkPixbufModulePattern *pattern; + GError *error = NULL; +#endif + GdkPixbufModule *builtin_module ; + + /* initialize on separate line to avoid compiler warnings in the + * common case of no compiled-in modules. + */ + builtin_module = NULL; + +#define load_one_builtin_module(format) \ + builtin_module = g_new0 (GdkPixbufModule, 1); \ + builtin_module->module_name = #format; \ + if (gdk_pixbuf_load_module_unlocked (builtin_module, NULL)) \ + file_formats = g_slist_prepend (file_formats, builtin_module);\ + else \ + g_free (builtin_module) + + /* Always include GdkPixdata format */ + load_one_builtin_module (pixdata); + +#ifdef INCLUDE_ani + load_one_builtin_module (ani); +#endif +#ifdef INCLUDE_png + load_one_builtin_module (png); +#endif +#ifdef INCLUDE_bmp + load_one_builtin_module (bmp); +#endif +#ifdef INCLUDE_wbmp + load_one_builtin_module (wbmp); +#endif +#ifdef INCLUDE_gif + load_one_builtin_module (gif); +#endif +#ifdef INCLUDE_ico + load_one_builtin_module (ico); +#endif +#ifdef INCLUDE_jpeg + load_one_builtin_module (jpeg); +#endif +#ifdef INCLUDE_pnm + load_one_builtin_module (pnm); +#endif +#ifdef INCLUDE_ras + load_one_builtin_module (ras); +#endif +#ifdef INCLUDE_tiff + load_one_builtin_module (tiff); +#endif +#ifdef INCLUDE_xpm + load_one_builtin_module (xpm); +#endif +#ifdef INCLUDE_xbm + load_one_builtin_module (xbm); +#endif +#ifdef INCLUDE_tga + load_one_builtin_module (tga); +#endif +#ifdef INCLUDE_pcx + load_one_builtin_module (pcx); +#endif +#ifdef INCLUDE_icns + load_one_builtin_module (icns); +#endif +#ifdef INCLUDE_jasper + load_one_builtin_module (jasper); +#endif +#ifdef INCLUDE_qtif + load_one_builtin_module (qtif); +#endif +#ifdef INCLUDE_gdiplus + /* We don't bother having the GDI+ loaders individually selectable + * for building in or not. + */ + load_one_builtin_module (ico); + load_one_builtin_module (wmf); + load_one_builtin_module (emf); + load_one_builtin_module (bmp); + load_one_builtin_module (gif); + load_one_builtin_module (jpeg); + load_one_builtin_module (tiff); +#endif +#ifdef INCLUDE_gdip_png + /* Except the gdip-png loader which normally isn't built at all even */ + load_one_builtin_module (png); +#endif + +#undef load_one_builtin_module + +#ifdef USE_GMODULE + channel = g_io_channel_new_file (filename, "r", &error); + if (!channel) { + /* Don't bother warning if we have some built-in loaders */ + if (file_formats == NULL || file_formats->next == NULL) + g_warning ("Cannot open pixbuf loader module file '%s': %s\n\n" + "This likely means that your installation is broken.\n" + "Try running the command\n" + " gdk-pixbuf-query-loaders > %s\n" + "to make things work again for the time being.", + filename, error->message, filename); + g_string_free (tmp_buf, TRUE); + g_free (filename); + return; + } + + while (!have_error && g_io_channel_read_line (channel, &line_buf, NULL, &term, NULL) == G_IO_STATUS_NORMAL) { + const char *p; + + p = line_buf; + + line_buf[term] = 0; + + if (!skip_space (&p)) { + /* Blank line marking the end of a module + */ + if (module && *p != '#') { +#ifdef G_OS_WIN32 + correct_prefix (&module->module_path); +#endif + file_formats = g_slist_prepend (file_formats, module); + module = NULL; + } + + goto next_line; + } + + if (*p == '#') + goto next_line; + + if (!module) { + /* Read a module location + */ + module = g_new0 (GdkPixbufModule, 1); + n_patterns = 0; + + if (!scan_string (&p, tmp_buf)) { + g_warning ("Error parsing loader info in '%s'\n %s", + filename, line_buf); + have_error = TRUE; + } + module->module_path = g_strdup (tmp_buf->str); + } + else if (!module->module_name) { + module->info = g_new0 (GdkPixbufFormat, 1); + if (!scan_string (&p, tmp_buf)) { + g_warning ("Error parsing loader info in '%s'\n %s", + filename, line_buf); + have_error = TRUE; + } + module->info->name = g_strdup (tmp_buf->str); + module->module_name = module->info->name; + + if (!scan_int (&p, &flags)) { + g_warning ("Error parsing loader info in '%s'\n %s", + filename, line_buf); + have_error = TRUE; + } + module->info->flags = flags; + + if (!scan_string (&p, tmp_buf)) { + g_warning ("Error parsing loader info in '%s'\n %s", + filename, line_buf); + have_error = TRUE; + } + if (tmp_buf->str[0] != 0) + module->info->domain = g_strdup (tmp_buf->str); + + if (!scan_string (&p, tmp_buf)) { + g_warning ("Error parsing loader info in '%s'\n %s", + filename, line_buf); + have_error = TRUE; + } + module->info->description = g_strdup (tmp_buf->str); + + if (scan_string (&p, tmp_buf)) { + module->info->license = g_strdup (tmp_buf->str); + } + } + else if (!module->info->mime_types) { + int n = 1; + module->info->mime_types = g_new0 (gchar*, 1); + while (scan_string (&p, tmp_buf)) { + if (tmp_buf->str[0] != 0) { + module->info->mime_types = + g_realloc (module->info->mime_types, (n + 1) * sizeof (gchar*)); + module->info->mime_types[n - 1] = g_strdup (tmp_buf->str); + module->info->mime_types[n] = NULL; + n++; + } + } + } + else if (!module->info->extensions) { + int n = 1; + module->info->extensions = g_new0 (gchar*, 1); + while (scan_string (&p, tmp_buf)) { + if (tmp_buf->str[0] != 0) { + module->info->extensions = + g_realloc (module->info->extensions, (n + 1) * sizeof (gchar*)); + module->info->extensions[n - 1] = g_strdup (tmp_buf->str); + module->info->extensions[n] = NULL; + n++; + } + } + } + else { + n_patterns++; + module->info->signature = (GdkPixbufModulePattern *) + g_realloc (module->info->signature, (n_patterns + 1) * sizeof (GdkPixbufModulePattern)); + pattern = module->info->signature + n_patterns; + pattern->prefix = NULL; + pattern->mask = NULL; + pattern->relevance = 0; + pattern--; + if (!scan_string (&p, tmp_buf)) + goto context_error; + pattern->prefix = g_strdup (tmp_buf->str); + + if (!scan_string (&p, tmp_buf)) + goto context_error; + if (*tmp_buf->str) + pattern->mask = g_strdup (tmp_buf->str); + else + pattern->mask = NULL; + + if (!scan_int (&p, &pattern->relevance)) + goto context_error; + + goto next_line; + + context_error: + g_free (pattern->prefix); + g_free (pattern->mask); + g_free (pattern); + g_warning ("Error parsing loader info in '%s'\n %s", + filename, line_buf); + have_error = TRUE; + } + next_line: + g_free (line_buf); + } + g_string_free (tmp_buf, TRUE); + g_io_channel_unref (channel); + g_free (filename); +#endif +} + + +#define module(type) \ + extern void _gdk_pixbuf__##type##_fill_info (GdkPixbufFormat *info); \ + extern void _gdk_pixbuf__##type##_fill_vtable (GdkPixbufModule *module) + +module (pixdata); +module (png); +module (jpeg); +module (gif); +module (ico); +module (ani); +module (ras); +module (xpm); +module (tiff); +module (pnm); +module (bmp); +module (wbmp); +module (xbm); +module (tga); +module (pcx); +module (icns); +module (jasper); +module (qtif); +module (gdip_ico); +module (gdip_wmf); +module (gdip_emf); +module (gdip_bmp); +module (gdip_gif); +module (gdip_jpeg); +module (gdip_png); +module (gdip_tiff); + +#undef module + +/* actually load the image handler - gdk_pixbuf_get_module only get a */ +/* reference to the module to load, it doesn't actually load it */ +/* perhaps these actions should be combined in one function */ +static gboolean +gdk_pixbuf_load_module_unlocked (GdkPixbufModule *image_module, + GError **error) +{ + GdkPixbufModuleFillInfoFunc fill_info = NULL; + GdkPixbufModuleFillVtableFunc fill_vtable = NULL; + + if (image_module->module != NULL) + return TRUE; + +#define try_module(format,id) \ + if (fill_info == NULL && \ + strcmp (image_module->module_name, #format) == 0) { \ + fill_info = _gdk_pixbuf__##id##_fill_info; \ + fill_vtable = _gdk_pixbuf__##id##_fill_vtable; \ + } + + try_module (pixdata,pixdata); + +#ifdef INCLUDE_png + try_module (png,png); +#endif +#ifdef INCLUDE_bmp + try_module (bmp,bmp); +#endif +#ifdef INCLUDE_wbmp + try_module (wbmp,wbmp); +#endif +#ifdef INCLUDE_gif + try_module (gif,gif); +#endif +#ifdef INCLUDE_ico + try_module (ico,ico); +#endif +#ifdef INCLUDE_ani + try_module (ani,ani); +#endif +#ifdef INCLUDE_jpeg + try_module (jpeg,jpeg); +#endif +#ifdef INCLUDE_pnm + try_module (pnm,pnm); +#endif +#ifdef INCLUDE_ras + try_module (ras,ras); +#endif +#ifdef INCLUDE_tiff + try_module (tiff,tiff); +#endif +#ifdef INCLUDE_xpm + try_module (xpm,xpm); +#endif +#ifdef INCLUDE_xbm + try_module (xbm,xbm); +#endif +#ifdef INCLUDE_tga + try_module (tga,tga); +#endif +#ifdef INCLUDE_pcx + try_module (pcx,pcx); +#endif +#ifdef INCLUDE_icns + try_module (icns,icns); +#endif +#ifdef INCLUDE_jasper + try_module (jasper,jasper); +#endif +#ifdef INCLUDE_qtif + try_module (qtif,qtif); +#endif +#ifdef INCLUDE_gdiplus + try_module (ico,gdip_ico); + try_module (wmf,gdip_wmf); + try_module (emf,gdip_emf); + try_module (bmp,gdip_bmp); + try_module (gif,gdip_gif); + try_module (jpeg,gdip_jpeg); + try_module (tiff,gdip_tiff); +#endif +#ifdef INCLUDE_gdip_png + try_module (png,gdip_png); +#endif + +#undef try_module + + if (fill_vtable) { + image_module->module = (void *) 1; + (* fill_vtable) (image_module); + if (image_module->info == NULL) { + image_module->info = g_new0 (GdkPixbufFormat, 1); + (* fill_info) (image_module->info); + } + return TRUE; + } + else +#ifdef USE_GMODULE + { + char *path; + GModule *module; + gpointer sym; + + path = image_module->module_path; + module = g_module_open (path, G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL); + + if (!module) { + g_set_error (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_FAILED, + _("Unable to load image-loading module: %s: %s"), + path, g_module_error ()); + return FALSE; + } + + image_module->module = module; + + if (g_module_symbol (module, "fill_vtable", &sym)) { + fill_vtable = (GdkPixbufModuleFillVtableFunc) sym; + (* fill_vtable) (image_module); + return TRUE; + } else { + g_set_error (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_FAILED, + _("Image-loading module %s does not export the proper interface; perhaps it's from a different gdk-pixbuf version?"), + path); + return FALSE; + } + } +#else + g_set_error (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_UNKNOWN_TYPE, + _("Image type '%s' is not supported"), + image_module->module_name); + return FALSE; +#endif /* !USE_GMODULE */ +} + + +gboolean +_gdk_pixbuf_load_module (GdkPixbufModule *image_module, + GError **error) +{ + gboolean ret; + gboolean locked = FALSE; + + /* be extra careful, maybe the module initializes + * the thread system + */ + if (g_threads_got_initialized) { + G_LOCK (init_lock); + locked = TRUE; + } + + ret = gdk_pixbuf_load_module_unlocked (image_module, error); + + if (locked) + G_UNLOCK (init_lock); + + return ret; +} + + + +GdkPixbufModule * +_gdk_pixbuf_get_named_module (const char *name, + GError **error) +{ + GSList *modules; + + for (modules = get_file_formats (); modules; modules = g_slist_next (modules)) { + GdkPixbufModule *module = (GdkPixbufModule *)modules->data; + + if (module->info->disabled) + continue; + + if (!strcmp (name, module->module_name)) + return module; + } + + g_set_error (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_UNKNOWN_TYPE, + _("Image type '%s' is not supported"), + name); + + return NULL; +} + +GdkPixbufModule * +_gdk_pixbuf_get_module (guchar *buffer, guint size, + const gchar *filename, + GError **error) +{ + GSList *modules; + + GdkPixbufModule *selected = NULL; + gchar *display_name = NULL; +#ifdef GDK_PIXBUF_USE_GIO_MIME + gchar *mime_type; + gchar **mimes; + gchar *type; + gint j; + gboolean uncertain; + + mime_type = g_content_type_guess (NULL, buffer, size, &uncertain); + if ((uncertain || g_str_equal (mime_type, "text/plain")) && filename != NULL) { + g_free (mime_type); + mime_type = g_content_type_guess (filename, buffer, size, NULL); + } + + for (modules = get_file_formats (); modules; modules = g_slist_next (modules)) { + GdkPixbufModule *module = (GdkPixbufModule *)modules->data; + GdkPixbufFormat *info = module->info; + + if (info->disabled) + continue; + + mimes = info->mime_types; + for (j = 0; mimes[j] != NULL; j++) { + type = g_content_type_from_mime_type (mimes[j]); + if (g_content_type_equals (type, mime_type)) { + g_free (type); + selected = module; + break; + } + g_free (type); + } + + if (selected != NULL) + break; + + /* Make sure the builtin GdkPixdata support works even without mime sniffing */ + if (strcmp (info->name, "GdkPixdata") == 0 && + format_check (module, buffer, size) == 100) { + selected = module; + break; + } + } + g_free (mime_type); +#else + gint score, best = 0; + + for (modules = get_file_formats (); modules; modules = g_slist_next (modules)) { + GdkPixbufModule *module = (GdkPixbufModule *)modules->data; + + if (module->info->disabled) + continue; + + score = format_check (module, buffer, size); + if (score > best) { + best = score; + selected = module; + } + if (score >= 100) + break; + } +#endif + + if (selected != NULL) + return selected; + + if (filename) + { + display_name = g_filename_display_name (filename); + g_set_error (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_UNKNOWN_TYPE, + _("Couldn't recognize the image file format for file '%s'"), + display_name); + g_free (display_name); + } + else + g_set_error_literal (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_UNKNOWN_TYPE, + _("Unrecognized image file format")); + + + return NULL; +} + +static +GdkPixbufModule * +_gdk_pixbuf_get_module_for_file (FILE *f, const gchar *filename, GError **error) +{ + guchar buffer[SNIFF_BUFFER_SIZE]; + int size; + + size = fread (&buffer, 1, sizeof (buffer), f); + if (size == 0) { + gchar *display_name; + display_name = g_filename_display_name (filename); + g_set_error (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_CORRUPT_IMAGE, + _("Image file '%s' contains no data"), + display_name); + g_free (display_name); + return NULL; + } + + return _gdk_pixbuf_get_module (buffer, size, filename, error); +} + +static void +prepared_notify (GdkPixbuf *pixbuf, + GdkPixbufAnimation *anim, + gpointer user_data) +{ + if (pixbuf != NULL) + g_object_ref (pixbuf); + *((GdkPixbuf **)user_data) = pixbuf; +} + +static GdkPixbuf * +generic_load_incrementally (GdkPixbufModule *module, FILE *f, GError **error) +{ + GdkPixbuf *pixbuf = NULL; + gpointer context; + + context = module->begin_load (NULL, prepared_notify, NULL, &pixbuf, error); + + if (!context) + goto out; + + while (!feof (f) && !ferror (f)) { + guchar buffer[LOAD_BUFFER_SIZE]; + size_t length; + + length = fread (buffer, 1, sizeof (buffer), f); + if (length > 0) { + if (!module->load_increment (context, buffer, length, error)) { + module->stop_load (context, NULL); + if (pixbuf != NULL) { + g_object_unref (pixbuf); + pixbuf = NULL; + } + goto out; + } + } + } + + if (!module->stop_load (context, error)) { + if (pixbuf != NULL) { + g_object_unref (pixbuf); + pixbuf = NULL; + } + } + +out: + return pixbuf; +} + +GdkPixbuf * +_gdk_pixbuf_generic_image_load (GdkPixbufModule *module, FILE *f, GError **error) +{ + GdkPixbuf *pixbuf = NULL; + + if (module->load != NULL) { + pixbuf = (* module->load) (f, error); + } else if (module->begin_load != NULL) { + pixbuf = generic_load_incrementally (module, f, error); + } else if (module->load_animation != NULL) { + GdkPixbufAnimation *animation; + + animation = (* module->load_animation) (f, error); + if (animation != NULL) { + pixbuf = gdk_pixbuf_animation_get_static_image (animation); + + g_object_ref (pixbuf); + g_object_unref (animation); + } + } + + return pixbuf; +} + +/** + * gdk_pixbuf_new_from_file: + * @filename: Name of file to load, in the GLib file name encoding + * @error: Return location for an error + * + * Creates a new pixbuf by loading an image from a file. The file format is + * detected automatically. If %NULL is returned, then @error will be set. + * Possible errors are in the #GDK_PIXBUF_ERROR and #G_FILE_ERROR domains. + * + * Return value: A newly-created pixbuf with a reference count of 1, or %NULL if + * any of several error conditions occurred: the file could not be opened, + * there was no loader for the file's format, there was not enough memory to + * allocate the image buffer, or the image file contained invalid data. + **/ +GdkPixbuf * +gdk_pixbuf_new_from_file (const char *filename, + GError **error) +{ + GdkPixbuf *pixbuf; + FILE *f; + GdkPixbufModule *image_module; + + g_return_val_if_fail (filename != NULL, NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + f = g_fopen (filename, "rb"); + if (!f) { + gint save_errno = errno; + gchar *display_name; + display_name = g_filename_display_name (filename); + g_set_error (error, + G_FILE_ERROR, + g_file_error_from_errno (save_errno), + _("Failed to open file '%s': %s"), + display_name, + g_strerror (save_errno)); + g_free (display_name); + return NULL; + } + + image_module = _gdk_pixbuf_get_module_for_file (f, filename, error); + if (image_module == NULL) { + fclose (f); + return NULL; + } + + if (!_gdk_pixbuf_load_module (image_module, error)) { + fclose (f); + return NULL; + } + + fseek (f, 0, SEEK_SET); + pixbuf = _gdk_pixbuf_generic_image_load (image_module, f, error); + fclose (f); + + if (pixbuf == NULL && error != NULL && *error == NULL) { + + /* I don't trust these crufty longjmp()'ing image libs + * to maintain proper error invariants, and I don't + * want user code to segfault as a result. We need to maintain + * the invariant that error gets set if NULL is returned. + */ + + gchar *display_name; + display_name = g_filename_display_name (filename); + g_warning ("Bug! gdk-pixbuf loader '%s' didn't set an error on failure.", image_module->module_name); + g_set_error (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_FAILED, + _("Failed to load image '%s': reason not known, probably a corrupt image file"), + display_name); + g_free (display_name); + } else if (error != NULL && *error != NULL) { + /* Add the filename to the error message */ + GError *e = *error; + gchar *old; + gchar *display_name; + + display_name = g_filename_display_name (filename); + old = e->message; + e->message = g_strdup_printf (_("Failed to load image '%s': %s"), + display_name, + old); + g_free (old); + g_free (display_name); + } + + return pixbuf; +} + +#ifdef G_OS_WIN32 + +#undef gdk_pixbuf_new_from_file +GdkPixbuf * +gdk_pixbuf_new_from_file (const char *filename, + GError **error) +{ + gchar *utf8_filename = + g_locale_to_utf8 (filename, -1, NULL, NULL, error); + GdkPixbuf *retval; + + if (utf8_filename == NULL) + return NULL; + + retval = gdk_pixbuf_new_from_file_utf8 (utf8_filename, error); + + g_free (utf8_filename); + + return retval; +} +#endif + + +/** + * gdk_pixbuf_new_from_file_at_size: + * @filename: Name of file to load, in the GLib file name encoding + * @width: The width the image should have or -1 to not constrain the width + * @height: The height the image should have or -1 to not constrain the height + * @error: Return location for an error + * + * Creates a new pixbuf by loading an image from a file. + * The file format is detected automatically. If %NULL is returned, then + * @error will be set. Possible errors are in the #GDK_PIXBUF_ERROR and + * #G_FILE_ERROR domains. + * + * The image will be scaled to fit in the requested size, preserving + * the image's aspect ratio. Note that the returned pixbuf may be smaller + * than @width x @height, if the aspect ratio requires it. To load + * and image at the requested size, regardless of aspect ratio, use + * gdk_pixbuf_new_from_file_at_scale(). + * + * Return value: A newly-created pixbuf with a reference count of 1, or + * %NULL if any of several error conditions occurred: the file could not + * be opened, there was no loader for the file's format, there was not + * enough memory to allocate the image buffer, or the image file contained + * invalid data. + * + * Since: 2.4 + **/ +GdkPixbuf * +gdk_pixbuf_new_from_file_at_size (const char *filename, + int width, + int height, + GError **error) +{ + return gdk_pixbuf_new_from_file_at_scale (filename, + width, height, + TRUE, error); +} + +#ifdef G_OS_WIN32 + +#undef gdk_pixbuf_new_from_file_at_size + +GdkPixbuf * +gdk_pixbuf_new_from_file_at_size (const char *filename, + int width, + int height, + GError **error) +{ + gchar *utf8_filename = + g_locale_to_utf8 (filename, -1, NULL, NULL, error); + GdkPixbuf *retval; + + if (utf8_filename == NULL) + return NULL; + + retval = gdk_pixbuf_new_from_file_at_size_utf8 (utf8_filename, + width, height, + error); + + g_free (utf8_filename); + + return retval; +} +#endif + +typedef struct { + gint width; + gint height; + gboolean preserve_aspect_ratio; +} AtScaleData; + +static void +at_scale_data_async_data_free (AtScaleData *data) +{ + g_slice_free (AtScaleData, data); +} + +static void +at_scale_size_prepared_cb (GdkPixbufLoader *loader, + int width, + int height, + gpointer data) +{ + AtScaleData *info = data; + + g_return_if_fail (width > 0 && height > 0); + + if (info->preserve_aspect_ratio && + (info->width > 0 || info->height > 0)) { + if (info->width < 0) + { + width = width * (double)info->height/(double)height; + height = info->height; + } + else if (info->height < 0) + { + height = height * (double)info->width/(double)width; + width = info->width; + } + else if ((double)height * (double)info->width > + (double)width * (double)info->height) { + width = 0.5 + (double)width * (double)info->height / (double)height; + height = info->height; + } else { + height = 0.5 + (double)height * (double)info->width / (double)width; + width = info->width; + } + } else { + if (info->width > 0) + width = info->width; + if (info->height > 0) + height = info->height; + } + + width = MAX (width, 1); + height = MAX (height, 1); + + gdk_pixbuf_loader_set_size (loader, width, height); +} + +/** + * gdk_pixbuf_new_from_file_at_scale: + * @filename: Name of file to load, in the GLib file name encoding + * @width: The width the image should have or -1 to not constrain the width + * @height: The height the image should have or -1 to not constrain the height + * @preserve_aspect_ratio: %TRUE to preserve the image's aspect ratio + * @error: Return location for an error + * + * Creates a new pixbuf by loading an image from a file. The file format is + * detected automatically. If %NULL is returned, then @error will be set. + * Possible errors are in the #GDK_PIXBUF_ERROR and #G_FILE_ERROR domains. + * The image will be scaled to fit in the requested size, optionally preserving + * the image's aspect ratio. + * + * When preserving the aspect ratio, a @width of -1 will cause the image + * to be scaled to the exact given height, and a @height of -1 will cause + * the image to be scaled to the exact given width. When not preserving + * aspect ratio, a @width or @height of -1 means to not scale the image + * at all in that dimension. Negative values for @width and @height are + * allowed since 2.8. + * + * Return value: A newly-created pixbuf with a reference count of 1, or %NULL + * if any of several error conditions occurred: the file could not be opened, + * there was no loader for the file's format, there was not enough memory to + * allocate the image buffer, or the image file contained invalid data. + * + * Since: 2.6 + **/ +GdkPixbuf * +gdk_pixbuf_new_from_file_at_scale (const char *filename, + int width, + int height, + gboolean preserve_aspect_ratio, + GError **error) +{ + + GdkPixbufLoader *loader; + GdkPixbuf *pixbuf; + guchar buffer[LOAD_BUFFER_SIZE]; + int length; + FILE *f; + AtScaleData info; + GdkPixbufAnimation *animation; + GdkPixbufAnimationIter *iter; + gboolean has_frame; + + g_return_val_if_fail (filename != NULL, NULL); + g_return_val_if_fail (width > 0 || width == -1, NULL); + g_return_val_if_fail (height > 0 || height == -1, NULL); + + f = g_fopen (filename, "rb"); + if (!f) { + gint save_errno = errno; + gchar *display_name = g_filename_display_name (filename); + g_set_error (error, + G_FILE_ERROR, + g_file_error_from_errno (save_errno), + _("Failed to open file '%s': %s"), + display_name, + g_strerror (save_errno)); + g_free (display_name); + return NULL; + } + + loader = _gdk_pixbuf_loader_new_with_filename (filename); + + info.width = width; + info.height = height; + info.preserve_aspect_ratio = preserve_aspect_ratio; + + g_signal_connect (loader, "size-prepared", + G_CALLBACK (at_scale_size_prepared_cb), &info); + + has_frame = FALSE; + while (!has_frame && !feof (f) && !ferror (f)) { + length = fread (buffer, 1, sizeof (buffer), f); + if (length > 0) + if (!gdk_pixbuf_loader_write (loader, buffer, length, error)) { + gdk_pixbuf_loader_close (loader, NULL); + fclose (f); + g_object_unref (loader); + return NULL; + } + + animation = gdk_pixbuf_loader_get_animation (loader); + if (animation) { + iter = gdk_pixbuf_animation_get_iter (animation, NULL); + if (!gdk_pixbuf_animation_iter_on_currently_loading_frame (iter)) { + has_frame = TRUE; + } + g_object_unref (iter); + } + } + + fclose (f); + + if (!gdk_pixbuf_loader_close (loader, error) && !has_frame) { + g_object_unref (loader); + return NULL; + } + + pixbuf = gdk_pixbuf_loader_get_pixbuf (loader); + + if (!pixbuf) { + gchar *display_name = g_filename_display_name (filename); + g_object_unref (loader); + g_set_error (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_FAILED, + _("Failed to load image '%s': reason not known, probably a corrupt image file"), + display_name); + g_free (display_name); + return NULL; + } + + g_object_ref (pixbuf); + + g_object_unref (loader); + + return pixbuf; +} + +#ifdef G_OS_WIN32 + +#undef gdk_pixbuf_new_from_file_at_scale + +GdkPixbuf * +gdk_pixbuf_new_from_file_at_scale (const char *filename, + int width, + int height, + gboolean preserve_aspect_ratio, + GError **error) +{ + gchar *utf8_filename = + g_locale_to_utf8 (filename, -1, NULL, NULL, error); + GdkPixbuf *retval; + + if (utf8_filename == NULL) + return NULL; + + retval = gdk_pixbuf_new_from_file_at_scale_utf8 (utf8_filename, + width, height, + preserve_aspect_ratio, + error); + + g_free (utf8_filename); + + return retval; +} +#endif + + +static GdkPixbuf * +load_from_stream (GdkPixbufLoader *loader, + GInputStream *stream, + GCancellable *cancellable, + GError **error) +{ + GdkPixbuf *pixbuf; + gssize n_read; + guchar buffer[LOAD_BUFFER_SIZE]; + gboolean res; + + res = TRUE; + while (1) { + n_read = g_input_stream_read (stream, + buffer, + sizeof (buffer), + cancellable, + error); + if (n_read < 0) { + res = FALSE; + error = NULL; /* Ignore further errors */ + break; + } + + if (n_read == 0) + break; + + if (!gdk_pixbuf_loader_write (loader, + buffer, + n_read, + error)) { + res = FALSE; + error = NULL; + break; + } + } + + if (!gdk_pixbuf_loader_close (loader, error)) { + res = FALSE; + error = NULL; + } + + pixbuf = NULL; + if (res) { + pixbuf = gdk_pixbuf_loader_get_pixbuf (loader); + if (pixbuf) + g_object_ref (pixbuf); + } + + return pixbuf; +} + + +/** + * gdk_pixbuf_new_from_stream_at_scale: + * @stream: a #GInputStream to load the pixbuf from + * @width: The width the image should have or -1 to not constrain the width + * @height: The height the image should have or -1 to not constrain the height + * @preserve_aspect_ratio: %TRUE to preserve the image's aspect ratio + * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore + * @error: Return location for an error + * + * Creates a new pixbuf by loading an image from an input stream. + * + * The file format is detected automatically. If %NULL is returned, then + * @error will be set. The @cancellable can be used to abort the operation + * from another thread. If the operation was cancelled, the error + * %G_IO_ERROR_CANCELLED will be returned. Other possible errors are in + * the #GDK_PIXBUF_ERROR and %G_IO_ERROR domains. + * + * The image will be scaled to fit in the requested size, optionally + * preserving the image's aspect ratio. + * + * When preserving the aspect ratio, a @width of -1 will cause the image to be + * scaled to the exact given height, and a @height of -1 will cause the image + * to be scaled to the exact given width. If both @width and @height are + * given, this function will behave as if the smaller of the two values + * is passed as -1. + * + * When not preserving aspect ratio, a @width or @height of -1 means to not + * scale the image at all in that dimension. + * + * The stream is not closed. + * + * Return value: A newly-created pixbuf, or %NULL if any of several error + * conditions occurred: the file could not be opened, the image format is + * not supported, there was not enough memory to allocate the image buffer, + * the stream contained invalid data, or the operation was cancelled. + * + * Since: 2.14 + */ +GdkPixbuf * +gdk_pixbuf_new_from_stream_at_scale (GInputStream *stream, + gint width, + gint height, + gboolean preserve_aspect_ratio, + GCancellable *cancellable, + GError **error) +{ + GdkPixbufLoader *loader; + GdkPixbuf *pixbuf; + AtScaleData info; + + loader = gdk_pixbuf_loader_new (); + + info.width = width; + info.height = height; + info.preserve_aspect_ratio = preserve_aspect_ratio; + + g_signal_connect (loader, "size-prepared", + G_CALLBACK (at_scale_size_prepared_cb), &info); + + pixbuf = load_from_stream (loader, stream, cancellable, error); + g_object_unref (loader); + + return pixbuf; +} + +static void +new_from_stream_thread (GTask *task, + GInputStream *stream, + AtScaleData *data, + GCancellable *cancellable) +{ + GdkPixbuf *pixbuf = NULL; + GError *error = NULL; + + /* If data != NULL, we're scaling the pixbuf while loading it */ + if (data != NULL) + pixbuf = gdk_pixbuf_new_from_stream_at_scale (stream, data->width, data->height, data->preserve_aspect_ratio, cancellable, &error); + else + pixbuf = gdk_pixbuf_new_from_stream (stream, cancellable, &error); + + /* Set the new pixbuf as the result, or error out */ + if (pixbuf == NULL) { + g_task_return_error (task, error); + } else { + g_task_return_pointer (task, g_object_ref (pixbuf), g_object_unref); + } + + g_clear_object (&pixbuf); +} + +/** + * gdk_pixbuf_new_from_stream_at_scale_async: + * @stream: a #GInputStream from which to load the pixbuf + * @width: the width the image should have or -1 to not constrain the width + * @height: the height the image should have or -1 to not constrain the height + * @preserve_aspect_ratio: %TRUE to preserve the image's aspect ratio + * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore + * @callback: a #GAsyncReadyCallback to call when the the pixbuf is loaded + * @user_data: the data to pass to the callback function + * + * Creates a new pixbuf by asynchronously loading an image from an input stream. + * + * For more details see gdk_pixbuf_new_from_stream_at_scale(), which is the synchronous + * version of this function. + * + * When the operation is finished, @callback will be called in the main thread. + * You can then call gdk_pixbuf_new_from_stream_finish() to get the result of the operation. + * + * Since: 2.24 + **/ +void +gdk_pixbuf_new_from_stream_at_scale_async (GInputStream *stream, + gint width, + gint height, + gboolean preserve_aspect_ratio, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + AtScaleData *data; + + g_return_if_fail (G_IS_INPUT_STREAM (stream)); + g_return_if_fail (callback != NULL); + g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable)); + + data = g_slice_new (AtScaleData); + data->width = width; + data->height = height; + data->preserve_aspect_ratio = preserve_aspect_ratio; + + task = g_task_new (stream, cancellable, callback, user_data); + g_task_set_source_tag (task, gdk_pixbuf_new_from_stream_at_scale_async); + g_task_set_task_data (task, data, (GDestroyNotify) at_scale_data_async_data_free); + g_task_run_in_thread (task, (GTaskThreadFunc) new_from_stream_thread); + g_object_unref (task); +} + +/** + * gdk_pixbuf_new_from_stream: + * @stream: a #GInputStream to load the pixbuf from + * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore + * @error: Return location for an error + * + * Creates a new pixbuf by loading an image from an input stream. + * + * The file format is detected automatically. If %NULL is returned, then + * @error will be set. The @cancellable can be used to abort the operation + * from another thread. If the operation was cancelled, the error + * %G_IO_ERROR_CANCELLED will be returned. Other possible errors are in + * the #GDK_PIXBUF_ERROR and %G_IO_ERROR domains. + * + * The stream is not closed. + * + * Return value: A newly-created pixbuf, or %NULL if any of several error + * conditions occurred: the file could not be opened, the image format is + * not supported, there was not enough memory to allocate the image buffer, + * the stream contained invalid data, or the operation was cancelled. + * + * Since: 2.14 + **/ +GdkPixbuf * +gdk_pixbuf_new_from_stream (GInputStream *stream, + GCancellable *cancellable, + GError **error) +{ + GdkPixbuf *pixbuf; + GdkPixbufLoader *loader; + + loader = gdk_pixbuf_loader_new (); + pixbuf = load_from_stream (loader, stream, cancellable, error); + g_object_unref (loader); + + return pixbuf; +} + +GdkPixbuf * +_gdk_pixbuf_new_from_resource_try_mmap (const char *resource_path) +{ + guint32 flags; + gsize data_size; + GBytes *bytes; + + /* We specialize uncompressed GdkPixdata files, making these a reference to the + compiled-in resource data */ + if (g_resources_get_info (resource_path, 0, &data_size, &flags, NULL) && + (flags & G_RESOURCE_FLAGS_COMPRESSED) == 0 && + data_size >= GDK_PIXDATA_HEADER_LENGTH && + (bytes = g_resources_lookup_data (resource_path, 0, NULL)) != NULL) { + GdkPixbuf*pixbuf = NULL; + const guint8 *stream = g_bytes_get_data (bytes, NULL); + GdkPixdata pixdata; + guint32 magic; + + magic = (stream[0] << 24) + (stream[1] << 16) + (stream[2] << 8) + stream[3]; + if (magic == GDK_PIXBUF_MAGIC_NUMBER && + gdk_pixdata_deserialize (&pixdata, data_size, stream, NULL)) { + pixbuf = gdk_pixbuf_from_pixdata (&pixdata, FALSE, NULL); + } + + if (pixbuf) { + /* Free the GBytes with the pixbuf */ + g_object_set_data_full (G_OBJECT (pixbuf), "gdk-pixbuf-resource-bytes", bytes, (GDestroyNotify) g_bytes_unref); + return pixbuf; + } else { + g_bytes_unref (bytes); + } + } + + return NULL; +} + +/** + * gdk_pixbuf_new_from_resource: + * @resource_path: the path of the resource file + * @error: Return location for an error + * + * Creates a new pixbuf by loading an image from an resource. + * + * The file format is detected automatically. If %NULL is returned, then + * @error will be set. + * + * Return value: A newly-created pixbuf, or %NULL if any of several error + * conditions occurred: the file could not be opened, the image format is + * not supported, there was not enough memory to allocate the image buffer, + * the stream contained invalid data, or the operation was cancelled. + * + * Since: 2.26 + **/ +GdkPixbuf * +gdk_pixbuf_new_from_resource (const char *resource_path, + GError **error) +{ + GInputStream *stream; + GdkPixbuf *pixbuf; + + pixbuf = _gdk_pixbuf_new_from_resource_try_mmap (resource_path); + if (pixbuf) + return pixbuf; + + stream = g_resources_open_stream (resource_path, 0, error); + if (stream == NULL) + return NULL; + + pixbuf = gdk_pixbuf_new_from_stream (stream, NULL, error); + g_object_unref (stream); + return pixbuf; +} + +/** + * gdk_pixbuf_new_from_resource_at_scale: + * @resource_path: the path of the resource file + * @width: The width the image should have or -1 to not constrain the width + * @height: The height the image should have or -1 to not constrain the height + * @preserve_aspect_ratio: %TRUE to preserve the image's aspect ratio + * @error: Return location for an error + * + * Creates a new pixbuf by loading an image from an resource. + * + * The file format is detected automatically. If %NULL is returned, then + * @error will be set. + * + * The image will be scaled to fit in the requested size, optionally + * preserving the image's aspect ratio. When preserving the aspect ratio, + * a @width of -1 will cause the image to be scaled to the exact given + * height, and a @height of -1 will cause the image to be scaled to the + * exact given width. When not preserving aspect ratio, a @width or + * @height of -1 means to not scale the image at all in that dimension. + * + * The stream is not closed. + * + * Return value: A newly-created pixbuf, or %NULL if any of several error + * conditions occurred: the file could not be opened, the image format is + * not supported, there was not enough memory to allocate the image buffer, + * the stream contained invalid data, or the operation was cancelled. + * + * Since: 2.26 + */ +GdkPixbuf * +gdk_pixbuf_new_from_resource_at_scale (const char *resource_path, + int width, + int height, + gboolean preserve_aspect_ratio, + GError **error) +{ + GInputStream *stream; + GdkPixbuf *pixbuf; + + stream = g_resources_open_stream (resource_path, 0, error); + if (stream == NULL) + return NULL; + + pixbuf = gdk_pixbuf_new_from_stream_at_scale (stream, width, height, preserve_aspect_ratio, NULL, error); + g_object_unref (stream); + return pixbuf; +} + +/** + * gdk_pixbuf_new_from_stream_async: + * @stream: a #GInputStream from which to load the pixbuf + * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore + * @callback: a #GAsyncReadyCallback to call when the the pixbuf is loaded + * @user_data: the data to pass to the callback function + * + * Creates a new pixbuf by asynchronously loading an image from an input stream. + * + * For more details see gdk_pixbuf_new_from_stream(), which is the synchronous + * version of this function. + * + * When the operation is finished, @callback will be called in the main thread. + * You can then call gdk_pixbuf_new_from_stream_finish() to get the result of the operation. + * + * Since: 2.24 + **/ +void +gdk_pixbuf_new_from_stream_async (GInputStream *stream, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + + g_return_if_fail (G_IS_INPUT_STREAM (stream)); + g_return_if_fail (callback != NULL); + g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable)); + + task = g_task_new (stream, cancellable, callback, user_data); + g_task_set_source_tag (task, gdk_pixbuf_new_from_stream_async); + g_task_run_in_thread (task, (GTaskThreadFunc) new_from_stream_thread); + g_object_unref (task); +} + +/** + * gdk_pixbuf_new_from_stream_finish: + * @async_result: a #GAsyncResult + * @error: a #GError, or %NULL + * + * Finishes an asynchronous pixbuf creation operation started with + * gdk_pixbuf_new_from_stream_async(). + * + * Return value: a #GdkPixbuf or %NULL on error. Free the returned + * object with g_object_unref(). + * + * Since: 2.24 + **/ +GdkPixbuf * +gdk_pixbuf_new_from_stream_finish (GAsyncResult *async_result, + GError **error) +{ + GTask *task; + + /* Can not use g_task_is_valid because our GTask has a + * source_object which is not available to us anymore. + */ + g_return_val_if_fail (G_IS_TASK (async_result), NULL); + + task = G_TASK (async_result); + + g_return_val_if_fail (!error || (error && !*error), NULL); + g_warn_if_fail (g_task_get_source_tag (task) == gdk_pixbuf_new_from_stream_async || + g_task_get_source_tag (task) == gdk_pixbuf_new_from_stream_at_scale_async); + + return g_task_propagate_pointer (task, error); +} + +static void +info_cb (GdkPixbufLoader *loader, + int width, + int height, + gpointer data) +{ + struct { + GdkPixbufFormat *format; + int width; + int height; + } *info = data; + + g_return_if_fail (width > 0 && height > 0); + + info->format = gdk_pixbuf_loader_get_format (loader); + info->width = width; + info->height = height; + + gdk_pixbuf_loader_set_size (loader, 0, 0); +} + +/** + * gdk_pixbuf_get_file_info: + * @filename: The name of the file to identify. + * @width: (optional) (out): Return location for the width of the + * image, or %NULL + * @height: (optional) (out): Return location for the height of the + * image, or %NULL + * + * Parses an image file far enough to determine its format and size. + * + * Returns: (nullable) (transfer none): A #GdkPixbufFormat describing + * the image format of the file or %NULL if the image format wasn't + * recognized. The return value is owned by #GdkPixbuf and should + * not be freed. + * + * Since: 2.4 + **/ +GdkPixbufFormat * +gdk_pixbuf_get_file_info (const gchar *filename, + gint *width, + gint *height) +{ + GdkPixbufLoader *loader; + guchar buffer[SNIFF_BUFFER_SIZE]; + int length; + FILE *f; + struct { + GdkPixbufFormat *format; + gint width; + gint height; + } info; + + g_return_val_if_fail (filename != NULL, NULL); + + f = g_fopen (filename, "rb"); + if (!f) + return NULL; + + loader = _gdk_pixbuf_loader_new_with_filename (filename); + + info.format = NULL; + info.width = -1; + info.height = -1; + + g_signal_connect (loader, "size-prepared", G_CALLBACK (info_cb), &info); + + while (!feof (f) && !ferror (f)) { + length = fread (buffer, 1, sizeof (buffer), f); + if (length > 0) { + if (!gdk_pixbuf_loader_write (loader, buffer, length, NULL)) + break; + } + if (info.format != NULL) + break; + } + + fclose (f); + gdk_pixbuf_loader_close (loader, NULL); + g_object_unref (loader); + + if (width) + *width = info.width; + if (height) + *height = info.height; + + return info.format; +} + +typedef struct { + gchar *filename; + gint width; + gint height; +} GetFileInfoAsyncData; + +static void +get_file_info_async_data_free (GetFileInfoAsyncData *data) +{ + g_free (data->filename); + g_slice_free (GetFileInfoAsyncData, data); +} + +static void +get_file_info_thread (GTask *task, + gpointer source_object, + GetFileInfoAsyncData *data, + GCancellable *cancellable) +{ + GdkPixbufFormat *format; + + format = gdk_pixbuf_get_file_info (data->filename, &data->width, &data->height); + if (format == NULL) { + g_task_return_new_error (task, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_UNKNOWN_TYPE, + "Failed to recognize image format"); + } else { + g_task_return_pointer (task, + gdk_pixbuf_format_copy (format), + (GDestroyNotify) gdk_pixbuf_format_free); + } +} + +/** + * gdk_pixbuf_get_file_info_async: + * @filename: The name of the file to identify + * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore + * @callback: a #GAsyncReadyCallback to call when the the pixbuf is loaded + * @user_data: the data to pass to the callback function + * + * Asynchronously parses an image file far enough to determine its + * format and size. + * + * For more details see gdk_pixbuf_get_file_info(), which is the synchronous + * version of this function. + * + * When the operation is finished, @callback will be called in the + * main thread. You can then call gdk_pixbuf_get_file_info_finish() to + * get the result of the operation. + * + * Since: 2.32 + **/ +void +gdk_pixbuf_get_file_info_async (const gchar *filename, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GetFileInfoAsyncData *data; + GTask *task; + + g_return_if_fail (filename != NULL); + g_return_if_fail (callback != NULL); + g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable)); + + data = g_slice_new0 (GetFileInfoAsyncData); + data->filename = g_strdup (filename); + + task = g_task_new (NULL, cancellable, callback, user_data); + g_task_set_return_on_cancel (task, TRUE); + g_task_set_source_tag (task, gdk_pixbuf_get_file_info_async); + g_task_set_task_data (task, data, (GDestroyNotify) get_file_info_async_data_free); + g_task_run_in_thread (task, (GTaskThreadFunc) get_file_info_thread); + g_object_unref (task); +} + +/** + * gdk_pixbuf_get_file_info_finish: + * @async_result: a #GAsyncResult + * @width: (out): Return location for the width of the image, or %NULL + * @height: (out): Return location for the height of the image, or %NULL + * @error: a #GError, or %NULL + * + * Finishes an asynchronous pixbuf parsing operation started with + * gdk_pixbuf_get_file_info_async(). + * + * Returns: (transfer none): A #GdkPixbufFormat describing the image + * format of the file or %NULL if the image format wasn't + * recognized. The return value is owned by GdkPixbuf and should + * not be freed. + * + * Since: 2.32 + **/ +GdkPixbufFormat * +gdk_pixbuf_get_file_info_finish (GAsyncResult *async_result, + gint *width, + gint *height, + GError **error) +{ + GetFileInfoAsyncData *data; + GTask *task; + + g_return_val_if_fail (g_task_is_valid (async_result, NULL), NULL); + + task = G_TASK (async_result); + + g_return_val_if_fail (!error || (error && !*error), NULL); + g_warn_if_fail (g_task_get_source_tag (task) == gdk_pixbuf_get_file_info_async); + + data = g_task_get_task_data (task); + + if (!g_task_had_error (task)) { + if (width) + *width = data->width; + if (height) + *height = data->height; + } + + return g_task_propagate_pointer (task, error); +} + +/** + * gdk_pixbuf_new_from_xpm_data: + * @data: (array zero-terminated=1): Pointer to inline XPM data. + * + * Creates a new pixbuf by parsing XPM data in memory. This data is commonly + * the result of including an XPM file into a program's C source. + * + * Return value: A newly-created pixbuf with a reference count of 1. + **/ +GdkPixbuf * +gdk_pixbuf_new_from_xpm_data (const char **data) +{ + GdkPixbuf *(* load_xpm_data) (const char **data); + GdkPixbuf *pixbuf; + GError *error = NULL; + GdkPixbufModule *xpm_module; + + g_return_val_if_fail (data != NULL, NULL); + + xpm_module = _gdk_pixbuf_get_named_module ("xpm", &error); + if (xpm_module == NULL) { + g_warning ("Error loading XPM image loader: %s", error->message); + g_error_free (error); + return NULL; + } + + if (!_gdk_pixbuf_load_module (xpm_module, &error)) { + g_warning ("Error loading XPM image loader: %s", error->message); + g_error_free (error); + return NULL; + } + + if (xpm_module->load_xpm_data == NULL) { + g_warning ("gdk-pixbuf XPM module lacks XPM data capability"); + pixbuf = NULL; + } else { + load_xpm_data = xpm_module->load_xpm_data; + pixbuf = (* load_xpm_data) (data); + } + + return pixbuf; +} + +static void +collect_save_options (va_list opts, + gchar ***keys, + gchar ***vals) +{ + gchar *key; + gchar *val; + gchar *next; + gint count; + + count = 0; + *keys = NULL; + *vals = NULL; + + next = va_arg (opts, gchar*); + while (next) + { + key = next; + val = va_arg (opts, gchar*); + + ++count; + + /* woo, slow */ + *keys = g_realloc (*keys, sizeof(gchar*) * (count + 1)); + *vals = g_realloc (*vals, sizeof(gchar*) * (count + 1)); + + (*keys)[count-1] = g_strdup (key); + (*vals)[count-1] = g_strdup (val); + + (*keys)[count] = NULL; + (*vals)[count] = NULL; + + next = va_arg (opts, gchar*); + } +} + +static gboolean +save_to_file_callback (const gchar *buf, + gsize count, + GError **error, + gpointer data) +{ + FILE *filehandle = data; + gsize n; + + n = fwrite (buf, 1, count, filehandle); + if (n != count) { + gint save_errno = errno; + g_set_error (error, + G_FILE_ERROR, + g_file_error_from_errno (save_errno), + _("Error writing to image file: %s"), + g_strerror (save_errno)); + return FALSE; + } + return TRUE; +} + +static gboolean +gdk_pixbuf_real_save (GdkPixbuf *pixbuf, + FILE *filehandle, + const char *type, + gchar **keys, + gchar **values, + GError **error) +{ + gboolean ret; + GdkPixbufModule *image_module = NULL; + + image_module = _gdk_pixbuf_get_named_module (type, error); + + if (image_module == NULL) + return FALSE; + + if (!_gdk_pixbuf_load_module (image_module, error)) + return FALSE; + + if (image_module->save) { + /* save normally */ + ret = (* image_module->save) (filehandle, pixbuf, + keys, values, + error); + } else if (image_module->save_to_callback) { + /* save with simple callback */ + ret = (* image_module->save_to_callback) (save_to_file_callback, + filehandle, pixbuf, + keys, values, + error); + } else { + /* can't save */ + g_set_error (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_UNSUPPORTED_OPERATION, + _("This build of gdk-pixbuf does not support saving the image format: %s"), + type); + ret = FALSE; + } + + return ret; +} + +#define TMP_FILE_BUF_SIZE 4096 + +static gboolean +save_to_callback_with_tmp_file (GdkPixbufModule *image_module, + GdkPixbuf *pixbuf, + GdkPixbufSaveFunc save_func, + gpointer user_data, + gchar **keys, + gchar **values, + GError **error) +{ + int fd; + FILE *f = NULL; + gboolean retval = FALSE; + gchar *buf = NULL; + gsize n; + gchar *filename = NULL; + + buf = g_try_malloc (TMP_FILE_BUF_SIZE); + if (buf == NULL) { + g_set_error_literal (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY, + _("Insufficient memory to save image to callback")); + goto end; + } + + fd = g_file_open_tmp ("gdkpixbuf-save-tmp.XXXXXX", &filename, error); + if (fd == -1) + goto end; + f = fdopen (fd, "wb+"); + if (f == NULL) { + gint save_errno = errno; + g_set_error_literal (error, + G_FILE_ERROR, + g_file_error_from_errno (save_errno), + _("Failed to open temporary file")); + goto end; + } + + retval = (image_module->save) (f, pixbuf, keys, values, error); + if (!retval) + goto end; + + rewind (f); + for (;;) { + n = fread (buf, 1, TMP_FILE_BUF_SIZE, f); + if (n > 0) { + if (!save_func (buf, n, error, user_data)) + goto end; + } + if (n != TMP_FILE_BUF_SIZE) + break; + } + if (ferror (f)) { + gint save_errno = errno; + g_set_error_literal (error, + G_FILE_ERROR, + g_file_error_from_errno (save_errno), + _("Failed to read from temporary file")); + goto end; + } + retval = TRUE; + + end: + /* cleanup and return retval */ + if (f) + fclose (f); + if (filename) { + g_unlink (filename); + g_free (filename); + } + g_free (buf); + + return retval; +} + +static gboolean +gdk_pixbuf_real_save_to_callback (GdkPixbuf *pixbuf, + GdkPixbufSaveFunc save_func, + gpointer user_data, + const char *type, + gchar **keys, + gchar **values, + GError **error) +{ + gboolean ret; + GdkPixbufModule *image_module = NULL; + + image_module = _gdk_pixbuf_get_named_module (type, error); + + if (image_module == NULL) + return FALSE; + + if (!_gdk_pixbuf_load_module (image_module, error)) + return FALSE; + + if (image_module->save_to_callback) { + /* save normally */ + ret = (* image_module->save_to_callback) (save_func, user_data, + pixbuf, keys, values, + error); + } else if (image_module->save) { + /* use a temporary file */ + ret = save_to_callback_with_tmp_file (image_module, pixbuf, + save_func, user_data, + keys, values, + error); + } else { + /* can't save */ + g_set_error (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_UNSUPPORTED_OPERATION, + _("This build of gdk-pixbuf does not support saving the image format: %s"), + type); + ret = FALSE; + } + + return ret; +} + + +/** + * gdk_pixbuf_save: + * @pixbuf: a #GdkPixbuf. + * @filename: name of file to save. + * @type: name of file format. + * @error: (allow-none): return location for error, or %NULL + * @...: list of key-value save options, followed by %NULL + * + * Saves pixbuf to a file in format @type. By default, "jpeg", "png", "ico" + * and "bmp" are possible file formats to save in, but more formats may be + * installed. The list of all writable formats can be determined in the + * following way: + * + * |[ + * void add_if_writable (GdkPixbufFormat *data, GSList **list) + * { + * if (gdk_pixbuf_format_is_writable (data)) + * *list = g_slist_prepend (*list, data); + * } + * + * GSList *formats = gdk_pixbuf_get_formats (); + * GSList *writable_formats = NULL; + * g_slist_foreach (formats, add_if_writable, &writable_formats); + * g_slist_free (formats); + * ]| + * + * If @error is set, %FALSE will be returned. Possible errors include + * those in the #GDK_PIXBUF_ERROR domain and those in the #G_FILE_ERROR domain. + * + * The variable argument list should be %NULL-terminated; if not empty, + * it should contain pairs of strings that modify the save + * parameters. For example: + * |[ + * gdk_pixbuf_save (pixbuf, handle, "jpeg", &error, "quality", "100", NULL); + * ]| + * + * Currently only few parameters exist. JPEG images can be saved with a + * "quality" parameter; its value should be in the range [0,100]. + * + * Text chunks can be attached to PNG images by specifying parameters of + * the form "tEXt::key", where key is an ASCII string of length 1-79. + * The values are UTF-8 encoded strings. The PNG compression level can + * be specified using the "compression" parameter; it's value is in an + * integer in the range of [0,9]. + * + * ICC color profiles can also be embedded into PNG, JPEG and TIFF images. + * The "icc-profile" value should be the complete ICC profile encoded + * into base64. + * + * |[ + * gchar *contents; + * gchar *contents_encode; + * gsize length; + * g_file_get_contents ("/home/hughsie/.color/icc/L225W.icm", &contents, &length, NULL); + * contents_encode = g_base64_encode ((const guchar *) contents, length); + * gdk_pixbuf_save (pixbuf, handle, "png", &error, "icc-profile", contents_encode, NULL); + * ]| + * + * TIFF images recognize a "compression" option which acceps an integer value. + * Among the codecs are 1 None, 2 Huffman, 5 LZW, 7 JPEG and 8 Deflate, see + * the libtiff documentation and tiff.h for all supported codec values. + * + * ICO images can be saved in depth 16, 24, or 32, by using the "depth" + * parameter. When the ICO saver is given "x_hot" and "y_hot" parameters, + * it produces a CUR instead of an ICO. + * + * Return value: whether an error was set + **/ +gboolean +gdk_pixbuf_save (GdkPixbuf *pixbuf, + const char *filename, + const char *type, + GError **error, + ...) +{ + gchar **keys = NULL; + gchar **values = NULL; + va_list args; + gboolean result; + + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + va_start (args, error); + + collect_save_options (args, &keys, &values); + + va_end (args); + + result = gdk_pixbuf_savev (pixbuf, filename, type, + keys, values, + error); + + g_strfreev (keys); + g_strfreev (values); + + return result; +} + +#ifdef G_OS_WIN32 + +#undef gdk_pixbuf_save + +gboolean +gdk_pixbuf_save (GdkPixbuf *pixbuf, + const char *filename, + const char *type, + GError **error, + ...) +{ + char *utf8_filename; + gchar **keys = NULL; + gchar **values = NULL; + va_list args; + gboolean result; + + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + utf8_filename = g_locale_to_utf8 (filename, -1, NULL, NULL, error); + + if (utf8_filename == NULL) + return FALSE; + + va_start (args, error); + + collect_save_options (args, &keys, &values); + + va_end (args); + + result = gdk_pixbuf_savev_utf8 (pixbuf, utf8_filename, type, + keys, values, + error); + + g_free (utf8_filename); + + g_strfreev (keys); + g_strfreev (values); + + return result; +} + +#endif + +/** + * gdk_pixbuf_savev: + * @pixbuf: a #GdkPixbuf. + * @filename: name of file to save. + * @type: name of file format. + * @option_keys: (array zero-terminated=1): name of options to set, %NULL-terminated + * @option_values: (array zero-terminated=1): values for named options + * @error: (allow-none): return location for error, or %NULL + * + * Saves pixbuf to a file in @type, which is currently "jpeg", "png", "tiff", "ico" or "bmp". + * If @error is set, %FALSE will be returned. + * See gdk_pixbuf_save () for more details. + * + * Return value: whether an error was set + **/ + +gboolean +gdk_pixbuf_savev (GdkPixbuf *pixbuf, + const char *filename, + const char *type, + char **option_keys, + char **option_values, + GError **error) +{ + FILE *f = NULL; + gboolean result; + + g_return_val_if_fail (filename != NULL, FALSE); + g_return_val_if_fail (type != NULL, FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + f = g_fopen (filename, "wb"); + + if (f == NULL) { + gint save_errno = errno; + gchar *display_name = g_filename_display_name (filename); + g_set_error (error, + G_FILE_ERROR, + g_file_error_from_errno (save_errno), + _("Failed to open '%s' for writing: %s"), + display_name, + g_strerror (save_errno)); + g_free (display_name); + return FALSE; + } + + + result = gdk_pixbuf_real_save (pixbuf, f, type, + option_keys, option_values, + error); + + + if (!result) { + g_return_val_if_fail (error == NULL || *error != NULL, FALSE); + fclose (f); + g_unlink (filename); + return FALSE; + } + + if (fclose (f) < 0) { + gint save_errno = errno; + gchar *display_name = g_filename_display_name (filename); + g_set_error (error, + G_FILE_ERROR, + g_file_error_from_errno (save_errno), + _("Failed to close '%s' while writing image, all data may not have been saved: %s"), + display_name, + g_strerror (save_errno)); + g_free (display_name); + return FALSE; + } + + return TRUE; +} + +#ifdef G_OS_WIN32 + +#undef gdk_pixbuf_savev + +gboolean +gdk_pixbuf_savev (GdkPixbuf *pixbuf, + const char *filename, + const char *type, + char **option_keys, + char **option_values, + GError **error) +{ + char *utf8_filename; + gboolean retval; + + g_return_val_if_fail (filename != NULL, FALSE); + + utf8_filename = g_locale_to_utf8 (filename, -1, NULL, NULL, error); + + if (utf8_filename == NULL) + return FALSE; + + retval = gdk_pixbuf_savev_utf8 (pixbuf, utf8_filename, type, + option_keys, option_values, error); + + g_free (utf8_filename); + + return retval; +} + +#endif + +/** + * gdk_pixbuf_save_to_callback: + * @pixbuf: a #GdkPixbuf. + * @save_func: (scope call): a function that is called to save each block of data that + * the save routine generates. + * @user_data: user data to pass to the save function. + * @type: name of file format. + * @error: (allow-none): return location for error, or %NULL + * @...: list of key-value save options + * + * Saves pixbuf in format @type by feeding the produced data to a + * callback. Can be used when you want to store the image to something + * other than a file, such as an in-memory buffer or a socket. + * If @error is set, %FALSE will be returned. Possible errors + * include those in the #GDK_PIXBUF_ERROR domain and whatever the save + * function generates. + * + * See gdk_pixbuf_save() for more details. + * + * Return value: whether an error was set + * + * Since: 2.4 + **/ +gboolean +gdk_pixbuf_save_to_callback (GdkPixbuf *pixbuf, + GdkPixbufSaveFunc save_func, + gpointer user_data, + const char *type, + GError **error, + ...) +{ + gchar **keys = NULL; + gchar **values = NULL; + va_list args; + gboolean result; + + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + va_start (args, error); + + collect_save_options (args, &keys, &values); + + va_end (args); + + result = gdk_pixbuf_save_to_callbackv (pixbuf, save_func, user_data, + type, keys, values, + error); + + g_strfreev (keys); + g_strfreev (values); + + return result; +} + +/** + * gdk_pixbuf_save_to_callbackv: + * @pixbuf: a #GdkPixbuf. + * @save_func: (scope call): a function that is called to save each block of data that + * the save routine generates. + * @user_data: (closure): user data to pass to the save function. + * @type: name of file format. + * @option_keys: (array zero-terminated=1) (element-type utf8): name of options to set, %NULL-terminated + * @option_values: (array zero-terminated=1) (element-type utf8): values for named options + * @error: (allow-none): return location for error, or %NULL + * + * Saves pixbuf to a callback in format @type, which is currently "jpeg", + * "png", "tiff", "ico" or "bmp". If @error is set, %FALSE will be returned. See + * gdk_pixbuf_save_to_callback () for more details. + * + * Return value: whether an error was set + * + * Since: 2.4 + **/ +gboolean +gdk_pixbuf_save_to_callbackv (GdkPixbuf *pixbuf, + GdkPixbufSaveFunc save_func, + gpointer user_data, + const char *type, + char **option_keys, + char **option_values, + GError **error) +{ + gboolean result; + + + g_return_val_if_fail (save_func != NULL, FALSE); + g_return_val_if_fail (type != NULL, FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + result = gdk_pixbuf_real_save_to_callback (pixbuf, + save_func, user_data, type, + option_keys, option_values, + error); + + if (!result) { + g_return_val_if_fail (error == NULL || *error != NULL, FALSE); + return FALSE; + } + + return TRUE; +} + +/** + * gdk_pixbuf_save_to_buffer: + * @pixbuf: a #GdkPixbuf. + * @buffer: (array length=buffer_size) (out) (element-type guint8): location to receive a pointer + * to the new buffer. + * @buffer_size: location to receive the size of the new buffer. + * @type: name of file format. + * @error: (allow-none): return location for error, or %NULL + * @...: list of key-value save options + * + * Saves pixbuf to a new buffer in format @type, which is currently "jpeg", + * "png", "tiff", "ico" or "bmp". This is a convenience function that uses + * gdk_pixbuf_save_to_callback() to do the real work. Note that the buffer + * is not nul-terminated and may contain embedded nuls. + * If @error is set, %FALSE will be returned and @buffer will be set to + * %NULL. Possible errors include those in the #GDK_PIXBUF_ERROR + * domain. + * + * See gdk_pixbuf_save() for more details. + * + * Return value: whether an error was set + * + * Since: 2.4 + **/ +gboolean +gdk_pixbuf_save_to_buffer (GdkPixbuf *pixbuf, + gchar **buffer, + gsize *buffer_size, + const char *type, + GError **error, + ...) +{ + gchar **keys = NULL; + gchar **values = NULL; + va_list args; + gboolean result; + + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + va_start (args, error); + + collect_save_options (args, &keys, &values); + + va_end (args); + + result = gdk_pixbuf_save_to_bufferv (pixbuf, buffer, buffer_size, + type, keys, values, + error); + + g_strfreev (keys); + g_strfreev (values); + + return result; +} + +struct SaveToBufferData { + gchar *buffer; + gsize len, max; +}; + +static gboolean +save_to_buffer_callback (const gchar *data, + gsize count, + GError **error, + gpointer user_data) +{ + struct SaveToBufferData *sdata = user_data; + gchar *new_buffer; + gsize new_max; + + if (sdata->len + count > sdata->max) { + new_max = MAX (sdata->max*2, sdata->len + count); + new_buffer = g_try_realloc (sdata->buffer, new_max); + if (!new_buffer) { + g_set_error_literal (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY, + _("Insufficient memory to save image into a buffer")); + return FALSE; + } + sdata->buffer = new_buffer; + sdata->max = new_max; + } + memcpy (sdata->buffer + sdata->len, data, count); + sdata->len += count; + return TRUE; +} + +/** + * gdk_pixbuf_save_to_bufferv: + * @pixbuf: a #GdkPixbuf. + * @buffer: (array length=buffer_size) (out) (element-type guint8): + * location to receive a pointer to the new buffer. + * @buffer_size: location to receive the size of the new buffer. + * @type: name of file format. + * @option_keys: (array zero-terminated=1): name of options to set, %NULL-terminated + * @option_values: (array zero-terminated=1): values for named options + * @error: (allow-none): return location for error, or %NULL + * + * Saves pixbuf to a new buffer in format @type, which is currently "jpeg", + * "tiff", "png", "ico" or "bmp". See gdk_pixbuf_save_to_buffer() + * for more details. + * + * Return value: whether an error was set + * + * Since: 2.4 + **/ +gboolean +gdk_pixbuf_save_to_bufferv (GdkPixbuf *pixbuf, + gchar **buffer, + gsize *buffer_size, + const char *type, + char **option_keys, + char **option_values, + GError **error) +{ + static const gint initial_max = 1024; + struct SaveToBufferData sdata; + + *buffer = NULL; + *buffer_size = 0; + + sdata.buffer = g_try_malloc (initial_max); + sdata.max = initial_max; + sdata.len = 0; + if (!sdata.buffer) { + g_set_error_literal (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY, + _("Insufficient memory to save image into a buffer")); + return FALSE; + } + + if (!gdk_pixbuf_save_to_callbackv (pixbuf, + save_to_buffer_callback, &sdata, + type, option_keys, option_values, + error)) { + g_free (sdata.buffer); + return FALSE; + } + + *buffer = sdata.buffer; + *buffer_size = sdata.len; + return TRUE; +} + +typedef struct { + GOutputStream *stream; + GCancellable *cancellable; +} SaveToStreamData; + +static gboolean +save_to_stream (const gchar *buffer, + gsize count, + GError **error, + gpointer data) +{ + SaveToStreamData *sdata = (SaveToStreamData *)data; + gsize remaining; + gssize written; + GError *my_error = NULL; + + remaining = count; + written = 0; + while (remaining > 0) { + buffer += written; + remaining -= written; + written = g_output_stream_write (sdata->stream, + buffer, remaining, + sdata->cancellable, + &my_error); + if (written < 0) { + if (!my_error) { + g_set_error_literal (error, + G_IO_ERROR, 0, + _("Error writing to image stream")); + } + else { + g_propagate_error (error, my_error); + } + return FALSE; + } + } + + return TRUE; +} + +/** + * gdk_pixbuf_save_to_stream: + * @pixbuf: a #GdkPixbuf + * @stream: a #GOutputStream to save the pixbuf to + * @type: name of file format + * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore + * @error: (allow-none): return location for error, or %NULL + * @...: list of key-value save options + * + * Saves @pixbuf to an output stream. + * + * Supported file formats are currently "jpeg", "tiff", "png", "ico" or + * "bmp". See gdk_pixbuf_save_to_buffer() for more details. + * + * The @cancellable can be used to abort the operation from another + * thread. If the operation was cancelled, the error %G_IO_ERROR_CANCELLED + * will be returned. Other possible errors are in the #GDK_PIXBUF_ERROR + * and %G_IO_ERROR domains. + * + * The stream is not closed. + * + * Returns: %TRUE if the pixbuf was saved successfully, %FALSE if an + * error was set. + * + * Since: 2.14 + */ +gboolean +gdk_pixbuf_save_to_stream (GdkPixbuf *pixbuf, + GOutputStream *stream, + const char *type, + GCancellable *cancellable, + GError **error, + ...) +{ + gboolean res; + gchar **keys = NULL; + gchar **values = NULL; + va_list args; + SaveToStreamData data; + + va_start (args, error); + collect_save_options (args, &keys, &values); + va_end (args); + + data.stream = stream; + data.cancellable = cancellable; + + res = gdk_pixbuf_save_to_callbackv (pixbuf, save_to_stream, + &data, type, + keys, values, + error); + + g_strfreev (keys); + g_strfreev (values); + + return res; +} + +typedef struct { + GOutputStream *stream; + gchar *type; + gchar **keys; + gchar **values; +} SaveToStreamAsyncData; + +static void +save_to_stream_async_data_free (SaveToStreamAsyncData *data) +{ + if (data->stream) + g_object_unref (data->stream); + g_strfreev (data->keys); + g_strfreev (data->values); + g_free (data->type); + g_slice_free (SaveToStreamAsyncData, data); +} + +static void +save_to_stream_thread (GTask *task, + GdkPixbuf *pixbuf, + SaveToStreamAsyncData *data, + GCancellable *cancellable) +{ + SaveToStreamData sync_data; + gboolean retval; + GError *error = NULL; + + sync_data.stream = data->stream; + sync_data.cancellable = cancellable; + + retval = gdk_pixbuf_save_to_callbackv (pixbuf, save_to_stream, + &sync_data, data->type, + data->keys, data->values, + &error); + + if (retval == FALSE) { + g_task_return_error (task, error); + } else { + g_task_return_boolean (task, TRUE); + } +} + +/** + * gdk_pixbuf_save_to_stream_async: + * @pixbuf: a #GdkPixbuf + * @stream: a #GOutputStream to which to save the pixbuf + * @type: name of file format + * @cancellable: (allow-none): optional #GCancellable object, %NULL to ignore + * @callback: a #GAsyncReadyCallback to call when the the pixbuf is loaded + * @user_data: the data to pass to the callback function + * @...: list of key-value save options + * + * Saves @pixbuf to an output stream asynchronously. + * + * For more details see gdk_pixbuf_save_to_stream(), which is the synchronous + * version of this function. + * + * When the operation is finished, @callback will be called in the main thread. + * You can then call gdk_pixbuf_save_to_stream_finish() to get the result of the operation. + * + * Since: 2.24 + **/ +void +gdk_pixbuf_save_to_stream_async (GdkPixbuf *pixbuf, + GOutputStream *stream, + const gchar *type, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data, + ...) +{ + GTask *task; + gchar **keys = NULL; + gchar **values = NULL; + va_list args; + SaveToStreamAsyncData *data; + + g_return_if_fail (GDK_IS_PIXBUF (pixbuf)); + g_return_if_fail (G_IS_OUTPUT_STREAM (stream)); + g_return_if_fail (type != NULL); + g_return_if_fail (callback != NULL); + g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable)); + + va_start (args, user_data); + collect_save_options (args, &keys, &values); + va_end (args); + + data = g_slice_new (SaveToStreamAsyncData); + data->stream = g_object_ref (stream); + data->type = g_strdup (type); + data->keys = keys; + data->values = values; + + task = g_task_new (pixbuf, cancellable, callback, user_data); + g_task_set_source_tag (task, gdk_pixbuf_save_to_stream_async); + g_task_set_task_data (task, data, (GDestroyNotify) save_to_stream_async_data_free); + g_task_run_in_thread (task, (GTaskThreadFunc) save_to_stream_thread); + g_object_unref (task); +} + +/** + * gdk_pixbuf_save_to_stream_finish: + * @async_result: a #GAsyncResult + * @error: a #GError, or %NULL + * + * Finishes an asynchronous pixbuf save operation started with + * gdk_pixbuf_save_to_stream_async(). + * + * Return value: %TRUE if the pixbuf was saved successfully, %FALSE if an error was set. + * + * Since: 2.24 + **/ +gboolean +gdk_pixbuf_save_to_stream_finish (GAsyncResult *async_result, + GError **error) +{ + GTask *task; + + /* Can not use g_task_is_valid because our GTask has a + * source_object which is not available to us anymore. + */ + g_return_val_if_fail (G_IS_TASK (async_result), FALSE); + + task = G_TASK (async_result); + + g_return_val_if_fail (!error || (error && !*error), FALSE); + g_warn_if_fail (g_task_get_source_tag (task) == gdk_pixbuf_save_to_stream_async); + + return g_task_propagate_boolean (task, error); +} + +/** + * gdk_pixbuf_format_get_name: + * @format: a #GdkPixbufFormat + * + * Returns the name of the format. + * + * Return value: the name of the format. + * + * Since: 2.2 + */ +gchar * +gdk_pixbuf_format_get_name (GdkPixbufFormat *format) +{ + g_return_val_if_fail (format != NULL, NULL); + + return g_strdup (format->name); +} + +/** + * gdk_pixbuf_format_get_description: + * @format: a #GdkPixbufFormat + * + * Returns a description of the format. + * + * Return value: a description of the format. + * + * Since: 2.2 + */ +gchar * +gdk_pixbuf_format_get_description (GdkPixbufFormat *format) +{ + gchar *domain; + const gchar *description; + g_return_val_if_fail (format != NULL, NULL); + + if (format->domain != NULL) + domain = format->domain; + else + domain = GETTEXT_PACKAGE; + description = g_dgettext (domain, format->description); + + return g_strdup (description); +} + +/** + * gdk_pixbuf_format_get_mime_types: + * @format: a #GdkPixbufFormat + * + * Returns the mime types supported by the format. + * + * Return value: (transfer full): a %NULL-terminated array of mime types which must be freed with + * g_strfreev() when it is no longer needed. + * + * Since: 2.2 + */ +gchar ** +gdk_pixbuf_format_get_mime_types (GdkPixbufFormat *format) +{ + g_return_val_if_fail (format != NULL, NULL); + + return g_strdupv (format->mime_types); +} + +/** + * gdk_pixbuf_format_get_extensions: + * @format: a #GdkPixbufFormat + * + * Returns the filename extensions typically used for files in the + * given format. + * + * Return value: (transfer full): a %NULL-terminated array of filename extensions which must be + * freed with g_strfreev() when it is no longer needed. + * + * Since: 2.2 + */ +gchar ** +gdk_pixbuf_format_get_extensions (GdkPixbufFormat *format) +{ + g_return_val_if_fail (format != NULL, NULL); + + return g_strdupv (format->extensions); +} + +/** + * gdk_pixbuf_format_is_writable: + * @format: a #GdkPixbufFormat + * + * Returns whether pixbufs can be saved in the given format. + * + * Return value: whether pixbufs can be saved in the given format. + * + * Since: 2.2 + */ +gboolean +gdk_pixbuf_format_is_writable (GdkPixbufFormat *format) +{ + g_return_val_if_fail (format != NULL, FALSE); + + return (format->flags & GDK_PIXBUF_FORMAT_WRITABLE) != 0; +} + +/** + * gdk_pixbuf_format_is_scalable: + * @format: a #GdkPixbufFormat + * + * Returns whether this image format is scalable. If a file is in a + * scalable format, it is preferable to load it at the desired size, + * rather than loading it at the default size and scaling the + * resulting pixbuf to the desired size. + * + * Return value: whether this image format is scalable. + * + * Since: 2.6 + */ +gboolean +gdk_pixbuf_format_is_scalable (GdkPixbufFormat *format) +{ + g_return_val_if_fail (format != NULL, FALSE); + + return (format->flags & GDK_PIXBUF_FORMAT_SCALABLE) != 0; +} + +/** + * gdk_pixbuf_format_is_disabled: + * @format: a #GdkPixbufFormat + * + * Returns whether this image format is disabled. See + * gdk_pixbuf_format_set_disabled(). + * + * Return value: whether this image format is disabled. + * + * Since: 2.6 + */ +gboolean +gdk_pixbuf_format_is_disabled (GdkPixbufFormat *format) +{ + g_return_val_if_fail (format != NULL, FALSE); + + return format->disabled; +} + +/** + * gdk_pixbuf_format_set_disabled: + * @format: a #GdkPixbufFormat + * @disabled: %TRUE to disable the format @format + * + * Disables or enables an image format. If a format is disabled, + * gdk-pixbuf won't use the image loader for this format to load + * images. Applications can use this to avoid using image loaders + * with an inappropriate license, see gdk_pixbuf_format_get_license(). + * + * Since: 2.6 + */ +void +gdk_pixbuf_format_set_disabled (GdkPixbufFormat *format, + gboolean disabled) +{ + g_return_if_fail (format != NULL); + + format->disabled = disabled != FALSE; +} + +/** + * gdk_pixbuf_format_get_license: + * @format: a #GdkPixbufFormat + * + * Returns information about the license of the image loader for the format. The + * returned string should be a shorthand for a wellknown license, e.g. "LGPL", + * "GPL", "QPL", "GPL/QPL", or "other" to indicate some other license. This + * string should be freed with g_free() when it's no longer needed. + * + * Returns: a string describing the license of @format. + * + * Since: 2.6 + */ +gchar* +gdk_pixbuf_format_get_license (GdkPixbufFormat *format) +{ + g_return_val_if_fail (format != NULL, NULL); + + return g_strdup (format->license); +} + +GdkPixbufFormat * +_gdk_pixbuf_get_format (GdkPixbufModule *module) +{ + g_return_val_if_fail (module != NULL, NULL); + + return module->info; +} + +/** + * gdk_pixbuf_get_formats: + * + * Obtains the available information about the image formats supported + * by GdkPixbuf. + * + * Returns: (transfer container) (element-type GdkPixbufFormat): A list of + * #GdkPixbufFormats describing the supported image formats. The list should + * be freed when it is no longer needed, but the structures themselves are + * owned by #GdkPixbuf and should not be freed. + * + * Since: 2.2 + */ +GSList * +gdk_pixbuf_get_formats (void) +{ + GSList *result = NULL; + GSList *modules; + + for (modules = get_file_formats (); modules; modules = g_slist_next (modules)) { + GdkPixbufModule *module = (GdkPixbufModule *)modules->data; + GdkPixbufFormat *info = _gdk_pixbuf_get_format (module); + result = g_slist_prepend (result, info); + } + + return result; +} + +/** + * gdk_pixbuf_format_copy: + * @format: a #GdkPixbufFormat + * + * Creates a copy of @format + * + * Return value: the newly allocated copy of a #GdkPixbufFormat. Use + * gdk_pixbuf_format_free() to free the resources when done + * + * Since: 2.22 + */ +GdkPixbufFormat * +gdk_pixbuf_format_copy (const GdkPixbufFormat *format) +{ + if (G_LIKELY (format != NULL)) + return g_slice_dup (GdkPixbufFormat, format); + + return NULL; +} + +/** + * gdk_pixbuf_format_free: + * @format: a #GdkPixbufFormat + * + * Frees the resources allocated when copying a #GdkPixbufFormat + * using gdk_pixbuf_format_copy() + * + * Since: 2.22 + */ +void +gdk_pixbuf_format_free (GdkPixbufFormat *format) +{ + if (G_LIKELY (format != NULL)) + g_slice_free (GdkPixbufFormat, format); +} + +G_DEFINE_BOXED_TYPE (GdkPixbufFormat, gdk_pixbuf_format, + gdk_pixbuf_format_copy, + gdk_pixbuf_format_free) diff --git a/libs/tk/ydk-pixbuf/gdk-pixbuf-loader.c b/libs/tk/ydk-pixbuf/gdk-pixbuf-loader.c new file mode 100644 index 0000000000..1835a47e64 --- /dev/null +++ b/libs/tk/ydk-pixbuf/gdk-pixbuf-loader.c @@ -0,0 +1,879 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ +/* GdkPixbuf library - Progressive loader object + * + * Copyright (C) 1999 The Free Software Foundation + * + * Authors: Mark Crichton + * Miguel de Icaza + * Federico Mena-Quintero + * Jonathan Blandford + * + * 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, see . + */ + +#include "config.h" +#include + +#include "gdk-pixbuf-private.h" +#include "gdk-pixbuf-animation.h" +#include "gdk-pixbuf-scaled-anim.h" +#include "gdk-pixbuf-loader.h" +#include "gdk-pixbuf-marshal.h" + +/** + * SECTION:gdk-pixbuf-loader + * @Short_description: Application-driven progressive image loading. + * @Title: GdkPixbufLoader + * @See_also: gdk_pixbuf_new_from_file(), gdk_pixbuf_animation_new_from_file() + * + * #GdkPixbufLoader provides a way for applications to drive the + * process of loading an image, by letting them send the image data + * directly to the loader instead of having the loader read the data + * from a file. Applications can use this functionality instead of + * gdk_pixbuf_new_from_file() or gdk_pixbuf_animation_new_from_file() + * when they need to parse image data in + * small chunks. For example, it should be used when reading an + * image from a (potentially) slow network connection, or when + * loading an extremely large file. + * + * + * To use #GdkPixbufLoader to load an image, just create a new one, and + * call gdk_pixbuf_loader_write() to send the data to it. When done, + * gdk_pixbuf_loader_close() should be called to end the stream and + * finalize everything. The loader will emit three important signals + * throughout the process. The first, #GdkPixbufLoader::size-prepared, + * will be emitted as soon as the image has enough information to + * determine the size of the image to be used. If you want to scale + * the image while loading it, you can call gdk_pixbuf_loader_set_size() + * in response to this signal. + * + * + * The second signal, #GdkPixbufLoader::area-prepared, will be emitted as + * soon as the pixbuf of the desired has been allocated. You can obtain it + * by calling gdk_pixbuf_loader_get_pixbuf(). If you want to use it, simply + * ref it. In addition, no actual information will be passed in yet, so the + * pixbuf can be safely filled with any temporary graphics (or an initial + * color) as needed. You can also call gdk_pixbuf_loader_get_pixbuf() later + * and get the same pixbuf. + * + * The last signal, #GdkPixbufLoader::area-updated, gets emitted every time + * a region is updated. This way you can update a partially completed image. + * Note that you do not know anything about the completeness of an image + * from the updated area. For example, in an interlaced image, you need to + * make several passes before the image is done loading. + * + * # Loading an animation + * + * Loading an animation is almost as easy as loading an image. Once the first + * #GdkPixbufLoader::area-prepared signal has been emitted, you can call + * gdk_pixbuf_loader_get_animation() to get the #GdkPixbufAnimation struct + * and gdk_pixbuf_animation_get_iter() to get a #GdkPixbufAnimationIter for + * displaying it. + */ + + +enum { + SIZE_PREPARED, + AREA_PREPARED, + AREA_UPDATED, + CLOSED, + LAST_SIGNAL +}; + + +static void gdk_pixbuf_loader_finalize (GObject *loader); + +static guint pixbuf_loader_signals[LAST_SIGNAL] = { 0 }; + +/* Internal data */ + +typedef struct +{ + GdkPixbufAnimation *animation; + gboolean closed; + guchar header_buf[SNIFF_BUFFER_SIZE]; + gint header_buf_offset; + GdkPixbufModule *image_module; + gpointer context; + gint width; + gint height; + gboolean size_fixed; + gboolean needs_scale; + gchar *filename; +} GdkPixbufLoaderPrivate; + +G_DEFINE_TYPE (GdkPixbufLoader, gdk_pixbuf_loader, G_TYPE_OBJECT) + + +static void +gdk_pixbuf_loader_class_init (GdkPixbufLoaderClass *class) +{ + GObjectClass *object_class; + + object_class = (GObjectClass *) class; + + object_class->finalize = gdk_pixbuf_loader_finalize; + + /** + * GdkPixbufLoader::size-prepared: + * @loader: the object which received the signal. + * @width: the original width of the image + * @height: the original height of the image + * + * This signal is emitted when the pixbuf loader has been fed the + * initial amount of data that is required to figure out the size + * of the image that it will create. Applications can call + * gdk_pixbuf_loader_set_size() in response to this signal to set + * the desired size to which the image should be scaled. + */ + pixbuf_loader_signals[SIZE_PREPARED] = + g_signal_new ("size-prepared", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GdkPixbufLoaderClass, size_prepared), + NULL, NULL, + _gdk_pixbuf_marshal_VOID__INT_INT, + G_TYPE_NONE, 2, + G_TYPE_INT, + G_TYPE_INT); + + /** + * GdkPixbufLoader::area-prepared: + * @loader: the object which received the signal. + * + * This signal is emitted when the pixbuf loader has allocated the + * pixbuf in the desired size. After this signal is emitted, + * applications can call gdk_pixbuf_loader_get_pixbuf() to fetch + * the partially-loaded pixbuf. + */ + pixbuf_loader_signals[AREA_PREPARED] = + g_signal_new ("area-prepared", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GdkPixbufLoaderClass, area_prepared), + NULL, NULL, + _gdk_pixbuf_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + /** + * GdkPixbufLoader::area-updated: + * @loader: the object which received the signal. + * @x: X offset of upper-left corner of the updated area. + * @y: Y offset of upper-left corner of the updated area. + * @width: Width of updated area. + * @height: Height of updated area. + * + * This signal is emitted when a significant area of the image being + * loaded has been updated. Normally it means that a complete + * scanline has been read in, but it could be a different area as + * well. Applications can use this signal to know when to repaint + * areas of an image that is being loaded. + */ + pixbuf_loader_signals[AREA_UPDATED] = + g_signal_new ("area-updated", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GdkPixbufLoaderClass, area_updated), + NULL, NULL, + _gdk_pixbuf_marshal_VOID__INT_INT_INT_INT, + G_TYPE_NONE, 4, + G_TYPE_INT, + G_TYPE_INT, + G_TYPE_INT, + G_TYPE_INT); + + /** + * GdkPixbufLoader::closed: + * @loader: the object which received the signal. + * + * This signal is emitted when gdk_pixbuf_loader_close() is called. + * It can be used by different parts of an application to receive + * notification when an image loader is closed by the code that + * drives it. + */ + pixbuf_loader_signals[CLOSED] = + g_signal_new ("closed", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GdkPixbufLoaderClass, closed), + NULL, NULL, + _gdk_pixbuf_marshal_VOID__VOID, + G_TYPE_NONE, 0); +} + +static void +gdk_pixbuf_loader_init (GdkPixbufLoader *loader) +{ + GdkPixbufLoaderPrivate *priv; + + priv = g_new0 (GdkPixbufLoaderPrivate, 1); + priv->width = -1; + priv->height = -1; + + loader->priv = priv; +} + +static void +gdk_pixbuf_loader_finalize (GObject *object) +{ + GdkPixbufLoader *loader; + GdkPixbufLoaderPrivate *priv = NULL; + + loader = GDK_PIXBUF_LOADER (object); + priv = loader->priv; + + if (!priv->closed) { + g_warning ("GdkPixbufLoader finalized without calling gdk_pixbuf_loader_close() - this is not allowed. You must explicitly end the data stream to the loader before dropping the last reference."); + } + if (priv->animation) + g_object_unref (priv->animation); + + g_free (priv->filename); + + g_free (priv); + + G_OBJECT_CLASS (gdk_pixbuf_loader_parent_class)->finalize (object); +} + +/** + * gdk_pixbuf_loader_set_size: + * @loader: A pixbuf loader. + * @width: The desired width of the image being loaded. + * @height: The desired height of the image being loaded. + * + * Causes the image to be scaled while it is loaded. The desired + * image size can be determined relative to the original size of + * the image by calling gdk_pixbuf_loader_set_size() from a + * signal handler for the ::size-prepared signal. + * + * Attempts to set the desired image size are ignored after the + * emission of the ::size-prepared signal. + * + * Since: 2.2 + */ +void +gdk_pixbuf_loader_set_size (GdkPixbufLoader *loader, + gint width, + gint height) +{ + GdkPixbufLoaderPrivate *priv; + + g_return_if_fail (GDK_IS_PIXBUF_LOADER (loader)); + g_return_if_fail (width >= 0 && height >= 0); + + priv = GDK_PIXBUF_LOADER (loader)->priv; + + if (!priv->size_fixed) + { + priv->width = width; + priv->height = height; + } +} + +static void +gdk_pixbuf_loader_size_func (gint *width, gint *height, gpointer loader) +{ + GdkPixbufLoaderPrivate *priv = GDK_PIXBUF_LOADER (loader)->priv; + + /* allow calling gdk_pixbuf_loader_set_size() before the signal */ + if (priv->width == -1 && priv->height == -1) + { + priv->width = *width; + priv->height = *height; + } + + g_signal_emit (loader, pixbuf_loader_signals[SIZE_PREPARED], 0, *width, *height); + priv->size_fixed = TRUE; + + *width = priv->width; + *height = priv->height; +} + +static void +gdk_pixbuf_loader_prepare (GdkPixbuf *pixbuf, + GdkPixbufAnimation *anim, + gpointer loader) +{ + GdkPixbufLoaderPrivate *priv = GDK_PIXBUF_LOADER (loader)->priv; + gint width, height; + g_return_if_fail (pixbuf != NULL); + + width = anim ? gdk_pixbuf_animation_get_width (anim) : + gdk_pixbuf_get_width (pixbuf); + height = anim ? gdk_pixbuf_animation_get_height (anim) : + gdk_pixbuf_get_height (pixbuf); + + if (!priv->size_fixed) + { + gint w = width; + gint h = height; + /* Defend against lazy loaders which don't call size_func */ + gdk_pixbuf_loader_size_func (&w, &h, loader); + } + + priv->needs_scale = FALSE; + if (priv->width > 0 && priv->height > 0 && + (priv->width != width || priv->height != height)) + priv->needs_scale = TRUE; + + if (anim) + g_object_ref (anim); + else + anim = gdk_pixbuf_non_anim_new (pixbuf); + + if (priv->needs_scale) { + priv->animation = GDK_PIXBUF_ANIMATION (_gdk_pixbuf_scaled_anim_new (anim, + (double) priv->width / width, + (double) priv->height / height, + 1.0)); + g_object_unref (anim); + } + else + priv->animation = anim; + + if (!priv->needs_scale) + g_signal_emit (loader, pixbuf_loader_signals[AREA_PREPARED], 0); +} + +static void +gdk_pixbuf_loader_update (GdkPixbuf *pixbuf, + gint x, + gint y, + gint width, + gint height, + gpointer loader) +{ + GdkPixbufLoaderPrivate *priv = GDK_PIXBUF_LOADER (loader)->priv; + + if (!priv->needs_scale) + g_signal_emit (loader, + pixbuf_loader_signals[AREA_UPDATED], + 0, + x, y, + /* sanity check in here. Defend against an errant loader */ + MIN (width, gdk_pixbuf_animation_get_width (priv->animation)), + MIN (height, gdk_pixbuf_animation_get_height (priv->animation))); +} + +/* Defense against broken loaders; DO NOT take this as a GError example! */ +static void +gdk_pixbuf_loader_ensure_error (GdkPixbufLoader *loader, + GError **error) +{ + GdkPixbufLoaderPrivate *priv = loader->priv; + + if (error == NULL || *error != NULL) + return; + + g_warning ("Bug! loader '%s' didn't set an error on failure", + priv->image_module->module_name); + g_set_error (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_FAILED, + _("Internal error: Image loader module '%s' failed to" + " complete an operation, but didn't give a reason for" + " the failure"), + priv->image_module->module_name); +} + +static gint +gdk_pixbuf_loader_load_module (GdkPixbufLoader *loader, + const char *image_type, + GError **error) +{ + GdkPixbufLoaderPrivate *priv = loader->priv; + + if (image_type) + { + priv->image_module = _gdk_pixbuf_get_named_module (image_type, + error); + } + else + { + priv->image_module = _gdk_pixbuf_get_module (priv->header_buf, + priv->header_buf_offset, + priv->filename, + error); + } + + if (priv->image_module == NULL) + return 0; + + if (!_gdk_pixbuf_load_module (priv->image_module, error)) + return 0; + + if (priv->image_module->module == NULL) + return 0; + + if ((priv->image_module->begin_load == NULL) || + (priv->image_module->stop_load == NULL) || + (priv->image_module->load_increment == NULL)) + { + g_set_error (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_UNSUPPORTED_OPERATION, + _("Incremental loading of image type '%s' is not supported"), + priv->image_module->module_name); + + return 0; + } + + priv->context = priv->image_module->begin_load (gdk_pixbuf_loader_size_func, + gdk_pixbuf_loader_prepare, + gdk_pixbuf_loader_update, + loader, + error); + + if (priv->context == NULL) + { + gdk_pixbuf_loader_ensure_error (loader, error); + return 0; + } + + if (priv->header_buf_offset + && priv->image_module->load_increment (priv->context, priv->header_buf, priv->header_buf_offset, error)) + return priv->header_buf_offset; + + return 0; +} + +static int +gdk_pixbuf_loader_eat_header_write (GdkPixbufLoader *loader, + const guchar *buf, + gsize count, + GError **error) +{ + gint n_bytes; + GdkPixbufLoaderPrivate *priv = loader->priv; + + n_bytes = MIN(SNIFF_BUFFER_SIZE - priv->header_buf_offset, count); + memcpy (priv->header_buf + priv->header_buf_offset, buf, n_bytes); + + priv->header_buf_offset += n_bytes; + + if (priv->header_buf_offset >= SNIFF_BUFFER_SIZE) + { + if (gdk_pixbuf_loader_load_module (loader, NULL, error) == 0) + return 0; + } + + return n_bytes; +} + +/** + * gdk_pixbuf_loader_write: + * @loader: A pixbuf loader. + * @buf: (array length=count): Pointer to image data. + * @count: Length of the @buf buffer in bytes. + * @error: return location for errors + * + * This will cause a pixbuf loader to parse the next @count bytes of + * an image. It will return %TRUE if the data was loaded successfully, + * and %FALSE if an error occurred. In the latter case, the loader + * will be closed, and will not accept further writes. If %FALSE is + * returned, @error will be set to an error from the #GDK_PIXBUF_ERROR + * or #G_FILE_ERROR domains. + * + * Return value: %TRUE if the write was successful, or %FALSE if the loader + * cannot parse the buffer. + **/ +gboolean +gdk_pixbuf_loader_write (GdkPixbufLoader *loader, + const guchar *buf, + gsize count, + GError **error) +{ + GdkPixbufLoaderPrivate *priv; + + g_return_val_if_fail (GDK_IS_PIXBUF_LOADER (loader), FALSE); + + g_return_val_if_fail (buf != NULL, FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + priv = loader->priv; + + /* we expect it's not to be closed */ + g_return_val_if_fail (priv->closed == FALSE, FALSE); + + if (count > 0 && priv->image_module == NULL) + { + gint eaten; + + eaten = gdk_pixbuf_loader_eat_header_write (loader, buf, count, error); + if (eaten <= 0) + goto fail; + + count -= eaten; + buf += eaten; + } + + if (count > 0 && priv->image_module->load_increment) + { + if (!priv->image_module->load_increment (priv->context, buf, count, + error)) + goto fail; + } + + return TRUE; + + fail: + gdk_pixbuf_loader_ensure_error (loader, error); + gdk_pixbuf_loader_close (loader, NULL); + + return FALSE; +} + +/** + * gdk_pixbuf_loader_write_bytes: + * @loader: A pixbuf loader. + * @buffer: The image data as a #GBytes + * @error: return location for errors + * + * This will cause a pixbuf loader to parse a buffer inside a #GBytes + * for an image. It will return %TRUE if the data was loaded successfully, + * and %FALSE if an error occurred. In the latter case, the loader + * will be closed, and will not accept further writes. If %FALSE is + * returned, @error will be set to an error from the #GDK_PIXBUF_ERROR + * or #G_FILE_ERROR domains. + * + * See also: gdk_pixbuf_loader_write() + * + * Return value: %TRUE if the write was successful, or %FALSE if the loader + * cannot parse the buffer. + * + * Since: 2.30 + */ +gboolean +gdk_pixbuf_loader_write_bytes (GdkPixbufLoader *loader, + GBytes *buffer, + GError **error) +{ + g_return_val_if_fail (GDK_IS_PIXBUF_LOADER (loader), FALSE); + + g_return_val_if_fail (buffer != NULL, FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + return gdk_pixbuf_loader_write (loader, + g_bytes_get_data (buffer, NULL), + g_bytes_get_size (buffer), + error); +} + +/** + * gdk_pixbuf_loader_new: + * + * Creates a new pixbuf loader object. + * + * Return value: A newly-created pixbuf loader. + **/ +GdkPixbufLoader * +gdk_pixbuf_loader_new (void) +{ + return g_object_new (GDK_TYPE_PIXBUF_LOADER, NULL); +} + +/** + * gdk_pixbuf_loader_new_with_type: + * @image_type: name of the image format to be loaded with the image + * @error: (allow-none): return location for an allocated #GError, or %NULL to ignore errors + * + * Creates a new pixbuf loader object that always attempts to parse + * image data as if it were an image of type @image_type, instead of + * identifying the type automatically. Useful if you want an error if + * the image isn't the expected type, for loading image formats + * that can't be reliably identified by looking at the data, or if + * the user manually forces a specific type. + * + * The list of supported image formats depends on what image loaders + * are installed, but typically "png", "jpeg", "gif", "tiff" and + * "xpm" are among the supported formats. To obtain the full list of + * supported image formats, call gdk_pixbuf_format_get_name() on each + * of the #GdkPixbufFormat structs returned by gdk_pixbuf_get_formats(). + * + * Return value: A newly-created pixbuf loader. + **/ +GdkPixbufLoader * +gdk_pixbuf_loader_new_with_type (const char *image_type, + GError **error) +{ + GdkPixbufLoader *retval; + GError *tmp; + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + retval = g_object_new (GDK_TYPE_PIXBUF_LOADER, NULL); + + tmp = NULL; + gdk_pixbuf_loader_load_module (retval, image_type, &tmp); + if (tmp != NULL) + { + g_propagate_error (error, tmp); + gdk_pixbuf_loader_close (retval, NULL); + g_object_unref (retval); + return NULL; + } + + return retval; +} + +/** + * gdk_pixbuf_loader_new_with_mime_type: + * @mime_type: the mime type to be loaded + * @error: (allow-none): return location for an allocated #GError, or %NULL to ignore errors + * + * Creates a new pixbuf loader object that always attempts to parse + * image data as if it were an image of mime type @mime_type, instead of + * identifying the type automatically. Useful if you want an error if + * the image isn't the expected mime type, for loading image formats + * that can't be reliably identified by looking at the data, or if + * the user manually forces a specific mime type. + * + * The list of supported mime types depends on what image loaders + * are installed, but typically "image/png", "image/jpeg", "image/gif", + * "image/tiff" and "image/x-xpixmap" are among the supported mime types. + * To obtain the full list of supported mime types, call + * gdk_pixbuf_format_get_mime_types() on each of the #GdkPixbufFormat + * structs returned by gdk_pixbuf_get_formats(). + * + * Return value: A newly-created pixbuf loader. + * Since: 2.4 + **/ +GdkPixbufLoader * +gdk_pixbuf_loader_new_with_mime_type (const char *mime_type, + GError **error) +{ + const char * image_type = NULL; + char ** mimes; + + GdkPixbufLoader *retval; + GError *tmp; + + GSList * formats; + GdkPixbufFormat *info; + int i, j, length; + + formats = gdk_pixbuf_get_formats (); + length = g_slist_length (formats); + + for (i = 0; i < length && image_type == NULL; i++) { + info = (GdkPixbufFormat *)g_slist_nth_data (formats, i); + mimes = info->mime_types; + + for (j = 0; mimes[j] != NULL; j++) + if (g_ascii_strcasecmp (mimes[j], mime_type) == 0) { + image_type = info->name; + break; + } + } + + g_slist_free (formats); + + retval = g_object_new (GDK_TYPE_PIXBUF_LOADER, NULL); + + tmp = NULL; + gdk_pixbuf_loader_load_module (retval, image_type, &tmp); + if (tmp != NULL) + { + g_propagate_error (error, tmp); + gdk_pixbuf_loader_close (retval, NULL); + g_object_unref (retval); + return NULL; + } + + return retval; +} + +GdkPixbufLoader * +_gdk_pixbuf_loader_new_with_filename (const char *filename) +{ + GdkPixbufLoader *retval; + GdkPixbufLoaderPrivate *priv; + + retval = g_object_new (GDK_TYPE_PIXBUF_LOADER, NULL); + priv = retval->priv; + priv->filename = g_strdup (filename); + + return retval; +} + +/** + * gdk_pixbuf_loader_get_pixbuf: + * @loader: A pixbuf loader. + * + * Queries the #GdkPixbuf that a pixbuf loader is currently creating. + * In general it only makes sense to call this function after the + * "area-prepared" signal has been emitted by the loader; this means + * that enough data has been read to know the size of the image that + * will be allocated. If the loader has not received enough data via + * gdk_pixbuf_loader_write(), then this function returns %NULL. The + * returned pixbuf will be the same in all future calls to the loader, + * so simply calling g_object_ref() should be sufficient to continue + * using it. Additionally, if the loader is an animation, it will + * return the "static image" of the animation + * (see gdk_pixbuf_animation_get_static_image()). + * + * Return value: (transfer none): The #GdkPixbuf that the loader is creating, or %NULL if not + * enough data has been read to determine how to create the image buffer. + **/ +GdkPixbuf * +gdk_pixbuf_loader_get_pixbuf (GdkPixbufLoader *loader) +{ + GdkPixbufLoaderPrivate *priv; + + g_return_val_if_fail (GDK_IS_PIXBUF_LOADER (loader), NULL); + + priv = loader->priv; + + if (priv->animation) + return gdk_pixbuf_animation_get_static_image (priv->animation); + else + return NULL; +} + +/** + * gdk_pixbuf_loader_get_animation: + * @loader: A pixbuf loader + * + * Queries the #GdkPixbufAnimation that a pixbuf loader is currently creating. + * In general it only makes sense to call this function after the "area-prepared" + * signal has been emitted by the loader. If the loader doesn't have enough + * bytes yet (hasn't emitted the "area-prepared" signal) this function will + * return %NULL. + * + * Return value: (transfer none): The #GdkPixbufAnimation that the loader is loading, or %NULL if + not enough data has been read to determine the information. +**/ +GdkPixbufAnimation * +gdk_pixbuf_loader_get_animation (GdkPixbufLoader *loader) +{ + GdkPixbufLoaderPrivate *priv; + + g_return_val_if_fail (GDK_IS_PIXBUF_LOADER (loader), NULL); + + priv = loader->priv; + + return priv->animation; +} + +/** + * gdk_pixbuf_loader_close: + * @loader: A pixbuf loader. + * @error: (allow-none): return location for a #GError, or %NULL to ignore errors + * + * Informs a pixbuf loader that no further writes with + * gdk_pixbuf_loader_write() will occur, so that it can free its + * internal loading structures. Also, tries to parse any data that + * hasn't yet been parsed; if the remaining data is partial or + * corrupt, an error will be returned. If %FALSE is returned, @error + * will be set to an error from the #GDK_PIXBUF_ERROR or #G_FILE_ERROR + * domains. If you're just cancelling a load rather than expecting it + * to be finished, passing %NULL for @error to ignore it is + * reasonable. + * + * Remember that this does not unref the loader, so if you plan not to + * use it anymore, please g_object_unref() it. + * + * Returns: %TRUE if all image data written so far was successfully + passed out via the update_area signal + **/ +gboolean +gdk_pixbuf_loader_close (GdkPixbufLoader *loader, + GError **error) +{ + GdkPixbufLoaderPrivate *priv; + gboolean retval = TRUE; + + g_return_val_if_fail (GDK_IS_PIXBUF_LOADER (loader), TRUE); + g_return_val_if_fail (error == NULL || *error == NULL, TRUE); + + priv = loader->priv; + + if (priv->closed) + return TRUE; + + /* We have less than SNIFF_BUFFER_SIZE bytes in the image. + * Flush it, and keep going. + */ + if (priv->image_module == NULL) + { + GError *tmp = NULL; + gdk_pixbuf_loader_load_module (loader, NULL, &tmp); + if (tmp != NULL) + { + g_propagate_error (error, tmp); + retval = FALSE; + } + } + + if (priv->image_module && priv->image_module->stop_load && priv->context) + { + GError *tmp = NULL; + if (!priv->image_module->stop_load (priv->context, &tmp) || tmp) + { + /* don't call gdk_pixbuf_loader_ensure_error() + * here, since we might not get an error in the + * gdk_pixbuf_get_file_info() case + */ + if (tmp) { + if (error && *error == NULL) + g_propagate_error (error, tmp); + else + g_error_free (tmp); + } + retval = FALSE; + } + } + + priv->closed = TRUE; + + if (priv->needs_scale) + { + + g_signal_emit (loader, pixbuf_loader_signals[AREA_PREPARED], 0); + g_signal_emit (loader, pixbuf_loader_signals[AREA_UPDATED], 0, + 0, 0, priv->width, priv->height); + } + + + g_signal_emit (loader, pixbuf_loader_signals[CLOSED], 0); + + return retval; +} + +/** + * gdk_pixbuf_loader_get_format: + * @loader: A pixbuf loader. + * + * Obtains the available information about the format of the + * currently loading image file. + * + * Returns: (nullable) (transfer none): A #GdkPixbufFormat or + * %NULL. The return value is owned by GdkPixbuf and should not be + * freed. + * + * Since: 2.2 + */ +GdkPixbufFormat * +gdk_pixbuf_loader_get_format (GdkPixbufLoader *loader) +{ + GdkPixbufLoaderPrivate *priv; + + g_return_val_if_fail (GDK_IS_PIXBUF_LOADER (loader), NULL); + + priv = loader->priv; + + if (priv->image_module) + return _gdk_pixbuf_get_format (priv->image_module); + else + return NULL; +} diff --git a/libs/tk/ydk-pixbuf/gdk-pixbuf-marshal.c b/libs/tk/ydk-pixbuf/gdk-pixbuf-marshal.c new file mode 100644 index 0000000000..5381d9a747 --- /dev/null +++ b/libs/tk/ydk-pixbuf/gdk-pixbuf-marshal.c @@ -0,0 +1,133 @@ + +#include + + +#ifdef G_ENABLE_DEBUG +#define g_marshal_value_peek_boolean(v) g_value_get_boolean (v) +#define g_marshal_value_peek_char(v) g_value_get_schar (v) +#define g_marshal_value_peek_uchar(v) g_value_get_uchar (v) +#define g_marshal_value_peek_int(v) g_value_get_int (v) +#define g_marshal_value_peek_uint(v) g_value_get_uint (v) +#define g_marshal_value_peek_long(v) g_value_get_long (v) +#define g_marshal_value_peek_ulong(v) g_value_get_ulong (v) +#define g_marshal_value_peek_int64(v) g_value_get_int64 (v) +#define g_marshal_value_peek_uint64(v) g_value_get_uint64 (v) +#define g_marshal_value_peek_enum(v) g_value_get_enum (v) +#define g_marshal_value_peek_flags(v) g_value_get_flags (v) +#define g_marshal_value_peek_float(v) g_value_get_float (v) +#define g_marshal_value_peek_double(v) g_value_get_double (v) +#define g_marshal_value_peek_string(v) (char*) g_value_get_string (v) +#define g_marshal_value_peek_param(v) g_value_get_param (v) +#define g_marshal_value_peek_boxed(v) g_value_get_boxed (v) +#define g_marshal_value_peek_pointer(v) g_value_get_pointer (v) +#define g_marshal_value_peek_object(v) g_value_get_object (v) +#define g_marshal_value_peek_variant(v) g_value_get_variant (v) +#else /* !G_ENABLE_DEBUG */ +/* WARNING: This code accesses GValues directly, which is UNSUPPORTED API. + * Do not access GValues directly in your code. Instead, use the + * g_value_get_*() functions + */ +#define g_marshal_value_peek_boolean(v) (v)->data[0].v_int +#define g_marshal_value_peek_char(v) (v)->data[0].v_int +#define g_marshal_value_peek_uchar(v) (v)->data[0].v_uint +#define g_marshal_value_peek_int(v) (v)->data[0].v_int +#define g_marshal_value_peek_uint(v) (v)->data[0].v_uint +#define g_marshal_value_peek_long(v) (v)->data[0].v_long +#define g_marshal_value_peek_ulong(v) (v)->data[0].v_ulong +#define g_marshal_value_peek_int64(v) (v)->data[0].v_int64 +#define g_marshal_value_peek_uint64(v) (v)->data[0].v_uint64 +#define g_marshal_value_peek_enum(v) (v)->data[0].v_long +#define g_marshal_value_peek_flags(v) (v)->data[0].v_ulong +#define g_marshal_value_peek_float(v) (v)->data[0].v_float +#define g_marshal_value_peek_double(v) (v)->data[0].v_double +#define g_marshal_value_peek_string(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_param(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_boxed(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_object(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_variant(v) (v)->data[0].v_pointer +#endif /* !G_ENABLE_DEBUG */ + + +/* VOID:VOID (./gdk-pixbuf-marshal.list:25) */ + +/* VOID:INT,INT (./gdk-pixbuf-marshal.list:26) */ +void +_gdk_pixbuf_marshal_VOID__INT_INT (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__INT_INT) (gpointer data1, + gint arg_1, + gint arg_2, + gpointer data2); + register GMarshalFunc_VOID__INT_INT callback; + register GCClosure *cc = (GCClosure*) closure; + register gpointer data1, data2; + + g_return_if_fail (n_param_values == 3); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__INT_INT) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_int (param_values + 1), + g_marshal_value_peek_int (param_values + 2), + data2); +} + +/* VOID:INT,INT,INT,INT (./gdk-pixbuf-marshal.list:27) */ +void +_gdk_pixbuf_marshal_VOID__INT_INT_INT_INT (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__INT_INT_INT_INT) (gpointer data1, + gint arg_1, + gint arg_2, + gint arg_3, + gint arg_4, + gpointer data2); + register GMarshalFunc_VOID__INT_INT_INT_INT callback; + register GCClosure *cc = (GCClosure*) closure; + register gpointer data1, data2; + + g_return_if_fail (n_param_values == 5); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__INT_INT_INT_INT) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_int (param_values + 1), + g_marshal_value_peek_int (param_values + 2), + g_marshal_value_peek_int (param_values + 3), + g_marshal_value_peek_int (param_values + 4), + data2); +} + +/* VOID:POINTER (./gdk-pixbuf-marshal.list:28) */ + diff --git a/libs/tk/ydk-pixbuf/gdk-pixbuf-scale.c b/libs/tk/ydk-pixbuf/gdk-pixbuf-scale.c new file mode 100644 index 0000000000..4288c658f2 --- /dev/null +++ b/libs/tk/ydk-pixbuf/gdk-pixbuf-scale.c @@ -0,0 +1,563 @@ +/* GdkPixbuf library - Scaling and compositing functions + * + * Copyright (C) 1999 The Free Software Foundation + * + * Author: Owen Taylor + * + * 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, see . + */ + +#include "config.h" +#include +#include +#include "gdk-pixbuf-transform.h" +#include "gdk-pixbuf-private.h" +#include "pixops/pixops.h" + +/** + * SECTION:scaling + * @Short_description: Scaling pixbufs and scaling and compositing pixbufs + * @Title: Scaling + * @See_also: GdkRGB. + * + * The GdkPixBuf contains functions to scale pixbufs, to scale + * pixbufs and composite against an existing image, and to scale + * pixbufs and composite against a solid color or checkerboard. + * Compositing a checkerboard is a common way to show an image with + * an alpha channel in image-viewing and editing software. + * + * + * Since the full-featured functions (gdk_pixbuf_scale(), + * gdk_pixbuf_composite(), and gdk_pixbuf_composite_color()) are + * rather complex to use and have many arguments, two simple + * convenience functions are provided, gdk_pixbuf_scale_simple() and + * gdk_pixbuf_composite_color_simple() which create a new pixbuf of a + * given size, scale an original image to fit, and then return the + * new pixbuf. + * + * If the destination pixbuf was created from a readonly source, these + * operations will force a copy into a mutable buffer. + * + * Scaling and compositing functions take advantage of MMX hardware + * acceleration on systems where MMX is supported. If gdk-pixbuf is built + * with the Sun mediaLib library, these functions are instead accelerated + * using mediaLib, which provides hardware acceleration on Intel, AMD, + * and Sparc chipsets. If desired, mediaLib support can be turned off by + * setting the `GDK_DISABLE_MEDIALIB` environment variable. + * + * + * The following example demonstrates handling an expose event by + * rendering the appropriate area of a source image (which is scaled + * to fit the widget) onto the widget's window. The source image is + * rendered against a checkerboard, which provides a visual + * representation of the alpha channel if the image has one. If the + * image doesn't have an alpha channel, calling + * gdk_pixbuf_composite_color() function has exactly the same effect + * as calling gdk_pixbuf_scale(). + * + * ## Handling an expose event + * + * |[ + * gboolean + * expose_cb (GtkWidget *widget, GdkEventExpose *event, gpointer data) + * { + * GdkPixbuf *dest; + * + * dest = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, event->area.width, event->area.height); + * + * gdk_pixbuf_composite_color (pixbuf, dest, + * 0, 0, event->area.width, event->area.height, + * -event->area.x, -event->area.y, + * (double) widget->allocation.width / gdk_pixbuf_get_width (pixbuf), + * (double) widget->allocation.height / gdk_pixbuf_get_height (pixbuf), + * GDK_INTERP_BILINEAR, 255, + * event->area.x, event->area.y, 16, 0xaaaaaa, 0x555555); + * + * gdk_draw_pixbuf (widget->window, widget->style->fg_gc[GTK_STATE_NORMAL], dest, + * 0, 0, event->area.x, event->area.y, + * event->area.width, event->area.height, + * GDK_RGB_DITHER_NORMAL, event->area.x, event->area.y); + * + * gdk_pixbuf_unref (dest); + * + * return TRUE; + * } + * ]| + */ + + +/** + * gdk_pixbuf_scale: + * @src: a #GdkPixbuf + * @dest: the #GdkPixbuf into which to render the results + * @dest_x: the left coordinate for region to render + * @dest_y: the top coordinate for region to render + * @dest_width: the width of the region to render + * @dest_height: the height of the region to render + * @offset_x: the offset in the X direction (currently rounded to an integer) + * @offset_y: the offset in the Y direction (currently rounded to an integer) + * @scale_x: the scale factor in the X direction + * @scale_y: the scale factor in the Y direction + * @interp_type: the interpolation type for the transformation. + * + * Creates a transformation of the source image @src by scaling by + * @scale_x and @scale_y then translating by @offset_x and @offset_y, + * then renders the rectangle (@dest_x, @dest_y, @dest_width, + * @dest_height) of the resulting image onto the destination image + * replacing the previous contents. + * + * Try to use gdk_pixbuf_scale_simple() first, this function is + * the industrial-strength power tool you can fall back to if + * gdk_pixbuf_scale_simple() isn't powerful enough. + * + * If the source rectangle overlaps the destination rectangle on the + * same pixbuf, it will be overwritten during the scaling which + * results in rendering artifacts. + **/ +void +gdk_pixbuf_scale (const GdkPixbuf *src, + GdkPixbuf *dest, + int dest_x, + int dest_y, + int dest_width, + int dest_height, + double offset_x, + double offset_y, + double scale_x, + double scale_y, + GdkInterpType interp_type) +{ + const guint8 *src_pixels; + guint8 *dest_pixels; + + g_return_if_fail (GDK_IS_PIXBUF (src)); + g_return_if_fail (GDK_IS_PIXBUF (dest)); + g_return_if_fail (dest_x >= 0 && dest_x + dest_width <= dest->width); + g_return_if_fail (dest_y >= 0 && dest_y + dest_height <= dest->height); + + offset_x = floor (offset_x + 0.5); + offset_y = floor (offset_y + 0.5); + + /* Force an implicit copy */ + dest_pixels = gdk_pixbuf_get_pixels (dest); + src_pixels = gdk_pixbuf_read_pixels (src); + + _pixops_scale (dest_pixels, dest->width, dest->height, dest->rowstride, + dest->n_channels, dest->has_alpha, src_pixels, src->width, + src->height, src->rowstride, src->n_channels, src->has_alpha, + dest_x, dest_y, dest_width, dest_height, offset_x, offset_y, + scale_x, scale_y, (PixopsInterpType)interp_type); +} + +/** + * gdk_pixbuf_composite: + * @src: a #GdkPixbuf + * @dest: the #GdkPixbuf into which to render the results + * @dest_x: the left coordinate for region to render + * @dest_y: the top coordinate for region to render + * @dest_width: the width of the region to render + * @dest_height: the height of the region to render + * @offset_x: the offset in the X direction (currently rounded to an integer) + * @offset_y: the offset in the Y direction (currently rounded to an integer) + * @scale_x: the scale factor in the X direction + * @scale_y: the scale factor in the Y direction + * @interp_type: the interpolation type for the transformation. + * @overall_alpha: overall alpha for source image (0..255) + * + * Creates a transformation of the source image @src by scaling by + * @scale_x and @scale_y then translating by @offset_x and @offset_y. + * This gives an image in the coordinates of the destination pixbuf. + * The rectangle (@dest_x, @dest_y, @dest_width, @dest_height) + * is then composited onto the corresponding rectangle of the + * original destination image. + * + * When the destination rectangle contains parts not in the source + * image, the data at the edges of the source image is replicated + * to infinity. + * + * ![](composite.png) + */ +void +gdk_pixbuf_composite (const GdkPixbuf *src, + GdkPixbuf *dest, + int dest_x, + int dest_y, + int dest_width, + int dest_height, + double offset_x, + double offset_y, + double scale_x, + double scale_y, + GdkInterpType interp_type, + int overall_alpha) +{ + const guint8 *src_pixels; + guint8 *dest_pixels; + + g_return_if_fail (GDK_IS_PIXBUF (src)); + g_return_if_fail (GDK_IS_PIXBUF (dest)); + g_return_if_fail (dest_x >= 0 && dest_x + dest_width <= dest->width); + g_return_if_fail (dest_y >= 0 && dest_y + dest_height <= dest->height); + g_return_if_fail (overall_alpha >= 0 && overall_alpha <= 255); + + offset_x = floor (offset_x + 0.5); + offset_y = floor (offset_y + 0.5); + + /* Force an implicit copy */ + dest_pixels = gdk_pixbuf_get_pixels (dest); + src_pixels = gdk_pixbuf_read_pixels (src); + + _pixops_composite (dest_pixels, dest->width, dest->height, dest->rowstride, + dest->n_channels, dest->has_alpha, src_pixels, + src->width, src->height, src->rowstride, src->n_channels, + src->has_alpha, dest_x, dest_y, dest_width, dest_height, + offset_x, offset_y, scale_x, scale_y, + (PixopsInterpType)interp_type, overall_alpha); +} + +/** + * gdk_pixbuf_composite_color: + * @src: a #GdkPixbuf + * @dest: the #GdkPixbuf into which to render the results + * @dest_x: the left coordinate for region to render + * @dest_y: the top coordinate for region to render + * @dest_width: the width of the region to render + * @dest_height: the height of the region to render + * @offset_x: the offset in the X direction (currently rounded to an integer) + * @offset_y: the offset in the Y direction (currently rounded to an integer) + * @scale_x: the scale factor in the X direction + * @scale_y: the scale factor in the Y direction + * @interp_type: the interpolation type for the transformation. + * @overall_alpha: overall alpha for source image (0..255) + * @check_x: the X offset for the checkboard (origin of checkboard is at -@check_x, -@check_y) + * @check_y: the Y offset for the checkboard + * @check_size: the size of checks in the checkboard (must be a power of two) + * @color1: the color of check at upper left + * @color2: the color of the other check + * + * Creates a transformation of the source image @src by scaling by + * @scale_x and @scale_y then translating by @offset_x and @offset_y, + * then composites the rectangle (@dest_x ,@dest_y, @dest_width, + * @dest_height) of the resulting image with a checkboard of the + * colors @color1 and @color2 and renders it onto the destination + * image. + * + * See gdk_pixbuf_composite_color_simple() for a simpler variant of this + * function suitable for many tasks. + * + **/ +void +gdk_pixbuf_composite_color (const GdkPixbuf *src, + GdkPixbuf *dest, + int dest_x, + int dest_y, + int dest_width, + int dest_height, + double offset_x, + double offset_y, + double scale_x, + double scale_y, + GdkInterpType interp_type, + int overall_alpha, + int check_x, + int check_y, + int check_size, + guint32 color1, + guint32 color2) +{ + const guint8 *src_pixels; + guint8 *dest_pixels; + + g_return_if_fail (GDK_IS_PIXBUF (src)); + g_return_if_fail (GDK_IS_PIXBUF (dest)); + g_return_if_fail (dest_x >= 0 && dest_x + dest_width <= dest->width); + g_return_if_fail (dest_y >= 0 && dest_y + dest_height <= dest->height); + g_return_if_fail (overall_alpha >= 0 && overall_alpha <= 255); + + offset_x = floor (offset_x + 0.5); + offset_y = floor (offset_y + 0.5); + + /* Force an implicit copy */ + dest_pixels = gdk_pixbuf_get_pixels (dest); + src_pixels = gdk_pixbuf_read_pixels (src); + + _pixops_composite_color (dest_pixels, dest_width, dest_height, + dest->rowstride, dest->n_channels, dest->has_alpha, + src_pixels, src->width, src->height, + src->rowstride, src->n_channels, src->has_alpha, + dest_x, dest_y, dest_width, dest_height, offset_x, + offset_y, scale_x, scale_y, + (PixopsInterpType)interp_type, overall_alpha, + check_x, check_y, check_size, color1, color2); +} + +/** + * gdk_pixbuf_scale_simple: + * @src: a #GdkPixbuf + * @dest_width: the width of destination image + * @dest_height: the height of destination image + * @interp_type: the interpolation type for the transformation. + * + * Create a new #GdkPixbuf containing a copy of @src scaled to + * @dest_width x @dest_height. Leaves @src unaffected. @interp_type + * should be #GDK_INTERP_NEAREST if you want maximum speed (but when + * scaling down #GDK_INTERP_NEAREST is usually unusably ugly). The + * default @interp_type should be #GDK_INTERP_BILINEAR which offers + * reasonable quality and speed. + * + * You can scale a sub-portion of @src by creating a sub-pixbuf + * pointing into @src; see gdk_pixbuf_new_subpixbuf(). + * + * For more complicated scaling/compositing see gdk_pixbuf_scale() + * and gdk_pixbuf_composite(). + * + * Return value: (transfer full): the new #GdkPixbuf, or %NULL if not enough memory could be + * allocated for it. + **/ +GdkPixbuf * +gdk_pixbuf_scale_simple (const GdkPixbuf *src, + int dest_width, + int dest_height, + GdkInterpType interp_type) +{ + GdkPixbuf *dest; + + g_return_val_if_fail (GDK_IS_PIXBUF (src), NULL); + g_return_val_if_fail (dest_width > 0, NULL); + g_return_val_if_fail (dest_height > 0, NULL); + + dest = gdk_pixbuf_new (GDK_COLORSPACE_RGB, src->has_alpha, 8, dest_width, dest_height); + if (!dest) + return NULL; + + gdk_pixbuf_scale (src, dest, 0, 0, dest_width, dest_height, 0, 0, + (double) dest_width / src->width, + (double) dest_height / src->height, + interp_type); + + return dest; +} + +/** + * gdk_pixbuf_composite_color_simple: + * @src: a #GdkPixbuf + * @dest_width: the width of destination image + * @dest_height: the height of destination image + * @interp_type: the interpolation type for the transformation. + * @overall_alpha: overall alpha for source image (0..255) + * @check_size: the size of checks in the checkboard (must be a power of two) + * @color1: the color of check at upper left + * @color2: the color of the other check + * + * Creates a new #GdkPixbuf by scaling @src to @dest_width x + * @dest_height and compositing the result with a checkboard of colors + * @color1 and @color2. + * + * Return value: (transfer full): the new #GdkPixbuf, or %NULL if not enough memory could be + * allocated for it. + **/ +GdkPixbuf * +gdk_pixbuf_composite_color_simple (const GdkPixbuf *src, + int dest_width, + int dest_height, + GdkInterpType interp_type, + int overall_alpha, + int check_size, + guint32 color1, + guint32 color2) +{ + GdkPixbuf *dest; + + g_return_val_if_fail (GDK_IS_PIXBUF (src), NULL); + g_return_val_if_fail (dest_width > 0, NULL); + g_return_val_if_fail (dest_height > 0, NULL); + g_return_val_if_fail (overall_alpha >= 0 && overall_alpha <= 255, NULL); + + dest = gdk_pixbuf_new (GDK_COLORSPACE_RGB, src->has_alpha, 8, dest_width, dest_height); + if (!dest) + return NULL; + + gdk_pixbuf_composite_color (src, dest, 0, 0, dest_width, dest_height, 0, 0, + (double) dest_width / src->width, + (double) dest_height / src->height, + interp_type, overall_alpha, 0, 0, check_size, color1, color2); + + return dest; +} + +#define OFFSET(pb, x, y) ((x) * (pb)->n_channels + (y) * (pb)->rowstride) + +/** + * gdk_pixbuf_rotate_simple: + * @src: a #GdkPixbuf + * @angle: the angle to rotate by + * + * Rotates a pixbuf by a multiple of 90 degrees, and returns the + * result in a new pixbuf. + * + * Returns: (nullable) (transfer full): the new #GdkPixbuf, or %NULL + * if not enough memory could be allocated for it. + * + * Since: 2.6 + */ +GdkPixbuf * +gdk_pixbuf_rotate_simple (const GdkPixbuf *src, + GdkPixbufRotation angle) +{ + const guint8 *src_pixels; + guint8 *dest_pixels; + GdkPixbuf *dest; + const guchar *p; + guchar *q; + gint x, y; + + src_pixels = gdk_pixbuf_read_pixels (src); + + switch (angle % 360) + { + case 0: + dest = gdk_pixbuf_copy (src); + break; + case 90: + dest = gdk_pixbuf_new (src->colorspace, + src->has_alpha, + src->bits_per_sample, + src->height, + src->width); + if (!dest) + return NULL; + + dest_pixels = gdk_pixbuf_get_pixels (dest); + + for (y = 0; y < src->height; y++) + { + for (x = 0; x < src->width; x++) + { + p = src_pixels + OFFSET (src, x, y); + q = dest_pixels + OFFSET (dest, y, src->width - x - 1); + memcpy (q, p, dest->n_channels); + } + } + break; + case 180: + dest = gdk_pixbuf_new (src->colorspace, + src->has_alpha, + src->bits_per_sample, + src->width, + src->height); + if (!dest) + return NULL; + + dest_pixels = gdk_pixbuf_get_pixels (dest); + + for (y = 0; y < src->height; y++) + { + for (x = 0; x < src->width; x++) + { + p = src_pixels + OFFSET (src, x, y); + q = dest_pixels + OFFSET (dest, src->width - x - 1, src->height - y - 1); + memcpy (q, p, dest->n_channels); + } + } + break; + case 270: + dest = gdk_pixbuf_new (src->colorspace, + src->has_alpha, + src->bits_per_sample, + src->height, + src->width); + if (!dest) + return NULL; + + dest_pixels = gdk_pixbuf_get_pixels (dest); + + for (y = 0; y < src->height; y++) + { + for (x = 0; x < src->width; x++) + { + p = src_pixels + OFFSET (src, x, y); + q = dest_pixels + OFFSET (dest, src->height - y - 1, x); + memcpy (q, p, dest->n_channels); + } + } + break; + default: + dest = NULL; + g_warning ("gdk_pixbuf_rotate_simple() can only rotate " + "by multiples of 90 degrees"); + g_assert_not_reached (); + } + + return dest; +} + +/** + * gdk_pixbuf_flip: + * @src: a #GdkPixbuf + * @horizontal: %TRUE to flip horizontally, %FALSE to flip vertically + * + * Flips a pixbuf horizontally or vertically and returns the + * result in a new pixbuf. + * + * Returns: (nullable) (transfer full): the new #GdkPixbuf, or %NULL + * if not enough memory could be allocated for it. + * + * Since: 2.6 + */ +GdkPixbuf * +gdk_pixbuf_flip (const GdkPixbuf *src, + gboolean horizontal) +{ + const guint8 *src_pixels; + guint8 *dest_pixels; + GdkPixbuf *dest; + const guchar *p; + guchar *q; + gint x, y; + + dest = gdk_pixbuf_new (src->colorspace, + src->has_alpha, + src->bits_per_sample, + src->width, + src->height); + if (!dest) + return NULL; + + dest_pixels = gdk_pixbuf_get_pixels (dest); + src_pixels = gdk_pixbuf_read_pixels (src); + + if (!horizontal) /* flip vertical */ + { + for (y = 0; y < dest->height; y++) + { + p = src_pixels + OFFSET (src, 0, y); + q = dest_pixels + OFFSET (dest, 0, dest->height - y - 1); + memcpy (q, p, dest->rowstride); + } + } + else /* flip horizontal */ + { + for (y = 0; y < dest->height; y++) + { + for (x = 0; x < dest->width; x++) + { + p = src_pixels + OFFSET (src, x, y); + q = dest_pixels + OFFSET (dest, dest->width - x - 1, y); + memcpy (q, p, dest->n_channels); + } + } + } + + return dest; +} diff --git a/libs/tk/ydk-pixbuf/gdk-pixbuf-scaled-anim.c b/libs/tk/ydk-pixbuf/gdk-pixbuf-scaled-anim.c new file mode 100644 index 0000000000..269b5e26f5 --- /dev/null +++ b/libs/tk/ydk-pixbuf/gdk-pixbuf-scaled-anim.c @@ -0,0 +1,280 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ +/* GdkPixbuf library - Simple transformations of animations + * + * Copyright (C) Red Hat, Inc + * + * Authors: Matthias Clasen + * + * 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, see . + * + */ + +#include + +#include "gdk-pixbuf.h" +#include "gdk-pixbuf-io.h" +#include "gdk-pixbuf-scaled-anim.h" + + +struct _GdkPixbufScaledAnimClass +{ + GdkPixbufAnimationClass parent_class; +}; + +struct _GdkPixbufScaledAnim +{ + GdkPixbufAnimation parent_instance; + + GdkPixbufAnimation *anim; + gdouble xscale; + gdouble yscale; + gdouble tscale; + + GdkPixbuf *current; +}; + +struct _GdkPixbufScaledAnimIterClass +{ + GdkPixbufAnimationClass parent_class; +}; + +struct _GdkPixbufScaledAnimIter +{ + GdkPixbufAnimationIter parent_instance; + + GdkPixbufScaledAnim *scaled; + GdkPixbufAnimationIter *iter; +}; + +typedef struct _GdkPixbufScaledAnimIter GdkPixbufScaledAnimIter; +typedef struct _GdkPixbufScaledAnimIterClass GdkPixbufScaledAnimIterClass; + +GdkPixbufScaledAnim * +_gdk_pixbuf_scaled_anim_new (GdkPixbufAnimation *anim, + gdouble xscale, + gdouble yscale, + gdouble tscale) +{ + GdkPixbufScaledAnim *scaled; + + scaled = g_object_new (GDK_TYPE_PIXBUF_SCALED_ANIM, NULL); + + scaled->anim = g_object_ref (anim); + scaled->xscale = xscale; + scaled->yscale = yscale; + scaled->tscale = tscale; + + return scaled; +} + +G_DEFINE_TYPE (GdkPixbufScaledAnim, gdk_pixbuf_scaled_anim, GDK_TYPE_PIXBUF_ANIMATION); + +static void +gdk_pixbuf_scaled_anim_init (GdkPixbufScaledAnim *scaled) +{ + scaled->xscale = 1.0; + scaled->yscale = 1.0; + scaled->tscale = 1.0; +} + +static void +gdk_pixbuf_scaled_anim_finalize (GObject *object) +{ + GdkPixbufScaledAnim *scaled = (GdkPixbufScaledAnim *)object; + + if (scaled->anim) { + g_object_unref (scaled->anim); + scaled->anim = NULL; + } + + if (scaled->current) { + g_object_unref (scaled->current); + scaled->current = NULL; + } + + G_OBJECT_CLASS (gdk_pixbuf_scaled_anim_parent_class)->finalize (object); +} + +static gboolean +is_static_image (GdkPixbufAnimation *anim) +{ + GdkPixbufScaledAnim *scaled = (GdkPixbufScaledAnim *)anim; + + return gdk_pixbuf_animation_is_static_image (scaled->anim); +} + +static GdkPixbuf * +get_scaled_pixbuf (GdkPixbufScaledAnim *scaled, + GdkPixbuf *pixbuf) +{ + GQuark quark; + gchar **options; + + if (scaled->current) + g_object_unref (scaled->current); + + /* Preserve the options associated with the original pixbuf + (if present), mostly so that client programs can use the + "orientation" option (if present) to rotate the image + appropriately. gdk_pixbuf_scale_simple (and most other + gdk transform operations) does not preserve the attached + options when returning a new pixbuf. */ + + quark = g_quark_from_static_string ("gdk_pixbuf_options"); + options = g_object_get_qdata (G_OBJECT (pixbuf), quark); + + /* Get a new scaled pixbuf */ + scaled->current = gdk_pixbuf_scale_simple (pixbuf, + MAX((int) ((gdouble) gdk_pixbuf_get_width (pixbuf) * scaled->xscale + .5), 1), + MAX((int) ((gdouble) gdk_pixbuf_get_height (pixbuf) * scaled->yscale + .5), 1), + GDK_INTERP_BILINEAR); + + /* Copy the original pixbuf options to the scaled pixbuf */ + if (options && scaled->current) + g_object_set_qdata_full (G_OBJECT (scaled->current), quark, + g_strdupv (options), (GDestroyNotify) g_strfreev); + + return scaled->current; +} + +static GdkPixbuf * +get_static_image (GdkPixbufAnimation *anim) +{ + GdkPixbufScaledAnim *scaled = (GdkPixbufScaledAnim *)anim; + GdkPixbuf *pixbuf; + + pixbuf = gdk_pixbuf_animation_get_static_image (scaled->anim); + return get_scaled_pixbuf (scaled, pixbuf); +} + +static void +get_size (GdkPixbufAnimation *anim, + int *width, + int *height) +{ + GdkPixbufScaledAnim *scaled = (GdkPixbufScaledAnim *)anim; + + GDK_PIXBUF_ANIMATION_GET_CLASS (scaled->anim)->get_size (scaled->anim, width, height); + if (width) + *width = (int)(*width * scaled->xscale + .5); + if (height) + *height = (int)(*height * scaled->yscale + .5); +} + +static GdkPixbufAnimationIter * +get_iter (GdkPixbufAnimation *anim, + const GTimeVal *start_time) +{ + GdkPixbufScaledAnim *scaled = (GdkPixbufScaledAnim *)anim; + GdkPixbufScaledAnimIter *iter; + + iter = g_object_new (GDK_TYPE_PIXBUF_SCALED_ANIM_ITER, NULL); + + iter->scaled = g_object_ref (scaled); + iter->iter = gdk_pixbuf_animation_get_iter (scaled->anim, start_time); + + return (GdkPixbufAnimationIter*)iter; +} + +static void +gdk_pixbuf_scaled_anim_class_init (GdkPixbufScaledAnimClass *klass) +{ + GObjectClass *object_class; + GdkPixbufAnimationClass *anim_class; + + object_class = G_OBJECT_CLASS (klass); + anim_class = GDK_PIXBUF_ANIMATION_CLASS (klass); + + object_class->finalize = gdk_pixbuf_scaled_anim_finalize; + + anim_class->is_static_image = is_static_image; + anim_class->get_static_image = get_static_image; + anim_class->get_size = get_size; + anim_class->get_iter = get_iter; +} + + +G_DEFINE_TYPE (GdkPixbufScaledAnimIter, gdk_pixbuf_scaled_anim_iter, GDK_TYPE_PIXBUF_ANIMATION_ITER); + +static void +gdk_pixbuf_scaled_anim_iter_init (GdkPixbufScaledAnimIter *iter) +{ +} + +static int +get_delay_time (GdkPixbufAnimationIter *iter) +{ + GdkPixbufScaledAnimIter *scaled = (GdkPixbufScaledAnimIter *)iter; + int delay; + + delay = gdk_pixbuf_animation_iter_get_delay_time (scaled->iter); + delay = (int)(delay * scaled->scaled->tscale); + + return delay; +} + +static GdkPixbuf * +get_pixbuf (GdkPixbufAnimationIter *iter) +{ + GdkPixbufScaledAnimIter *scaled = (GdkPixbufScaledAnimIter *)iter; + GdkPixbuf *pixbuf; + + pixbuf = gdk_pixbuf_animation_iter_get_pixbuf (scaled->iter); + return get_scaled_pixbuf (scaled->scaled, pixbuf); +} + +static gboolean +on_currently_loading_frame (GdkPixbufAnimationIter *iter) +{ + GdkPixbufScaledAnimIter *scaled = (GdkPixbufScaledAnimIter *)iter; + + return gdk_pixbuf_animation_iter_on_currently_loading_frame (scaled->iter); +} + +static gboolean +advance (GdkPixbufAnimationIter *iter, + const GTimeVal *current_time) +{ + GdkPixbufScaledAnimIter *scaled = (GdkPixbufScaledAnimIter *)iter; + + return gdk_pixbuf_animation_iter_advance (scaled->iter, current_time); +} + +static void +gdk_pixbuf_scaled_anim_iter_finalize (GObject *object) +{ + GdkPixbufScaledAnimIter *iter = (GdkPixbufScaledAnimIter *)object; + + g_object_unref (iter->iter); + g_object_unref (iter->scaled); + + G_OBJECT_CLASS (gdk_pixbuf_scaled_anim_iter_parent_class)->finalize (object); +} + +static void +gdk_pixbuf_scaled_anim_iter_class_init (GdkPixbufScaledAnimIterClass *klass) +{ + GObjectClass *object_class; + GdkPixbufAnimationIterClass *anim_iter_class; + + object_class = G_OBJECT_CLASS (klass); + anim_iter_class = GDK_PIXBUF_ANIMATION_ITER_CLASS (klass); + + object_class->finalize = gdk_pixbuf_scaled_anim_iter_finalize; + + anim_iter_class->get_delay_time = get_delay_time; + anim_iter_class->get_pixbuf = get_pixbuf; + anim_iter_class->on_currently_loading_frame = on_currently_loading_frame; + anim_iter_class->advance = advance; +} diff --git a/libs/tk/ydk-pixbuf/gdk-pixbuf-simple-anim.c b/libs/tk/ydk-pixbuf/gdk-pixbuf-simple-anim.c new file mode 100644 index 0000000000..97acdb95b3 --- /dev/null +++ b/libs/tk/ydk-pixbuf/gdk-pixbuf-simple-anim.c @@ -0,0 +1,546 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ +/* GdkPixbuf library - Simple frame-based animations + * + * Copyright (C) Dom Lachowicz + * + * Authors: Dom Lachowicz + * + * 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, see . + * + * Based on code originally by: + * Jonathan Blandford + * Havoc Pennington + */ + +#include "config.h" +#include + +#define GDK_PIXBUF_C_COMPILATION +#include "gdk-pixbuf.h" +#include "gdk-pixbuf-private.h" +#include "gdk-pixbuf-simple-anim.h" + +struct _GdkPixbufSimpleAnimClass +{ + GdkPixbufAnimationClass parent_class; +}; + +/* Private part of the GdkPixbufSimpleAnim structure */ +struct _GdkPixbufSimpleAnim +{ + GdkPixbufAnimation parent_instance; + + gint n_frames; + + gfloat rate; + gint total_time; + + GList *frames; + + gint width; + gint height; + + gboolean loop; +}; + + +typedef struct _GdkPixbufSimpleAnimIter GdkPixbufSimpleAnimIter; +typedef struct _GdkPixbufSimpleAnimIterClass GdkPixbufSimpleAnimIterClass; + +#define GDK_TYPE_PIXBUF_SIMPLE_ANIM_ITER (gdk_pixbuf_simple_anim_iter_get_type ()) +#define GDK_PIXBUF_SIMPLE_ANIM_ITER(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_PIXBUF_SIMPLE_ANIM_ITER, GdkPixbufSimpleAnimIter)) +#define GDK_IS_PIXBUF_SIMPLE_ANIM_ITER(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_PIXBUF_SIMPLE_ANIM_ITER)) + +#define GDK_PIXBUF_SIMPLE_ANIM_ITER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_PIXBUF_SIMPLE_ANIM_ITER, GdkPixbufSimpleAnimIterClass)) +#define GDK_IS_PIXBUF_SIMPLE_ANIM_ITER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_PIXBUF_SIMPLE_ANIM_ITER)) +#define GDK_PIXBUF_SIMPLE_ANIM_ITER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_PIXBUF_SIMPLE_ANIM_ITER, GdkPixbufSimpleAnimIterClass)) + +GType gdk_pixbuf_simple_anim_iter_get_type (void) G_GNUC_CONST; + + +struct _GdkPixbufSimpleAnimIterClass +{ + GdkPixbufAnimationIterClass parent_class; +}; + +struct _GdkPixbufSimpleAnimIter +{ + GdkPixbufAnimationIter parent_instance; + + GdkPixbufSimpleAnim *simple_anim; + + GTimeVal start_time; + GTimeVal current_time; + + gint position; + + GList *current_frame; +}; + +typedef struct _GdkPixbufFrame GdkPixbufFrame; +struct _GdkPixbufFrame +{ + GdkPixbuf *pixbuf; + gint delay_time; + gint elapsed; +}; + +static void gdk_pixbuf_simple_anim_finalize (GObject *object); + +static gboolean is_static_image (GdkPixbufAnimation *animation); +static GdkPixbuf *get_static_image (GdkPixbufAnimation *animation); + +static void get_size (GdkPixbufAnimation *anim, + gint *width, + gint *height); +static GdkPixbufAnimationIter *get_iter (GdkPixbufAnimation *anim, + const GTimeVal *start_time); + + +static void gdk_pixbuf_simple_anim_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static void gdk_pixbuf_simple_anim_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); + +enum +{ + PROP_0, + PROP_LOOP +}; + +G_DEFINE_TYPE (GdkPixbufSimpleAnim, gdk_pixbuf_simple_anim, GDK_TYPE_PIXBUF_ANIMATION) + +static void +gdk_pixbuf_simple_anim_init (GdkPixbufSimpleAnim *anim) +{ +} + +static void +gdk_pixbuf_simple_anim_class_init (GdkPixbufSimpleAnimClass *klass) +{ + GObjectClass *object_class; + GdkPixbufAnimationClass *anim_class; + + object_class = G_OBJECT_CLASS (klass); + anim_class = GDK_PIXBUF_ANIMATION_CLASS (klass); + + object_class->set_property = gdk_pixbuf_simple_anim_set_property; + object_class->get_property = gdk_pixbuf_simple_anim_get_property; + object_class->finalize = gdk_pixbuf_simple_anim_finalize; + + anim_class->is_static_image = is_static_image; + anim_class->get_static_image = get_static_image; + anim_class->get_size = get_size; + anim_class->get_iter = get_iter; + + /** + * GdkPixbufSimpleAnim:loop: + * + * Whether the animation should loop when it reaches the end. + * + * Since: 2.18 + */ + g_object_class_install_property (object_class, + PROP_LOOP, + g_param_spec_boolean ("loop", + P_("Loop"), + P_("Whether the animation should loop when it reaches the end"), + FALSE, + G_PARAM_READWRITE)); +} + +static void +gdk_pixbuf_simple_anim_finalize (GObject *object) +{ + GdkPixbufSimpleAnim *anim; + GList *l; + GdkPixbufFrame *frame; + + anim = GDK_PIXBUF_SIMPLE_ANIM (object); + + for (l = anim->frames; l; l = l->next) { + frame = l->data; + g_object_unref (frame->pixbuf); + g_free (frame); + } + + g_list_free (anim->frames); + + G_OBJECT_CLASS (gdk_pixbuf_simple_anim_parent_class)->finalize (object); +} + +static gboolean +is_static_image (GdkPixbufAnimation *animation) +{ + GdkPixbufSimpleAnim *anim; + + anim = GDK_PIXBUF_SIMPLE_ANIM (animation); + + return (anim->frames != NULL && anim->frames->next == NULL); +} + +static GdkPixbuf * +get_static_image (GdkPixbufAnimation *animation) +{ + GdkPixbufSimpleAnim *anim; + + anim = GDK_PIXBUF_SIMPLE_ANIM (animation); + + if (anim->frames == NULL) + return NULL; + else + return ((GdkPixbufFrame *)anim->frames->data)->pixbuf; +} + +static void +get_size (GdkPixbufAnimation *animation, + gint *width, + gint *height) +{ + GdkPixbufSimpleAnim *anim; + + anim = GDK_PIXBUF_SIMPLE_ANIM (animation); + + if (width) + *width = anim->width; + + if (height) + *height = anim->height; +} + +static void +iter_clear (GdkPixbufSimpleAnimIter *iter) +{ + iter->current_frame = NULL; +} + +static void +iter_restart (GdkPixbufSimpleAnimIter *iter) +{ + iter_clear (iter); + + iter->current_frame = iter->simple_anim->frames; +} + +static GdkPixbufAnimationIter * +get_iter (GdkPixbufAnimation *anim, + const GTimeVal *start_time) +{ + GdkPixbufSimpleAnimIter *iter; + + iter = g_object_new (GDK_TYPE_PIXBUF_SIMPLE_ANIM_ITER, NULL); + + iter->simple_anim = GDK_PIXBUF_SIMPLE_ANIM (anim); + + g_object_ref (iter->simple_anim); + + iter_restart (iter); + + iter->start_time = *start_time; + iter->current_time = *start_time; + + return GDK_PIXBUF_ANIMATION_ITER (iter); +} + +static void gdk_pixbuf_simple_anim_iter_finalize (GObject *object); + +static gint get_delay_time (GdkPixbufAnimationIter *iter); +static GdkPixbuf *get_pixbuf (GdkPixbufAnimationIter *iter); +static gboolean on_currently_loading_frame (GdkPixbufAnimationIter *iter); +static gboolean advance (GdkPixbufAnimationIter *iter, + const GTimeVal *current_time); + +G_DEFINE_TYPE (GdkPixbufSimpleAnimIter, gdk_pixbuf_simple_anim_iter, GDK_TYPE_PIXBUF_ANIMATION_ITER) + +static void +gdk_pixbuf_simple_anim_iter_init (GdkPixbufSimpleAnimIter *iter) +{ +} + +static void +gdk_pixbuf_simple_anim_iter_class_init (GdkPixbufSimpleAnimIterClass *klass) +{ + GObjectClass *object_class; + GdkPixbufAnimationIterClass *anim_iter_class; + + object_class = G_OBJECT_CLASS (klass); + anim_iter_class = GDK_PIXBUF_ANIMATION_ITER_CLASS (klass); + + object_class->finalize = gdk_pixbuf_simple_anim_iter_finalize; + + anim_iter_class->get_delay_time = get_delay_time; + anim_iter_class->get_pixbuf = get_pixbuf; + anim_iter_class->on_currently_loading_frame = on_currently_loading_frame; + anim_iter_class->advance = advance; +} + +static void +gdk_pixbuf_simple_anim_iter_finalize (GObject *object) +{ + GdkPixbufSimpleAnimIter *iter; + + iter = GDK_PIXBUF_SIMPLE_ANIM_ITER (object); + iter_clear (iter); + + g_object_unref (iter->simple_anim); + + G_OBJECT_CLASS (gdk_pixbuf_simple_anim_iter_parent_class)->finalize (object); +} + +static gboolean +advance (GdkPixbufAnimationIter *anim_iter, + const GTimeVal *current_time) +{ + GdkPixbufSimpleAnimIter *iter; + gint elapsed; + gint loop_count; + GList *tmp; + GList *old; + + iter = GDK_PIXBUF_SIMPLE_ANIM_ITER (anim_iter); + + iter->current_time = *current_time; + + /* We use milliseconds for all times */ + elapsed = (((iter->current_time.tv_sec - iter->start_time.tv_sec) * G_USEC_PER_SEC + + iter->current_time.tv_usec - iter->start_time.tv_usec)) / 1000; + + if (elapsed < 0) { + /* Try to compensate; probably the system clock + * was set backwards + */ + iter->start_time = iter->current_time; + elapsed = 0; + } + + g_assert (iter->simple_anim->total_time > 0); + + /* See how many times we've already played the full animation, + * and subtract time for that. + */ + loop_count = elapsed / iter->simple_anim->total_time; + elapsed = elapsed % iter->simple_anim->total_time; + + iter->position = elapsed; + + /* Now move to the proper frame */ + if (loop_count < 1 || iter->simple_anim->loop) + tmp = iter->simple_anim->frames; + else + tmp = NULL; + + while (tmp != NULL) { + GdkPixbufFrame *frame = tmp->data; + + if (iter->position >= frame->elapsed && + iter->position < (frame->elapsed + frame->delay_time)) + break; + + tmp = tmp->next; + } + + old = iter->current_frame; + + iter->current_frame = tmp; + + return iter->current_frame != old; +} + +static gint +get_delay_time (GdkPixbufAnimationIter *anim_iter) +{ + GdkPixbufFrame *frame; + GdkPixbufSimpleAnimIter *iter; + + iter = GDK_PIXBUF_SIMPLE_ANIM_ITER (anim_iter); + + if (iter->current_frame) { + frame = iter->current_frame->data; + return frame->delay_time - (iter->position - frame->elapsed); + } + else { + return -1; /* show last frame forever */ + } +} + +static GdkPixbuf * +get_pixbuf (GdkPixbufAnimationIter *anim_iter) +{ + GdkPixbufSimpleAnimIter *iter; + GdkPixbufFrame *frame; + + iter = GDK_PIXBUF_SIMPLE_ANIM_ITER (anim_iter); + + if (iter->current_frame) + frame = iter->current_frame->data; + else if (g_list_length (iter->simple_anim->frames) > 0) + frame = g_list_last (iter->simple_anim->frames)->data; + else + frame = NULL; + + if (frame == NULL) + return NULL; + + return frame->pixbuf; +} + +static gboolean +on_currently_loading_frame (GdkPixbufAnimationIter *anim_iter) +{ + GdkPixbufSimpleAnimIter *iter; + + iter = GDK_PIXBUF_SIMPLE_ANIM_ITER (anim_iter); + + return iter->current_frame == NULL || iter->current_frame->next == NULL; +} + +/** + * gdk_pixbuf_simple_anim_new: + * @width: the width of the animation + * @height: the height of the animation + * @rate: the speed of the animation, in frames per second + * + * Creates a new, empty animation. + * + * Returns: a newly allocated #GdkPixbufSimpleAnim + * + * Since: 2.8 + */ +GdkPixbufSimpleAnim * +gdk_pixbuf_simple_anim_new (gint width, + gint height, + gfloat rate) +{ + GdkPixbufSimpleAnim *anim; + + anim = g_object_new (GDK_TYPE_PIXBUF_SIMPLE_ANIM, NULL); + anim->width = width; + anim->height = height; + anim->rate = rate; + + return anim; +} + +/** + * gdk_pixbuf_simple_anim_add_frame: + * @animation: a #GdkPixbufSimpleAnim + * @pixbuf: the pixbuf to add + * + * Adds a new frame to @animation. The @pixbuf must + * have the dimensions specified when the animation + * was constructed. + * + * Since: 2.8 + */ +void +gdk_pixbuf_simple_anim_add_frame (GdkPixbufSimpleAnim *animation, + GdkPixbuf *pixbuf) +{ + GdkPixbufFrame *frame; + int nframe = 0; + + g_return_if_fail (GDK_IS_PIXBUF_SIMPLE_ANIM (animation)); + g_return_if_fail (GDK_IS_PIXBUF (pixbuf)); + + nframe = g_list_length (animation->frames); + + frame = g_new0 (GdkPixbufFrame, 1); + frame->delay_time = (gint) (1000 / animation->rate); + frame->elapsed = (gint) (frame->delay_time * nframe); + animation->total_time += frame->delay_time; + frame->pixbuf = g_object_ref (pixbuf); + + animation->frames = g_list_append (animation->frames, frame); +} + +static void +gdk_pixbuf_simple_anim_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GdkPixbufSimpleAnim *animation = GDK_PIXBUF_SIMPLE_ANIM (object); + + switch (prop_id) { + case PROP_LOOP: + g_value_set_boolean (value, + gdk_pixbuf_simple_anim_get_loop (animation)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gdk_pixbuf_simple_anim_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GdkPixbufSimpleAnim *animation = GDK_PIXBUF_SIMPLE_ANIM (object); + + switch (prop_id) { + case PROP_LOOP: + gdk_pixbuf_simple_anim_set_loop (animation, + g_value_get_boolean (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +/** + * gdk_pixbuf_simple_anim_set_loop: + * @animation: a #GdkPixbufSimpleAnim + * @loop: whether to loop the animation + * + * Sets whether @animation should loop indefinitely when it reaches the end. + * + * Since: 2.18 + **/ +void +gdk_pixbuf_simple_anim_set_loop (GdkPixbufSimpleAnim *animation, + gboolean loop) +{ + g_return_if_fail (GDK_IS_PIXBUF_SIMPLE_ANIM (animation)); + + if (loop != animation->loop) { + animation->loop = loop; + g_object_notify (G_OBJECT (animation), "loop"); + } +} + +/** + * gdk_pixbuf_simple_anim_get_loop: + * @animation: a #GdkPixbufSimpleAnim + * + * Gets whether @animation should loop indefinitely when it reaches the end. + * + * Returns: %TRUE if the animation loops forever, %FALSE otherwise + * + * Since: 2.18 + **/ +gboolean +gdk_pixbuf_simple_anim_get_loop (GdkPixbufSimpleAnim *animation) +{ + g_return_val_if_fail (GDK_IS_PIXBUF_SIMPLE_ANIM (animation), FALSE); + + return animation->loop; +} diff --git a/libs/tk/ydk-pixbuf/gdk-pixbuf-util.c b/libs/tk/ydk-pixbuf/gdk-pixbuf-util.c new file mode 100644 index 0000000000..63627e97b6 --- /dev/null +++ b/libs/tk/ydk-pixbuf/gdk-pixbuf-util.c @@ -0,0 +1,392 @@ +/* GdkPixbuf library - Utilities and miscellaneous convenience functions + * + * Copyright (C) 1999 The Free Software Foundation + * + * Authors: Federico Mena-Quintero + * Cody Russell + * + * 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, see . + */ + +#include "config.h" +#include +#include + +#include "gdk-pixbuf-transform.h" +#include "gdk-pixbuf-private.h" + +/** + * SECTION:util + * @Short_description: Utility and miscellaneous convenience functions. + * @Title: Utilities + * @See_also: #GdkPixbuf + * + * These functions provide miscellaneous utilities for manipulating + * pixbufs. The pixel data in pixbufs may of course be manipulated + * directly by applications, but several common operations can be + * performed by these functions instead. + */ + + +/** + * gdk_pixbuf_add_alpha: + * @pixbuf: A #GdkPixbuf. + * @substitute_color: Whether to set a color to zero opacity. If this + * is %FALSE, then the (@r, @g, @b) arguments will be ignored. + * @r: Red value to substitute. + * @g: Green value to substitute. + * @b: Blue value to substitute. + * + * Takes an existing pixbuf and adds an alpha channel to it. + * If the existing pixbuf already had an alpha channel, the channel + * values are copied from the original; otherwise, the alpha channel + * is initialized to 255 (full opacity). + * + * If @substitute_color is %TRUE, then the color specified by (@r, @g, @b) will be + * assigned zero opacity. That is, if you pass (255, 255, 255) for the + * substitute color, all white pixels will become fully transparent. + * + * Return value: (transfer full): A newly-created pixbuf with a reference count of 1. + **/ +GdkPixbuf * +gdk_pixbuf_add_alpha (const GdkPixbuf *pixbuf, + gboolean substitute_color, guchar r, guchar g, guchar b) +{ + GdkPixbuf *new_pixbuf; + int x, y; + const guint8 *src_pixels; + guint8 *ret_pixels; + + g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), NULL); + g_return_val_if_fail (pixbuf->colorspace == GDK_COLORSPACE_RGB, NULL); + g_return_val_if_fail (pixbuf->n_channels == 3 || pixbuf->n_channels == 4, NULL); + g_return_val_if_fail (pixbuf->bits_per_sample == 8, NULL); + + src_pixels = gdk_pixbuf_read_pixels (pixbuf); + + if (pixbuf->has_alpha) { + new_pixbuf = gdk_pixbuf_copy (pixbuf); + if (!new_pixbuf) + return NULL; + + if (!substitute_color) + return new_pixbuf; + } else { + new_pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, pixbuf->width, pixbuf->height); + } + + if (!new_pixbuf) + return NULL; + + ret_pixels = gdk_pixbuf_get_pixels (new_pixbuf); + + for (y = 0; y < pixbuf->height; y++) { + const guchar *src; + guchar *dest; + guchar tr, tg, tb; + + src = src_pixels + y * pixbuf->rowstride; + dest = ret_pixels + y * new_pixbuf->rowstride; + + if (pixbuf->has_alpha) { + /* Just subst color, we already copied everything else */ + for (x = 0; x < pixbuf->width; x++) { + if (src[0] == r && src[1] == g && src[2] == b) + dest[3] = 0; + src += 4; + dest += 4; + } + } else { + for (x = 0; x < pixbuf->width; x++) { + tr = *dest++ = *src++; + tg = *dest++ = *src++; + tb = *dest++ = *src++; + + if (substitute_color && tr == r && tg == g && tb == b) + *dest++ = 0; + else + *dest++ = 255; + } + } + } + + return new_pixbuf; +} + +/** + * gdk_pixbuf_copy_area: + * @src_pixbuf: Source pixbuf. + * @src_x: Source X coordinate within @src_pixbuf. + * @src_y: Source Y coordinate within @src_pixbuf. + * @width: Width of the area to copy. + * @height: Height of the area to copy. + * @dest_pixbuf: Destination pixbuf. + * @dest_x: X coordinate within @dest_pixbuf. + * @dest_y: Y coordinate within @dest_pixbuf. + * + * Copies a rectangular area from @src_pixbuf to @dest_pixbuf. Conversion of + * pixbuf formats is done automatically. + * + * If the source rectangle overlaps the destination rectangle on the + * same pixbuf, it will be overwritten during the copy operation. + * Therefore, you can not use this function to scroll a pixbuf. + **/ +void +gdk_pixbuf_copy_area (const GdkPixbuf *src_pixbuf, + int src_x, int src_y, + int width, int height, + GdkPixbuf *dest_pixbuf, + int dest_x, int dest_y) +{ + g_return_if_fail (src_pixbuf != NULL); + g_return_if_fail (dest_pixbuf != NULL); + + g_return_if_fail (src_x >= 0 && src_x + width <= src_pixbuf->width); + g_return_if_fail (src_y >= 0 && src_y + height <= src_pixbuf->height); + + g_return_if_fail (dest_x >= 0 && dest_x + width <= dest_pixbuf->width); + g_return_if_fail (dest_y >= 0 && dest_y + height <= dest_pixbuf->height); + + g_return_if_fail (!(gdk_pixbuf_get_has_alpha (src_pixbuf) && !gdk_pixbuf_get_has_alpha (dest_pixbuf))); + + /* This will perform format conversions automatically */ + + gdk_pixbuf_scale (src_pixbuf, + dest_pixbuf, + dest_x, dest_y, + width, height, + (double) (dest_x - src_x), + (double) (dest_y - src_y), + 1.0, 1.0, + GDK_INTERP_NEAREST); +} + + + +/** + * gdk_pixbuf_saturate_and_pixelate: + * @src: source image + * @dest: place to write modified version of @src + * @saturation: saturation factor + * @pixelate: whether to pixelate + * + * Modifies saturation and optionally pixelates @src, placing the result in + * @dest. @src and @dest may be the same pixbuf with no ill effects. If + * @saturation is 1.0 then saturation is not changed. If it's less than 1.0, + * saturation is reduced (the image turns toward grayscale); if greater than + * 1.0, saturation is increased (the image gets more vivid colors). If @pixelate + * is %TRUE, then pixels are faded in a checkerboard pattern to create a + * pixelated image. @src and @dest must have the same image format, size, and + * rowstride. + * + **/ +void +gdk_pixbuf_saturate_and_pixelate(const GdkPixbuf *src, + GdkPixbuf *dest, + gfloat saturation, + gboolean pixelate) +{ + /* NOTE that src and dest MAY be the same pixbuf! */ + + g_return_if_fail (GDK_IS_PIXBUF (src)); + g_return_if_fail (GDK_IS_PIXBUF (dest)); + g_return_if_fail (gdk_pixbuf_get_height (src) == gdk_pixbuf_get_height (dest)); + g_return_if_fail (gdk_pixbuf_get_width (src) == gdk_pixbuf_get_width (dest)); + g_return_if_fail (gdk_pixbuf_get_has_alpha (src) == gdk_pixbuf_get_has_alpha (dest)); + g_return_if_fail (gdk_pixbuf_get_colorspace (src) == gdk_pixbuf_get_colorspace (dest)); + + if (saturation == 1.0 && !pixelate) { + if (dest != src) + gdk_pixbuf_copy_area (src, 0, 0, + gdk_pixbuf_get_width (src), + gdk_pixbuf_get_height (src), + dest, 0, 0); + } else { + int i, j, t; + int width, height, has_alpha, src_rowstride, dest_rowstride, bytes_per_pixel; + const guchar *src_line; + guchar *dest_line; + const guchar *src_pixel; + guchar *dest_pixel; + guchar intensity; + + has_alpha = gdk_pixbuf_get_has_alpha (src); + bytes_per_pixel = has_alpha ? 4 : 3; + width = gdk_pixbuf_get_width (src); + height = gdk_pixbuf_get_height (src); + src_rowstride = gdk_pixbuf_get_rowstride (src); + dest_rowstride = gdk_pixbuf_get_rowstride (dest); + + dest_line = gdk_pixbuf_get_pixels (dest); + src_line = gdk_pixbuf_read_pixels (src); + +#define DARK_FACTOR 0.7 +#define INTENSITY(r, g, b) ((r) * 0.30 + (g) * 0.59 + (b) * 0.11) +#define CLAMP_UCHAR(v) (t = (v), CLAMP (t, 0, 255)) +#define SATURATE(v) ((1.0 - saturation) * intensity + saturation * (v)) + + for (i = 0 ; i < height ; i++) { + src_pixel = src_line; + src_line += src_rowstride; + dest_pixel = dest_line; + dest_line += dest_rowstride; + + for (j = 0 ; j < width ; j++) { + intensity = INTENSITY (src_pixel[0], src_pixel[1], src_pixel[2]); + if (pixelate && (i + j) % 2 == 0) { + dest_pixel[0] = intensity / 2 + 127; + dest_pixel[1] = intensity / 2 + 127; + dest_pixel[2] = intensity / 2 + 127; + } else if (pixelate) { + dest_pixel[0] = CLAMP_UCHAR ((SATURATE (src_pixel[0])) * DARK_FACTOR); + dest_pixel[1] = CLAMP_UCHAR ((SATURATE (src_pixel[1])) * DARK_FACTOR); + dest_pixel[2] = CLAMP_UCHAR ((SATURATE (src_pixel[2])) * DARK_FACTOR); + } else { + dest_pixel[0] = CLAMP_UCHAR (SATURATE (src_pixel[0])); + dest_pixel[1] = CLAMP_UCHAR (SATURATE (src_pixel[1])); + dest_pixel[2] = CLAMP_UCHAR (SATURATE (src_pixel[2])); + } + + if (has_alpha) + dest_pixel[3] = src_pixel[3]; + + src_pixel += bytes_per_pixel; + dest_pixel += bytes_per_pixel; + } + } + } +} + + +/** + * gdk_pixbuf_apply_embedded_orientation: + * @src: A #GdkPixbuf. + * + * Takes an existing pixbuf and checks for the presence of an + * associated "orientation" option, which may be provided by the + * jpeg loader (which reads the exif orientation tag) or the + * tiff loader (which reads the tiff orientation tag, and + * compensates it for the partial transforms performed by + * libtiff). If an orientation option/tag is present, the + * appropriate transform will be performed so that the pixbuf + * is oriented correctly. + * + * Return value: (transfer full): A newly-created pixbuf, or a reference to the + * input pixbuf (with an increased reference count). + * + * Since: 2.12 + **/ +GdkPixbuf * +gdk_pixbuf_apply_embedded_orientation (GdkPixbuf *src) +{ + const gchar *orientation_string; + int transform = 0; + GdkPixbuf *temp; + GdkPixbuf *dest; + + g_return_val_if_fail (GDK_IS_PIXBUF (src), NULL); + + /* Read the orientation option associated with the pixbuf */ + orientation_string = gdk_pixbuf_get_option (src, "orientation"); + + if (orientation_string) { + /* If an orientation option was found, convert the + orientation string into an integer. */ + transform = (int) g_ascii_strtoll (orientation_string, NULL, 10); + } + + /* Apply the actual transforms, which involve rotations and flips. + The meaning of orientation values 1-8 and the required transforms + are defined by the TIFF and EXIF (for JPEGs) standards. */ + switch (transform) { + case 1: + dest = src; + g_object_ref (dest); + break; + case 2: + dest = gdk_pixbuf_flip (src, TRUE); + break; + case 3: + dest = gdk_pixbuf_rotate_simple (src, GDK_PIXBUF_ROTATE_UPSIDEDOWN); + break; + case 4: + dest = gdk_pixbuf_flip (src, FALSE); + break; + case 5: + temp = gdk_pixbuf_rotate_simple (src, GDK_PIXBUF_ROTATE_CLOCKWISE); + dest = gdk_pixbuf_flip (temp, TRUE); + g_object_unref (temp); + break; + case 6: + dest = gdk_pixbuf_rotate_simple (src, GDK_PIXBUF_ROTATE_CLOCKWISE); + break; + case 7: + temp = gdk_pixbuf_rotate_simple (src, GDK_PIXBUF_ROTATE_CLOCKWISE); + dest = gdk_pixbuf_flip (temp, FALSE); + g_object_unref (temp); + break; + case 8: + dest = gdk_pixbuf_rotate_simple (src, GDK_PIXBUF_ROTATE_COUNTERCLOCKWISE); + break; + default: + /* if no orientation tag was present */ + dest = src; + g_object_ref (dest); + break; + } + + return dest; +} + +#ifdef G_OS_WIN32 + +static const gchar * +get_localedir (void) +{ + gchar *temp; + gchar *retval; + + /* In gdk-pixbuf-io.c */ + extern char *_gdk_pixbuf_win32_get_toplevel (void); + + temp = g_build_filename (_gdk_pixbuf_win32_get_toplevel (), "share/locale", NULL); + + /* The localedir is passed to bindtextdomain() which isn't + * UTF-8-aware. + */ + retval = g_win32_locale_filename_from_utf8 (temp); + g_free (temp); + return retval; +} + +#undef GDK_PIXBUF_LOCALEDIR +#define GDK_PIXBUF_LOCALEDIR get_localedir () + +#endif + +const gchar * +gdk_pixbuf_gettext (const gchar *msgid) +{ + static gsize gettext_initialized = FALSE; + + if (G_UNLIKELY (g_once_init_enter (&gettext_initialized))) { + bindtextdomain (GETTEXT_PACKAGE, GDK_PIXBUF_LOCALEDIR); +#ifdef HAVE_BIND_TEXTDOMAIN_CODESET + bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); +#endif + g_once_init_leave (&gettext_initialized, TRUE); + } + + return g_dgettext (GETTEXT_PACKAGE, msgid); +} diff --git a/libs/tk/ydk-pixbuf/gdk-pixbuf.c b/libs/tk/ydk-pixbuf/gdk-pixbuf.c new file mode 100644 index 0000000000..655252107a --- /dev/null +++ b/libs/tk/ydk-pixbuf/gdk-pixbuf.c @@ -0,0 +1,1064 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ +/* GdkPixbuf library - Basic memory management + * + * Copyright (C) 1999 The Free Software Foundation + * + * Authors: Mark Crichton + * Miguel de Icaza + * Federico Mena-Quintero + * + * 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, see . + */ + +#include "config.h" + +#include +#include +#include + +#define GDK_PIXBUF_C_COMPILATION +#include "gdk-pixbuf-private.h" +#include "gdk-pixbuf-features.h" +#include "gdk-pixbuf-enum-types.h" + +/* Include the marshallers */ +#include +#include +#include "gdk-pixbuf-marshal.c" + +/** + * SECTION:creating + * @Short_description: Creating a pixbuf from image data that is already in memory. + * @Title: Image Data in Memory + * @See_also: gdk_pixbuf_finalize(). + * + * The most basic way to create a pixbuf is to wrap an existing pixel + * buffer with a #GdkPixbuf structure. You can use the + * gdk_pixbuf_new_from_data() function to do this You need to specify + * the destroy notification function that will be called when the + * data buffer needs to be freed; this will happen when a #GdkPixbuf + * is finalized by the reference counting functions If you have a + * chunk of static data compiled into your application, you can pass + * in %NULL as the destroy notification function so that the data + * will not be freed. + * + * The gdk_pixbuf_new() function can be used as a convenience to + * create a pixbuf with an empty buffer. This is equivalent to + * allocating a data buffer using malloc() and then wrapping it with + * gdk_pixbuf_new_from_data(). The gdk_pixbuf_new() function will + * compute an optimal rowstride so that rendering can be performed + * with an efficient algorithm. + * + * As a special case, you can use the gdk_pixbuf_new_from_xpm_data() + * function to create a pixbuf from inline XPM image data. + * + * You can also copy an existing pixbuf with the gdk_pixbuf_copy() + * function. This is not the same as just doing a g_object_ref() + * on the old pixbuf; the copy function will actually duplicate the + * pixel data in memory and create a new #GdkPixbuf structure for it. + */ + +/** + * SECTION:refcounting + * @Short_description: Functions for reference counting and memory management on pixbufs. + * @Title: Reference Counting and Memory Mangement + * @See_also: #GdkPixbuf, gdk_pixbuf_new_from_data(). + * + * #GdkPixbuf structures are reference counted. This means that an + * application can share a single pixbuf among many parts of the + * code. When a piece of the program needs to keep a pointer to a + * pixbuf, it should add a reference to it by calling g_object_ref(). + * When it no longer needs the pixbuf, it should subtract a reference + * by calling g_object_unref(). The pixbuf will be destroyed when + * its reference count drops to zero. Newly-created #GdkPixbuf + * structures start with a reference count of one. + * + * > As #GdkPixbuf is derived from #GObject now, gdk_pixbuf_ref() and + * > gdk_pixbuf_unref() are deprecated in favour of g_object_ref() + * > and g_object_unref() resp. + * + * Finalizing a pixbuf means to free its pixel data and to free the + * #GdkPixbuf structure itself. Most of the library functions that + * create #GdkPixbuf structures create the pixel data by themselves + * and define the way it should be freed; you do not need to worry + * about those. + * + * To provide preallocated pixel data, use + * gdk_pixbuf_new_from_bytes(). The gdk_pixbuf_new_from_data() API is + * an older variant that predates the existence of #GBytes. + */ + +static void gdk_pixbuf_finalize (GObject *object); +static void gdk_pixbuf_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static void gdk_pixbuf_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); + + +enum +{ + PROP_0, + PROP_COLORSPACE, + PROP_N_CHANNELS, + PROP_HAS_ALPHA, + PROP_BITS_PER_SAMPLE, + PROP_WIDTH, + PROP_HEIGHT, + PROP_ROWSTRIDE, + PROP_PIXELS, + PROP_PIXEL_BYTES +}; + +static void gdk_pixbuf_icon_iface_init (GIconIface *iface); +static void gdk_pixbuf_loadable_icon_iface_init (GLoadableIconIface *iface); + +G_DEFINE_TYPE_WITH_CODE (GdkPixbuf, gdk_pixbuf, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (G_TYPE_ICON, gdk_pixbuf_icon_iface_init) + G_IMPLEMENT_INTERFACE (G_TYPE_LOADABLE_ICON, gdk_pixbuf_loadable_icon_iface_init)) + +static void +gdk_pixbuf_init (GdkPixbuf *pixbuf) +{ +} + +static void +gdk_pixbuf_class_init (GdkPixbufClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = gdk_pixbuf_finalize; + object_class->set_property = gdk_pixbuf_set_property; + object_class->get_property = gdk_pixbuf_get_property; + +#define PIXBUF_PARAM_FLAGS G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY|\ + G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB + /** + * GdkPixbuf:n-channels: + * + * The number of samples per pixel. + * Currently, only 3 or 4 samples per pixel are supported. + */ + g_object_class_install_property (object_class, + PROP_N_CHANNELS, + g_param_spec_int ("n-channels", + P_("Number of Channels"), + P_("The number of samples per pixel"), + 0, + G_MAXINT, + 3, + PIXBUF_PARAM_FLAGS)); + + g_object_class_install_property (object_class, + PROP_COLORSPACE, + g_param_spec_enum ("colorspace", + P_("Colorspace"), + P_("The colorspace in which the samples are interpreted"), + GDK_TYPE_COLORSPACE, + GDK_COLORSPACE_RGB, + PIXBUF_PARAM_FLAGS)); + + g_object_class_install_property (object_class, + PROP_HAS_ALPHA, + g_param_spec_boolean ("has-alpha", + P_("Has Alpha"), + P_("Whether the pixbuf has an alpha channel"), + FALSE, + PIXBUF_PARAM_FLAGS)); + + /** + * GdkPixbuf:bits-per-sample: + * + * The number of bits per sample. + * Currently only 8 bit per sample are supported. + */ + g_object_class_install_property (object_class, + PROP_BITS_PER_SAMPLE, + g_param_spec_int ("bits-per-sample", + P_("Bits per Sample"), + P_("The number of bits per sample"), + 1, + 16, + 8, + PIXBUF_PARAM_FLAGS)); + + g_object_class_install_property (object_class, + PROP_WIDTH, + g_param_spec_int ("width", + P_("Width"), + P_("The number of columns of the pixbuf"), + 1, + G_MAXINT, + 1, + PIXBUF_PARAM_FLAGS)); + + g_object_class_install_property (object_class, + PROP_HEIGHT, + g_param_spec_int ("height", + P_("Height"), + P_("The number of rows of the pixbuf"), + 1, + G_MAXINT, + 1, + PIXBUF_PARAM_FLAGS)); + + /** + * GdkPixbuf:rowstride: + * + * The number of bytes between the start of a row and + * the start of the next row. This number must (obviously) + * be at least as large as the width of the pixbuf. + */ + g_object_class_install_property (object_class, + PROP_ROWSTRIDE, + g_param_spec_int ("rowstride", + P_("Rowstride"), + P_("The number of bytes between the start of a row and the start of the next row"), + 1, + G_MAXINT, + 1, + PIXBUF_PARAM_FLAGS)); + + g_object_class_install_property (object_class, + PROP_PIXELS, + g_param_spec_pointer ("pixels", + P_("Pixels"), + P_("A pointer to the pixel data of the pixbuf"), + PIXBUF_PARAM_FLAGS)); + + /** + * GdkPixbuf::pixel-bytes: + * + * If set, this pixbuf was created from read-only #GBytes. + * Replaces GdkPixbuf::pixels. + * + * Since: 2.32 + */ + g_object_class_install_property (object_class, + PROP_PIXEL_BYTES, + g_param_spec_boxed ("pixel-bytes", + P_("Pixel Bytes"), + P_("Readonly pixel data"), + G_TYPE_BYTES, + PIXBUF_PARAM_FLAGS)); +} + +static void +gdk_pixbuf_finalize (GObject *object) +{ + GdkPixbuf *pixbuf = GDK_PIXBUF (object); + + if (pixbuf->pixels && pixbuf->destroy_fn) + (* pixbuf->destroy_fn) (pixbuf->pixels, pixbuf->destroy_fn_data); + + g_clear_pointer (&pixbuf->bytes, g_bytes_unref); + + G_OBJECT_CLASS (gdk_pixbuf_parent_class)->finalize (object); +} + + +/** + * gdk_pixbuf_ref: (skip) + * @pixbuf: A pixbuf. + * + * Adds a reference to a pixbuf. + * + * Return value: The same as the @pixbuf argument. + * + * Deprecated: 2.0: Use g_object_ref(). + **/ +GdkPixbuf * +gdk_pixbuf_ref (GdkPixbuf *pixbuf) +{ + return (GdkPixbuf *) g_object_ref (pixbuf); +} + +/** + * gdk_pixbuf_unref: (skip) + * @pixbuf: A pixbuf. + * + * Removes a reference from a pixbuf. + * + * Deprecated: 2.0: Use g_object_unref(). + **/ +void +gdk_pixbuf_unref (GdkPixbuf *pixbuf) +{ + g_object_unref (pixbuf); +} + +static GBytes * +gdk_pixbuf_make_bytes (GdkPixbuf *pixbuf, + GError **error) +{ + gchar *buffer; + gsize size; + + if (!gdk_pixbuf_save_to_buffer (pixbuf, &buffer, &size, "png", error, NULL)) + return NULL; + + return g_bytes_new_take (buffer, size); +} + +static GVariant * +gdk_pixbuf_serialize (GIcon *icon) +{ + GError *error = NULL; + GVariant *result; + GBytes *bytes; + + bytes = gdk_pixbuf_make_bytes (GDK_PIXBUF (icon), &error); + if (!bytes) + { + g_critical ("Unable to serialise GdkPixbuf to png (via g_icon_serialize()): %s", error->message); + g_error_free (error); + return NULL; + } + result = g_variant_new_from_bytes (G_VARIANT_TYPE_BYTESTRING, bytes, TRUE); + g_bytes_unref (bytes); + + return g_variant_new ("(sv)", "bytes", result); +} + +static GInputStream * +gdk_pixbuf_load (GLoadableIcon *icon, + int size, + char **type, + GCancellable *cancellable, + GError **error) +{ + GInputStream *stream; + GBytes *bytes; + + bytes = gdk_pixbuf_make_bytes (GDK_PIXBUF (icon), error); + if (!bytes) + return NULL; + + stream = g_memory_input_stream_new_from_bytes (bytes); + g_bytes_unref (bytes); + + if (type) + *type = g_strdup ("image/png"); + + return stream; +} + +static void +gdk_pixbuf_load_async (GLoadableIcon *icon, + int size, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + + task = g_task_new (icon, cancellable, callback, user_data); + g_task_return_pointer (task, icon, NULL); + g_object_unref (task); +} + +static GInputStream * +gdk_pixbuf_load_finish (GLoadableIcon *icon, + GAsyncResult *res, + char **type, + GError **error) +{ + g_return_val_if_fail (g_task_is_valid (res, icon), NULL); + + if (!g_task_propagate_pointer (G_TASK (res), error)) + return NULL; + + return gdk_pixbuf_load (icon, 0, type, NULL, error); +} + +static void +gdk_pixbuf_loadable_icon_iface_init (GLoadableIconIface *iface) +{ + iface->load = gdk_pixbuf_load; + + /* In theory encoding a png could be time-consuming but we're talking + * about icons here, so assume it's probably going to be OK and handle + * the async variant of the call in-thread instead of having the + * default implementation dispatch it to a worker. + */ + iface->load_async = gdk_pixbuf_load_async; + iface->load_finish = gdk_pixbuf_load_finish; +} + +static void +gdk_pixbuf_icon_iface_init (GIconIface *iface) +{ + iface->hash = (guint (*) (GIcon *)) g_direct_hash; + iface->equal = (gboolean (*) (GIcon *, GIcon *)) g_direct_equal; + iface->serialize = gdk_pixbuf_serialize; +} + +/* Used as the destroy notification function for gdk_pixbuf_new() */ +static void +free_buffer (guchar *pixels, gpointer data) +{ + g_free (pixels); +} + +/** + * gdk_pixbuf_new: + * @colorspace: Color space for image + * @has_alpha: Whether the image should have transparency information + * @bits_per_sample: Number of bits per color sample + * @width: Width of image in pixels, must be > 0 + * @height: Height of image in pixels, must be > 0 + * + * Creates a new #GdkPixbuf structure and allocates a buffer for it. The + * buffer has an optimal rowstride. Note that the buffer is not cleared; + * you will have to fill it completely yourself. + * + * Return value: A newly-created #GdkPixbuf with a reference count of 1, or + * %NULL if not enough memory could be allocated for the image buffer. + **/ +GdkPixbuf * +gdk_pixbuf_new (GdkColorspace colorspace, + gboolean has_alpha, + int bits_per_sample, + int width, + int height) +{ + guchar *buf; + int channels; + int rowstride; + + g_return_val_if_fail (colorspace == GDK_COLORSPACE_RGB, NULL); + g_return_val_if_fail (bits_per_sample == 8, NULL); + g_return_val_if_fail (width > 0, NULL); + g_return_val_if_fail (height > 0, NULL); + + channels = has_alpha ? 4 : 3; + rowstride = width * channels; + if (rowstride / channels != width || rowstride + 3 < 0) /* overflow */ + return NULL; + + /* Always align rows to 32-bit boundaries */ + rowstride = (rowstride + 3) & ~3; + + buf = g_try_malloc_n (height, rowstride); + if (!buf) + return NULL; + + return gdk_pixbuf_new_from_data (buf, colorspace, has_alpha, bits_per_sample, + width, height, rowstride, + free_buffer, NULL); +} + +/** + * gdk_pixbuf_copy: + * @pixbuf: A pixbuf. + * + * Creates a new #GdkPixbuf with a copy of the information in the specified + * @pixbuf. + * + * Return value: (transfer full): A newly-created pixbuf with a reference count of 1, or %NULL if + * not enough memory could be allocated. + **/ +GdkPixbuf * +gdk_pixbuf_copy (const GdkPixbuf *pixbuf) +{ + guchar *buf; + int size; + + g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), NULL); + + /* Calculate a semi-exact size. Here we copy with full rowstrides; + * maybe we should copy each row individually with the minimum + * rowstride? + */ + + size = gdk_pixbuf_get_byte_length (pixbuf); + + buf = g_try_malloc (size); + if (!buf) + return NULL; + + memcpy (buf, gdk_pixbuf_read_pixels (pixbuf), size); + + return gdk_pixbuf_new_from_data (buf, + pixbuf->colorspace, pixbuf->has_alpha, + pixbuf->bits_per_sample, + pixbuf->width, pixbuf->height, + pixbuf->rowstride, + free_buffer, + NULL); +} + +/** + * gdk_pixbuf_new_subpixbuf: + * @src_pixbuf: a #GdkPixbuf + * @src_x: X coord in @src_pixbuf + * @src_y: Y coord in @src_pixbuf + * @width: width of region in @src_pixbuf + * @height: height of region in @src_pixbuf + * + * Creates a new pixbuf which represents a sub-region of @src_pixbuf. + * The new pixbuf shares its pixels with the original pixbuf, so + * writing to one affects both. The new pixbuf holds a reference to + * @src_pixbuf, so @src_pixbuf will not be finalized until the new + * pixbuf is finalized. + * + * Note that if @src_pixbuf is read-only, this function will force it + * to be mutable. + * + * Return value: (transfer full): a new pixbuf + **/ +GdkPixbuf* +gdk_pixbuf_new_subpixbuf (GdkPixbuf *src_pixbuf, + int src_x, + int src_y, + int width, + int height) +{ + guchar *pixels; + GdkPixbuf *sub; + + g_return_val_if_fail (GDK_IS_PIXBUF (src_pixbuf), NULL); + g_return_val_if_fail (src_x >= 0 && src_x + width <= src_pixbuf->width, NULL); + g_return_val_if_fail (src_y >= 0 && src_y + height <= src_pixbuf->height, NULL); + + /* Note causes an implicit copy where src_pixbuf owns the data */ + pixels = (gdk_pixbuf_get_pixels (src_pixbuf) + + src_y * src_pixbuf->rowstride + + src_x * src_pixbuf->n_channels); + + sub = gdk_pixbuf_new_from_data (pixels, + src_pixbuf->colorspace, + src_pixbuf->has_alpha, + src_pixbuf->bits_per_sample, + width, height, + src_pixbuf->rowstride, + NULL, NULL); + + /* Keep a reference to src_pixbuf */ + g_object_ref (src_pixbuf); + + g_object_set_qdata_full (G_OBJECT (sub), + g_quark_from_static_string ("gdk-pixbuf-subpixbuf-src"), + src_pixbuf, + (GDestroyNotify) g_object_unref); + + return sub; +} + + + +/* Accessors */ + +/** + * gdk_pixbuf_get_colorspace: + * @pixbuf: A pixbuf. + * + * Queries the color space of a pixbuf. + * + * Return value: Color space. + **/ +GdkColorspace +gdk_pixbuf_get_colorspace (const GdkPixbuf *pixbuf) +{ + g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), GDK_COLORSPACE_RGB); + + return pixbuf->colorspace; +} + +/** + * gdk_pixbuf_get_n_channels: + * @pixbuf: A pixbuf. + * + * Queries the number of channels of a pixbuf. + * + * Return value: Number of channels. + **/ +int +gdk_pixbuf_get_n_channels (const GdkPixbuf *pixbuf) +{ + g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), -1); + + return pixbuf->n_channels; +} + +/** + * gdk_pixbuf_get_has_alpha: + * @pixbuf: A pixbuf. + * + * Queries whether a pixbuf has an alpha channel (opacity information). + * + * Return value: %TRUE if it has an alpha channel, %FALSE otherwise. + **/ +gboolean +gdk_pixbuf_get_has_alpha (const GdkPixbuf *pixbuf) +{ + g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), FALSE); + + return pixbuf->has_alpha ? TRUE : FALSE; +} + +/** + * gdk_pixbuf_get_bits_per_sample: + * @pixbuf: A pixbuf. + * + * Queries the number of bits per color sample in a pixbuf. + * + * Return value: Number of bits per color sample. + **/ +int +gdk_pixbuf_get_bits_per_sample (const GdkPixbuf *pixbuf) +{ + g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), -1); + + return pixbuf->bits_per_sample; +} + +/** + * gdk_pixbuf_get_pixels: + * @pixbuf: A pixbuf. + * + * Queries a pointer to the pixel data of a pixbuf. + * + * Return value: (array): A pointer to the pixbuf's pixel data. + * Please see the section on [image data](image-data) for information + * about how the pixel data is stored in memory. + * + * This function will cause an implicit copy of the pixbuf data if the + * pixbuf was created from read-only data. + **/ +guchar * +gdk_pixbuf_get_pixels (const GdkPixbuf *pixbuf) +{ + return gdk_pixbuf_get_pixels_with_length (pixbuf, NULL); +} + +/** + * gdk_pixbuf_get_pixels_with_length: + * @pixbuf: A pixbuf. + * @length: (out): The length of the binary data. + * + * Queries a pointer to the pixel data of a pixbuf. + * + * Return value: (array length=length): A pointer to the pixbuf's + * pixel data. Please see the section on [image data](image-data) + * for information about how the pixel data is stored in memory. + * + * This function will cause an implicit copy of the pixbuf data if the + * pixbuf was created from read-only data. + * + * Rename to: gdk_pixbuf_get_pixels + * + * Since: 2.26 + */ +guchar * +gdk_pixbuf_get_pixels_with_length (const GdkPixbuf *pixbuf, + guint *length) +{ + g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), NULL); + + if (pixbuf->bytes) { + GdkPixbuf *mut_pixbuf = (GdkPixbuf*)pixbuf; + gsize len; + mut_pixbuf->pixels = g_bytes_unref_to_data (pixbuf->bytes, &len); + mut_pixbuf->bytes = NULL; + } + + if (length) + *length = gdk_pixbuf_get_byte_length (pixbuf); + + return pixbuf->pixels; +} + +/** + * gdk_pixbuf_read_pixels: + * @pixbuf: A pixbuf + * + * Returns a read-only pointer to the raw pixel data; must not be + * modified. This function allows skipping the implicit copy that + * must be made if gdk_pixbuf_get_pixels() is called on a read-only + * pixbuf. + * + * Since: 2.32 + */ +const guint8* +gdk_pixbuf_read_pixels (const GdkPixbuf *pixbuf) +{ + g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), NULL); + + if (pixbuf->bytes) { + gsize len; + /* Ignore len; callers know the size via other variables */ + return g_bytes_get_data (pixbuf->bytes, &len); + } else { + return pixbuf->pixels; + } +} + +/** + * gdk_pixbuf_read_pixel_bytes: + * @pixbuf: A pixbuf + * + * Returns: (transfer full): A new reference to a read-only copy of + * the pixel data. Note that for mutable pixbufs, this function will + * incur a one-time copy of the pixel data for conversion into the + * returned #GBytes. + * + * Since: 2.32 + */ +GBytes * +gdk_pixbuf_read_pixel_bytes (const GdkPixbuf *pixbuf) +{ + g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), NULL); + + if (pixbuf->bytes) { + return g_bytes_ref (pixbuf->bytes); + } else { + return g_bytes_new (pixbuf->pixels, + gdk_pixbuf_get_byte_length (pixbuf)); + } +} + +/** + * gdk_pixbuf_get_width: + * @pixbuf: A pixbuf. + * + * Queries the width of a pixbuf. + * + * Return value: Width in pixels. + **/ +int +gdk_pixbuf_get_width (const GdkPixbuf *pixbuf) +{ + g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), -1); + + return pixbuf->width; +} + +/** + * gdk_pixbuf_get_height: + * @pixbuf: A pixbuf. + * + * Queries the height of a pixbuf. + * + * Return value: Height in pixels. + **/ +int +gdk_pixbuf_get_height (const GdkPixbuf *pixbuf) +{ + g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), -1); + + return pixbuf->height; +} + +/** + * gdk_pixbuf_get_rowstride: + * @pixbuf: A pixbuf. + * + * Queries the rowstride of a pixbuf, which is the number of bytes between + * the start of a row and the start of the next row. + * + * Return value: Distance between row starts. + **/ +int +gdk_pixbuf_get_rowstride (const GdkPixbuf *pixbuf) +{ + g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), -1); + + return pixbuf->rowstride; +} + +/** + * gdk_pixbuf_get_byte_length: + * @pixbuf: A pixbuf + * + * Returns the length of the pixel data, in bytes. + * + * Return value: The length of the pixel data. + * + * Since: 2.26 + */ +gsize +gdk_pixbuf_get_byte_length (const GdkPixbuf *pixbuf) +{ + g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), -1); + + return ((pixbuf->height - 1) * pixbuf->rowstride + + pixbuf->width * ((pixbuf->n_channels * pixbuf->bits_per_sample + 7) / 8)); +} + + + +/* General initialization hooks */ +const guint gdk_pixbuf_major_version = GDK_PIXBUF_MAJOR; +const guint gdk_pixbuf_minor_version = GDK_PIXBUF_MINOR; +const guint gdk_pixbuf_micro_version = GDK_PIXBUF_MICRO; + +const char *gdk_pixbuf_version = GDK_PIXBUF_VERSION; + +/* Error quark */ +GQuark +gdk_pixbuf_error_quark (void) +{ + return g_quark_from_static_string ("gdk-pixbuf-error-quark"); +} + +/** + * gdk_pixbuf_fill: + * @pixbuf: a #GdkPixbuf + * @pixel: RGBA pixel to clear to + * (0xffffffff is opaque white, 0x00000000 transparent black) + * + * Clears a pixbuf to the given RGBA value, converting the RGBA value into + * the pixbuf's pixel format. The alpha will be ignored if the pixbuf + * doesn't have an alpha channel. + * + **/ +void +gdk_pixbuf_fill (GdkPixbuf *pixbuf, + guint32 pixel) +{ + guchar *pixels; + guint r, g, b, a; + guchar *p; + guint w, h; + + g_return_if_fail (GDK_IS_PIXBUF (pixbuf)); + + if (pixbuf->width == 0 || pixbuf->height == 0) + return; + + /* Force an implicit copy */ + pixels = gdk_pixbuf_get_pixels (pixbuf); + + r = (pixel & 0xff000000) >> 24; + g = (pixel & 0x00ff0000) >> 16; + b = (pixel & 0x0000ff00) >> 8; + a = (pixel & 0x000000ff); + + h = pixbuf->height; + + while (h--) { + w = pixbuf->width; + p = pixels; + + switch (pixbuf->n_channels) { + case 3: + while (w--) { + p[0] = r; + p[1] = g; + p[2] = b; + p += 3; + } + break; + case 4: + while (w--) { + p[0] = r; + p[1] = g; + p[2] = b; + p[3] = a; + p += 4; + } + break; + default: + break; + } + + pixels += pixbuf->rowstride; + } +} + + + +/** + * gdk_pixbuf_get_option: + * @pixbuf: a #GdkPixbuf + * @key: a nul-terminated string. + * + * Looks up @key in the list of options that may have been attached to the + * @pixbuf when it was loaded, or that may have been attached by another + * function using gdk_pixbuf_set_option(). + * + * For instance, the ANI loader provides "Title" and "Artist" options. + * The ICO, XBM, and XPM loaders provide "x_hot" and "y_hot" hot-spot + * options for cursor definitions. The PNG loader provides the tEXt ancillary + * chunk key/value pairs as options. Since 2.12, the TIFF and JPEG loaders + * return an "orientation" option string that corresponds to the embedded + * TIFF/Exif orientation tag (if present). + * + * Return value: the value associated with @key. This is a nul-terminated + * string that should not be freed or %NULL if @key was not found. + **/ +const gchar * +gdk_pixbuf_get_option (GdkPixbuf *pixbuf, + const gchar *key) +{ + gchar **options; + gint i; + + g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), NULL); + g_return_val_if_fail (key != NULL, NULL); + + options = g_object_get_qdata (G_OBJECT (pixbuf), + g_quark_from_static_string ("gdk_pixbuf_options")); + if (options) { + for (i = 0; options[2*i]; i++) { + if (strcmp (options[2*i], key) == 0) + return options[2*i+1]; + } + } + + return NULL; +} + +/** + * gdk_pixbuf_set_option: + * @pixbuf: a #GdkPixbuf + * @key: a nul-terminated string. + * @value: a nul-terminated string. + * + * Attaches a key/value pair as an option to a #GdkPixbuf. If @key already + * exists in the list of options attached to @pixbuf, the new value is + * ignored and %FALSE is returned. + * + * Return value: %TRUE on success. + * + * Since: 2.2 + **/ +gboolean +gdk_pixbuf_set_option (GdkPixbuf *pixbuf, + const gchar *key, + const gchar *value) +{ + GQuark quark; + gchar **options; + gint n = 0; + + g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), FALSE); + g_return_val_if_fail (key != NULL, FALSE); + g_return_val_if_fail (value != NULL, FALSE); + + quark = g_quark_from_static_string ("gdk_pixbuf_options"); + + options = g_object_get_qdata (G_OBJECT (pixbuf), quark); + + if (options) { + for (n = 0; options[2*n]; n++) { + if (strcmp (options[2*n], key) == 0) + return FALSE; + } + + g_object_steal_qdata (G_OBJECT (pixbuf), quark); + options = g_renew (gchar *, options, 2*(n+1) + 1); + } else { + options = g_new (gchar *, 3); + } + + options[2*n] = g_strdup (key); + options[2*n+1] = g_strdup (value); + options[2*n+2] = NULL; + + g_object_set_qdata_full (G_OBJECT (pixbuf), quark, + options, (GDestroyNotify) g_strfreev); + + return TRUE; +} + +static void +gdk_pixbuf_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GdkPixbuf *pixbuf = GDK_PIXBUF (object); + + switch (prop_id) + { + case PROP_COLORSPACE: + pixbuf->colorspace = g_value_get_enum (value); + break; + case PROP_N_CHANNELS: + pixbuf->n_channels = g_value_get_int (value); + break; + case PROP_HAS_ALPHA: + pixbuf->has_alpha = g_value_get_boolean (value); + break; + case PROP_BITS_PER_SAMPLE: + pixbuf->bits_per_sample = g_value_get_int (value); + break; + case PROP_WIDTH: + pixbuf->width = g_value_get_int (value); + break; + case PROP_HEIGHT: + pixbuf->height = g_value_get_int (value); + break; + case PROP_ROWSTRIDE: + pixbuf->rowstride = g_value_get_int (value); + break; + case PROP_PIXELS: + pixbuf->pixels = (guchar *) g_value_get_pointer (value); + break; + case PROP_PIXEL_BYTES: + pixbuf->bytes = g_value_dup_boxed (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gdk_pixbuf_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GdkPixbuf *pixbuf = GDK_PIXBUF (object); + + switch (prop_id) + { + case PROP_COLORSPACE: + g_value_set_enum (value, gdk_pixbuf_get_colorspace (pixbuf)); + break; + case PROP_N_CHANNELS: + g_value_set_int (value, gdk_pixbuf_get_n_channels (pixbuf)); + break; + case PROP_HAS_ALPHA: + g_value_set_boolean (value, gdk_pixbuf_get_has_alpha (pixbuf)); + break; + case PROP_BITS_PER_SAMPLE: + g_value_set_int (value, gdk_pixbuf_get_bits_per_sample (pixbuf)); + break; + case PROP_WIDTH: + g_value_set_int (value, gdk_pixbuf_get_width (pixbuf)); + break; + case PROP_HEIGHT: + g_value_set_int (value, gdk_pixbuf_get_height (pixbuf)); + break; + case PROP_ROWSTRIDE: + g_value_set_int (value, gdk_pixbuf_get_rowstride (pixbuf)); + break; + case PROP_PIXELS: + g_value_set_pointer (value, gdk_pixbuf_get_pixels (pixbuf)); + break; + case PROP_PIXEL_BYTES: + g_value_set_boxed (value, pixbuf->bytes); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} diff --git a/libs/tk/ydk-pixbuf/gdk-pixdata.c b/libs/tk/ydk-pixbuf/gdk-pixdata.c new file mode 100644 index 0000000000..d0fe7d5e0b --- /dev/null +++ b/libs/tk/ydk-pixbuf/gdk-pixdata.c @@ -0,0 +1,914 @@ +/* GdkPixbuf library - GdkPixdata - functions for inlined pixbuf handling + * Copyright (C) 1999, 2001 Tim Janik + * + * 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, see . + */ +#include "config.h" + +#include "gdk-pixbuf-private.h" +#include "gdk-pixdata.h" +#include + +/** + * SECTION:inline + * @Short_description: Functions for inlined pixbuf handling. + * @Title: Inline data + * + * Using #GdkPixdata, images can be compiled into an application, + * making it unnecessary to refer to external image files at runtime. + * GdkPixBuf includes a utility named gdk-pixbuf-csource, which + * can be used to convert image files into #GdkPixdata structures suitable + * for inclusion in C sources. To convert the #GdkPixdata structures back + * into #GdkPixbufs, use gdk_pixbuf_from_pixdata. + */ + +#define APPEND g_string_append_printf + +/* --- functions --- */ +static guint +pixdata_get_length (const GdkPixdata *pixdata) +{ + guint bpp, length; + + if ((pixdata->pixdata_type & GDK_PIXDATA_COLOR_TYPE_MASK) == GDK_PIXDATA_COLOR_TYPE_RGB) + bpp = 3; + else if ((pixdata->pixdata_type & GDK_PIXDATA_COLOR_TYPE_MASK) == GDK_PIXDATA_COLOR_TYPE_RGBA) + bpp = 4; + else + return 0; /* invalid format */ + switch (pixdata->pixdata_type & GDK_PIXDATA_ENCODING_MASK) + { + guint8 *rle_buffer; + guint max_length; + case GDK_PIXDATA_ENCODING_RAW: + length = pixdata->rowstride * pixdata->height; + break; + case GDK_PIXDATA_ENCODING_RLE: + /* need an RLE walk to determine size */ + max_length = pixdata->rowstride * pixdata->height; + rle_buffer = pixdata->pixel_data; + length = 0; + while (length < max_length) + { + guint chunk_length = *(rle_buffer++); + + if (chunk_length & 128) + { + chunk_length = chunk_length - 128; + if (!chunk_length) /* RLE data corrupted */ + return 0; + length += chunk_length * bpp; + rle_buffer += bpp; + } + else + { + if (!chunk_length) /* RLE data corrupted */ + return 0; + chunk_length *= bpp; + length += chunk_length; + rle_buffer += chunk_length; + } + } + length = rle_buffer - pixdata->pixel_data; + break; + default: + length = 0; + break; + } + return length; +} + +/** + * gdk_pixdata_serialize: + * @pixdata: a valid #GdkPixdata structure to serialize. + * @stream_length_p: location to store the resulting stream length in. + * + * Serializes a #GdkPixdata structure into a byte stream. + * The byte stream consists of a straightforward writeout of the + * #GdkPixdata fields in network byte order, plus the @pixel_data + * bytes the structure points to. + * + * Return value: (array length=stream_length_p) (transfer full): A + * newly-allocated string containing the serialized #GdkPixdata + * structure. + **/ +guint8* /* free result */ +gdk_pixdata_serialize (const GdkPixdata *pixdata, + guint *stream_length_p) +{ + guint8 *stream, *s; + guint32 *istream; + guint length; + + /* check args passing */ + g_return_val_if_fail (pixdata != NULL, NULL); + g_return_val_if_fail (stream_length_p != NULL, NULL); + /* check pixdata contents */ + g_return_val_if_fail (pixdata->magic == GDK_PIXBUF_MAGIC_NUMBER, NULL); + g_return_val_if_fail (pixdata->width > 0, NULL); + g_return_val_if_fail (pixdata->height > 0, NULL); + g_return_val_if_fail (pixdata->rowstride >= pixdata->width, NULL); + g_return_val_if_fail ((pixdata->pixdata_type & GDK_PIXDATA_COLOR_TYPE_MASK) == GDK_PIXDATA_COLOR_TYPE_RGB || + (pixdata->pixdata_type & GDK_PIXDATA_COLOR_TYPE_MASK) == GDK_PIXDATA_COLOR_TYPE_RGBA, NULL); + g_return_val_if_fail ((pixdata->pixdata_type & GDK_PIXDATA_SAMPLE_WIDTH_MASK) == GDK_PIXDATA_SAMPLE_WIDTH_8, NULL); + g_return_val_if_fail ((pixdata->pixdata_type & GDK_PIXDATA_ENCODING_MASK) == GDK_PIXDATA_ENCODING_RAW || + (pixdata->pixdata_type & GDK_PIXDATA_ENCODING_MASK) == GDK_PIXDATA_ENCODING_RLE, NULL); + g_return_val_if_fail (pixdata->pixel_data != NULL, NULL); + + length = pixdata_get_length (pixdata); + + /* check length field */ + g_return_val_if_fail (length != 0, NULL); + + stream = g_malloc (GDK_PIXDATA_HEADER_LENGTH + length); + istream = (guint32*) stream; + + /* store header */ + *istream++ = g_htonl (GDK_PIXBUF_MAGIC_NUMBER); + *istream++ = g_htonl (GDK_PIXDATA_HEADER_LENGTH + length); + *istream++ = g_htonl (pixdata->pixdata_type); + *istream++ = g_htonl (pixdata->rowstride); + *istream++ = g_htonl (pixdata->width); + *istream++ = g_htonl (pixdata->height); + + /* copy pixel data */ + s = (guint8*) istream; + memcpy (s, pixdata->pixel_data, length); + s += length; + + *stream_length_p = GDK_PIXDATA_HEADER_LENGTH + length; + g_assert (s - stream == *stream_length_p); /* paranoid */ + + return stream; +} + +#define return_header_corrupt(error) { \ + g_set_error_literal (error, GDK_PIXBUF_ERROR, \ + GDK_PIXBUF_ERROR_CORRUPT_IMAGE, _("Image header corrupt")); \ + return FALSE; \ +} +#define return_invalid_format(error) { \ + g_set_error_literal (error, GDK_PIXBUF_ERROR, \ + GDK_PIXBUF_ERROR_UNKNOWN_TYPE, _("Image format unknown")); \ + return FALSE; \ +} +#define return_pixel_corrupt(error) { \ + g_set_error_literal (error, GDK_PIXBUF_ERROR, \ + GDK_PIXBUF_ERROR_CORRUPT_IMAGE, _("Image pixel data corrupt")); \ + return FALSE; \ +} + +static inline const guint8 * +get_uint32 (const guint8 *stream, guint *result) +{ + *result = (stream[0] << 24) + (stream[1] << 16) + (stream[2] << 8) + stream[3]; + return stream + 4; +} + +/** + * gdk_pixdata_deserialize: + * @pixdata: a #GdkPixdata structure to be filled in. + * @stream_length: length of the stream used for deserialization. + * @stream: (array length=stream_length): stream of bytes containing a + * serialized #GdkPixdata structure. + * @error: #GError location to indicate failures (maybe %NULL to ignore errors). + * + * Deserializes (reconstruct) a #GdkPixdata structure from a byte stream. + * The byte stream consists of a straightforward writeout of the + * #GdkPixdata fields in network byte order, plus the @pixel_data + * bytes the structure points to. + * The @pixdata contents are reconstructed byte by byte and are checked + * for validity. This function may fail with %GDK_PIXBUF_ERROR_CORRUPT_IMAGE + * or %GDK_PIXBUF_ERROR_UNKNOWN_TYPE. + * + * Return value: Upon successful deserialization %TRUE is returned, + * %FALSE otherwise. + **/ +gboolean +gdk_pixdata_deserialize (GdkPixdata *pixdata, + guint stream_length, + const guint8 *stream, + GError **error) +{ + guint color_type, sample_width, encoding; + + g_return_val_if_fail (pixdata != NULL, FALSE); + if (stream_length < GDK_PIXDATA_HEADER_LENGTH) + return_header_corrupt (error); + g_return_val_if_fail (stream != NULL, FALSE); + + + /* deserialize header */ + stream = get_uint32 (stream, &pixdata->magic); + stream = get_uint32 (stream, (guint32 *)&pixdata->length); + if (pixdata->magic != GDK_PIXBUF_MAGIC_NUMBER || pixdata->length < GDK_PIXDATA_HEADER_LENGTH) + return_header_corrupt (error); + stream = get_uint32 (stream, &pixdata->pixdata_type); + stream = get_uint32 (stream, &pixdata->rowstride); + stream = get_uint32 (stream, &pixdata->width); + stream = get_uint32 (stream, &pixdata->height); + if (pixdata->width < 1 || pixdata->height < 1 || + pixdata->rowstride < pixdata->width) + return_header_corrupt (error); + color_type = pixdata->pixdata_type & GDK_PIXDATA_COLOR_TYPE_MASK; + sample_width = pixdata->pixdata_type & GDK_PIXDATA_SAMPLE_WIDTH_MASK; + encoding = pixdata->pixdata_type & GDK_PIXDATA_ENCODING_MASK; + if ((color_type != GDK_PIXDATA_COLOR_TYPE_RGB && + color_type != GDK_PIXDATA_COLOR_TYPE_RGBA) || + sample_width != GDK_PIXDATA_SAMPLE_WIDTH_8 || + (encoding != GDK_PIXDATA_ENCODING_RAW && + encoding != GDK_PIXDATA_ENCODING_RLE)) + return_invalid_format (error); + + /* deserialize pixel data */ + if (stream_length < pixdata->length - GDK_PIXDATA_HEADER_LENGTH) + return_pixel_corrupt (error); + pixdata->pixel_data = (guint8 *)stream; + + return TRUE; +} + +static gboolean +diff2_rgb (guint8 *ip) +{ + return ip[0] != ip[3] || ip[1] != ip[4] || ip[2] != ip[5]; +} + +static gboolean +diff2_rgba (guint8 *ip) +{ + return ip[0] != ip[4] || ip[1] != ip[5] || ip[2] != ip[6] || ip[3] != ip[7]; +} + +static guint8* /* dest buffer bound */ +rl_encode_rgbx (guint8 *bp, /* dest buffer */ + guint8 *ip, /* image pointer */ + guint8 *limit, /* image upper bound */ + guint n_ch) +{ + gboolean (*diff2_pix) (guint8 *) = n_ch > 3 ? diff2_rgba : diff2_rgb; + guint8 *ilimit = limit - n_ch; + + while (ip < limit) + { + g_assert (ip < ilimit); /* paranoid */ + + if (diff2_pix (ip)) + { + guint8 *s_ip = ip; + guint l = 1; + + ip += n_ch; + while (l < 127 && ip < ilimit && diff2_pix (ip)) + { ip += n_ch; l += 1; } + if (ip == ilimit && l < 127) + { ip += n_ch; l += 1; } + *(bp++) = l; + memcpy (bp, s_ip, l * n_ch); + bp += l * n_ch; + } + else + { + guint l = 2; + + ip += n_ch; + while (l < 127 && ip < ilimit && !diff2_pix (ip)) + { ip += n_ch; l += 1; } + *(bp++) = l | 128; + memcpy (bp, ip, n_ch); + ip += n_ch; + bp += n_ch; + } + if (ip == ilimit) + { + *(bp++) = 1; + memcpy (bp, ip, n_ch); + ip += n_ch; + bp += n_ch; + } + } + + return bp; +} + +/* Used as the destroy notification function for gdk_pixbuf_new() */ +static void +free_buffer (guchar *pixels, gpointer data) +{ + g_free (pixels); +} + +/** + * gdk_pixdata_from_pixbuf: (skip) + * @pixdata: a #GdkPixdata to fill. + * @pixbuf: the data to fill @pixdata with. + * @use_rle: whether to use run-length encoding for the pixel data. + * + * Converts a #GdkPixbuf to a #GdkPixdata. If @use_rle is %TRUE, the + * pixel data is run-length encoded into newly-allocated memory and a + * pointer to that memory is returned. + * + * Returns: (nullable): If @use_rle is %TRUE, a pointer to the + * newly-allocated memory for the run-length encoded pixel data, + * otherwise %NULL. + **/ +gpointer +gdk_pixdata_from_pixbuf (GdkPixdata *pixdata, + const GdkPixbuf *pixbuf, + gboolean use_rle) +{ + gpointer free_me = NULL; + guint height, rowstride, encoding, bpp, length; + guint8 *img_buffer; + + g_return_val_if_fail (pixdata != NULL, NULL); + g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), NULL); + g_return_val_if_fail (pixbuf->bits_per_sample == 8, NULL); + g_return_val_if_fail ((pixbuf->n_channels == 3 && !pixbuf->has_alpha) || + (pixbuf->n_channels == 4 && pixbuf->has_alpha), NULL); + g_return_val_if_fail (pixbuf->rowstride >= pixbuf->width, NULL); + + height = pixbuf->height; + rowstride = pixbuf->rowstride; + bpp = pixbuf->has_alpha ? 4 : 3; + encoding = use_rle && ((rowstride / bpp | height) > 1) ? GDK_PIXDATA_ENCODING_RLE : GDK_PIXDATA_ENCODING_RAW; + + if (encoding == GDK_PIXDATA_ENCODING_RLE) + { + guint pad, n_bytes = rowstride * height; + guint8 *img_buffer_end, *data; + GdkPixbuf *buf = NULL; + + if (n_bytes % bpp != 0) + { + rowstride = pixbuf->width * bpp; + n_bytes = rowstride * height; + data = g_malloc (n_bytes); + buf = gdk_pixbuf_new_from_data (data, + GDK_COLORSPACE_RGB, + pixbuf->has_alpha, 8, + pixbuf->width, + pixbuf->height, + rowstride, + free_buffer, NULL); + gdk_pixbuf_copy_area (pixbuf, 0, 0, pixbuf->width, pixbuf->height, + buf, 0, 0); + } + else + buf = (GdkPixbuf *)pixbuf; + pad = rowstride; + pad = MAX (pad, 130 + n_bytes / 127); + data = g_new (guint8, pad + n_bytes); + free_me = data; + img_buffer = data; + img_buffer_end = rl_encode_rgbx (img_buffer, + buf->pixels, buf->pixels + n_bytes, + bpp); + length = img_buffer_end - img_buffer; + if (buf != pixbuf) + g_object_unref (buf); + } + else + { + img_buffer = pixbuf->pixels; + length = rowstride * height; + } + + pixdata->magic = GDK_PIXBUF_MAGIC_NUMBER; + pixdata->length = GDK_PIXDATA_HEADER_LENGTH + length; + pixdata->pixdata_type = pixbuf->has_alpha ? GDK_PIXDATA_COLOR_TYPE_RGBA : GDK_PIXDATA_COLOR_TYPE_RGB; + pixdata->pixdata_type |= GDK_PIXDATA_SAMPLE_WIDTH_8; + pixdata->pixdata_type |= encoding; + pixdata->rowstride = rowstride; + pixdata->width = pixbuf->width; + pixdata->height = height; + pixdata->pixel_data = img_buffer; + + return free_me; +} + +/** + * gdk_pixbuf_from_pixdata: + * @pixdata: a #GdkPixdata to convert into a #GdkPixbuf. + * @copy_pixels: whether to copy raw pixel data; run-length encoded + * pixel data is always copied. + * @error: location to store possible errors. + * + * Converts a #GdkPixdata to a #GdkPixbuf. If @copy_pixels is %TRUE or + * if the pixel data is run-length-encoded, the pixel data is copied into + * newly-allocated memory; otherwise it is reused. + * + * Returns: (transfer full): a new #GdkPixbuf. + **/ +GdkPixbuf* +gdk_pixbuf_from_pixdata (const GdkPixdata *pixdata, + gboolean copy_pixels, + GError **error) +{ + guint encoding, bpp; + guint8 *data = NULL; + + g_return_val_if_fail (pixdata != NULL, NULL); + g_return_val_if_fail (pixdata->width > 0, NULL); + g_return_val_if_fail (pixdata->height > 0, NULL); + g_return_val_if_fail (pixdata->rowstride >= pixdata->width, NULL); + g_return_val_if_fail ((pixdata->pixdata_type & GDK_PIXDATA_COLOR_TYPE_MASK) == GDK_PIXDATA_COLOR_TYPE_RGB || + (pixdata->pixdata_type & GDK_PIXDATA_COLOR_TYPE_MASK) == GDK_PIXDATA_COLOR_TYPE_RGBA, NULL); + g_return_val_if_fail ((pixdata->pixdata_type & GDK_PIXDATA_SAMPLE_WIDTH_MASK) == GDK_PIXDATA_SAMPLE_WIDTH_8, NULL); + g_return_val_if_fail ((pixdata->pixdata_type & GDK_PIXDATA_ENCODING_MASK) == GDK_PIXDATA_ENCODING_RAW || + (pixdata->pixdata_type & GDK_PIXDATA_ENCODING_MASK) == GDK_PIXDATA_ENCODING_RLE, NULL); + g_return_val_if_fail (pixdata->pixel_data != NULL, NULL); + + bpp = (pixdata->pixdata_type & GDK_PIXDATA_COLOR_TYPE_MASK) == GDK_PIXDATA_COLOR_TYPE_RGB ? 3 : 4; + encoding = pixdata->pixdata_type & GDK_PIXDATA_ENCODING_MASK; + if (encoding == GDK_PIXDATA_ENCODING_RLE) + copy_pixels = TRUE; + if (copy_pixels) + { + data = g_try_malloc_n (pixdata->height, pixdata->rowstride); + if (!data) + { + g_set_error (error, GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY, + g_dngettext(GETTEXT_PACKAGE, + "failed to allocate image buffer of %u byte", + "failed to allocate image buffer of %u bytes", + pixdata->rowstride * pixdata->height), + pixdata->rowstride * pixdata->height); + return NULL; + } + } + if (encoding == GDK_PIXDATA_ENCODING_RLE) + { + const guint8 *rle_buffer = pixdata->pixel_data; + guint8 *image_buffer = data; + guint8 *image_limit = data + pixdata->rowstride * pixdata->height; + gboolean check_overrun = FALSE; + + while (image_buffer < image_limit) + { + guint length = *(rle_buffer++); + + if (length & 128) + { + length = length - 128; + check_overrun = image_buffer + length * bpp > image_limit; + if (check_overrun) + length = (image_limit - image_buffer) / bpp; + if (bpp < 4) /* RGB */ + do + { + memcpy (image_buffer, rle_buffer, 3); + image_buffer += 3; + } + while (--length); + else /* RGBA */ + do + { + memcpy (image_buffer, rle_buffer, 4); + image_buffer += 4; + } + while (--length); + rle_buffer += bpp; + } + else + { + length *= bpp; + check_overrun = image_buffer + length > image_limit; + if (check_overrun) + length = image_limit - image_buffer; + memcpy (image_buffer, rle_buffer, length); + image_buffer += length; + rle_buffer += length; + } + } + if (check_overrun) + { + g_free (data); + g_set_error_literal (error, GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_CORRUPT_IMAGE, + _("Image pixel data corrupt")); + return NULL; + } + } + else if (copy_pixels) + memcpy (data, pixdata->pixel_data, pixdata->rowstride * pixdata->height); + else + data = pixdata->pixel_data; + + return gdk_pixbuf_new_from_data (data, GDK_COLORSPACE_RGB, + (pixdata->pixdata_type & GDK_PIXDATA_COLOR_TYPE_MASK) == GDK_PIXDATA_COLOR_TYPE_RGBA, + 8, pixdata->width, pixdata->height, pixdata->rowstride, + copy_pixels ? (GdkPixbufDestroyNotify) g_free : NULL, data); +} + +typedef struct { + /* config */ + gboolean dump_stream; + gboolean dump_struct; + gboolean dump_macros; + gboolean dump_gtypes; + gboolean dump_rle_decoder; + const gchar *static_prefix; + const gchar *const_prefix; + /* runtime */ + GString *gstring; + guint pos; + gboolean pad; +} CSourceData; + +static inline void +save_uchar (CSourceData *cdata, + guint8 d) +{ + GString *gstring = cdata->gstring; + + if (cdata->pos > 70) + { + if (cdata->dump_struct || cdata->dump_stream) + { + g_string_append (gstring, "\"\n \""); + cdata->pos = 3; + cdata->pad = FALSE; + } + if (cdata->dump_macros) + { + g_string_append (gstring, "\" \\\n \""); + cdata->pos = 3; + cdata->pad = FALSE; + } + } + if (d < 33 || d > 126 || d == '?') + { + APPEND (gstring, "\\%o", d); + cdata->pos += 1 + 1 + (d > 7) + (d > 63); + cdata->pad = d < 64; + return; + } + if (d == '\\') + { + g_string_append (gstring, "\\\\"); + cdata->pos += 2; + } + else if (d == '"') + { + g_string_append (gstring, "\\\""); + cdata->pos += 2; + } + else if (cdata->pad && d >= '0' && d <= '9') + { + g_string_append (gstring, "\"\""); + g_string_append_c (gstring, d); + cdata->pos += 3; + } + else + { + g_string_append_c (gstring, d); + cdata->pos += 1; + } + cdata->pad = FALSE; + return; +} + +static inline void +save_rle_decoder (GString *gstring, + const gchar *macro_name, + const gchar *s_uint, + const gchar *s_uint_8, + guint n_ch) +{ + APPEND (gstring, "#define %s_RUN_LENGTH_DECODE(image_buf, rle_data, size, bpp) do \\\n", + macro_name); + APPEND (gstring, "{ %s __bpp; %s *__ip; const %s *__il, *__rd; \\\n", s_uint, s_uint_8, s_uint_8); + APPEND (gstring, " __bpp = (bpp); __ip = (image_buf); __il = __ip + (size) * __bpp; \\\n"); + + APPEND (gstring, " __rd = (rle_data); if (__bpp > 3) { /* RGBA */ \\\n"); + + APPEND (gstring, " while (__ip < __il) { %s __l = *(__rd++); \\\n", s_uint); + APPEND (gstring, " if (__l & 128) { __l = __l - 128; \\\n"); + APPEND (gstring, " do { memcpy (__ip, __rd, 4); __ip += 4; } while (--__l); __rd += 4; \\\n"); + APPEND (gstring, " } else { __l *= 4; memcpy (__ip, __rd, __l); \\\n"); + APPEND (gstring, " __ip += __l; __rd += __l; } } \\\n"); + + APPEND (gstring, " } else { /* RGB */ \\\n"); + + APPEND (gstring, " while (__ip < __il) { %s __l = *(__rd++); \\\n", s_uint); + APPEND (gstring, " if (__l & 128) { __l = __l - 128; \\\n"); + APPEND (gstring, " do { memcpy (__ip, __rd, 3); __ip += 3; } while (--__l); __rd += 3; \\\n"); + APPEND (gstring, " } else { __l *= 3; memcpy (__ip, __rd, __l); \\\n"); + APPEND (gstring, " __ip += __l; __rd += __l; } } \\\n"); + + APPEND (gstring, " } } while (0)\n"); +} + +/** + * gdk_pixdata_to_csource: + * @pixdata: a #GdkPixdata to convert to C source. + * @name: used for naming generated data structures or macros. + * @dump_type: a #GdkPixdataDumpType determining the kind of C + * source to be generated. + * + * Generates C source code suitable for compiling images directly + * into programs. + * + * gdk-pixbuf ships with a program called + * [gdk-pixbuf-csource][gdk-pixbuf-csource], which offers a command + * line interface to this function. + * + * Returns: a newly-allocated string containing the C source form + * of @pixdata. + **/ +GString* +gdk_pixdata_to_csource (GdkPixdata *pixdata, + const gchar *name, + GdkPixdataDumpType dump_type) +{ + CSourceData cdata = { 0, }; + gchar *s_uint_8; + guint bpp, width, height, rowstride; + gboolean rle_encoded; + gchar *macro_name; + guint8 *img_buffer, *img_buffer_end, *stream = NULL; + guint stream_length; + GString *gstring; + + /* check args passing */ + g_return_val_if_fail (pixdata != NULL, NULL); + g_return_val_if_fail (name != NULL, NULL); + /* check pixdata contents */ + g_return_val_if_fail (pixdata->magic == GDK_PIXBUF_MAGIC_NUMBER, NULL); + g_return_val_if_fail (pixdata->width > 0, NULL); + g_return_val_if_fail (pixdata->height > 0, NULL); + g_return_val_if_fail (pixdata->rowstride >= pixdata->width, NULL); + g_return_val_if_fail ((pixdata->pixdata_type & GDK_PIXDATA_COLOR_TYPE_MASK) == GDK_PIXDATA_COLOR_TYPE_RGB || + (pixdata->pixdata_type & GDK_PIXDATA_COLOR_TYPE_MASK) == GDK_PIXDATA_COLOR_TYPE_RGBA, NULL); + g_return_val_if_fail ((pixdata->pixdata_type & GDK_PIXDATA_SAMPLE_WIDTH_MASK) == GDK_PIXDATA_SAMPLE_WIDTH_8, NULL); + g_return_val_if_fail ((pixdata->pixdata_type & GDK_PIXDATA_ENCODING_MASK) == GDK_PIXDATA_ENCODING_RAW || + (pixdata->pixdata_type & GDK_PIXDATA_ENCODING_MASK) == GDK_PIXDATA_ENCODING_RLE, NULL); + g_return_val_if_fail (pixdata->pixel_data != NULL, NULL); + + img_buffer = pixdata->pixel_data; + if (pixdata->length < 1) + img_buffer_end = img_buffer + pixdata_get_length (pixdata); + else + img_buffer_end = img_buffer + pixdata->length - GDK_PIXDATA_HEADER_LENGTH; + g_return_val_if_fail (img_buffer < img_buffer_end, NULL); + + bpp = (pixdata->pixdata_type & GDK_PIXDATA_COLOR_TYPE_MASK) == GDK_PIXDATA_COLOR_TYPE_RGB ? 3 : 4; + width = pixdata->width; + height = pixdata->height; + rowstride = pixdata->rowstride; + rle_encoded = (pixdata->pixdata_type & GDK_PIXDATA_ENCODING_RLE) > 0; + macro_name = g_ascii_strup (name, -1); + + cdata.dump_macros = (dump_type & GDK_PIXDATA_DUMP_MACROS) > 0; + cdata.dump_struct = (dump_type & GDK_PIXDATA_DUMP_PIXDATA_STRUCT) > 0; + cdata.dump_stream = !cdata.dump_macros && !cdata.dump_struct; + g_return_val_if_fail (cdata.dump_macros + cdata.dump_struct + cdata.dump_stream == 1, NULL); + + cdata.dump_gtypes = (dump_type & GDK_PIXDATA_DUMP_CTYPES) == 0; + cdata.dump_rle_decoder = (dump_type & GDK_PIXDATA_DUMP_RLE_DECODER) > 0; + cdata.static_prefix = (dump_type & GDK_PIXDATA_DUMP_STATIC) ? "static " : ""; + cdata.const_prefix = (dump_type & GDK_PIXDATA_DUMP_CONST) ? "const " : ""; + gstring = g_string_new (NULL); + cdata.gstring = gstring; + + if (!cdata.dump_macros && cdata.dump_gtypes) + s_uint_8 = "guint8 "; + else if (!cdata.dump_macros) + s_uint_8 = "unsigned char"; + else if (cdata.dump_macros && cdata.dump_gtypes) + s_uint_8 = "guint8"; + else /* cdata.dump_macros && !cdata.dump_gtypes */ + s_uint_8 = "unsigned char"; + + /* initial comment + */ + APPEND (gstring, + "/* GdkPixbuf %s C-Source image dump %s*/\n\n", + bpp > 3 ? "RGBA" : "RGB", + rle_encoded ? "1-byte-run-length-encoded " : ""); + + /* dump RLE decoder for structures + */ + if (cdata.dump_rle_decoder && cdata.dump_struct) + save_rle_decoder (gstring, + macro_name, + cdata.dump_gtypes ? "guint" : "unsigned int", + cdata.dump_gtypes ? "guint8" : "unsigned char", + bpp); + + /* format & size blurbs + */ + if (cdata.dump_macros) + { + APPEND (gstring, "#define %s_ROWSTRIDE (%u)\n", + macro_name, rowstride); + APPEND (gstring, "#define %s_WIDTH (%u)\n", + macro_name, width); + APPEND (gstring, "#define %s_HEIGHT (%u)\n", + macro_name, height); + APPEND (gstring, "#define %s_BYTES_PER_PIXEL (%u) /* 3:RGB, 4:RGBA */\n", + macro_name, bpp); + } + if (cdata.dump_struct) + { + APPEND (gstring, "%s%sGdkPixdata %s = {\n", + cdata.static_prefix, cdata.const_prefix, name); + APPEND (gstring, " 0x%x, /* Pixbuf magic: 'GdkP' */\n", + GDK_PIXBUF_MAGIC_NUMBER); + APPEND (gstring, " %d + %lu, /* header length + pixel_data length */\n", + GDK_PIXDATA_HEADER_LENGTH, + rle_encoded ? (glong)(img_buffer_end - img_buffer) : (glong)rowstride * height); + APPEND (gstring, " 0x%x, /* pixdata_type */\n", + pixdata->pixdata_type); + APPEND (gstring, " %u, /* rowstride */\n", + rowstride); + APPEND (gstring, " %u, /* width */\n", + width); + APPEND (gstring, " %u, /* height */\n", + height); + APPEND (gstring, " /* pixel_data: */\n"); + } + if (cdata.dump_stream) + { + guint pix_length = img_buffer_end - img_buffer; + + stream = gdk_pixdata_serialize (pixdata, &stream_length); + img_buffer = stream; + img_buffer_end = stream + stream_length; + + APPEND (gstring, "#ifdef __SUNPRO_C\n"); + APPEND (gstring, "#pragma align 4 (%s)\n", name); + APPEND (gstring, "#endif\n"); + + APPEND (gstring, "#ifdef __GNUC__\n"); + APPEND (gstring, "%s%s%s %s[] __attribute__ ((__aligned__ (4))) = \n", + cdata.static_prefix, cdata.const_prefix, + cdata.dump_gtypes ? "guint8" : "unsigned char", + name); + APPEND (gstring, "#else\n"); + APPEND (gstring, "%s%s%s %s[] = \n", + cdata.static_prefix, cdata.const_prefix, + cdata.dump_gtypes ? "guint8" : "unsigned char", + name); + APPEND (gstring, "#endif\n"); + + APPEND (gstring, "{ \"\"\n /* Pixbuf magic (0x%x) */\n \"", + GDK_PIXBUF_MAGIC_NUMBER); + cdata.pos = 3; + save_uchar (&cdata, *img_buffer++); save_uchar (&cdata, *img_buffer++); + save_uchar (&cdata, *img_buffer++); save_uchar (&cdata, *img_buffer++); + APPEND (gstring, "\"\n /* length: header (%d) + pixel_data (%u) */\n \"", + GDK_PIXDATA_HEADER_LENGTH, + rle_encoded ? pix_length : rowstride * height); + cdata.pos = 3; + save_uchar (&cdata, *img_buffer++); save_uchar (&cdata, *img_buffer++); + save_uchar (&cdata, *img_buffer++); save_uchar (&cdata, *img_buffer++); + APPEND (gstring, "\"\n /* pixdata_type (0x%x) */\n \"", + pixdata->pixdata_type); + cdata.pos = 3; + save_uchar (&cdata, *img_buffer++); save_uchar (&cdata, *img_buffer++); + save_uchar (&cdata, *img_buffer++); save_uchar (&cdata, *img_buffer++); + APPEND (gstring, "\"\n /* rowstride (%u) */\n \"", + rowstride); + cdata.pos = 3; + save_uchar (&cdata, *img_buffer++); save_uchar (&cdata, *img_buffer++); + save_uchar (&cdata, *img_buffer++); save_uchar (&cdata, *img_buffer++); + APPEND (gstring, "\"\n /* width (%u) */\n \"", width); + cdata.pos = 3; + save_uchar (&cdata, *img_buffer++); save_uchar (&cdata, *img_buffer++); + save_uchar (&cdata, *img_buffer++); save_uchar (&cdata, *img_buffer++); + APPEND (gstring, "\"\n /* height (%u) */\n \"", height); + cdata.pos = 3; + save_uchar (&cdata, *img_buffer++); save_uchar (&cdata, *img_buffer++); + save_uchar (&cdata, *img_buffer++); save_uchar (&cdata, *img_buffer++); + APPEND (gstring, "\"\n /* pixel_data: */\n"); + } + + /* pixel_data intro + */ + if (cdata.dump_macros) + { + APPEND (gstring, "#define %s_%sPIXEL_DATA ((%s*) \\\n", + macro_name, + rle_encoded ? "RLE_" : "", + s_uint_8); + APPEND (gstring, " \""); + cdata.pos = 2; + } + if (cdata.dump_struct) + { + APPEND (gstring, " \""); + cdata.pos = 3; + } + if (cdata.dump_stream) + { + APPEND (gstring, " \""); + cdata.pos = 3; + } + + /* pixel_data + */ + do + save_uchar (&cdata, *img_buffer++); + while (img_buffer < img_buffer_end); + + /* pixel_data trailer + */ + if (cdata.dump_macros) + APPEND (gstring, "\")\n\n"); + if (cdata.dump_struct) + APPEND (gstring, "\",\n};\n\n"); + if (cdata.dump_stream) + APPEND (gstring, "\"};\n\n"); + + /* dump RLE decoder for macros + */ + if (cdata.dump_rle_decoder && cdata.dump_macros) + save_rle_decoder (gstring, + macro_name, + cdata.dump_gtypes ? "guint" : "unsigned int", + cdata.dump_gtypes ? "guint8" : "unsigned char", + bpp); + + /* cleanup + */ + g_free (stream); + g_free (macro_name); + + return gstring; +} + +/** + * gdk_pixbuf_new_from_inline: + * @data_length: Length in bytes of the @data argument or -1 to + * disable length checks + * @data: (array length=data_length): Byte data containing a + * serialized #GdkPixdata structure + * @copy_pixels: Whether to copy the pixel data, or use direct pointers + * @data for the resulting pixbuf + * @error: #GError return location, may be %NULL to ignore errors + * + * Create a #GdkPixbuf from a flat representation that is suitable for + * storing as inline data in a program. This is useful if you want to + * ship a program with images, but don't want to depend on any + * external files. + * + * gdk-pixbuf ships with a program called [gdk-pixbuf-csource][gdk-pixbuf-csource], + * which allows for conversion of #GdkPixbufs into such a inline representation. + * In almost all cases, you should pass the `--raw` option to + * `gdk-pixbuf-csource`. A sample invocation would be: + * + * |[ + * gdk-pixbuf-csource --raw --name=myimage_inline myimage.png + * ]| + * + * For the typical case where the inline pixbuf is read-only static data, + * you don't need to copy the pixel data unless you intend to write to + * it, so you can pass %FALSE for @copy_pixels. (If you pass `--rle` to + * `gdk-pixbuf-csource`, a copy will be made even if @copy_pixels is %FALSE, + * so using this option is generally a bad idea.) + * + * If you create a pixbuf from const inline data compiled into your + * program, it's probably safe to ignore errors and disable length checks, + * since things will always succeed: + * |[ + * pixbuf = gdk_pixbuf_new_from_inline (-1, myimage_inline, FALSE, NULL); + * ]| + * + * For non-const inline data, you could get out of memory. For untrusted + * inline data located at runtime, you could have corrupt inline data in + * addition. + * + * Return value: A newly-created #GdkPixbuf structure with a reference, + * count of 1, or %NULL if an error occurred. + **/ +GdkPixbuf* +gdk_pixbuf_new_from_inline (gint data_length, + const guint8 *data, + gboolean copy_pixels, + GError **error) +{ + GdkPixdata pixdata; + + if (data_length != -1) + g_return_val_if_fail (data_length > GDK_PIXDATA_HEADER_LENGTH, NULL); + g_return_val_if_fail (data != NULL, NULL); + + if (!gdk_pixdata_deserialize (&pixdata, data_length, data, error)) + return NULL; + + return gdk_pixbuf_from_pixdata (&pixdata, copy_pixels, error); +} diff --git a/libs/tk/ydk-pixbuf/io-pixdata.c b/libs/tk/ydk-pixbuf/io-pixdata.c new file mode 100644 index 0000000000..5822c5c669 --- /dev/null +++ b/libs/tk/ydk-pixbuf/io-pixdata.c @@ -0,0 +1,190 @@ +/* GdkPixdata loader + * + * Copyright (c) 2012 Alexander Larsson + * + * 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, see . + */ + +#include "config.h" +#include "gdk-pixbuf-private.h" +#include "gdk-pixdata.h" + +G_MODULE_EXPORT void fill_vtable (GdkPixbufModule * module); +G_MODULE_EXPORT void fill_info (GdkPixbufFormat * info); + +struct pixdata_context { + GdkPixbufModuleSizeFunc size_func; + GdkPixbufModuleUpdatedFunc updated_func; + GdkPixbufModulePreparedFunc prepared_func; + gpointer user_data; + + GString *data; + + GdkPixdata pixdata; + gboolean got_header; + gboolean got_pixbuf; +}; + +static void +free_pixdata_context (struct pixdata_context *context) +{ + if (!context) + return; + + g_free (context); +} + +static gpointer +pixdata_image_begin_load (GdkPixbufModuleSizeFunc size_func, + GdkPixbufModulePreparedFunc prepared_func, + GdkPixbufModuleUpdatedFunc updated_func, + gpointer user_data, GError **error) +{ + struct pixdata_context *context; + + context = g_new0 (struct pixdata_context, 1); + if (!context) + return NULL; + + context->size_func = size_func; + context->updated_func = updated_func; + context->prepared_func = prepared_func; + context->user_data = user_data; + + context->data = g_string_new (""); + + return context; +} + +static gboolean try_load (struct pixdata_context *context, GError **error) +{ + GdkPixbuf *pixbuf; + + if (context->got_pixbuf) + return TRUE; + + if (!gdk_pixdata_deserialize (&context->pixdata, + context->data->len, + (guchar *)context->data->str, + error)) + return FALSE; + + pixbuf = gdk_pixbuf_from_pixdata (&context->pixdata, + TRUE, error); + if (pixbuf == NULL) + return FALSE; + + context->got_pixbuf = TRUE; + + if (context->prepared_func) + (* context->prepared_func) (pixbuf, + NULL, + context->user_data); + if (context->updated_func) + (* context->updated_func) (pixbuf, 0, 0, pixbuf->width, pixbuf->height, context->user_data); + + return TRUE; +} + +static gboolean +pixdata_image_stop_load (gpointer data, GError **error) +{ + struct pixdata_context *context = (struct pixdata_context *) data; + gboolean res; + + res = try_load (context, error); + + g_string_free (context->data, TRUE); + + free_pixdata_context (context); + + return res; +} + +static gboolean +pixdata_image_load_increment (gpointer data, const guchar *buf, guint size, GError **error) +{ + struct pixdata_context *context = (struct pixdata_context *) data; + + g_string_append_len (context->data, (char *)buf, size); + + if (!context->got_header && context->data->len >= GDK_PIXDATA_HEADER_LENGTH) + { + /* This never reads past the header anyway, and we know we have at least + the header size, so we pass it a really large size to avoid any error reporting + due to missing data */ + if (!gdk_pixdata_deserialize (&context->pixdata, + G_MAXUINT, + (guchar *)context->data->str, + error)) + return FALSE; + + context->got_header = TRUE; + + if (context->size_func) + { + gint w = context->pixdata.width; + gint h = context->pixdata.height; + (* context->size_func) (&w, &h, context->user_data); + + if (w == 0 || h == 0) + { + g_set_error_literal (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_FAILED, + _("Transformed pixbuf has zero width or height.")); + return FALSE; + } + } + } + + try_load (context, NULL); + + return TRUE; +} + +/* Always included */ +#define MODULE_ENTRY(function) void _gdk_pixbuf__pixdata_ ## function + +MODULE_ENTRY (fill_vtable) (GdkPixbufModule * module) +{ + module->begin_load = pixdata_image_begin_load; + module->stop_load = pixdata_image_stop_load; + module->load_increment = pixdata_image_load_increment; +} + +MODULE_ENTRY (fill_info) (GdkPixbufFormat * info) +{ + static const GdkPixbufModulePattern signature[] = { + { "GdkP", NULL, 100 }, /* file begins with 'GdkP' at offset 0 */ + { NULL, NULL, 0 } + }; + static const gchar *mime_types[] = { + "image/x-gdkpixdata", + NULL + }; + static const gchar *extensions[] = { + "gdkp", + NULL + }; + + info->name = "GdkPixdata"; + info->signature = (GdkPixbufModulePattern *) signature; + info->description = N_("The GdkPixdata format"); + info->mime_types = (gchar **) mime_types; + info->extensions = (gchar **) extensions; + info->flags = GDK_PIXBUF_FORMAT_THREADSAFE; + info->license = "LGPL"; + info->disabled = FALSE; +} diff --git a/libs/tk/ydk-pixbuf/io-png.c b/libs/tk/ydk-pixbuf/io-png.c new file mode 100644 index 0000000000..83e46ff50e --- /dev/null +++ b/libs/tk/ydk-pixbuf/io-png.c @@ -0,0 +1,1122 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ +/* GdkPixbuf library - PNG image loader + * + * Copyright (C) 1999 Mark Crichton + * Copyright (C) 1999 The Free Software Foundation + * + * Authors: Mark Crichton + * Federico Mena-Quintero + * + * 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, see . + */ + +#include "config.h" +#include +#include +#include +#include +#include "gdk-pixbuf-private.h" + + + +static gboolean +setup_png_transformations(png_structp png_read_ptr, png_infop png_info_ptr, + GError **error, + png_uint_32* width_p, png_uint_32* height_p, + int* color_type_p) +{ + png_uint_32 width, height; + int bit_depth, color_type, interlace_type, compression_type, filter_type; + int channels; + + /* Get the image info */ + + /* Must check bit depth, since png_get_IHDR generates an + FPE on bit_depth 0. + */ + bit_depth = png_get_bit_depth (png_read_ptr, png_info_ptr); + if (bit_depth < 1 || bit_depth > 16) { + g_set_error_literal (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_CORRUPT_IMAGE, + _("Bits per channel of PNG image is invalid.")); + return FALSE; + } + png_get_IHDR (png_read_ptr, png_info_ptr, + &width, &height, + &bit_depth, + &color_type, + &interlace_type, + &compression_type, + &filter_type); + + /* set_expand() basically needs to be called unless + we are already in RGB/RGBA mode + */ + if (color_type == PNG_COLOR_TYPE_PALETTE && + bit_depth <= 8) { + + /* Convert indexed images to RGB */ + png_set_expand (png_read_ptr); + + } else if (color_type == PNG_COLOR_TYPE_GRAY && + bit_depth < 8) { + + /* Convert grayscale to RGB */ + png_set_expand (png_read_ptr); + + } else if (png_get_valid (png_read_ptr, + png_info_ptr, PNG_INFO_tRNS)) { + + /* If we have transparency header, convert it to alpha + channel */ + png_set_expand(png_read_ptr); + + } else if (bit_depth < 8) { + + /* If we have < 8 scale it up to 8 */ + png_set_expand(png_read_ptr); + + + /* Conceivably, png_set_packing() is a better idea; + * God only knows how libpng works + */ + } + + /* If we are 16-bit, convert to 8-bit */ + if (bit_depth == 16) { + png_set_strip_16(png_read_ptr); + } + + /* If gray scale, convert to RGB */ + if (color_type == PNG_COLOR_TYPE_GRAY || + color_type == PNG_COLOR_TYPE_GRAY_ALPHA) { + png_set_gray_to_rgb(png_read_ptr); + } + + /* If interlaced, handle that */ + if (interlace_type != PNG_INTERLACE_NONE) { + png_set_interlace_handling(png_read_ptr); + } + + /* Update the info the reflect our transformations */ + png_read_update_info(png_read_ptr, png_info_ptr); + + png_get_IHDR (png_read_ptr, png_info_ptr, + &width, &height, + &bit_depth, + &color_type, + &interlace_type, + &compression_type, + &filter_type); + + *width_p = width; + *height_p = height; + *color_type_p = color_type; + + /* Check that the new info is what we want */ + + if (width == 0 || height == 0) { + g_set_error_literal (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_CORRUPT_IMAGE, + _("Transformed PNG has zero width or height.")); + return FALSE; + } + + if (bit_depth != 8) { + g_set_error_literal (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_CORRUPT_IMAGE, + _("Bits per channel of transformed PNG is not 8.")); + return FALSE; + } + + if ( ! (color_type == PNG_COLOR_TYPE_RGB || + color_type == PNG_COLOR_TYPE_RGB_ALPHA) ) { + g_set_error_literal (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_CORRUPT_IMAGE, + _("Transformed PNG not RGB or RGBA.")); + return FALSE; + } + + channels = png_get_channels(png_read_ptr, png_info_ptr); + if ( ! (channels == 3 || channels == 4) ) { + g_set_error_literal (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_CORRUPT_IMAGE, + _("Transformed PNG has unsupported number of channels, must be 3 or 4.")); + return FALSE; + } + return TRUE; +} + +static void +png_simple_error_callback(png_structp png_save_ptr, + png_const_charp error_msg) +{ + GError **error; + + error = png_get_error_ptr(png_save_ptr); + + /* I don't trust libpng to call the error callback only once, + * so check for already-set error + */ + if (error && *error == NULL) { + g_set_error (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_FAILED, + _("Fatal error in PNG image file: %s"), + error_msg); + } + + longjmp (png_jmpbuf(png_save_ptr), 1); +} + +static void +png_simple_warning_callback(png_structp png_save_ptr, + png_const_charp warning_msg) +{ + /* Don't print anything; we should not be dumping junk to + * stderr, since that may be bad for some apps. If it's + * important enough to display, we need to add a GError + * **warning return location wherever we have an error return + * location. + */ +} + +static gboolean +png_text_to_pixbuf_option (png_text text_ptr, + gchar **key, + gchar **value) +{ + gboolean is_ascii = TRUE; + int i; + + /* Avoid loading iconv if the text is plain ASCII */ + for (i = 0; i < text_ptr.text_length; i++) + if (text_ptr.text[i] & 0x80) { + is_ascii = FALSE; + break; + } + + if (is_ascii) { + *value = g_strdup (text_ptr.text); + } else { + *value = g_convert (text_ptr.text, -1, + "UTF-8", "ISO-8859-1", + NULL, NULL, NULL); + } + + if (*value) { + *key = g_strconcat ("tEXt::", text_ptr.key, NULL); + return TRUE; + } else { + g_warning ("Couldn't convert text chunk value to UTF-8."); + *key = NULL; + return FALSE; + } +} + +static png_voidp +png_malloc_callback (png_structp o, png_size_t size) +{ + return g_try_malloc (size); +} + +static void +png_free_callback (png_structp o, png_voidp x) +{ + g_free (x); +} + +/* Shared library entry point */ +static GdkPixbuf * +gdk_pixbuf__png_image_load (FILE *f, GError **error) +{ + GdkPixbuf * volatile pixbuf = NULL; + png_structp png_ptr; + png_infop info_ptr; + png_textp text_ptr; + gint i, ctype; + png_uint_32 w, h; + png_bytepp volatile rows = NULL; + gint num_texts; + gchar *key; + gchar *value; + gchar *icc_profile_base64; + const gchar *icc_profile_title; + const gchar *icc_profile; + png_uint_32 icc_profile_size; + guint32 retval; + gint compression_type; + +#ifdef PNG_USER_MEM_SUPPORTED + png_ptr = png_create_read_struct_2 (PNG_LIBPNG_VER_STRING, + error, + png_simple_error_callback, + png_simple_warning_callback, + NULL, + png_malloc_callback, + png_free_callback); +#else + png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, + error, + png_simple_error_callback, + png_simple_warning_callback); +#endif + if (!png_ptr) + return NULL; + + info_ptr = png_create_info_struct (png_ptr); + if (!info_ptr) { + png_destroy_read_struct (&png_ptr, NULL, NULL); + return NULL; + } + + if (setjmp (png_jmpbuf(png_ptr))) { + g_free (rows); + + if (pixbuf) + g_object_unref (pixbuf); + + png_destroy_read_struct (&png_ptr, &info_ptr, NULL); + return NULL; + } + + png_init_io (png_ptr, f); + png_read_info (png_ptr, info_ptr); + + if (!setup_png_transformations(png_ptr, info_ptr, error, &w, &h, &ctype)) { + png_destroy_read_struct (&png_ptr, &info_ptr, NULL); + return NULL; + } + + pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, ctype & PNG_COLOR_MASK_ALPHA, 8, w, h); + + if (!pixbuf) { + if (error && *error == NULL) { + g_set_error_literal (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY, + _("Insufficient memory to load PNG file")); + } + + + png_destroy_read_struct (&png_ptr, &info_ptr, NULL); + return NULL; + } + + rows = g_new (png_bytep, h); + + for (i = 0; i < h; i++) + rows[i] = pixbuf->pixels + i * pixbuf->rowstride; + + png_read_image (png_ptr, rows); + png_read_end (png_ptr, info_ptr); + + if (png_get_text (png_ptr, info_ptr, &text_ptr, &num_texts)) { + for (i = 0; i < num_texts; i++) { + png_text_to_pixbuf_option (text_ptr[i], &key, &value); + gdk_pixbuf_set_option (pixbuf, key, value); + g_free (key); + g_free (value); + } + } + +#if defined(PNG_cHRM_SUPPORTED) + /* Extract embedded ICC profile */ + retval = png_get_iCCP (png_ptr, info_ptr, + (png_charpp) &icc_profile_title, &compression_type, + (png_bytepp) &icc_profile, (png_uint_32*) &icc_profile_size); + if (retval != 0) { + icc_profile_base64 = g_base64_encode ((const guchar *) icc_profile, (gsize)icc_profile_size); + gdk_pixbuf_set_option (pixbuf, "icc-profile", icc_profile_base64); + g_free (icc_profile_base64); + } +#endif + + g_free (rows); + png_destroy_read_struct (&png_ptr, &info_ptr, NULL); + + return pixbuf; +} + +/* I wish these avoided the setjmp()/longjmp() crap in libpng instead + just allow you to change the error reporting. */ +static void png_error_callback (png_structp png_read_ptr, + png_const_charp error_msg); + +static void png_warning_callback (png_structp png_read_ptr, + png_const_charp warning_msg); + +/* Called at the start of the progressive load */ +static void png_info_callback (png_structp png_read_ptr, + png_infop png_info_ptr); + +/* Called for each row; note that you will get duplicate row numbers + for interlaced PNGs */ +static void png_row_callback (png_structp png_read_ptr, + png_bytep new_row, + png_uint_32 row_num, + int pass_num); + +/* Called after reading the entire image */ +static void png_end_callback (png_structp png_read_ptr, + png_infop png_info_ptr); + +typedef struct _LoadContext LoadContext; + +struct _LoadContext { + png_structp png_read_ptr; + png_infop png_info_ptr; + + GdkPixbufModuleSizeFunc size_func; + GdkPixbufModulePreparedFunc prepare_func; + GdkPixbufModuleUpdatedFunc update_func; + gpointer notify_user_data; + + GdkPixbuf* pixbuf; + + /* row number of first row seen, or -1 if none yet seen */ + + gint first_row_seen_in_chunk; + + /* pass number for the first row seen */ + + gint first_pass_seen_in_chunk; + + /* row number of last row seen */ + gint last_row_seen_in_chunk; + + gint last_pass_seen_in_chunk; + + /* highest row number seen */ + gint max_row_seen_in_chunk; + + guint fatal_error_occurred : 1; + + GError **error; +}; + +static gpointer +gdk_pixbuf__png_image_begin_load (GdkPixbufModuleSizeFunc size_func, + GdkPixbufModulePreparedFunc prepare_func, + GdkPixbufModuleUpdatedFunc update_func, + gpointer user_data, + GError **error) +{ + LoadContext* lc; + + lc = g_new0(LoadContext, 1); + + lc->fatal_error_occurred = FALSE; + + lc->size_func = size_func; + lc->prepare_func = prepare_func; + lc->update_func = update_func; + lc->notify_user_data = user_data; + + lc->first_row_seen_in_chunk = -1; + lc->last_row_seen_in_chunk = -1; + lc->first_pass_seen_in_chunk = -1; + lc->last_pass_seen_in_chunk = -1; + lc->max_row_seen_in_chunk = -1; + lc->error = error; + + /* Create the main PNG context struct */ + +#ifdef PNG_USER_MEM_SUPPORTED + lc->png_read_ptr = png_create_read_struct_2 (PNG_LIBPNG_VER_STRING, + lc, /* error/warning callback data */ + png_error_callback, + png_warning_callback, + NULL, + png_malloc_callback, + png_free_callback); +#else + lc->png_read_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, + lc, /* error/warning callback data */ + png_error_callback, + png_warning_callback); +#endif + if (lc->png_read_ptr == NULL) { + g_free(lc); + /* error callback should have set the error */ + return NULL; + } + + if (setjmp (png_jmpbuf(lc->png_read_ptr))) { + if (lc->png_info_ptr) + png_destroy_read_struct(&lc->png_read_ptr, NULL, NULL); + g_free(lc); + /* error callback should have set the error */ + return NULL; + } + + /* Create the auxiliary context struct */ + + lc->png_info_ptr = png_create_info_struct(lc->png_read_ptr); + + if (lc->png_info_ptr == NULL) { + png_destroy_read_struct(&lc->png_read_ptr, NULL, NULL); + g_free(lc); + /* error callback should have set the error */ + return NULL; + } + + png_set_progressive_read_fn(lc->png_read_ptr, + lc, /* callback data */ + png_info_callback, + png_row_callback, + png_end_callback); + + + /* We don't want to keep modifying error after returning here, + * it may no longer be valid. + */ + lc->error = NULL; + + return lc; +} + +static gboolean +gdk_pixbuf__png_image_stop_load (gpointer context, GError **error) +{ + LoadContext* lc = context; + + g_return_val_if_fail(lc != NULL, TRUE); + + /* FIXME this thing needs to report errors if + * we have unused image data + */ + + if (lc->pixbuf) + g_object_unref (lc->pixbuf); + + png_destroy_read_struct(&lc->png_read_ptr, &lc->png_info_ptr, NULL); + g_free(lc); + + return TRUE; +} + +static gboolean +gdk_pixbuf__png_image_load_increment(gpointer context, + const guchar *buf, guint size, + GError **error) +{ + LoadContext* lc = context; + + g_return_val_if_fail(lc != NULL, FALSE); + + /* reset */ + lc->first_row_seen_in_chunk = -1; + lc->last_row_seen_in_chunk = -1; + lc->first_pass_seen_in_chunk = -1; + lc->last_pass_seen_in_chunk = -1; + lc->max_row_seen_in_chunk = -1; + lc->error = error; + + /* Invokes our callbacks as needed */ + if (setjmp (png_jmpbuf(lc->png_read_ptr))) { + lc->error = NULL; + return FALSE; + } else { + png_process_data(lc->png_read_ptr, lc->png_info_ptr, + (guchar*) buf, size); + } + + if (lc->fatal_error_occurred) { + lc->error = NULL; + return FALSE; + } else { + if (lc->first_row_seen_in_chunk >= 0 && lc->update_func) { + /* We saw at least one row */ + gint pass_diff = lc->last_pass_seen_in_chunk - lc->first_pass_seen_in_chunk; + + g_assert(pass_diff >= 0); + + if (pass_diff == 0) { + /* start and end row were in the same pass */ + (lc->update_func)(lc->pixbuf, 0, + lc->first_row_seen_in_chunk, + lc->pixbuf->width, + (lc->last_row_seen_in_chunk - + lc->first_row_seen_in_chunk) + 1, + lc->notify_user_data); + } else if (pass_diff == 1) { + /* We have from the first row seen to + the end of the image (max row + seen), then from the top of the + image to the last row seen */ + /* first row to end */ + (lc->update_func)(lc->pixbuf, 0, + lc->first_row_seen_in_chunk, + lc->pixbuf->width, + (lc->max_row_seen_in_chunk - + lc->first_row_seen_in_chunk) + 1, + lc->notify_user_data); + /* top to last row */ + (lc->update_func)(lc->pixbuf, + 0, 0, + lc->pixbuf->width, + lc->last_row_seen_in_chunk + 1, + lc->notify_user_data); + } else { + /* We made at least one entire pass, so update the + whole image */ + (lc->update_func)(lc->pixbuf, + 0, 0, + lc->pixbuf->width, + lc->max_row_seen_in_chunk + 1, + lc->notify_user_data); + } + } + + lc->error = NULL; + + return TRUE; + } +} + +/* Called at the start of the progressive load, once we have image info */ +static void +png_info_callback (png_structp png_read_ptr, + png_infop png_info_ptr) +{ + LoadContext* lc; + png_uint_32 width, height; + png_textp png_text_ptr; + int i, num_texts; + int color_type; + gboolean have_alpha = FALSE; + gchar *icc_profile_base64; + const gchar *icc_profile_title; + const gchar *icc_profile; + png_uint_32 icc_profile_size; + guint32 retval; + gint compression_type; + + lc = png_get_progressive_ptr(png_read_ptr); + + if (lc->fatal_error_occurred) + return; + + if (!setup_png_transformations(lc->png_read_ptr, + lc->png_info_ptr, + lc->error, + &width, &height, &color_type)) { + lc->fatal_error_occurred = TRUE; + return; + } + + /* If we have alpha, set a flag */ + if (color_type & PNG_COLOR_MASK_ALPHA) + have_alpha = TRUE; + + if (lc->size_func) { + gint w = width; + gint h = height; + (* lc->size_func) (&w, &h, lc->notify_user_data); + + if (w == 0 || h == 0) { + lc->fatal_error_occurred = TRUE; + if (lc->error && *lc->error == NULL) { + g_set_error_literal (lc->error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_FAILED, + _("Transformed PNG has zero width or height.")); + } + return; + } + } + + lc->pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, have_alpha, 8, width, height); + + if (lc->pixbuf == NULL) { + /* Failed to allocate memory */ + lc->fatal_error_occurred = TRUE; + if (lc->error && *lc->error == NULL) { + g_set_error (lc->error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY, + _("Insufficient memory to store a %lu by %lu image; try exiting some applications to reduce memory usage"), + (gulong) width, (gulong) height); + } + return; + } + + /* Extract text chunks and attach them as pixbuf options */ + + if (png_get_text (png_read_ptr, png_info_ptr, &png_text_ptr, &num_texts)) { + for (i = 0; i < num_texts; i++) { + gchar *key, *value; + + if (png_text_to_pixbuf_option (png_text_ptr[i], + &key, &value)) { + gdk_pixbuf_set_option (lc->pixbuf, key, value); + g_free (key); + g_free (value); + } + } + } + +#if defined(PNG_cHRM_SUPPORTED) + /* Extract embedded ICC profile */ + retval = png_get_iCCP (png_read_ptr, png_info_ptr, + (png_charpp) &icc_profile_title, &compression_type, + (png_bytepp) &icc_profile, &icc_profile_size); + if (retval != 0) { + icc_profile_base64 = g_base64_encode ((const guchar *) icc_profile, (gsize)icc_profile_size); + gdk_pixbuf_set_option (lc->pixbuf, "icc-profile", icc_profile_base64); + g_free (icc_profile_base64); + } +#endif + + /* Notify the client that we are ready to go */ + + if (lc->prepare_func) + (* lc->prepare_func) (lc->pixbuf, NULL, lc->notify_user_data); + + return; +} + +/* Called for each row; note that you will get duplicate row numbers + for interlaced PNGs */ +static void +png_row_callback (png_structp png_read_ptr, + png_bytep new_row, + png_uint_32 row_num, + int pass_num) +{ + LoadContext* lc; + guchar* old_row = NULL; + + lc = png_get_progressive_ptr(png_read_ptr); + + if (lc->fatal_error_occurred) + return; + + if (row_num >= lc->pixbuf->height) { + lc->fatal_error_occurred = TRUE; + if (lc->error && *lc->error == NULL) { + g_set_error_literal (lc->error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_CORRUPT_IMAGE, + _("Fatal error reading PNG image file")); + } + return; + } + + if (lc->first_row_seen_in_chunk < 0) { + lc->first_row_seen_in_chunk = row_num; + lc->first_pass_seen_in_chunk = pass_num; + } + + lc->max_row_seen_in_chunk = MAX(lc->max_row_seen_in_chunk, ((gint)row_num)); + lc->last_row_seen_in_chunk = row_num; + lc->last_pass_seen_in_chunk = pass_num; + + old_row = lc->pixbuf->pixels + (row_num * lc->pixbuf->rowstride); + + png_progressive_combine_row(lc->png_read_ptr, old_row, new_row); +} + +/* Called after reading the entire image */ +static void +png_end_callback (png_structp png_read_ptr, + png_infop png_info_ptr) +{ + LoadContext* lc; + + lc = png_get_progressive_ptr(png_read_ptr); + + if (lc->fatal_error_occurred) + return; +} + +static void +png_error_callback(png_structp png_read_ptr, + png_const_charp error_msg) +{ + LoadContext* lc; + + lc = png_get_error_ptr(png_read_ptr); + + lc->fatal_error_occurred = TRUE; + + /* I don't trust libpng to call the error callback only once, + * so check for already-set error + */ + if (lc->error && *lc->error == NULL) { + g_set_error (lc->error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_CORRUPT_IMAGE, + _("Fatal error reading PNG image file: %s"), + error_msg); + } + + longjmp (png_jmpbuf(png_read_ptr), 1); +} + +static void +png_warning_callback (png_structp png_read_ptr, + png_const_charp warning_msg) +{ + /* Don't print anything; we should not be dumping junk to + * stderr, since that may be bad for some apps. If it's + * important enough to display, we need to add a GError + * **warning return location wherever we have an error return + * location. + */ +} + + +/* Save */ + +typedef struct { + GdkPixbufSaveFunc save_func; + gpointer user_data; + GError **error; +} SaveToFunctionIoPtr; + +static void +png_save_to_callback_write_func (png_structp png_ptr, + png_bytep data, + png_size_t length) +{ + SaveToFunctionIoPtr *ioptr = png_get_io_ptr (png_ptr); + + if (!ioptr->save_func ((gchar *)data, length, ioptr->error, ioptr->user_data)) { + /* If save_func has already set an error, which it + should have done, this won't overwrite it. */ + png_error (png_ptr, "write function failed"); + } +} + +static void +png_save_to_callback_flush_func (png_structp png_ptr) +{ + ; +} + +static gboolean real_save_png (GdkPixbuf *pixbuf, + gchar **keys, + gchar **values, + GError **error, + gboolean to_callback, + FILE *f, + GdkPixbufSaveFunc save_func, + gpointer user_data) +{ + png_structp png_ptr = NULL; + png_infop info_ptr; + png_textp text_ptr = NULL; + guchar *ptr; + guchar *pixels; + int y; + int i; + png_bytep row_ptr; + png_color_8 sig_bit; + int w, h, rowstride; + int has_alpha; + int bpc; + int num_keys; + int compression = -1; + gboolean success = TRUE; + guchar *icc_profile = NULL; + gsize icc_profile_size = 0; + SaveToFunctionIoPtr to_callback_ioptr; + + num_keys = 0; + + if (keys && *keys) { + gchar **kiter = keys; + gchar **viter = values; + + while (*kiter) { + if (strncmp (*kiter, "tEXt::", 6) == 0) { + gchar *key = *kiter + 6; + int len = strlen (key); + if (len < 1 || len > 79) { + g_set_error_literal (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_BAD_OPTION, + _("Keys for PNG text chunks must have at least 1 and at most 79 characters.")); + success = FALSE; + goto cleanup; + } + for (i = 0; i < len; i++) { + if ((guchar) key[i] > 127) { + g_set_error_literal (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_BAD_OPTION, + _("Keys for PNG text chunks must be ASCII characters.")); + success = FALSE; + goto cleanup; + } + } + num_keys++; + } else if (strcmp (*kiter, "icc-profile") == 0) { + /* decode from base64 */ + icc_profile = g_base64_decode (*viter, &icc_profile_size); + if (icc_profile_size < 127) { + /* This is a user-visible error */ + g_set_error (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_BAD_OPTION, + _("Color profile has invalid length %d."), + (gint)icc_profile_size); + success = FALSE; + goto cleanup; + } + } else if (strcmp (*kiter, "compression") == 0) { + char *endptr = NULL; + compression = strtol (*viter, &endptr, 10); + + if (endptr == *viter) { + g_set_error (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_BAD_OPTION, + _("PNG compression level must be a value between 0 and 9; value '%s' could not be parsed."), + *viter); + success = FALSE; + goto cleanup; + } + if (compression < 0 || compression > 9) { + /* This is a user-visible error; + * lets people skip the range-checking + * in their app. + */ + g_set_error (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_BAD_OPTION, + _("PNG compression level must be a value between 0 and 9; value '%d' is not allowed."), + compression); + success = FALSE; + goto cleanup; + } + } else { + g_warning ("Unrecognized parameter (%s) passed to PNG saver.", *kiter); + } + + ++kiter; + ++viter; + } + } + + if (num_keys > 0) { + gchar **kiter = keys; + gchar **viter = values; + + text_ptr = g_new0 (png_text, num_keys); + for (i = 0; i < num_keys; i++) { + if (strncmp (*kiter, "tEXt::", 6) != 0) { + kiter++; + viter++; + } + + text_ptr[i].compression = PNG_TEXT_COMPRESSION_NONE; + text_ptr[i].key = *kiter + 6; + text_ptr[i].text = g_convert (*viter, -1, + "ISO-8859-1", "UTF-8", + NULL, &text_ptr[i].text_length, + NULL); + +#ifdef PNG_iTXt_SUPPORTED + if (!text_ptr[i].text) { + text_ptr[i].compression = PNG_ITXT_COMPRESSION_NONE; + text_ptr[i].text = g_strdup (*viter); + text_ptr[i].text_length = 0; + text_ptr[i].itxt_length = strlen (text_ptr[i].text); + text_ptr[i].lang = NULL; + text_ptr[i].lang_key = NULL; + } +#endif + + if (!text_ptr[i].text) { + gint j; + g_set_error (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_BAD_OPTION, + _("Value for PNG text chunk %s cannot be converted to ISO-8859-1 encoding."), *kiter + 6); + for (j = 0; j < i; j++) + g_free (text_ptr[j].text); + g_free (text_ptr); + return FALSE; + } + + kiter++; + viter++; + } + } + + bpc = gdk_pixbuf_get_bits_per_sample (pixbuf); + w = gdk_pixbuf_get_width (pixbuf); + h = gdk_pixbuf_get_height (pixbuf); + rowstride = gdk_pixbuf_get_rowstride (pixbuf); + has_alpha = gdk_pixbuf_get_has_alpha (pixbuf); + pixels = gdk_pixbuf_get_pixels (pixbuf); + + png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, + error, + png_simple_error_callback, + png_simple_warning_callback); + if (png_ptr == NULL) { + success = FALSE; + goto cleanup; + } + + info_ptr = png_create_info_struct (png_ptr); + if (info_ptr == NULL) { + success = FALSE; + goto cleanup; + } + if (setjmp (png_jmpbuf(png_ptr))) { + success = FALSE; + goto cleanup; + } + + if (num_keys > 0) { + png_set_text (png_ptr, info_ptr, text_ptr, num_keys); + } + + if (to_callback) { + to_callback_ioptr.save_func = save_func; + to_callback_ioptr.user_data = user_data; + to_callback_ioptr.error = error; + png_set_write_fn (png_ptr, &to_callback_ioptr, + png_save_to_callback_write_func, + png_save_to_callback_flush_func); + } else { + png_init_io (png_ptr, f); + } + + if (compression >= 0) + png_set_compression_level (png_ptr, compression); + +#if defined(PNG_iCCP_SUPPORTED) + /* the proper ICC profile title is encoded in the profile */ + if (icc_profile != NULL) { + png_set_iCCP (png_ptr, info_ptr, + "ICC profile", PNG_COMPRESSION_TYPE_BASE, + (png_bytep) icc_profile, icc_profile_size); + } +#endif + + if (has_alpha) { + png_set_IHDR (png_ptr, info_ptr, w, h, bpc, + PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); + } else { + png_set_IHDR (png_ptr, info_ptr, w, h, bpc, + PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); + } + sig_bit.red = bpc; + sig_bit.green = bpc; + sig_bit.blue = bpc; + sig_bit.alpha = bpc; + png_set_sBIT (png_ptr, info_ptr, &sig_bit); + png_write_info (png_ptr, info_ptr); + png_set_shift (png_ptr, &sig_bit); + png_set_packing (png_ptr); + + ptr = pixels; + for (y = 0; y < h; y++) { + row_ptr = (png_bytep)ptr; + png_write_rows (png_ptr, &row_ptr, 1); + ptr += rowstride; + } + + png_write_end (png_ptr, info_ptr); + +cleanup: + if (png_ptr != NULL) + png_destroy_write_struct (&png_ptr, &info_ptr); + + g_free (icc_profile); + + if (text_ptr != NULL) { + for (i = 0; i < num_keys; i++) + g_free (text_ptr[i].text); + g_free (text_ptr); + } + + return success; +} + +static gboolean +gdk_pixbuf__png_image_save (FILE *f, + GdkPixbuf *pixbuf, + gchar **keys, + gchar **values, + GError **error) +{ + return real_save_png (pixbuf, keys, values, error, + FALSE, f, NULL, NULL); +} + +static gboolean +gdk_pixbuf__png_image_save_to_callback (GdkPixbufSaveFunc save_func, + gpointer user_data, + GdkPixbuf *pixbuf, + gchar **keys, + gchar **values, + GError **error) +{ + return real_save_png (pixbuf, keys, values, error, + TRUE, NULL, save_func, user_data); +} + +#ifndef INCLUDE_png +#define MODULE_ENTRY(function) G_MODULE_EXPORT void function +#else +#define MODULE_ENTRY(function) void _gdk_pixbuf__png_ ## function +#endif + +MODULE_ENTRY (fill_vtable) (GdkPixbufModule *module) +{ + module->load = gdk_pixbuf__png_image_load; + module->begin_load = gdk_pixbuf__png_image_begin_load; + module->stop_load = gdk_pixbuf__png_image_stop_load; + module->load_increment = gdk_pixbuf__png_image_load_increment; + module->save = gdk_pixbuf__png_image_save; + module->save_to_callback = gdk_pixbuf__png_image_save_to_callback; +} + +MODULE_ENTRY (fill_info) (GdkPixbufFormat *info) +{ + static const GdkPixbufModulePattern signature[] = { + { "\x89PNG\r\n\x1a\x0a", NULL, 100 }, + { NULL, NULL, 0 } + }; + static const gchar *mime_types[] = { + "image/png", + NULL + }; + static const gchar *extensions[] = { + "png", + NULL + }; + + info->name = "png"; + info->signature = (GdkPixbufModulePattern *) signature; + info->description = N_("The PNG image format"); + info->mime_types = (gchar **) mime_types; + info->extensions = (gchar **) extensions; + info->flags = GDK_PIXBUF_FORMAT_WRITABLE | GDK_PIXBUF_FORMAT_THREADSAFE; + info->license = "LGPL"; +} diff --git a/libs/tk/ydk-pixbuf/io-xbm.c b/libs/tk/ydk-pixbuf/io-xbm.c new file mode 100644 index 0000000000..1856adab51 --- /dev/null +++ b/libs/tk/ydk-pixbuf/io-xbm.c @@ -0,0 +1,504 @@ +/* -*- mode: C; c-file-style: "linux" -*- */ +/* GdkPixbuf library - XBM image loader + * + * Copyright (C) 1999 Mark Crichton + * Copyright (C) 1999 The Free Software Foundation + * Copyright (C) 2001 Eazel, Inc. + * + * Authors: Mark Crichton + * Federico Mena-Quintero + * Jonathan Blandford + * John Harper + * + * 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, see . + */ + +/* Following code adapted from io-tiff.c, which was ``(almost) blatantly + ripped from Imlib'' */ + +#include "config.h" +#include +#include +#ifdef HAVE_UNISTD_H +#include +#endif +#include +#include +#include "gdk-pixbuf-private.h" +#include + + + + +typedef struct _XBMData XBMData; +struct _XBMData +{ + GdkPixbufModulePreparedFunc prepare_func; + GdkPixbufModuleUpdatedFunc update_func; + gpointer user_data; + + gchar *tempname; + FILE *file; + gboolean all_okay; +}; + + +/* xbm parser borrowed from xc/lib/X11/RdBitF.c */ + +#define MAX_SIZE 255 + +/* shared data for the image read/parse logic */ +static short hex_table[256]; /* conversion value */ +static gboolean initialized = FALSE; /* easier to fill in at run time */ + + +/* Table index for the hex values. Initialized once, first time. + * Used for translation value or delimiter significance lookup. + */ +static void +init_hex_table (void) +{ + /* + * We build the table at run time for several reasons: + * + * 1. portable to non-ASCII machines. + * 2. still reentrant since we set the init flag after setting table. + * 3. easier to extend. + * 4. less prone to bugs. + */ + hex_table['0'] = 0; + hex_table['1'] = 1; + hex_table['2'] = 2; + hex_table['3'] = 3; + hex_table['4'] = 4; + hex_table['5'] = 5; + hex_table['6'] = 6; + hex_table['7'] = 7; + hex_table['8'] = 8; + hex_table['9'] = 9; + hex_table['A'] = 10; + hex_table['B'] = 11; + hex_table['C'] = 12; + hex_table['D'] = 13; + hex_table['E'] = 14; + hex_table['F'] = 15; + hex_table['a'] = 10; + hex_table['b'] = 11; + hex_table['c'] = 12; + hex_table['d'] = 13; + hex_table['e'] = 14; + hex_table['f'] = 15; + + /* delimiters of significance are flagged w/ negative value */ + hex_table[' '] = -1; + hex_table[','] = -1; + hex_table['}'] = -1; + hex_table['\n'] = -1; + hex_table['\t'] = -1; + + initialized = TRUE; +} + +/* Read next hex value in the input stream, return -1 if EOF */ +static int +next_int (FILE *fstream) +{ + int ch; + int value = 0; + int gotone = 0; + int done = 0; + + /* loop, accumulate hex value until find delimiter + skip any initial delimiters found in read stream */ + + while (!done) { + ch = getc (fstream); + if (ch == EOF) { + value = -1; + done++; + } else { + /* trim high bits, check type and accumulate */ + ch &= 0xff; + if (g_ascii_isxdigit (ch)) { + value = (value << 4) + g_ascii_xdigit_value (ch); + gotone++; + } else if ((hex_table[ch]) < 0 && gotone) { + done++; + } + } + } + return value; +} + +static gboolean +read_bitmap_file_data (FILE *fstream, + guint *width, + guint *height, + guchar **data, + int *x_hot, + int *y_hot) +{ + guchar *bits = NULL; /* working variable */ + char line[MAX_SIZE]; /* input line from file */ + int size; /* number of bytes of data */ + char name_and_type[MAX_SIZE]; /* an input line */ + char *type; /* for parsing */ + int value; /* from an input line */ + int version10p; /* boolean, old format */ + int padding; /* to handle alignment */ + int bytes_per_line; /* per scanline of data */ + guint ww = 0; /* width */ + guint hh = 0; /* height */ + int hx = -1; /* x hotspot */ + int hy = -1; /* y hotspot */ + + /* first time initialization */ + if (!initialized) { + init_hex_table (); + } + + /* error cleanup and return macro */ +#define RETURN(code) { g_free (bits); return code; } + + while (fgets (line, MAX_SIZE, fstream)) { + if (strlen (line) == MAX_SIZE-1) + RETURN (FALSE); + if (sscanf (line,"#define %s %d",name_and_type,&value) == 2) { + if (!(type = strrchr (name_and_type, '_'))) + type = name_and_type; + else { + type++; + } + + if (!strcmp ("width", type)) { + if (value <= 0) + RETURN (FALSE); + ww = (unsigned int) value; + } + if (!strcmp ("height", type)) { + if (value <= 0) + RETURN (FALSE); + hh = (unsigned int) value; + } + if (!strcmp ("hot", type)) { + if (type-- == name_and_type + || type-- == name_and_type) + continue; + if (!strcmp ("x_hot", type)) + hx = value; + if (!strcmp ("y_hot", type)) + hy = value; + } + continue; + } + + if (sscanf (line, "static short %s = {", name_and_type) == 1) + version10p = 1; + else if (sscanf (line,"static const unsigned char %s = {",name_and_type) == 1) + version10p = 0; + else if (sscanf (line,"static unsigned char %s = {",name_and_type) == 1) + version10p = 0; + else if (sscanf (line, "static const char %s = {", name_and_type) == 1) + version10p = 0; + else if (sscanf (line, "static char %s = {", name_and_type) == 1) + version10p = 0; + else + continue; + + if (!(type = strrchr (name_and_type, '_'))) + type = name_and_type; + else + type++; + + if (strcmp ("bits[]", type)) + continue; + + if (!ww || !hh) + RETURN (FALSE); + + if ((ww % 16) && ((ww % 16) < 9) && version10p) + padding = 1; + else + padding = 0; + + bytes_per_line = (ww+7)/8 + padding; + + size = bytes_per_line * hh; + if (size / bytes_per_line != hh) /* overflow */ + RETURN (FALSE); + bits = g_malloc (size); + + if (version10p) { + unsigned char *ptr; + int bytes; + + for (bytes = 0, ptr = bits; bytes < size; (bytes += 2)) { + if ((value = next_int (fstream)) < 0) + RETURN (FALSE); + *(ptr++) = value; + if (!padding || ((bytes+2) % bytes_per_line)) + *(ptr++) = value >> 8; + } + } else { + unsigned char *ptr; + int bytes; + + for (bytes = 0, ptr = bits; bytes < size; bytes++, ptr++) { + if ((value = next_int (fstream)) < 0) + RETURN (FALSE); + *ptr=value; + } + } + break; + } + + if (!bits) + RETURN (FALSE); + + *data = bits; + *width = ww; + *height = hh; + if (x_hot) + *x_hot = hx; + if (y_hot) + *y_hot = hy; + + return TRUE; +} + + + +static GdkPixbuf * +gdk_pixbuf__xbm_image_load_real (FILE *f, + XBMData *context, + GError **error) +{ + guint w, h; + int x_hot, y_hot; + guchar *data, *ptr; + guchar *pixels; + guint row_stride; + int x, y; + int reg = 0; /* Quiet compiler */ + int bits; + + GdkPixbuf *pixbuf; + + if (!read_bitmap_file_data (f, &w, &h, &data, &x_hot, &y_hot)) { + g_set_error_literal (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_CORRUPT_IMAGE, + _("Invalid XBM file")); + return NULL; + } + + pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, w, h); + + if (pixbuf == NULL) { + g_set_error_literal (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY, + _("Insufficient memory to load XBM image file")); + return NULL; + } + + if (x_hot != -1 && y_hot != -1) { + gchar hot[10]; + g_snprintf (hot, 10, "%d", x_hot); + gdk_pixbuf_set_option (pixbuf, "x_hot", hot); + g_snprintf (hot, 10, "%d", y_hot); + gdk_pixbuf_set_option (pixbuf, "y_hot", hot); + } + + pixels = gdk_pixbuf_get_pixels (pixbuf); + row_stride = gdk_pixbuf_get_rowstride (pixbuf); + + if (context && context->prepare_func) + (* context->prepare_func) (pixbuf, NULL, context->user_data); + + + /* Initialize PIXBUF */ + + ptr = data; + for (y = 0; y < h; y++) { + bits = 0; + for (x = 0; x < w; x++) { + guchar channel; + if (bits == 0) { + reg = *ptr++; + bits = 8; + } + + channel = (reg & 1) ? 0 : 255; + reg >>= 1; + bits--; + + pixels[x*3+0] = channel; + pixels[x*3+1] = channel; + pixels[x*3+2] = channel; + } + pixels += row_stride; + } + g_free (data); + + if (context) { + if (context->update_func) + (* context->update_func) (pixbuf, 0, 0, w, h, context->user_data); + } + + return pixbuf; +} + + +/* Static loader */ + +static GdkPixbuf * +gdk_pixbuf__xbm_image_load (FILE *f, + GError **error) +{ + return gdk_pixbuf__xbm_image_load_real (f, NULL, error); +} + + +/* Progressive loader */ + +/* + * Proper XBM progressive loading isn't implemented. Instead we write + * it to a file, then load the file when it's done. It's not pretty. + */ + +static gpointer +gdk_pixbuf__xbm_image_begin_load (GdkPixbufModuleSizeFunc size_func, + GdkPixbufModulePreparedFunc prepare_func, + GdkPixbufModuleUpdatedFunc update_func, + gpointer user_data, + GError **error) +{ + XBMData *context; + gint fd; + + context = g_new (XBMData, 1); + context->prepare_func = prepare_func; + context->update_func = update_func; + context->user_data = user_data; + context->all_okay = TRUE; + fd = g_file_open_tmp ("gdkpixbuf-xbm-tmp.XXXXXX", + &context->tempname, + NULL); + if (fd < 0) { + g_free (context); + return NULL; + } + + context->file = fdopen (fd, "w+"); + if (context->file == NULL) { + g_free (context->tempname); + g_free (context); + return NULL; + } + + return context; +} + +static gboolean +gdk_pixbuf__xbm_image_stop_load (gpointer data, + GError **error) +{ + XBMData *context = (XBMData*) data; + gboolean retval = TRUE; + + g_return_val_if_fail (data != NULL, TRUE); + + fflush (context->file); + rewind (context->file); + if (context->all_okay) { + GdkPixbuf *pixbuf; + pixbuf = gdk_pixbuf__xbm_image_load_real (context->file, + context, + error); + if (pixbuf == NULL) + retval = FALSE; + else + g_object_unref (pixbuf); + } + + fclose (context->file); + g_unlink (context->tempname); + g_free (context->tempname); + g_free ((XBMData *) context); + + return retval; +} + +static gboolean +gdk_pixbuf__xbm_image_load_increment (gpointer data, + const guchar *buf, + guint size, + GError **error) +{ + XBMData *context = (XBMData *) data; + + g_return_val_if_fail (data != NULL, FALSE); + + if (fwrite (buf, sizeof (guchar), size, context->file) != size) { + gint save_errno = errno; + context->all_okay = FALSE; + g_set_error_literal (error, + G_FILE_ERROR, + g_file_error_from_errno (save_errno), + _("Failed to write to temporary file when loading XBM image")); + return FALSE; + } + + return TRUE; +} + +#ifndef INCLUDE_xbm +#define MODULE_ENTRY(function) G_MODULE_EXPORT void function +#else +#define MODULE_ENTRY(function) void _gdk_pixbuf__xbm_ ## function +#endif + +MODULE_ENTRY (fill_vtable) (GdkPixbufModule *module) +{ + module->load = gdk_pixbuf__xbm_image_load; + module->begin_load = gdk_pixbuf__xbm_image_begin_load; + module->stop_load = gdk_pixbuf__xbm_image_stop_load; + module->load_increment = gdk_pixbuf__xbm_image_load_increment; +} + +MODULE_ENTRY (fill_info) (GdkPixbufFormat *info) +{ + static const GdkPixbufModulePattern signature[] = { + { "#define ", NULL, 100 }, + { "/*", NULL, 50 }, + { NULL, NULL, 0 } + }; + static const gchar *mime_types[] = { + "image/x-xbitmap", + NULL + }; + static const gchar *extensions[] = { + "xbm", + NULL + }; + + info->name = "xbm"; + info->signature = (GdkPixbufModulePattern *) signature; + info->description = N_("The XBM image format"); + info->mime_types = (gchar **) mime_types; + info->extensions = (gchar **) extensions; + info->flags = GDK_PIXBUF_FORMAT_THREADSAFE; + info->license = "LGPL"; +} diff --git a/libs/tk/ydk-pixbuf/io-xpm.c b/libs/tk/ydk-pixbuf/io-xpm.c new file mode 100644 index 0000000000..43dee42603 --- /dev/null +++ b/libs/tk/ydk-pixbuf/io-xpm.c @@ -0,0 +1,820 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* GdkPixbuf library - XPM image loader + * + * Copyright (C) 1999 Mark Crichton + * Copyright (C) 1999 The Free Software Foundation + * + * Authors: Mark Crichton + * Federico Mena-Quintero + * + * 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, see . + */ + +#include "config.h" +#include +#include +#include +#include +#ifdef HAVE_UNISTD_H +#include /* for unlink */ +#endif +#include +#include "gdk-pixbuf-private.h" +#include + + + + +/* I have must have done something to deserve this. + * XPM is such a crappy format to handle. + * This code is an ugly hybrid from gdkpixmap.c + * modified to respect transparent colors. + * It's still a mess, though. + */ + +enum buf_op { + op_header, + op_cmap, + op_body +}; + +typedef struct { + gchar *color_string; + guint16 red; + guint16 green; + guint16 blue; + gint transparent; +} XPMColor; + +struct file_handle { + FILE *infile; + gchar *buffer; + guint buffer_size; +}; + +struct mem_handle { + const gchar **data; + int offset; +}; + +/* The following 2 routines (parse_color, find_color) come from Tk, via the Win32 + * port of GDK. The licensing terms on these (longer than the functions) is: + * + * This software is copyrighted by the Regents of the University of + * California, Sun Microsystems, Inc., and other parties. The following + * terms apply to all files associated with the software unless explicitly + * disclaimed in individual files. + * + * The authors hereby grant permission to use, copy, modify, distribute, + * and license this software and its documentation for any purpose, provided + * that existing copyright notices are retained in all copies and that this + * notice is included verbatim in any distributions. No written agreement, + * license, or royalty fee is required for any of the authorized uses. + * Modifications to this software may be copyrighted by their authors + * and need not follow the licensing terms described here, provided that + * the new terms are clearly indicated on the first page of each file where + * they apply. + * + * IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY + * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY + * DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE + * IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE + * NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR + * MODIFICATIONS. + * + * GOVERNMENT USE: If you are acquiring this software on behalf of the + * U.S. government, the Government shall have only "Restricted Rights" + * in the software and related documentation as defined in the Federal + * Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you + * are acquiring the software on behalf of the Department of Defense, the + * software shall be classified as "Commercial Computer Software" and the + * Government shall have only "Restricted Rights" as defined in Clause + * 252.227-7013 (c) (1) of DFARs. Notwithstanding the foregoing, the + * authors grant the U.S. Government and others acting in its behalf + * permission to use and distribute the software in accordance with the + * terms specified in this license. + */ + +#include "xpm-color-table.h" + +/* + *---------------------------------------------------------------------- + * + * find_color -- + * + * This routine finds the color entry that corresponds to the + * specified color. + * + * Results: + * Returns non-zero on success. The RGB values of the XColor + * will be initialized to the proper values on success. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +static int +compare_xcolor_entries (const void *a, const void *b) +{ + return g_ascii_strcasecmp ((const char *) a, + color_names + ((const XPMColorEntry *)b)->name_offset); +} + +static gboolean +find_color(const char *name, + XPMColor *colorPtr) +{ + XPMColorEntry *found; + + found = bsearch (name, xColors, G_N_ELEMENTS (xColors), sizeof (XPMColorEntry), + compare_xcolor_entries); + if (found == NULL) + return FALSE; + + colorPtr->red = (found->red * 65535) / 255; + colorPtr->green = (found->green * 65535) / 255; + colorPtr->blue = (found->blue * 65535) / 255; + + return TRUE; +} + +/* + *---------------------------------------------------------------------- + * + * parse_color -- + * + * Partial implementation of X color name parsing interface. + * + * Results: + * Returns TRUE on success. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +static gboolean +parse_color (const char *spec, + XPMColor *colorPtr) +{ + if (spec[0] == '#') { + char fmt[16]; + int i, red, green, blue; + + if ((i = strlen (spec + 1)) % 3) { + return FALSE; + } + i /= 3; + + g_snprintf (fmt, 16, "%%%dx%%%dx%%%dx", i, i, i); + + if (sscanf (spec + 1, fmt, &red, &green, &blue) != 3) { + return FALSE; + } + if (i == 4) { + colorPtr->red = red; + colorPtr->green = green; + colorPtr->blue = blue; + } else if (i == 1) { + colorPtr->red = (red * 65535) / 15; + colorPtr->green = (green * 65535) / 15; + colorPtr->blue = (blue * 65535) / 15; + } else if (i == 2) + { + colorPtr->red = (red * 65535) / 255; + colorPtr->green = (green * 65535) / 255; + colorPtr->blue = (blue * 65535) / 255; + } else /* if (i == 3) */ { + colorPtr->red = (red * 65535) / 4095; + colorPtr->green = (green * 65535) / 4095; + colorPtr->blue = (blue * 65535) / 4095; + } + } else { + if (!find_color(spec, colorPtr)) + return FALSE; + } + return TRUE; +} + +static gint +xpm_seek_string (FILE *infile, const gchar *str) +{ + char instr[1024]; + + while (!feof (infile)) { + if (fscanf (infile, "%1023s", instr) < 0) + return FALSE; + if (strcmp (instr, str) == 0) + return TRUE; + } + + return FALSE; +} + +static gint +xpm_seek_char (FILE *infile, gchar c) +{ + gint b, oldb; + + while ((b = getc (infile)) != EOF) { + if (c != b && b == '/') { + b = getc (infile); + if (b == EOF) + return FALSE; + + else if (b == '*') { /* we have a comment */ + b = -1; + do { + oldb = b; + b = getc (infile); + if (b == EOF) + return FALSE; + } while (!(oldb == '*' && b == '/')); + } + } else if (c == b) + return TRUE; + } + + return FALSE; +} + +static gint +xpm_read_string (FILE *infile, gchar **buffer, guint *buffer_size) +{ + gint c; + guint cnt = 0, bufsiz, ret = FALSE; + gchar *buf; + + buf = *buffer; + bufsiz = *buffer_size; + if (buf == NULL) { + bufsiz = 10 * sizeof (gchar); + buf = g_new (gchar, bufsiz); + } + + do { + c = getc (infile); + } while (c != EOF && c != '"'); + + if (c != '"') + goto out; + + while ((c = getc (infile)) != EOF) { + if (cnt == bufsiz) { + guint new_size = bufsiz * 2; + + if (new_size > bufsiz) + bufsiz = new_size; + else + goto out; + + buf = g_realloc (buf, bufsiz); + buf[bufsiz - 1] = '\0'; + } + + if (c != '"') + buf[cnt++] = c; + else { + buf[cnt] = 0; + ret = TRUE; + break; + } + } + + out: + buf[bufsiz - 1] = '\0'; /* ensure null termination for errors */ + *buffer = buf; + *buffer_size = bufsiz; + return ret; +} + +static gchar * +xpm_extract_color (const gchar *buffer) +{ + const gchar *p = &buffer[0]; + gint new_key = 0; + gint key = 0; + gint current_key = 1; + gint space = 128; + gchar word[129], color[129], current_color[129]; + gchar *r; + + word[0] = '\0'; + color[0] = '\0'; + current_color[0] = '\0'; + while (1) { + /* skip whitespace */ + for (; *p != '\0' && g_ascii_isspace (*p); p++) { + } + /* copy word */ + for (r = word; *p != '\0' && !g_ascii_isspace (*p) && r - word < sizeof (word) - 1; p++, r++) { + *r = *p; + } + *r = '\0'; + if (*word == '\0') { + if (color[0] == '\0') /* incomplete colormap entry */ + return NULL; + else /* end of entry, still store the last color */ + new_key = 1; + } + else if (key > 0 && color[0] == '\0') /* next word must be a color name part */ + new_key = 0; + else { + if (strcmp (word, "c") == 0) + new_key = 5; + else if (strcmp (word, "g") == 0) + new_key = 4; + else if (strcmp (word, "g4") == 0) + new_key = 3; + else if (strcmp (word, "m") == 0) + new_key = 2; + else if (strcmp (word, "s") == 0) + new_key = 1; + else + new_key = 0; + } + if (new_key == 0) { /* word is a color name part */ + if (key == 0) /* key expected */ + return NULL; + /* accumulate color name */ + if (color[0] != '\0') { + strncat (color, " ", space); + space -= MIN (space, 1); + } + strncat (color, word, space); + space -= MIN (space, strlen (word)); + } + else { /* word is a key */ + if (key > current_key) { + current_key = key; + strcpy (current_color, color); + } + space = 128; + color[0] = '\0'; + key = new_key; + if (*p == '\0') break; + } + + } + if (current_key > 1) + return g_strdup (current_color); + else + return NULL; +} + +/* (almost) direct copy from gdkpixmap.c... loads an XPM from a file */ + +static const gchar * +file_buffer (enum buf_op op, gpointer handle) +{ + struct file_handle *h = handle; + + switch (op) { + case op_header: + if (xpm_seek_string (h->infile, "XPM") != TRUE) + break; + + if (xpm_seek_char (h->infile, '{') != TRUE) + break; + /* Fall through to the next xpm_seek_char. */ + + case op_cmap: + xpm_seek_char (h->infile, '"'); + fseek (h->infile, -1, SEEK_CUR); + /* Fall through to the xpm_read_string. */ + + case op_body: + if(!xpm_read_string (h->infile, &h->buffer, &h->buffer_size)) + return NULL; + return h->buffer; + + default: + g_assert_not_reached (); + } + + return NULL; +} + +/* This reads from memory */ +static const gchar * +mem_buffer (enum buf_op op, gpointer handle) +{ + struct mem_handle *h = handle; + switch (op) { + case op_header: + case op_cmap: + case op_body: + if (h->data[h->offset]) { + const gchar* retval; + + retval = h->data[h->offset]; + h->offset += 1; + return retval; + } + break; + + default: + g_assert_not_reached (); + break; + } + + return NULL; +} + +/* This function does all the work. */ +static GdkPixbuf * +pixbuf_create_from_xpm (const gchar * (*get_buf) (enum buf_op op, gpointer handle), gpointer handle, + GError **error) +{ + gint w, h, n_col, cpp, x_hot, y_hot, items; + gint cnt, xcnt, ycnt, wbytes, n; + gint is_trans = FALSE; + const gchar *buffer; + gchar *name_buf; + gchar pixel_str[32]; + GHashTable *color_hash; + XPMColor *colors, *color, *fallbackcolor; + guchar *pixtmp; + GdkPixbuf *pixbuf; + + fallbackcolor = NULL; + + buffer = (*get_buf) (op_header, handle); + if (!buffer) { + g_set_error_literal (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_CORRUPT_IMAGE, + _("No XPM header found")); + return NULL; + } + items = sscanf (buffer, "%d %d %d %d %d %d", &w, &h, &n_col, &cpp, &x_hot, &y_hot); + + if (items != 4 && items != 6) { + g_set_error_literal (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_CORRUPT_IMAGE, + _("Invalid XPM header")); + return NULL; + } + + if (w <= 0) { + g_set_error_literal (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_CORRUPT_IMAGE, + _("XPM file has image width <= 0")); + return NULL; + + } + if (h <= 0) { + g_set_error_literal (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_CORRUPT_IMAGE, + _("XPM file has image height <= 0")); + return NULL; + + } + if (cpp <= 0 || cpp >= 32) { + g_set_error_literal (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_CORRUPT_IMAGE, + _("XPM has invalid number of chars per pixel")); + return NULL; + } + if (n_col <= 0 || + n_col >= G_MAXINT / (cpp + 1) || + n_col >= G_MAXINT / sizeof (XPMColor)) { + g_set_error_literal (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_CORRUPT_IMAGE, + _("XPM file has invalid number of colors")); + return NULL; + } + + /* The hash is used for fast lookups of color from chars */ + color_hash = g_hash_table_new (g_str_hash, g_str_equal); + + name_buf = g_try_malloc (n_col * (cpp + 1)); + if (!name_buf) { + g_set_error_literal (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY, + _("Cannot allocate memory for loading XPM image")); + g_hash_table_destroy (color_hash); + return NULL; + } + colors = (XPMColor *) g_try_malloc (sizeof (XPMColor) * n_col); + if (!colors) { + g_set_error_literal (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY, + _("Cannot allocate memory for loading XPM image")); + g_hash_table_destroy (color_hash); + g_free (name_buf); + return NULL; + } + + for (cnt = 0; cnt < n_col; cnt++) { + gchar *color_name; + + buffer = (*get_buf) (op_cmap, handle); + if (!buffer) { + g_set_error_literal (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_CORRUPT_IMAGE, + _("Cannot read XPM colormap")); + g_hash_table_destroy (color_hash); + g_free (name_buf); + g_free (colors); + return NULL; + } + + color = &colors[cnt]; + color->color_string = &name_buf[cnt * (cpp + 1)]; + strncpy (color->color_string, buffer, cpp); + color->color_string[cpp] = 0; + buffer += strlen (color->color_string); + color->transparent = FALSE; + + color_name = xpm_extract_color (buffer); + + if ((color_name == NULL) || (g_ascii_strcasecmp (color_name, "None") == 0) + || (parse_color (color_name, color) == FALSE)) { + color->transparent = TRUE; + color->red = 0; + color->green = 0; + color->blue = 0; + is_trans = TRUE; + } + + g_free (color_name); + g_hash_table_insert (color_hash, color->color_string, color); + + if (cnt == 0) + fallbackcolor = color; + } + + pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, is_trans, 8, w, h); + + if (!pixbuf) { + g_set_error_literal (error, + GDK_PIXBUF_ERROR, + GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY, + _("Cannot allocate memory for loading XPM image")); + g_hash_table_destroy (color_hash); + g_free (colors); + g_free (name_buf); + return NULL; + } + + wbytes = w * cpp; + + for (ycnt = 0; ycnt < h; ycnt++) { + pixtmp = pixbuf->pixels + ycnt * pixbuf->rowstride; + + buffer = (*get_buf) (op_body, handle); + if ((!buffer) || (strlen (buffer) < wbytes)) + continue; + + for (n = 0, xcnt = 0; n < wbytes; n += cpp, xcnt++) { + strncpy (pixel_str, &buffer[n], cpp); + pixel_str[cpp] = 0; + + color = g_hash_table_lookup (color_hash, pixel_str); + + /* Bad XPM...punt */ + if (!color) + color = fallbackcolor; + + *pixtmp++ = color->red >> 8; + *pixtmp++ = color->green >> 8; + *pixtmp++ = color->blue >> 8; + + if (is_trans && color->transparent) + *pixtmp++ = 0; + else if (is_trans) + *pixtmp++ = 0xFF; + } + } + + g_hash_table_destroy (color_hash); + g_free (colors); + g_free (name_buf); + + if (items == 6) { + gchar hot[10]; + g_snprintf (hot, 10, "%d", x_hot); + gdk_pixbuf_set_option (pixbuf, "x_hot", hot); + g_snprintf (hot, 10, "%d", y_hot); + gdk_pixbuf_set_option (pixbuf, "y_hot", hot); + + } + + return pixbuf; +} + +/* Shared library entry point for file loading */ +static GdkPixbuf * +gdk_pixbuf__xpm_image_load (FILE *f, + GError **error) +{ + GdkPixbuf *pixbuf; + struct file_handle h; + + memset (&h, 0, sizeof (h)); + h.infile = f; + pixbuf = pixbuf_create_from_xpm (file_buffer, &h, error); + g_free (h.buffer); + + return pixbuf; +} + +/* Shared library entry point for memory loading */ +static GdkPixbuf * +gdk_pixbuf__xpm_image_load_xpm_data (const gchar **data) +{ + GdkPixbuf *pixbuf; + struct mem_handle h; + GError *error = NULL; + + h.data = data; + h.offset = 0; + + pixbuf = pixbuf_create_from_xpm (mem_buffer, &h, &error); + + if (error) { + g_warning ("Inline XPM data is broken: %s", error->message); + g_error_free (error); + error = NULL; + } + + return pixbuf; +} + +/* Progressive loader */ +typedef struct _XPMContext XPMContext; +struct _XPMContext +{ + GdkPixbufModulePreparedFunc prepare_func; + GdkPixbufModuleUpdatedFunc update_func; + gpointer user_data; + + gchar *tempname; + FILE *file; + gboolean all_okay; +}; + +/* + * FIXME xpm loading progressively is not properly implemented. + * Instead we will buffer to a file then load that file when done. + * This is very broken but it should be relatively simple to fix + * in the future. + */ +static gpointer +gdk_pixbuf__xpm_image_begin_load (GdkPixbufModuleSizeFunc size_func, + GdkPixbufModulePreparedFunc prepare_func, + GdkPixbufModuleUpdatedFunc update_func, + gpointer user_data, + GError **error) +{ + XPMContext *context; + gint fd; + + context = g_new (XPMContext, 1); + context->prepare_func = prepare_func; + context->update_func = update_func; + context->user_data = user_data; + context->all_okay = TRUE; + fd = g_file_open_tmp ("gdkpixbuf-xpm-tmp.XXXXXX", &context->tempname, + NULL); + if (fd < 0) { + g_free (context); + return NULL; + } + + context->file = fdopen (fd, "w+"); + if (context->file == NULL) { + g_free (context->tempname); + g_free (context); + return NULL; + } + + return context; +} + +static gboolean +gdk_pixbuf__xpm_image_stop_load (gpointer data, + GError **error) +{ + XPMContext *context = (XPMContext*) data; + GdkPixbuf *pixbuf; + gboolean retval = FALSE; + + g_return_val_if_fail (data != NULL, FALSE); + + fflush (context->file); + rewind (context->file); + if (context->all_okay) { + pixbuf = gdk_pixbuf__xpm_image_load (context->file, error); + + if (pixbuf != NULL) { + if (context->prepare_func) + (* context->prepare_func) (pixbuf, + NULL, + context->user_data); + if (context->update_func) + (* context->update_func) (pixbuf, 0, 0, pixbuf->width, pixbuf->height, context->user_data); + g_object_unref (pixbuf); + + retval = TRUE; + } + } + + fclose (context->file); + g_unlink (context->tempname); + g_free (context->tempname); + g_free ((XPMContext *) context); + + return retval; +} + +static gboolean +gdk_pixbuf__xpm_image_load_increment (gpointer data, + const guchar *buf, + guint size, + GError **error) +{ + XPMContext *context = (XPMContext *) data; + + g_return_val_if_fail (data != NULL, FALSE); + + if (fwrite (buf, sizeof (guchar), size, context->file) != size) { + gint save_errno = errno; + context->all_okay = FALSE; + g_set_error_literal (error, + G_FILE_ERROR, + g_file_error_from_errno (save_errno), + _("Failed to write to temporary file when loading XPM image")); + return FALSE; + } + + return TRUE; +} + +#ifndef INCLUDE_xpm +#define MODULE_ENTRY(function) G_MODULE_EXPORT void function +#else +#define MODULE_ENTRY(function) void _gdk_pixbuf__xpm_ ## function +#endif + +MODULE_ENTRY (fill_vtable) (GdkPixbufModule *module) +{ + module->load = gdk_pixbuf__xpm_image_load; + module->load_xpm_data = gdk_pixbuf__xpm_image_load_xpm_data; + module->begin_load = gdk_pixbuf__xpm_image_begin_load; + module->stop_load = gdk_pixbuf__xpm_image_stop_load; + module->load_increment = gdk_pixbuf__xpm_image_load_increment; +} + +MODULE_ENTRY (fill_info) (GdkPixbufFormat *info) +{ + static const GdkPixbufModulePattern signature[] = { + { "/* XPM */", NULL, 100 }, + { NULL, NULL, 0 } + }; + static const gchar *mime_types[] = { + "image/x-xpixmap", + NULL + }; + static const gchar *extensions[] = { + "xpm", + NULL + }; + + info->name = "xpm"; + info->signature = (GdkPixbufModulePattern *) signature; + info->description = N_("The XPM image format"); + info->mime_types = (gchar **) mime_types; + info->extensions = (gchar **) extensions; + info->flags = GDK_PIXBUF_FORMAT_THREADSAFE; + info->license = "LGPL"; +} diff --git a/libs/tk/ydk-pixbuf/pixops/DETAILS b/libs/tk/ydk-pixbuf/pixops/DETAILS new file mode 100644 index 0000000000..acf16f57e7 --- /dev/null +++ b/libs/tk/ydk-pixbuf/pixops/DETAILS @@ -0,0 +1,355 @@ +General ideas of Pixops +======================= + + - Gain speed by special-casing the common case, and using + generic code to handle the uncommon case. + + - Most of the time in scaling an image is in the center; + however code that can handle edges properly is slow + because it needs to deal with the possibility of running + off the edge. So make the fast case code only handle + the centers, and use generic, slow, code for the edges, + +Structure of Pixops +=================== + +The code of pixops can roughly be grouped into four parts: + + - Filter computation functions + + - Functions for scaling or compositing lines and pixels + using precomputed filters + + - pixops process, the central driver that iterates through + the image calling pixel or line functions as necessary + + - Wrapper functions (pixops_scale/composite/composite_color) + that compute the filter, chooses the line and pixel functions + and then call pixops_processs with the filter, line, + and pixel functions. + + +pixops process is a pretty scary looking function: + +static void +pixops_process (guchar *dest_buf, + int render_x0, + int render_y0, + int render_x1, + int render_y1, + int dest_rowstride, + int dest_channels, + gboolean dest_has_alpha, + const guchar *src_buf, + int src_width, + int src_height, + int src_rowstride, + int src_channels, + gboolean src_has_alpha, + double scale_x, + double scale_y, + int check_x, + int check_y, + int check_size, + guint32 color1, + guint32 color2, + PixopsFilter *filter, + PixopsLineFunc line_func, + PixopsPixelFunc pixel_func) + +(Some of the arguments should be moved into structures. It's basically +"all the arguments to pixops_composite_color plus three more") The +arguments can be divided up into: + + +Information about the destination buffer + + guchar *dest_buf, int dest_rowstride, int dest_channels, gboolean dest_has_alpha, + +Information about the source buffer + + guchar *src_buf, int src_rowstride, int src_channels, gboolean src_has_alpha, + int src_width, int src_height, + +Information on how to scale the source buf and the region of the scaled source +to render onto the destination buffer + + int render_x0, int render_y0, int render_x1, int render_y1 + double scale_x, double scale_y + +Information about a constant color or check pattern onto which to to composite + + int check_x, int check_y, int check_size, guint32 color1, guint32 color2 + +Information precomputed to use during the scale operation + + PixopsFilter *filter, PixopsLineFunc line_func, OixopsPixelFunc pixel_func + + +Filter computation +================== + +The PixopsFilter structure looks like: + +struct _PixopsFilter +{ + int *weights; + int n_x; + int n_y; + double x_offset; + double y_offset; +}; + + +'weights' is an array of size: + + weights[SUBSAMPLE][SUBSAMPLE][n_x][n_y] + +SUBSAMPLE is a constant - currently 16 in pixops.c. + + +In order to compute a scaled destination pixel we convolve +an array of n_x by n_y source pixels with one of +the SUBSAMPLE * SUBSAMPLE filter matrices stored +in weights. The choice of filter matrix is determined +by the fractional part of the source location. + +To compute dest[i,j] we do the following: + + x = i * scale_x + x_offset; + y = i * scale_x + y_offset; + x_int = floor(x) + y_int = floor(y) + + C = weights[SUBSAMPLE*(x - x_int)][SUBSAMPLE*(y - y_int)] + total = sum[l=0..n_x-1, j=0..n_y-1] (C[l,m] * src[x_int + l, x_int + m]) + +The filter weights are integers scaled so that the total of the +weights in the weights array is equal to 65536. + +When the source does not have alpha, we simply compute each channel +as above, so total is in the range [0,255*65536] + + dest = src / 65536 + +When the source does have alpha, then we need to compute using +"pre-multiplied alpha": + + a_total = sum (C[l,m] * src_a[x_int + l, x_int + m]) + c_total = sum (C[l,m] * src_a[x_int + l, x_int + m] * src_c[x_int + l, x_int + m]) + +This gives us a result for c_total in the range of [0,255*a_total] + + c_dest = c_total / a_total + + +Mathematical aside: + +The process of producing a destination filter consists +of: + + - Producing a continuous approximation to the source + image via interpolation. + + - Sampling that continuous approximation with filter. + +This is representable as: + + S(x,y) = sum[i=-inf,inf; j=-inf,inf] A(frac(x),frac(y))[i,j] * S[floor(x)+i,floor(y)+j] + + D[i,j] = Integral(s=-inf,inf; t=-inf,inf) B(i+x,j+y) S((i+x)/scale_x,(i+y)/scale_y) + +By reordering the sums and integrals, you get something of the form: + + D[i,j] = sum[l=-inf,inf; m=-inf;inf] C[l,m] S[i+l,j+l] + +The arrays in weights are the C[l,m] above, and are thus +determined by the interpolating algorithm in use and the +sampling filter: + + INTERPOLATE SAMPLE + ART_FILTER_NEAREST nearest neighbour point + ART_FILTER_TILES nearest neighbour box + ART_FILTER_BILINEAR (scale < 1) nearest neighbour box (scale < 1) + ART_FILTER_BILINEAR (scale > 1) bilinear point (scale > 1) + ART_FILTER_HYPER bilinear box + + +Pixel Functions +=============== + +typedef void (*PixopsPixelFunc) (guchar *dest, int dest_x, int dest_channels, int dest_has_alpha, + int src_has_alpha, + int check_size, guint32 color1, guint32 color2, + int r, int g, int b, int a); + +The arguments here are: + + dest: location to store the output pixel + dest_x: x coordinate of destination (for handling checks) + dest_has_alpha, dest_channels: Information about the destination pixbuf + src_has_alpha: Information about the source pixbuf + + check_size, color1, color2: Information for color background for composite_color variant + + r,g,b,a - scaled red, green, blue and alpha + +r,g,b are premultiplied alpha. + + a is in [0,65536*255] + r is in [0,255*a] + g is in [0,255*a] + b is in [0,255*a] + +If src_has_alpha is false, then a will be 65536*255, allowing optimization. + + +Line functions +============== + +typedef guchar *(*PixopsLineFunc) (int *weights, int n_x, int n_y, + guchar *dest, int dest_x, guchar *dest_end, int dest_channels, int dest_has_alpha, + guchar **src, int src_channels, gboolean src_has_alpha, + int x_init, int x_step, int src_width, + int check_size, guint32 color1, guint32 color2); + +The argumets are: + + weights, n_x, n_y + + Filter weights for this row - dimensions weights[SUBSAMPLE][n_x][n_y] + + dest, dest_x, dest_end, dest_channels, dest_has_alpha + + The destination buffer, function will start writing into *dest and + increment by dest_channels, until dest == dest_end. Reading from + src for these pixels is guaranteed not to go outside of the + bufer bounds + + src, src_channels, src_has_alpha + + src[n_y] - an array of pointers to the start of the source rows + for each filter coordinate. + + x_init, x_step + + Information about x positions in source image. + + src_width - unused + + check_size, color1, color2: Information for color background for composite_color variant + + The total for the destination pixel at dest + i is given by + + SUM (l=0..n_x - 1, m=0..n_y - 1) + src[m][(x_init + i * x_step)>> SCALE_SHIFT + l] * weights[m][l] + + +Algorithms for compositing +========================== + +Compositing alpha on non alpha: + + R = As * Rs + (1 - As) * Rd + G = As * Gs + (1 - As) * Gd + B = As * Bs + (1 - As) * Bd + +This can be regrouped as: + + Cd + Cs * (Cs - Rd) + +Compositing alpha on alpha: + + A = As + (1 - As) * Ad + R = (As * Rs + (1 - As) * Rd * Ad) / A + G = (As * Gs + (1 - As) * Gd * Ad) / A + B = (As * Bs + (1 - As) * Bd * Ad) / A + +The way to think of this is in terms of the "area": + +The final pixel is composed of area As of the source pixel +and (1 - As) * Ad of the target pixel. So the final pixel +is a weighted average with those weights. + +Note that the weights do not add up to one - hence the +non-constant division. + + +Integer tricks for compositing +============================== + + + +MMX Code +======== + +Line functions are provided in MMX functionsfor a few special +cases: + + n_x = n_y = 2 + + src_channels = 3 dest_channels = 3 op = scale + src_channels = 4 with alpha dest_channels = 4 no alpha op = composite + src_channels = 4 with alpha dest_channels = 4 no alpha op = composite_color + +For the case n_x = n_y = 2 - primarily hit when scaling up with bilinear +scaling, we can take advantage of the fact that multiple destination +pixels will be composed from the same source pixels. + +That is a destination pixel is a linear combination of the source +pixels around it: + + + S0 S1 + + + + + + D D' D'' ... + + + + + S2 S3 + +Each mmx register is 64 bits wide, so we can unpack a source pixel +into the low 8 bits of 4 16 bit words, and store it into a mmx +register. + +For each destination pixel, we first make sure that we have pixels S0 +... S3 loaded into registers mm0 ...mm3. (This will often involve not +doing anything or moving mm1 and mm3 into mm0 and mm1 then reloading +mm1 and mm3 with new values). + +Then we load up the appropriate weights for the 4 corner pixels +based on the offsets of the destination pixel within the source +pixels. + +We have preexpanded the weights to 64 bits wide and truncated the +range to 8 bits, so an original filter value of + + 0x5321 would be expanded to + + 0x0053005300530053 + +For source buffers without alpha, we simply do a multiply-add +of the weights, giving us a 16 bit quantity for the result +that we shift left by 8 and store in the destination buffer. + +When the source buffer has alpha, then things become more +complicated - when we load up mm0 and mm3, we premultiply +the alpha, so they contain: + + (a*ff >> 8) (r*a >> 8) (g*a >> 8) (b*a >> a) + +Then when we multiply by the weights, and add we end up +with premultiplied r,g,b,a in the range of 0 .. 0xff * 0ff, +call them A,R,G,B + +We then need to composite with the dest pixels - which +we do by: + + r_dest = (R + ((0xff * 0xff - A) >> 8) * r_dest) >> 8 + +(0xff * 0xff) diff --git a/libs/tk/ydk-pixbuf/pixops/README b/libs/tk/ydk-pixbuf/pixops/README new file mode 100644 index 0000000000..354c3a1977 --- /dev/null +++ b/libs/tk/ydk-pixbuf/pixops/README @@ -0,0 +1,163 @@ +The code in this directory implements optimized, filtered scaling +for pixmap data. + +This code is copyright Red Hat, Inc, 2000 and licensed under the terms +of the GNU Lesser General Public License (LGPL). + +(If you want to use it in a project where that license is not +appropriate, please contact me, and most likely something can be +worked out.) + +Owen Taylor + +PRINCIPLES +========== + +The general principle of this code is that it first computes a filter +matrix for the given filtering mode, and then calls a general driver +routine, passing in functions to composite pixels and lines. + +(The pixel functions are used for handling edge cases, and the line +functions are simply used for the middle parts of the image.) + +The system is designed so that the line functions can be simple, +don't have to worry about special cases, can be selected to +be specific to the particular formats involved. This allows them +to be hyper-optimized. Since most of the compution time is +spent in these functions, this results in an overall fast design. + +MMX assembly code for Intel (and compatible) processors is included +for a number of the most common special cases: + + scaling from RGB to RGB + compositing from RGBA to RGBx + compositing against a color from RGBA and storing in a RGBx buffer + +Alpha compositing 8 bit RGBAa onto RGB is defined in terms of +rounding the exact result (real values in [0,1]): + + cc = ca * aa + (1 - aa) * Cb + + Cc = ROUND [255. * (Ca/255. * Aa/255. + (1 - Aa/255.) * Cb/255.)] + +ROUND(i / 255.) can be computed exactly for i in [0,255*255] as: + + t = i + 0x80; result = (t + (t >> 8)) >> 8; [ call this as To8(i) ] + +So, + + t = Ca * Aa + (255 - Aa) * Cb + 0x80; + Cc = (t + (t >> 8)) >> 8; + +Alpha compositing 8 bit RaGaBaAa onto RbGbBbAa is a little harder, for +non-premultiplied alpha. The premultiplied result is simple: + + ac = aa + (1 - aa) * ab + cc = ca + (1 - aa) * cb + +Which can be computed in integers terms as: + + Cc = Ca + To8 ((255 - Aa) * Cb) + Ac = Aa + To8 ((255 - Aa) * Ab) + +For non-premultiplied alpha, we need divide the color components by +the alpha: + + +- (ca * aa + (1 - aa) * ab * cb)) / ac; aa != 0 + cc = | + +- cb; aa == 0 + +To calculate this as in integer, we note the alternate form: + + cc = cb + aa * (ca - cb) / ac + +[ 'cc = ca + (ac - aa) * (cb - ca) / ac' can also be useful numerically, + but isn't important here ] + +We can express this as integers as: + + Ac_tmp = Aa * 255 + (255 - Aa) * Ab; + + +- Cb + (255 * Aa * (Ca - Cb) + Ac_tmp / 2) / Ac_tmp ; Ca > Cb + Cc = | + +- Cb - (255 * Aa * (Cb - Ca) + Ac_tmp / 2) / Ac_tmp ; ca <= Cb + +Or, playing bit tricks to avoid the conditional + + Cc = Cb + (255 * Aa * (Ca - Cb) + (((Ca - Cb) >> 8) ^ (Ac_tmp / 2)) ) / Ac_tmp + +TODO +==== + +* ART_FILTER_HYPER is not correctly implemented. It is currently + implemented as a filter that is derived by doing linear interpolation + on the source image and then averaging that with a box filter. + + It should be defined as followed (see art_filterlevel.h) + + "HYPER is the highest quality reconstruction function. It is derived + from the hyperbolic filters in Wolberg's "Digital Image Warping," + and is formally defined as the hyperbolic-filter sampling the ideal + hyperbolic-filter interpolated image (the filter is designed to be + idempotent for 1:1 pixel mapping). It is the slowest and highest + quality." + + The current HYPER is probably as slow, but lower quality. Also, there + are some subtle errors in the calculation current HYPER that show up as dark + stripes if you scale a constant-color image. + +* There are some roundoff errors in the compositing routines. + the _nearest() variants do it right, most of the other code + is wrong to some degree or another. + + For instance, in composite_line_22_4a4(), we have: + + dest[0] = ((0xff0000 - a) * dest[0] + r) >> 24; + + if a is 0 (implies r == 0), then we have: + + (0xff0000 * dest[0]) >> 24 + + which gives results which are 1 to low: + + 255 => 254, 1 => 0. + + So, this should be something like: + + ((0xff0000 - a) * dest[0] + r + 0xffffff) >> 24; + + (Not checked, caveat emptor) + + An alternatve formulation of this as: + + dest[0] + (r - a * dest[0] + 0xffffff) >> 24 + + may be better numerically, but would need consideration for overflow. + +* The generic functions could be sped up considerably by + switching around conditionals and inner loops in various + places. + +* Right now, in several of the most common cases, there are + optimized mmx routines, but no optimized C routines. + + For instance, there is a + + pixops_composite_line_22_4a4_mmx() + + But no + + pixops_composite_line_22_4a4() + + Also, it may be desirable to include a few more special cases - in particular: + + pixops_composite_line_22_4a3() + + May be desirable. + +* Scaling down images by large scale factors is _slow_ since huge filter + matrixes are computed. (e.g., to scale down by a factor of 100, we compute + 101x101 filter matrixes. At some point, it would be more efficent to + switch over to subsampling when scaling down - one should never need a filter + matrix bigger than 16x16. + diff --git a/libs/tk/ydk-pixbuf/pixops/composite_line_22_4a4_mmx.S b/libs/tk/ydk-pixbuf/pixops/composite_line_22_4a4_mmx.S new file mode 100644 index 0000000000..c062cad915 --- /dev/null +++ b/libs/tk/ydk-pixbuf/pixops/composite_line_22_4a4_mmx.S @@ -0,0 +1,239 @@ +/* + * Copyright (C) 2000 Red Hat, 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, see . + */ + .file "composite_line_22_4a4_mmx.S" + .version "01.01" +gcc2_compiled.: +.text + .align 16 + +#if !defined(__MINGW32__) && !defined(__CYGWIN__) && !defined(__INTERIX) + +/* Magic indicating no need for an executable stack */ +#if !defined __powerpc64__ && !defined __ia64__ +.section .note.GNU-stack; .previous +#endif + +.globl _pixops_composite_line_22_4a4_mmx + .type _pixops_composite_line_22_4a4_mmx,@function +_pixops_composite_line_22_4a4_mmx: + +#else + +.globl __pixops_composite_line_22_4a4_mmx +__pixops_composite_line_22_4a4_mmx: + +#endif +/* + * Arguments + * + * weights: 8(%ebp) + * p: 12(%ebp) %esi + * q1: 16(%ebp) + * q2: 20(%ebp) + * xstep: 24(%ebp) + * p_end: 28(%ebp) + * xinit: 32(%ebp) + * +*/ +/* + * Function call entry + */ + pushl %ebp + movl %esp,%ebp + subl $28,%esp + pushl %edi + pushl %esi + pushl %ebx +/* Locals: + * int x %ebx + * int x_scaled -24(%ebp) + */ + +/* + * Setup + */ +/* Initialize variables */ + movl 32(%ebp),%ebx + movl 32(%ebp),%edx + sarl $16,%edx + movl 12(%ebp),%esi + + movl %edx,-24(%ebp) + + cmpl 28(%ebp),%esi + jnb .out + +/* Load initial values into %mm1, %mm3 */ + shll $2, %edx + + pxor %mm4, %mm4 + + movl 16(%ebp),%edi + movl (%edi, %edx), %eax + movd (%edi, %edx), %mm5 + punpcklbw %mm4, %mm5 + shrl $24, %eax + movl $0x010101, %ecx + mull %ecx + orl $0xff000000, %eax + movd %eax, %mm1 + punpcklbw %mm4, %mm1 + pmullw %mm5,%mm1 + + movl -24(%ebp),%edx + shll $2, %edx + + movl 20(%ebp),%edi + movl (%edi, %edx), %eax + movd (%edi, %edx), %mm5 + punpcklbw %mm4, %mm5 + shrl $24, %eax + movl $0x010101, %ecx + mull %ecx + orl $0xff000000, %eax + movd %eax, %mm3 + punpcklbw %mm4, %mm3 + pmullw %mm5,%mm3 + + psrlw $8,%mm1 + psrlw $8,%mm3 + + addl $65536,%ebx + movl %ebx,%edx + sarl $16,%edx + + jmp .newx + .p2align 4,,7 +.loop: +/* int x_index = (x & 0xf000) >> 12 */ + movl %ebx,%eax + andl $0xf000,%eax + shrl $7,%eax + + movq (%edi,%eax),%mm4 + pmullw %mm0,%mm4 + movq 8(%edi,%eax),%mm5 + pmullw %mm1,%mm5 + movq 16(%edi,%eax),%mm6 + movq 24(%edi,%eax),%mm7 + pmullw %mm2,%mm6 + pmullw %mm3,%mm7 + paddw %mm4, %mm5 + paddw %mm6, %mm7 + paddw %mm5, %mm7 + + movl $0xffff,%ecx + movd %ecx,%mm4 + psllq $48,%mm4 + movq %mm4,%mm6 + psubw %mm7,%mm4 + pand %mm6,%mm4 + + movq %mm4,%mm5 + psrlq $16,%mm4 + por %mm4,%mm5 + psrlq $32,%mm5 + por %mm4,%mm5 + + psrlw $8,%mm5 + + movd (%esi),%mm7 + pxor %mm4,%mm4 + punpcklbw %mm4, %mm7 + + pmullw %mm7,%mm5 + +/* x += x_step; */ + addl 24(%ebp),%ebx +/* x_scale = x >> 16; */ + movl %ebx,%edx + sarl $16,%edx + + paddw %mm5,%mm6 + + psrlw $8,%mm6 + packuswb %mm6, %mm6 + movd %mm6,(%esi) + + addl $4, %esi + + cmpl %esi,28(%ebp) + je .out + + cmpl %edx,-24(%ebp) + je .loop + +.newx: + movl %edx,-24(%ebp) +/* + * Load the two new values into %mm1, %mm3, move old values into %mm0, %mm2 + */ + movq %mm1, %mm0 + movq %mm3, %mm2 + + shll $2, %edx + +/* # %mm4 will always be already clear here */ +/* # pxor %mm4, %mm4 */ + + movl 16(%ebp),%edi + movl (%edi, %edx), %eax + movd (%edi, %edx), %mm5 + punpcklbw %mm4, %mm5 + shrl $24, %eax + movl $0x010101, %ecx + mull %ecx +/* + * mull destroyed %edx, need to reconstitute + */ + movl -24(%ebp),%edx + shll $2, %edx + + orl $0xff000000, %eax + movd %eax, %mm1 + punpcklbw %mm4, %mm1 + pmullw %mm5,%mm1 + + movl 20(%ebp),%edi + movl (%edi, %edx), %eax + movd (%edi, %edx), %mm5 + punpcklbw %mm4, %mm5 + shrl $24, %eax + movl $0x010101, %ecx + mull %ecx + orl $0xff000000, %eax + movd %eax, %mm3 + punpcklbw %mm4, %mm3 + pmullw %mm5,%mm3 + + psrlw $8,%mm1 + psrlw $8,%mm3 + + movl 8(%ebp),%edi + + jmp .loop + +.out: + movl %esi,%eax + emms + leal -40(%ebp),%esp + popl %ebx + popl %esi + popl %edi + movl %ebp,%esp + popl %ebp + ret diff --git a/libs/tk/ydk-pixbuf/pixops/composite_line_color_22_4a4_mmx.S b/libs/tk/ydk-pixbuf/pixops/composite_line_color_22_4a4_mmx.S new file mode 100644 index 0000000000..f72a8bf5d3 --- /dev/null +++ b/libs/tk/ydk-pixbuf/pixops/composite_line_color_22_4a4_mmx.S @@ -0,0 +1,251 @@ +/* + * Copyright (C) 2000 Red Hat, 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, see . + */ + .file "composite_line_color_22_4a4_mmx.S" + .version "01.01" +gcc2_compiled.: +.text + .align 16 + +#if !defined(__MINGW32__) && !defined(__CYGWIN__) && !defined(__INTERIX) + +/* Magic indicating no need for an executable stack */ +#if !defined __powerpc64__ && !defined __ia64__ +.section .note.GNU-stack; .previous +#endif + +.globl _pixops_composite_line_color_22_4a4_mmx + .type _pixops_composite_line_color_22_4a4_mmx,@function +_pixops_composite_line_color_22_4a4_mmx: + +#else + +.globl __pixops_composite_line_color_22_4a4_mmx +__pixops_composite_line_color_22_4a4_mmx: + +#endif +/* + * Arguments + * + * weights: 8(%ebp) + * p: 12(%ebp) %esi + * q1: 16(%ebp) + * q2: 20(%ebp) + * xstep: 24(%ebp) + * p_end: 28(%ebp) + * xinit: 32(%ebp) + * dest_x: 36(%ebp) + * check_shift: 40(%ebp) + * colors: 44(%ebp) + * +*/ + +/* + * Function call entry + */ + pushl %ebp + movl %esp,%ebp + subl $28,%esp + pushl %edi + pushl %esi + pushl %ebx +/* Locals: + * int x %ebx + * int x_scaled -24(%ebp) + */ + +/* + * Setup + */ +/* Initialize variables */ + movl 32(%ebp),%ebx + movl 32(%ebp),%edx + sarl $16,%edx + movl 12(%ebp),%esi + + movl %edx,-24(%ebp) + + cmpl 28(%ebp),%esi + jnb .out + +/* Load initial values into %mm1, %mm3 */ + shll $2, %edx + + pxor %mm4, %mm4 + + movl 16(%ebp),%edi + movl (%edi, %edx), %eax + movd (%edi, %edx), %mm5 + punpcklbw %mm4, %mm5 + shrl $24, %eax + movl $0x010101, %ecx + mull %ecx + orl $0xff000000, %eax + movd %eax, %mm1 + punpcklbw %mm4, %mm1 + pmullw %mm5,%mm1 + +/* + * mull destroyed %edx, need to reconstitute + */ + movl -24(%ebp),%edx + shll $2, %edx + + movl 20(%ebp),%edi + movl (%edi, %edx), %eax + movd (%edi, %edx), %mm5 + punpcklbw %mm4, %mm5 + shrl $24, %eax + movl $0x010101, %ecx + mull %ecx + orl $0xff000000, %eax + movd %eax, %mm3 + punpcklbw %mm4, %mm3 + pmullw %mm5,%mm3 + + psrlw $8,%mm1 + psrlw $8,%mm3 + + addl $65536,%ebx + movl %ebx,%edx + sarl $16,%edx + + jmp .newx + .p2align 4,,7 +.loop: +/* int x_index = (x & 0xf000) >> 12 */ + movl %ebx,%eax + andl $0xf000,%eax + shrl $7,%eax + + movq (%edi,%eax),%mm4 + pmullw %mm0,%mm4 + movq 8(%edi,%eax),%mm5 + pmullw %mm1,%mm5 + movq 16(%edi,%eax),%mm6 + movq 24(%edi,%eax),%mm7 + pmullw %mm2,%mm6 + pmullw %mm3,%mm7 + paddw %mm4, %mm5 + paddw %mm6, %mm7 + paddw %mm5, %mm7 + + movl $0xffff,%ecx + movd %ecx,%mm4 + psllq $48,%mm4 + movq %mm4,%mm6 + psubw %mm7,%mm4 + pand %mm6,%mm4 + + movq %mm4,%mm5 + psrlq $16,%mm4 + por %mm4,%mm5 + psrlq $32,%mm5 + por %mm4,%mm5 + + psrlw $8,%mm5 + + movl 36(%ebp),%eax + incl 36(%ebp) + + movl 40(%ebp),%ecx + shrl %cl,%eax + andl $1,%eax + + movl 44(%ebp),%ecx + movq (%ecx,%eax,8),%mm6 + + pmullw %mm6,%mm5 + +/* x += x_step; */ + addl 24(%ebp),%ebx +/* x_scale = x >> 16; */ + movl %ebx,%edx + sarl $16,%edx + + paddw %mm5,%mm7 + + psrlw $8,%mm7 + packuswb %mm7, %mm7 + movd %mm7,(%esi) + + addl $4, %esi + + cmpl %esi,28(%ebp) + je .out + + cmpl %edx,-24(%ebp) + je .loop + +.newx: + movl %edx,-24(%ebp) +/* + * Load the two new values into %mm1, %mm3, move old values into %mm0, %mm2 + */ + movq %mm1, %mm0 + movq %mm3, %mm2 + + shll $2, %edx + + pxor %mm4, %mm4 + + movl 16(%ebp),%edi + movl (%edi, %edx), %eax + movd (%edi, %edx), %mm5 + punpcklbw %mm4, %mm5 + shrl $24, %eax + movl $0x010101, %ecx + mull %ecx +/* + * mull destroyed %edx, need to reconstitute + */ + movl -24(%ebp),%edx + shll $2, %edx + + orl $0xff000000, %eax + movd %eax, %mm1 + punpcklbw %mm4, %mm1 + pmullw %mm5,%mm1 + + movl 20(%ebp),%edi + movl (%edi, %edx), %eax + movd (%edi, %edx), %mm5 + punpcklbw %mm4, %mm5 + shrl $24, %eax + movl $0x010101, %ecx + mull %ecx + orl $0xff000000, %eax + movd %eax, %mm3 + punpcklbw %mm4, %mm3 + pmullw %mm5,%mm3 + + psrlw $8,%mm1 + psrlw $8,%mm3 + + movl 8(%ebp),%edi + + jmp .loop + +.out: + movl %esi,%eax + emms + leal -40(%ebp),%esp + popl %ebx + popl %esi + popl %edi + movl %ebp,%esp + popl %ebp + ret diff --git a/libs/tk/ydk-pixbuf/pixops/have_mmx.S b/libs/tk/ydk-pixbuf/pixops/have_mmx.S new file mode 100644 index 0000000000..ce0bb00884 --- /dev/null +++ b/libs/tk/ydk-pixbuf/pixops/have_mmx.S @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2000 Red Hat, 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, see . + */ + .file "have_mmx.S" + .version "01.01" +gcc2_compiled.: +.text + .align 16 + +#if !defined(__MINGW32__) && !defined(__CYGWIN__) && !defined(__INTERIX) + +/* Magic indicating no need for an executable stack */ +#if !defined __powerpc64__ && !defined __ia64__ +.section .note.GNU-stack; .previous +#endif + +.globl _pixops_have_mmx + .type _pixops_have_mmx,@function +_pixops_have_mmx: + +#else + +.globl __pixops_have_mmx +__pixops_have_mmx: + +#endif + + push %ebx + +/* # Check if bit 21 in flags word is writeable */ + + pushfl + popl %eax + movl %eax,%ebx + xorl $0x00200000, %eax + pushl %eax + popfl + pushfl + popl %eax + + cmpl %eax, %ebx + + je .notfound + +/* # OK, we have CPUID */ + + movl $1, %eax + cpuid + + test $0x00800000, %edx + jz .notfound + + movl $1, %eax + jmp .out + +.notfound: + movl $0, %eax +.out: + popl %ebx + ret + diff --git a/libs/tk/ydk-pixbuf/pixops/pixbuf-transform-math.ltx b/libs/tk/ydk-pixbuf/pixops/pixbuf-transform-math.ltx new file mode 100644 index 0000000000..19e231308d --- /dev/null +++ b/libs/tk/ydk-pixbuf/pixops/pixbuf-transform-math.ltx @@ -0,0 +1,112 @@ +\documentclass{article} + +\begin{document} + +\title{Some image transform math} +\author{Owen Taylor} +\date{18 February 2003} +\maketitle + +\section{Basics} + +The transform process is composed of three steps; +first we reconstruct a continuous image from the +source data \(A_{i,j}\): +\[a(u,v) = \sum_{i = -\infty}^{\infty} \sum_{j = -\infty}^{\infty} A_{i,j}F\left( {u - i \atop v - j} \right) \] +Then we transform from destination coordinates to source coordinates: +\[b(x,y) = a\left(u(x,y) \atop v(x,y)\right) + = a\left(t_{00}x + t_{01}y + t_{02} \atop t_{10}x + t_{11}y + t_{12} \right)\] +Finally, we resample using a sampling function \(G\): +\[B_{x_0,y_0} = \int_{-\infty}^{\infty}\int_{-\infty}^{\infty} b(x,y)G\left( {x - x_0 \atop y - y_0} \right) dxdy\] +Putting all of these together: +\[B_{x_0,y_0} = +\int_{-\infty}^{\infty}\int_{-\infty}^{\infty} +\sum_{i = -\infty}^{\infty} \sum_{j = -\infty}^{\infty} A_{i,j} +F\left( {u(x,y) - i \atop v(x,y) - j} \right) +G\left( {x - x_0 \atop y - y_0} \right) dxdy\] +We can reverse the order of the integrals and the sums: +\[B_{x_0,y_0} = +\sum_{i = -\infty}^{\infty} \sum_{j = -\infty}^{\infty} A_{i,j} +\int_{-\infty}^{\infty}\int_{-\infty}^{\infty} +F\left( {u(x,y) - i \atop v(x,y) - j} \right) +G\left( {x - x_0 \atop y - y_0} \right) dxdy\] +Which shows that the destination pixel values are a linear combination of the +source pixel values. But the coefficents depend on \(x_0\) and \(y_0\). +To simplify this a bit, define: +\[i_0 = \lfloor u(x_0,y_0) \rfloor = \lfloor {t_{00}x_0 + t_{01}y_0 + t_{02}} \rfloor \] +\[j_0 = \lfloor v(x_0,y_0) \rfloor = \lfloor {t_{10}x_0 + t_{11}y_0 + t_{12}} \rfloor \] +\[\Delta_u = u(x_0,y_0) - i_0 = t_{00}x_0 + t_{01}y_0 + t_{02} - \lfloor {t_{00}x_0 + t_{01}y_0 + t_{02}} \rfloor \] +\[\Delta_v = v(x_0,y_0) - j_0 = t_{10}x_0 + t_{11}y_0 + t_{12} - \lfloor {t_{10}x_0 + t_{11}y_0 + t_{12}} \rfloor \] +Then making the transforms \(x' = x - x_0\), \(y' = y - x_0\), \(i' = i - i_0\), \(j' = j - x_0\) +\begin{eqnarray*} +F(u,v) & = & F\left( {t_{00}x + t_{01}y + t_{02} - i \atop t_{10}x + t_{11}y + t_{12} - j} \right)\\ + & = & F\left( {t_{00}(x'+x_0) + t_{01}(y'+y_0) + t_{02} - (i'+i_0) \atop + t_{10}(x'+x_0) + t_{11}(y'+y_0) + t_{12} - (j'+j_0)} \right) \\ + & = & F\left( {\Delta_u + t_{00}x' + t_{01}y' - i' \atop + \Delta_v + t_{10}x' + t_{11}y' - j'} \right) +\end{eqnarray*} +Using that, we can then reparameterize the sums and integrals and +define coefficients that depend only on \((\Delta_u,\Delta_v)\), +which we'll call the \emph{phase} at the point \((x_0,y_0)\): +\[ +B_{x_0,y_0} = +\sum_{i = -\infty}^{\infty} \sum_{j = -\infty}^{\infty} A_{i_0+i,j_0+j} C_{i,j}(\Delta_u,\Delta_v) +\] +\[ +C_{i,j}(\Delta_u,\Delta_v) = +\int_{-\infty}^{\infty}\int_{-\infty}^{\infty} +F\left( {\Delta_u + t_{00}x + t_{01}y - i \atop + \Delta_v + t_{10}x + t_{11}y - j} \right) +G\left( {x \atop y} \right) dxdy +\] +\section{Separability} +A frequent special case is when the reconstruction and sampling functions +are of the form: +\[F(u,v) = f(u)f(v)\] +\[G(x,y) = g(x)g(y)\] +If we also have a transform that is purely a scale and translation; +(\(t_{10} = 0\), \(t_{01} = 0\)), then we can separate +\(C_{i,j}(\Delta_u,\Delta_v)\) into the product of a \(x\) portion +and a \(y\) portion: +\[C_{i,j}(\Delta_u,\Delta_v) = c_{i}(\Delta_u) c_{j}(\Delta_v)\] +\[c_{i}(\Delta_u) = \int_{-\infty}^{\infty} f(\Delta_u + t_{00}x - i)g(x)dx\] +\[c_{j}(\Delta_v) = \int_{-\infty}^{\infty} f(\Delta_v + t_{11}y - j)g(y)dy\] + +\section{Some filters} +gdk-pixbuf provides 4 standard filters for scaling, under the names ``NEAREST'', +``TILES'', ``BILINEAR'', and ``HYPER''. All of turn out to be separable +as discussed in the previous section. +For ``NEAREST'' filter, the reconstruction function is simple replication +and the sampling function is a delta function\footnote{A delta function is an infinitely narrow spike, such that: +\[\int_{-\infty}^{\infty}\delta(x)f(x) = f(0)\]}: +\[f(t) = \cases{1, & if \(0 \le t \le 1\); \cr + 0, & otherwise}\] +\[g(t) = \delta(t - 0.5)\] +For ``TILES'', the reconstruction function is again replication, but we +replace the delta-function for sampling with a box filter: +\[f(t) = \cases{1, & if \(0 \le t \le 1\); \cr + 0, & otherwise}\] +\[g(t) = \cases{1, & if \(0 \le t \le 1\); \cr + 0, & otherwise}\] +The ``HYPER'' filter (in practice, it was originally intended to be +something else) uses bilinear interpolation for reconstruction and +a box filter for sampling: +\[f(t) = \cases{1 - |t - 0.5|, & if \(-0.5 \le t \le 1.5\); \cr + 0, & otherwise}\] +\[g(t) = \cases{1, & if \(0 \le t \le 1\); \cr + 0, & otherwise}\] +The ``BILINEAR'' filter is defined in a somewhat more complicated way; +the definition depends on the scale factor in the transform (\(t_{00}\) +or \(t_{01}]\). In the \(x\) direction, for \(t_{00} < 1\), it is +the same as for ``TILES'': +\[f_u(t) = \cases{1, & if \(0 \le t \le 1\); \cr + 0, & otherwise}\] +\[g_u(t) = \cases{1, & if \(0 \le t \le 1\); \cr + 0, & otherwise}\] +but for \(t_{10} > 1\), we use bilinear reconstruction and delta-function +sampling: +\[f_u(t) = \cases{1 - |t - 0.5|, & if \(-0.5 \le t \le 1.5\); \cr + 0, & otherwise}\] +\[g_u(t) = \delta(t - 0.5)\] +The behavior in the \(y\) direction depends in the same way on \(t_{11}\). +\end{document} \ No newline at end of file diff --git a/libs/tk/ydk-pixbuf/pixops/pixops-internal.h b/libs/tk/ydk-pixbuf/pixops/pixops-internal.h new file mode 100644 index 0000000000..6497c2424d --- /dev/null +++ b/libs/tk/ydk-pixbuf/pixops/pixops-internal.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2000 Red Hat, 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, see . + */ +#ifdef USE_MMX +guchar *_pixops_scale_line_22_33_mmx (guint32 weights[16][8], guchar *p, guchar *q1, guchar *q2, int x_step, guchar *p_stop, int x_init); +guchar *_pixops_composite_line_22_4a4_mmx (guint32 weights[16][8], guchar *p, guchar *q1, guchar *q2, int x_step, guchar *p_stop, int x_init); +guchar *_pixops_composite_line_color_22_4a4_mmx (guint32 weights[16][8], guchar *p, guchar *q1, guchar *q2, int x_step, guchar *p_stop, int x_init, int dest_x, int check_shift, int *colors); +int _pixops_have_mmx (void); +#endif + diff --git a/libs/tk/ydk-pixbuf/pixops/pixops.c b/libs/tk/ydk-pixbuf/pixops/pixops.c new file mode 100644 index 0000000000..993223ed07 --- /dev/null +++ b/libs/tk/ydk-pixbuf/pixops/pixops.c @@ -0,0 +1,2558 @@ +/* + * Copyright (C) 2000 Red Hat, Inc + * mediaLib integration Copyright (c) 2001-2007 Sun Microsystems, Inc. + * All rights reserved. (Brian Cameron, Dmitriy Demin, James Cheng, + * Padraig O'Briain) + * + * 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, see . + */ +#include "config.h" +#include +#include + +#include "pixops.h" +#include "pixops-internal.h" + +#define SUBSAMPLE_BITS 4 +#define SUBSAMPLE (1 << SUBSAMPLE_BITS) +#define SUBSAMPLE_MASK ((1 << SUBSAMPLE_BITS)-1) +#define SCALE_SHIFT 16 + +static void +_pixops_scale_real (guchar *dest_buf, + int render_x0, + int render_y0, + int render_x1, + int render_y1, + int dest_rowstride, + int dest_channels, + gboolean dest_has_alpha, + const guchar *src_buf, + int src_width, + int src_height, + int src_rowstride, + int src_channels, + gboolean src_has_alpha, + double scale_x, + double scale_y, + PixopsInterpType interp_type); + +typedef struct _PixopsFilter PixopsFilter; +typedef struct _PixopsFilterDimension PixopsFilterDimension; + +struct _PixopsFilterDimension +{ + int n; + double offset; + double *weights; +}; + +struct _PixopsFilter +{ + PixopsFilterDimension x; + PixopsFilterDimension y; + double overall_alpha; +}; + +typedef guchar *(*PixopsLineFunc) (int *weights, int n_x, int n_y, + guchar *dest, int dest_x, guchar *dest_end, + int dest_channels, int dest_has_alpha, + guchar **src, int src_channels, + gboolean src_has_alpha, int x_init, + int x_step, int src_width, int check_size, + guint32 color1, guint32 color2); +typedef void (*PixopsPixelFunc) (guchar *dest, int dest_x, int dest_channels, + int dest_has_alpha, int src_has_alpha, + int check_size, guint32 color1, + guint32 color2, + guint r, guint g, guint b, guint a); + +#ifdef USE_MEDIALIB +#include +#include +#include + +#ifdef HAVE_STRINGS_H +#include +#endif + +#ifdef HAVE_STRING_H +#include +#endif + +#if defined(HAVE_SYS_SYSTEMINFO_H) +#include +#elif defined(HAVE_SYS_SYSINFO_H) +#include +#endif + +static void pixops_medialib_composite (guchar *dest_buf, + int dest_width, + int dest_height, + int dest_rowstride, + int dest_channels, + int dest_has_alpha, + const guchar *src_buf, + int src_width, + int src_height, + int src_rowstride, + int src_channels, + int src_has_alpha, + int dest_x, + int dest_y, + int dest_region_width, + int dest_region_height, + double offset_x, + double offset_y, + double scale_x, + double scale_y, + PixopsInterpType interp_type, + int overall_alpha); + +static void pixops_medialib_scale (guchar *dest_buf, + int dest_width, + int dest_height, + int dest_rowstride, + int dest_channels, + int dest_has_alpha, + const guchar *src_buf, + int src_width, + int src_height, + int src_rowstride, + int src_channels, + int src_has_alpha, + int dest_x, + int dest_y, + int dest_region_width, + int dest_region_height, + double offset_x, + double offset_y, + double scale_x, + double scale_y, + PixopsInterpType interp_type); + +typedef struct _mlInterp mlInterp; + +struct _mlInterp +{ + double tx; + double ty; + PixopsFilter po_filter; + void *interp_table; +}; + +static gboolean medialib_initialized = FALSE; +static gboolean use_medialib = TRUE; + +/* + * Sun mediaLib(tm) support. + * + * http://www.sun.com/processors/vis/mlib.html + * + */ +static void +_pixops_use_medialib () +{ + char *mlib_version_string; + char sys_info[257]; + long count; + + medialib_initialized = TRUE; + + if (getenv ("GDK_DISABLE_MEDIALIB")) + { + use_medialib = FALSE; + return; + } + + /* + * The imaging functions we want to use were added in mediaLib version 2. + * So turn off mediaLib support if the user has an older version. + * mlib_version returns a string in this format: + * + * mediaLib:0210:20011101:v8plusa + * ^^^^^^^^ ^^^^ ^^^^^^^^ ^^^^^^^ + * libname vers build ISALIST identifier + * date (in this case sparcv8plus+vis) + * + * The first 2 digits of the version are the major version. The 3rd digit + * is the minor version, and the 4th digit is the micro version. So the + * above string corresponds to version 2.1.0. In the following test we only + * care about the major version. + */ + mlib_version_string = mlib_version (); + + count = sysinfo (SI_ARCHITECTURE, &sys_info[0], 257); + + if (count != -1) + { + if (strcmp (sys_info, "i386") == 0) + { + char *mlib_target_isa = &mlib_version_string[23]; + + /* + * For x86 processors mediaLib generic C implementation + * does not give any performance advantage so disable it + */ + if (strncmp (mlib_target_isa, "sse", 3) != 0) + { + use_medialib = FALSE; + return; + } + + /* + * For x86 processors use of libumem conflicts with + * mediaLib, so avoid using it. + */ + if (dlsym (RTLD_PROBE, "umem_alloc") != NULL) + { + use_medialib = FALSE; + return; + } + } + } + else + { + /* Failed to get system architecture, disable mediaLib anyway */ + use_medialib = FALSE; + return; + } +} +#endif + +static int +get_check_shift (int check_size) +{ + int check_shift = 0; + g_return_val_if_fail (check_size >= 0, 4); + + while (!(check_size & 1)) + { + check_shift++; + check_size >>= 1; + } + + return check_shift; +} + +static void +pixops_scale_nearest (guchar *dest_buf, + int render_x0, + int render_y0, + int render_x1, + int render_y1, + int dest_rowstride, + int dest_channels, + gboolean dest_has_alpha, + const guchar *src_buf, + int src_width, + int src_height, + int src_rowstride, + int src_channels, + gboolean src_has_alpha, + double scale_x, + double scale_y) +{ + int i; + int x; + int x_step = (1 << SCALE_SHIFT) / scale_x; + int y_step = (1 << SCALE_SHIFT) / scale_y; + int xmax, xstart, xstop, x_pos, y_pos; + const guchar *p; + +#define INNER_LOOP(SRC_CHANNELS,DEST_CHANNELS,ASSIGN_PIXEL) \ + xmax = x + (render_x1 - render_x0) * x_step; \ + xstart = MIN (0, xmax); \ + xstop = MIN (src_width << SCALE_SHIFT, xmax); \ + p = src + (CLAMP (x, xstart, xstop) >> SCALE_SHIFT) * SRC_CHANNELS; \ + while (x < xstart) \ + { \ + ASSIGN_PIXEL; \ + dest += DEST_CHANNELS; \ + x += x_step; \ + } \ + while (x < xstop) \ + { \ + p = src + (x >> SCALE_SHIFT) * SRC_CHANNELS; \ + ASSIGN_PIXEL; \ + dest += DEST_CHANNELS; \ + x += x_step; \ + } \ + x_pos = x >> SCALE_SHIFT; \ + p = src + CLAMP (x_pos, 0, src_width - 1) * SRC_CHANNELS; \ + while (x < xmax) \ + { \ + ASSIGN_PIXEL; \ + dest += DEST_CHANNELS; \ + x += x_step; \ + } + + for (i = 0; i < (render_y1 - render_y0); i++) + { + const guchar *src; + guchar *dest; + y_pos = ((i + render_y0) * y_step + y_step / 2) >> SCALE_SHIFT; + y_pos = CLAMP (y_pos, 0, src_height - 1); + src = src_buf + y_pos * src_rowstride; + dest = dest_buf + i * dest_rowstride; + + x = render_x0 * x_step + x_step / 2; + + if (src_channels == 3) + { + if (dest_channels == 3) + { + INNER_LOOP (3, 3, dest[0]=p[0];dest[1]=p[1];dest[2]=p[2]); + } + else + { + INNER_LOOP (3, 4, dest[0]=p[0];dest[1]=p[1];dest[2]=p[2];dest[3]=0xff); + } + } + else if (src_channels == 4) + { + if (dest_channels == 3) + { + INNER_LOOP (4, 3, dest[0]=p[0];dest[1]=p[1];dest[2]=p[2]); + } + else + { + guint32 *p32; + INNER_LOOP(4, 4, p32=(guint32*)dest;*p32=*((guint32*)p)); + } + } + } +} + +static void +pixops_composite_nearest (guchar *dest_buf, + int render_x0, + int render_y0, + int render_x1, + int render_y1, + int dest_rowstride, + int dest_channels, + gboolean dest_has_alpha, + const guchar *src_buf, + int src_width, + int src_height, + int src_rowstride, + int src_channels, + gboolean src_has_alpha, + double scale_x, + double scale_y, + int overall_alpha) +{ + int i; + int x; + int x_step = (1 << SCALE_SHIFT) / scale_x; + int y_step = (1 << SCALE_SHIFT) / scale_y; + int xmax, xstart, xstop, x_pos, y_pos; + const guchar *p; + unsigned int a0; + + for (i = 0; i < (render_y1 - render_y0); i++) + { + const guchar *src; + guchar *dest; + y_pos = ((i + render_y0) * y_step + y_step / 2) >> SCALE_SHIFT; + y_pos = CLAMP (y_pos, 0, src_height - 1); + src = src_buf + y_pos * src_rowstride; + dest = dest_buf + i * dest_rowstride; + + x = render_x0 * x_step + x_step / 2; + + INNER_LOOP(src_channels, dest_channels, + if (src_has_alpha) + a0 = (p[3] * overall_alpha) / 0xff; + else + a0 = overall_alpha; + + switch (a0) + { + case 0: + break; + case 255: + dest[0] = p[0]; + dest[1] = p[1]; + dest[2] = p[2]; + if (dest_has_alpha) + dest[3] = 0xff; + break; + default: + if (dest_has_alpha) + { + unsigned int w0 = 0xff * a0; + unsigned int w1 = (0xff - a0) * dest[3]; + unsigned int w = w0 + w1; + + dest[0] = (w0 * p[0] + w1 * dest[0]) / w; + dest[1] = (w0 * p[1] + w1 * dest[1]) / w; + dest[2] = (w0 * p[2] + w1 * dest[2]) / w; + dest[3] = w / 0xff; + } + else + { + unsigned int a1 = 0xff - a0; + unsigned int tmp; + + tmp = a0 * p[0] + a1 * dest[0] + 0x80; + dest[0] = (tmp + (tmp >> 8)) >> 8; + tmp = a0 * p[1] + a1 * dest[1] + 0x80; + dest[1] = (tmp + (tmp >> 8)) >> 8; + tmp = a0 * p[2] + a1 * dest[2] + 0x80; + dest[2] = (tmp + (tmp >> 8)) >> 8; + } + break; + } + ); + } +} + +static void +pixops_composite_color_nearest (guchar *dest_buf, + int render_x0, + int render_y0, + int render_x1, + int render_y1, + int dest_rowstride, + int dest_channels, + gboolean dest_has_alpha, + const guchar *src_buf, + int src_width, + int src_height, + int src_rowstride, + int src_channels, + gboolean src_has_alpha, + double scale_x, + double scale_y, + int overall_alpha, + int check_x, + int check_y, + int check_size, + guint32 color1, + guint32 color2) +{ + int i, j; + int x; + int x_step = (1 << SCALE_SHIFT) / scale_x; + int y_step = (1 << SCALE_SHIFT) / scale_y; + int r1, g1, b1, r2, g2, b2; + int check_shift = get_check_shift (check_size); + int xmax, xstart, xstop, x_pos, y_pos; + const guchar *p; + unsigned int a0; + + for (i = 0; i < (render_y1 - render_y0); i++) + { + const guchar *src; + guchar *dest; + y_pos = ((i + render_y0) * y_step + y_step / 2) >> SCALE_SHIFT; + y_pos = CLAMP (y_pos, 0, src_height - 1); + src = src_buf + y_pos * src_rowstride; + dest = dest_buf + i * dest_rowstride; + + x = render_x0 * x_step + x_step / 2; + + + if (((i + check_y) >> check_shift) & 1) + { + r1 = (color2 & 0xff0000) >> 16; + g1 = (color2 & 0xff00) >> 8; + b1 = color2 & 0xff; + + r2 = (color1 & 0xff0000) >> 16; + g2 = (color1 & 0xff00) >> 8; + b2 = color1 & 0xff; + } + else + { + r1 = (color1 & 0xff0000) >> 16; + g1 = (color1 & 0xff00) >> 8; + b1 = color1 & 0xff; + + r2 = (color2 & 0xff0000) >> 16; + g2 = (color2 & 0xff00) >> 8; + b2 = color2 & 0xff; + } + + j = 0; + INNER_LOOP(src_channels, dest_channels, + if (src_has_alpha) + a0 = (p[3] * overall_alpha + 0xff) >> 8; + else + a0 = overall_alpha; + + switch (a0) + { + case 0: + if (((j + check_x) >> check_shift) & 1) + { + dest[0] = r2; + dest[1] = g2; + dest[2] = b2; + } + else + { + dest[0] = r1; + dest[1] = g1; + dest[2] = b1; + } + break; + case 255: + dest[0] = p[0]; + dest[1] = p[1]; + dest[2] = p[2]; + break; + default: + { + unsigned int tmp; + if (((j + check_x) >> check_shift) & 1) + { + tmp = ((int) p[0] - r2) * a0; + dest[0] = r2 + ((tmp + (tmp >> 8) + 0x80) >> 8); + tmp = ((int) p[1] - g2) * a0; + dest[1] = g2 + ((tmp + (tmp >> 8) + 0x80) >> 8); + tmp = ((int) p[2] - b2) * a0; + dest[2] = b2 + ((tmp + (tmp >> 8) + 0x80) >> 8); + } + else + { + tmp = ((int) p[0] - r1) * a0; + dest[0] = r1 + ((tmp + (tmp >> 8) + 0x80) >> 8); + tmp = ((int) p[1] - g1) * a0; + dest[1] = g1 + ((tmp + (tmp >> 8) + 0x80) >> 8); + tmp = ((int) p[2] - b1) * a0; + dest[2] = b1 + ((tmp + (tmp >> 8) + 0x80) >> 8); + } + } + break; + } + + if (dest_channels == 4) + dest[3] = 0xff; + + j++; + ); + } +} +#undef INNER_LOOP + +static void +composite_pixel (guchar *dest, int dest_x, int dest_channels, int dest_has_alpha, + int src_has_alpha, int check_size, guint32 color1, guint32 color2, + guint r, guint g, guint b, guint a) +{ + if (dest_has_alpha) + { + unsigned int w0 = a - (a >> 8); + unsigned int w1 = ((0xff0000 - a) >> 8) * dest[3]; + unsigned int w = w0 + w1; + + if (w != 0) + { + dest[0] = (r - (r >> 8) + w1 * dest[0]) / w; + dest[1] = (g - (g >> 8) + w1 * dest[1]) / w; + dest[2] = (b - (b >> 8) + w1 * dest[2]) / w; + dest[3] = w / 0xff00; + } + else + { + dest[0] = 0; + dest[1] = 0; + dest[2] = 0; + dest[3] = 0; + } + } + else + { + dest[0] = (r + (0xff0000 - a) * dest[0]) / 0xff0000; + dest[1] = (g + (0xff0000 - a) * dest[1]) / 0xff0000; + dest[2] = (b + (0xff0000 - a) * dest[2]) / 0xff0000; + } +} + +static guchar * +composite_line (int *weights, int n_x, int n_y, + guchar *dest, int dest_x, guchar *dest_end, int dest_channels, int dest_has_alpha, + guchar **src, int src_channels, gboolean src_has_alpha, + int x_init, int x_step, int src_width, + int check_size, guint32 color1, guint32 color2) +{ + int x = x_init; + int i, j; + + while (dest < dest_end) + { + int x_scaled = x >> SCALE_SHIFT; + unsigned int r = 0, g = 0, b = 0, a = 0; + int *pixel_weights; + + pixel_weights = weights + ((x >> (SCALE_SHIFT - SUBSAMPLE_BITS)) & SUBSAMPLE_MASK) * n_x * n_y; + + for (i=0; i> 8); + unsigned int w1 = ((0xff0000 - a) >> 8) * dest[3]; + unsigned int w = w0 + w1; + + if (w != 0) + { + dest[0] = (r - (r >> 8) + w1 * dest[0]) / w; + dest[1] = (g - (g >> 8) + w1 * dest[1]) / w; + dest[2] = (b - (b >> 8) + w1 * dest[2]) / w; + dest[3] = w / 0xff00; + } + else + { + dest[0] = 0; + dest[1] = 0; + dest[2] = 0; + dest[3] = 0; + } + } + else + { + dest[0] = (r + (0xff0000 - a) * dest[0]) / 0xff0000; + dest[1] = (g + (0xff0000 - a) * dest[1]) / 0xff0000; + dest[2] = (b + (0xff0000 - a) * dest[2]) / 0xff0000; + } + + dest += dest_channels; + x += x_step; + } + + return dest; +} + +static guchar * +composite_line_22_4a4 (int *weights, int n_x, int n_y, + guchar *dest, int dest_x, guchar *dest_end, int dest_channels, int dest_has_alpha, + guchar **src, int src_channels, gboolean src_has_alpha, + int x_init, int x_step, int src_width, + int check_size, guint32 color1, guint32 color2) +{ + int x = x_init; + guchar *src0 = src[0]; + guchar *src1 = src[1]; + + g_return_val_if_fail (src_channels != 3, dest); + g_return_val_if_fail (src_has_alpha, dest); + + while (dest < dest_end) + { + int x_scaled = x >> SCALE_SHIFT; + unsigned int r, g, b, a, ta; + int *pixel_weights; + guchar *q0, *q1; + int w1, w2, w3, w4; + + q0 = src0 + x_scaled * 4; + q1 = src1 + x_scaled * 4; + + pixel_weights = (int *)((char *)weights + + ((x >> (SCALE_SHIFT - SUBSAMPLE_BITS - 4)) & (SUBSAMPLE_MASK << 4))); + + w1 = pixel_weights[0]; + w2 = pixel_weights[1]; + w3 = pixel_weights[2]; + w4 = pixel_weights[3]; + + a = w1 * q0[3]; + r = a * q0[0]; + g = a * q0[1]; + b = a * q0[2]; + + ta = w2 * q0[7]; + r += ta * q0[4]; + g += ta * q0[5]; + b += ta * q0[6]; + a += ta; + + ta = w3 * q1[3]; + r += ta * q1[0]; + g += ta * q1[1]; + b += ta * q1[2]; + a += ta; + + ta = w4 * q1[7]; + r += ta * q1[4]; + g += ta * q1[5]; + b += ta * q1[6]; + a += ta; + + dest[0] = ((0xff0000 - a) * dest[0] + r) >> 24; + dest[1] = ((0xff0000 - a) * dest[1] + g) >> 24; + dest[2] = ((0xff0000 - a) * dest[2] + b) >> 24; + dest[3] = a >> 16; + + dest += 4; + x += x_step; + } + + return dest; +} + +#ifdef USE_MMX +static guchar * +composite_line_22_4a4_mmx_stub (int *weights, int n_x, int n_y, guchar *dest, + int dest_x, guchar *dest_end, + int dest_channels, int dest_has_alpha, + guchar **src, int src_channels, + gboolean src_has_alpha, int x_init, + int x_step, int src_width, int check_size, + guint32 color1, guint32 color2) +{ + guint32 mmx_weights[16][8]; + int j; + + for (j=0; j<16; j++) + { + mmx_weights[j][0] = 0x00010001 * (weights[4*j] >> 8); + mmx_weights[j][1] = 0x00010001 * (weights[4*j] >> 8); + mmx_weights[j][2] = 0x00010001 * (weights[4*j + 1] >> 8); + mmx_weights[j][3] = 0x00010001 * (weights[4*j + 1] >> 8); + mmx_weights[j][4] = 0x00010001 * (weights[4*j + 2] >> 8); + mmx_weights[j][5] = 0x00010001 * (weights[4*j + 2] >> 8); + mmx_weights[j][6] = 0x00010001 * (weights[4*j + 3] >> 8); + mmx_weights[j][7] = 0x00010001 * (weights[4*j + 3] >> 8); + } + + return _pixops_composite_line_22_4a4_mmx (mmx_weights, dest, src[0], src[1], + x_step, dest_end, x_init); +} +#endif /* USE_MMX */ + +static void +composite_pixel_color (guchar *dest, int dest_x, int dest_channels, + int dest_has_alpha, int src_has_alpha, int check_size, + guint32 color1, guint32 color2, guint r, guint g, + guint b, guint a) +{ + int dest_r, dest_g, dest_b; + int check_shift = get_check_shift (check_size); + + if ((dest_x >> check_shift) & 1) + { + dest_r = (color2 & 0xff0000) >> 16; + dest_g = (color2 & 0xff00) >> 8; + dest_b = color2 & 0xff; + } + else + { + dest_r = (color1 & 0xff0000) >> 16; + dest_g = (color1 & 0xff00) >> 8; + dest_b = color1 & 0xff; + } + + dest[0] = ((0xff0000 - a) * dest_r + r) >> 24; + dest[1] = ((0xff0000 - a) * dest_g + g) >> 24; + dest[2] = ((0xff0000 - a) * dest_b + b) >> 24; + + if (dest_has_alpha) + dest[3] = 0xff; + else if (dest_channels == 4) + dest[3] = a >> 16; +} + +static guchar * +composite_line_color (int *weights, int n_x, int n_y, guchar *dest, + int dest_x, guchar *dest_end, int dest_channels, + int dest_has_alpha, guchar **src, int src_channels, + gboolean src_has_alpha, int x_init, int x_step, + int src_width, int check_size, guint32 color1, + guint32 color2) +{ + int x = x_init; + int i, j; + int check_shift = get_check_shift (check_size); + int dest_r1, dest_g1, dest_b1; + int dest_r2, dest_g2, dest_b2; + + g_return_val_if_fail (check_size != 0, dest); + + dest_r1 = (color1 & 0xff0000) >> 16; + dest_g1 = (color1 & 0xff00) >> 8; + dest_b1 = color1 & 0xff; + + dest_r2 = (color2 & 0xff0000) >> 16; + dest_g2 = (color2 & 0xff00) >> 8; + dest_b2 = color2 & 0xff; + + while (dest < dest_end) + { + int x_scaled = x >> SCALE_SHIFT; + unsigned int r = 0, g = 0, b = 0, a = 0; + int *pixel_weights; + + pixel_weights = weights + ((x >> (SCALE_SHIFT - SUBSAMPLE_BITS)) & SUBSAMPLE_MASK) * n_x * n_y; + + for (i=0; i> check_shift) & 1) + { + dest[0] = ((0xff0000 - a) * dest_r2 + r) >> 24; + dest[1] = ((0xff0000 - a) * dest_g2 + g) >> 24; + dest[2] = ((0xff0000 - a) * dest_b2 + b) >> 24; + } + else + { + dest[0] = ((0xff0000 - a) * dest_r1 + r) >> 24; + dest[1] = ((0xff0000 - a) * dest_g1 + g) >> 24; + dest[2] = ((0xff0000 - a) * dest_b1 + b) >> 24; + } + + if (dest_has_alpha) + dest[3] = 0xff; + else if (dest_channels == 4) + dest[3] = a >> 16; + + dest += dest_channels; + x += x_step; + dest_x++; + } + + return dest; +} + +#ifdef USE_MMX +static guchar * +composite_line_color_22_4a4_mmx_stub (int *weights, int n_x, int n_y, + guchar *dest, int dest_x, + guchar *dest_end, int dest_channels, + int dest_has_alpha, guchar **src, + int src_channels, gboolean src_has_alpha, + int x_init, int x_step, int src_width, + int check_size, guint32 color1, + guint32 color2) +{ + guint32 mmx_weights[16][8]; + int check_shift = get_check_shift (check_size); + int colors[4]; + int j; + + for (j=0; j<16; j++) + { + mmx_weights[j][0] = 0x00010001 * (weights[4*j] >> 8); + mmx_weights[j][1] = 0x00010001 * (weights[4*j] >> 8); + mmx_weights[j][2] = 0x00010001 * (weights[4*j + 1] >> 8); + mmx_weights[j][3] = 0x00010001 * (weights[4*j + 1] >> 8); + mmx_weights[j][4] = 0x00010001 * (weights[4*j + 2] >> 8); + mmx_weights[j][5] = 0x00010001 * (weights[4*j + 2] >> 8); + mmx_weights[j][6] = 0x00010001 * (weights[4*j + 3] >> 8); + mmx_weights[j][7] = 0x00010001 * (weights[4*j + 3] >> 8); + } + + colors[0] = (color1 & 0xff00) << 8 | (color1 & 0xff); + colors[1] = (color1 & 0xff0000) >> 16; + colors[2] = (color2 & 0xff00) << 8 | (color2 & 0xff); + colors[3] = (color2 & 0xff0000) >> 16; + + return _pixops_composite_line_color_22_4a4_mmx (mmx_weights, dest, src[0], + src[1], x_step, dest_end, x_init, dest_x, check_shift, colors); +} +#endif /* USE_MMX */ + +static void +scale_pixel (guchar *dest, int dest_x, int dest_channels, int dest_has_alpha, + int src_has_alpha, int check_size, guint32 color1, guint32 color2, + guint r, guint g, guint b, guint a) +{ + if (src_has_alpha) + { + if (a) + { + dest[0] = r / a; + dest[1] = g / a; + dest[2] = b / a; + dest[3] = a >> 16; + } + else + { + dest[0] = 0; + dest[1] = 0; + dest[2] = 0; + dest[3] = 0; + } + } + else + { + dest[0] = (r + 0xffffff) >> 24; + dest[1] = (g + 0xffffff) >> 24; + dest[2] = (b + 0xffffff) >> 24; + + if (dest_has_alpha) + dest[3] = 0xff; + } +} + +static guchar * +scale_line (int *weights, int n_x, int n_y, guchar *dest, int dest_x, + guchar *dest_end, int dest_channels, int dest_has_alpha, + guchar **src, int src_channels, gboolean src_has_alpha, int x_init, + int x_step, int src_width, int check_size, guint32 color1, + guint32 color2) +{ + int x = x_init; + int i, j; + + while (dest < dest_end) + { + int x_scaled = x >> SCALE_SHIFT; + int *pixel_weights; + + pixel_weights = weights + + ((x >> (SCALE_SHIFT - SUBSAMPLE_BITS)) & SUBSAMPLE_MASK) * n_x * n_y; + + if (src_has_alpha) + { + unsigned int r = 0, g = 0, b = 0, a = 0; + for (i=0; i> 16; + } + else + { + dest[0] = 0; + dest[1] = 0; + dest[2] = 0; + dest[3] = 0; + } + } + else + { + unsigned int r = 0, g = 0, b = 0; + for (i=0; i> 16; + dest[1] = (g + 0xffff) >> 16; + dest[2] = (b + 0xffff) >> 16; + + if (dest_has_alpha) + dest[3] = 0xff; + } + + dest += dest_channels; + + x += x_step; + } + + return dest; +} + +#ifdef USE_MMX +static guchar * +scale_line_22_33_mmx_stub (int *weights, int n_x, int n_y, guchar *dest, + int dest_x, guchar *dest_end, int dest_channels, + int dest_has_alpha, guchar **src, int src_channels, + gboolean src_has_alpha, int x_init, int x_step, + int src_width, int check_size, guint32 color1, + guint32 color2) +{ + guint32 mmx_weights[16][8]; + int j; + + for (j=0; j<16; j++) + { + mmx_weights[j][0] = 0x00010001 * (weights[4*j] >> 8); + mmx_weights[j][1] = 0x00010001 * (weights[4*j] >> 8); + mmx_weights[j][2] = 0x00010001 * (weights[4*j + 1] >> 8); + mmx_weights[j][3] = 0x00010001 * (weights[4*j + 1] >> 8); + mmx_weights[j][4] = 0x00010001 * (weights[4*j + 2] >> 8); + mmx_weights[j][5] = 0x00010001 * (weights[4*j + 2] >> 8); + mmx_weights[j][6] = 0x00010001 * (weights[4*j + 3] >> 8); + mmx_weights[j][7] = 0x00010001 * (weights[4*j + 3] >> 8); + } + + return _pixops_scale_line_22_33_mmx (mmx_weights, dest, src[0], src[1], + x_step, dest_end, x_init); +} +#endif /* USE_MMX */ + +static guchar * +scale_line_22_33 (int *weights, int n_x, int n_y, guchar *dest, int dest_x, + guchar *dest_end, int dest_channels, int dest_has_alpha, + guchar **src, int src_channels, gboolean src_has_alpha, + int x_init, int x_step, int src_width, + int check_size, guint32 color1, guint32 color2) +{ + int x = x_init; + guchar *src0 = src[0]; + guchar *src1 = src[1]; + + while (dest < dest_end) + { + unsigned int r, g, b; + int x_scaled = x >> SCALE_SHIFT; + int *pixel_weights; + guchar *q0, *q1; + int w1, w2, w3, w4; + + q0 = src0 + x_scaled * 3; + q1 = src1 + x_scaled * 3; + + pixel_weights = weights + + ((x >> (SCALE_SHIFT - SUBSAMPLE_BITS)) & SUBSAMPLE_MASK) * 4; + + w1 = pixel_weights[0]; + w2 = pixel_weights[1]; + w3 = pixel_weights[2]; + w4 = pixel_weights[3]; + + r = w1 * q0[0]; + g = w1 * q0[1]; + b = w1 * q0[2]; + + r += w2 * q0[3]; + g += w2 * q0[4]; + b += w2 * q0[5]; + + r += w3 * q1[0]; + g += w3 * q1[1]; + b += w3 * q1[2]; + + r += w4 * q1[3]; + g += w4 * q1[4]; + b += w4 * q1[5]; + + dest[0] = (r + 0x8000) >> 16; + dest[1] = (g + 0x8000) >> 16; + dest[2] = (b + 0x8000) >> 16; + + dest += 3; + x += x_step; + } + + return dest; +} + +static void +process_pixel (int *weights, int n_x, int n_y, guchar *dest, int dest_x, + int dest_channels, int dest_has_alpha, guchar **src, + int src_channels, gboolean src_has_alpha, int x_start, + int src_width, int check_size, guint32 color1, guint32 color2, + PixopsPixelFunc pixel_func) +{ + unsigned int r = 0, g = 0, b = 0, a = 0; + int i, j; + + for (i=0; i= 0 && c != 0 && remaining != 0; i--) + if (*(weights + i) + c >= 0) + { + *(weights + i) += c; + remaining -= c; + if ((0 < remaining && remaining < c) || + (0 > remaining && remaining > c)) + c = remaining; + } + } +} + +static int * +make_filter_table (PixopsFilter *filter) +{ + int i_offset, j_offset; + int n_x = filter->x.n; + int n_y = filter->y.n; + int *weights = g_new (int, SUBSAMPLE * SUBSAMPLE * n_x * n_y); + + for (i_offset=0; i_offset < SUBSAMPLE; i_offset++) + for (j_offset=0; j_offset < SUBSAMPLE; j_offset++) + { + double weight; + int *pixel_weights = weights + ((i_offset*SUBSAMPLE) + j_offset) * n_x * n_y; + int total = 0; + int i, j; + + for (i=0; i < n_y; i++) + for (j=0; j < n_x; j++) + { + weight = filter->x.weights[(j_offset * n_x) + j] * + filter->y.weights[(i_offset * n_y) + i] * + filter->overall_alpha * 65536 + 0.5; + + total += (int)weight; + + *(pixel_weights + n_x * i + j) = weight; + } + + correct_total (pixel_weights, n_x, n_y, total, filter->overall_alpha); + } + + return weights; +} + +static void +pixops_process (guchar *dest_buf, + int render_x0, + int render_y0, + int render_x1, + int render_y1, + int dest_rowstride, + int dest_channels, + gboolean dest_has_alpha, + const guchar *src_buf, + int src_width, + int src_height, + int src_rowstride, + int src_channels, + gboolean src_has_alpha, + double scale_x, + double scale_y, + int check_x, + int check_y, + int check_size, + guint32 color1, + guint32 color2, + PixopsFilter *filter, + PixopsLineFunc line_func, + PixopsPixelFunc pixel_func) +{ + int i, j; + int x, y; /* X and Y position in source (fixed_point) */ + + guchar **line_bufs; + int *filter_weights; + + int x_step; + int y_step; + + int check_shift; + int scaled_x_offset; + + int run_end_x; + int run_end_index; + + x_step = (1 << SCALE_SHIFT) / scale_x; /* X step in source (fixed point) */ + y_step = (1 << SCALE_SHIFT) / scale_y; /* Y step in source (fixed point) */ + + if (x_step == 0 || y_step == 0) + return; /* overflow, bail out */ + + line_bufs = g_new (guchar *, filter->y.n); + filter_weights = make_filter_table (filter); + + check_shift = check_size ? get_check_shift (check_size) : 0; + + scaled_x_offset = floor (filter->x.offset * (1 << SCALE_SHIFT)); + + /* Compute the index where we run off the end of the source buffer. The + * furthest source pixel we access at index i is: + * + * ((render_x0 + i) * x_step + scaled_x_offset) >> SCALE_SHIFT + filter->x.n - 1 + * + * So, run_end_index is the smallest i for which this pixel is src_width, + * i.e, for which: + * + * (i + render_x0) * x_step >= ((src_width - filter->x.n + 1) << SCALE_SHIFT) - scaled_x_offset + * + */ +#define MYDIV(a,b) ((a) > 0 ? (a) / (b) : ((a) - (b) + 1) / (b)) /* Division so that -1/5 = -1 */ + + run_end_x = (((src_width - filter->x.n + 1) << SCALE_SHIFT) - scaled_x_offset); + run_end_index = MYDIV (run_end_x + x_step - 1, x_step) - render_x0; + run_end_index = MIN (run_end_index, render_x1 - render_x0); + + y = render_y0 * y_step + floor (filter->y.offset * (1 << SCALE_SHIFT)); + for (i = 0; i < (render_y1 - render_y0); i++) + { + int dest_x; + int y_start = y >> SCALE_SHIFT; + int x_start; + int *run_weights = filter_weights + + ((y >> (SCALE_SHIFT - SUBSAMPLE_BITS)) & SUBSAMPLE_MASK) * + filter->x.n * filter->y.n * SUBSAMPLE; + guchar *new_outbuf; + guint32 tcolor1, tcolor2; + + guchar *outbuf = dest_buf + dest_rowstride * i; + guchar *outbuf_end = outbuf + dest_channels * (render_x1 - render_x0); + + if (((i + check_y) >> check_shift) & 1) + { + tcolor1 = color2; + tcolor2 = color1; + } + else + { + tcolor1 = color1; + tcolor2 = color2; + } + + for (j=0; jy.n; j++) + { + if (y_start < 0) + line_bufs[j] = (guchar *)src_buf; + else if (y_start < src_height) + line_bufs[j] = (guchar *)src_buf + src_rowstride * y_start; + else + line_bufs[j] = (guchar *)src_buf + src_rowstride * (src_height - 1); + + y_start++; + } + + dest_x = check_x; + x = render_x0 * x_step + scaled_x_offset; + x_start = x >> SCALE_SHIFT; + + while (x_start < 0 && outbuf < outbuf_end) + { + process_pixel (run_weights + ((x >> (SCALE_SHIFT - SUBSAMPLE_BITS)) & SUBSAMPLE_MASK) * (filter->x.n * filter->y.n), filter->x.n, filter->y.n, + outbuf, dest_x, dest_channels, dest_has_alpha, + line_bufs, src_channels, src_has_alpha, + x >> SCALE_SHIFT, src_width, + check_size, tcolor1, tcolor2, pixel_func); + + x += x_step; + x_start = x >> SCALE_SHIFT; + dest_x++; + outbuf += dest_channels; + } + + new_outbuf = (*line_func) (run_weights, filter->x.n, filter->y.n, + outbuf, dest_x, dest_buf + dest_rowstride * + i + run_end_index * dest_channels, + dest_channels, dest_has_alpha, + line_bufs, src_channels, src_has_alpha, + x, x_step, src_width, check_size, tcolor1, + tcolor2); + + dest_x += (new_outbuf - outbuf) / dest_channels; + + x = (dest_x - check_x + render_x0) * x_step + scaled_x_offset; + outbuf = new_outbuf; + + while (outbuf < outbuf_end) + { + process_pixel (run_weights + ((x >> (SCALE_SHIFT - SUBSAMPLE_BITS)) & SUBSAMPLE_MASK) * (filter->x.n * filter->y.n), filter->x.n, filter->y.n, + outbuf, dest_x, dest_channels, dest_has_alpha, + line_bufs, src_channels, src_has_alpha, + x >> SCALE_SHIFT, src_width, + check_size, tcolor1, tcolor2, pixel_func); + + x += x_step; + dest_x++; + outbuf += dest_channels; + } + + y += y_step; + } + + g_free (line_bufs); + g_free (filter_weights); +} + +/* Compute weights for reconstruction by replication followed by + * sampling with a box filter + */ +static void +tile_make_weights (PixopsFilterDimension *dim, + double scale) +{ + int n = ceil (1 / scale + 1); + double *pixel_weights = g_new (double, SUBSAMPLE * n); + int offset; + int i; + + dim->n = n; + dim->offset = 0; + dim->weights = pixel_weights; + + for (offset = 0; offset < SUBSAMPLE; offset++) + { + double x = (double)offset / SUBSAMPLE; + double a = x + 1 / scale; + + for (i = 0; i < n; i++) + { + if (i < x) + { + if (i + 1 > x) + *(pixel_weights++) = (MIN (i + 1, a) - x) * scale; + else + *(pixel_weights++) = 0; + } + else + { + if (a > i) + *(pixel_weights++) = (MIN (i + 1, a) - i) * scale; + else + *(pixel_weights++) = 0; + } + } + } +} + +/* Compute weights for a filter that, for minification + * is the same as 'tiles', and for magnification, is bilinear + * reconstruction followed by a sampling with a delta function. + */ +static void +bilinear_magnify_make_weights (PixopsFilterDimension *dim, + double scale) +{ + double *pixel_weights; + int n; + int offset; + int i; + + if (scale > 1.0) /* Linear */ + { + n = 2; + dim->offset = 0.5 * (1 / scale - 1); + } + else /* Tile */ + { + n = ceil (1.0 + 1.0 / scale); + dim->offset = 0.0; + } + + dim->n = n; + dim->weights = g_new (double, SUBSAMPLE * n); + + pixel_weights = dim->weights; + + for (offset=0; offset < SUBSAMPLE; offset++) + { + double x = (double)offset / SUBSAMPLE; + + if (scale > 1.0) /* Linear */ + { + for (i = 0; i < n; i++) + *(pixel_weights++) = (((i == 0) ? (1 - x) : x) / scale) * scale; + } + else /* Tile */ + { + double a = x + 1 / scale; + + /* x + * ---------|--.-|----|--.-|------- SRC + * ------------|---------|--------- DEST + */ + for (i = 0; i < n; i++) + { + if (i < x) + { + if (i + 1 > x) + *(pixel_weights++) = (MIN (i + 1, a) - x) * scale; + else + *(pixel_weights++) = 0; + } + else + { + if (a > i) + *(pixel_weights++) = (MIN (i + 1, a) - i) * scale; + else + *(pixel_weights++) = 0; + } + } + } + } +} + +/* Computes the integral from b0 to b1 of + * + * f(x) = x; 0 <= x < 1 + * f(x) = 0; otherwise + * + * We combine two of these to compute the convolution of + * a box filter with a triangular spike. + */ +static double +linear_box_half (double b0, double b1) +{ + double a0, a1; + double x0, x1; + + a0 = 0.; + a1 = 1.; + + if (a0 < b0) + { + if (a1 > b0) + { + x0 = b0; + x1 = MIN (a1, b1); + } + else + return 0; + } + else + { + if (b1 > a0) + { + x0 = a0; + x1 = MIN (a1, b1); + } + else + return 0; + } + + return 0.5 * (x1*x1 - x0*x0); +} + +/* Compute weights for reconstructing with bilinear + * interpolation, then sampling with a box filter + */ +static void +bilinear_box_make_weights (PixopsFilterDimension *dim, + double scale) +{ + int n = ceil (1/scale + 3.0); + double *pixel_weights = g_new (double, SUBSAMPLE * n); + double w; + int offset, i; + + dim->offset = -1.0; + dim->n = n; + dim->weights = pixel_weights; + + for (offset = 0; offset < SUBSAMPLE; offset++) + { + double x = (double)offset / SUBSAMPLE; + double a = x + 1 / scale; + + for (i = 0; i < n; i++) + { + w = linear_box_half (0.5 + i - a, 0.5 + i - x); + w += linear_box_half (1.5 + x - i, 1.5 + a - i); + + *(pixel_weights++) = w * scale; + } + } +} + +static void +make_weights (PixopsFilter *filter, + PixopsInterpType interp_type, + double scale_x, + double scale_y) +{ + switch (interp_type) + { + case PIXOPS_INTERP_NEAREST: + g_assert_not_reached (); + break; + + case PIXOPS_INTERP_TILES: + tile_make_weights (&filter->x, scale_x); + tile_make_weights (&filter->y, scale_y); + break; + + case PIXOPS_INTERP_BILINEAR: + bilinear_magnify_make_weights (&filter->x, scale_x); + bilinear_magnify_make_weights (&filter->y, scale_y); + break; + + case PIXOPS_INTERP_HYPER: + bilinear_box_make_weights (&filter->x, scale_x); + bilinear_box_make_weights (&filter->y, scale_y); + break; + } +} + +static void +_pixops_composite_color_real (guchar *dest_buf, + int render_x0, + int render_y0, + int render_x1, + int render_y1, + int dest_rowstride, + int dest_channels, + gboolean dest_has_alpha, + const guchar *src_buf, + int src_width, + int src_height, + int src_rowstride, + int src_channels, + gboolean src_has_alpha, + double scale_x, + double scale_y, + PixopsInterpType interp_type, + int overall_alpha, + int check_x, + int check_y, + int check_size, + guint32 color1, + guint32 color2) +{ + PixopsFilter filter; + PixopsLineFunc line_func; + +#ifdef USE_MMX + gboolean found_mmx = _pixops_have_mmx (); +#endif + + g_return_if_fail (!(dest_channels == 3 && dest_has_alpha)); + g_return_if_fail (!(src_channels == 3 && src_has_alpha)); + + if (scale_x == 0 || scale_y == 0) + return; + + if (interp_type == PIXOPS_INTERP_NEAREST) + { + pixops_composite_color_nearest (dest_buf, render_x0, render_y0, + render_x1, render_y1, dest_rowstride, + dest_channels, dest_has_alpha, src_buf, + src_width, src_height, src_rowstride, + src_channels, src_has_alpha, scale_x, + scale_y, overall_alpha, check_x, check_y, + check_size, color1, color2); + return; + } + + filter.overall_alpha = overall_alpha / 255.; + make_weights (&filter, interp_type, scale_x, scale_y); + +#ifdef USE_MMX + if (filter.x.n == 2 && filter.y.n == 2 && + dest_channels == 4 && src_channels == 4 && + src_has_alpha && !dest_has_alpha && found_mmx) + line_func = composite_line_color_22_4a4_mmx_stub; + else +#endif + line_func = composite_line_color; + + pixops_process (dest_buf, render_x0, render_y0, render_x1, render_y1, + dest_rowstride, dest_channels, dest_has_alpha, + src_buf, src_width, src_height, src_rowstride, src_channels, + src_has_alpha, scale_x, scale_y, check_x, check_y, check_size, color1, color2, + &filter, line_func, composite_pixel_color); + + g_free (filter.x.weights); + g_free (filter.y.weights); +} + +void +_pixops_composite_color (guchar *dest_buf, + int dest_width, + int dest_height, + int dest_rowstride, + int dest_channels, + gboolean dest_has_alpha, + const guchar *src_buf, + int src_width, + int src_height, + int src_rowstride, + int src_channels, + gboolean src_has_alpha, + int dest_x, + int dest_y, + int dest_region_width, + int dest_region_height, + double offset_x, + double offset_y, + double scale_x, + double scale_y, + PixopsInterpType interp_type, + int overall_alpha, + int check_x, + int check_y, + int check_size, + guint32 color1, + guint32 color2) +{ + guchar *new_dest_buf; + int render_x0; + int render_y0; + int render_x1; + int render_y1; + + if (!src_has_alpha && overall_alpha == 255) + { + _pixops_scale (dest_buf, dest_width, dest_height, dest_rowstride, + dest_channels, dest_has_alpha, src_buf, src_width, + src_height, src_rowstride, src_channels, src_has_alpha, + dest_x, dest_y, dest_region_width, dest_region_height, + offset_x, offset_y, scale_x, scale_y, interp_type); + return; + } + + new_dest_buf = dest_buf + dest_y * dest_rowstride + dest_x * + dest_channels; + render_x0 = dest_x - offset_x; + render_y0 = dest_y - offset_y; + render_x1 = dest_x + dest_region_width - offset_x; + render_y1 = dest_y + dest_region_height - offset_y; + + _pixops_composite_color_real (new_dest_buf, render_x0, render_y0, render_x1, + render_y1, dest_rowstride, dest_channels, + dest_has_alpha, src_buf, src_width, + src_height, src_rowstride, src_channels, + src_has_alpha, scale_x, scale_y, + (PixopsInterpType)interp_type, overall_alpha, + check_x, check_y, check_size, color1, color2); +} + +/** + * _pixops_composite_real: + * @dest_buf: pointer to location to store result + * @render_x0: x0 of region of scaled source to store into @dest_buf + * @render_y0: y0 of region of scaled source to store into @dest_buf + * @render_x1: x1 of region of scaled source to store into @dest_buf + * @render_y1: y1 of region of scaled source to store into @dest_buf + * @dest_rowstride: rowstride of @dest_buf + * @dest_channels: number of channels in @dest_buf + * @dest_has_alpha: whether @dest_buf has alpha + * @src_buf: pointer to source pixels + * @src_width: width of source (used for clipping) + * @src_height: height of source (used for clipping) + * @src_rowstride: rowstride of source + * @src_channels: number of channels in @src_buf + * @src_has_alpha: whether @src_buf has alpha + * @scale_x: amount to scale source by in X direction + * @scale_y: amount to scale source by in Y direction + * @interp_type: type of enumeration + * @overall_alpha: overall alpha factor to multiply source by + * + * Scale source buffer by scale_x / scale_y, then composite a given rectangle + * of the result into the destination buffer. + **/ +static void +_pixops_composite_real (guchar *dest_buf, + int render_x0, + int render_y0, + int render_x1, + int render_y1, + int dest_rowstride, + int dest_channels, + gboolean dest_has_alpha, + const guchar *src_buf, + int src_width, + int src_height, + int src_rowstride, + int src_channels, + gboolean src_has_alpha, + double scale_x, + double scale_y, + PixopsInterpType interp_type, + int overall_alpha) +{ + PixopsFilter filter; + PixopsLineFunc line_func; + +#ifdef USE_MMX + gboolean found_mmx = _pixops_have_mmx (); +#endif + + g_return_if_fail (!(dest_channels == 3 && dest_has_alpha)); + g_return_if_fail (!(src_channels == 3 && src_has_alpha)); + + if (scale_x == 0 || scale_y == 0) + return; + + if (interp_type == PIXOPS_INTERP_NEAREST) + { + pixops_composite_nearest (dest_buf, render_x0, render_y0, render_x1, + render_y1, dest_rowstride, dest_channels, + dest_has_alpha, src_buf, src_width, src_height, + src_rowstride, src_channels, src_has_alpha, + scale_x, scale_y, overall_alpha); + return; + } + + filter.overall_alpha = overall_alpha / 255.; + make_weights (&filter, interp_type, scale_x, scale_y); + + if (filter.x.n == 2 && filter.y.n == 2 && dest_channels == 4 && + src_channels == 4 && src_has_alpha && !dest_has_alpha) + { +#ifdef USE_MMX + if (found_mmx) + line_func = composite_line_22_4a4_mmx_stub; + else +#endif + line_func = composite_line_22_4a4; + } + else + line_func = composite_line; + + pixops_process (dest_buf, render_x0, render_y0, render_x1, render_y1, + dest_rowstride, dest_channels, dest_has_alpha, + src_buf, src_width, src_height, src_rowstride, src_channels, + src_has_alpha, scale_x, scale_y, 0, 0, 0, 0, 0, + &filter, line_func, composite_pixel); + + g_free (filter.x.weights); + g_free (filter.y.weights); +} + +void +_pixops_composite (guchar *dest_buf, + int dest_width, + int dest_height, + int dest_rowstride, + int dest_channels, + int dest_has_alpha, + const guchar *src_buf, + int src_width, + int src_height, + int src_rowstride, + int src_channels, + int src_has_alpha, + int dest_x, + int dest_y, + int dest_region_width, + int dest_region_height, + double offset_x, + double offset_y, + double scale_x, + double scale_y, + PixopsInterpType interp_type, + int overall_alpha) +{ + guchar *new_dest_buf; + int render_x0; + int render_y0; + int render_x1; + int render_y1; + + if (!src_has_alpha && overall_alpha == 255) + { + _pixops_scale (dest_buf, dest_width, dest_height, dest_rowstride, + dest_channels, dest_has_alpha, src_buf, src_width, + src_height, src_rowstride, src_channels, src_has_alpha, + dest_x, dest_y, dest_region_width, dest_region_height, + offset_x, offset_y, scale_x, scale_y, interp_type); + return; + } + +#ifdef USE_MEDIALIB + pixops_medialib_composite (dest_buf, dest_width, dest_height, dest_rowstride, + dest_channels, dest_has_alpha, src_buf, + src_width, src_height, src_rowstride, + src_channels, src_has_alpha, dest_x, dest_y, + dest_region_width, dest_region_height, offset_x, + offset_y, scale_x, scale_y, + (PixopsInterpType)interp_type, overall_alpha); + return; +#endif + + new_dest_buf = dest_buf + dest_y * dest_rowstride + dest_x * dest_channels; + render_x0 = dest_x - offset_x; + render_y0 = dest_y - offset_y; + render_x1 = dest_x + dest_region_width - offset_x; + render_y1 = dest_y + dest_region_height - offset_y; + + _pixops_composite_real (new_dest_buf, render_x0, render_y0, render_x1, + render_y1, dest_rowstride, dest_channels, + dest_has_alpha, src_buf, src_width, src_height, + src_rowstride, src_channels, src_has_alpha, scale_x, + scale_y, (PixopsInterpType)interp_type, + overall_alpha); +} + +#ifdef USE_MEDIALIB +static void +medialib_get_interpolation (mlInterp * ml_interp, + PixopsInterpType interp_type, + double scale_x, + double scale_y, + double overall_alpha) +{ + mlib_s32 leftPadding, topPadding; + ml_interp->interp_table = NULL; + + /* + * medialib 2.1 and later supports scaling with user-defined interpolation + * tables, so this logic is used. + * + * bilinear_magnify_make_weights builds an interpolation table of size 2x2 if + * the scale factor >= 1.0 and "ceil (1.0 + 1.0/scale)" otherwise. These map + * most closely to MLIB_BILINEAR, which uses an interpolation table of size + * 2x2. + * + * tile_make_weights builds an interpolation table of size 2x2 if the scale + * factor >= 1.0 and "ceil (1.0 + 1.0/scale)" otherwise. These map most + * closely to MLIB_BILINEAR, which uses an interpolation table of size 2x2. + * + * bilinear_box_make_weights builds an interpolation table of size 4x4 if the + * scale factor >= 1.0 and "ceil (1.0 + 1.0/scale)" otherwise. These map most + * closely to MLIB_BICUBIC, which uses an interpolation table of size 4x4. + * + * PIXOPS_INTERP_NEAREST calls pixops_scale_nearest which does not use an + * interpolation table. This maps to MLIB_NEAREST. + */ + switch (interp_type) + { + case PIXOPS_INTERP_BILINEAR: + bilinear_magnify_make_weights (&(ml_interp->po_filter.x), scale_x); + bilinear_magnify_make_weights (&(ml_interp->po_filter.y), scale_y); + leftPadding = 0; + topPadding = 0; + + if (scale_x <= 1.0) + ml_interp->tx = 0.5 * (1 - scale_x); + else + ml_interp->tx = 0.0; + + if (scale_y <= 1.0) + ml_interp->ty = 0.5 * (1 - scale_y); + else + ml_interp->ty = 0.0; + + break; + + case PIXOPS_INTERP_TILES: + tile_make_weights (&(ml_interp->po_filter.x), scale_x); + tile_make_weights (&(ml_interp->po_filter.y), scale_y); + leftPadding = 0; + topPadding = 0; + ml_interp->tx = 0.5 * (1 - scale_x); + ml_interp->ty = 0.5 * (1 - scale_y); + break; + + case PIXOPS_INTERP_HYPER: + bilinear_box_make_weights (&(ml_interp->po_filter.x), scale_x); + bilinear_box_make_weights (&(ml_interp->po_filter.y), scale_y); + leftPadding = 1; + topPadding = 1; + ml_interp->tx = 0.5 * (1 - scale_x); + ml_interp->ty = 0.5 * (1 - scale_y); + break; + + case PIXOPS_INTERP_NEAREST: + default: + /* + * Note that this function should not be called in the + * PIXOPS_INTERP_NEAREST case since it does not use an interpolation + * table. + */ + g_assert_not_reached (); + break; + } + + /* + * If overall_alpha is not 1.0, then multiply the vectors built by the + * sqrt (overall_alpha). This will cause overall_alpha to get evenly + * blended across both axis. + * + * Note there is no need to multiply the vectors built by the various + * make-weight functions by sqrt (overall_alpha) since the make-weight + * functions are called with overall_alpha hardcoded to 1.0. + */ + if (overall_alpha != 1.0) + { + double sqrt_alpha = sqrt (overall_alpha); + int i; + + for (i=0; i < SUBSAMPLE * ml_interp->po_filter.x.n; i++) + ml_interp->po_filter.x.weights[i] *= sqrt_alpha; + for (i=0; i < SUBSAMPLE * ml_interp->po_filter.y.n; i++) + ml_interp->po_filter.y.weights[i] *= sqrt_alpha; + } + + ml_interp->interp_table = (void *) mlib_ImageInterpTableCreate (MLIB_DOUBLE, + ml_interp->po_filter.x.n, ml_interp->po_filter.y.n, leftPadding, + topPadding, SUBSAMPLE_BITS, SUBSAMPLE_BITS, 8, + ml_interp->po_filter.x.weights, ml_interp->po_filter.y.weights); + + g_free (ml_interp->po_filter.x.weights); + g_free (ml_interp->po_filter.y.weights); +} + +static void +pixops_medialib_composite (guchar *dest_buf, + int dest_width, + int dest_height, + int dest_rowstride, + int dest_channels, + int dest_has_alpha, + const guchar *src_buf, + int src_width, + int src_height, + int src_rowstride, + int src_channels, + int src_has_alpha, + int dest_x, + int dest_y, + int dest_region_width, + int dest_region_height, + double offset_x, + double offset_y, + double scale_x, + double scale_y, + PixopsInterpType interp_type, + int overall_alpha) +{ + mlib_blend blend; + g_return_if_fail (!(dest_channels == 3 && dest_has_alpha)); + g_return_if_fail (!(src_channels == 3 && src_has_alpha)); + + if (scale_x == 0 || scale_y == 0) + return; + + if (!medialib_initialized) + _pixops_use_medialib (); + + if (!use_medialib) + { + /* Use non-mediaLib version */ + _pixops_composite_real (dest_buf + dest_y * dest_rowstride + dest_x * + dest_channels, dest_x - offset_x, dest_y - + offset_y, dest_x + dest_region_width - offset_x, + dest_y + dest_region_height - offset_y, + dest_rowstride, dest_channels, dest_has_alpha, + src_buf, src_width, src_height, src_rowstride, + src_channels, src_has_alpha, scale_x, scale_y, + interp_type, overall_alpha); + } + else + { + mlInterp ml_interp; + mlib_image img_src, img_dest; + double ml_offset_x, ml_offset_y; + + if (!src_has_alpha && overall_alpha == 255 && + dest_channels <= src_channels) + { + pixops_medialib_scale (dest_buf, dest_region_width, + dest_region_height, dest_rowstride, + dest_channels, dest_has_alpha, src_buf, + src_width, src_height, src_rowstride, + src_channels, src_has_alpha, dest_x, dest_y, + dest_region_width, dest_region_height, + offset_x, offset_y, scale_x, scale_y, + interp_type); + return; + } + + mlib_ImageSetStruct (&img_src, MLIB_BYTE, src_channels, + src_width, src_height, src_rowstride, src_buf); + + if (dest_x == 0 && dest_y == 0 && + dest_width == dest_region_width && + dest_height == dest_region_height) + { + mlib_ImageSetStruct (&img_dest, MLIB_BYTE, dest_channels, + dest_width, dest_height, dest_rowstride, + dest_buf); + } + else + { + mlib_u8 *data = dest_buf + (dest_y * dest_rowstride) + + (dest_x * dest_channels); + + mlib_ImageSetStruct (&img_dest, MLIB_BYTE, dest_channels, + dest_region_width, dest_region_height, + dest_rowstride, data); + } + + ml_offset_x = floor (offset_x) - dest_x; + ml_offset_y = floor (offset_y) - dest_y; + + if (interp_type == PIXOPS_INTERP_NEAREST) + { + blend = src_has_alpha ? MLIB_BLEND_GTK_SRC_OVER2 : MLIB_BLEND_GTK_SRC; + + mlib_ImageZoomTranslateBlend (&img_dest, + &img_src, + scale_x, + scale_y, + ml_offset_x, + ml_offset_y, + MLIB_NEAREST, + MLIB_EDGE_SRC_EXTEND_INDEF, + blend, + overall_alpha, + 1); + } + else + { + blend = src_has_alpha ? MLIB_BLEND_GTK_SRC_OVER : MLIB_BLEND_GTK_SRC; + + if (interp_type == PIXOPS_INTERP_BILINEAR && + scale_x > 1.0 && scale_y > 1.0) + { + mlib_ImageZoomTranslateBlend (&img_dest, + &img_src, + scale_x, + scale_y, + ml_offset_x, + ml_offset_y, + MLIB_BILINEAR, + MLIB_EDGE_SRC_EXTEND_INDEF, + blend, + overall_alpha, + 1); + } + else + { + medialib_get_interpolation (&ml_interp, interp_type, scale_x, + scale_y, overall_alpha/255.0); + + if (ml_interp.interp_table != NULL) + { + mlib_ImageZoomTranslateTableBlend (&img_dest, + &img_src, + scale_x, + scale_y, + ml_offset_x + ml_interp.tx, + ml_offset_y + ml_interp.ty, + ml_interp.interp_table, + MLIB_EDGE_SRC_EXTEND_INDEF, + blend, + 1); + mlib_ImageInterpTableDelete (ml_interp.interp_table); + } + else + { + /* Should not happen - Use non-mediaLib version */ + _pixops_composite_real (dest_buf + dest_y * dest_rowstride + + dest_x * dest_channels, + dest_x - offset_x, dest_y - offset_y, + dest_x + dest_region_width - offset_x, + dest_y + dest_region_height - offset_y, + dest_rowstride, dest_channels, + dest_has_alpha, src_buf, src_width, + src_height, src_rowstride, + src_channels, src_has_alpha, scale_x, + scale_y, interp_type, overall_alpha); + } + } + } + } +} +#endif + +static void +_pixops_scale_real (guchar *dest_buf, + int render_x0, + int render_y0, + int render_x1, + int render_y1, + int dest_rowstride, + int dest_channels, + gboolean dest_has_alpha, + const guchar *src_buf, + int src_width, + int src_height, + int src_rowstride, + int src_channels, + gboolean src_has_alpha, + double scale_x, + double scale_y, + PixopsInterpType interp_type) +{ + PixopsFilter filter; + PixopsLineFunc line_func; + +#ifdef USE_MMX + gboolean found_mmx = _pixops_have_mmx (); +#endif + + g_return_if_fail (!(dest_channels == 3 && dest_has_alpha)); + g_return_if_fail (!(src_channels == 3 && src_has_alpha)); + g_return_if_fail (!(src_has_alpha && !dest_has_alpha)); + + if (scale_x == 0 || scale_y == 0) + return; + + if (interp_type == PIXOPS_INTERP_NEAREST) + { + pixops_scale_nearest (dest_buf, render_x0, render_y0, render_x1, + render_y1, dest_rowstride, dest_channels, + dest_has_alpha, src_buf, src_width, src_height, + src_rowstride, src_channels, src_has_alpha, + scale_x, scale_y); + return; + } + + filter.overall_alpha = 1.0; + make_weights (&filter, interp_type, scale_x, scale_y); + + if (filter.x.n == 2 && filter.y.n == 2 && dest_channels == 3 && src_channels == 3) + { +#ifdef USE_MMX + if (found_mmx) + line_func = scale_line_22_33_mmx_stub; + else +#endif + line_func = scale_line_22_33; + } + else + line_func = scale_line; + + pixops_process (dest_buf, render_x0, render_y0, render_x1, render_y1, + dest_rowstride, dest_channels, dest_has_alpha, + src_buf, src_width, src_height, src_rowstride, src_channels, + src_has_alpha, scale_x, scale_y, 0, 0, 0, 0, 0, + &filter, line_func, scale_pixel); + + g_free (filter.x.weights); + g_free (filter.y.weights); +} + +void +_pixops_scale (guchar *dest_buf, + int dest_width, + int dest_height, + int dest_rowstride, + int dest_channels, + int dest_has_alpha, + const guchar *src_buf, + int src_width, + int src_height, + int src_rowstride, + int src_channels, + int src_has_alpha, + int dest_x, + int dest_y, + int dest_region_width, + int dest_region_height, + double offset_x, + double offset_y, + double scale_x, + double scale_y, + PixopsInterpType interp_type) +{ + guchar *new_dest_buf; + int render_x0; + int render_y0; + int render_x1; + int render_y1; + +#ifdef USE_MEDIALIB + pixops_medialib_scale (dest_buf, dest_width, dest_height, dest_rowstride, + dest_channels, dest_has_alpha, src_buf, src_width, + src_height, src_rowstride, src_channels, + src_has_alpha, dest_x, dest_y, dest_region_width, + dest_region_height, offset_x, offset_y, scale_x, + scale_y, (PixopsInterpType)interp_type); + return; +#endif + + new_dest_buf = dest_buf + dest_y * dest_rowstride + dest_x * dest_channels; + render_x0 = dest_x - offset_x; + render_y0 = dest_y - offset_y; + render_x1 = dest_x + dest_region_width - offset_x; + render_y1 = dest_y + dest_region_height - offset_y; + + _pixops_scale_real (new_dest_buf, render_x0, render_y0, render_x1, + render_y1, dest_rowstride, dest_channels, + dest_has_alpha, src_buf, src_width, src_height, + src_rowstride, src_channels, src_has_alpha, + scale_x, scale_y, (PixopsInterpType)interp_type); +} + +#ifdef USE_MEDIALIB +static void +pixops_medialib_scale (guchar *dest_buf, + int dest_width, + int dest_height, + int dest_rowstride, + int dest_channels, + int dest_has_alpha, + const guchar *src_buf, + int src_width, + int src_height, + int src_rowstride, + int src_channels, + int src_has_alpha, + int dest_x, + int dest_y, + int dest_region_width, + int dest_region_height, + double offset_x, + double offset_y, + double scale_x, + double scale_y, + PixopsInterpType interp_type) +{ + if (scale_x == 0 || scale_y == 0) + return; + + if (!medialib_initialized) + _pixops_use_medialib (); + + /* + * We no longer support mediaLib 2.1 because it has a core dumping problem + * in the mlib_ImageZoomTranslateTable function that has been corrected in + * 2.2. Although the mediaLib_zoom function could be used, it does not + * work properly if the source and destination images have different + * values for "has_alpha" or "num_channels". The complicated if-logic + * required to support both versions is not worth supporting + * mediaLib 2.1 moving forward. + */ + if (!use_medialib) + { + _pixops_scale_real (dest_buf + dest_y * dest_rowstride + dest_x * + dest_channels, dest_x - offset_x, dest_y - offset_y, + dest_x + dest_region_width - offset_x, + dest_y + dest_region_height - offset_y, + dest_rowstride, dest_channels, dest_has_alpha, + src_buf, src_width, src_height, src_rowstride, + src_channels, src_has_alpha, scale_x, scale_y, + interp_type); + } + else + { + mlInterp ml_interp; + mlib_image img_orig_src, img_src, img_dest; + double ml_offset_x, ml_offset_y; + guchar *tmp_buf = NULL; + + mlib_ImageSetStruct (&img_orig_src, MLIB_BYTE, src_channels, src_width, + src_height, src_rowstride, src_buf); + + if (dest_x == 0 && dest_y == 0 && + dest_width == dest_region_width && + dest_height == dest_region_height) + { + mlib_ImageSetStruct (&img_dest, MLIB_BYTE, dest_channels, + dest_width, dest_height, dest_rowstride, + dest_buf); + } + else + { + mlib_u8 *data = dest_buf + (dest_y * dest_rowstride) + + (dest_x * dest_channels); + + mlib_ImageSetStruct (&img_dest, MLIB_BYTE, dest_channels, + dest_region_width, dest_region_height, + dest_rowstride, data); + } + + ml_offset_x = floor (offset_x) - dest_x; + ml_offset_y = floor (offset_y) - dest_y; + + /* + * Note that zoomTranslate and zoomTranslateTable are faster + * than zoomTranslateBlend and zoomTranslateTableBlend. However + * the faster functions only work in the following case: + * + * if (src_channels == dest_channels && + * (!src_alpha && interp_table != PIXOPS_INTERP_NEAREST)) + * + * We use the faster versions if we can. + * + * Note when the interp_type is BILINEAR and the interpolation + * table will be size 2x2 (when both x/y scale factors > 1.0), + * then we do not bother building the interpolation table. In + * this case we can just use MLIB_BILINEAR, which is faster than + * using a specified interpolation table. + */ + img_src = img_orig_src; + + if (!src_has_alpha) + { + if (src_channels > dest_channels) + { + int channels = 3; + int rowstride = (channels * src_width + 3) & ~3; + + tmp_buf = g_malloc (src_rowstride * src_height); + + if (src_buf != NULL) + { + src_channels = channels; + src_rowstride = rowstride; + + mlib_ImageSetStruct (&img_src, MLIB_BYTE, src_channels, + src_width, src_height, src_rowstride, + tmp_buf); + mlib_ImageChannelExtract (&img_src, &img_orig_src, 0xE); + } + } + } + + if (interp_type == PIXOPS_INTERP_NEAREST) + { + if (src_channels == dest_channels) + { + mlib_ImageZoomTranslate (&img_dest, + &img_src, + scale_x, + scale_y, + ml_offset_x, + ml_offset_y, + MLIB_NEAREST, + MLIB_EDGE_SRC_EXTEND_INDEF); + } + else + { + mlib_ImageZoomTranslateBlend (&img_dest, + &img_src, + scale_x, + scale_y, + ml_offset_x, + ml_offset_y, + MLIB_NEAREST, + MLIB_EDGE_SRC_EXTEND_INDEF, + MLIB_BLEND_GTK_SRC, + 1.0, + 1); + } + } + else if (src_channels == dest_channels && !src_has_alpha) + { + if (interp_type == PIXOPS_INTERP_BILINEAR && + scale_x > 1.0 && scale_y > 1.0) + { + mlib_ImageZoomTranslate (&img_dest, + &img_src, + scale_x, + scale_y, + ml_offset_x, + ml_offset_y, + MLIB_BILINEAR, + MLIB_EDGE_SRC_EXTEND_INDEF); + } + else + { + medialib_get_interpolation (&ml_interp, interp_type, + scale_x, scale_y, 1.0); + + if (ml_interp.interp_table != NULL) + { + mlib_ImageZoomTranslateTable (&img_dest, + &img_src, + scale_x, + scale_y, + ml_offset_x + ml_interp.tx, + ml_offset_y + ml_interp.ty, + ml_interp.interp_table, + MLIB_EDGE_SRC_EXTEND_INDEF); + + mlib_ImageInterpTableDelete (ml_interp.interp_table); + } + else + { + /* Should not happen. */ + mlib_filter ml_filter; + + switch (interp_type) + { + case PIXOPS_INTERP_BILINEAR: + ml_filter = MLIB_BILINEAR; + break; + + case PIXOPS_INTERP_TILES: + ml_filter = MLIB_BILINEAR; + break; + + case PIXOPS_INTERP_HYPER: + ml_filter = MLIB_BICUBIC; + break; + } + + mlib_ImageZoomTranslate (&img_dest, + &img_src, + scale_x, + scale_y, + ml_offset_x, + ml_offset_y, + ml_filter, + MLIB_EDGE_SRC_EXTEND_INDEF); + } + } + } + + /* Deal with case where src_channels != dest_channels || src_has_alpha */ + else if (interp_type == PIXOPS_INTERP_BILINEAR && + scale_x > 1.0 && scale_y > 1.0) + { + mlib_ImageZoomTranslateBlend (&img_dest, + &img_src, + scale_x, + scale_y, + ml_offset_x, + ml_offset_y, + MLIB_BILINEAR, + MLIB_EDGE_SRC_EXTEND_INDEF, + MLIB_BLEND_GTK_SRC, + 1.0, + 1); + } + else + { + medialib_get_interpolation (&ml_interp, interp_type, + scale_x, scale_y, 1.0); + + if (ml_interp.interp_table != NULL) + { + mlib_ImageZoomTranslateTableBlend (&img_dest, + &img_src, + scale_x, + scale_y, + ml_offset_x + ml_interp.tx, + ml_offset_y + ml_interp.ty, + ml_interp.interp_table, + MLIB_EDGE_SRC_EXTEND_INDEF, + MLIB_BLEND_GTK_SRC, + 1); + mlib_ImageInterpTableDelete (ml_interp.interp_table); + } + else + { + mlib_filter ml_filter; + + switch (interp_type) + { + case PIXOPS_INTERP_BILINEAR: + ml_filter = MLIB_BILINEAR; + break; + + case PIXOPS_INTERP_TILES: + ml_filter = MLIB_BILINEAR; + break; + + case PIXOPS_INTERP_HYPER: + ml_filter = MLIB_BICUBIC; + break; + } + + mlib_ImageZoomTranslate (&img_dest, + &img_src, + scale_x, + scale_y, + ml_offset_x, + ml_offset_y, + ml_filter, + MLIB_EDGE_SRC_EXTEND_INDEF); + } + } + + if (tmp_buf != NULL) + g_free (tmp_buf); + } +} +#endif diff --git a/libs/tk/ydk-pixbuf/pixops/pixops.h b/libs/tk/ydk-pixbuf/pixops/pixops.h new file mode 100644 index 0000000000..d78bb6808a --- /dev/null +++ b/libs/tk/ydk-pixbuf/pixops/pixops.h @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2000 Red Hat, 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, see . + */ +#ifndef PIXOPS_H +#define PIXOPS_H + +#include + +/* Interpolation modes; must match GdkInterpType */ +typedef enum { + PIXOPS_INTERP_NEAREST, + PIXOPS_INTERP_TILES, + PIXOPS_INTERP_BILINEAR, + PIXOPS_INTERP_HYPER +} PixopsInterpType; + +/* Scale src_buf from src_width / src_height by factors scale_x, scale_y + * and composite the portion corresponding to + * render_x, render_y, render_width, render_height in the new + * coordinate system into dest_buf starting at 0, 0 + */ +void _pixops_composite (guchar *dest_buf, + int dest_width, + int dest_height, + int dest_rowstride, + int dest_channels, + int dest_has_alpha, + const guchar *src_buf, + int src_width, + int src_height, + int src_rowstride, + int src_channels, + int src_has_alpha, + int dest_x, + int dest_y, + int dest_region_width, + int dest_region_height, + double offset_x, + double offset_y, + double scale_x, + double scale_y, + PixopsInterpType interp_type, + int overall_alpha); + +/* Scale src_buf from src_width / src_height by factors scale_x, scale_y + * and composite the portion corresponding to + * render_x, render_y, render_width, render_height in the new + * coordinate system against a checkboard with checks of size check_size + * of the colors color1 and color2 into dest_buf starting at 0, 0 + */ +void _pixops_composite_color (guchar *dest_buf, + int dest_width, + int dest_height, + int dest_rowstride, + int dest_channels, + int dest_has_alpha, + const guchar *src_buf, + int src_width, + int src_height, + int src_rowstride, + int src_channels, + int src_has_alpha, + int dest_x, + int dest_y, + int dest_region_width, + int dest_region_height, + double offset_x, + double offset_y, + double scale_x, + double scale_y, + PixopsInterpType interp_type, + int overall_alpha, + int check_x, + int check_y, + int check_size, + guint32 color1, + guint32 color2); + +/* Scale src_buf from src_width / src_height by factors scale_x, scale_y + * and composite the portion corresponding to + * render_x, render_y, render_width, render_height in the new + * coordinate system into dest_buf starting at 0, 0 + */ +void _pixops_scale (guchar *dest_buf, + int dest_width, + int dest_height, + int dest_rowstride, + int dest_channels, + int dest_has_alpha, + const guchar *src_buf, + int src_width, + int src_height, + int src_rowstride, + int src_channels, + int src_has_alpha, + int dest_x, + int dest_y, + int dest_region_width, + int dest_region_height, + double offset_x, + double offset_y, + double scale_x, + double scale_y, + PixopsInterpType interp_type); +#endif diff --git a/libs/tk/ydk-pixbuf/pixops/scale_line_22_33_mmx.S b/libs/tk/ydk-pixbuf/pixops/scale_line_22_33_mmx.S new file mode 100644 index 0000000000..6080844c1a --- /dev/null +++ b/libs/tk/ydk-pixbuf/pixops/scale_line_22_33_mmx.S @@ -0,0 +1,204 @@ +/* + * Copyright (C) 2000 Red Hat, 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, see . + */ + .file "scale_line_22_33_mmx.S" + .version "01.01" +gcc2_compiled.: +.text + .align 16 + +#if !defined(__MINGW32__) && !defined(__CYGWIN__) && !defined(__INTERIX) + +/* Magic indicating no need for an executable stack */ +#if !defined __powerpc64__ && !defined __ia64__ +.section .note.GNU-stack; .previous +#endif + +.globl _pixops_scale_line_22_33_mmx + .type _pixops_scale_line_22_33_mmx,@function +_pixops_scale_line_22_33_mmx: + +#else + +.globl __pixops_scale_line_22_33_mmx +__pixops_scale_line_22_33_mmx: + +#endif +/* + * Arguments + * + * weights: 8(%ebp) + * p: 12(%ebp) %esi + * q1: 16(%ebp) + * q2: 20(%ebp) + * xstep: 24(%ebp) + * p_end: 28(%ebp) + * xinit: 32(%ebp) + * +*/ + +/* + * Function call entry + */ + pushl %ebp + movl %esp,%ebp + subl $28,%esp + pushl %edi + pushl %esi + pushl %ebx +/* Locals: + * int x %ebx + * int x_scaled -24(%ebp) + */ + +/* + * Setup + */ +/* Initialize variables */ + movl 32(%ebp),%ebx + movl 32(%ebp),%edx + sarl $16,%edx + movl 12(%ebp),%esi + + cmpl 28(%ebp),%esi + jnb .out + +/* For the body of this loop, %mm01, %mm1, %mm2, %mm3 hold the 4 adjoining + * points we are interpolating between, as: + * + * 000000BB00GG00RR + */ + +/* Load initial values into %mm1, %mm3 */ + leal (%edx,%edx,2),%edx # Multiply by 3 + + movl 16(%ebp),%edi + pxor %mm4, %mm4 + movzbl 2(%edi,%edx),%ecx + shll $16,%ecx + movzwl (%edi,%edx),%eax + orl %eax,%ecx + movd %ecx, %mm1 + punpcklbw %mm4, %mm1 + + movl 20(%ebp),%edi + movzbl 2(%edi,%edx),%ecx + shll $16,%ecx + movzwl (%edi,%edx),%eax + orl %eax,%ecx + movd %ecx, %mm3 + punpcklbw %mm4, %mm3 + + addl $65536,%ebx + movl %ebx,%edx + sarl $16,%edx + + jmp .newx + .p2align 4,,7 +.loop: +/* short *pixel_weights = weights + ((x >> (SCALE_SHIFT - SUBSAMPLE_BITS)) & SUBSAMPLE_MASK) * n_x * n_y + * 16 4 0xf 2 2 + */ + movl %ebx,%eax + andl $0xf000,%eax + shrl $7,%eax + +/* At this point, %edi holds weights. Load the 4 weights into %mm4,%mm5,%mm6,%mm7, multiply and + * accumulate. + */ + movq (%edi,%eax),%mm4 + pmullw %mm0,%mm4 + movq 8(%edi,%eax),%mm5 + pmullw %mm1,%mm5 + movq 16(%edi,%eax),%mm6 + movq 24(%edi,%eax),%mm7 + pmullw %mm2,%mm6 + pmullw %mm3,%mm7 + paddw %mm4, %mm5 + paddw %mm6, %mm7 + paddw %mm5, %mm7 + +/* %mm7 holds the accumulated sum. Compute (C + 0x80) / 256 + */ + pxor %mm4, %mm4 + movl $8421504, %eax # 0x00808080 + movd %eax, %mm6 + punpcklbw %mm4, %mm6 + paddw %mm6, %mm7 + psrlw $8, %mm7 + +/* Pack into %eax and store result + */ + packuswb %mm7, %mm7 + movd %mm7, %eax + + movb %al, (%esi) + shrl $8, %eax + movw %ax, 1(%esi) + addl $3, %esi + + cmpl %esi,28(%ebp) + je .out + +/* x += x_step; */ + addl 24(%ebp),%ebx +/* x_scaled = x >> 16; */ + movl %ebx,%edx + sarl $16,%edx + + cmpl %edx,-24(%ebp) + je .loop + +.newx: + movl %edx,-24(%ebp) +/* + * Load the two new values into %mm1, %mm3, move old values into %mm0, %mm2 + */ + movq %mm1, %mm0 + movq %mm3, %mm2 + + leal (%edx,%edx,2),%edx # Multiply by 3 + + movl 16(%ebp),%edi + movzbl 2(%edi,%edx),%ecx + shll $16,%ecx + movzwl (%edi,%edx),%eax + orl %eax,%ecx + movd %ecx, %mm1 + punpcklbw %mm4, %mm1 + + movl 20(%ebp),%edi + movzbl 2(%edi,%edx),%ecx + shll $16,%ecx + movzwl (%edi,%edx),%eax + orl %eax,%ecx + movd %ecx, %mm3 + punpcklbw %mm4, %mm3 + + movl 8(%ebp),%edi + + jmp .loop + +.out: + movl %esi,%eax + emms + leal -40(%ebp),%esp + popl %ebx + popl %esi + popl %edi + movl %ebp,%esp + popl %ebp + ret diff --git a/libs/tk/ydk-pixbuf/pixops/timescale b/libs/tk/ydk-pixbuf/pixops/timescale new file mode 100755 index 0000000000000000000000000000000000000000..63032619154e4dfd2f2693c284d027841d377066 GIT binary patch literal 84472 zcmeIb3tUr2+CM%g36KyjK|mm(A!t?N4N<(%t}j8nqo9DT+TDhW5s>@ER;ygRwc5C? zsdg{5yJ{7Ms9U?%7TWG=ZMC*_ZLQnx{&xFT)GAT5YC!=N`F)?069_?V-}c@A=lA*i zPug*2&YAPfJl}bqXJ($6bNKAmmAhVyaST5RLKwpDJQ-WVbVxB4f-n`qXq*){Wzzgf z$w_pz=Z}B5=cQgbqO$}Q7>%iu=BD<%%|Cyr=QSqe-Ef(Lhj80yEHf=B6EcWg>Ag3{ z&dl-!_A-hIkrblvTLogaA#-+v?dfiXjQ$}M(X}7la=68uekNV8R=qv4Qf!Zz}R_NE_lfM%a;Dk*xd^ z`2mP)CUR^XE<%3UECl-b3W4lj0D?2F$oBX};CZs$u0N7F9Rk^>$i<~4k$E{8kqegQ z3FeV$aGl!m-uU@{_^xGi#_Qt96Ega_ljaAD5yan8;9sW^kno{j3&U%Z4Xf1o`%1!Z|X z8`O&qM~bNUAvzfBo*F*ViL+jG*ci|m^8<8>3bLZc49EXnqS%`buk}Abrz~gT!r`O4 zsoX=JB|nBv-ZS~>z3CXhi9;{EC8W8KzX$5sGsB~V#`NZgbpD6>X;G0WtG7J&)Pr#_ zUp@68Woc=dDS!9`XB-BiHnJ!CU=Je@>xDeoNBTV^STs??+~`BS<0-3JPqxhNZ+8ekD=WI=@v@&F|^B&zKJwG>=kfha8>fn zxmC$6(!SPaX`r>`39h#JaaOBi>~mHWX$eBvu}HVBeALnw?`>&7I3o?RN@P{ZR2N&t zy7CIjOS!JR8-Kq$&++#qUH3bJ>G|$_JLRR)uKPFm``!8L{C!#1{VT|~eIU0qAUN7& z#oYsa@i z11=4kSUcT~S@bJ7i_x21zwz1hT0=QYRf4vWW7mm>m)lzPr9rY(B+AnIuuVrXxW23T9A3hPXsHf!fpRmo>@EgAV6yI6e<@KK{3 z4N|prB44kgjM_R4`2g_Vn&e(v>DkRMzJK?*9{ffSze%k9BJul#q5fhc_~I0UZNCN2 zkXtzyWVTHK9*`G49ZzX*d-_qLPcurlLe2LpyBIi8KmsT0tf&a-%{Z+LIunD>2 zk>`}38n}!+ z7TX|J+u*_FU-oAmyv|>XvZ%pR%hLw5!_e-vH2MzV9*k?7+?i!dA9npvb7$(sB-}S5 z4B~1p#v;z5v|u;b2#W&cxA?H)8pcvl*EM-Mv#_OQZFHTl=NHiycfKChZu_mFK0BO6 z8&Hlla28t-+tgXf)v|9{B!|$_A6R{4sJHpD`c|pjYHONNYg4lNo0Kk1)wdzO{kWn1 zc7LWnBTcH6#HDHbBeX*X&Pqe9=cJ+58))mduy5xZ4fPk$kIm@cmM0ADjff|>_pGlO z_1!db`c~M)+nJ!5lvLXw^|w0cI%pETJD_(S^ob_XigclM6FA-!+TYrr(-S?S)eIRu z<4SXvp`LG}6FrS9Jc^Xqm785yP@B7Hp9PN8-dlWssjcVH?%RBOHE3^$^&hTuLGupLEJc3-i&nI`IfeQw zpa&LRvH(23MIA)X!nZk~ z3un7b1X?lB_K;_y*+y;7q(0PGZ+oCm(e~R?R^QI|V+h)gF;KQ6-iJj0b}qF!q>I*B&^^avV5f5d?Is#4K%+q_vnZf@w&x7()1Zs` zGn_^5W@r!N6iuESOTC{R!gqlK$S(bCdlYkTdvvp}V2>UZ?2%w6zQJ{8J7EjMJf^=) z@30lO1zSNjqmAsucBZ!hXB%*C#vDL9Z2Z+=@2d1U+8Ph$iIB)mAv$Nr$a)*tHG! zqDwR($F0!k)+g+?ttE?ekL0&or*G%Ztaa#hPkW)Uw(+_bY+Z5>`psx}Ghqwb7q`Ry zQ{N4;%QMk$cdEld|0b`4eR=&R-ENcyThs4F8+09Zv<Pm%*^a6AsKbH#9pH0EkPosSG(U01hiJD$C(j}NmY;|Bwch0Aq^}?+fz}cC zq7NR3?k%+a7Respb{BgJ+hM2c4@^LpZ+Bl_=QS=gFG7E8z}z-Spv%kN1L&cR7eJHj zha9xXezXU6*^kfvr}iTSbEeX>oF!NCljk)1Vo_5d6E+}W#wo4^l^Ad**Yed~!eqx=xK482i z`%d`YPk$YAEE<~~wxOBl*WX(8zg0JHv%BqTw@vDv*EXX5c7)8ISf}0QcJoVf;G13Z zslHwFh&Fys65NG#&v7lp8vj%42iCVS&%aGJGb>ep=PHe6K#+Nb6C@ z_~6XvMP|3Vn*;7`cZa;tnM!lB#dkV`uOJuqMHm zHL>f^jaQsY+{pvkX2F|U+@4qt!Oa7(&JRdPSj%EWyg;wKSz ze!!i)l_dc^Dd@^T-wi%7_u7tCoP~T`c78@%%J^r%$BdDdT%^+^hK}?;hK`JWhK{pJ z)^Wyzbu>s>M>Kfd^ukCB$x=GX;V%d5`|9~I$oI8Uy`zyoP(k+tt@DVEJLvQUoq;{+ z(DSo#AAYfYt&8aSAZrTp^jrcx=ZWXkcy4g-=i+f6-`C$4981pyTPF$6ji={)@SGOU z4e$NjXxxv%b1`A`T!?in@;v{)9BCO&&yK{i6Yy+u?`H?%KJhr1j{~j!sQeg|pN#U4 z^)9dG%LQ4rLixT_{t=X)j`H(+m-pez1zY|%ZnH#uIJhbz1p!GVHUx@Ngq5QMG%U|Tn1zE2M<RN{7JrCi1kavuk-4pe1z8ugmaL|Z((i z{eq>+5jQ-_QiqlYYrGB(HD|!zIAL6xHjypSJ`*)+b3ZAIFY@qf zDH-x?T)Ng1`EBkjS|^47l70P!&D-`p2R|1hU#2wV&em0ulREIhA+$?Gc}Z4JuWH1I#YK3i{#bOWZq*C^AsluGr4kL?MGzNtUvb&;6g z0SnCO+8wmX7f5S_vshzn_s`Xz2W}UD8_k8kz+8AM?ByuP#@1DH+kOZ?J!GVHMB7+7 z?B3gqjlBqaB6nkctreVqZKv;;X`CkEVmxb)bz{Y!MzK_H_!|{k+ZQ_U%?0OZS#Y*? zFmTDOFl| zk9tRhA5+^np9H@sPfe@@dkcTwqP~c}j~K5?3FG{7xi>6o%%O7EzF&oy%Z)g+RxK}A z`5#7|^71j8$wwOj`nFMCdU+*$wvnv;0_MxN;Oo8pG^;1y@fEC7_QFqlYx|VigBU+< zKW(Tt41sKN8s+6(GxhQ)1^m4#|1h*o@%|R|Wwber^UAg5q8)FnRbND($jcQP@;yer zA7QqQnys(ldyS+oYMT2#8Y`%!g8PYWT`hG6Pp-|UgvFy(dUO~MwiR|58jm) z>o8V+$+6Mvq(RD9w6{veQneh533g*K9tsxoDCn)@3^58^Tjz!t*VicwF&MJ~*5Dbs zcaW(T8KBF0&O1R5-?%<}no`e6{66kKP3d^9`hz)jdd{uKeFfbY=;=9ik9!w&)0Frd zQUNm5>w_{4op`t@(DQ=gXjp8-y=xj^#zj8p$@v^;Os)yKMXA z4nEs?U)jc=2TDBv+3ti~r;%J=4;vQ@dGdffJpx+1T;m!q*CgMN>rujWdgi_|Ej)8y znHFf>SElj256VcVHR_i)BGgzp<;>4$j2!(%P9 z*V^OShhr@acKnCNhClfU&;4?ooz|=4_~&k5Y-^SJTCK2i)qZS~6?%UaHjopqJBN(Ym1kCe(=vcHrg>)2+U`r=Q1{W zF=Co099m?bCsZMxiZNtexqR~{b_3UzmsS&6g?6SFsm%6=TavVczg0uJ7f1 zl&=Z%1`UmeoR>09m^XwXe;4CWoEwXl-);QDmdV;%;w9Lpl~^2OdJ=r#)V3AjEVYy7 zFo2ze-S+efq&q7mwOGe&koyg?U|qC99~Z*UDc~Qn(42zyL2pz_^*8%V z^q2Z$eldj8H(=azo?OG6T(CV25nKQn|TPqHH=epQW}`$Ty#tXqDB=y*1U$2eHZ@ zeG=LGD!?EYosj3<-vcQHfEb9io-3^AUomiK(lRH^c> zluB}Q@hsuE3ph5vNI3fEp5M1hT`Bd;y@dVTYMGmI7y39x>R~pazJrjF{f8{-H_?x! zl7Ixtn>>%Jsb3FP2c>^+wHFUsHVAnVbdy356yhZBXgg;%Ex)WGFD|I&?g}lV# znxj0<0R-#>ZhU`$Z-3apzn7K2w8lNa{4)4i0}Pi*-IOMGe;!lv9d12z+I!m}gZBU> zv%H45Dt?PsX+P{mOZ=NS;CPw^G_3%weAwMnMay3zA6z5a)`DlN4xgU6;;><6G@f0F z*ct!R%)g0UhRwbcHrC`+FSTQU)DTlGVKDc2u? zFOa?l_te+Hkd=X?uh7+IURV8l=<36e7t%NQOahw6!jB~hFbA?g^E;5Q`BDV}>8iR* zSDT^F&q%c9gA#Sq;SqLS&HMpfy#=hBrS8@=$Vxh7FE*Z z8|mp07kzWqQ&VN)#_E=emq<_d`#9W_HoNnc4%dHi@iCH(Aq>e&K4 zEz_p#=k?UTOHX$SdU}-E_4Ej^bk@_m4n39no13Ah3t`J1q^DG#^mMuIILuBQdinZ>Z1WG7otm+zCw0(Mf9NUMSh5dPFSUd8^ayYzJv{&`WL6gFbaaL9BcvyVR{(_07LU#4jcYUX9yziSL?CYhdLm+8McjX~p_#voU@ zz5{v2yfA=bUaldt4!M3*;bvaO%e2NW(|wqw8RO3~^w~j)rb#j?^%gxBFUa&7;P{Oa z zGs~+O3$|eF`4qD0jW%z@*kd|sAA3lqPYE)8N|0&7-uc-zkmoIs?F3=`A-Qhhn%>>k3+842;*J%WTdq$_-J8y0Y&r@|j;fr;9<3Gg zw63vdCGc~MJzpvV_;CkgxbhpNznR9I9gyW}Va(ZyI19eG52fAX&KdCI7yFuZ^6{&#|QFBRA-5 zvQvlIB?M%B`OmW|G}DNMrXJq$~GePK9}fThj`DUKP?*g>j`?VyIs; zh1EIcPiEXBEF5;(w8&J~eIGK4`wsg{y6%wEBaV3z*41Qx--P|eoT!KWB{@CH>~h*= zfAhNMN%;Hj0Y{|)<`≺+yO*$?3C#oK{M@=SXzcu^P7bP0VFphHP#w@Y1A#-{0e` z?Jev*=)kiMJkO73*SDd~gc-Yzwu9g5$qs(~a*5xSkj)>OH_+M-f2H?Y_>M;`62!D# z^+X$bT*G?R&Gp)~M}#%(gXbk3-td91l3{JB#M;se^A>N+Uwkl+@x^>bg|($$Z3oUj zw(xe#9s1*jJ_7YhY0(FG&c;eb}XBXx@VycNoY$V+B6e$sTr6{CFG;6mhspxi}kgy zS-%|9?b8k&E38#V2y0cuQ{mH=ABr&B*P?0KnOK{x4UgH3GX(7ug!Sp;xR#Ces6<$w z`XC>{!Lul=Pvyv;!P?aJs8W9=lhvoO-u~@|6zpSRPrc1vq7V!nC@Yt~!v zd$(Y}8+&Zs{%+{+x#tq}bbjnxoMW~7yF;uVSg)pIy^6D|2{z0Z!?0#;8iccA(Ayzc z!^^RDWxRhrN9zS1yYt!b-!IXIVZBOcj^)*B)e5X*vpwKL-sP!ZTkfrKtYuYh8+!sNfR9Fw=jGv3m2x~Ef$=s*sx${<%nXylS50kz zFD8^@(Z_rYG4gV$Ca8SS=GMDur)(0rGN|0c-&QeInSHl2I;=xlj6ctvdJOH0Ks%11 z9TBMS80sUsb2>Vs2Vx#zgAMtzy)!!KSHUSKz)z&FA?5_y0(uFb!T`YNY`jzC5#Kmjd)|VI*jICjh(4<#-4bM!8qGPW}A)U?kSVaVdHq2eUMC( z%%ZLLlv%X9TW0-oKY<^7Ayq{ID!3u{Bj`QOE1vaw7Kfwmmo+JG4IMZQh@9Tv) ziF^eQ9^bsYgz>#7rfbaa8s8n)x_s0RrsW1&O+((pdrVw@OOgcRxfH%)W{JR@S%E-j zHDclaHF#irk|UNQ#`{ZWFbDNi6=)MeaNE7_(p39GMM z$!fQ_v*J(jyd2{VoySw$Z2W@S%OVzOX|FUajujt*-eTNI4kur!JYAciPuF6?Ne>+zyS=5ehoffcGAd?pPL&`NjmyFXC_>=EJ;j1q*PL z+XO$){mT8?jRi~#$=2%bfzJ-YM-6-=5*{DC1JeT^4%pf;O7FtRfc+W5s2?z*_d)vW zGkA>Bcz!aqtH)(%SIe`tG8c>-JiB7xj1kdr+@A!D(sU+m_3=#Yj&TcmVdRPjuNU!> zlMi|iu5l3d9xx|q!Tj(B=7-G~=WgM=-zl1%-CaEXC zmp&bHi{02uUl+=v$q#Whgr!;sP1Yy;N|iEeygX&%L#)qGq{kpV2x;0AkHDVzMJdiZ zK^~1BnAbpFt%L9mQ5dVYeiX02gmY?JHHP|aN<+H@Yl3r9_25fEbROGt@XSh2%@w?( zGP%5BjIny9+fBa*eS%*E*(B+cNmwXNN(`76=1oJI5+T0gGi$L=--IAqk zjD?yR))L?Het{rsF#J`ErWop`W6m0U%{Xq#Lx{1Ce{v~e_@*A47p$4jsg;aL%&TSW z`U>a(jSH<& zPpM}D)i>oKrACSNJh>Dx+Vj{v+Lpe58!m-yO*UXJ`=CU==o02`O;RuG4($J5!knQA z`(ix6_+D zM_)pp8~w0H4ZpadQkC)>==Ads$y1Wzyb?aq%2N{K`X*com8Z;%^GH~P>oek%37)u~ z5T{Cb9@nSG$r7%C);DLpCh^(K(`ol4WL^Dy2YTI2D;eS=|z|J6dv@9 zb2~mjJIHR`@4R0p_P>PnShPpved?%@!_GvUCeW7&MrnFo4vLHBXce++BCIXJK7 z&bOWRHE+^6V(fLES%v+p1lC>y9~`}RTZ8#M-dAjYvp@2&I3x5r&SO1_csJs)I7=lB zuB#b^JkE2~z#iESA|8V4@#;D}TW`w(EyyIj16c#z$C>l?8rTrpkF0@i+j3cZmAa~) z#=oJ!p$%i_%UIXHsy5VbtPIp-KN-xAk1K%V!?^$Es*tuSoHeY(__$Ttx9zR?fV$Sr ztiB0nRtOV18zoWYX*qdZSOoCc0y~!L4;i8HG#KmVRrA`$Dq!OR4ebXfu;Rnm`=jxJ z-sjB2SiJXU#VHQY|LObkQ@)@_;|azY%XF+|E92Ppv`1K~3T2D0EI;*3dFW<(Z|NLt zF0HRr*xSow{>pIXV-ADg(E!9`7l$P`z_75(}MSy zZ^BNV#hhl!Z}Vvu+Vno` zlN-)B=v&)*D$&WfZN0ZzV z#=CJ&i!jbbOc+N97+ZnoLFnnq2>zYfWG~?1jk!nxuzs<*oX1)PoT5c%J~9y<#_G=ji)=lMrgx7qp9s){pIGp52)skaz8C_Tq3f78S&YOV{8ck> z_Ad`Uey?Lg&BM@tSMd(TcL;im@R~=)WZNA7u6938DXv_3zzgUH|{L+w9QU zcMF!kM0&diXWRY+S$iFNyXWr2QzTQIk33P*A}y3cpZ%(s<%)!}?3D(#y(ZCodPVDH z-n%NGO&aWFhF>UP_o~O*NYAaS9Tc3p3(rEvEMH0dmAR1HMh4l%e)m@CV{IfaG)KVu(#gjwDmGRyFY_>omw7$T5Kx~7 zq0gzGX}*E89OiGNKA3ZaHtAr?hGH-I;iY+Z+`eUnYqYXNcf>8wgIgH;FXQ}#2l6U} zmnK*2-IQ3l_cxCj_Wth4xV_0QeV7!5unD0Q;VXm#2*DdaOln0O_0plFWQ0@QxK0j{#4>)h{qgXoHz&Z z=;KQg=OP|={OQExcg`e^efLb__v)7tHz6HGLA@#Q?}$q&ARU1F2atXf>FU*gPCUB$ zjl{;)`xBF=#O_r+`(|QF%E~>PBofPd=m^)|nR;Y(b>evhw`Z#ptLxrKe3K2-R!Re# z3^;#u8FuLw_8`t+{93cdaA%F&q;*4Zhi+DTO%Ag{H#cFvIURoSaKV1=fS!6|EoAt< zGj%BXrX85JAP6?duipE(I#$YxSE~)r=-_9*1)Yn7pYHDb^tx}PA-vAreI~qalO!Zz z3)wvA*A__#uXCHAbCf2XqxbcUO1sUR2c4Vm!A|~N&^e4Zye-`ORK-g)))Yd9U1gT+ znB6A&D#;#JVZBH8a1%f7C^2T(?F8Ay2^e$21>2YgJ0V3m*|Bgl(a3~+u7*9V#CWk4 z_e|KAczCJl&Ux^B0b_q7u)7fO{+^>7K1{0S!=a?38xAE+L7xsfzA$kz;(^CaiAU@*^IT!So>N=Az@>`%QdvqdWP1zbf(vewTu$H(0Z8eIi6W3@lUvj zbL6qGeV2gw0r+O=zVmhE82gxQ#kgc}Gjz~dVp=mZteO2-k=EeX^BOalw6)UII(@mn zCY=1$5$SLfEx~sL4E0ws4ehm@B4JPbyt;L93XD~L3HmsLAJq?=)MxsU_4D=cbL$~P zS69)QP~U`0*#Dc3IF|Fw)xYt)dNC!>0#W>G|OCP!GuVS8bxscUw!PsyK?+(e!JvAXH|2D#7 z2!lb_mO$5WHhH&O?HSDJ93!tl`t;u`{RD=U&&j;+R(QaJts9|JiJbOgqOy9rBEGS zz`15sO4~lz>WkPXQ}$Evyp(Zrb8WeohJ4bmuL^9d-5sHys$$WXW3k?Z-#a2dG=*@e zh3$>_IKo^5d)?HZ-Z4;Gn+px~cYq&1HvxS;_@F+M*Ty|F82iG4J|^R=c`}VHm&bDY zOOf>cTOe#psP#4US+#GGen*0cp!!}{K+IAsNmMcDhGc_h_Ebz)vbbI@d6xm@G7+)uN0)njdb z$D+)KDttDR4pYBGNqlkUOVOmmJnjs}^RtkFb5cLddE{0V%D62nYFjwbP`As=5OZ|7 zhlb8deG-8f>)cO=dT8jZ)bSB+n!hn`|C)Xx8D8yRf#gWCAfFN0J5iuU0QRRXo=lL&3EcK%P=cow$j4A#Wd$JE!< z=VV`Kd?uOV(B~5LIbC~w)tt7bu@h@A$3m9N+P4vP1hMCdk{Z zLcCuOowp5=>Zxy=alWw@{bz&D(fKBakD{Z?c>*ZXavKBN$^$JbRu57)WmtRE>`3*w*?=PG5o?hSs zWs}@C(SHUUSo-AfD-V>pB%4rR>1#7}|jMowHH)X>|)3Iz4+By+!jz`-kfQLBvD2~<$ zzLj2hJuKk$FW9F}DTlrGp1$}7Y1Me*O#z>9L`a&J>G0l=J_o*%Y%TfIIaP(0gTI`7 z1>sm1P6PJr>vV0v$#rV@4?6;|o^$riyU}-Jq=&}Cr_|oiKSw(gW87NuDdfTLfN=~y z&V5_@v0{nflW#)Zc)ve@=7+m;f7nk=XTWJJaQLaE_w-X&{>S~)o{P(0QhIrs8$9HR z;Y+7rL5cf9MuFDlG9j|oKAW! zE_SbF+R8oQt9SbB4ab}S<5C#s*^~yX?R{3DHDbQg&nrzkA-GaIL0+lNSi|mM{@}Mo z;+Y$cImDqG(n9Kom5?nOQ!im0h(JGhfv-j0Ugk64s~`BvUBN8!Q*uBH~_pYMA(I(5_q$KH|nRCzzg-$#`QaSo;I!DHGC8D zQK1-YW;48CW6N00^h_6iuv!})GO_{xN&+66tdhka5CRJf?WrLl! zHC~z8YVcK!elt1oMg0~JzGOFg@)FB+Wn+1Nd3R)3@JF^NL z{Ir6n;Ekt~=FE%T`*`}wJy>h^;>$y|NUKuW`SSD0(nhH(wNajx+F}>JK7wCmg9~4- z{dFCDjTHK86!La6@ibUm5yxmt z3LZgt6yX;LF`cF0r?g-h!m9`lewKl!R}tpr#O{5f7(S6_>w59!ugcX1Y_Rk7vQMe@ z0Qfopz81Uil>)vtx$x!MUpK(l7@@z$f}bS_^$2Q#uYZFt;^S+9kNCK_d_C^MS0Ki32hR?>PxIx=u!*$KqlDd`;jJ{k0QE@K(>hJJr8;gtk#2OZ>*HoAHr(0 z7JZHI2ZTQ&{18@~fz=;+VWs59Mt|TG0K6(OemKj(9Pk34CdLjWKQ=n}p>fgG2K`)_ zo~MOQB0PccON5^z(|(ZWK9Fk~51nUUH%X$DmuKn|K$MTJ# zn2R91jPM(TpEH(AF^|lm=Bf*Yc`{+}L-XX%L(>XQB7A{x z3gL(5$s;gN9x2R|bDh=zbiQ4Vy4mOX{2GAvdBd>|2nTQB;B5tXbF2esp6q8e^*WoiMq)pkCBNJHMYeE0Yq!h!EKXI(uP4c0$0D%S zgzXKB!@eQbg#FQ8+B2M}&(xaWPkt8R67~nMj}uAbRPy{B?WhUqm}`}4XHQNJ8|9gy zRShoHsywr`s@3dHBk0k%WWbu}T11A{?~w)CK96K-Bl@Lj_hRhAUQnd2Uyk-er0FcX zAM#UikFNg>*JgqKNS=O)RyBE6mMGUU!bvr{EJvuJ7~~#FI@W?*PL;s zb6vDPZ%O(qd<-0X40v}3z6ILf5A(*JsscXaF!*v6bOy<-X(i6V)%KsL->o#XFB)d3 zy$s*Mu=2!>dv8>{l*oCT^ARH9kGtx<{3T!Pqg|V1(4QF}r$6j%h*4qR{4i&T`M}K( zBSBhPA=P}SfS>arLrheKyXL5$Ax2gq)AaL1I?xc)-^X2ZBE%506VDFs_x2@X6B|lwzDyErieGGdDkb9_J?iHrh`^XI~28|Hy~m!@EM2k`Et8 zDc)z%!^cio#J4%lmBhjCahUgW;Oq$AoqxoF^Lhb%I`0t+d_^0=kK50QG}4(z>_v4f z>wbp58HH~m!e7$+yHS zIA_J`qn6|B7W!l$&WyX`%y=N$@jMGoD1x7M)*O{aRk3rk>h9C0iWtu8z^6QGw$n8k zuE`BC(`TyS2im!LddJhJ7RliY0>7C!t3Yiz44=3WXAGKf#*5BF?nXQcK7Tsvm4dyN zzQ;zHM`7RK=?X9YoYyBF_H$l%7Z0DNu1d!HOUVHUinn*L_FR4Vb6%vk zM4#%R`lw!yw$5nJ{&N#H00&itJmo3))`ReU?3)tLAys$}!`g2SkI$vS;9K#PdJ(XB zzF%qr;nQ^u*evRol0f)$T?00s0MF?ig{KyIv6#1@Tb1xRy@{Cij9qzt20YJ~f@i#6 z<>2{`;P(?_aLTN6#&Od*Z36Mf^9}xazQI57{UDx?p}q#_?7hC{bf++m|E3e^xNS(B zzG;v_|ACZ6&kUcQK)U-p_M)akU%i0I4EWEV=e&m)a3(W1JR!jwGGiX*t;tnO z@a>iaB`{ex0KP$7Qveg3=}%AqlePSr_)paMre;h8WKRy+n_6Cjv+;$e;aqy?wZOfg)cYFDTd7bRTQZEmhp|_1q&|eyYy*Ai}W3UbR&^;sG z%l)+vbQSS1oCUoCTagG`5xKnL)HT=++B?MAh-3)@WH$!Bw3uSFWj&`*W}x3P@t!Hw z@fx0WhfHJdI++v7({s;3_dhE4(0CjhWZnpzODmL{QM z#Qbxzp)RO0Nb|ezjpM%U6Ri22#1M1V6R|rmbPv{C$Jwe)5~UgY9Q+whoPEL>DPNqC zQt`Td@>XZ`YWYd^0!P7*4jiwcR1j9zrJ~`oVK;muQBJtzTdXev(>=V^T z^_F5>Dg`g4;Oi*!RUXCnofe`WRwIpXS)?pLe+&ZeMd**u!0ScGMJ&ha`(tm5`iAnW zFkgbdJK%ozym7A)zI#Q(!Q>q1jRS}6c#h6YpzoJfk_-y{P4w*Y=jzWt!jE(KHkTe} zPU~^@EV{|pP~Sx7Mirl`F>i^{Bj#-bV$#)Y$T!umY&h75zLQ3K4177HX^(*~i!|*q zQ29(@kHKL#!UR1Z0sp)T-`Qo7u&?;EyHgr}JEZG6{&q-L8h<;aE8W*At#(RloznfB z(gU5+gPqdDozf$n(qruDD6})`FlV_oCX_-bY^d%kp33wr-U@k`PK^QZ;-AL(sWkiEg}6+q)!OxFOmLQ zNPmHJ6Vh`^)3Z#E=t?uw^Gv!YN=q`0PvI( zGnE+gOi!8e#~5P^hyfbUJ%W6$*xAW?_C&VQEg8$t8;$d4(kkHlTFC0>yyg zQ41CLcck#ICmW^H;ro0D={lmq28_W?olc1CF-wV$n=#3AJpDXbeA3KWNh#A(g$phh zjqyn{l9KIZ`3LxaJlU*ibCYJJ7^fwsPD-9-oH}pTq-3U0DA3-LQbk!|S$dvAkzZ=c zERCc~ikU?@O8`jeHO3 zQLbl~3&nVO>MoUKDuY;X1T@CLd#%qFu&NKSIuYKKc8S8slQ_K_l)=$ZW>c8PiLO;1&oDxFqto7vM>$-F^3p!lVSXjN_DW7 zv+PZR?c#sjGs%owqUBUxVGQ4XU}Upqz+llYTWCC+=uO3MFT4H5{kI;! zlmA}visxqKt5_TVs9(lk>=-2q@mL|g{hs~$k0K%#5)lv)5D^d&5D^d&5D^d&5D^d& z5D^d&5D^d&5D^d&5D^d&5D^d&5D^d&5D^d&5D^d&5D^d&5D^d&5D^d&5D^d&5D^d& z5D^d&5D^d&5D^d&5D^d&5D^d&5D^d&5D^d&5D^d&5D^d&5D^d&5D^d&5D^d&5D^d& z_)!S7;kyR(Ed<%S_E;svp+X!X#L+@*5aJm^JXeSp2yu}RFBjsqLcB?ce^jHyLLvep z0wMw;0wMw;0wMw;0wMw;0wMw;0wMw;0wMw;0wMw;0wMw;0wMw;0wMw;0wMw;0wMw; z0wMw;0wMw;0wMw;0wMw;0wMw;0wMw;0wMw;0wMw;0wMw;0wMw;0wMw;0wMw;0wMw; z0wMw;0wMw;0wMw;0wMzcKSRK;UvO%F_9P247>&l#vh>VcV`g@)F>7&p$pSXJgl({2 zUtlUJDMDt!(!2#Iwm8F>kyC(+Y=eMTsVjwr={b40TPg?T^s>SnN~@4IEy*dPbTHBj zpDxKMGf_?#WH4qK7nYd#Tm+xXGL;!K7nhWn3d)RSIr;pZ5&WI}^t`;nOnPpdQ{GrW zR}B1>5>wgYk^*DSLL;@q_;h+nK~6yy-Jgnj^G*4sCcYK3x^l*%^s+KjNkP;YDm53^ zi%N0|$`(>CjdF|2GPBc(;nHk-wiIc6G{MM>gn#&-OJ!@o6aB%Cp`Ft4zLdCS;w z8$Pfg$t=t-Dl8>-{Yx{`^Gqz9N%FG+hbeP$naP-KN+&oKMLA0fi%N}bkc_>zo1QbW zNAuHj3fMfVgwe&V1CP1Y_MKx98)9{PFen{5(f_@Ps7G5%Rii_I#C)4|vU<-y-CHvCp1=N62q_!=67W z9a`7=U($pL%*dm%sTEqh)D{HVR--nQpeLjJ>gd;THHD;X<7>rjjhrMwqoON2bK z%$HN~ywm-@e4eqImGp$HElXc58?bO_-H{Sf*i1R_vhJdE&DY2Z=NH5z-Xi_s|POSg9Q zz9eX3*A2V+8F{VhVf1*D)#HlY4Dy%k7SL|W>_*ICz8r=NaW9jFYl5-rO2JGaeIEnm zFik@2WRx7{sLK#hqLlSA$i@YW^NWn>B_-)g8S2h88J{-gWM!i$a1cz8F)ydUX59M5>kwm758TRpu0zZNd9TJcy-=Kkl3 zx4-d7*yAjVE{yewv=*5MHWdAsMGFOr`*R6B;o6DbB^RK^{r>+~i>py+} z`>FY7A1NqG`tP`_$F$=#@@*a4J>DPq+o_L)W**6U?ZvY9zFYFX{E12VV-60Ezq(@j zfi1zShDitgA@`i@#=K>ZrDcSF&GtpV`bx{IZ|yzB1rFadcGwGV6#w;|yQcS>C;vO@ z;IE#JbdP@fYU7S)K3?-~(4-T;c=bk5^q(e;ID9u~&)?%0uc;6lh{`He7+qN&iekkwU>WSNe_q@G$ zPtr|~^Ev)|UEf2%t%eem>>YpcJ1#pBIB zTSI^I{G&Ib>s~%PBjlC;bp5wuu1_g!|J(OtpDMVeZ3tU7%gtJ}^y)V$5uYlbpL*lO H4#xg3KSkg* literal 0 HcmV?d00001 diff --git a/libs/tk/ydk-pixbuf/pixops/timescale.c b/libs/tk/ydk-pixbuf/pixops/timescale.c new file mode 100644 index 0000000000..1a1b59d5de --- /dev/null +++ b/libs/tk/ydk-pixbuf/pixops/timescale.c @@ -0,0 +1,265 @@ +/* + * Copyright (C) 2000 Red Hat, 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, see . + */ +#include "config.h" +#include +#include +#include +#include + +#include "pixops.h" + +static GTimeVal start_time; + +static void +start_timing (void) +{ + g_get_current_time (&start_time); +} + +static double +stop_timing (const char *test, int iterations, int bytes) +{ + GTimeVal stop_time; + double msecs; + + g_get_current_time (&stop_time); + if (stop_time.tv_usec < start_time.tv_usec) + { + stop_time.tv_usec += 1000000; + stop_time.tv_sec -= 1; + } + + msecs = (stop_time.tv_sec - start_time.tv_sec) * 1000. + + (stop_time.tv_usec - start_time.tv_usec) / 1000.; + + printf("%s%d\t%.1f\t\t%.2f\t\t%.2f\n", + test, iterations, msecs, msecs / iterations, ((double)bytes * iterations) / (1000*msecs)); + + return ((double)bytes * iterations) / (1000*msecs); +} + +static void +init_array (double times[3][3][4]) +{ + int i, j, k; + + for (i=0; i<3; i++) + for (j=0; j<3; j++) + for (k=0; k<4; k++) + times[i][j][k] = -1; +} + +static void +dump_array (double times[3][3][4]) +{ + int i, j; + + printf(" 3\t4\t4a\n"); + for (i=0; i<3; i++) + { + for (j=0; j<4; j++) + { + if (j == 0) + switch (i) + { + case 0: + printf("3 "); + break; + case 1: + printf("4 "); + break; + case 2: + printf("4a "); + break; + } + else + printf(" "); + + printf("%6.2f %6.2f %6.2f", + times[i][0][j], times[i][1][j], times[i][2][j]); + + switch (j) + { + case PIXOPS_INTERP_NEAREST: + printf (" NEAREST\n"); + break; + case PIXOPS_INTERP_TILES: + printf (" TILES\n"); + break; + case PIXOPS_INTERP_BILINEAR: + printf (" BILINEAR\n"); + break; + case PIXOPS_INTERP_HYPER: + printf (" HYPER\n"); + break; + } + } + } + printf("\n"); +} + +#define ITERS 10 + +int main (int argc, char **argv) +{ + int src_width, src_height, dest_width, dest_height; + unsigned char *src_buf, *dest_buf; + int src_index, dest_index; + int i; + double scale_times[3][3][4]; + double composite_times[3][3][4]; + double composite_color_times[3][3][4]; + + if (argc == 5) + { + src_width = atoi(argv[1]); + src_height = atoi(argv[2]); + dest_width = atoi(argv[3]); + dest_height = atoi(argv[4]); + } + else if (argc == 1) + { + src_width = 343; + src_height = 343; + dest_width = 711; + dest_height = 711; + } + else + { + fprintf (stderr, "Usage: scale [src_width src_height dest_width dest_height]\n"); + exit(1); + } + + + printf ("Scaling from (%d, %d) to (%d, %d)\n\n", src_width, src_height, dest_width, dest_height); + + init_array (scale_times); + init_array (composite_times); + init_array (composite_color_times); + + for (src_index = 0; src_index < 3; src_index++) + for (dest_index = 0; dest_index < 3; dest_index++) + { + int src_channels = (src_index == 0) ? 3 : 4; + int src_has_alpha = (src_index == 2); + int dest_channels = (dest_index == 0) ? 3 : 4; + int dest_has_alpha = (dest_index == 2); + + int src_rowstride = (src_channels*src_width + 3) & ~3; + int dest_rowstride = (dest_channels *dest_width + 3) & ~3; + + int filter_level; + + src_buf = g_malloc(src_rowstride * src_height); + memset (src_buf, 0x80, src_rowstride * src_height); + + dest_buf = g_malloc(dest_rowstride * dest_height); + memset (dest_buf, 0x80, dest_rowstride * dest_height); + + for (filter_level = PIXOPS_INTERP_NEAREST ; filter_level <= PIXOPS_INTERP_HYPER; filter_level++) + { + printf ("src_channels = %d (%s); dest_channels = %d (%s); filter_level=", + src_channels, src_has_alpha ? "alpha" : "no alpha", + dest_channels, dest_has_alpha ? "alpha" : "no alpha"); + switch (filter_level) + { + case PIXOPS_INTERP_NEAREST: + printf ("PIXOPS_INTERP_NEAREST\n"); + break; + case PIXOPS_INTERP_TILES: + printf ("PIXOPS_INTERP_TILES\n"); + break; + case PIXOPS_INTERP_BILINEAR: + printf ("PIXOPS_INTERP_BILINEAR\n"); + break; + case PIXOPS_INTERP_HYPER: + printf ("PIXOPS_INTERP_HYPER\n"); + break; + } + + printf("\t\t\titers\ttotal\t\tmsecs/iter\tMpixels/sec\t\n"); + + + if (!(src_has_alpha && !dest_has_alpha)) + { + start_timing (); + for (i = 0; i < ITERS; i++) + { + _pixops_scale (dest_buf, dest_width, dest_height, + dest_rowstride, dest_channels, + dest_has_alpha, src_buf, src_width, + src_height, src_rowstride, src_channels, + src_has_alpha, 0, 0, 0, 0, 0, 0, + (double)dest_width / src_width, + (double)dest_height / src_height, + filter_level); + } + scale_times[src_index][dest_index][filter_level] = + stop_timing (" scale\t\t", ITERS, dest_height * dest_width); + } + + start_timing (); + for (i = 0; i < ITERS; i++) + { + _pixops_composite (dest_buf, dest_width, dest_height, + dest_rowstride, dest_channels, + dest_has_alpha, src_buf, src_width, + src_height, src_rowstride, src_channels, + src_has_alpha, 0, 0, 0, 0, 0, 0, + (double)dest_width / src_width, + (double)dest_height / src_height, + filter_level, 255); + } + composite_times[src_index][dest_index][filter_level] = + stop_timing (" composite\t\t", ITERS, + dest_height * dest_width); + + start_timing (); + for (i = 0; i < ITERS; i++) + { + _pixops_composite_color (dest_buf, dest_width, dest_height, + dest_rowstride, dest_channels, + dest_has_alpha, src_buf, src_width, + src_height, src_rowstride, + src_channels, src_has_alpha, 0, 0, + 0, 0, 0, 0, + (double)dest_width / src_width, + (double)dest_height / src_height, + filter_level, 255, 0, 0, 16, + 0xaaaaaa, 0x555555); + } + composite_color_times[src_index][dest_index][filter_level] = + stop_timing (" composite color\t", ITERS, dest_height * dest_width); + + printf ("\n"); + } + printf ("\n"); + + g_free (src_buf); + g_free (dest_buf); + } + + printf ("SCALE\n=====\n\n"); + dump_array (scale_times); + + printf ("COMPOSITE\n=========\n\n"); + dump_array (composite_times); + + printf ("COMPOSITE_COLOR\n===============\n\n"); + dump_array (composite_color_times); + return 0; +} diff --git a/libs/tk/ydk-pixbuf/wscript b/libs/tk/ydk-pixbuf/wscript new file mode 100644 index 0000000000..0d7f7739f7 --- /dev/null +++ b/libs/tk/ydk-pixbuf/wscript @@ -0,0 +1,65 @@ +#!/usr/bin/env python +from waflib.extras import autowaf as autowaf +import sys + +# Version of this package (even if built as a child) +MAJOR = '2' +MINOR = '31' +MICRO = '1' +LIBYDKPIXBUF_VERSION = "%s.%s.%s" % (MAJOR, MINOR, MICRO) + +I18N_PACKAGE = 'libydk-pixbuf' + +libydkpixbuf_sources = [ + 'gdk-pixbuf-animation.c', + 'gdk-pixbuf-data.c', + 'gdk-pixbuf-enum-types.c', + 'gdk-pixbuf-io.c', + 'gdk-pixbuf-loader.c', + 'gdk-pixbuf-scale.c', + 'gdk-pixbuf-scaled-anim.c', + 'gdk-pixbuf-simple-anim.c', + 'gdk-pixbuf-util.c', + 'gdk-pixbuf.c', + 'gdk-pixdata.c', + 'io-pixdata.c', + 'io-png.c', + 'io-xbm.c', + 'io-xpm.c', + 'pixops/pixops.c' +] + +def options(opt): + pass + +def configure(conf): + if conf.is_defined('YTK'): + autowaf.check_pkg(conf, 'glib-2.0', uselib_store='GLIB', atleast_version='2.28', mandatory=True) + autowaf.check_pkg(conf, 'gio-2.0', uselib_store='GIO', atleast_version='2.2', mandatory=True) + autowaf.check_pkg(conf, 'gobject-2.0', uselib_store='GOBJECT', mandatory=True) + autowaf.check_pkg(conf, 'libpng', uselib_store='LIBPNG', mandatory=True) + +def build(bld): + if not bld.is_defined('YTK'): + return + + obj = bld.shlib(features = 'c cshlib', source=libydkpixbuf_sources) + obj.cflags = [ bld.env['compiler_flags_dict']['pic'] ] + obj.export_includes = ['ydk-pixbuf'] + obj.includes = ['.', 'ydk-pixbuf', 'ydk-pixbuf/gdk-pixbuf'] + obj.name = 'libydk-pixbuf' + obj.target = 'ydk-pixbuf' + obj.use = '' + obj.uselib = 'GLIB GIO GOBJECT LIBPNG' + obj.defines = [ 'HAVE_CONFIG_H', '_LARGEFILE64_SOURCE', '_REENTRANT', 'G_LOG_DOMAIN="GdkPixbuf"', 'DGDK_PIXBUF_COMPILATION', '_FILE_OFFSET_BITS=64', + 'GDK_PIXBUF_ENABLE_BACKEND', 'G_DISABLE_SINGLE_INCLUDES', + 'INCLUDE_png', 'INCLUDE_xbm', 'INCLUDE_xpm', + 'PACKAGE="' + I18N_PACKAGE + '"', 'GDK_PIXBUF_LOCALEDIR=""' + + ] + obj.vnum = LIBYDKPIXBUF_VERSION + obj.install_path = bld.env['LIBDIR'] + + if sys.platform == 'darwin': + obj.uselib += ' OSX' + obj.ldflags = ' -lintl' diff --git a/libs/tk/ydk-pixbuf/ydk-pixbuf/gdk-pixbuf/gdk-pixbuf-animation.h b/libs/tk/ydk-pixbuf/ydk-pixbuf/gdk-pixbuf/gdk-pixbuf-animation.h new file mode 100644 index 0000000000..36b35801bd --- /dev/null +++ b/libs/tk/ydk-pixbuf/ydk-pixbuf/gdk-pixbuf/gdk-pixbuf-animation.h @@ -0,0 +1,204 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ +/* GdkPixbuf library - Animation support + * + * Copyright (C) 1999 The Free Software Foundation + * + * Authors: Mark Crichton + * Miguel de Icaza + * Federico Mena-Quintero + * Havoc Pennington + * + * 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, see . + */ + +#ifndef GDK_PIXBUF_ANIMATION_H +#define GDK_PIXBUF_ANIMATION_H + +#if defined(GDK_PIXBUF_DISABLE_SINGLE_INCLUDES) && !defined (GDK_PIXBUF_H_INSIDE) && !defined (GDK_PIXBUF_COMPILATION) +#error "Only can be included directly." +#endif + +#include +#include + +G_BEGIN_DECLS + +/* Animation support */ + +/** + * GdkPixbufAnimation: + * + * An opaque struct representing an animation. + */ +typedef struct _GdkPixbufAnimation GdkPixbufAnimation; + + +/** + * GdkPixbufAnimationIter: + * + * An opaque struct representing an iterator which points to a + * certain position in an animation. + */ +typedef struct _GdkPixbufAnimationIter GdkPixbufAnimationIter; + +#define GDK_TYPE_PIXBUF_ANIMATION (gdk_pixbuf_animation_get_type ()) +#define GDK_PIXBUF_ANIMATION(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_PIXBUF_ANIMATION, GdkPixbufAnimation)) +#define GDK_IS_PIXBUF_ANIMATION(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_PIXBUF_ANIMATION)) + +#define GDK_TYPE_PIXBUF_ANIMATION_ITER (gdk_pixbuf_animation_iter_get_type ()) +#define GDK_PIXBUF_ANIMATION_ITER(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_PIXBUF_ANIMATION_ITER, GdkPixbufAnimationIter)) +#define GDK_IS_PIXBUF_ANIMATION_ITER(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_PIXBUF_ANIMATION_ITER)) + +GType gdk_pixbuf_animation_get_type (void) G_GNUC_CONST; + +#ifndef __GTK_DOC_IGNORE__ +#ifdef G_OS_WIN32 +#define gdk_pixbuf_animation_new_from_file gdk_pixbuf_animation_new_from_file_utf8 +#endif +#endif + +GdkPixbufAnimation *gdk_pixbuf_animation_new_from_file (const char *filename, + GError **error); +GdkPixbufAnimation *gdk_pixbuf_animation_new_from_stream (GInputStream *stream, + GCancellable *cancellable, + GError **error); +void gdk_pixbuf_animation_new_from_stream_async (GInputStream *stream, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GdkPixbufAnimation *gdk_pixbuf_animation_new_from_stream_finish (GAsyncResult*async_result, + GError **error); +GdkPixbufAnimation *gdk_pixbuf_animation_new_from_resource(const char *resource_path, + GError **error); + +#ifndef GDK_PIXBUF_DISABLE_DEPRECATED +G_DEPRECATED_FOR(g_object_ref) +GdkPixbufAnimation *gdk_pixbuf_animation_ref (GdkPixbufAnimation *animation); +G_DEPRECATED_FOR(g_object_unref) +void gdk_pixbuf_animation_unref (GdkPixbufAnimation *animation); +#endif + +int gdk_pixbuf_animation_get_width (GdkPixbufAnimation *animation); +int gdk_pixbuf_animation_get_height (GdkPixbufAnimation *animation); +gboolean gdk_pixbuf_animation_is_static_image (GdkPixbufAnimation *animation); +GdkPixbuf *gdk_pixbuf_animation_get_static_image (GdkPixbufAnimation *animation); + +GdkPixbufAnimationIter *gdk_pixbuf_animation_get_iter (GdkPixbufAnimation *animation, + const GTimeVal *start_time); +GType gdk_pixbuf_animation_iter_get_type (void) G_GNUC_CONST; +int gdk_pixbuf_animation_iter_get_delay_time (GdkPixbufAnimationIter *iter); +GdkPixbuf *gdk_pixbuf_animation_iter_get_pixbuf (GdkPixbufAnimationIter *iter); +gboolean gdk_pixbuf_animation_iter_on_currently_loading_frame (GdkPixbufAnimationIter *iter); +gboolean gdk_pixbuf_animation_iter_advance (GdkPixbufAnimationIter *iter, + const GTimeVal *current_time); + + +#ifdef GDK_PIXBUF_ENABLE_BACKEND + + + +/** + * GdkPixbufAnimationClass: + * @parent_class: the parent class + * @is_static_image: returns whether the given animation is just a static image. + * @get_static_image: returns a static image representing the given animation. + * @get_size: fills @width and @height with the frame size of the animation. + * @get_iter: returns an iterator for the given animation. + * + * Modules supporting animations must derive a type from + * #GdkPixbufAnimation, providing suitable implementations of the + * virtual functions. + */ +typedef struct _GdkPixbufAnimationClass GdkPixbufAnimationClass; + +#define GDK_PIXBUF_ANIMATION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_PIXBUF_ANIMATION, GdkPixbufAnimationClass)) +#define GDK_IS_PIXBUF_ANIMATION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_PIXBUF_ANIMATION)) +#define GDK_PIXBUF_ANIMATION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_PIXBUF_ANIMATION, GdkPixbufAnimationClass)) + +/* Private part of the GdkPixbufAnimation structure */ +struct _GdkPixbufAnimation { + GObject parent_instance; + +}; + +struct _GdkPixbufAnimationClass { + GObjectClass parent_class; + + /*< public >*/ + + gboolean (*is_static_image) (GdkPixbufAnimation *anim); + + GdkPixbuf* (*get_static_image) (GdkPixbufAnimation *anim); + + void (*get_size) (GdkPixbufAnimation *anim, + int *width, + int *height); + + GdkPixbufAnimationIter* (*get_iter) (GdkPixbufAnimation *anim, + const GTimeVal *start_time); + +}; + + + +/** + * GdkPixbufAnimationIterClass: + * @parent_class: the parent class + * @get_delay_time: returns the time in milliseconds that the current frame + * should be shown. + * @get_pixbuf: returns the current frame. + * @on_currently_loading_frame: returns whether the current frame of @iter is + * being loaded. + * @advance: advances the iterator to @current_time, possibly changing the + * current frame. + * + * Modules supporting animations must derive a type from + * #GdkPixbufAnimationIter, providing suitable implementations of the + * virtual functions. + */ +typedef struct _GdkPixbufAnimationIterClass GdkPixbufAnimationIterClass; + +#define GDK_PIXBUF_ANIMATION_ITER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_PIXBUF_ANIMATION_ITER, GdkPixbufAnimationIterClass)) +#define GDK_IS_PIXBUF_ANIMATION_ITER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_PIXBUF_ANIMATION_ITER)) +#define GDK_PIXBUF_ANIMATION_ITER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_PIXBUF_ANIMATION_ITER, GdkPixbufAnimationIterClass)) + +struct _GdkPixbufAnimationIter { + GObject parent_instance; + +}; + +struct _GdkPixbufAnimationIterClass { + GObjectClass parent_class; + + /*< public >*/ + + int (*get_delay_time) (GdkPixbufAnimationIter *iter); + + GdkPixbuf* (*get_pixbuf) (GdkPixbufAnimationIter *iter); + + gboolean (*on_currently_loading_frame) (GdkPixbufAnimationIter *iter); + + gboolean (*advance) (GdkPixbufAnimationIter *iter, + const GTimeVal *current_time); +}; + + +GType gdk_pixbuf_non_anim_get_type (void) G_GNUC_CONST; +GdkPixbufAnimation* gdk_pixbuf_non_anim_new (GdkPixbuf *pixbuf); + +#endif /* GDK_PIXBUF_ENABLE_BACKEND */ + +G_END_DECLS + +#endif /* GDK_PIXBUF_ANIMATION_H */ diff --git a/libs/tk/ydk-pixbuf/ydk-pixbuf/gdk-pixbuf/gdk-pixbuf-core.h b/libs/tk/ydk-pixbuf/ydk-pixbuf/gdk-pixbuf/gdk-pixbuf-core.h new file mode 100644 index 0000000000..b152aa911c --- /dev/null +++ b/libs/tk/ydk-pixbuf/ydk-pixbuf/gdk-pixbuf/gdk-pixbuf-core.h @@ -0,0 +1,473 @@ +/* GdkPixbuf library - GdkPixbuf data structure + * + * Copyright (C) 2003 The Free Software Foundation + * + * Authors: Mark Crichton + * Miguel de Icaza + * Federico Mena-Quintero + * Havoc Pennington + * + * 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, see . + */ + +#ifndef GDK_PIXBUF_CORE_H +#define GDK_PIXBUF_CORE_H + +#if defined(GDK_PIXBUF_DISABLE_SINGLE_INCLUDES) && !defined (GDK_PIXBUF_H_INSIDE) && !defined (GDK_PIXBUF_COMPILATION) +#error "Only can be included directly." +#endif + +#include +#include +#include + +G_BEGIN_DECLS + +/** + * SECTION:gdk-pixbuf + * @Short_description: Information that describes an image. + * @Title: The GdkPixbuf Structure + * + * The #GdkPixbuf structure contains + * information that describes an image in memory. + * + * ## Image Data ## {#image-data} + * + * Image data in a pixbuf is stored in memory in uncompressed, + * packed format. Rows in the image are stored top to bottom, and + * in each row pixels are stored from left to right. There may be + * padding at the end of a row. The "rowstride" value of a pixbuf, + * as returned by gdk_pixbuf_get_rowstride(), indicates the number + * of bytes between rows. + * + * ## put_pixel() Example ## {#put-pixel} + * + * The following code illustrates a simple put_pixel() + * function for RGB pixbufs with 8 bits per channel with an alpha + * channel. It is not included in the gdk-pixbuf library for + * performance reasons; rather than making several function calls + * for each pixel, your own code can take shortcuts. + * + * |[ + * static void + * put_pixel (GdkPixbuf *pixbuf, int x, int y, guchar red, guchar green, guchar blue, guchar alpha) + * { + * int width, height, rowstride, n_channels; + * guchar *pixels, *p; + * + * n_channels = gdk_pixbuf_get_n_channels (pixbuf); + * + * g_assert (gdk_pixbuf_get_colorspace (pixbuf) == GDK_COLORSPACE_RGB); + * g_assert (gdk_pixbuf_get_bits_per_sample (pixbuf) == 8); + * g_assert (gdk_pixbuf_get_has_alpha (pixbuf)); + * g_assert (n_channels == 4); + * + * width = gdk_pixbuf_get_width (pixbuf); + * height = gdk_pixbuf_get_height (pixbuf); + * + * g_assert (x >= 0 && x < width); + * g_assert (y >= 0 && y < height); + * + * rowstride = gdk_pixbuf_get_rowstride (pixbuf); + * pixels = gdk_pixbuf_get_pixels (pixbuf); + * + * p = pixels + y * rowstride + x * n_channels; + * p[0] = red; + * p[1] = green; + * p[2] = blue; + * p[3] = alpha; + * } + * ]| + * + * This function will not work for pixbufs with images that are + * other than 8 bits per sample or channel, but it will work for + * most of the pixbufs that GTK+ uses. + * + * If you are doing memcpy() of raw pixbuf data, note that the last row + * in the pixbuf may not be as wide as the full rowstride, but rather + * just as wide as the pixel data needs to be. That is, it is unsafe to + * do `memcpy (dest, pixels, rowstride * height)` to copy a whole pixbuf. + * Use gdk_pixbuf_copy() instead, or compute the width in bytes of the + * last row as `width * ((n_channels * bits_per_sample + 7) / 8)`. + */ + + +/** + * GdkPixbufAlphaMode: + * @GDK_PIXBUF_ALPHA_BILEVEL: A bilevel clipping mask (black and white) + * will be created and used to draw the image. Pixels below 0.5 opacity + * will be considered fully transparent, and all others will be + * considered fully opaque. + * @GDK_PIXBUF_ALPHA_FULL: For now falls back to #GDK_PIXBUF_ALPHA_BILEVEL. + * In the future it will do full alpha compositing. + * + * These values can be passed to + * gdk_pixbuf_render_to_drawable_alpha() to control how the alpha + * channel of an image should be handled. This function can create a + * bilevel clipping mask (black and white) and use it while painting + * the image. In the future, when the X Window System gets an alpha + * channel extension, it will be possible to do full alpha + * compositing onto arbitrary drawables. For now both cases fall + * back to a bilevel clipping mask. + */ +typedef enum +{ + GDK_PIXBUF_ALPHA_BILEVEL, + GDK_PIXBUF_ALPHA_FULL +} GdkPixbufAlphaMode; + +/** + * GdkColorspace: + * @GDK_COLORSPACE_RGB: Indicates a red/green/blue additive color space. + * + * This enumeration defines the color spaces that are supported by + * the gdk-pixbuf library. Currently only RGB is supported. + */ +/* Note that these values are encoded in inline pixbufs + * as ints, so don't reorder them + */ +typedef enum { + GDK_COLORSPACE_RGB +} GdkColorspace; + +/* All of these are opaque structures */ + +/** + * GdkPixbuf: + * + * This is the main structure in the gdk-pixbuf library. It is + * used to represent images. It contains information about the + * image's pixel data, its color space, bits per sample, width and + * height, and the rowstride (the number of bytes between the start of + * one row and the start of the next). + */ +typedef struct _GdkPixbuf GdkPixbuf; + +#define GDK_TYPE_PIXBUF (gdk_pixbuf_get_type ()) +#define GDK_PIXBUF(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_PIXBUF, GdkPixbuf)) +#define GDK_IS_PIXBUF(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_PIXBUF)) + + +/** + * GdkPixbufDestroyNotify: + * @pixels: (array) (element-type guint8): The pixel array of the pixbuf + * that is being finalized. + * @data: (closure): User closure data. + * + * A function of this type is responsible for freeing the pixel array + * of a pixbuf. The gdk_pixbuf_new_from_data() function lets you + * pass in a pre-allocated pixel array so that a pixbuf can be + * created from it; in this case you will need to pass in a function + * of #GdkPixbufDestroyNotify so that the pixel data can be freed + * when the pixbuf is finalized. + */ +typedef void (* GdkPixbufDestroyNotify) (guchar *pixels, gpointer data); + +/** + * GDK_PIXBUF_ERROR: + * + * Error domain used for pixbuf operations. Indicates that the error code + * will be in the #GdkPixbufError enumeration. See #GError for + * information on error domains and error codes. + */ +#define GDK_PIXBUF_ERROR gdk_pixbuf_error_quark () + +/** + * GdkPixbufError: + * @GDK_PIXBUF_ERROR_CORRUPT_IMAGE: An image file was broken somehow. + * @GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY: Not enough memory. + * @GDK_PIXBUF_ERROR_BAD_OPTION: A bad option was passed to a pixbuf save module. + * @GDK_PIXBUF_ERROR_UNKNOWN_TYPE: Unknown image type. + * @GDK_PIXBUF_ERROR_UNSUPPORTED_OPERATION: Don't know how to perform the + * given operation on the type of image at hand. + * @GDK_PIXBUF_ERROR_FAILED: Generic failure code, something went wrong. + * + * An error code in the #GDK_PIXBUF_ERROR domain. Many gdk-pixbuf + * operations can cause errors in this domain, or in the #G_FILE_ERROR + * domain. + */ +typedef enum { + /* image data hosed */ + GDK_PIXBUF_ERROR_CORRUPT_IMAGE, + /* no mem to load image */ + GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY, + /* bad option passed to save routine */ + GDK_PIXBUF_ERROR_BAD_OPTION, + /* unsupported image type (sort of an ENOSYS) */ + GDK_PIXBUF_ERROR_UNKNOWN_TYPE, + /* unsupported operation (load, save) for image type */ + GDK_PIXBUF_ERROR_UNSUPPORTED_OPERATION, + GDK_PIXBUF_ERROR_FAILED +} GdkPixbufError; + +GQuark gdk_pixbuf_error_quark (void); + + + +GType gdk_pixbuf_get_type (void) G_GNUC_CONST; + +/* Reference counting */ + +#ifndef GDK_PIXBUF_DISABLE_DEPRECATED +G_DEPRECATED_FOR(g_object_ref) +GdkPixbuf *gdk_pixbuf_ref (GdkPixbuf *pixbuf); +G_DEPRECATED_FOR(g_object_unref) +void gdk_pixbuf_unref (GdkPixbuf *pixbuf); +#endif + +/* GdkPixbuf accessors */ + +GdkColorspace gdk_pixbuf_get_colorspace (const GdkPixbuf *pixbuf); +int gdk_pixbuf_get_n_channels (const GdkPixbuf *pixbuf); +gboolean gdk_pixbuf_get_has_alpha (const GdkPixbuf *pixbuf); +int gdk_pixbuf_get_bits_per_sample (const GdkPixbuf *pixbuf); +guchar *gdk_pixbuf_get_pixels (const GdkPixbuf *pixbuf); +int gdk_pixbuf_get_width (const GdkPixbuf *pixbuf); +int gdk_pixbuf_get_height (const GdkPixbuf *pixbuf); +int gdk_pixbuf_get_rowstride (const GdkPixbuf *pixbuf); +gsize gdk_pixbuf_get_byte_length (const GdkPixbuf *pixbuf); + +guchar *gdk_pixbuf_get_pixels_with_length (const GdkPixbuf *pixbuf, + guint *length); + +const guint8* gdk_pixbuf_read_pixels (const GdkPixbuf *pixbuf); +GBytes * gdk_pixbuf_read_pixel_bytes (const GdkPixbuf *pixbuf); + + + +/* Create a blank pixbuf with an optimal rowstride and a new buffer */ +GdkPixbuf *gdk_pixbuf_new (GdkColorspace colorspace, gboolean has_alpha, int bits_per_sample, + int width, int height); + +/* Copy a pixbuf */ + +GdkPixbuf *gdk_pixbuf_copy (const GdkPixbuf *pixbuf); + +/* Create a pixbuf which points to the pixels of another pixbuf */ +GdkPixbuf *gdk_pixbuf_new_subpixbuf (GdkPixbuf *src_pixbuf, + int src_x, + int src_y, + int width, + int height); + +/* Simple loading */ + +#ifndef __GTK_DOC_IGNORE__ +#ifdef G_OS_WIN32 +/* DLL ABI stability hack. */ +#define gdk_pixbuf_new_from_file gdk_pixbuf_new_from_file_utf8 +#define gdk_pixbuf_new_from_file_at_size gdk_pixbuf_new_from_file_at_size_utf8 +#define gdk_pixbuf_new_from_file_at_scale gdk_pixbuf_new_from_file_at_scale_utf8 +#endif +#endif + +GdkPixbuf *gdk_pixbuf_new_from_file (const char *filename, + GError **error); +GdkPixbuf *gdk_pixbuf_new_from_file_at_size (const char *filename, + int width, + int height, + GError **error); +GdkPixbuf *gdk_pixbuf_new_from_file_at_scale (const char *filename, + int width, + int height, + gboolean preserve_aspect_ratio, + GError **error); +GdkPixbuf *gdk_pixbuf_new_from_resource (const char *resource_path, + GError **error); +GdkPixbuf *gdk_pixbuf_new_from_resource_at_scale (const char *resource_path, + int width, + int height, + gboolean preserve_aspect_ratio, + GError **error); + +GdkPixbuf *gdk_pixbuf_new_from_data (const guchar *data, + GdkColorspace colorspace, + gboolean has_alpha, + int bits_per_sample, + int width, int height, + int rowstride, + GdkPixbufDestroyNotify destroy_fn, + gpointer destroy_fn_data); + +GdkPixbuf *gdk_pixbuf_new_from_bytes (GBytes *data, + GdkColorspace colorspace, + gboolean has_alpha, + int bits_per_sample, + int width, int height, + int rowstride); + +GdkPixbuf *gdk_pixbuf_new_from_xpm_data (const char **data); +GdkPixbuf* gdk_pixbuf_new_from_inline (gint data_length, + const guint8 *data, + gboolean copy_pixels, + GError **error); + +/* Mutations */ +void gdk_pixbuf_fill (GdkPixbuf *pixbuf, + guint32 pixel); + +/* Saving */ + +#ifndef __GTK_DOC_IGNORE__ +#ifdef G_OS_WIN32 +/* DLL ABI stability hack. */ +#define gdk_pixbuf_save gdk_pixbuf_save_utf8 +#define gdk_pixbuf_savev gdk_pixbuf_savev_utf8 +#endif +#endif + +gboolean gdk_pixbuf_save (GdkPixbuf *pixbuf, + const char *filename, + const char *type, + GError **error, + ...) G_GNUC_NULL_TERMINATED; + +gboolean gdk_pixbuf_savev (GdkPixbuf *pixbuf, + const char *filename, + const char *type, + char **option_keys, + char **option_values, + GError **error); + +/* Saving to a callback function */ + + +/** + * GdkPixbufSaveFunc: + * @buf: (array length=count) (element-type guint8): bytes to be written. + * @count: number of bytes in @buf. + * @error: (out): A location to return an error. + * @data: (closure): user data passed to gdk_pixbuf_save_to_callback(). + * + * Specifies the type of the function passed to + * gdk_pixbuf_save_to_callback(). It is called once for each block of + * bytes that is "written" by gdk_pixbuf_save_to_callback(). If + * successful it should return %TRUE. If an error occurs it should set + * @error and return %FALSE, in which case gdk_pixbuf_save_to_callback() + * will fail with the same error. + * + * Since: 2.4 + * Returns: %TRUE if successful, %FALSE (with @error set) if failed. + */ + +typedef gboolean (*GdkPixbufSaveFunc) (const gchar *buf, + gsize count, + GError **error, + gpointer data); + +gboolean gdk_pixbuf_save_to_callback (GdkPixbuf *pixbuf, + GdkPixbufSaveFunc save_func, + gpointer user_data, + const char *type, + GError **error, + ...) G_GNUC_NULL_TERMINATED; + +gboolean gdk_pixbuf_save_to_callbackv (GdkPixbuf *pixbuf, + GdkPixbufSaveFunc save_func, + gpointer user_data, + const char *type, + char **option_keys, + char **option_values, + GError **error); + +/* Saving into a newly allocated char array */ + +gboolean gdk_pixbuf_save_to_buffer (GdkPixbuf *pixbuf, + gchar **buffer, + gsize *buffer_size, + const char *type, + GError **error, + ...) G_GNUC_NULL_TERMINATED; + +gboolean gdk_pixbuf_save_to_bufferv (GdkPixbuf *pixbuf, + gchar **buffer, + gsize *buffer_size, + const char *type, + char **option_keys, + char **option_values, + GError **error); + +GdkPixbuf *gdk_pixbuf_new_from_stream (GInputStream *stream, + GCancellable *cancellable, + GError **error); + +void gdk_pixbuf_new_from_stream_async (GInputStream *stream, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + +GdkPixbuf *gdk_pixbuf_new_from_stream_finish (GAsyncResult *async_result, + GError **error); + +GdkPixbuf *gdk_pixbuf_new_from_stream_at_scale (GInputStream *stream, + gint width, + gint height, + gboolean preserve_aspect_ratio, + GCancellable *cancellable, + GError **error); + +void gdk_pixbuf_new_from_stream_at_scale_async (GInputStream *stream, + gint width, + gint height, + gboolean preserve_aspect_ratio, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + +gboolean gdk_pixbuf_save_to_stream (GdkPixbuf *pixbuf, + GOutputStream *stream, + const char *type, + GCancellable *cancellable, + GError **error, + ...); + +void gdk_pixbuf_save_to_stream_async (GdkPixbuf *pixbuf, + GOutputStream *stream, + const gchar *type, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data, + ...); + +gboolean gdk_pixbuf_save_to_stream_finish (GAsyncResult *async_result, + GError **error); + +/* Adding an alpha channel */ +GdkPixbuf *gdk_pixbuf_add_alpha (const GdkPixbuf *pixbuf, gboolean substitute_color, + guchar r, guchar g, guchar b); + +/* Copy an area of a pixbuf onto another one */ +void gdk_pixbuf_copy_area (const GdkPixbuf *src_pixbuf, + int src_x, int src_y, + int width, int height, + GdkPixbuf *dest_pixbuf, + int dest_x, int dest_y); + +/* Brighten/darken and optionally make it pixelated-looking */ +void gdk_pixbuf_saturate_and_pixelate (const GdkPixbuf *src, + GdkPixbuf *dest, + gfloat saturation, + gboolean pixelate); + +/* Transform an image to agree with its embedded orientation option / tag */ +GdkPixbuf *gdk_pixbuf_apply_embedded_orientation (GdkPixbuf *src); + +const gchar * gdk_pixbuf_get_option (GdkPixbuf *pixbuf, + const gchar *key); + + +G_END_DECLS + + +#endif /* GDK_PIXBUF_CORE_H */ diff --git a/libs/tk/ydk-pixbuf/ydk-pixbuf/gdk-pixbuf/gdk-pixbuf-enum-types.h b/libs/tk/ydk-pixbuf/ydk-pixbuf/gdk-pixbuf/gdk-pixbuf-enum-types.h new file mode 100644 index 0000000000..b69612eddc --- /dev/null +++ b/libs/tk/ydk-pixbuf/ydk-pixbuf/gdk-pixbuf/gdk-pixbuf-enum-types.h @@ -0,0 +1,33 @@ + +/* This file is generated by glib-mkenums, do not modify it. This code is licensed under the same license as the containing project. Note that it links to GLib, so must comply with the LGPL linking clauses. */ + +#if defined(GDK_PIXBUF_DISABLE_SINGLE_INCLUDES) && !defined (GDK_PIXBUF_H_INSIDE) && !defined (GDK_PIXBUF_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __GDK_PIXBUF_ENUM_TYPES_H__ +#define __GDK_PIXBUF_ENUM_TYPES_H__ + +#include + +G_BEGIN_DECLS + +/* enumerations from "gdk-pixbuf-core.h" */ +GType gdk_pixbuf_alpha_mode_get_type (void) G_GNUC_CONST; +#define GDK_TYPE_PIXBUF_ALPHA_MODE (gdk_pixbuf_alpha_mode_get_type ()) +GType gdk_colorspace_get_type (void) G_GNUC_CONST; +#define GDK_TYPE_COLORSPACE (gdk_colorspace_get_type ()) +GType gdk_pixbuf_error_get_type (void) G_GNUC_CONST; +#define GDK_TYPE_PIXBUF_ERROR (gdk_pixbuf_error_get_type ()) + +/* enumerations from "gdk-pixbuf-transform.h" */ +GType gdk_interp_type_get_type (void) G_GNUC_CONST; +#define GDK_TYPE_INTERP_TYPE (gdk_interp_type_get_type ()) +GType gdk_pixbuf_rotation_get_type (void) G_GNUC_CONST; +#define GDK_TYPE_PIXBUF_ROTATION (gdk_pixbuf_rotation_get_type ()) +G_END_DECLS + +#endif /* __GDK_PIXBUF_ENUM_TYPES_H__ */ + +/* Generated data ends here */ + diff --git a/libs/tk/ydk-pixbuf/ydk-pixbuf/gdk-pixbuf/gdk-pixbuf-features.h b/libs/tk/ydk-pixbuf/ydk-pixbuf/gdk-pixbuf/gdk-pixbuf-features.h new file mode 100644 index 0000000000..352a5c80e7 --- /dev/null +++ b/libs/tk/ydk-pixbuf/ydk-pixbuf/gdk-pixbuf/gdk-pixbuf-features.h @@ -0,0 +1,120 @@ +#if defined(GDK_PIXBUF_DISABLE_SINGLE_INCLUDES) && !defined (GDK_PIXBUF_H_INSIDE) && !defined (GDK_PIXBUF_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef GDK_PIXBUF_FEATURES_H +#define GDK_PIXBUF_FEATURES_H 1 + +#include + +/** + * SECTION:initialization_versions + * @Short_description: +Library version numbers. + * @Title: Initialization and Versions + * + * These macros and variables let you check the version of gdk-pixbuf + * you're linking against. + */ + +/** + * GDK_PIXBUF_MAJOR: + * + * Major version of gdk-pixbuf library, that is the "0" in + * "0.8.2" for example. + */ +/** + * GDK_PIXBUF_MINOR: + * + * Minor version of gdk-pixbuf library, that is the "8" in + * "0.8.2" for example. + */ +/** + * GDK_PIXBUF_MICRO: + * + * Micro version of gdk-pixbuf library, that is the "2" in + * "0.8.2" for example. + */ +/** + * GDK_PIXBUF_VERSION: + * + * Contains the full version of the gdk-pixbuf header as a string. + * This is the version being compiled against; contrast with + * #gdk_pixbuf_version. + */ + +#define GDK_PIXBUF_MAJOR (2) +#define GDK_PIXBUF_MINOR (31) +#define GDK_PIXBUF_MICRO (1) +#define GDK_PIXBUF_VERSION "2.31.1" + +/* We prefix variable declarations so they can + * properly get exported/imported from Windows DLLs. + */ +#ifdef G_PLATFORM_WIN32 +# ifdef GDK_PIXBUF_STATIC_COMPILATION +# define GDK_PIXBUF_VAR extern +# else /* !GDK_PIXBUF_STATIC_COMPILATION */ +# ifdef GDK_PIXBUF_C_COMPILATION +# ifdef DLL_EXPORT +# define GDK_PIXBUF_VAR __declspec(dllexport) +# else /* !DLL_EXPORT */ +# define GDK_PIXBUF_VAR extern +# endif /* !DLL_EXPORT */ +# else /* !GDK_PIXBUF_C_COMPILATION */ +# define GDK_PIXBUF_VAR extern __declspec(dllimport) +# endif /* !GDK_PIXBUF_C_COMPILATION */ +# endif /* !GDK_PIXBUF_STATIC_COMPILATION */ +#else /* !G_PLATFORM_WIN32 */ +# define GDK_PIXBUF_VAR extern +#endif /* !G_PLATFORM_WIN32 */ + +/** + * gdk_pixbuf_major_version: + * + * The major version number of the gdk-pixbuf library. (e.g. in + * gdk-pixbuf version 1.2.5 this is 1.) + * + * + * This variable is in the library, so represents the + * gdk-pixbuf library you have linked against. Contrast with the + * #GDK_PIXBUF_MAJOR macro, which represents the major version of the + * gdk-pixbuf headers you have included. + */ +/** + * gdk_pixbuf_minor_version: + * + * The minor version number of the gdk-pixbuf library. (e.g. in + * gdk-pixbuf version 1.2.5 this is 2.) + * + * + * This variable is in the library, so represents the + * gdk-pixbuf library you have linked against. Contrast with the + * #GDK_PIXBUF_MINOR macro, which represents the minor version of the + * gdk-pixbuf headers you have included. + */ +/** + * gdk_pixbuf_micro_version: + * + * The micro version number of the gdk-pixbuf library. (e.g. in + * gdk-pixbuf version 1.2.5 this is 5.) + * + * + * This variable is in the library, so represents the + * gdk-pixbuf library you have linked against. Contrast with the + * #GDK_PIXBUF_MICRO macro, which represents the micro version of the + * gdk-pixbuf headers you have included. + */ +/** + * gdk_pixbuf_version: + * + * Contains the full version of the gdk-pixbuf library as a string. + * This is the version currently in use by a running program. + */ + +GDK_PIXBUF_VAR const guint gdk_pixbuf_major_version; +GDK_PIXBUF_VAR const guint gdk_pixbuf_minor_version; +GDK_PIXBUF_VAR const guint gdk_pixbuf_micro_version; +GDK_PIXBUF_VAR const char *gdk_pixbuf_version; + +#endif /* GDK_PIXBUF_FEATURES_H */ diff --git a/libs/tk/ydk-pixbuf/ydk-pixbuf/gdk-pixbuf/gdk-pixbuf-i18n.h b/libs/tk/ydk-pixbuf/ydk-pixbuf/gdk-pixbuf/gdk-pixbuf-i18n.h new file mode 100644 index 0000000000..854860a15a --- /dev/null +++ b/libs/tk/ydk-pixbuf/ydk-pixbuf/gdk-pixbuf/gdk-pixbuf-i18n.h @@ -0,0 +1,36 @@ +/* GdkPixbuf library - Internationalization + * + * Copyright (C) 2000 Havoc Pennington + * + * 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, see . + */ +#ifndef __GDKPIXBUFINTL_H__ +#define __GDKPIXBUFINTL_H__ + +#include + +#ifdef ENABLE_NLS +#define _(String) gdk_pixbuf_gettext(String) +#define P_(String) gdk_pixbuf_gettext(String) +#define N_(String) (String) +#else +#define _(String) (String) +#define P_(String) (String) +#define N_(String) (String) +#endif + +const gchar * +gdk_pixbuf_gettext (const gchar *msgid) G_GNUC_FORMAT(1); + +#endif diff --git a/libs/tk/ydk-pixbuf/ydk-pixbuf/gdk-pixbuf/gdk-pixbuf-io.h b/libs/tk/ydk-pixbuf/ydk-pixbuf/gdk-pixbuf/gdk-pixbuf-io.h new file mode 100644 index 0000000000..63c1e529fe --- /dev/null +++ b/libs/tk/ydk-pixbuf/ydk-pixbuf/gdk-pixbuf/gdk-pixbuf-io.h @@ -0,0 +1,351 @@ +/* GdkPixbuf library - Io handling. This is an internal header for + * GdkPixbuf. You should never use it unless you are doing development for + * GdkPixbuf itself. + * + * Copyright (C) 1999 The Free Software Foundation + * + * Authors: Mark Crichton + * Miguel de Icaza + * Federico Mena-Quintero + * Jonathan Blandford + * Michael Fulbright + * + * 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, see . + */ + +#ifndef GDK_PIXBUF_IO_H +#define GDK_PIXBUF_IO_H + +#if defined(GDK_PIXBUF_DISABLE_SINGLE_INCLUDES) && !defined (GDK_PIXBUF_H_INSIDE) && !defined (GDK_PIXBUF_COMPILATION) +#error "Only can be included directly." +#endif + +#include +#include +#include +#include +#include + +G_BEGIN_DECLS + +typedef struct _GdkPixbufFormat GdkPixbufFormat; + +GType gdk_pixbuf_format_get_type (void) G_GNUC_CONST; + +GSList *gdk_pixbuf_get_formats (void); +gchar *gdk_pixbuf_format_get_name (GdkPixbufFormat *format); +gchar *gdk_pixbuf_format_get_description (GdkPixbufFormat *format); +gchar **gdk_pixbuf_format_get_mime_types (GdkPixbufFormat *format); +gchar **gdk_pixbuf_format_get_extensions (GdkPixbufFormat *format); +gboolean gdk_pixbuf_format_is_writable (GdkPixbufFormat *format); +gboolean gdk_pixbuf_format_is_scalable (GdkPixbufFormat *format); +gboolean gdk_pixbuf_format_is_disabled (GdkPixbufFormat *format); +void gdk_pixbuf_format_set_disabled (GdkPixbufFormat *format, + gboolean disabled); +gchar *gdk_pixbuf_format_get_license (GdkPixbufFormat *format); + +GdkPixbufFormat *gdk_pixbuf_get_file_info (const gchar *filename, + gint *width, + gint *height); +void gdk_pixbuf_get_file_info_async (const gchar *filename, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +GdkPixbufFormat *gdk_pixbuf_get_file_info_finish (GAsyncResult *async_result, + gint *width, + gint *height, + GError **error); + +GdkPixbufFormat *gdk_pixbuf_format_copy (const GdkPixbufFormat *format); +void gdk_pixbuf_format_free (GdkPixbufFormat *format); + +#ifdef GDK_PIXBUF_ENABLE_BACKEND + + + +/** + * GdkPixbufModuleSizeFunc: + * @width: pointer to a location containing the current image width + * @height: pointer to a location containing the current image height + * @user_data: the loader. + * + * Defines the type of the function that gets called once the size + * of the loaded image is known. + * + * The function is expected to set @width and @height to the desired + * size to which the image should be scaled. If a module has no efficient + * way to achieve the desired scaling during the loading of the image, it may + * either ignore the size request, or only approximate it - gdk-pixbuf will + * then perform the required scaling on the completely loaded image. + * + * If the function sets @width or @height to zero, the module should interpret + * this as a hint that it will be closed soon and shouldn't allocate further + * resources. This convention is used to implement gdk_pixbuf_get_file_info() + * efficiently. + * + * Since: 2.2 + */ +typedef void (* GdkPixbufModuleSizeFunc) (gint *width, + gint *height, + gpointer user_data); + +/** + * GdkPixbufModulePreparedFunc: + * @pixbuf: the #GdkPixbuf that is currently being loaded. + * @anim: if an animation is being loaded, the #GdkPixbufAnimation, else %NULL. + * @user_data: the loader. + * + * Defines the type of the function that gets called once the initial + * setup of @pixbuf is done. + * + * #GdkPixbufLoader uses a function of this type to emit the + * "area_prepared" + * signal. + * + * Since: 2.2 + */ +typedef void (* GdkPixbufModulePreparedFunc) (GdkPixbuf *pixbuf, + GdkPixbufAnimation *anim, + gpointer user_data); + +/** + * GdkPixbufModuleUpdatedFunc: + * @pixbuf: the #GdkPixbuf that is currently being loaded. + * @x: the X origin of the updated area. + * @y: the Y origin of the updated area. + * @width: the width of the updated area. + * @height: the height of the updated area. + * @user_data: the loader. + * + * Defines the type of the function that gets called every time a region + * of @pixbuf is updated. + * + * #GdkPixbufLoader uses a function of this type to emit the + * "area_updated" + * signal. + * + * Since: 2.2 + */ +typedef void (* GdkPixbufModuleUpdatedFunc) (GdkPixbuf *pixbuf, + int x, + int y, + int width, + int height, + gpointer user_data); + +/** + * GdkPixbufModulePattern: + * @prefix: the prefix for this pattern + * @mask: mask containing bytes which modify how the prefix is matched against + * test data + * @relevance: relevance of this pattern + * + * The signature of a module is a set of prefixes. Prefixes are encoded as + * pairs of ordinary strings, where the second string, called the mask, if + * not %NULL, must be of the same length as the first one and may contain + * ' ', '!', 'x', 'z', and 'n' to indicate bytes that must be matched, + * not matched, "don't-care"-bytes, zeros and non-zeros. + * Each prefix has an associated integer that describes the relevance of + * the prefix, with 0 meaning a mismatch and 100 a "perfect match". + * + * Starting with gdk-pixbuf 2.8, the first byte of the mask may be '*', + * indicating an unanchored pattern that matches not only at the beginning, + * but also in the middle. Versions prior to 2.8 will interpret the '*' + * like an 'x'. + * + * The signature of a module is stored as an array of + * #GdkPixbufModulePatterns. The array is terminated by a pattern + * where the @prefix is %NULL. + * + * + * + * GdkPixbufModulePattern *signature[] = { + * { "abcdx", " !x z", 100 }, + * { "bla", NULL, 90 }, + * { NULL, NULL, 0 } + * }; + * + * The example matches e.g. "auud\0" with relevance 100, and "blau" with + * relevance 90. + * + * Since: 2.2 + */ +typedef struct _GdkPixbufModulePattern GdkPixbufModulePattern; +struct _GdkPixbufModulePattern { + char *prefix; + char *mask; + int relevance; +}; + +/** + * GdkPixbufModule: + * @module_name: the name of the module, usually the same as the + * usual file extension for images of this type, eg. "xpm", "jpeg" or "png". + * @module_path: the path from which the module is loaded. + * @module: the loaded #GModule. + * @info: a #GdkPixbufFormat holding information about the module. + * @load: loads an image from a file. + * @load_xpm_data: loads an image from data in memory. + * @begin_load: begins an incremental load. + * @stop_load: stops an incremental load. + * @load_increment: continues an incremental load. + * @load_animation: loads an animation from a file. + * @save: saves a #GdkPixbuf to a file. + * @save_to_callback: saves a #GdkPixbuf by calling the given #GdkPixbufSaveFunc. + * + * A #GdkPixbufModule contains the necessary functions to load and save + * images in a certain file format. + * + * A #GdkPixbufModule can be loaded dynamically from a #GModule. + * Each loadable module must contain a #GdkPixbufModuleFillVtableFunc function + * named fill_vtable, which will get called when the module + * is loaded and must set the function pointers of the #GdkPixbufModule. + */ +typedef struct _GdkPixbufModule GdkPixbufModule; +struct _GdkPixbufModule { + char *module_name; + char *module_path; + GModule *module; + GdkPixbufFormat *info; + + GdkPixbuf *(* load) (FILE *f, + GError **error); + GdkPixbuf *(* load_xpm_data) (const char **data); + + /* Incremental loading */ + + gpointer (* begin_load) (GdkPixbufModuleSizeFunc size_func, + GdkPixbufModulePreparedFunc prepare_func, + GdkPixbufModuleUpdatedFunc update_func, + gpointer user_data, + GError **error); + gboolean (* stop_load) (gpointer context, + GError **error); + gboolean (* load_increment) (gpointer context, + const guchar *buf, + guint size, + GError **error); + + /* Animation loading */ + GdkPixbufAnimation *(* load_animation) (FILE *f, + GError **error); + + /* Saving */ + gboolean (* save) (FILE *f, + GdkPixbuf *pixbuf, + gchar **param_keys, + gchar **param_values, + GError **error); + + gboolean (*save_to_callback) (GdkPixbufSaveFunc save_func, + gpointer user_data, + GdkPixbuf *pixbuf, + gchar **option_keys, + gchar **option_values, + GError **error); + + /*< private >*/ + void (*_reserved1) (void); + void (*_reserved2) (void); + void (*_reserved3) (void); + void (*_reserved4) (void); + void (*_reserved5) (void); + +}; + +/** + * GdkPixbufModuleFillVtableFunc: + * @module: a #GdkPixbufModule. + * + * Defines the type of the function used to set the vtable of a + * #GdkPixbufModule when it is loaded. + * + * Since: 2.2 + */ + +typedef void (* GdkPixbufModuleFillVtableFunc) (GdkPixbufModule *module); + +/** + * GdkPixbufModuleFillInfoFunc: + * @info: a #GdkPixbufFormat. + * + * Defines the type of the function used to fill a + * #GdkPixbufFormat structure with information about a module. + * + * Since: 2.2 + */ +typedef void (* GdkPixbufModuleFillInfoFunc) (GdkPixbufFormat *info); + +/* key/value pairs that can be attached by the pixbuf loader */ + +gboolean gdk_pixbuf_set_option (GdkPixbuf *pixbuf, + const gchar *key, + const gchar *value); + +/** + * GdkPixbufFormatFlags: + * @GDK_PIXBUF_FORMAT_WRITABLE: the module can write out images in the format. + * @GDK_PIXBUF_FORMAT_SCALABLE: the image format is scalable + * @GDK_PIXBUF_FORMAT_THREADSAFE: the module is threadsafe. gdk-pixbuf + * ignores modules that are not marked as threadsafe. (Since 2.28). + * + * Flags which allow a module to specify further details about the supported + * operations. + * + * Since: 2.2 + */ +typedef enum /*< skip >*/ +{ + GDK_PIXBUF_FORMAT_WRITABLE = 1 << 0, + GDK_PIXBUF_FORMAT_SCALABLE = 1 << 1, + GDK_PIXBUF_FORMAT_THREADSAFE = 1 << 2 +} GdkPixbufFormatFlags; + +/** + * GdkPixbufFormat: + * @name: the name of the image format. + * @signature: the signature of the module. + * @domain: the message domain for the @description. + * @description: a description of the image format. + * @mime_types: a %NULL-terminated array of MIME types for the image format. + * @extensions: a %NULL-terminated array of typical filename extensions for the + * image format. + * @flags: a combination of #GdkPixbufFormatFlags. + * @disabled: a boolean determining whether the loader is disabled. + * @license: a string containing license information, typically set to + * shorthands like "GPL", "LGPL", etc. + * + * A #GdkPixbufFormat contains information about the image format accepted by a + * module. Only modules should access the fields directly, applications should + * use the gdk_pixbuf_format_* functions. + * + * Since: 2.2 + */ +struct _GdkPixbufFormat { + gchar *name; + GdkPixbufModulePattern *signature; + gchar *domain; + gchar *description; + gchar **mime_types; + gchar **extensions; + guint32 flags; + gboolean disabled; + gchar *license; +}; + +#endif /* GDK_PIXBUF_ENABLE_BACKEND */ + +G_END_DECLS + +#endif /* GDK_PIXBUF_IO_H */ diff --git a/libs/tk/ydk-pixbuf/ydk-pixbuf/gdk-pixbuf/gdk-pixbuf-loader.h b/libs/tk/ydk-pixbuf/ydk-pixbuf/gdk-pixbuf/gdk-pixbuf-loader.h new file mode 100644 index 0000000000..d37b810bdb --- /dev/null +++ b/libs/tk/ydk-pixbuf/ydk-pixbuf/gdk-pixbuf/gdk-pixbuf-loader.h @@ -0,0 +1,108 @@ +/* GdkPixbuf library - Progressive loader object + * + * Copyright (C) 1999 The Free Software Foundation + * + * Authors: Mark Crichton + * Miguel de Icaza + * Federico Mena-Quintero + * Jonathan Blandford + * + * 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, see . + */ + +#ifndef GDK_PIXBUF_LOADER_H +#define GDK_PIXBUF_LOADER_H + +#if defined(GDK_PIXBUF_DISABLE_SINGLE_INCLUDES) && !defined (GDK_PIXBUF_H_INSIDE) && !defined (GDK_PIXBUF_COMPILATION) +#error "Only can be included directly." +#endif + +#include +#include +#include +#include +#include + +G_BEGIN_DECLS + +#define GDK_TYPE_PIXBUF_LOADER (gdk_pixbuf_loader_get_type ()) +#define GDK_PIXBUF_LOADER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDK_TYPE_PIXBUF_LOADER, GdkPixbufLoader)) +#define GDK_PIXBUF_LOADER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_PIXBUF_LOADER, GdkPixbufLoaderClass)) +#define GDK_IS_PIXBUF_LOADER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDK_TYPE_PIXBUF_LOADER)) +#define GDK_IS_PIXBUF_LOADER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_PIXBUF_LOADER)) +#define GDK_PIXBUF_LOADER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_PIXBUF_LOADER, GdkPixbufLoaderClass)) + +/** + * GdkPixbufLoader: + * + * The GdkPixbufLoader struct contains only private + * fields. + */ +typedef struct _GdkPixbufLoader GdkPixbufLoader; +struct _GdkPixbufLoader +{ + GObject parent_instance; + + /*< private >*/ + gpointer priv; +}; + +typedef struct _GdkPixbufLoaderClass GdkPixbufLoaderClass; +struct _GdkPixbufLoaderClass +{ + GObjectClass parent_class; + + void (*size_prepared) (GdkPixbufLoader *loader, + int width, + int height); + + void (*area_prepared) (GdkPixbufLoader *loader); + + /* Last known frame needs a redraw for x, y, width, height */ + void (*area_updated) (GdkPixbufLoader *loader, + int x, + int y, + int width, + int height); + + void (*closed) (GdkPixbufLoader *loader); +}; + +GType gdk_pixbuf_loader_get_type (void) G_GNUC_CONST; +GdkPixbufLoader * gdk_pixbuf_loader_new (void); +GdkPixbufLoader * gdk_pixbuf_loader_new_with_type (const char *image_type, + GError **error); +GdkPixbufLoader * gdk_pixbuf_loader_new_with_mime_type (const char *mime_type, + GError **error); +void gdk_pixbuf_loader_set_size (GdkPixbufLoader *loader, + int width, + int height); +gboolean gdk_pixbuf_loader_write (GdkPixbufLoader *loader, + const guchar *buf, + gsize count, + GError **error); +gboolean gdk_pixbuf_loader_write_bytes (GdkPixbufLoader *loader, + GBytes *buffer, + GError **error); +GdkPixbuf * gdk_pixbuf_loader_get_pixbuf (GdkPixbufLoader *loader); +GdkPixbufAnimation * gdk_pixbuf_loader_get_animation (GdkPixbufLoader *loader); +gboolean gdk_pixbuf_loader_close (GdkPixbufLoader *loader, + GError **error); +GdkPixbufFormat *gdk_pixbuf_loader_get_format (GdkPixbufLoader *loader); + +G_END_DECLS + +#endif + + diff --git a/libs/tk/ydk-pixbuf/ydk-pixbuf/gdk-pixbuf/gdk-pixbuf-marshal.h b/libs/tk/ydk-pixbuf/ydk-pixbuf/gdk-pixbuf/gdk-pixbuf-marshal.h new file mode 100644 index 0000000000..0b4153a81e --- /dev/null +++ b/libs/tk/ydk-pixbuf/ydk-pixbuf/gdk-pixbuf/gdk-pixbuf-marshal.h @@ -0,0 +1,38 @@ +#if !defined(GDK_PIXBUF_DISABLE_DEPRECATED) || defined(GDK_PIXBUF_COMPILATION) +/* This file is generated by glib-genmarshal, do not modify it. This code is licensed under the same license as the containing project. Note that it links to GLib, so must comply with the LGPL linking clauses. */ +#ifndef ___GDK_PIXBUF_MARSHAL_MARSHAL_H__ +#define ___GDK_PIXBUF_MARSHAL_MARSHAL_H__ + +#include + +G_BEGIN_DECLS + +/* VOID:VOID (./gdk-pixbuf-marshal.list:25) */ +#define _gdk_pixbuf_marshal_VOID__VOID g_cclosure_marshal_VOID__VOID + +/* VOID:INT,INT (./gdk-pixbuf-marshal.list:26) */ +extern +void _gdk_pixbuf_marshal_VOID__INT_INT (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); + +/* VOID:INT,INT,INT,INT (./gdk-pixbuf-marshal.list:27) */ +extern +void _gdk_pixbuf_marshal_VOID__INT_INT_INT_INT (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); + +/* VOID:POINTER (./gdk-pixbuf-marshal.list:28) */ +#define _gdk_pixbuf_marshal_VOID__POINTER g_cclosure_marshal_VOID__POINTER + + +G_END_DECLS + +#endif /* ___GDK_PIXBUF_MARSHAL_MARSHAL_H__ */ +#endif /* !GDK_PIXBUF_DISABLE_DEPRECATED || GDK_PIXBUF_COMPILATION */ diff --git a/libs/tk/ydk-pixbuf/ydk-pixbuf/gdk-pixbuf/gdk-pixbuf-private.h b/libs/tk/ydk-pixbuf/ydk-pixbuf/gdk-pixbuf/gdk-pixbuf-private.h new file mode 100644 index 0000000000..e2096948d5 --- /dev/null +++ b/libs/tk/ydk-pixbuf/ydk-pixbuf/gdk-pixbuf/gdk-pixbuf-private.h @@ -0,0 +1,112 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ +/* GdkPixbuf library - Private declarations + * + * Copyright (C) 1999 The Free Software Foundation + * + * Authors: Mark Crichton + * Miguel de Icaza + * Federico Mena-Quintero + * Havoc Pennington + * + * 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, see . + */ + +#ifndef GDK_PIXBUF_PRIVATE_H +#define GDK_PIXBUF_PRIVATE_H + +#include + +#include + +#include "gdk-pixbuf-core.h" +#include "gdk-pixbuf-loader.h" +#include "gdk-pixbuf-io.h" +#include "gdk-pixbuf-i18n.h" + +#define LOAD_BUFFER_SIZE 65536 +#define SNIFF_BUFFER_SIZE 4096 + + + +typedef struct _GdkPixbufClass GdkPixbufClass; + +#define GDK_PIXBUF_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_PIXBUF, GdkPixbufClass)) +#define GDK_IS_PIXBUF_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_PIXBUF)) +#define GDK_PIXBUF_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_PIXBUF, GdkPixbufClass)) + +/* Private part of the GdkPixbuf structure */ +struct _GdkPixbuf { + GObject parent_instance; + + /* Color space */ + GdkColorspace colorspace; + + /* Number of channels, alpha included */ + int n_channels; + + /* Bits per channel */ + int bits_per_sample; + + /* Size */ + int width, height; + + /* Offset between rows */ + int rowstride; + + /* The pixel array */ + guchar *pixels; + + /* Destroy notification function; it is supposed to free the pixel array */ + GdkPixbufDestroyNotify destroy_fn; + + /* User data for the destroy notification function */ + gpointer destroy_fn_data; + + /* Replaces "pixels" member (and destroy notify) */ + GBytes *bytes; + + /* Do we have an alpha channel? */ + guint has_alpha : 1; +}; + +struct _GdkPixbufClass { + GObjectClass parent_class; + +}; + +#ifdef GDK_PIXBUF_ENABLE_BACKEND + +GdkPixbufModule *_gdk_pixbuf_get_module (guchar *buffer, guint size, + const gchar *filename, + GError **error); +GdkPixbufModule *_gdk_pixbuf_get_named_module (const char *name, + GError **error); +gboolean _gdk_pixbuf_load_module (GdkPixbufModule *image_module, + GError **error); + +GdkPixbuf *_gdk_pixbuf_generic_image_load (GdkPixbufModule *image_module, + FILE *f, + GError **error); + +GdkPixbufFormat *_gdk_pixbuf_get_format (GdkPixbufModule *image_module); + + +#endif /* GDK_PIXBUF_ENABLE_BACKEND */ + +GdkPixbuf * _gdk_pixbuf_new_from_resource_try_mmap (const char *resource_path); +GdkPixbufLoader *_gdk_pixbuf_loader_new_with_filename (const char *filename); + +#endif /* GDK_PIXBUF_PRIVATE_H */ + + diff --git a/libs/tk/ydk-pixbuf/ydk-pixbuf/gdk-pixbuf/gdk-pixbuf-scaled-anim.h b/libs/tk/ydk-pixbuf/ydk-pixbuf/gdk-pixbuf/gdk-pixbuf-scaled-anim.h new file mode 100644 index 0000000000..5442e8ef67 --- /dev/null +++ b/libs/tk/ydk-pixbuf/ydk-pixbuf/gdk-pixbuf/gdk-pixbuf-scaled-anim.h @@ -0,0 +1,45 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ +/* GdkPixbuf library - Simple transformations of animations + * + * Copyright (C) 2007 Red Hat, Inc + * + * Authors: Matthias Clasen + * + * 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, see . + */ + +#ifndef GDK_PIXBUF_SCALED_ANIM_H +#define GDK_PIXBUF_SCALED_ANIM_H + +#include + +G_BEGIN_DECLS + +#define GDK_TYPE_PIXBUF_SCALED_ANIM (gdk_pixbuf_scaled_anim_get_type ()) +#define GDK_TYPE_PIXBUF_SCALED_ANIM_ITER (gdk_pixbuf_scaled_anim_iter_get_type ()) + +typedef struct _GdkPixbufScaledAnim GdkPixbufScaledAnim; +typedef struct _GdkPixbufScaledAnimClass GdkPixbufScaledAnimClass; + +GType gdk_pixbuf_scaled_anim_get_type (void) G_GNUC_CONST; +GType gdk_pixbuf_scaled_anim_iter_get_type (void) G_GNUC_CONST; + +GdkPixbufScaledAnim *_gdk_pixbuf_scaled_anim_new (GdkPixbufAnimation *anim, + gdouble xscale, + gdouble yscale, + gdouble tscale); + +G_END_DECLS + +#endif /* GDK_PIXBUF_SCALED_ANIM_H */ diff --git a/libs/tk/ydk-pixbuf/ydk-pixbuf/gdk-pixbuf/gdk-pixbuf-simple-anim.h b/libs/tk/ydk-pixbuf/ydk-pixbuf/gdk-pixbuf/gdk-pixbuf-simple-anim.h new file mode 100644 index 0000000000..932be8a892 --- /dev/null +++ b/libs/tk/ydk-pixbuf/ydk-pixbuf/gdk-pixbuf/gdk-pixbuf-simple-anim.h @@ -0,0 +1,64 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */ +/* GdkPixbuf library - Simple frame-based animations + * + * Copyright (C) 2004 Dom Lachowicz + * + * Authors: Dom Lachowicz + * + * 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, see . + */ + +#ifndef GDK_PIXBUF_SIMPLE_ANIM_H +#define GDK_PIXBUF_SIMPLE_ANIM_H + +#if defined(GDK_PIXBUF_DISABLE_SINGLE_INCLUDES) && !defined (GDK_PIXBUF_H_INSIDE) && !defined (GDK_PIXBUF_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +/** + * GdkPixbufSimpleAnim: + * + * An opaque struct representing a simple animation. + */ +typedef struct _GdkPixbufSimpleAnim GdkPixbufSimpleAnim; +typedef struct _GdkPixbufSimpleAnimClass GdkPixbufSimpleAnimClass; + +#define GDK_TYPE_PIXBUF_SIMPLE_ANIM (gdk_pixbuf_simple_anim_get_type ()) +#define GDK_PIXBUF_SIMPLE_ANIM(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_PIXBUF_SIMPLE_ANIM, GdkPixbufSimpleAnim)) +#define GDK_IS_PIXBUF_SIMPLE_ANIM(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_PIXBUF_SIMPLE_ANIM)) + +#define GDK_PIXBUF_SIMPLE_ANIM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_PIXBUF_SIMPLE_ANIM, GdkPixbufSimpleAnimClass)) +#define GDK_IS_PIXBUF_SIMPLE_ANIM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_PIXBUF_SIMPLE_ANIM)) +#define GDK_PIXBUF_SIMPLE_ANIM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_PIXBUF_SIMPLE_ANIM, GdkPixbufSimpleAnimClass)) + +GType gdk_pixbuf_simple_anim_get_type (void) G_GNUC_CONST; +GType gdk_pixbuf_simple_anim_iter_get_type (void) G_GNUC_CONST; + +GdkPixbufSimpleAnim *gdk_pixbuf_simple_anim_new (gint width, + gint height, + gfloat rate); +void gdk_pixbuf_simple_anim_add_frame (GdkPixbufSimpleAnim *animation, + GdkPixbuf *pixbuf); +void gdk_pixbuf_simple_anim_set_loop (GdkPixbufSimpleAnim *animation, + gboolean loop); +gboolean gdk_pixbuf_simple_anim_get_loop (GdkPixbufSimpleAnim *animation); + +G_END_DECLS + + +#endif /* GDK_PIXBUF_SIMPLE_ANIM_H */ diff --git a/libs/tk/ydk-pixbuf/ydk-pixbuf/gdk-pixbuf/gdk-pixbuf-transform.h b/libs/tk/ydk-pixbuf/ydk-pixbuf/gdk-pixbuf/gdk-pixbuf-transform.h new file mode 100644 index 0000000000..2a8f936cf3 --- /dev/null +++ b/libs/tk/ydk-pixbuf/ydk-pixbuf/gdk-pixbuf/gdk-pixbuf-transform.h @@ -0,0 +1,158 @@ +/* GdkPixbuf library - transformations + * + * Copyright (C) 2003 The Free Software Foundation + * + * Authors: Mark Crichton + * Miguel de Icaza + * Federico Mena-Quintero + * Havoc Pennington + * + * 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, see . + */ + +#ifndef GDK_PIXBUF_TRANSFORM_H +#define GDK_PIXBUF_TRANSFORM_H + +#if defined(GDK_PIXBUF_DISABLE_SINGLE_INCLUDES) && !defined (GDK_PIXBUF_H_INSIDE) && !defined (GDK_PIXBUF_COMPILATION) +#error "Only can be included directly." +#endif + +#include +#include + + +G_BEGIN_DECLS + +/* Scaling */ + +/** + * GdkInterpType: + * @GDK_INTERP_NEAREST: Nearest neighbor sampling; this is the fastest + * and lowest quality mode. Quality is normally unacceptable when scaling + * down, but may be OK when scaling up. + * @GDK_INTERP_TILES: This is an accurate simulation of the PostScript + * image operator without any interpolation enabled. Each pixel is + * rendered as a tiny parallelogram of solid color, the edges of which + * are implemented with antialiasing. It resembles nearest neighbor for + * enlargement, and bilinear for reduction. + * @GDK_INTERP_BILINEAR: Best quality/speed balance; use this mode by + * default. Bilinear interpolation. For enlargement, it is + * equivalent to point-sampling the ideal bilinear-interpolated image. + * For reduction, it is equivalent to laying down small tiles and + * integrating over the coverage area. + * @GDK_INTERP_HYPER: This is the slowest and highest quality + * reconstruction function. It is derived from the hyperbolic filters in + * Wolberg's "Digital Image Warping", and is formally defined as the + * hyperbolic-filter sampling the ideal hyperbolic-filter interpolated + * image (the filter is designed to be idempotent for 1:1 pixel mapping). + * + * This enumeration describes the different interpolation modes that + * can be used with the scaling functions. @GDK_INTERP_NEAREST is + * the fastest scaling method, but has horrible quality when + * scaling down. @GDK_INTERP_BILINEAR is the best choice if you + * aren't sure what to choose, it has a good speed/quality balance. + * + * + * Cubic filtering is missing from the list; hyperbolic + * interpolation is just as fast and results in higher quality. + * + */ +typedef enum { + GDK_INTERP_NEAREST, + GDK_INTERP_TILES, + GDK_INTERP_BILINEAR, + GDK_INTERP_HYPER +} GdkInterpType; + +/** + * GdkPixbufRotation: + * @GDK_PIXBUF_ROTATE_NONE: No rotation. + * @GDK_PIXBUF_ROTATE_COUNTERCLOCKWISE: Rotate by 90 degrees. + * @GDK_PIXBUF_ROTATE_UPSIDEDOWN: Rotate by 180 degrees. + * @GDK_PIXBUF_ROTATE_CLOCKWISE: Rotate by 270 degrees. + * + * The possible rotations which can be passed to gdk_pixbuf_rotate_simple(). + * To make them easier to use, their numerical values are the actual degrees. + */ +typedef enum { + GDK_PIXBUF_ROTATE_NONE = 0, + GDK_PIXBUF_ROTATE_COUNTERCLOCKWISE = 90, + GDK_PIXBUF_ROTATE_UPSIDEDOWN = 180, + GDK_PIXBUF_ROTATE_CLOCKWISE = 270 +} GdkPixbufRotation; + +void gdk_pixbuf_scale (const GdkPixbuf *src, + GdkPixbuf *dest, + int dest_x, + int dest_y, + int dest_width, + int dest_height, + double offset_x, + double offset_y, + double scale_x, + double scale_y, + GdkInterpType interp_type); +void gdk_pixbuf_composite (const GdkPixbuf *src, + GdkPixbuf *dest, + int dest_x, + int dest_y, + int dest_width, + int dest_height, + double offset_x, + double offset_y, + double scale_x, + double scale_y, + GdkInterpType interp_type, + int overall_alpha); +void gdk_pixbuf_composite_color (const GdkPixbuf *src, + GdkPixbuf *dest, + int dest_x, + int dest_y, + int dest_width, + int dest_height, + double offset_x, + double offset_y, + double scale_x, + double scale_y, + GdkInterpType interp_type, + int overall_alpha, + int check_x, + int check_y, + int check_size, + guint32 color1, + guint32 color2); + +GdkPixbuf *gdk_pixbuf_scale_simple (const GdkPixbuf *src, + int dest_width, + int dest_height, + GdkInterpType interp_type); + +GdkPixbuf *gdk_pixbuf_composite_color_simple (const GdkPixbuf *src, + int dest_width, + int dest_height, + GdkInterpType interp_type, + int overall_alpha, + int check_size, + guint32 color1, + guint32 color2); + +GdkPixbuf *gdk_pixbuf_rotate_simple (const GdkPixbuf *src, + GdkPixbufRotation angle); +GdkPixbuf *gdk_pixbuf_flip (const GdkPixbuf *src, + gboolean horizontal); + +G_END_DECLS + + +#endif /* GDK_PIXBUF_TRANSFORM_H */ diff --git a/libs/tk/ydk-pixbuf/ydk-pixbuf/gdk-pixbuf/gdk-pixbuf.h b/libs/tk/ydk-pixbuf/ydk-pixbuf/gdk-pixbuf/gdk-pixbuf.h new file mode 100644 index 0000000000..29cdf6f426 --- /dev/null +++ b/libs/tk/ydk-pixbuf/ydk-pixbuf/gdk-pixbuf/gdk-pixbuf.h @@ -0,0 +1,43 @@ +/* GdkPixbuf library - Main header file + * + * Copyright (C) 1999 The Free Software Foundation + * + * Authors: Mark Crichton + * Miguel de Icaza + * Federico Mena-Quintero + * Havoc Pennington + * + * 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, see . + */ + +#ifndef GDK_PIXBUF_H +#define GDK_PIXBUF_H + +#define GDK_PIXBUF_H_INSIDE + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#undef GDK_PIXBUF_H_INSIDE + +#endif /* GDK_PIXBUF_H */ diff --git a/libs/tk/ydk-pixbuf/ydk-pixbuf/gdk-pixbuf/gdk-pixdata.h b/libs/tk/ydk-pixbuf/ydk-pixbuf/gdk-pixbuf/gdk-pixdata.h new file mode 100644 index 0000000000..51de915508 --- /dev/null +++ b/libs/tk/ydk-pixbuf/ydk-pixbuf/gdk-pixbuf/gdk-pixdata.h @@ -0,0 +1,168 @@ +/* GdkPixbuf library - GdkPixdata - functions for inlined pixbuf handling + * Copyright (C) 1999, 2001 Tim Janik + * + * 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, see . + */ +#ifndef __GDK_PIXDATA_H__ +#define __GDK_PIXDATA_H__ + +#include + +G_BEGIN_DECLS + +/** + * GDK_PIXBUF_MAGIC_NUMBER: + * + * Magic number for #GdkPixdata structures. + **/ +#define GDK_PIXBUF_MAGIC_NUMBER (0x47646b50) /* 'GdkP' */ + +/** + * GdkPixdataType: + * @GDK_PIXDATA_COLOR_TYPE_RGB: each pixel has red, green and blue samples. + * @GDK_PIXDATA_COLOR_TYPE_RGBA: each pixel has red, green and blue samples + * and an alpha value. + * @GDK_PIXDATA_COLOR_TYPE_MASK: mask for the colortype flags of the enum. + * @GDK_PIXDATA_SAMPLE_WIDTH_8: each sample has 8 bits. + * @GDK_PIXDATA_SAMPLE_WIDTH_MASK: mask for the sample width flags of the enum. + * @GDK_PIXDATA_ENCODING_RAW: the pixel data is in raw form. + * @GDK_PIXDATA_ENCODING_RLE: the pixel data is run-length encoded. Runs may + * be up to 127 bytes long; their length is stored in a single byte + * preceding the pixel data for the run. If a run is constant, its length + * byte has the high bit set and the pixel data consists of a single pixel + * which must be repeated. + * @GDK_PIXDATA_ENCODING_MASK: mask for the encoding flags of the enum. + * + * An enumeration containing three sets of flags for a #GdkPixdata struct: + * one for the used colorspace, one for the width of the samples and one + * for the encoding of the pixel data. + **/ +typedef enum +{ + /* colorspace + alpha */ + GDK_PIXDATA_COLOR_TYPE_RGB = 0x01, + GDK_PIXDATA_COLOR_TYPE_RGBA = 0x02, + GDK_PIXDATA_COLOR_TYPE_MASK = 0xff, + /* width, support 8bits only currently */ + GDK_PIXDATA_SAMPLE_WIDTH_8 = 0x01 << 16, + GDK_PIXDATA_SAMPLE_WIDTH_MASK = 0x0f << 16, + /* encoding */ + GDK_PIXDATA_ENCODING_RAW = 0x01 << 24, + GDK_PIXDATA_ENCODING_RLE = 0x02 << 24, + GDK_PIXDATA_ENCODING_MASK = 0x0f << 24 +} GdkPixdataType; + +/** + * GdkPixdata: + * @magic: magic number. A valid #GdkPixdata structure must have + * #GDK_PIXBUF_MAGIC_NUMBER here. + * @length: less than 1 to disable length checks, otherwise + * #GDK_PIXDATA_HEADER_LENGTH + length of @pixel_data. + * @pixdata_type: information about colorspace, sample width and + * encoding, in a #GdkPixdataType. + * @rowstride: Distance in bytes between rows. + * @width: Width of the image in pixels. + * @height: Height of the image in pixels. + * @pixel_data: (array) (element-type guint8): @width x @height pixels, encoded according to @pixdata_type + * and @rowstride. + * + * A #GdkPixdata contains pixbuf information in a form suitable for + * serialization and streaming. + **/ +typedef struct _GdkPixdata GdkPixdata; +struct _GdkPixdata +{ + guint32 magic; /* GDK_PIXBUF_MAGIC_NUMBER */ + gint32 length; /* <1 to disable length checks, otherwise: + * GDK_PIXDATA_HEADER_LENGTH + pixel_data length + */ + guint32 pixdata_type; /* GdkPixdataType */ + guint32 rowstride; + guint32 width; + guint32 height; + guint8 *pixel_data; +}; + +/** + * GDK_PIXDATA_HEADER_LENGTH: + * + * The length of a #GdkPixdata structure without the @pixel_data pointer. + **/ +#define GDK_PIXDATA_HEADER_LENGTH (4 + 4 + 4 + 4 + 4 + 4) + +/* the returned stream is plain htonl of GdkPixdata members + pixel_data */ +guint8* gdk_pixdata_serialize (const GdkPixdata *pixdata, + guint *stream_length_p); +gboolean gdk_pixdata_deserialize (GdkPixdata *pixdata, + guint stream_length, + const guint8 *stream, + GError **error); +gpointer gdk_pixdata_from_pixbuf (GdkPixdata *pixdata, + const GdkPixbuf *pixbuf, + gboolean use_rle); +GdkPixbuf* gdk_pixbuf_from_pixdata (const GdkPixdata *pixdata, + gboolean copy_pixels, + GError **error); +/** + * GdkPixdataDumpType: + * @GDK_PIXDATA_DUMP_PIXDATA_STREAM: Generate pixbuf data stream (a single + * string containing a serialized #GdkPixdata structure in network byte + * order). + * @GDK_PIXDATA_DUMP_PIXDATA_STRUCT: Generate #GdkPixdata structure (needs + * the #GdkPixdata structure definition from gdk-pixdata.h). + * @GDK_PIXDATA_DUMP_MACROS: Generate *_ROWSTRIDE, + * *_WIDTH, *_HEIGHT, + * *_BYTES_PER_PIXEL and + * *_RLE_PIXEL_DATA or *_PIXEL_DATA + * macro definitions for the image. + * @GDK_PIXDATA_DUMP_GTYPES: Generate GLib data types instead of + * standard C data types. + * @GDK_PIXDATA_DUMP_CTYPES: Generate standard C data types instead of + * GLib data types. + * @GDK_PIXDATA_DUMP_STATIC: Generate static symbols. + * @GDK_PIXDATA_DUMP_CONST: Generate const symbols. + * @GDK_PIXDATA_DUMP_RLE_DECODER: Provide a *_RUN_LENGTH_DECODE(image_buf, rle_data, size, bpp) + * macro definition to decode run-length encoded image data. + * + * An enumeration which is used by gdk_pixdata_to_csource() to + * determine the form of C source to be generated. The three values + * @GDK_PIXDATA_DUMP_PIXDATA_STREAM, @GDK_PIXDATA_DUMP_PIXDATA_STRUCT + * and @GDK_PIXDATA_DUMP_MACROS are mutually exclusive, as are + * @GDK_PIXBUF_DUMP_GTYPES and @GDK_PIXBUF_DUMP_CTYPES. The remaining + * elements are optional flags that can be freely added. + **/ +typedef enum +{ + /* type of source to save */ + GDK_PIXDATA_DUMP_PIXDATA_STREAM = 0, + GDK_PIXDATA_DUMP_PIXDATA_STRUCT = 1, + GDK_PIXDATA_DUMP_MACROS = 2, + /* type of variables to use */ + GDK_PIXDATA_DUMP_GTYPES = 0, + GDK_PIXDATA_DUMP_CTYPES = 1 << 8, + GDK_PIXDATA_DUMP_STATIC = 1 << 9, + GDK_PIXDATA_DUMP_CONST = 1 << 10, + /* save RLE decoder macro? */ + GDK_PIXDATA_DUMP_RLE_DECODER = 1 << 16 +} GdkPixdataDumpType; + + +GString* gdk_pixdata_to_csource (GdkPixdata *pixdata, + const gchar *name, + GdkPixdataDumpType dump_type); + + +G_END_DECLS + +#endif /* __GDK_PIXDATA_H__ */ diff --git a/libs/tk/ydk-pixbuf/ydk-pixbuf/gdk-pixbuf/xpm-color-table.h b/libs/tk/ydk-pixbuf/ydk-pixbuf/gdk-pixbuf/xpm-color-table.h new file mode 100644 index 0000000000..8e9e6057a2 --- /dev/null +++ b/libs/tk/ydk-pixbuf/ydk-pixbuf/gdk-pixbuf/xpm-color-table.h @@ -0,0 +1,1347 @@ +/* xpm-color-table.h: Generated by gen-color-table.pl from rgb.txt + * + * Date: Sat Apr 6 06:45:32 2013 + * + * Do not edit. + */ +static const char color_names[] = + "AliceBlue\0" + "AntiqueWhite\0" + "AntiqueWhite1\0" + "AntiqueWhite2\0" + "AntiqueWhite3\0" + "AntiqueWhite4\0" + "aqua\0" + "aquamarine\0" + "aquamarine1\0" + "aquamarine2\0" + "aquamarine3\0" + "aquamarine4\0" + "azure\0" + "azure1\0" + "azure2\0" + "azure3\0" + "azure4\0" + "beige\0" + "bisque\0" + "bisque1\0" + "bisque2\0" + "bisque3\0" + "bisque4\0" + "black\0" + "BlanchedAlmond\0" + "blue\0" + "blue1\0" + "blue2\0" + "blue3\0" + "blue4\0" + "BlueViolet\0" + "brown\0" + "brown1\0" + "brown2\0" + "brown3\0" + "brown4\0" + "burlywood\0" + "burlywood1\0" + "burlywood2\0" + "burlywood3\0" + "burlywood4\0" + "CadetBlue\0" + "CadetBlue1\0" + "CadetBlue2\0" + "CadetBlue3\0" + "CadetBlue4\0" + "chartreuse\0" + "chartreuse1\0" + "chartreuse2\0" + "chartreuse3\0" + "chartreuse4\0" + "chocolate\0" + "chocolate1\0" + "chocolate2\0" + "chocolate3\0" + "chocolate4\0" + "coral\0" + "coral1\0" + "coral2\0" + "coral3\0" + "coral4\0" + "CornflowerBlue\0" + "cornsilk\0" + "cornsilk1\0" + "cornsilk2\0" + "cornsilk3\0" + "cornsilk4\0" + "crimson\0" + "cyan\0" + "cyan1\0" + "cyan2\0" + "cyan3\0" + "cyan4\0" + "DarkBlue\0" + "DarkCyan\0" + "DarkGoldenrod\0" + "DarkGoldenrod1\0" + "DarkGoldenrod2\0" + "DarkGoldenrod3\0" + "DarkGoldenrod4\0" + "DarkGray\0" + "DarkGreen\0" + "DarkGrey\0" + "DarkKhaki\0" + "DarkMagenta\0" + "DarkOliveGreen\0" + "DarkOliveGreen1\0" + "DarkOliveGreen2\0" + "DarkOliveGreen3\0" + "DarkOliveGreen4\0" + "DarkOrange\0" + "DarkOrange1\0" + "DarkOrange2\0" + "DarkOrange3\0" + "DarkOrange4\0" + "DarkOrchid\0" + "DarkOrchid1\0" + "DarkOrchid2\0" + "DarkOrchid3\0" + "DarkOrchid4\0" + "DarkRed\0" + "DarkSalmon\0" + "DarkSeaGreen\0" + "DarkSeaGreen1\0" + "DarkSeaGreen2\0" + "DarkSeaGreen3\0" + "DarkSeaGreen4\0" + "DarkSlateBlue\0" + "DarkSlateGray\0" + "DarkSlateGray1\0" + "DarkSlateGray2\0" + "DarkSlateGray3\0" + "DarkSlateGray4\0" + "DarkSlateGrey\0" + "DarkTurquoise\0" + "DarkViolet\0" + "DeepPink\0" + "DeepPink1\0" + "DeepPink2\0" + "DeepPink3\0" + "DeepPink4\0" + "DeepSkyBlue\0" + "DeepSkyBlue1\0" + "DeepSkyBlue2\0" + "DeepSkyBlue3\0" + "DeepSkyBlue4\0" + "DimGray\0" + "DimGrey\0" + "DodgerBlue\0" + "DodgerBlue1\0" + "DodgerBlue2\0" + "DodgerBlue3\0" + "DodgerBlue4\0" + "firebrick\0" + "firebrick1\0" + "firebrick2\0" + "firebrick3\0" + "firebrick4\0" + "FloralWhite\0" + "ForestGreen\0" + "fuchsia\0" + "gainsboro\0" + "GhostWhite\0" + "gold\0" + "gold1\0" + "gold2\0" + "gold3\0" + "gold4\0" + "goldenrod\0" + "goldenrod1\0" + "goldenrod2\0" + "goldenrod3\0" + "goldenrod4\0" + "gray\0" + "gray0\0" + "gray1\0" + "gray10\0" + "gray100\0" + "gray11\0" + "gray12\0" + "gray13\0" + "gray14\0" + "gray15\0" + "gray16\0" + "gray17\0" + "gray18\0" + "gray19\0" + "gray2\0" + "gray20\0" + "gray21\0" + "gray22\0" + "gray23\0" + "gray24\0" + "gray25\0" + "gray26\0" + "gray27\0" + "gray28\0" + "gray29\0" + "gray3\0" + "gray30\0" + "gray31\0" + "gray32\0" + "gray33\0" + "gray34\0" + "gray35\0" + "gray36\0" + "gray37\0" + "gray38\0" + "gray39\0" + "gray4\0" + "gray40\0" + "gray41\0" + "gray42\0" + "gray43\0" + "gray44\0" + "gray45\0" + "gray46\0" + "gray47\0" + "gray48\0" + "gray49\0" + "gray5\0" + "gray50\0" + "gray51\0" + "gray52\0" + "gray53\0" + "gray54\0" + "gray55\0" + "gray56\0" + "gray57\0" + "gray58\0" + "gray59\0" + "gray6\0" + "gray60\0" + "gray61\0" + "gray62\0" + "gray63\0" + "gray64\0" + "gray65\0" + "gray66\0" + "gray67\0" + "gray68\0" + "gray69\0" + "gray7\0" + "gray70\0" + "gray71\0" + "gray72\0" + "gray73\0" + "gray74\0" + "gray75\0" + "gray76\0" + "gray77\0" + "gray78\0" + "gray79\0" + "gray8\0" + "gray80\0" + "gray81\0" + "gray82\0" + "gray83\0" + "gray84\0" + "gray85\0" + "gray86\0" + "gray87\0" + "gray88\0" + "gray89\0" + "gray9\0" + "gray90\0" + "gray91\0" + "gray92\0" + "gray93\0" + "gray94\0" + "gray95\0" + "gray96\0" + "gray97\0" + "gray98\0" + "gray99\0" + "green\0" + "green1\0" + "green2\0" + "green3\0" + "green4\0" + "GreenYellow\0" + "grey\0" + "grey0\0" + "grey1\0" + "grey10\0" + "grey100\0" + "grey11\0" + "grey12\0" + "grey13\0" + "grey14\0" + "grey15\0" + "grey16\0" + "grey17\0" + "grey18\0" + "grey19\0" + "grey2\0" + "grey20\0" + "grey21\0" + "grey22\0" + "grey23\0" + "grey24\0" + "grey25\0" + "grey26\0" + "grey27\0" + "grey28\0" + "grey29\0" + "grey3\0" + "grey30\0" + "grey31\0" + "grey32\0" + "grey33\0" + "grey34\0" + "grey35\0" + "grey36\0" + "grey37\0" + "grey38\0" + "grey39\0" + "grey4\0" + "grey40\0" + "grey41\0" + "grey42\0" + "grey43\0" + "grey44\0" + "grey45\0" + "grey46\0" + "grey47\0" + "grey48\0" + "grey49\0" + "grey5\0" + "grey50\0" + "grey51\0" + "grey52\0" + "grey53\0" + "grey54\0" + "grey55\0" + "grey56\0" + "grey57\0" + "grey58\0" + "grey59\0" + "grey6\0" + "grey60\0" + "grey61\0" + "grey62\0" + "grey63\0" + "grey64\0" + "grey65\0" + "grey66\0" + "grey67\0" + "grey68\0" + "grey69\0" + "grey7\0" + "grey70\0" + "grey71\0" + "grey72\0" + "grey73\0" + "grey74\0" + "grey75\0" + "grey76\0" + "grey77\0" + "grey78\0" + "grey79\0" + "grey8\0" + "grey80\0" + "grey81\0" + "grey82\0" + "grey83\0" + "grey84\0" + "grey85\0" + "grey86\0" + "grey87\0" + "grey88\0" + "grey89\0" + "grey9\0" + "grey90\0" + "grey91\0" + "grey92\0" + "grey93\0" + "grey94\0" + "grey95\0" + "grey96\0" + "grey97\0" + "grey98\0" + "grey99\0" + "honeydew\0" + "honeydew1\0" + "honeydew2\0" + "honeydew3\0" + "honeydew4\0" + "HotPink\0" + "HotPink1\0" + "HotPink2\0" + "HotPink3\0" + "HotPink4\0" + "IndianRed\0" + "IndianRed1\0" + "IndianRed2\0" + "IndianRed3\0" + "IndianRed4\0" + "indigo\0" + "ivory\0" + "ivory1\0" + "ivory2\0" + "ivory3\0" + "ivory4\0" + "khaki\0" + "khaki1\0" + "khaki2\0" + "khaki3\0" + "khaki4\0" + "lavender\0" + "LavenderBlush\0" + "LavenderBlush1\0" + "LavenderBlush2\0" + "LavenderBlush3\0" + "LavenderBlush4\0" + "LawnGreen\0" + "LemonChiffon\0" + "LemonChiffon1\0" + "LemonChiffon2\0" + "LemonChiffon3\0" + "LemonChiffon4\0" + "LightBlue\0" + "LightBlue1\0" + "LightBlue2\0" + "LightBlue3\0" + "LightBlue4\0" + "LightCoral\0" + "LightCyan\0" + "LightCyan1\0" + "LightCyan2\0" + "LightCyan3\0" + "LightCyan4\0" + "LightGoldenrod\0" + "LightGoldenrod1\0" + "LightGoldenrod2\0" + "LightGoldenrod3\0" + "LightGoldenrod4\0" + "LightGoldenrodYellow\0" + "LightGray\0" + "LightGreen\0" + "LightGrey\0" + "LightPink\0" + "LightPink1\0" + "LightPink2\0" + "LightPink3\0" + "LightPink4\0" + "LightSalmon\0" + "LightSalmon1\0" + "LightSalmon2\0" + "LightSalmon3\0" + "LightSalmon4\0" + "LightSeaGreen\0" + "LightSkyBlue\0" + "LightSkyBlue1\0" + "LightSkyBlue2\0" + "LightSkyBlue3\0" + "LightSkyBlue4\0" + "LightSlateBlue\0" + "LightSlateGray\0" + "LightSlateGrey\0" + "LightSteelBlue\0" + "LightSteelBlue1\0" + "LightSteelBlue2\0" + "LightSteelBlue3\0" + "LightSteelBlue4\0" + "LightYellow\0" + "LightYellow1\0" + "LightYellow2\0" + "LightYellow3\0" + "LightYellow4\0" + "lime\0" + "LimeGreen\0" + "linen\0" + "magenta\0" + "magenta1\0" + "magenta2\0" + "magenta3\0" + "magenta4\0" + "maroon\0" + "maroon1\0" + "maroon2\0" + "maroon3\0" + "maroon4\0" + "MediumAquamarine\0" + "MediumBlue\0" + "MediumOrchid\0" + "MediumOrchid1\0" + "MediumOrchid2\0" + "MediumOrchid3\0" + "MediumOrchid4\0" + "MediumPurple\0" + "MediumPurple1\0" + "MediumPurple2\0" + "MediumPurple3\0" + "MediumPurple4\0" + "MediumSeaGreen\0" + "MediumSlateBlue\0" + "MediumSpringGreen\0" + "MediumTurquoise\0" + "MediumVioletRed\0" + "MidnightBlue\0" + "MintCream\0" + "MistyRose\0" + "MistyRose1\0" + "MistyRose2\0" + "MistyRose3\0" + "MistyRose4\0" + "moccasin\0" + "NavajoWhite\0" + "NavajoWhite1\0" + "NavajoWhite2\0" + "NavajoWhite3\0" + "NavajoWhite4\0" + "navy\0" + "NavyBlue\0" + "OldLace\0" + "olive\0" + "OliveDrab\0" + "OliveDrab1\0" + "OliveDrab2\0" + "OliveDrab3\0" + "OliveDrab4\0" + "orange\0" + "orange1\0" + "orange2\0" + "orange3\0" + "orange4\0" + "OrangeRed\0" + "OrangeRed1\0" + "OrangeRed2\0" + "OrangeRed3\0" + "OrangeRed4\0" + "orchid\0" + "orchid1\0" + "orchid2\0" + "orchid3\0" + "orchid4\0" + "PaleGoldenrod\0" + "PaleGreen\0" + "PaleGreen1\0" + "PaleGreen2\0" + "PaleGreen3\0" + "PaleGreen4\0" + "PaleTurquoise\0" + "PaleTurquoise1\0" + "PaleTurquoise2\0" + "PaleTurquoise3\0" + "PaleTurquoise4\0" + "PaleVioletRed\0" + "PaleVioletRed1\0" + "PaleVioletRed2\0" + "PaleVioletRed3\0" + "PaleVioletRed4\0" + "PapayaWhip\0" + "PeachPuff\0" + "PeachPuff1\0" + "PeachPuff2\0" + "PeachPuff3\0" + "PeachPuff4\0" + "peru\0" + "pink\0" + "pink1\0" + "pink2\0" + "pink3\0" + "pink4\0" + "plum\0" + "plum1\0" + "plum2\0" + "plum3\0" + "plum4\0" + "PowderBlue\0" + "purple\0" + "purple1\0" + "purple2\0" + "purple3\0" + "purple4\0" + "red\0" + "red1\0" + "red2\0" + "red3\0" + "red4\0" + "RosyBrown\0" + "RosyBrown1\0" + "RosyBrown2\0" + "RosyBrown3\0" + "RosyBrown4\0" + "RoyalBlue\0" + "RoyalBlue1\0" + "RoyalBlue2\0" + "RoyalBlue3\0" + "RoyalBlue4\0" + "SaddleBrown\0" + "salmon\0" + "salmon1\0" + "salmon2\0" + "salmon3\0" + "salmon4\0" + "SandyBrown\0" + "SeaGreen\0" + "SeaGreen1\0" + "SeaGreen2\0" + "SeaGreen3\0" + "SeaGreen4\0" + "seashell\0" + "seashell1\0" + "seashell2\0" + "seashell3\0" + "seashell4\0" + "sienna\0" + "sienna1\0" + "sienna2\0" + "sienna3\0" + "sienna4\0" + "silver\0" + "SkyBlue\0" + "SkyBlue1\0" + "SkyBlue2\0" + "SkyBlue3\0" + "SkyBlue4\0" + "SlateBlue\0" + "SlateBlue1\0" + "SlateBlue2\0" + "SlateBlue3\0" + "SlateBlue4\0" + "SlateGray\0" + "SlateGray1\0" + "SlateGray2\0" + "SlateGray3\0" + "SlateGray4\0" + "SlateGrey\0" + "snow\0" + "snow1\0" + "snow2\0" + "snow3\0" + "snow4\0" + "SpringGreen\0" + "SpringGreen1\0" + "SpringGreen2\0" + "SpringGreen3\0" + "SpringGreen4\0" + "SteelBlue\0" + "SteelBlue1\0" + "SteelBlue2\0" + "SteelBlue3\0" + "SteelBlue4\0" + "tan\0" + "tan1\0" + "tan2\0" + "tan3\0" + "tan4\0" + "teal\0" + "thistle\0" + "thistle1\0" + "thistle2\0" + "thistle3\0" + "thistle4\0" + "tomato\0" + "tomato1\0" + "tomato2\0" + "tomato3\0" + "tomato4\0" + "turquoise\0" + "turquoise1\0" + "turquoise2\0" + "turquoise3\0" + "turquoise4\0" + "violet\0" + "VioletRed\0" + "VioletRed1\0" + "VioletRed2\0" + "VioletRed3\0" + "VioletRed4\0" + "wheat\0" + "wheat1\0" + "wheat2\0" + "wheat3\0" + "wheat4\0" + "white\0" + "WhiteSmoke\0" + "yellow\0" + "yellow1\0" + "yellow2\0" + "yellow3\0" + "yellow4\0" + "YellowGreen\0"; + +typedef struct { + guint16 name_offset; + guchar red; + guchar green; + guchar blue; +} XPMColorEntry; + +static const XPMColorEntry xColors[] = { + { 0, 240, 248, 255 }, + { 10, 250, 235, 215 }, + { 23, 255, 239, 219 }, + { 37, 238, 223, 204 }, + { 51, 205, 192, 176 }, + { 65, 139, 131, 120 }, + { 79, 0, 255, 255 }, + { 84, 127, 255, 212 }, + { 95, 127, 255, 212 }, + { 107, 118, 238, 198 }, + { 119, 102, 205, 170 }, + { 131, 69, 139, 116 }, + { 143, 240, 255, 255 }, + { 149, 240, 255, 255 }, + { 156, 224, 238, 238 }, + { 163, 193, 205, 205 }, + { 170, 131, 139, 139 }, + { 177, 245, 245, 220 }, + { 183, 255, 228, 196 }, + { 190, 255, 228, 196 }, + { 198, 238, 213, 183 }, + { 206, 205, 183, 158 }, + { 214, 139, 125, 107 }, + { 222, 0, 0, 0 }, + { 228, 255, 235, 205 }, + { 243, 0, 0, 255 }, + { 248, 0, 0, 255 }, + { 254, 0, 0, 238 }, + { 260, 0, 0, 205 }, + { 266, 0, 0, 139 }, + { 272, 138, 43, 226 }, + { 283, 165, 42, 42 }, + { 289, 255, 64, 64 }, + { 296, 238, 59, 59 }, + { 303, 205, 51, 51 }, + { 310, 139, 35, 35 }, + { 317, 222, 184, 135 }, + { 327, 255, 211, 155 }, + { 338, 238, 197, 145 }, + { 349, 205, 170, 125 }, + { 360, 139, 115, 85 }, + { 371, 95, 158, 160 }, + { 381, 152, 245, 255 }, + { 392, 142, 229, 238 }, + { 403, 122, 197, 205 }, + { 414, 83, 134, 139 }, + { 425, 127, 255, 0 }, + { 436, 127, 255, 0 }, + { 448, 118, 238, 0 }, + { 460, 102, 205, 0 }, + { 472, 69, 139, 0 }, + { 484, 210, 105, 30 }, + { 494, 255, 127, 36 }, + { 505, 238, 118, 33 }, + { 516, 205, 102, 29 }, + { 527, 139, 69, 19 }, + { 538, 255, 127, 80 }, + { 544, 255, 114, 86 }, + { 551, 238, 106, 80 }, + { 558, 205, 91, 69 }, + { 565, 139, 62, 47 }, + { 572, 100, 149, 237 }, + { 587, 255, 248, 220 }, + { 596, 255, 248, 220 }, + { 606, 238, 232, 205 }, + { 616, 205, 200, 177 }, + { 626, 139, 136, 120 }, + { 636, 220, 20, 60 }, + { 644, 0, 255, 255 }, + { 649, 0, 255, 255 }, + { 655, 0, 238, 238 }, + { 661, 0, 205, 205 }, + { 667, 0, 139, 139 }, + { 673, 0, 0, 139 }, + { 682, 0, 139, 139 }, + { 691, 184, 134, 11 }, + { 705, 255, 185, 15 }, + { 720, 238, 173, 14 }, + { 735, 205, 149, 12 }, + { 750, 139, 101, 8 }, + { 765, 169, 169, 169 }, + { 774, 0, 100, 0 }, + { 784, 169, 169, 169 }, + { 793, 189, 183, 107 }, + { 803, 139, 0, 139 }, + { 815, 85, 107, 47 }, + { 830, 202, 255, 112 }, + { 846, 188, 238, 104 }, + { 862, 162, 205, 90 }, + { 878, 110, 139, 61 }, + { 894, 255, 140, 0 }, + { 905, 255, 127, 0 }, + { 917, 238, 118, 0 }, + { 929, 205, 102, 0 }, + { 941, 139, 69, 0 }, + { 953, 153, 50, 204 }, + { 964, 191, 62, 255 }, + { 976, 178, 58, 238 }, + { 988, 154, 50, 205 }, + { 1000, 104, 34, 139 }, + { 1012, 139, 0, 0 }, + { 1020, 233, 150, 122 }, + { 1031, 143, 188, 143 }, + { 1044, 193, 255, 193 }, + { 1058, 180, 238, 180 }, + { 1072, 155, 205, 155 }, + { 1086, 105, 139, 105 }, + { 1100, 72, 61, 139 }, + { 1114, 47, 79, 79 }, + { 1128, 151, 255, 255 }, + { 1143, 141, 238, 238 }, + { 1158, 121, 205, 205 }, + { 1173, 82, 139, 139 }, + { 1188, 47, 79, 79 }, + { 1202, 0, 206, 209 }, + { 1216, 148, 0, 211 }, + { 1227, 255, 20, 147 }, + { 1236, 255, 20, 147 }, + { 1246, 238, 18, 137 }, + { 1256, 205, 16, 118 }, + { 1266, 139, 10, 80 }, + { 1276, 0, 191, 255 }, + { 1288, 0, 191, 255 }, + { 1301, 0, 178, 238 }, + { 1314, 0, 154, 205 }, + { 1327, 0, 104, 139 }, + { 1340, 105, 105, 105 }, + { 1348, 105, 105, 105 }, + { 1356, 30, 144, 255 }, + { 1367, 30, 144, 255 }, + { 1379, 28, 134, 238 }, + { 1391, 24, 116, 205 }, + { 1403, 16, 78, 139 }, + { 1415, 178, 34, 34 }, + { 1425, 255, 48, 48 }, + { 1436, 238, 44, 44 }, + { 1447, 205, 38, 38 }, + { 1458, 139, 26, 26 }, + { 1469, 255, 250, 240 }, + { 1481, 34, 139, 34 }, + { 1493, 255, 0, 255 }, + { 1501, 220, 220, 220 }, + { 1511, 248, 248, 255 }, + { 1522, 255, 215, 0 }, + { 1527, 255, 215, 0 }, + { 1533, 238, 201, 0 }, + { 1539, 205, 173, 0 }, + { 1545, 139, 117, 0 }, + { 1551, 218, 165, 32 }, + { 1561, 255, 193, 37 }, + { 1572, 238, 180, 34 }, + { 1583, 205, 155, 29 }, + { 1594, 139, 105, 20 }, + { 1605, 128, 128, 128 }, + { 1610, 0, 0, 0 }, + { 1616, 3, 3, 3 }, + { 1622, 26, 26, 26 }, + { 1629, 255, 255, 255 }, + { 1637, 28, 28, 28 }, + { 1644, 31, 31, 31 }, + { 1651, 33, 33, 33 }, + { 1658, 36, 36, 36 }, + { 1665, 38, 38, 38 }, + { 1672, 41, 41, 41 }, + { 1679, 43, 43, 43 }, + { 1686, 46, 46, 46 }, + { 1693, 48, 48, 48 }, + { 1700, 5, 5, 5 }, + { 1706, 51, 51, 51 }, + { 1713, 54, 54, 54 }, + { 1720, 56, 56, 56 }, + { 1727, 59, 59, 59 }, + { 1734, 61, 61, 61 }, + { 1741, 64, 64, 64 }, + { 1748, 66, 66, 66 }, + { 1755, 69, 69, 69 }, + { 1762, 71, 71, 71 }, + { 1769, 74, 74, 74 }, + { 1776, 8, 8, 8 }, + { 1782, 77, 77, 77 }, + { 1789, 79, 79, 79 }, + { 1796, 82, 82, 82 }, + { 1803, 84, 84, 84 }, + { 1810, 87, 87, 87 }, + { 1817, 89, 89, 89 }, + { 1824, 92, 92, 92 }, + { 1831, 94, 94, 94 }, + { 1838, 97, 97, 97 }, + { 1845, 99, 99, 99 }, + { 1852, 10, 10, 10 }, + { 1858, 102, 102, 102 }, + { 1865, 105, 105, 105 }, + { 1872, 107, 107, 107 }, + { 1879, 110, 110, 110 }, + { 1886, 112, 112, 112 }, + { 1893, 115, 115, 115 }, + { 1900, 117, 117, 117 }, + { 1907, 120, 120, 120 }, + { 1914, 122, 122, 122 }, + { 1921, 125, 125, 125 }, + { 1928, 13, 13, 13 }, + { 1934, 127, 127, 127 }, + { 1941, 130, 130, 130 }, + { 1948, 133, 133, 133 }, + { 1955, 135, 135, 135 }, + { 1962, 138, 138, 138 }, + { 1969, 140, 140, 140 }, + { 1976, 143, 143, 143 }, + { 1983, 145, 145, 145 }, + { 1990, 148, 148, 148 }, + { 1997, 150, 150, 150 }, + { 2004, 15, 15, 15 }, + { 2010, 153, 153, 153 }, + { 2017, 156, 156, 156 }, + { 2024, 158, 158, 158 }, + { 2031, 161, 161, 161 }, + { 2038, 163, 163, 163 }, + { 2045, 166, 166, 166 }, + { 2052, 168, 168, 168 }, + { 2059, 171, 171, 171 }, + { 2066, 173, 173, 173 }, + { 2073, 176, 176, 176 }, + { 2080, 18, 18, 18 }, + { 2086, 179, 179, 179 }, + { 2093, 181, 181, 181 }, + { 2100, 184, 184, 184 }, + { 2107, 186, 186, 186 }, + { 2114, 189, 189, 189 }, + { 2121, 191, 191, 191 }, + { 2128, 194, 194, 194 }, + { 2135, 196, 196, 196 }, + { 2142, 199, 199, 199 }, + { 2149, 201, 201, 201 }, + { 2156, 20, 20, 20 }, + { 2162, 204, 204, 204 }, + { 2169, 207, 207, 207 }, + { 2176, 209, 209, 209 }, + { 2183, 212, 212, 212 }, + { 2190, 214, 214, 214 }, + { 2197, 217, 217, 217 }, + { 2204, 219, 219, 219 }, + { 2211, 222, 222, 222 }, + { 2218, 224, 224, 224 }, + { 2225, 227, 227, 227 }, + { 2232, 23, 23, 23 }, + { 2238, 229, 229, 229 }, + { 2245, 232, 232, 232 }, + { 2252, 235, 235, 235 }, + { 2259, 237, 237, 237 }, + { 2266, 240, 240, 240 }, + { 2273, 242, 242, 242 }, + { 2280, 245, 245, 245 }, + { 2287, 247, 247, 247 }, + { 2294, 250, 250, 250 }, + { 2301, 252, 252, 252 }, + { 2308, 0, 128, 0 }, + { 2314, 0, 255, 0 }, + { 2321, 0, 238, 0 }, + { 2328, 0, 205, 0 }, + { 2335, 0, 139, 0 }, + { 2342, 173, 255, 47 }, + { 2354, 128, 128, 128 }, + { 2359, 0, 0, 0 }, + { 2365, 3, 3, 3 }, + { 2371, 26, 26, 26 }, + { 2378, 255, 255, 255 }, + { 2386, 28, 28, 28 }, + { 2393, 31, 31, 31 }, + { 2400, 33, 33, 33 }, + { 2407, 36, 36, 36 }, + { 2414, 38, 38, 38 }, + { 2421, 41, 41, 41 }, + { 2428, 43, 43, 43 }, + { 2435, 46, 46, 46 }, + { 2442, 48, 48, 48 }, + { 2449, 5, 5, 5 }, + { 2455, 51, 51, 51 }, + { 2462, 54, 54, 54 }, + { 2469, 56, 56, 56 }, + { 2476, 59, 59, 59 }, + { 2483, 61, 61, 61 }, + { 2490, 64, 64, 64 }, + { 2497, 66, 66, 66 }, + { 2504, 69, 69, 69 }, + { 2511, 71, 71, 71 }, + { 2518, 74, 74, 74 }, + { 2525, 8, 8, 8 }, + { 2531, 77, 77, 77 }, + { 2538, 79, 79, 79 }, + { 2545, 82, 82, 82 }, + { 2552, 84, 84, 84 }, + { 2559, 87, 87, 87 }, + { 2566, 89, 89, 89 }, + { 2573, 92, 92, 92 }, + { 2580, 94, 94, 94 }, + { 2587, 97, 97, 97 }, + { 2594, 99, 99, 99 }, + { 2601, 10, 10, 10 }, + { 2607, 102, 102, 102 }, + { 2614, 105, 105, 105 }, + { 2621, 107, 107, 107 }, + { 2628, 110, 110, 110 }, + { 2635, 112, 112, 112 }, + { 2642, 115, 115, 115 }, + { 2649, 117, 117, 117 }, + { 2656, 120, 120, 120 }, + { 2663, 122, 122, 122 }, + { 2670, 125, 125, 125 }, + { 2677, 13, 13, 13 }, + { 2683, 127, 127, 127 }, + { 2690, 130, 130, 130 }, + { 2697, 133, 133, 133 }, + { 2704, 135, 135, 135 }, + { 2711, 138, 138, 138 }, + { 2718, 140, 140, 140 }, + { 2725, 143, 143, 143 }, + { 2732, 145, 145, 145 }, + { 2739, 148, 148, 148 }, + { 2746, 150, 150, 150 }, + { 2753, 15, 15, 15 }, + { 2759, 153, 153, 153 }, + { 2766, 156, 156, 156 }, + { 2773, 158, 158, 158 }, + { 2780, 161, 161, 161 }, + { 2787, 163, 163, 163 }, + { 2794, 166, 166, 166 }, + { 2801, 168, 168, 168 }, + { 2808, 171, 171, 171 }, + { 2815, 173, 173, 173 }, + { 2822, 176, 176, 176 }, + { 2829, 18, 18, 18 }, + { 2835, 179, 179, 179 }, + { 2842, 181, 181, 181 }, + { 2849, 184, 184, 184 }, + { 2856, 186, 186, 186 }, + { 2863, 189, 189, 189 }, + { 2870, 191, 191, 191 }, + { 2877, 194, 194, 194 }, + { 2884, 196, 196, 196 }, + { 2891, 199, 199, 199 }, + { 2898, 201, 201, 201 }, + { 2905, 20, 20, 20 }, + { 2911, 204, 204, 204 }, + { 2918, 207, 207, 207 }, + { 2925, 209, 209, 209 }, + { 2932, 212, 212, 212 }, + { 2939, 214, 214, 214 }, + { 2946, 217, 217, 217 }, + { 2953, 219, 219, 219 }, + { 2960, 222, 222, 222 }, + { 2967, 224, 224, 224 }, + { 2974, 227, 227, 227 }, + { 2981, 23, 23, 23 }, + { 2987, 229, 229, 229 }, + { 2994, 232, 232, 232 }, + { 3001, 235, 235, 235 }, + { 3008, 237, 237, 237 }, + { 3015, 240, 240, 240 }, + { 3022, 242, 242, 242 }, + { 3029, 245, 245, 245 }, + { 3036, 247, 247, 247 }, + { 3043, 250, 250, 250 }, + { 3050, 252, 252, 252 }, + { 3057, 240, 255, 240 }, + { 3066, 240, 255, 240 }, + { 3076, 224, 238, 224 }, + { 3086, 193, 205, 193 }, + { 3096, 131, 139, 131 }, + { 3106, 255, 105, 180 }, + { 3114, 255, 110, 180 }, + { 3123, 238, 106, 167 }, + { 3132, 205, 96, 144 }, + { 3141, 139, 58, 98 }, + { 3150, 205, 92, 92 }, + { 3160, 255, 106, 106 }, + { 3171, 238, 99, 99 }, + { 3182, 205, 85, 85 }, + { 3193, 139, 58, 58 }, + { 3204, 75, 0, 130 }, + { 3211, 255, 255, 240 }, + { 3217, 255, 255, 240 }, + { 3224, 238, 238, 224 }, + { 3231, 205, 205, 193 }, + { 3238, 139, 139, 131 }, + { 3245, 240, 230, 140 }, + { 3251, 255, 246, 143 }, + { 3258, 238, 230, 133 }, + { 3265, 205, 198, 115 }, + { 3272, 139, 134, 78 }, + { 3279, 230, 230, 250 }, + { 3288, 255, 240, 245 }, + { 3302, 255, 240, 245 }, + { 3317, 238, 224, 229 }, + { 3332, 205, 193, 197 }, + { 3347, 139, 131, 134 }, + { 3362, 124, 252, 0 }, + { 3372, 255, 250, 205 }, + { 3385, 255, 250, 205 }, + { 3399, 238, 233, 191 }, + { 3413, 205, 201, 165 }, + { 3427, 139, 137, 112 }, + { 3441, 173, 216, 230 }, + { 3451, 191, 239, 255 }, + { 3462, 178, 223, 238 }, + { 3473, 154, 192, 205 }, + { 3484, 104, 131, 139 }, + { 3495, 240, 128, 128 }, + { 3506, 224, 255, 255 }, + { 3516, 224, 255, 255 }, + { 3527, 209, 238, 238 }, + { 3538, 180, 205, 205 }, + { 3549, 122, 139, 139 }, + { 3560, 238, 221, 130 }, + { 3575, 255, 236, 139 }, + { 3591, 238, 220, 130 }, + { 3607, 205, 190, 112 }, + { 3623, 139, 129, 76 }, + { 3639, 250, 250, 210 }, + { 3660, 211, 211, 211 }, + { 3670, 144, 238, 144 }, + { 3681, 211, 211, 211 }, + { 3691, 255, 182, 193 }, + { 3701, 255, 174, 185 }, + { 3712, 238, 162, 173 }, + { 3723, 205, 140, 149 }, + { 3734, 139, 95, 101 }, + { 3745, 255, 160, 122 }, + { 3757, 255, 160, 122 }, + { 3770, 238, 149, 114 }, + { 3783, 205, 129, 98 }, + { 3796, 139, 87, 66 }, + { 3809, 32, 178, 170 }, + { 3823, 135, 206, 250 }, + { 3836, 176, 226, 255 }, + { 3850, 164, 211, 238 }, + { 3864, 141, 182, 205 }, + { 3878, 96, 123, 139 }, + { 3892, 132, 112, 255 }, + { 3907, 119, 136, 153 }, + { 3922, 119, 136, 153 }, + { 3937, 176, 196, 222 }, + { 3952, 202, 225, 255 }, + { 3968, 188, 210, 238 }, + { 3984, 162, 181, 205 }, + { 4000, 110, 123, 139 }, + { 4016, 255, 255, 224 }, + { 4028, 255, 255, 224 }, + { 4041, 238, 238, 209 }, + { 4054, 205, 205, 180 }, + { 4067, 139, 139, 122 }, + { 4080, 0, 255, 0 }, + { 4085, 50, 205, 50 }, + { 4095, 250, 240, 230 }, + { 4101, 255, 0, 255 }, + { 4109, 255, 0, 255 }, + { 4118, 238, 0, 238 }, + { 4127, 205, 0, 205 }, + { 4136, 139, 0, 139 }, + { 4145, 128, 0, 0 }, + { 4152, 255, 52, 179 }, + { 4160, 238, 48, 167 }, + { 4168, 205, 41, 144 }, + { 4176, 139, 28, 98 }, + { 4184, 102, 205, 170 }, + { 4201, 0, 0, 205 }, + { 4212, 186, 85, 211 }, + { 4225, 224, 102, 255 }, + { 4239, 209, 95, 238 }, + { 4253, 180, 82, 205 }, + { 4267, 122, 55, 139 }, + { 4281, 147, 112, 219 }, + { 4294, 171, 130, 255 }, + { 4308, 159, 121, 238 }, + { 4322, 137, 104, 205 }, + { 4336, 93, 71, 139 }, + { 4350, 60, 179, 113 }, + { 4365, 123, 104, 238 }, + { 4381, 0, 250, 154 }, + { 4399, 72, 209, 204 }, + { 4415, 199, 21, 133 }, + { 4431, 25, 25, 112 }, + { 4444, 245, 255, 250 }, + { 4454, 255, 228, 225 }, + { 4464, 255, 228, 225 }, + { 4475, 238, 213, 210 }, + { 4486, 205, 183, 181 }, + { 4497, 139, 125, 123 }, + { 4508, 255, 228, 181 }, + { 4517, 255, 222, 173 }, + { 4529, 255, 222, 173 }, + { 4542, 238, 207, 161 }, + { 4555, 205, 179, 139 }, + { 4568, 139, 121, 94 }, + { 4581, 0, 0, 128 }, + { 4586, 0, 0, 128 }, + { 4595, 253, 245, 230 }, + { 4603, 128, 128, 0 }, + { 4609, 107, 142, 35 }, + { 4619, 192, 255, 62 }, + { 4630, 179, 238, 58 }, + { 4641, 154, 205, 50 }, + { 4652, 105, 139, 34 }, + { 4663, 255, 165, 0 }, + { 4670, 255, 165, 0 }, + { 4678, 238, 154, 0 }, + { 4686, 205, 133, 0 }, + { 4694, 139, 90, 0 }, + { 4702, 255, 69, 0 }, + { 4712, 255, 69, 0 }, + { 4723, 238, 64, 0 }, + { 4734, 205, 55, 0 }, + { 4745, 139, 37, 0 }, + { 4756, 218, 112, 214 }, + { 4763, 255, 131, 250 }, + { 4771, 238, 122, 233 }, + { 4779, 205, 105, 201 }, + { 4787, 139, 71, 137 }, + { 4795, 238, 232, 170 }, + { 4809, 152, 251, 152 }, + { 4819, 154, 255, 154 }, + { 4830, 144, 238, 144 }, + { 4841, 124, 205, 124 }, + { 4852, 84, 139, 84 }, + { 4863, 175, 238, 238 }, + { 4877, 187, 255, 255 }, + { 4892, 174, 238, 238 }, + { 4907, 150, 205, 205 }, + { 4922, 102, 139, 139 }, + { 4937, 219, 112, 147 }, + { 4951, 255, 130, 171 }, + { 4966, 238, 121, 159 }, + { 4981, 205, 104, 137 }, + { 4996, 139, 71, 93 }, + { 5011, 255, 239, 213 }, + { 5022, 255, 218, 185 }, + { 5032, 255, 218, 185 }, + { 5043, 238, 203, 173 }, + { 5054, 205, 175, 149 }, + { 5065, 139, 119, 101 }, + { 5076, 205, 133, 63 }, + { 5081, 255, 192, 203 }, + { 5086, 255, 181, 197 }, + { 5092, 238, 169, 184 }, + { 5098, 205, 145, 158 }, + { 5104, 139, 99, 108 }, + { 5110, 221, 160, 221 }, + { 5115, 255, 187, 255 }, + { 5121, 238, 174, 238 }, + { 5127, 205, 150, 205 }, + { 5133, 139, 102, 139 }, + { 5139, 176, 224, 230 }, + { 5150, 128, 0, 128 }, + { 5157, 155, 48, 255 }, + { 5165, 145, 44, 238 }, + { 5173, 125, 38, 205 }, + { 5181, 85, 26, 139 }, + { 5189, 255, 0, 0 }, + { 5193, 255, 0, 0 }, + { 5198, 238, 0, 0 }, + { 5203, 205, 0, 0 }, + { 5208, 139, 0, 0 }, + { 5213, 188, 143, 143 }, + { 5223, 255, 193, 193 }, + { 5234, 238, 180, 180 }, + { 5245, 205, 155, 155 }, + { 5256, 139, 105, 105 }, + { 5267, 65, 105, 225 }, + { 5277, 72, 118, 255 }, + { 5288, 67, 110, 238 }, + { 5299, 58, 95, 205 }, + { 5310, 39, 64, 139 }, + { 5321, 139, 69, 19 }, + { 5333, 250, 128, 114 }, + { 5340, 255, 140, 105 }, + { 5348, 238, 130, 98 }, + { 5356, 205, 112, 84 }, + { 5364, 139, 76, 57 }, + { 5372, 244, 164, 96 }, + { 5383, 46, 139, 87 }, + { 5392, 84, 255, 159 }, + { 5402, 78, 238, 148 }, + { 5412, 67, 205, 128 }, + { 5422, 46, 139, 87 }, + { 5432, 255, 245, 238 }, + { 5441, 255, 245, 238 }, + { 5451, 238, 229, 222 }, + { 5461, 205, 197, 191 }, + { 5471, 139, 134, 130 }, + { 5481, 160, 82, 45 }, + { 5488, 255, 130, 71 }, + { 5496, 238, 121, 66 }, + { 5504, 205, 104, 57 }, + { 5512, 139, 71, 38 }, + { 5520, 192, 192, 192 }, + { 5527, 135, 206, 235 }, + { 5535, 135, 206, 255 }, + { 5544, 126, 192, 238 }, + { 5553, 108, 166, 205 }, + { 5562, 74, 112, 139 }, + { 5571, 106, 90, 205 }, + { 5581, 131, 111, 255 }, + { 5592, 122, 103, 238 }, + { 5603, 105, 89, 205 }, + { 5614, 71, 60, 139 }, + { 5625, 112, 128, 144 }, + { 5635, 198, 226, 255 }, + { 5646, 185, 211, 238 }, + { 5657, 159, 182, 205 }, + { 5668, 108, 123, 139 }, + { 5679, 112, 128, 144 }, + { 5689, 255, 250, 250 }, + { 5694, 255, 250, 250 }, + { 5700, 238, 233, 233 }, + { 5706, 205, 201, 201 }, + { 5712, 139, 137, 137 }, + { 5718, 0, 255, 127 }, + { 5730, 0, 255, 127 }, + { 5743, 0, 238, 118 }, + { 5756, 0, 205, 102 }, + { 5769, 0, 139, 69 }, + { 5782, 70, 130, 180 }, + { 5792, 99, 184, 255 }, + { 5803, 92, 172, 238 }, + { 5814, 79, 148, 205 }, + { 5825, 54, 100, 139 }, + { 5836, 210, 180, 140 }, + { 5840, 255, 165, 79 }, + { 5845, 238, 154, 73 }, + { 5850, 205, 133, 63 }, + { 5855, 139, 90, 43 }, + { 5860, 0, 128, 128 }, + { 5865, 216, 191, 216 }, + { 5873, 255, 225, 255 }, + { 5882, 238, 210, 238 }, + { 5891, 205, 181, 205 }, + { 5900, 139, 123, 139 }, + { 5909, 255, 99, 71 }, + { 5916, 255, 99, 71 }, + { 5924, 238, 92, 66 }, + { 5932, 205, 79, 57 }, + { 5940, 139, 54, 38 }, + { 5948, 64, 224, 208 }, + { 5958, 0, 245, 255 }, + { 5969, 0, 229, 238 }, + { 5980, 0, 197, 205 }, + { 5991, 0, 134, 139 }, + { 6002, 238, 130, 238 }, + { 6009, 208, 32, 144 }, + { 6019, 255, 62, 150 }, + { 6030, 238, 58, 140 }, + { 6041, 205, 50, 120 }, + { 6052, 139, 34, 82 }, + { 6063, 245, 222, 179 }, + { 6069, 255, 231, 186 }, + { 6076, 238, 216, 174 }, + { 6083, 205, 186, 150 }, + { 6090, 139, 126, 102 }, + { 6097, 255, 255, 255 }, + { 6103, 245, 245, 245 }, + { 6114, 255, 255, 0 }, + { 6121, 255, 255, 0 }, + { 6129, 238, 238, 0 }, + { 6137, 205, 205, 0 }, + { 6145, 139, 139, 0 }, + { 6153, 154, 205, 50 } +}; diff --git a/libs/tk/ydk/config.h b/libs/tk/ydk/config.h new file mode 100644 index 0000000000..d933837df2 --- /dev/null +++ b/libs/tk/ydk/config.h @@ -0,0 +1,153 @@ +/* always defined to indicate that i18n is enabled */ +#undef ENABLE_NLS + +/* The prefix for our gettext translation domains. */ +#define GETTEXT_PACKAGE "gtk20" + +/* Define the location where the catalogs will be installed */ +#define GTK_LOCALEDIR "/ardour/share/locale" + +/* Define to 1 if you have the `bind_textdomain_codeset' function. */ +#ifndef __APPLE__ +#define HAVE_BIND_TEXTDOMAIN_CODESET 1 +#endif + +/* Is the wctype implementation broken */ +#ifdef __APPLE__ +#define HAVE_BROKEN_WCTYPE 1 +#endif + +/* Define to 1 if you have the header file. */ +#define HAVE_FTW_H 1 + +/* Define to 1 if you have the `getresuid' function. */ +#if !(defined PLATFORM_WINDOWS || defined __APPLE__) +#define HAVE_GETRESUID 1 +#endif + +#ifndef __APPLE__ +/* Have GNU ftw */ +#define HAVE_GNU_FTW 1 +#endif + +/* Define to 1 if ipc.h is available */ +#if !(defined PLATFORM_WINDOWS || defined __APPLE__) +#define HAVE_IPC_H 1 +#endif + +#ifndef PLATFORM_WINDOWS +/* Define to 1 if you have the `localtime_r' function. */ +#define HAVE_LOCALTIME_R 1 +#endif + +#ifndef PLATFORM_WINDOWS +#define HAVE_PWD_H 1 +#endif + +/* Have the Xrandr extension library */ +/* #undef HAVE_RANDR */ + +/* Define to 1 if shm.h is available */ +#if !(defined PLATFORM_WINDOWS || defined __APPLE__) +#define HAVE_SHM_H 1 +#endif + +/* Define to 1 if solaris xinerama is available */ +/* #undef HAVE_SOLARIS_XINERAMA */ + +/* Define to 1 if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_PARAM_H 1 + +/* Define to 1 if sys/sysinfo.h is available */ +#if !(defined PLATFORM_WINDOWS || defined __APPLE__) +#define HAVE_SYS_SYSINFO_H 1 +#endif + +/* Define to 1 if sys/systeminfo.h is available */ +/* #undef HAVE_SYS_SYSTEMINFO_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Have wchar.h include file */ +#define HAVE_WCHAR_H 1 + +/* Have wctype.h include file */ +#define HAVE_WCTYPE_H 1 + +/* Define if we have X11R6 */ +#if !(defined PLATFORM_WINDOWS || defined __APPLE__) +#define HAVE_X11R6 1 +#endif + +/* Have the XCOMPOSITE X extension */ +/* #undef HAVE_XCOMPOSITE */ + +/* Define to 1 if you have the `XConvertCase' function. */ +#if !(defined PLATFORM_WINDOWS || defined __APPLE__) +#define HAVE_XCONVERTCASE 1 +#endif + +/* Have the Xcursor library */ +/* #undef HAVE_XCURSOR */ + +/* Have the XDAMAGE X extension */ +/* #undef HAVE_XDAMAGE */ + +/* Have the XFIXES X extension */ +/* #undef HAVE_XFIXES */ + +/* Define to 1 if XFree Xinerama is available */ +/* #undef HAVE_XFREE_XINERAMA */ + +/* Define to 1 if you have the `XInternAtoms' function. */ +#if !(defined PLATFORM_WINDOWS || defined __APPLE__) +#define HAVE_XINTERNATOMS 1 + +/* Define to use XKB extension */ +#define HAVE_XKB 1 + +/* Define to 1 if xshm.h is available */ +#define HAVE_XSHM_H 1 + +/* Have the SYNC extension library */ +#define HAVE_XSYNC 1 +#endif + +/* Define if needed for xReply */ +/* #undef NEED_XIPROTO_H_FOR_XREPLY */ + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "2.24.23" + +/* Define to 1 if medialib is available and should be used */ +/* #undef USE_MEDIALIB */ + +/* Define to 1 if medialib 2.5 is available */ +/* #undef USE_MEDIALIB25 */ + +/* Define to 1 if no XInput should be used */ +#if !(defined PLATFORM_WINDOWS || defined __APPLE__) +#define XINPUT_NONE 1 +#endif + +/* Enable large inode numbers on Mac OS X 10.5. */ +#ifdef __APPLE__ +#ifndef _DARWIN_USE_64_BIT_INODE +# define _DARWIN_USE_64_BIT_INODE 1 +#endif +#endif + +#ifdef PLATFORM_WINDOWS +/* Define to `int' if doesn't define. */ +#define gid_t int + +/* Define to `int' if doesn't define. */ +#define uid_t int +#endif diff --git a/libs/tk/ydk/gdk.c b/libs/tk/ydk/gdk.c new file mode 100644 index 0000000000..f722dbf96a --- /dev/null +++ b/libs/tk/ydk/gdk.c @@ -0,0 +1,838 @@ +/* GDK - The GIMP Drawing Kit + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, 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 "config.h" + +#include +#include + +#include "gdk.h" +#include "gdkinternals.h" +#include "gdkintl.h" + +#ifndef HAVE_XCONVERTCASE +#include "gdkkeysyms.h" +#endif +#include "gdkalias.h" + +typedef struct _GdkPredicate GdkPredicate; + +struct _GdkPredicate +{ + GdkEventFunc func; + gpointer data; +}; + +typedef struct _GdkThreadsDispatch GdkThreadsDispatch; + +struct _GdkThreadsDispatch +{ + GSourceFunc func; + gpointer data; + GDestroyNotify destroy; +}; + + +/* Private variable declarations + */ +static int gdk_initialized = 0; /* 1 if the library is initialized, + * 0 otherwise. + */ + +static gchar *gdk_progclass = NULL; + +#ifdef G_ENABLE_DEBUG +static const GDebugKey gdk_debug_keys[] = { + {"events", GDK_DEBUG_EVENTS}, + {"misc", GDK_DEBUG_MISC}, + {"dnd", GDK_DEBUG_DND}, + {"xim", GDK_DEBUG_XIM}, + {"nograbs", GDK_DEBUG_NOGRABS}, + {"colormap", GDK_DEBUG_COLORMAP}, + {"gdkrgb", GDK_DEBUG_GDKRGB}, + {"gc", GDK_DEBUG_GC}, + {"pixmap", GDK_DEBUG_PIXMAP}, + {"image", GDK_DEBUG_IMAGE}, + {"input", GDK_DEBUG_INPUT}, + {"cursor", GDK_DEBUG_CURSOR}, + {"multihead", GDK_DEBUG_MULTIHEAD}, + {"xinerama", GDK_DEBUG_XINERAMA}, + {"draw", GDK_DEBUG_DRAW}, + {"eventloop", GDK_DEBUG_EVENTLOOP} +}; + +static const int gdk_ndebug_keys = G_N_ELEMENTS (gdk_debug_keys); + +#endif /* G_ENABLE_DEBUG */ + +#ifdef G_ENABLE_DEBUG +static gboolean +gdk_arg_debug_cb (const char *key, const char *value, gpointer user_data, GError **error) +{ + guint debug_value = g_parse_debug_string (value, + (GDebugKey *) gdk_debug_keys, + gdk_ndebug_keys); + + if (debug_value == 0 && value != NULL && strcmp (value, "") != 0) + { + g_set_error (error, + G_OPTION_ERROR, G_OPTION_ERROR_FAILED, + _("Error parsing option --gdk-debug")); + return FALSE; + } + + _gdk_debug_flags |= debug_value; + + return TRUE; +} + +static gboolean +gdk_arg_no_debug_cb (const char *key, const char *value, gpointer user_data, GError **error) +{ + guint debug_value = g_parse_debug_string (value, + (GDebugKey *) gdk_debug_keys, + gdk_ndebug_keys); + + if (debug_value == 0 && value != NULL && strcmp (value, "") != 0) + { + g_set_error (error, + G_OPTION_ERROR, G_OPTION_ERROR_FAILED, + _("Error parsing option --gdk-no-debug")); + return FALSE; + } + + _gdk_debug_flags &= ~debug_value; + + return TRUE; +} +#endif /* G_ENABLE_DEBUG */ + +static gboolean +gdk_arg_class_cb (const char *key, const char *value, gpointer user_data, GError **error) +{ + gdk_set_program_class (value); + + return TRUE; +} + +static gboolean +gdk_arg_name_cb (const char *key, const char *value, gpointer user_data, GError **error) +{ + g_set_prgname (value); + + return TRUE; +} + +static const GOptionEntry gdk_args[] = { + { "class", 0, 0, G_OPTION_ARG_CALLBACK, gdk_arg_class_cb, + /* Description of --class=CLASS in --help output */ N_("Program class as used by the window manager"), + /* Placeholder in --class=CLASS in --help output */ N_("CLASS") }, + { "name", 0, 0, G_OPTION_ARG_CALLBACK, gdk_arg_name_cb, + /* Description of --name=NAME in --help output */ N_("Program name as used by the window manager"), + /* Placeholder in --name=NAME in --help output */ N_("NAME") }, + { "display", 0, G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_STRING, &_gdk_display_name, + /* Description of --display=DISPLAY in --help output */ N_("X display to use"), + /* Placeholder in --display=DISPLAY in --help output */ N_("DISPLAY") }, + { "screen", 0, 0, G_OPTION_ARG_INT, &_gdk_screen_number, + /* Description of --screen=SCREEN in --help output */ N_("X screen to use"), + /* Placeholder in --screen=SCREEN in --help output */ N_("SCREEN") }, +#ifdef G_ENABLE_DEBUG + { "gdk-debug", 0, 0, G_OPTION_ARG_CALLBACK, gdk_arg_debug_cb, + /* Description of --gdk-debug=FLAGS in --help output */ N_("GDK debugging flags to set"), + /* Placeholder in --gdk-debug=FLAGS in --help output */ N_("FLAGS") }, + { "gdk-no-debug", 0, 0, G_OPTION_ARG_CALLBACK, gdk_arg_no_debug_cb, + /* Description of --gdk-no-debug=FLAGS in --help output */ N_("GDK debugging flags to unset"), + /* Placeholder in --gdk-no-debug=FLAGS in --help output */ N_("FLAGS") }, +#endif + { NULL } +}; + +/** + * gdk_add_option_entries_libgtk_only: + * @group: An option group. + * + * Appends gdk option entries to the passed in option group. This is + * not public API and must not be used by applications. + **/ +void +gdk_add_option_entries_libgtk_only (GOptionGroup *group) +{ + g_option_group_add_entries (group, gdk_args); + g_option_group_add_entries (group, _gdk_windowing_args); +} + +void +gdk_pre_parse_libgtk_only (void) +{ + gdk_initialized = TRUE; + + /* We set the fallback program class here, rather than lazily in + * gdk_get_program_class, since we don't want -name to override it. + */ + gdk_progclass = g_strdup (g_get_prgname ()); + if (gdk_progclass && gdk_progclass[0]) + gdk_progclass[0] = g_ascii_toupper (gdk_progclass[0]); + +#ifdef G_ENABLE_DEBUG + { + gchar *debug_string = getenv("GDK_DEBUG"); + if (debug_string != NULL) + _gdk_debug_flags = g_parse_debug_string (debug_string, + (GDebugKey *) gdk_debug_keys, + gdk_ndebug_keys); + } +#endif /* G_ENABLE_DEBUG */ + + if (getenv ("GDK_NATIVE_WINDOWS")) + { + _gdk_native_windows = TRUE; + /* Ensure that this is not propagated + to spawned applications */ + g_unsetenv ("GDK_NATIVE_WINDOWS"); + } + + g_type_init (); + + /* Do any setup particular to the windowing system + */ + _gdk_windowing_init (); +} + + +/** + * gdk_parse_args: + * @argc: the number of command line arguments. + * @argv: (inout) (array length=argc): the array of command line arguments. + * + * Parse command line arguments, and store for future + * use by calls to gdk_display_open(). + * + * Any arguments used by GDK are removed from the array and @argc and @argv are + * updated accordingly. + * + * You shouldn't call this function explicitely if you are using + * gtk_init(), gtk_init_check(), gdk_init(), or gdk_init_check(). + * + * Since: 2.2 + **/ +void +gdk_parse_args (int *argc, + char ***argv) +{ + GOptionContext *option_context; + GOptionGroup *option_group; + GError *error = NULL; + + if (gdk_initialized) + return; + + gdk_pre_parse_libgtk_only (); + + option_context = g_option_context_new (NULL); + g_option_context_set_ignore_unknown_options (option_context, TRUE); + g_option_context_set_help_enabled (option_context, FALSE); + option_group = g_option_group_new (NULL, NULL, NULL, NULL, NULL); + g_option_context_set_main_group (option_context, option_group); + + g_option_group_add_entries (option_group, gdk_args); + g_option_group_add_entries (option_group, _gdk_windowing_args); + + if (!g_option_context_parse (option_context, argc, argv, &error)) + { + g_warning ("%s", error->message); + g_error_free (error); + } + g_option_context_free (option_context); + + if (_gdk_debug_flags && GDK_DEBUG_GDKRGB) + gdk_rgb_set_verbose (TRUE); + + GDK_NOTE (MISC, g_message ("progname: \"%s\"", g_get_prgname ())); +} + +/** + * gdk_get_display_arg_name: + * + * Gets the display name specified in the command line arguments passed + * to gdk_init() or gdk_parse_args(), if any. + * + * Returns: the display name, if specified explicitely, otherwise %NULL + * this string is owned by GTK+ and must not be modified or freed. + * + * Since: 2.2 + */ +const gchar * +gdk_get_display_arg_name (void) +{ + if (!_gdk_display_arg_name) + { + if (_gdk_screen_number >= 0) + _gdk_display_arg_name = _gdk_windowing_substitute_screen_number (_gdk_display_name, _gdk_screen_number); + else + _gdk_display_arg_name = g_strdup (_gdk_display_name); + } + + return _gdk_display_arg_name; +} + +/** + * gdk_display_open_default_libgtk_only: + * + * Opens the default display specified by command line arguments or + * environment variables, sets it as the default display, and returns + * it. gdk_parse_args must have been called first. If the default + * display has previously been set, simply returns that. An internal + * function that should not be used by applications. + * + * Return value: the default display, if it could be opened, + * otherwise %NULL. + **/ +GdkDisplay * +gdk_display_open_default_libgtk_only (void) +{ + GdkDisplay *display; + + g_return_val_if_fail (gdk_initialized, NULL); + + display = gdk_display_get_default (); + if (display) + return display; + + display = gdk_display_open (gdk_get_display_arg_name ()); + + if (!display && _gdk_screen_number >= 0) + { + g_free (_gdk_display_arg_name); + _gdk_display_arg_name = g_strdup (_gdk_display_name); + + display = gdk_display_open (_gdk_display_name); + } + + if (display) + gdk_display_manager_set_default_display (gdk_display_manager_get (), + display); + + return display; +} + +/** + * gdk_init_check: + * @argc: (inout): + * @argv: (array length=argc) (inout): + * + * Initialize the library for use. + * + * Arguments: + * "argc" is the number of arguments. + * "argv" is an array of strings. + * + * Results: + * "argc" and "argv" are modified to reflect any arguments + * which were not handled. (Such arguments should either + * be handled by the application or dismissed). If initialization + * fails, returns FALSE, otherwise TRUE. + * + * Side effects: + * The library is initialized. + * + *-------------------------------------------------------------- + */ +gboolean +gdk_init_check (int *argc, + char ***argv) +{ + gdk_parse_args (argc, argv); + + return gdk_display_open_default_libgtk_only () != NULL; +} + + +/** + * gdk_init: + * @argc: (inout): + * @argv: (array length=argc) (inout): + */ +void +gdk_init (int *argc, char ***argv) +{ + if (!gdk_init_check (argc, argv)) + { + const char *display_name = gdk_get_display_arg_name (); + g_warning ("cannot open display: %s", display_name ? display_name : ""); + exit(1); + } +} + +/* + *-------------------------------------------------------------- + * gdk_exit + * + * Restores the library to an un-itialized state and exits + * the program using the "exit" system call. + * + * Arguments: + * "errorcode" is the error value to pass to "exit". + * + * Results: + * Allocated structures are freed and the program exits + * cleanly. + * + * Side effects: + * + *-------------------------------------------------------------- + */ + +void +gdk_exit (gint errorcode) +{ + exit (errorcode); +} + +void +gdk_threads_enter (void) +{ + GDK_THREADS_ENTER (); +} + +void +gdk_threads_leave (void) +{ + GDK_THREADS_LEAVE (); +} + +static void +gdk_threads_impl_lock (void) +{ + if (gdk_threads_mutex) + g_mutex_lock (gdk_threads_mutex); +} + +static void +gdk_threads_impl_unlock (void) +{ + if (gdk_threads_mutex) + { + /* we need a trylock() here because trying to unlock a mutex + * that hasn't been locked yet is: + * + * a) not portable + * b) fail on GLib ≥ 2.41 + * + * trylock() will either succeed because nothing is holding the + * GDK mutex, and will be unlocked right afterwards; or it's + * going to fail because the mutex is locked already, in which + * case we unlock it as expected. + * + * this is needed in the case somebody called gdk_threads_init() + * without calling gdk_threads_enter() before calling gtk_main(). + * in theory, we could just say that this is undefined behaviour, + * but our documentation has always been *less* than explicit as + * to what the behaviour should actually be. + * + * see bug: https://bugzilla.gnome.org/show_bug.cgi?id=735428 + */ + g_mutex_trylock (gdk_threads_mutex); + g_mutex_unlock (gdk_threads_mutex); + } +} + +/** + * gdk_threads_init: + * + * Initializes GDK so that it can be used from multiple threads + * in conjunction with gdk_threads_enter() and gdk_threads_leave(). + * g_thread_init() must be called previous to this function. + * + * This call must be made before any use of the main loop from + * GTK+; to be safe, call it before gtk_init(). + **/ +void +gdk_threads_init (void) +{ + if (!g_thread_supported ()) + g_error ("g_thread_init() must be called before gdk_threads_init()"); + + gdk_threads_mutex = g_mutex_new (); + if (!gdk_threads_lock) + gdk_threads_lock = gdk_threads_impl_lock; + if (!gdk_threads_unlock) + gdk_threads_unlock = gdk_threads_impl_unlock; +} + +/** + * gdk_threads_set_lock_functions: + * @enter_fn: function called to guard GDK + * @leave_fn: function called to release the guard + * + * Allows the application to replace the standard method that + * GDK uses to protect its data structures. Normally, GDK + * creates a single #GMutex that is locked by gdk_threads_enter(), + * and released by gdk_threads_leave(); using this function an + * application provides, instead, a function @enter_fn that is + * called by gdk_threads_enter() and a function @leave_fn that is + * called by gdk_threads_leave(). + * + * The functions must provide at least same locking functionality + * as the default implementation, but can also do extra application + * specific processing. + * + * As an example, consider an application that has its own recursive + * lock that when held, holds the GTK+ lock as well. When GTK+ unlocks + * the GTK+ lock when entering a recursive main loop, the application + * must temporarily release its lock as well. + * + * Most threaded GTK+ apps won't need to use this method. + * + * This method must be called before gdk_threads_init(), and cannot + * be called multiple times. + * + * Since: 2.4 + **/ +void +gdk_threads_set_lock_functions (GCallback enter_fn, + GCallback leave_fn) +{ + g_return_if_fail (gdk_threads_lock == NULL && + gdk_threads_unlock == NULL); + + gdk_threads_lock = enter_fn; + gdk_threads_unlock = leave_fn; +} + +static gboolean +gdk_threads_dispatch (gpointer data) +{ + GdkThreadsDispatch *dispatch = data; + gboolean ret = FALSE; + + GDK_THREADS_ENTER (); + + if (!g_source_is_destroyed (g_main_current_source ())) + ret = dispatch->func (dispatch->data); + + GDK_THREADS_LEAVE (); + + return ret; +} + +static void +gdk_threads_dispatch_free (gpointer data) +{ + GdkThreadsDispatch *dispatch = data; + + if (dispatch->destroy && dispatch->data) + dispatch->destroy (dispatch->data); + + g_slice_free (GdkThreadsDispatch, data); +} + + +/** + * gdk_threads_add_idle_full: + * @priority: the priority of the idle source. Typically this will be in the + * range btweeen #G_PRIORITY_DEFAULT_IDLE and #G_PRIORITY_HIGH_IDLE + * @function: function to call + * @data: data to pass to @function + * @notify: (allow-none): function to call when the idle is removed, or %NULL + * + * Adds a function to be called whenever there are no higher priority + * events pending. If the function returns %FALSE it is automatically + * removed from the list of event sources and will not be called again. + * + * This variant of g_idle_add_full() calls @function with the GDK lock + * held. It can be thought of a MT-safe version for GTK+ widgets for the + * following use case, where you have to worry about idle_callback() + * running in thread A and accessing @self after it has been finalized + * in thread B: + * + * |[ + * static gboolean + * idle_callback (gpointer data) + * { + * /* gdk_threads_enter(); would be needed for g_idle_add() */ + * + * SomeWidget *self = data; + * /* do stuff with self */ + * + * self->idle_id = 0; + * + * /* gdk_threads_leave(); would be needed for g_idle_add() */ + * return FALSE; + * } + * + * static void + * some_widget_do_stuff_later (SomeWidget *self) + * { + * self->idle_id = gdk_threads_add_idle (idle_callback, self) + * /* using g_idle_add() here would require thread protection in the callback */ + * } + * + * static void + * some_widget_finalize (GObject *object) + * { + * SomeWidget *self = SOME_WIDGET (object); + * if (self->idle_id) + * g_source_remove (self->idle_id); + * G_OBJECT_CLASS (parent_class)->finalize (object); + * } + * ]| + * + * Return value: the ID (greater than 0) of the event source. + * + * Since: 2.12 + */ +guint +gdk_threads_add_idle_full (gint priority, + GSourceFunc function, + gpointer data, + GDestroyNotify notify) +{ + GdkThreadsDispatch *dispatch; + + g_return_val_if_fail (function != NULL, 0); + + dispatch = g_slice_new (GdkThreadsDispatch); + dispatch->func = function; + dispatch->data = data; + dispatch->destroy = notify; + + return g_idle_add_full (priority, + gdk_threads_dispatch, + dispatch, + gdk_threads_dispatch_free); +} + +/** + * gdk_threads_add_idle: + * @function: function to call + * @data: data to pass to @function + * + * A wrapper for the common usage of gdk_threads_add_idle_full() + * assigning the default priority, #G_PRIORITY_DEFAULT_IDLE. + * + * See gdk_threads_add_idle_full(). + * + * Return value: the ID (greater than 0) of the event source. + * + * Since: 2.12 + */ +guint +gdk_threads_add_idle (GSourceFunc function, + gpointer data) +{ + return gdk_threads_add_idle_full (G_PRIORITY_DEFAULT_IDLE, + function, data, NULL); +} + + +/** + * gdk_threads_add_timeout_full: + * @priority: the priority of the timeout source. Typically this will be in the + * range between #G_PRIORITY_DEFAULT_IDLE and #G_PRIORITY_HIGH_IDLE. + * @interval: the time between calls to the function, in milliseconds + * (1/1000ths of a second) + * @function: function to call + * @data: data to pass to @function + * @notify: (allow-none): function to call when the timeout is removed, or %NULL + * + * Sets a function to be called at regular intervals holding the GDK lock, + * with the given priority. The function is called repeatedly until it + * returns %FALSE, at which point the timeout is automatically destroyed + * and the function will not be called again. The @notify function is + * called when the timeout is destroyed. The first call to the + * function will be at the end of the first @interval. + * + * Note that timeout functions may be delayed, due to the processing of other + * event sources. Thus they should not be relied on for precise timing. + * After each call to the timeout function, the time of the next + * timeout is recalculated based on the current time and the given interval + * (it does not try to 'catch up' time lost in delays). + * + * This variant of g_timeout_add_full() can be thought of a MT-safe version + * for GTK+ widgets for the following use case: + * + * |[ + * static gboolean timeout_callback (gpointer data) + * { + * SomeWidget *self = data; + * + * /* do stuff with self */ + * + * self->timeout_id = 0; + * + * return FALSE; + * } + * + * static void some_widget_do_stuff_later (SomeWidget *self) + * { + * self->timeout_id = g_timeout_add (timeout_callback, self) + * } + * + * static void some_widget_finalize (GObject *object) + * { + * SomeWidget *self = SOME_WIDGET (object); + * + * if (self->timeout_id) + * g_source_remove (self->timeout_id); + * + * G_OBJECT_CLASS (parent_class)->finalize (object); + * } + * ]| + * + * Return value: the ID (greater than 0) of the event source. + * + * Since: 2.12 + */ +guint +gdk_threads_add_timeout_full (gint priority, + guint interval, + GSourceFunc function, + gpointer data, + GDestroyNotify notify) +{ + GdkThreadsDispatch *dispatch; + + g_return_val_if_fail (function != NULL, 0); + + dispatch = g_slice_new (GdkThreadsDispatch); + dispatch->func = function; + dispatch->data = data; + dispatch->destroy = notify; + + return g_timeout_add_full (priority, + interval, + gdk_threads_dispatch, + dispatch, + gdk_threads_dispatch_free); +} + +/** + * gdk_threads_add_timeout: + * @interval: the time between calls to the function, in milliseconds + * (1/1000ths of a second) + * @function: function to call + * @data: data to pass to @function + * + * A wrapper for the common usage of gdk_threads_add_timeout_full() + * assigning the default priority, #G_PRIORITY_DEFAULT. + * + * See gdk_threads_add_timeout_full(). + * + * Return value: the ID (greater than 0) of the event source. + * + * Since: 2.12 + */ +guint +gdk_threads_add_timeout (guint interval, + GSourceFunc function, + gpointer data) +{ + return gdk_threads_add_timeout_full (G_PRIORITY_DEFAULT, + interval, function, data, NULL); +} + + +/** + * gdk_threads_add_timeout_seconds_full: + * @priority: the priority of the timeout source. Typically this will be in the + * range between #G_PRIORITY_DEFAULT_IDLE and #G_PRIORITY_HIGH_IDLE. + * @interval: the time between calls to the function, in seconds + * @function: function to call + * @data: data to pass to @function + * @notify: (allow-none): function to call when the timeout is removed, or %NULL + * + * A variant of gdk_threads_add_timout_full() with second-granularity. + * See g_timeout_add_seconds_full() for a discussion of why it is + * a good idea to use this function if you don't need finer granularity. + * + * Return value: the ID (greater than 0) of the event source. + * + * Since: 2.14 + */ +guint +gdk_threads_add_timeout_seconds_full (gint priority, + guint interval, + GSourceFunc function, + gpointer data, + GDestroyNotify notify) +{ + GdkThreadsDispatch *dispatch; + + g_return_val_if_fail (function != NULL, 0); + + dispatch = g_slice_new (GdkThreadsDispatch); + dispatch->func = function; + dispatch->data = data; + dispatch->destroy = notify; + + return g_timeout_add_seconds_full (priority, + interval, + gdk_threads_dispatch, + dispatch, + gdk_threads_dispatch_free); +} + +/** + * gdk_threads_add_timeout_seconds: + * @interval: the time between calls to the function, in seconds + * @function: function to call + * @data: data to pass to @function + * + * A wrapper for the common usage of gdk_threads_add_timeout_seconds_full() + * assigning the default priority, #G_PRIORITY_DEFAULT. + * + * For details, see gdk_threads_add_timeout_full(). + * + * Return value: the ID (greater than 0) of the event source. + * + * Since: 2.14 + */ +guint +gdk_threads_add_timeout_seconds (guint interval, + GSourceFunc function, + gpointer data) +{ + return gdk_threads_add_timeout_seconds_full (G_PRIORITY_DEFAULT, + interval, function, data, NULL); +} + + +const char * +gdk_get_program_class (void) +{ + return gdk_progclass; +} + +void +gdk_set_program_class (const char *program_class) +{ + g_free (gdk_progclass); + + gdk_progclass = g_strdup (program_class); +} + +#define __GDK_C__ +#include "gdkaliasdef.c" diff --git a/libs/tk/ydk/gdkaliasdef.c b/libs/tk/ydk/gdkaliasdef.c new file mode 100644 index 0000000000..329c0fc87c --- /dev/null +++ b/libs/tk/ydk/gdkaliasdef.c @@ -0,0 +1,2918 @@ +/* Generated by makegdkalias.pl */ + +#ifndef DISABLE_VISIBILITY + +#include + +#ifdef G_HAVE_GNUC_VISIBILITY + +#undef IN_FILE +#define IN_FILE defined + +#undef IN_HEADER +#define IN_HEADER(x) 1 + +#if IN_HEADER(__GDK_EVENTS_H__) +#if IN_FILE(__GDK_EVENTS_X11_C__) +#undef gdk_add_client_message_filter +extern __typeof (gdk_add_client_message_filter) gdk_add_client_message_filter __attribute((alias("IA__gdk_add_client_message_filter"), visibility("default"))); + +#ifndef GDK_DISABLE_DEPRECATED +#undef gdk_event_get_graphics_expose +extern __typeof (gdk_event_get_graphics_expose) gdk_event_get_graphics_expose __attribute((alias("IA__gdk_event_get_graphics_expose"), visibility("default"))); + +#endif +#undef gdk_events_pending +extern __typeof (gdk_events_pending) gdk_events_pending __attribute((alias("IA__gdk_events_pending"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_TEST_UTILS_H__) +#if IN_FILE(__GDK_TEST_UTILS_X11_C__) +#undef gdk_test_simulate_button +extern __typeof (gdk_test_simulate_button) gdk_test_simulate_button __attribute((alias("IA__gdk_test_simulate_button"), visibility("default"))); + +#undef gdk_test_simulate_key +extern __typeof (gdk_test_simulate_key) gdk_test_simulate_key __attribute((alias("IA__gdk_test_simulate_key"), visibility("default"))); + +#undef gdk_test_render_sync +extern __typeof (gdk_test_render_sync) gdk_test_render_sync __attribute((alias("IA__gdk_test_render_sync"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_EVENTS_H__) +#if IN_FILE(__GDK_EVENTS_C__) +#undef gdk_event_copy +extern __typeof (gdk_event_copy) gdk_event_copy __attribute((alias("IA__gdk_event_copy"), visibility("default"))); + +#undef gdk_event_free +extern __typeof (gdk_event_free) gdk_event_free __attribute((alias("IA__gdk_event_free"), visibility("default"))); + +#undef gdk_event_get +extern __typeof (gdk_event_get) gdk_event_get __attribute((alias("IA__gdk_event_get"), visibility("default"))); + +#undef gdk_event_get_axis +extern __typeof (gdk_event_get_axis) gdk_event_get_axis __attribute((alias("IA__gdk_event_get_axis"), visibility("default"))); + +#undef gdk_event_get_coords +extern __typeof (gdk_event_get_coords) gdk_event_get_coords __attribute((alias("IA__gdk_event_get_coords"), visibility("default"))); + +#undef gdk_event_get_root_coords +extern __typeof (gdk_event_get_root_coords) gdk_event_get_root_coords __attribute((alias("IA__gdk_event_get_root_coords"), visibility("default"))); + +#undef gdk_event_get_screen +extern __typeof (gdk_event_get_screen) gdk_event_get_screen __attribute((alias("IA__gdk_event_get_screen"), visibility("default"))); + +#undef gdk_event_get_state +extern __typeof (gdk_event_get_state) gdk_event_get_state __attribute((alias("IA__gdk_event_get_state"), visibility("default"))); + +#undef gdk_event_get_time +extern __typeof (gdk_event_get_time) gdk_event_get_time __attribute((alias("IA__gdk_event_get_time"), visibility("default"))); + +#undef gdk_event_get_type +extern __typeof (gdk_event_get_type) gdk_event_get_type __attribute((alias("IA__gdk_event_get_type"), visibility("default"))); + +#undef gdk_event_handler_set +extern __typeof (gdk_event_handler_set) gdk_event_handler_set __attribute((alias("IA__gdk_event_handler_set"), visibility("default"))); + +#undef gdk_event_new +extern __typeof (gdk_event_new) gdk_event_new __attribute((alias("IA__gdk_event_new"), visibility("default"))); + +#undef gdk_event_peek +extern __typeof (gdk_event_peek) gdk_event_peek __attribute((alias("IA__gdk_event_peek"), visibility("default"))); + +#undef gdk_event_put +extern __typeof (gdk_event_put) gdk_event_put __attribute((alias("IA__gdk_event_put"), visibility("default"))); + +#undef gdk_event_request_motions +extern __typeof (gdk_event_request_motions) gdk_event_request_motions __attribute((alias("IA__gdk_event_request_motions"), visibility("default"))); + +#undef gdk_event_set_screen +extern __typeof (gdk_event_set_screen) gdk_event_set_screen __attribute((alias("IA__gdk_event_set_screen"), visibility("default"))); + +#undef gdk_get_show_events +extern __typeof (gdk_get_show_events) gdk_get_show_events __attribute((alias("IA__gdk_get_show_events"), visibility("default"))); + +#undef gdk_set_show_events +extern __typeof (gdk_set_show_events) gdk_set_show_events __attribute((alias("IA__gdk_set_show_events"), visibility("default"))); + +#undef gdk_setting_get +extern __typeof (gdk_setting_get) gdk_setting_get __attribute((alias("IA__gdk_setting_get"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_H__) +#if IN_FILE(__GDK_MAIN_X11_C__) +#undef gdk_error_trap_pop +extern __typeof (gdk_error_trap_pop) gdk_error_trap_pop __attribute((alias("IA__gdk_error_trap_pop"), visibility("default"))); + +#undef gdk_error_trap_push +extern __typeof (gdk_error_trap_push) gdk_error_trap_push __attribute((alias("IA__gdk_error_trap_push"), visibility("default"))); + +#undef gdk_get_display +extern __typeof (gdk_get_display) gdk_get_display __attribute((alias("IA__gdk_get_display"), visibility("default"))); + +#ifndef GDK_DISABLE_DEPRECATED +#undef gdk_get_use_xshm +extern __typeof (gdk_get_use_xshm) gdk_get_use_xshm __attribute((alias("IA__gdk_get_use_xshm"), visibility("default"))); + +#undef gdk_set_use_xshm +extern __typeof (gdk_set_use_xshm) gdk_set_use_xshm __attribute((alias("IA__gdk_set_use_xshm"), visibility("default"))); + +#endif +#undef gdk_keyboard_grab +extern __typeof (gdk_keyboard_grab) gdk_keyboard_grab __attribute((alias("IA__gdk_keyboard_grab"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_H__) +#if IN_FILE(__GDK_DISPLAY_C__) +#undef gdk_beep +extern __typeof (gdk_beep) gdk_beep __attribute((alias("IA__gdk_beep"), visibility("default"))); + +#undef gdk_set_pointer_hooks +extern __typeof (gdk_set_pointer_hooks) gdk_set_pointer_hooks __attribute((alias("IA__gdk_set_pointer_hooks"), visibility("default"))); + +#undef gdk_keyboard_ungrab +extern __typeof (gdk_keyboard_ungrab) gdk_keyboard_ungrab __attribute((alias("IA__gdk_keyboard_ungrab"), visibility("default"))); + +#undef gdk_pointer_is_grabbed +extern __typeof (gdk_pointer_is_grabbed) gdk_pointer_is_grabbed __attribute((alias("IA__gdk_pointer_is_grabbed"), visibility("default"))); + +#undef gdk_pointer_ungrab +extern __typeof (gdk_pointer_ungrab) gdk_pointer_ungrab __attribute((alias("IA__gdk_pointer_ungrab"), visibility("default"))); + +#undef gdk_event_send_client_message +extern __typeof (gdk_event_send_client_message) gdk_event_send_client_message __attribute((alias("IA__gdk_event_send_client_message"), visibility("default"))); + +#undef gdk_event_send_clientmessage_toall +extern __typeof (gdk_event_send_clientmessage_toall) gdk_event_send_clientmessage_toall __attribute((alias("IA__gdk_event_send_clientmessage_toall"), visibility("default"))); + +#undef gdk_keyboard_grab_info_libgtk_only +extern __typeof (gdk_keyboard_grab_info_libgtk_only) gdk_keyboard_grab_info_libgtk_only __attribute((alias("IA__gdk_keyboard_grab_info_libgtk_only"), visibility("default"))); + +#undef gdk_pointer_grab_info_libgtk_only +extern __typeof (gdk_pointer_grab_info_libgtk_only) gdk_pointer_grab_info_libgtk_only __attribute((alias("IA__gdk_pointer_grab_info_libgtk_only"), visibility("default"))); + +#undef gdk_display_pointer_is_grabbed +extern __typeof (gdk_display_pointer_is_grabbed) gdk_display_pointer_is_grabbed __attribute((alias("IA__gdk_display_pointer_is_grabbed"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_H__) +#if IN_FILE(__GDK_IM_X11_C__) +#ifndef GDK_DISABLE_DEPRECATED +#undef gdk_mbstowcs +extern __typeof (gdk_mbstowcs) gdk_mbstowcs __attribute((alias("IA__gdk_mbstowcs"), visibility("default"))); + +#undef gdk_wcstombs +extern __typeof (gdk_wcstombs) gdk_wcstombs __attribute((alias("IA__gdk_wcstombs"), visibility("default"))); + +#undef gdk_set_locale +extern __typeof (gdk_set_locale) gdk_set_locale __attribute((alias("IA__gdk_set_locale"), visibility("default"))); + +#endif +#endif +#endif +#if IN_HEADER(__GDK_H__) +#if IN_FILE(__GDK_EVENTS_X11_C__) +#undef gdk_event_send_client_message_for_display +extern __typeof (gdk_event_send_client_message_for_display) gdk_event_send_client_message_for_display __attribute((alias("IA__gdk_event_send_client_message_for_display"), visibility("default"))); + +#undef gdk_flush +extern __typeof (gdk_flush) gdk_flush __attribute((alias("IA__gdk_flush"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_H__) +#if IN_FILE(__GDK_DISPLAY_X11_C__) +#undef gdk_notify_startup_complete +extern __typeof (gdk_notify_startup_complete) gdk_notify_startup_complete __attribute((alias("IA__gdk_notify_startup_complete"), visibility("default"))); + +#undef gdk_notify_startup_complete_with_id +extern __typeof (gdk_notify_startup_complete_with_id) gdk_notify_startup_complete_with_id __attribute((alias("IA__gdk_notify_startup_complete_with_id"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_H__) +#if IN_FILE(__GDK_RECTANGLE_C__) +#undef gdk_rectangle_get_type +extern __typeof (gdk_rectangle_get_type) gdk_rectangle_get_type __attribute((alias("IA__gdk_rectangle_get_type"), visibility("default"))); + +#undef gdk_rectangle_intersect +extern __typeof (gdk_rectangle_intersect) gdk_rectangle_intersect __attribute((alias("IA__gdk_rectangle_intersect"), visibility("default"))); + +#undef gdk_rectangle_union +extern __typeof (gdk_rectangle_union) gdk_rectangle_union __attribute((alias("IA__gdk_rectangle_union"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_H__) +#if IN_FILE(__GDK_EVENTS_C__) +#undef gdk_set_double_click_time +extern __typeof (gdk_set_double_click_time) gdk_set_double_click_time __attribute((alias("IA__gdk_set_double_click_time"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_H__) +#if IN_FILE(__GDK_C__) +#undef gdk_add_option_entries_libgtk_only +extern __typeof (gdk_add_option_entries_libgtk_only) gdk_add_option_entries_libgtk_only __attribute((alias("IA__gdk_add_option_entries_libgtk_only"), visibility("default"))); + +#undef gdk_get_display_arg_name +extern __typeof (gdk_get_display_arg_name) gdk_get_display_arg_name __attribute((alias("IA__gdk_get_display_arg_name"), visibility("default"))); + +#undef gdk_get_program_class +extern __typeof (gdk_get_program_class) gdk_get_program_class __attribute((alias("IA__gdk_get_program_class"), visibility("default"))); + +#undef gdk_init +extern __typeof (gdk_init) gdk_init __attribute((alias("IA__gdk_init"), visibility("default"))); + +#undef gdk_init_check +extern __typeof (gdk_init_check) gdk_init_check __attribute((alias("IA__gdk_init_check"), visibility("default"))); + +#ifndef GDK_DISABLE_DEPRECATED +#undef gdk_exit +extern __typeof (gdk_exit) gdk_exit __attribute((alias("IA__gdk_exit"), visibility("default"))); + +#endif +#undef gdk_pre_parse_libgtk_only +extern __typeof (gdk_pre_parse_libgtk_only) gdk_pre_parse_libgtk_only __attribute((alias("IA__gdk_pre_parse_libgtk_only"), visibility("default"))); + +#undef gdk_parse_args +extern __typeof (gdk_parse_args) gdk_parse_args __attribute((alias("IA__gdk_parse_args"), visibility("default"))); + +#undef gdk_set_program_class +extern __typeof (gdk_set_program_class) gdk_set_program_class __attribute((alias("IA__gdk_set_program_class"), visibility("default"))); + +#undef gdk_threads_enter +extern __typeof (gdk_threads_enter) gdk_threads_enter __attribute((alias("IA__gdk_threads_enter"), visibility("default"))); + +#undef gdk_threads_init +extern __typeof (gdk_threads_init) gdk_threads_init __attribute((alias("IA__gdk_threads_init"), visibility("default"))); + +#undef gdk_threads_leave +extern __typeof (gdk_threads_leave) gdk_threads_leave __attribute((alias("IA__gdk_threads_leave"), visibility("default"))); + +#undef gdk_threads_set_lock_functions +extern __typeof (gdk_threads_set_lock_functions) gdk_threads_set_lock_functions __attribute((alias("IA__gdk_threads_set_lock_functions"), visibility("default"))); + +#undef gdk_threads_add_idle +extern __typeof (gdk_threads_add_idle) gdk_threads_add_idle __attribute((alias("IA__gdk_threads_add_idle"), visibility("default"))); + +#undef gdk_threads_add_idle_full +extern __typeof (gdk_threads_add_idle_full) gdk_threads_add_idle_full __attribute((alias("IA__gdk_threads_add_idle_full"), visibility("default"))); + +#undef gdk_threads_add_timeout +extern __typeof (gdk_threads_add_timeout) gdk_threads_add_timeout __attribute((alias("IA__gdk_threads_add_timeout"), visibility("default"))); + +#undef gdk_threads_add_timeout_full +extern __typeof (gdk_threads_add_timeout_full) gdk_threads_add_timeout_full __attribute((alias("IA__gdk_threads_add_timeout_full"), visibility("default"))); + +#undef gdk_threads_add_timeout_seconds +extern __typeof (gdk_threads_add_timeout_seconds) gdk_threads_add_timeout_seconds __attribute((alias("IA__gdk_threads_add_timeout_seconds"), visibility("default"))); + +#undef gdk_threads_add_timeout_seconds_full +extern __typeof (gdk_threads_add_timeout_seconds_full) gdk_threads_add_timeout_seconds_full __attribute((alias("IA__gdk_threads_add_timeout_seconds_full"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_H__) +#if IN_FILE(__GDK_EVENTS_C__) +#ifndef GDK_DISABLE_DEPRECATED +#undef gdk_input_add +extern __typeof (gdk_input_add) gdk_input_add __attribute((alias("IA__gdk_input_add"), visibility("default"))); + +#undef gdk_input_remove +extern __typeof (gdk_input_remove) gdk_input_remove __attribute((alias("IA__gdk_input_remove"), visibility("default"))); + +#undef gdk_input_add_full +extern __typeof (gdk_input_add_full) gdk_input_add_full __attribute((alias("IA__gdk_input_add_full"), visibility("default"))); + +#endif +#endif +#endif +#if IN_HEADER(__GDK_H__) +#if IN_FILE(__GDK_SCREEN_C__) +#undef gdk_screen_width +extern __typeof (gdk_screen_width) gdk_screen_width __attribute((alias("IA__gdk_screen_width"), visibility("default"))); + +#undef gdk_screen_width_mm +extern __typeof (gdk_screen_width_mm) gdk_screen_width_mm __attribute((alias("IA__gdk_screen_width_mm"), visibility("default"))); + +#undef gdk_screen_height +extern __typeof (gdk_screen_height) gdk_screen_height __attribute((alias("IA__gdk_screen_height"), visibility("default"))); + +#undef gdk_screen_height_mm +extern __typeof (gdk_screen_height_mm) gdk_screen_height_mm __attribute((alias("IA__gdk_screen_height_mm"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_PROPERTY_H__) +#if IN_FILE(__GDK_SELECTION_C__) +#ifndef GDK_DISABLE_DEPRECATED +#undef gdk_string_to_compound_text +extern __typeof (gdk_string_to_compound_text) gdk_string_to_compound_text __attribute((alias("IA__gdk_string_to_compound_text"), visibility("default"))); + +#undef gdk_text_property_to_text_list +extern __typeof (gdk_text_property_to_text_list) gdk_text_property_to_text_list __attribute((alias("IA__gdk_text_property_to_text_list"), visibility("default"))); + +#undef gdk_text_property_to_utf8_list +extern __typeof (gdk_text_property_to_utf8_list) gdk_text_property_to_utf8_list __attribute((alias("IA__gdk_text_property_to_utf8_list"), visibility("default"))); + +#undef gdk_utf8_to_compound_text +extern __typeof (gdk_utf8_to_compound_text) gdk_utf8_to_compound_text __attribute((alias("IA__gdk_utf8_to_compound_text"), visibility("default"))); + +#endif +#endif +#endif +#if IN_HEADER(__GDK_PROPERTY_H__) +#if IN_FILE(__GDK_PROPERTY_X11_C__) +#undef gdk_atom_intern +extern __typeof (gdk_atom_intern) gdk_atom_intern __attribute((alias("IA__gdk_atom_intern"), visibility("default"))); + +#undef gdk_atom_intern_static_string +extern __typeof (gdk_atom_intern_static_string) gdk_atom_intern_static_string __attribute((alias("IA__gdk_atom_intern_static_string"), visibility("default"))); + +#undef gdk_atom_name +extern __typeof (gdk_atom_name) gdk_atom_name __attribute((alias("IA__gdk_atom_name"), visibility("default"))); + +#undef gdk_property_change +extern __typeof (gdk_property_change) gdk_property_change __attribute((alias("IA__gdk_property_change"), visibility("default"))); + +#undef gdk_property_delete +extern __typeof (gdk_property_delete) gdk_property_delete __attribute((alias("IA__gdk_property_delete"), visibility("default"))); + +#undef gdk_property_get +extern __typeof (gdk_property_get) gdk_property_get __attribute((alias("IA__gdk_property_get"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_PROPERTY_H__) +#if IN_FILE(__GDK_SELECTION_X11_C__) +#ifndef GDK_DISABLE_DEPRECATED +#undef gdk_free_compound_text +extern __typeof (gdk_free_compound_text) gdk_free_compound_text __attribute((alias("IA__gdk_free_compound_text"), visibility("default"))); + +#undef gdk_free_text_list +extern __typeof (gdk_free_text_list) gdk_free_text_list __attribute((alias("IA__gdk_free_text_list"), visibility("default"))); + +#undef gdk_string_to_compound_text_for_display +extern __typeof (gdk_string_to_compound_text_for_display) gdk_string_to_compound_text_for_display __attribute((alias("IA__gdk_string_to_compound_text_for_display"), visibility("default"))); + +#undef gdk_text_property_to_text_list_for_display +extern __typeof (gdk_text_property_to_text_list_for_display) gdk_text_property_to_text_list_for_display __attribute((alias("IA__gdk_text_property_to_text_list_for_display"), visibility("default"))); + +#undef gdk_utf8_to_compound_text_for_display +extern __typeof (gdk_utf8_to_compound_text_for_display) gdk_utf8_to_compound_text_for_display __attribute((alias("IA__gdk_utf8_to_compound_text_for_display"), visibility("default"))); + +#endif +#undef gdk_text_property_to_utf8_list_for_display +extern __typeof (gdk_text_property_to_utf8_list_for_display) gdk_text_property_to_utf8_list_for_display __attribute((alias("IA__gdk_text_property_to_utf8_list_for_display"), visibility("default"))); + +#undef gdk_utf8_to_string_target +extern __typeof (gdk_utf8_to_string_target) gdk_utf8_to_string_target __attribute((alias("IA__gdk_utf8_to_string_target"), visibility("default"))); + +#endif +#endif +#ifdef GDK_WINDOWING_X11 +#if IN_HEADER(__GDK_X_H__) +#if IN_FILE(__GDK_SELECTION_X11_C__) +#undef gdk_x11_display_string_to_compound_text +extern __typeof (gdk_x11_display_string_to_compound_text) gdk_x11_display_string_to_compound_text __attribute((alias("IA__gdk_x11_display_string_to_compound_text"), visibility("default"))); + +#undef gdk_x11_display_text_property_to_text_list +extern __typeof (gdk_x11_display_text_property_to_text_list) gdk_x11_display_text_property_to_text_list __attribute((alias("IA__gdk_x11_display_text_property_to_text_list"), visibility("default"))); + +#undef gdk_x11_display_utf8_to_compound_text +extern __typeof (gdk_x11_display_utf8_to_compound_text) gdk_x11_display_utf8_to_compound_text __attribute((alias("IA__gdk_x11_display_utf8_to_compound_text"), visibility("default"))); + +#undef gdk_x11_free_compound_text +extern __typeof (gdk_x11_free_compound_text) gdk_x11_free_compound_text __attribute((alias("IA__gdk_x11_free_compound_text"), visibility("default"))); + +#undef gdk_x11_free_text_list +extern __typeof (gdk_x11_free_text_list) gdk_x11_free_text_list __attribute((alias("IA__gdk_x11_free_text_list"), visibility("default"))); + +#endif +#endif +#endif +#if IN_HEADER(__GDK_ENUM_TYPES_H__) +#if IN_FILE(__GDK_ENUM_TYPES_C__) +#undef gdk_rgb_dither_get_type +extern __typeof (gdk_rgb_dither_get_type) gdk_rgb_dither_get_type __attribute((alias("IA__gdk_rgb_dither_get_type"), visibility("default"))); + +#undef gdk_drag_protocol_get_type +extern __typeof (gdk_drag_protocol_get_type) gdk_drag_protocol_get_type __attribute((alias("IA__gdk_drag_protocol_get_type"), visibility("default"))); + +#undef gdk_input_source_get_type +extern __typeof (gdk_input_source_get_type) gdk_input_source_get_type __attribute((alias("IA__gdk_input_source_get_type"), visibility("default"))); + +#undef gdk_input_condition_get_type +extern __typeof (gdk_input_condition_get_type) gdk_input_condition_get_type __attribute((alias("IA__gdk_input_condition_get_type"), visibility("default"))); + +#undef gdk_input_mode_get_type +extern __typeof (gdk_input_mode_get_type) gdk_input_mode_get_type __attribute((alias("IA__gdk_input_mode_get_type"), visibility("default"))); + +#undef gdk_axis_use_get_type +extern __typeof (gdk_axis_use_get_type) gdk_axis_use_get_type __attribute((alias("IA__gdk_axis_use_get_type"), visibility("default"))); + +#undef gdk_byte_order_get_type +extern __typeof (gdk_byte_order_get_type) gdk_byte_order_get_type __attribute((alias("IA__gdk_byte_order_get_type"), visibility("default"))); + +#undef gdk_cap_style_get_type +extern __typeof (gdk_cap_style_get_type) gdk_cap_style_get_type __attribute((alias("IA__gdk_cap_style_get_type"), visibility("default"))); + +#undef gdk_crossing_mode_get_type +extern __typeof (gdk_crossing_mode_get_type) gdk_crossing_mode_get_type __attribute((alias("IA__gdk_crossing_mode_get_type"), visibility("default"))); + +#undef gdk_extension_mode_get_type +extern __typeof (gdk_extension_mode_get_type) gdk_extension_mode_get_type __attribute((alias("IA__gdk_extension_mode_get_type"), visibility("default"))); + +#undef gdk_event_mask_get_type +extern __typeof (gdk_event_mask_get_type) gdk_event_mask_get_type __attribute((alias("IA__gdk_event_mask_get_type"), visibility("default"))); + +#undef gdk_event_type_get_type +extern __typeof (gdk_event_type_get_type) gdk_event_type_get_type __attribute((alias("IA__gdk_event_type_get_type"), visibility("default"))); + +#undef gdk_fill_get_type +extern __typeof (gdk_fill_get_type) gdk_fill_get_type __attribute((alias("IA__gdk_fill_get_type"), visibility("default"))); + +#ifndef GDK_DISABLE_DEPRECATED +#undef gdk_fill_rule_get_type +extern __typeof (gdk_fill_rule_get_type) gdk_fill_rule_get_type __attribute((alias("IA__gdk_fill_rule_get_type"), visibility("default"))); + +#endif +#undef gdk_filter_return_get_type +extern __typeof (gdk_filter_return_get_type) gdk_filter_return_get_type __attribute((alias("IA__gdk_filter_return_get_type"), visibility("default"))); + +#undef gdk_function_get_type +extern __typeof (gdk_function_get_type) gdk_function_get_type __attribute((alias("IA__gdk_function_get_type"), visibility("default"))); + +#undef gdk_grab_status_get_type +extern __typeof (gdk_grab_status_get_type) gdk_grab_status_get_type __attribute((alias("IA__gdk_grab_status_get_type"), visibility("default"))); + +#undef gdk_gravity_get_type +extern __typeof (gdk_gravity_get_type) gdk_gravity_get_type __attribute((alias("IA__gdk_gravity_get_type"), visibility("default"))); + +#undef gdk_join_style_get_type +extern __typeof (gdk_join_style_get_type) gdk_join_style_get_type __attribute((alias("IA__gdk_join_style_get_type"), visibility("default"))); + +#undef gdk_line_style_get_type +extern __typeof (gdk_line_style_get_type) gdk_line_style_get_type __attribute((alias("IA__gdk_line_style_get_type"), visibility("default"))); + +#undef gdk_modifier_type_get_type +extern __typeof (gdk_modifier_type_get_type) gdk_modifier_type_get_type __attribute((alias("IA__gdk_modifier_type_get_type"), visibility("default"))); + +#undef gdk_notify_type_get_type +extern __typeof (gdk_notify_type_get_type) gdk_notify_type_get_type __attribute((alias("IA__gdk_notify_type_get_type"), visibility("default"))); + +#undef gdk_overlap_type_get_type +extern __typeof (gdk_overlap_type_get_type) gdk_overlap_type_get_type __attribute((alias("IA__gdk_overlap_type_get_type"), visibility("default"))); + +#undef gdk_owner_change_get_type +extern __typeof (gdk_owner_change_get_type) gdk_owner_change_get_type __attribute((alias("IA__gdk_owner_change_get_type"), visibility("default"))); + +#undef gdk_property_state_get_type +extern __typeof (gdk_property_state_get_type) gdk_property_state_get_type __attribute((alias("IA__gdk_property_state_get_type"), visibility("default"))); + +#undef gdk_prop_mode_get_type +extern __typeof (gdk_prop_mode_get_type) gdk_prop_mode_get_type __attribute((alias("IA__gdk_prop_mode_get_type"), visibility("default"))); + +#undef gdk_scroll_direction_get_type +extern __typeof (gdk_scroll_direction_get_type) gdk_scroll_direction_get_type __attribute((alias("IA__gdk_scroll_direction_get_type"), visibility("default"))); + +#undef gdk_setting_action_get_type +extern __typeof (gdk_setting_action_get_type) gdk_setting_action_get_type __attribute((alias("IA__gdk_setting_action_get_type"), visibility("default"))); + +#undef gdk_status_get_type +extern __typeof (gdk_status_get_type) gdk_status_get_type __attribute((alias("IA__gdk_status_get_type"), visibility("default"))); + +#undef gdk_subwindow_mode_get_type +extern __typeof (gdk_subwindow_mode_get_type) gdk_subwindow_mode_get_type __attribute((alias("IA__gdk_subwindow_mode_get_type"), visibility("default"))); + +#undef gdk_visibility_state_get_type +extern __typeof (gdk_visibility_state_get_type) gdk_visibility_state_get_type __attribute((alias("IA__gdk_visibility_state_get_type"), visibility("default"))); + +#undef gdk_wm_decoration_get_type +extern __typeof (gdk_wm_decoration_get_type) gdk_wm_decoration_get_type __attribute((alias("IA__gdk_wm_decoration_get_type"), visibility("default"))); + +#undef gdk_wm_function_get_type +extern __typeof (gdk_wm_function_get_type) gdk_wm_function_get_type __attribute((alias("IA__gdk_wm_function_get_type"), visibility("default"))); + +#undef gdk_font_type_get_type +extern __typeof (gdk_font_type_get_type) gdk_font_type_get_type __attribute((alias("IA__gdk_font_type_get_type"), visibility("default"))); + +#undef gdk_cursor_type_get_type +extern __typeof (gdk_cursor_type_get_type) gdk_cursor_type_get_type __attribute((alias("IA__gdk_cursor_type_get_type"), visibility("default"))); + +#undef gdk_drag_action_get_type +extern __typeof (gdk_drag_action_get_type) gdk_drag_action_get_type __attribute((alias("IA__gdk_drag_action_get_type"), visibility("default"))); + +#undef gdk_gc_values_mask_get_type +extern __typeof (gdk_gc_values_mask_get_type) gdk_gc_values_mask_get_type __attribute((alias("IA__gdk_gc_values_mask_get_type"), visibility("default"))); + +#undef gdk_window_attributes_type_get_type +extern __typeof (gdk_window_attributes_type_get_type) gdk_window_attributes_type_get_type __attribute((alias("IA__gdk_window_attributes_type_get_type"), visibility("default"))); + +#undef gdk_window_class_get_type +extern __typeof (gdk_window_class_get_type) gdk_window_class_get_type __attribute((alias("IA__gdk_window_class_get_type"), visibility("default"))); + +#undef gdk_window_edge_get_type +extern __typeof (gdk_window_edge_get_type) gdk_window_edge_get_type __attribute((alias("IA__gdk_window_edge_get_type"), visibility("default"))); + +#undef gdk_window_hints_get_type +extern __typeof (gdk_window_hints_get_type) gdk_window_hints_get_type __attribute((alias("IA__gdk_window_hints_get_type"), visibility("default"))); + +#undef gdk_window_state_get_type +extern __typeof (gdk_window_state_get_type) gdk_window_state_get_type __attribute((alias("IA__gdk_window_state_get_type"), visibility("default"))); + +#undef gdk_window_type_get_type +extern __typeof (gdk_window_type_get_type) gdk_window_type_get_type __attribute((alias("IA__gdk_window_type_get_type"), visibility("default"))); + +#undef gdk_window_type_hint_get_type +extern __typeof (gdk_window_type_hint_get_type) gdk_window_type_hint_get_type __attribute((alias("IA__gdk_window_type_hint_get_type"), visibility("default"))); + +#undef gdk_image_type_get_type +extern __typeof (gdk_image_type_get_type) gdk_image_type_get_type __attribute((alias("IA__gdk_image_type_get_type"), visibility("default"))); + +#undef gdk_visual_type_get_type +extern __typeof (gdk_visual_type_get_type) gdk_visual_type_get_type __attribute((alias("IA__gdk_visual_type_get_type"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_FONT_H__) +#if IN_FILE(__GDK_FONT_C__) +#ifndef GDK_DISABLE_DEPRECATED +#undef gdk_font_from_description +extern __typeof (gdk_font_from_description) gdk_font_from_description __attribute((alias("IA__gdk_font_from_description"), visibility("default"))); + +#endif +#undef gdk_font_get_type +extern __typeof (gdk_font_get_type) gdk_font_get_type __attribute((alias("IA__gdk_font_get_type"), visibility("default"))); + +#undef gdk_font_ref +extern __typeof (gdk_font_ref) gdk_font_ref __attribute((alias("IA__gdk_font_ref"), visibility("default"))); + +#undef gdk_font_unref +extern __typeof (gdk_font_unref) gdk_font_unref __attribute((alias("IA__gdk_font_unref"), visibility("default"))); + +#ifndef GDK_DISABLE_DEPRECATED +#undef gdk_font_load +extern __typeof (gdk_font_load) gdk_font_load __attribute((alias("IA__gdk_font_load"), visibility("default"))); + +#undef gdk_string_width +extern __typeof (gdk_string_width) gdk_string_width __attribute((alias("IA__gdk_string_width"), visibility("default"))); + +#undef gdk_char_width +extern __typeof (gdk_char_width) gdk_char_width __attribute((alias("IA__gdk_char_width"), visibility("default"))); + +#undef gdk_char_width_wc +extern __typeof (gdk_char_width_wc) gdk_char_width_wc __attribute((alias("IA__gdk_char_width_wc"), visibility("default"))); + +#undef gdk_string_measure +extern __typeof (gdk_string_measure) gdk_string_measure __attribute((alias("IA__gdk_string_measure"), visibility("default"))); + +#undef gdk_text_measure +extern __typeof (gdk_text_measure) gdk_text_measure __attribute((alias("IA__gdk_text_measure"), visibility("default"))); + +#undef gdk_char_measure +extern __typeof (gdk_char_measure) gdk_char_measure __attribute((alias("IA__gdk_char_measure"), visibility("default"))); + +#undef gdk_string_height +extern __typeof (gdk_string_height) gdk_string_height __attribute((alias("IA__gdk_string_height"), visibility("default"))); + +#undef gdk_text_height +extern __typeof (gdk_text_height) gdk_text_height __attribute((alias("IA__gdk_text_height"), visibility("default"))); + +#undef gdk_char_height +extern __typeof (gdk_char_height) gdk_char_height __attribute((alias("IA__gdk_char_height"), visibility("default"))); + +#undef gdk_string_extents +extern __typeof (gdk_string_extents) gdk_string_extents __attribute((alias("IA__gdk_string_extents"), visibility("default"))); + +#endif +#endif +#endif +#if IN_HEADER(__GDK_FONT_H__) +#if IN_FILE(__GDK_FONT_X11_C__) +#ifndef GDK_DISABLE_DEPRECATED +#undef gdk_text_extents +extern __typeof (gdk_text_extents) gdk_text_extents __attribute((alias("IA__gdk_text_extents"), visibility("default"))); + +#undef gdk_text_extents_wc +extern __typeof (gdk_text_extents_wc) gdk_text_extents_wc __attribute((alias("IA__gdk_text_extents_wc"), visibility("default"))); + +#undef gdk_text_width +extern __typeof (gdk_text_width) gdk_text_width __attribute((alias("IA__gdk_text_width"), visibility("default"))); + +#undef gdk_text_width_wc +extern __typeof (gdk_text_width_wc) gdk_text_width_wc __attribute((alias("IA__gdk_text_width_wc"), visibility("default"))); + +#undef gdk_font_get_display +extern __typeof (gdk_font_get_display) gdk_font_get_display __attribute((alias("IA__gdk_font_get_display"), visibility("default"))); + +#undef gdk_fontset_load +extern __typeof (gdk_fontset_load) gdk_fontset_load __attribute((alias("IA__gdk_fontset_load"), visibility("default"))); + +#endif +#undef gdk_font_id +extern __typeof (gdk_font_id) gdk_font_id __attribute((alias("IA__gdk_font_id"), visibility("default"))); + +#undef gdk_font_equal +extern __typeof (gdk_font_equal) gdk_font_equal __attribute((alias("IA__gdk_font_equal"), visibility("default"))); + +#undef gdk_font_load_for_display +extern __typeof (gdk_font_load_for_display) gdk_font_load_for_display __attribute((alias("IA__gdk_font_load_for_display"), visibility("default"))); + +#undef gdk_font_from_description_for_display +extern __typeof (gdk_font_from_description_for_display) gdk_font_from_description_for_display __attribute((alias("IA__gdk_font_from_description_for_display"), visibility("default"))); + +#undef gdk_fontset_load_for_display +extern __typeof (gdk_fontset_load_for_display) gdk_fontset_load_for_display __attribute((alias("IA__gdk_fontset_load_for_display"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_CAIRO_H__) +#if IN_FILE(__GDK_CAIRO_C__) +#undef gdk_cairo_create +extern __typeof (gdk_cairo_create) gdk_cairo_create __attribute((alias("IA__gdk_cairo_create"), visibility("default"))); + +#undef gdk_cairo_reset_clip +extern __typeof (gdk_cairo_reset_clip) gdk_cairo_reset_clip __attribute((alias("IA__gdk_cairo_reset_clip"), visibility("default"))); + +#undef gdk_cairo_set_source_color +extern __typeof (gdk_cairo_set_source_color) gdk_cairo_set_source_color __attribute((alias("IA__gdk_cairo_set_source_color"), visibility("default"))); + +#undef gdk_cairo_set_source_pixbuf +extern __typeof (gdk_cairo_set_source_pixbuf) gdk_cairo_set_source_pixbuf __attribute((alias("IA__gdk_cairo_set_source_pixbuf"), visibility("default"))); + +#undef gdk_cairo_set_source_pixmap +extern __typeof (gdk_cairo_set_source_pixmap) gdk_cairo_set_source_pixmap __attribute((alias("IA__gdk_cairo_set_source_pixmap"), visibility("default"))); + +#undef gdk_cairo_set_source_window +extern __typeof (gdk_cairo_set_source_window) gdk_cairo_set_source_window __attribute((alias("IA__gdk_cairo_set_source_window"), visibility("default"))); + +#undef gdk_cairo_rectangle +extern __typeof (gdk_cairo_rectangle) gdk_cairo_rectangle __attribute((alias("IA__gdk_cairo_rectangle"), visibility("default"))); + +#undef gdk_cairo_region +extern __typeof (gdk_cairo_region) gdk_cairo_region __attribute((alias("IA__gdk_cairo_region"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_COLOR_H__) +#if IN_FILE(__GDK_COLOR_C__) +#ifndef GDK_DISABLE_DEPRECATED +#undef gdk_colors_store +extern __typeof (gdk_colors_store) gdk_colors_store __attribute((alias("IA__gdk_colors_store"), visibility("default"))); + +#undef gdk_color_white +extern __typeof (gdk_color_white) gdk_color_white __attribute((alias("IA__gdk_color_white"), visibility("default"))); + +#undef gdk_color_black +extern __typeof (gdk_color_black) gdk_color_black __attribute((alias("IA__gdk_color_black"), visibility("default"))); + +#undef gdk_color_alloc +extern __typeof (gdk_color_alloc) gdk_color_alloc __attribute((alias("IA__gdk_color_alloc"), visibility("default"))); + +#endif +#undef gdk_color_copy +extern __typeof (gdk_color_copy) gdk_color_copy __attribute((alias("IA__gdk_color_copy"), visibility("default"))); + +#undef gdk_color_equal +extern __typeof (gdk_color_equal) gdk_color_equal __attribute((alias("IA__gdk_color_equal"), visibility("default"))); + +#undef gdk_color_free +extern __typeof (gdk_color_free) gdk_color_free __attribute((alias("IA__gdk_color_free"), visibility("default"))); + +#undef gdk_color_get_type +extern __typeof (gdk_color_get_type) gdk_color_get_type __attribute((alias("IA__gdk_color_get_type"), visibility("default"))); + +#undef gdk_color_hash +extern __typeof (gdk_color_hash) gdk_color_hash __attribute((alias("IA__gdk_color_hash"), visibility("default"))); + +#undef gdk_colormap_alloc_color +extern __typeof (gdk_colormap_alloc_color) gdk_colormap_alloc_color __attribute((alias("IA__gdk_colormap_alloc_color"), visibility("default"))); + +#undef gdk_colormap_get_system +extern __typeof (gdk_colormap_get_system) gdk_colormap_get_system __attribute((alias("IA__gdk_colormap_get_system"), visibility("default"))); + +#undef gdk_colormap_get_visual +extern __typeof (gdk_colormap_get_visual) gdk_colormap_get_visual __attribute((alias("IA__gdk_colormap_get_visual"), visibility("default"))); + +#ifndef GDK_DISABLE_DEPRECATED +#undef gdk_colormap_ref +extern __typeof (gdk_colormap_ref) gdk_colormap_ref __attribute((alias("IA__gdk_colormap_ref"), visibility("default"))); + +#undef gdk_colormap_unref +extern __typeof (gdk_colormap_unref) gdk_colormap_unref __attribute((alias("IA__gdk_colormap_unref"), visibility("default"))); + +#endif +#undef gdk_color_parse +extern __typeof (gdk_color_parse) gdk_color_parse __attribute((alias("IA__gdk_color_parse"), visibility("default"))); + +#undef gdk_color_to_string +extern __typeof (gdk_color_to_string) gdk_color_to_string __attribute((alias("IA__gdk_color_to_string"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_COLOR_H__) +#if IN_FILE(__GDK_COLOR_X11_C__) +#undef gdk_colormap_new +extern __typeof (gdk_colormap_new) gdk_colormap_new __attribute((alias("IA__gdk_colormap_new"), visibility("default"))); + +#undef gdk_colormap_get_type +extern __typeof (gdk_colormap_get_type) gdk_colormap_get_type __attribute((alias("IA__gdk_colormap_get_type"), visibility("default"))); + +#ifndef GDK_DISABLE_DEPRECATED +#undef gdk_colormap_change +extern __typeof (gdk_colormap_change) gdk_colormap_change __attribute((alias("IA__gdk_colormap_change"), visibility("default"))); + +#undef gdk_colors_alloc +extern __typeof (gdk_colors_alloc) gdk_colors_alloc __attribute((alias("IA__gdk_colors_alloc"), visibility("default"))); + +#undef gdk_colors_free +extern __typeof (gdk_colors_free) gdk_colors_free __attribute((alias("IA__gdk_colors_free"), visibility("default"))); + +#undef gdk_colormap_get_system_size +extern __typeof (gdk_colormap_get_system_size) gdk_colormap_get_system_size __attribute((alias("IA__gdk_colormap_get_system_size"), visibility("default"))); + +#undef gdk_color_change +extern __typeof (gdk_color_change) gdk_color_change __attribute((alias("IA__gdk_color_change"), visibility("default"))); + +#endif +#undef gdk_colormap_alloc_colors +extern __typeof (gdk_colormap_alloc_colors) gdk_colormap_alloc_colors __attribute((alias("IA__gdk_colormap_alloc_colors"), visibility("default"))); + +#undef gdk_colormap_free_colors +extern __typeof (gdk_colormap_free_colors) gdk_colormap_free_colors __attribute((alias("IA__gdk_colormap_free_colors"), visibility("default"))); + +#undef gdk_colormap_query_color +extern __typeof (gdk_colormap_query_color) gdk_colormap_query_color __attribute((alias("IA__gdk_colormap_query_color"), visibility("default"))); + +#undef gdk_colormap_get_screen +extern __typeof (gdk_colormap_get_screen) gdk_colormap_get_screen __attribute((alias("IA__gdk_colormap_get_screen"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_CURSOR_H__) +#if IN_FILE(__GDK_CURSOR_C__) +#undef gdk_cursor_get_type +extern __typeof (gdk_cursor_get_type) gdk_cursor_get_type __attribute((alias("IA__gdk_cursor_get_type"), visibility("default"))); + +#undef gdk_cursor_get_cursor_type +extern __typeof (gdk_cursor_get_cursor_type) gdk_cursor_get_cursor_type __attribute((alias("IA__gdk_cursor_get_cursor_type"), visibility("default"))); + +#undef gdk_cursor_new +extern __typeof (gdk_cursor_new) gdk_cursor_new __attribute((alias("IA__gdk_cursor_new"), visibility("default"))); + +#undef gdk_cursor_ref +extern __typeof (gdk_cursor_ref) gdk_cursor_ref __attribute((alias("IA__gdk_cursor_ref"), visibility("default"))); + +#undef gdk_cursor_unref +extern __typeof (gdk_cursor_unref) gdk_cursor_unref __attribute((alias("IA__gdk_cursor_unref"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_CURSOR_H__) +#if IN_FILE(__GDK_CURSOR_X11_C__) +#undef gdk_cursor_get_display +extern __typeof (gdk_cursor_get_display) gdk_cursor_get_display __attribute((alias("IA__gdk_cursor_get_display"), visibility("default"))); + +#undef gdk_cursor_new_for_display +extern __typeof (gdk_cursor_new_for_display) gdk_cursor_new_for_display __attribute((alias("IA__gdk_cursor_new_for_display"), visibility("default"))); + +#undef gdk_cursor_new_from_pixbuf +extern __typeof (gdk_cursor_new_from_pixbuf) gdk_cursor_new_from_pixbuf __attribute((alias("IA__gdk_cursor_new_from_pixbuf"), visibility("default"))); + +#undef gdk_cursor_new_from_pixmap +extern __typeof (gdk_cursor_new_from_pixmap) gdk_cursor_new_from_pixmap __attribute((alias("IA__gdk_cursor_new_from_pixmap"), visibility("default"))); + +#undef gdk_cursor_new_from_name +extern __typeof (gdk_cursor_new_from_name) gdk_cursor_new_from_name __attribute((alias("IA__gdk_cursor_new_from_name"), visibility("default"))); + +#undef gdk_cursor_get_image +extern __typeof (gdk_cursor_get_image) gdk_cursor_get_image __attribute((alias("IA__gdk_cursor_get_image"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_INPUT_H__) +#if IN_FILE(__GDK_INPUT_C__) +#undef gdk_device_free_history +extern __typeof (gdk_device_free_history) gdk_device_free_history __attribute((alias("IA__gdk_device_free_history"), visibility("default"))); + +#undef gdk_device_get_axis +extern __typeof (gdk_device_get_axis) gdk_device_get_axis __attribute((alias("IA__gdk_device_get_axis"), visibility("default"))); + +#undef gdk_device_get_axis_use +extern __typeof (gdk_device_get_axis_use) gdk_device_get_axis_use __attribute((alias("IA__gdk_device_get_axis_use"), visibility("default"))); + +#undef gdk_device_get_has_cursor +extern __typeof (gdk_device_get_has_cursor) gdk_device_get_has_cursor __attribute((alias("IA__gdk_device_get_has_cursor"), visibility("default"))); + +#undef gdk_device_get_history +extern __typeof (gdk_device_get_history) gdk_device_get_history __attribute((alias("IA__gdk_device_get_history"), visibility("default"))); + +#undef gdk_device_get_key +extern __typeof (gdk_device_get_key) gdk_device_get_key __attribute((alias("IA__gdk_device_get_key"), visibility("default"))); + +#undef gdk_device_get_mode +extern __typeof (gdk_device_get_mode) gdk_device_get_mode __attribute((alias("IA__gdk_device_get_mode"), visibility("default"))); + +#undef gdk_device_get_name +extern __typeof (gdk_device_get_name) gdk_device_get_name __attribute((alias("IA__gdk_device_get_name"), visibility("default"))); + +#undef gdk_device_get_n_axes +extern __typeof (gdk_device_get_n_axes) gdk_device_get_n_axes __attribute((alias("IA__gdk_device_get_n_axes"), visibility("default"))); + +#undef gdk_device_get_n_keys +extern __typeof (gdk_device_get_n_keys) gdk_device_get_n_keys __attribute((alias("IA__gdk_device_get_n_keys"), visibility("default"))); + +#undef gdk_device_get_source +extern __typeof (gdk_device_get_source) gdk_device_get_source __attribute((alias("IA__gdk_device_get_source"), visibility("default"))); + +#undef gdk_device_get_type +extern __typeof (gdk_device_get_type) gdk_device_get_type __attribute((alias("IA__gdk_device_get_type"), visibility("default"))); + +#undef gdk_device_set_axis_use +extern __typeof (gdk_device_set_axis_use) gdk_device_set_axis_use __attribute((alias("IA__gdk_device_set_axis_use"), visibility("default"))); + +#undef gdk_device_set_key +extern __typeof (gdk_device_set_key) gdk_device_set_key __attribute((alias("IA__gdk_device_set_key"), visibility("default"))); + +#undef gdk_device_set_source +extern __typeof (gdk_device_set_source) gdk_device_set_source __attribute((alias("IA__gdk_device_set_source"), visibility("default"))); + +#undef gdk_devices_list +extern __typeof (gdk_devices_list) gdk_devices_list __attribute((alias("IA__gdk_devices_list"), visibility("default"))); + +#undef gdk_input_set_extension_events +extern __typeof (gdk_input_set_extension_events) gdk_input_set_extension_events __attribute((alias("IA__gdk_input_set_extension_events"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_INPUT_H__) +#if IN_FILE(__GDK_DISPLAY_C__) +#undef gdk_device_get_core_pointer +extern __typeof (gdk_device_get_core_pointer) gdk_device_get_core_pointer __attribute((alias("IA__gdk_device_get_core_pointer"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_INPUT_H__) +#if IN_FILE(__GDK_INPUT_X11_C__) +#undef gdk_device_get_state +extern __typeof (gdk_device_get_state) gdk_device_get_state __attribute((alias("IA__gdk_device_get_state"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_INPUT_H__) +#if IN_FILE(__GDK_INPUT_XFREE_C__) +#undef gdk_device_set_mode +extern __typeof (gdk_device_set_mode) gdk_device_set_mode __attribute((alias("IA__gdk_device_set_mode"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_INPUT_H__) +#if IN_FILE(__GDK_INPUT_NONE_C__) +#undef gdk_device_get_state +extern __typeof (gdk_device_get_state) gdk_device_get_state __attribute((alias("IA__gdk_device_get_state"), visibility("default"))); + +#undef gdk_device_set_mode +extern __typeof (gdk_device_set_mode) gdk_device_set_mode __attribute((alias("IA__gdk_device_set_mode"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_DISPLAY_H__) +#if IN_FILE(__GDK_EVENTS_X11_C__) +#undef gdk_display_add_client_message_filter +extern __typeof (gdk_display_add_client_message_filter) gdk_display_add_client_message_filter __attribute((alias("IA__gdk_display_add_client_message_filter"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_DISPLAY_H__) +#if IN_FILE(__GDK_DISPLAY_C__) +#undef gdk_display_close +extern __typeof (gdk_display_close) gdk_display_close __attribute((alias("IA__gdk_display_close"), visibility("default"))); + +#undef gdk_display_get_core_pointer +extern __typeof (gdk_display_get_core_pointer) gdk_display_get_core_pointer __attribute((alias("IA__gdk_display_get_core_pointer"), visibility("default"))); + +#undef gdk_display_get_event +extern __typeof (gdk_display_get_event) gdk_display_get_event __attribute((alias("IA__gdk_display_get_event"), visibility("default"))); + +#undef gdk_display_get_pointer +extern __typeof (gdk_display_get_pointer) gdk_display_get_pointer __attribute((alias("IA__gdk_display_get_pointer"), visibility("default"))); + +#undef gdk_display_get_type +extern __typeof (gdk_display_get_type) gdk_display_get_type __attribute((alias("IA__gdk_display_get_type"), visibility("default"))); + +#undef gdk_display_get_window_at_pointer +extern __typeof (gdk_display_get_window_at_pointer) gdk_display_get_window_at_pointer __attribute((alias("IA__gdk_display_get_window_at_pointer"), visibility("default"))); + +#undef gdk_display_is_closed +extern __typeof (gdk_display_is_closed) gdk_display_is_closed __attribute((alias("IA__gdk_display_is_closed"), visibility("default"))); + +#undef gdk_display_peek_event +extern __typeof (gdk_display_peek_event) gdk_display_peek_event __attribute((alias("IA__gdk_display_peek_event"), visibility("default"))); + +#undef gdk_display_put_event +extern __typeof (gdk_display_put_event) gdk_display_put_event __attribute((alias("IA__gdk_display_put_event"), visibility("default"))); + +#undef gdk_display_set_pointer_hooks +extern __typeof (gdk_display_set_pointer_hooks) gdk_display_set_pointer_hooks __attribute((alias("IA__gdk_display_set_pointer_hooks"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_DISPLAY_H__) +#if IN_FILE(__GDK_WINDOW_X11_C__) +#undef gdk_display_warp_pointer +extern __typeof (gdk_display_warp_pointer) gdk_display_warp_pointer __attribute((alias("IA__gdk_display_warp_pointer"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_DISPLAY_H__) +#if IN_FILE(__GDK_DISPLAY_MANAGER_C__) +#undef gdk_display_get_default +extern __typeof (gdk_display_get_default) gdk_display_get_default __attribute((alias("IA__gdk_display_get_default"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_DISPLAY_H__) +#if IN_FILE(__GDK_CURSOR_X11_C__) +#undef gdk_display_get_default_cursor_size +extern __typeof (gdk_display_get_default_cursor_size) gdk_display_get_default_cursor_size __attribute((alias("IA__gdk_display_get_default_cursor_size"), visibility("default"))); + +#undef gdk_display_get_maximal_cursor_size +extern __typeof (gdk_display_get_maximal_cursor_size) gdk_display_get_maximal_cursor_size __attribute((alias("IA__gdk_display_get_maximal_cursor_size"), visibility("default"))); + +#undef gdk_display_supports_cursor_alpha +extern __typeof (gdk_display_supports_cursor_alpha) gdk_display_supports_cursor_alpha __attribute((alias("IA__gdk_display_supports_cursor_alpha"), visibility("default"))); + +#undef gdk_display_supports_cursor_color +extern __typeof (gdk_display_supports_cursor_color) gdk_display_supports_cursor_color __attribute((alias("IA__gdk_display_supports_cursor_color"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_DISPLAY_H__) +#if IN_FILE(__GDK_DISPLAY_X11_C__) +#undef gdk_display_beep +extern __typeof (gdk_display_beep) gdk_display_beep __attribute((alias("IA__gdk_display_beep"), visibility("default"))); + +#undef gdk_display_sync +extern __typeof (gdk_display_sync) gdk_display_sync __attribute((alias("IA__gdk_display_sync"), visibility("default"))); + +#undef gdk_display_flush +extern __typeof (gdk_display_flush) gdk_display_flush __attribute((alias("IA__gdk_display_flush"), visibility("default"))); + +#undef gdk_display_get_default_group +extern __typeof (gdk_display_get_default_group) gdk_display_get_default_group __attribute((alias("IA__gdk_display_get_default_group"), visibility("default"))); + +#undef gdk_display_get_default_screen +extern __typeof (gdk_display_get_default_screen) gdk_display_get_default_screen __attribute((alias("IA__gdk_display_get_default_screen"), visibility("default"))); + +#undef gdk_display_get_name +extern __typeof (gdk_display_get_name) gdk_display_get_name __attribute((alias("IA__gdk_display_get_name"), visibility("default"))); + +#undef gdk_display_get_n_screens +extern __typeof (gdk_display_get_n_screens) gdk_display_get_n_screens __attribute((alias("IA__gdk_display_get_n_screens"), visibility("default"))); + +#undef gdk_display_get_screen +extern __typeof (gdk_display_get_screen) gdk_display_get_screen __attribute((alias("IA__gdk_display_get_screen"), visibility("default"))); + +#undef gdk_display_pointer_ungrab +extern __typeof (gdk_display_pointer_ungrab) gdk_display_pointer_ungrab __attribute((alias("IA__gdk_display_pointer_ungrab"), visibility("default"))); + +#undef gdk_display_keyboard_ungrab +extern __typeof (gdk_display_keyboard_ungrab) gdk_display_keyboard_ungrab __attribute((alias("IA__gdk_display_keyboard_ungrab"), visibility("default"))); + +#undef gdk_display_open +extern __typeof (gdk_display_open) gdk_display_open __attribute((alias("IA__gdk_display_open"), visibility("default"))); + +#undef gdk_display_request_selection_notification +extern __typeof (gdk_display_request_selection_notification) gdk_display_request_selection_notification __attribute((alias("IA__gdk_display_request_selection_notification"), visibility("default"))); + +#undef gdk_display_store_clipboard +extern __typeof (gdk_display_store_clipboard) gdk_display_store_clipboard __attribute((alias("IA__gdk_display_store_clipboard"), visibility("default"))); + +#undef gdk_display_supports_clipboard_persistence +extern __typeof (gdk_display_supports_clipboard_persistence) gdk_display_supports_clipboard_persistence __attribute((alias("IA__gdk_display_supports_clipboard_persistence"), visibility("default"))); + +#undef gdk_display_supports_selection_notification +extern __typeof (gdk_display_supports_selection_notification) gdk_display_supports_selection_notification __attribute((alias("IA__gdk_display_supports_selection_notification"), visibility("default"))); + +#undef gdk_display_supports_shapes +extern __typeof (gdk_display_supports_shapes) gdk_display_supports_shapes __attribute((alias("IA__gdk_display_supports_shapes"), visibility("default"))); + +#undef gdk_display_supports_input_shapes +extern __typeof (gdk_display_supports_input_shapes) gdk_display_supports_input_shapes __attribute((alias("IA__gdk_display_supports_input_shapes"), visibility("default"))); + +#undef gdk_display_supports_composite +extern __typeof (gdk_display_supports_composite) gdk_display_supports_composite __attribute((alias("IA__gdk_display_supports_composite"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_DISPLAY_H__) +#if IN_FILE(__GDK_INPUT_C__) +#undef gdk_display_list_devices +extern __typeof (gdk_display_list_devices) gdk_display_list_devices __attribute((alias("IA__gdk_display_list_devices"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_DISPLAY_H__) +#if IN_FILE(__GDK_C__) +#undef gdk_display_open_default_libgtk_only +extern __typeof (gdk_display_open_default_libgtk_only) gdk_display_open_default_libgtk_only __attribute((alias("IA__gdk_display_open_default_libgtk_only"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_DISPLAY_H__) +#if IN_FILE(__GDK_EVENTS_C__) +#undef gdk_display_set_double_click_distance +extern __typeof (gdk_display_set_double_click_distance) gdk_display_set_double_click_distance __attribute((alias("IA__gdk_display_set_double_click_distance"), visibility("default"))); + +#undef gdk_display_set_double_click_time +extern __typeof (gdk_display_set_double_click_time) gdk_display_set_double_click_time __attribute((alias("IA__gdk_display_set_double_click_time"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_DISPLAY_MANAGER_H__) +#if IN_FILE(__GDK_DISPLAY_MANAGER_C__) +#undef gdk_display_manager_get +extern __typeof (gdk_display_manager_get) gdk_display_manager_get __attribute((alias("IA__gdk_display_manager_get"), visibility("default"))); + +#undef gdk_display_manager_get_type +extern __typeof (gdk_display_manager_get_type) gdk_display_manager_get_type __attribute((alias("IA__gdk_display_manager_get_type"), visibility("default"))); + +#undef gdk_display_manager_list_displays +extern __typeof (gdk_display_manager_list_displays) gdk_display_manager_list_displays __attribute((alias("IA__gdk_display_manager_list_displays"), visibility("default"))); + +#undef gdk_display_manager_set_default_display +extern __typeof (gdk_display_manager_set_default_display) gdk_display_manager_set_default_display __attribute((alias("IA__gdk_display_manager_set_default_display"), visibility("default"))); + +#undef gdk_display_manager_get_default_display +extern __typeof (gdk_display_manager_get_default_display) gdk_display_manager_get_default_display __attribute((alias("IA__gdk_display_manager_get_default_display"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_DND_H__) +#if IN_FILE(__GDK_DND_X11_C__) +#undef gdk_drag_abort +extern __typeof (gdk_drag_abort) gdk_drag_abort __attribute((alias("IA__gdk_drag_abort"), visibility("default"))); + +#undef gdk_drag_begin +extern __typeof (gdk_drag_begin) gdk_drag_begin __attribute((alias("IA__gdk_drag_begin"), visibility("default"))); + +#undef gdk_drag_context_get_type +extern __typeof (gdk_drag_context_get_type) gdk_drag_context_get_type __attribute((alias("IA__gdk_drag_context_get_type"), visibility("default"))); + +#ifndef GDK_DISABLE_DEPRECATED +#undef gdk_drag_context_new +extern __typeof (gdk_drag_context_new) gdk_drag_context_new __attribute((alias("IA__gdk_drag_context_new"), visibility("default"))); + +#undef gdk_drag_context_ref +extern __typeof (gdk_drag_context_ref) gdk_drag_context_ref __attribute((alias("IA__gdk_drag_context_ref"), visibility("default"))); + +#undef gdk_drag_context_unref +extern __typeof (gdk_drag_context_unref) gdk_drag_context_unref __attribute((alias("IA__gdk_drag_context_unref"), visibility("default"))); + +#endif +#undef gdk_drag_drop +extern __typeof (gdk_drag_drop) gdk_drag_drop __attribute((alias("IA__gdk_drag_drop"), visibility("default"))); + +#undef gdk_drag_drop_succeeded +extern __typeof (gdk_drag_drop_succeeded) gdk_drag_drop_succeeded __attribute((alias("IA__gdk_drag_drop_succeeded"), visibility("default"))); + +#undef gdk_drag_find_window_for_screen +extern __typeof (gdk_drag_find_window_for_screen) gdk_drag_find_window_for_screen __attribute((alias("IA__gdk_drag_find_window_for_screen"), visibility("default"))); + +#undef gdk_drag_get_protocol_for_display +extern __typeof (gdk_drag_get_protocol_for_display) gdk_drag_get_protocol_for_display __attribute((alias("IA__gdk_drag_get_protocol_for_display"), visibility("default"))); + +#undef gdk_drag_get_selection +extern __typeof (gdk_drag_get_selection) gdk_drag_get_selection __attribute((alias("IA__gdk_drag_get_selection"), visibility("default"))); + +#undef gdk_drag_motion +extern __typeof (gdk_drag_motion) gdk_drag_motion __attribute((alias("IA__gdk_drag_motion"), visibility("default"))); + +#undef gdk_drag_status +extern __typeof (gdk_drag_status) gdk_drag_status __attribute((alias("IA__gdk_drag_status"), visibility("default"))); + +#undef gdk_drop_finish +extern __typeof (gdk_drop_finish) gdk_drop_finish __attribute((alias("IA__gdk_drop_finish"), visibility("default"))); + +#undef gdk_drop_reply +extern __typeof (gdk_drop_reply) gdk_drop_reply __attribute((alias("IA__gdk_drop_reply"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_DND_H__) +#if IN_FILE(__GDK_DND_C__) +#undef gdk_drag_context_get_actions +extern __typeof (gdk_drag_context_get_actions) gdk_drag_context_get_actions __attribute((alias("IA__gdk_drag_context_get_actions"), visibility("default"))); + +#undef gdk_drag_context_get_selected_action +extern __typeof (gdk_drag_context_get_selected_action) gdk_drag_context_get_selected_action __attribute((alias("IA__gdk_drag_context_get_selected_action"), visibility("default"))); + +#undef gdk_drag_context_get_suggested_action +extern __typeof (gdk_drag_context_get_suggested_action) gdk_drag_context_get_suggested_action __attribute((alias("IA__gdk_drag_context_get_suggested_action"), visibility("default"))); + +#undef gdk_drag_context_list_targets +extern __typeof (gdk_drag_context_list_targets) gdk_drag_context_list_targets __attribute((alias("IA__gdk_drag_context_list_targets"), visibility("default"))); + +#undef gdk_drag_context_get_source_window +extern __typeof (gdk_drag_context_get_source_window) gdk_drag_context_get_source_window __attribute((alias("IA__gdk_drag_context_get_source_window"), visibility("default"))); + +#undef gdk_drag_context_get_dest_window +extern __typeof (gdk_drag_context_get_dest_window) gdk_drag_context_get_dest_window __attribute((alias("IA__gdk_drag_context_get_dest_window"), visibility("default"))); + +#undef gdk_drag_context_get_protocol +extern __typeof (gdk_drag_context_get_protocol) gdk_drag_context_get_protocol __attribute((alias("IA__gdk_drag_context_get_protocol"), visibility("default"))); + +#ifndef GDK_DISABLE_DEPRECATED +#undef gdk_drag_find_window +extern __typeof (gdk_drag_find_window) gdk_drag_find_window __attribute((alias("IA__gdk_drag_find_window"), visibility("default"))); + +#undef gdk_drag_get_protocol +extern __typeof (gdk_drag_get_protocol) gdk_drag_get_protocol __attribute((alias("IA__gdk_drag_get_protocol"), visibility("default"))); + +#endif +#endif +#endif +#if IN_HEADER(__GDK_DRAWABLE_H__) +#if IN_FILE(__GDK_DRAW_C__) +#undef gdk_drawable_copy_to_image +extern __typeof (gdk_drawable_copy_to_image) gdk_drawable_copy_to_image __attribute((alias("IA__gdk_drawable_copy_to_image"), visibility("default"))); + +#undef gdk_drawable_get_clip_region +extern __typeof (gdk_drawable_get_clip_region) gdk_drawable_get_clip_region __attribute((alias("IA__gdk_drawable_get_clip_region"), visibility("default"))); + +#undef gdk_drawable_get_colormap +extern __typeof (gdk_drawable_get_colormap) gdk_drawable_get_colormap __attribute((alias("IA__gdk_drawable_get_colormap"), visibility("default"))); + +#ifndef GDK_DISABLE_DEPRECATED +#undef gdk_drawable_get_data +extern __typeof (gdk_drawable_get_data) gdk_drawable_get_data __attribute((alias("IA__gdk_drawable_get_data"), visibility("default"))); + +#undef gdk_drawable_set_data +extern __typeof (gdk_drawable_set_data) gdk_drawable_set_data __attribute((alias("IA__gdk_drawable_set_data"), visibility("default"))); + +#undef gdk_drawable_ref +extern __typeof (gdk_drawable_ref) gdk_drawable_ref __attribute((alias("IA__gdk_drawable_ref"), visibility("default"))); + +#undef gdk_drawable_unref +extern __typeof (gdk_drawable_unref) gdk_drawable_unref __attribute((alias("IA__gdk_drawable_unref"), visibility("default"))); + +#undef gdk_draw_string +extern __typeof (gdk_draw_string) gdk_draw_string __attribute((alias("IA__gdk_draw_string"), visibility("default"))); + +#undef gdk_draw_text +extern __typeof (gdk_draw_text) gdk_draw_text __attribute((alias("IA__gdk_draw_text"), visibility("default"))); + +#undef gdk_draw_text_wc +extern __typeof (gdk_draw_text_wc) gdk_draw_text_wc __attribute((alias("IA__gdk_draw_text_wc"), visibility("default"))); + +#undef gdk_drawable_get_display +extern __typeof (gdk_drawable_get_display) gdk_drawable_get_display __attribute((alias("IA__gdk_drawable_get_display"), visibility("default"))); + +#undef gdk_drawable_get_screen +extern __typeof (gdk_drawable_get_screen) gdk_drawable_get_screen __attribute((alias("IA__gdk_drawable_get_screen"), visibility("default"))); + +#undef gdk_drawable_get_size +extern __typeof (gdk_drawable_get_size) gdk_drawable_get_size __attribute((alias("IA__gdk_drawable_get_size"), visibility("default"))); + +#undef gdk_drawable_get_visual +extern __typeof (gdk_drawable_get_visual) gdk_drawable_get_visual __attribute((alias("IA__gdk_drawable_get_visual"), visibility("default"))); + +#endif +#undef gdk_drawable_get_depth +extern __typeof (gdk_drawable_get_depth) gdk_drawable_get_depth __attribute((alias("IA__gdk_drawable_get_depth"), visibility("default"))); + +#undef gdk_drawable_get_image +extern __typeof (gdk_drawable_get_image) gdk_drawable_get_image __attribute((alias("IA__gdk_drawable_get_image"), visibility("default"))); + +#undef gdk_drawable_get_type +extern __typeof (gdk_drawable_get_type) gdk_drawable_get_type __attribute((alias("IA__gdk_drawable_get_type"), visibility("default"))); + +#undef gdk_drawable_get_visible_region +extern __typeof (gdk_drawable_get_visible_region) gdk_drawable_get_visible_region __attribute((alias("IA__gdk_drawable_get_visible_region"), visibility("default"))); + +#undef gdk_drawable_set_colormap +extern __typeof (gdk_drawable_set_colormap) gdk_drawable_set_colormap __attribute((alias("IA__gdk_drawable_set_colormap"), visibility("default"))); + +#undef gdk_draw_arc +extern __typeof (gdk_draw_arc) gdk_draw_arc __attribute((alias("IA__gdk_draw_arc"), visibility("default"))); + +#undef gdk_draw_drawable +extern __typeof (gdk_draw_drawable) gdk_draw_drawable __attribute((alias("IA__gdk_draw_drawable"), visibility("default"))); + +#undef gdk_draw_glyphs +extern __typeof (gdk_draw_glyphs) gdk_draw_glyphs __attribute((alias("IA__gdk_draw_glyphs"), visibility("default"))); + +#undef gdk_draw_glyphs_transformed +extern __typeof (gdk_draw_glyphs_transformed) gdk_draw_glyphs_transformed __attribute((alias("IA__gdk_draw_glyphs_transformed"), visibility("default"))); + +#undef gdk_draw_image +extern __typeof (gdk_draw_image) gdk_draw_image __attribute((alias("IA__gdk_draw_image"), visibility("default"))); + +#undef gdk_draw_line +extern __typeof (gdk_draw_line) gdk_draw_line __attribute((alias("IA__gdk_draw_line"), visibility("default"))); + +#undef gdk_draw_lines +extern __typeof (gdk_draw_lines) gdk_draw_lines __attribute((alias("IA__gdk_draw_lines"), visibility("default"))); + +#undef gdk_draw_pixbuf +extern __typeof (gdk_draw_pixbuf) gdk_draw_pixbuf __attribute((alias("IA__gdk_draw_pixbuf"), visibility("default"))); + +#undef gdk_draw_point +extern __typeof (gdk_draw_point) gdk_draw_point __attribute((alias("IA__gdk_draw_point"), visibility("default"))); + +#undef gdk_draw_points +extern __typeof (gdk_draw_points) gdk_draw_points __attribute((alias("IA__gdk_draw_points"), visibility("default"))); + +#undef gdk_draw_polygon +extern __typeof (gdk_draw_polygon) gdk_draw_polygon __attribute((alias("IA__gdk_draw_polygon"), visibility("default"))); + +#undef gdk_draw_rectangle +extern __typeof (gdk_draw_rectangle) gdk_draw_rectangle __attribute((alias("IA__gdk_draw_rectangle"), visibility("default"))); + +#undef gdk_draw_segments +extern __typeof (gdk_draw_segments) gdk_draw_segments __attribute((alias("IA__gdk_draw_segments"), visibility("default"))); + +#undef gdk_draw_trapezoids +extern __typeof (gdk_draw_trapezoids) gdk_draw_trapezoids __attribute((alias("IA__gdk_draw_trapezoids"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_DRAWABLE_H__) +#if IN_FILE(__GDK_PANGO_C__) +#undef gdk_draw_layout +extern __typeof (gdk_draw_layout) gdk_draw_layout __attribute((alias("IA__gdk_draw_layout"), visibility("default"))); + +#undef gdk_draw_layout_line +extern __typeof (gdk_draw_layout_line) gdk_draw_layout_line __attribute((alias("IA__gdk_draw_layout_line"), visibility("default"))); + +#undef gdk_draw_layout_line_with_colors +extern __typeof (gdk_draw_layout_line_with_colors) gdk_draw_layout_line_with_colors __attribute((alias("IA__gdk_draw_layout_line_with_colors"), visibility("default"))); + +#undef gdk_draw_layout_with_colors +extern __typeof (gdk_draw_layout_with_colors) gdk_draw_layout_with_colors __attribute((alias("IA__gdk_draw_layout_with_colors"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_GC_H__) +#if IN_FILE(__GDK_GC_C__) +#undef gdk_gc_new +extern __typeof (gdk_gc_new) gdk_gc_new __attribute((alias("IA__gdk_gc_new"), visibility("default"))); + +#undef gdk_gc_get_type +extern __typeof (gdk_gc_get_type) gdk_gc_get_type __attribute((alias("IA__gdk_gc_get_type"), visibility("default"))); + +#undef gdk_gc_new_with_values +extern __typeof (gdk_gc_new_with_values) gdk_gc_new_with_values __attribute((alias("IA__gdk_gc_new_with_values"), visibility("default"))); + +#ifndef GDK_DISABLE_DEPRECATED +#undef gdk_gc_ref +extern __typeof (gdk_gc_ref) gdk_gc_ref __attribute((alias("IA__gdk_gc_ref"), visibility("default"))); + +#undef gdk_gc_unref +extern __typeof (gdk_gc_unref) gdk_gc_unref __attribute((alias("IA__gdk_gc_unref"), visibility("default"))); + +#undef gdk_gc_set_font +extern __typeof (gdk_gc_set_font) gdk_gc_set_font __attribute((alias("IA__gdk_gc_set_font"), visibility("default"))); + +#endif +#undef gdk_gc_get_values +extern __typeof (gdk_gc_get_values) gdk_gc_get_values __attribute((alias("IA__gdk_gc_get_values"), visibility("default"))); + +#undef gdk_gc_set_values +extern __typeof (gdk_gc_set_values) gdk_gc_set_values __attribute((alias("IA__gdk_gc_set_values"), visibility("default"))); + +#undef gdk_gc_set_foreground +extern __typeof (gdk_gc_set_foreground) gdk_gc_set_foreground __attribute((alias("IA__gdk_gc_set_foreground"), visibility("default"))); + +#undef gdk_gc_set_background +extern __typeof (gdk_gc_set_background) gdk_gc_set_background __attribute((alias("IA__gdk_gc_set_background"), visibility("default"))); + +#undef gdk_gc_set_function +extern __typeof (gdk_gc_set_function) gdk_gc_set_function __attribute((alias("IA__gdk_gc_set_function"), visibility("default"))); + +#undef gdk_gc_set_fill +extern __typeof (gdk_gc_set_fill) gdk_gc_set_fill __attribute((alias("IA__gdk_gc_set_fill"), visibility("default"))); + +#undef gdk_gc_set_tile +extern __typeof (gdk_gc_set_tile) gdk_gc_set_tile __attribute((alias("IA__gdk_gc_set_tile"), visibility("default"))); + +#undef gdk_gc_set_stipple +extern __typeof (gdk_gc_set_stipple) gdk_gc_set_stipple __attribute((alias("IA__gdk_gc_set_stipple"), visibility("default"))); + +#undef gdk_gc_set_ts_origin +extern __typeof (gdk_gc_set_ts_origin) gdk_gc_set_ts_origin __attribute((alias("IA__gdk_gc_set_ts_origin"), visibility("default"))); + +#undef gdk_gc_set_clip_origin +extern __typeof (gdk_gc_set_clip_origin) gdk_gc_set_clip_origin __attribute((alias("IA__gdk_gc_set_clip_origin"), visibility("default"))); + +#undef gdk_gc_set_clip_mask +extern __typeof (gdk_gc_set_clip_mask) gdk_gc_set_clip_mask __attribute((alias("IA__gdk_gc_set_clip_mask"), visibility("default"))); + +#undef gdk_gc_set_clip_rectangle +extern __typeof (gdk_gc_set_clip_rectangle) gdk_gc_set_clip_rectangle __attribute((alias("IA__gdk_gc_set_clip_rectangle"), visibility("default"))); + +#undef gdk_gc_set_clip_region +extern __typeof (gdk_gc_set_clip_region) gdk_gc_set_clip_region __attribute((alias("IA__gdk_gc_set_clip_region"), visibility("default"))); + +#undef gdk_gc_set_subwindow +extern __typeof (gdk_gc_set_subwindow) gdk_gc_set_subwindow __attribute((alias("IA__gdk_gc_set_subwindow"), visibility("default"))); + +#undef gdk_gc_set_exposures +extern __typeof (gdk_gc_set_exposures) gdk_gc_set_exposures __attribute((alias("IA__gdk_gc_set_exposures"), visibility("default"))); + +#undef gdk_gc_set_line_attributes +extern __typeof (gdk_gc_set_line_attributes) gdk_gc_set_line_attributes __attribute((alias("IA__gdk_gc_set_line_attributes"), visibility("default"))); + +#undef gdk_gc_set_dashes +extern __typeof (gdk_gc_set_dashes) gdk_gc_set_dashes __attribute((alias("IA__gdk_gc_set_dashes"), visibility("default"))); + +#undef gdk_gc_offset +extern __typeof (gdk_gc_offset) gdk_gc_offset __attribute((alias("IA__gdk_gc_offset"), visibility("default"))); + +#undef gdk_gc_copy +extern __typeof (gdk_gc_copy) gdk_gc_copy __attribute((alias("IA__gdk_gc_copy"), visibility("default"))); + +#undef gdk_gc_get_colormap +extern __typeof (gdk_gc_get_colormap) gdk_gc_get_colormap __attribute((alias("IA__gdk_gc_get_colormap"), visibility("default"))); + +#undef gdk_gc_set_colormap +extern __typeof (gdk_gc_set_colormap) gdk_gc_set_colormap __attribute((alias("IA__gdk_gc_set_colormap"), visibility("default"))); + +#undef gdk_gc_set_rgb_bg_color +extern __typeof (gdk_gc_set_rgb_bg_color) gdk_gc_set_rgb_bg_color __attribute((alias("IA__gdk_gc_set_rgb_bg_color"), visibility("default"))); + +#undef gdk_gc_set_rgb_fg_color +extern __typeof (gdk_gc_set_rgb_fg_color) gdk_gc_set_rgb_fg_color __attribute((alias("IA__gdk_gc_set_rgb_fg_color"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_GC_H__) +#if IN_FILE(__GDK_GC_X11_C__) +#undef gdk_gc_get_screen +extern __typeof (gdk_gc_get_screen) gdk_gc_get_screen __attribute((alias("IA__gdk_gc_get_screen"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_PIXMAP_X11_H__) +#if IN_FILE(__GDK_PIXMAP_X11_C__) +#ifdef GDK_WINDOWING_X11 +#undef gdk_pixmap_impl_x11_get_type +extern __typeof (gdk_pixmap_impl_x11_get_type) gdk_pixmap_impl_x11_get_type __attribute((alias("IA__gdk_pixmap_impl_x11_get_type"), visibility("default"))); + +#endif +#endif +#endif +#if IN_HEADER(__GDK_WINDOW_X11_H__) +#if IN_FILE(__GDK_WINDOW_X11_C__) +#ifdef GDK_WINDOWING_X11 +#undef gdk_window_impl_x11_get_type +extern __typeof (gdk_window_impl_x11_get_type) gdk_window_impl_x11_get_type __attribute((alias("IA__gdk_window_impl_x11_get_type"), visibility("default"))); + +#endif +#endif +#endif +#if IN_HEADER(__GDK_WINDOW_H__) +#if IN_FILE(__GDK_WINDOW_C__) +#undef gdk_get_default_root_window +extern __typeof (gdk_get_default_root_window) gdk_get_default_root_window __attribute((alias("IA__gdk_get_default_root_window"), visibility("default"))); + +#undef gdk_window_new +extern __typeof (gdk_window_new) gdk_window_new __attribute((alias("IA__gdk_window_new"), visibility("default"))); + +#undef gdk_window_show_unraised +extern __typeof (gdk_window_show_unraised) gdk_window_show_unraised __attribute((alias("IA__gdk_window_show_unraised"), visibility("default"))); + +#undef gdk_window_show +extern __typeof (gdk_window_show) gdk_window_show __attribute((alias("IA__gdk_window_show"), visibility("default"))); + +#undef gdk_window_hide +extern __typeof (gdk_window_hide) gdk_window_hide __attribute((alias("IA__gdk_window_hide"), visibility("default"))); + +#undef gdk_window_withdraw +extern __typeof (gdk_window_withdraw) gdk_window_withdraw __attribute((alias("IA__gdk_window_withdraw"), visibility("default"))); + +#undef gdk_window_get_events +extern __typeof (gdk_window_get_events) gdk_window_get_events __attribute((alias("IA__gdk_window_get_events"), visibility("default"))); + +#undef gdk_window_set_events +extern __typeof (gdk_window_set_events) gdk_window_set_events __attribute((alias("IA__gdk_window_set_events"), visibility("default"))); + +#undef gdk_window_raise +extern __typeof (gdk_window_raise) gdk_window_raise __attribute((alias("IA__gdk_window_raise"), visibility("default"))); + +#undef gdk_window_lower +extern __typeof (gdk_window_lower) gdk_window_lower __attribute((alias("IA__gdk_window_lower"), visibility("default"))); + +#undef gdk_window_restack +extern __typeof (gdk_window_restack) gdk_window_restack __attribute((alias("IA__gdk_window_restack"), visibility("default"))); + +#undef gdk_window_move +extern __typeof (gdk_window_move) gdk_window_move __attribute((alias("IA__gdk_window_move"), visibility("default"))); + +#undef gdk_window_resize +extern __typeof (gdk_window_resize) gdk_window_resize __attribute((alias("IA__gdk_window_resize"), visibility("default"))); + +#undef gdk_window_move_resize +extern __typeof (gdk_window_move_resize) gdk_window_move_resize __attribute((alias("IA__gdk_window_move_resize"), visibility("default"))); + +#undef gdk_window_scroll +extern __typeof (gdk_window_scroll) gdk_window_scroll __attribute((alias("IA__gdk_window_scroll"), visibility("default"))); + +#undef gdk_window_move_region +extern __typeof (gdk_window_move_region) gdk_window_move_region __attribute((alias("IA__gdk_window_move_region"), visibility("default"))); + +#undef gdk_window_get_accept_focus +extern __typeof (gdk_window_get_accept_focus) gdk_window_get_accept_focus __attribute((alias("IA__gdk_window_get_accept_focus"), visibility("default"))); + +#undef gdk_window_get_background_pattern +extern __typeof (gdk_window_get_background_pattern) gdk_window_get_background_pattern __attribute((alias("IA__gdk_window_get_background_pattern"), visibility("default"))); + +#undef gdk_window_get_composited +extern __typeof (gdk_window_get_composited) gdk_window_get_composited __attribute((alias("IA__gdk_window_get_composited"), visibility("default"))); + +#undef gdk_window_get_cursor +extern __typeof (gdk_window_get_cursor) gdk_window_get_cursor __attribute((alias("IA__gdk_window_get_cursor"), visibility("default"))); + +#undef gdk_window_get_deskrelative_origin +extern __typeof (gdk_window_get_deskrelative_origin) gdk_window_get_deskrelative_origin __attribute((alias("IA__gdk_window_get_deskrelative_origin"), visibility("default"))); + +#undef gdk_window_get_focus_on_map +extern __typeof (gdk_window_get_focus_on_map) gdk_window_get_focus_on_map __attribute((alias("IA__gdk_window_get_focus_on_map"), visibility("default"))); + +#undef gdk_window_get_geometry +extern __typeof (gdk_window_get_geometry) gdk_window_get_geometry __attribute((alias("IA__gdk_window_get_geometry"), visibility("default"))); + +#undef gdk_window_get_modal_hint +extern __typeof (gdk_window_get_modal_hint) gdk_window_get_modal_hint __attribute((alias("IA__gdk_window_get_modal_hint"), visibility("default"))); + +#undef gdk_window_get_origin +extern __typeof (gdk_window_get_origin) gdk_window_get_origin __attribute((alias("IA__gdk_window_get_origin"), visibility("default"))); + +#undef gdk_window_get_root_coords +extern __typeof (gdk_window_get_root_coords) gdk_window_get_root_coords __attribute((alias("IA__gdk_window_get_root_coords"), visibility("default"))); + +#undef gdk_window_set_background +extern __typeof (gdk_window_set_background) gdk_window_set_background __attribute((alias("IA__gdk_window_set_background"), visibility("default"))); + +#undef gdk_window_set_back_pixmap +extern __typeof (gdk_window_set_back_pixmap) gdk_window_set_back_pixmap __attribute((alias("IA__gdk_window_set_back_pixmap"), visibility("default"))); + +#undef gdk_window_set_cursor +extern __typeof (gdk_window_set_cursor) gdk_window_set_cursor __attribute((alias("IA__gdk_window_set_cursor"), visibility("default"))); + +#undef gdk_window_shape_combine_mask +extern __typeof (gdk_window_shape_combine_mask) gdk_window_shape_combine_mask __attribute((alias("IA__gdk_window_shape_combine_mask"), visibility("default"))); + +#undef gdk_window_shape_combine_region +extern __typeof (gdk_window_shape_combine_region) gdk_window_shape_combine_region __attribute((alias("IA__gdk_window_shape_combine_region"), visibility("default"))); + +#undef gdk_window_set_child_shapes +extern __typeof (gdk_window_set_child_shapes) gdk_window_set_child_shapes __attribute((alias("IA__gdk_window_set_child_shapes"), visibility("default"))); + +#undef gdk_window_merge_child_shapes +extern __typeof (gdk_window_merge_child_shapes) gdk_window_merge_child_shapes __attribute((alias("IA__gdk_window_merge_child_shapes"), visibility("default"))); + +#undef gdk_window_input_shape_combine_mask +extern __typeof (gdk_window_input_shape_combine_mask) gdk_window_input_shape_combine_mask __attribute((alias("IA__gdk_window_input_shape_combine_mask"), visibility("default"))); + +#undef gdk_window_input_shape_combine_region +extern __typeof (gdk_window_input_shape_combine_region) gdk_window_input_shape_combine_region __attribute((alias("IA__gdk_window_input_shape_combine_region"), visibility("default"))); + +#undef gdk_window_set_child_input_shapes +extern __typeof (gdk_window_set_child_input_shapes) gdk_window_set_child_input_shapes __attribute((alias("IA__gdk_window_set_child_input_shapes"), visibility("default"))); + +#undef gdk_window_merge_child_input_shapes +extern __typeof (gdk_window_merge_child_input_shapes) gdk_window_merge_child_input_shapes __attribute((alias("IA__gdk_window_merge_child_input_shapes"), visibility("default"))); + +#undef gdk_window_set_static_gravities +extern __typeof (gdk_window_set_static_gravities) gdk_window_set_static_gravities __attribute((alias("IA__gdk_window_set_static_gravities"), visibility("default"))); + +#undef gdk_window_reparent +extern __typeof (gdk_window_reparent) gdk_window_reparent __attribute((alias("IA__gdk_window_reparent"), visibility("default"))); + +#undef gdk_window_add_filter +extern __typeof (gdk_window_add_filter) gdk_window_add_filter __attribute((alias("IA__gdk_window_add_filter"), visibility("default"))); + +#undef gdk_window_at_pointer +extern __typeof (gdk_window_at_pointer) gdk_window_at_pointer __attribute((alias("IA__gdk_window_at_pointer"), visibility("default"))); + +#undef gdk_window_begin_paint_rect +extern __typeof (gdk_window_begin_paint_rect) gdk_window_begin_paint_rect __attribute((alias("IA__gdk_window_begin_paint_rect"), visibility("default"))); + +#undef gdk_window_begin_paint_region +extern __typeof (gdk_window_begin_paint_region) gdk_window_begin_paint_region __attribute((alias("IA__gdk_window_begin_paint_region"), visibility("default"))); + +#undef gdk_window_clear +extern __typeof (gdk_window_clear) gdk_window_clear __attribute((alias("IA__gdk_window_clear"), visibility("default"))); + +#undef gdk_window_clear_area +extern __typeof (gdk_window_clear_area) gdk_window_clear_area __attribute((alias("IA__gdk_window_clear_area"), visibility("default"))); + +#undef gdk_window_clear_area_e +extern __typeof (gdk_window_clear_area_e) gdk_window_clear_area_e __attribute((alias("IA__gdk_window_clear_area_e"), visibility("default"))); + +#undef gdk_window_constrain_size +extern __typeof (gdk_window_constrain_size) gdk_window_constrain_size __attribute((alias("IA__gdk_window_constrain_size"), visibility("default"))); + +#undef gdk_window_coords_from_parent +extern __typeof (gdk_window_coords_from_parent) gdk_window_coords_from_parent __attribute((alias("IA__gdk_window_coords_from_parent"), visibility("default"))); + +#undef gdk_window_coords_to_parent +extern __typeof (gdk_window_coords_to_parent) gdk_window_coords_to_parent __attribute((alias("IA__gdk_window_coords_to_parent"), visibility("default"))); + +#undef gdk_window_create_similar_surface +extern __typeof (gdk_window_create_similar_surface) gdk_window_create_similar_surface __attribute((alias("IA__gdk_window_create_similar_surface"), visibility("default"))); + +#undef gdk_window_destroy +extern __typeof (gdk_window_destroy) gdk_window_destroy __attribute((alias("IA__gdk_window_destroy"), visibility("default"))); + +#undef gdk_window_end_paint +extern __typeof (gdk_window_end_paint) gdk_window_end_paint __attribute((alias("IA__gdk_window_end_paint"), visibility("default"))); + +#undef gdk_window_flush +extern __typeof (gdk_window_flush) gdk_window_flush __attribute((alias("IA__gdk_window_flush"), visibility("default"))); + +#undef gdk_window_foreign_new +extern __typeof (gdk_window_foreign_new) gdk_window_foreign_new __attribute((alias("IA__gdk_window_foreign_new"), visibility("default"))); + +#undef gdk_window_freeze_toplevel_updates_libgtk_only +extern __typeof (gdk_window_freeze_toplevel_updates_libgtk_only) gdk_window_freeze_toplevel_updates_libgtk_only __attribute((alias("IA__gdk_window_freeze_toplevel_updates_libgtk_only"), visibility("default"))); + +#undef gdk_window_freeze_updates +extern __typeof (gdk_window_freeze_updates) gdk_window_freeze_updates __attribute((alias("IA__gdk_window_freeze_updates"), visibility("default"))); + +#undef gdk_window_get_children +extern __typeof (gdk_window_get_children) gdk_window_get_children __attribute((alias("IA__gdk_window_get_children"), visibility("default"))); + +#undef gdk_window_get_internal_paint_info +extern __typeof (gdk_window_get_internal_paint_info) gdk_window_get_internal_paint_info __attribute((alias("IA__gdk_window_get_internal_paint_info"), visibility("default"))); + +#undef gdk_window_get_parent +extern __typeof (gdk_window_get_parent) gdk_window_get_parent __attribute((alias("IA__gdk_window_get_parent"), visibility("default"))); + +#undef gdk_window_get_effective_parent +extern __typeof (gdk_window_get_effective_parent) gdk_window_get_effective_parent __attribute((alias("IA__gdk_window_get_effective_parent"), visibility("default"))); + +#undef gdk_window_get_pointer +extern __typeof (gdk_window_get_pointer) gdk_window_get_pointer __attribute((alias("IA__gdk_window_get_pointer"), visibility("default"))); + +#undef gdk_window_get_position +extern __typeof (gdk_window_get_position) gdk_window_get_position __attribute((alias("IA__gdk_window_get_position"), visibility("default"))); + +#undef gdk_window_get_state +extern __typeof (gdk_window_get_state) gdk_window_get_state __attribute((alias("IA__gdk_window_get_state"), visibility("default"))); + +#undef gdk_window_get_toplevel +extern __typeof (gdk_window_get_toplevel) gdk_window_get_toplevel __attribute((alias("IA__gdk_window_get_toplevel"), visibility("default"))); + +#undef gdk_window_get_effective_toplevel +extern __typeof (gdk_window_get_effective_toplevel) gdk_window_get_effective_toplevel __attribute((alias("IA__gdk_window_get_effective_toplevel"), visibility("default"))); + +#ifndef GDK_DISABLE_DEPRECATED +#undef gdk_window_get_toplevels +extern __typeof (gdk_window_get_toplevels) gdk_window_get_toplevels __attribute((alias("IA__gdk_window_get_toplevels"), visibility("default"))); + +#endif +#undef gdk_window_get_update_area +extern __typeof (gdk_window_get_update_area) gdk_window_get_update_area __attribute((alias("IA__gdk_window_get_update_area"), visibility("default"))); + +#undef gdk_window_get_user_data +extern __typeof (gdk_window_get_user_data) gdk_window_get_user_data __attribute((alias("IA__gdk_window_get_user_data"), visibility("default"))); + +#undef gdk_window_get_window_type +extern __typeof (gdk_window_get_window_type) gdk_window_get_window_type __attribute((alias("IA__gdk_window_get_window_type"), visibility("default"))); + +#undef gdk_window_has_native +extern __typeof (gdk_window_has_native) gdk_window_has_native __attribute((alias("IA__gdk_window_has_native"), visibility("default"))); + +#undef gdk_window_invalidate_maybe_recurse +extern __typeof (gdk_window_invalidate_maybe_recurse) gdk_window_invalidate_maybe_recurse __attribute((alias("IA__gdk_window_invalidate_maybe_recurse"), visibility("default"))); + +#undef gdk_window_invalidate_rect +extern __typeof (gdk_window_invalidate_rect) gdk_window_invalidate_rect __attribute((alias("IA__gdk_window_invalidate_rect"), visibility("default"))); + +#undef gdk_window_invalidate_region +extern __typeof (gdk_window_invalidate_region) gdk_window_invalidate_region __attribute((alias("IA__gdk_window_invalidate_region"), visibility("default"))); + +#undef gdk_window_is_destroyed +extern __typeof (gdk_window_is_destroyed) gdk_window_is_destroyed __attribute((alias("IA__gdk_window_is_destroyed"), visibility("default"))); + +#undef gdk_window_is_input_only +extern __typeof (gdk_window_is_input_only) gdk_window_is_input_only __attribute((alias("IA__gdk_window_is_input_only"), visibility("default"))); + +#undef gdk_window_is_shaped +extern __typeof (gdk_window_is_shaped) gdk_window_is_shaped __attribute((alias("IA__gdk_window_is_shaped"), visibility("default"))); + +#undef gdk_window_is_viewable +extern __typeof (gdk_window_is_viewable) gdk_window_is_viewable __attribute((alias("IA__gdk_window_is_viewable"), visibility("default"))); + +#undef gdk_window_is_visible +extern __typeof (gdk_window_is_visible) gdk_window_is_visible __attribute((alias("IA__gdk_window_is_visible"), visibility("default"))); + +#undef gdk_window_object_get_type +extern __typeof (gdk_window_object_get_type) gdk_window_object_get_type __attribute((alias("IA__gdk_window_object_get_type"), visibility("default"))); + +#undef gdk_window_peek_children +extern __typeof (gdk_window_peek_children) gdk_window_peek_children __attribute((alias("IA__gdk_window_peek_children"), visibility("default"))); + +#undef gdk_window_process_all_updates +extern __typeof (gdk_window_process_all_updates) gdk_window_process_all_updates __attribute((alias("IA__gdk_window_process_all_updates"), visibility("default"))); + +#undef gdk_window_process_updates +extern __typeof (gdk_window_process_updates) gdk_window_process_updates __attribute((alias("IA__gdk_window_process_updates"), visibility("default"))); + +#undef gdk_window_redirect_to_drawable +extern __typeof (gdk_window_redirect_to_drawable) gdk_window_redirect_to_drawable __attribute((alias("IA__gdk_window_redirect_to_drawable"), visibility("default"))); + +#undef gdk_window_remove_filter +extern __typeof (gdk_window_remove_filter) gdk_window_remove_filter __attribute((alias("IA__gdk_window_remove_filter"), visibility("default"))); + +#undef gdk_window_remove_redirection +extern __typeof (gdk_window_remove_redirection) gdk_window_remove_redirection __attribute((alias("IA__gdk_window_remove_redirection"), visibility("default"))); + +#undef gdk_window_set_debug_updates +extern __typeof (gdk_window_set_debug_updates) gdk_window_set_debug_updates __attribute((alias("IA__gdk_window_set_debug_updates"), visibility("default"))); + +#undef gdk_window_set_user_data +extern __typeof (gdk_window_set_user_data) gdk_window_set_user_data __attribute((alias("IA__gdk_window_set_user_data"), visibility("default"))); + +#undef gdk_window_thaw_toplevel_updates_libgtk_only +extern __typeof (gdk_window_thaw_toplevel_updates_libgtk_only) gdk_window_thaw_toplevel_updates_libgtk_only __attribute((alias("IA__gdk_window_thaw_toplevel_updates_libgtk_only"), visibility("default"))); + +#undef gdk_window_thaw_updates +extern __typeof (gdk_window_thaw_updates) gdk_window_thaw_updates __attribute((alias("IA__gdk_window_thaw_updates"), visibility("default"))); + +#undef gdk_window_set_composited +extern __typeof (gdk_window_set_composited) gdk_window_set_composited __attribute((alias("IA__gdk_window_set_composited"), visibility("default"))); + +#undef gdk_pointer_grab +extern __typeof (gdk_pointer_grab) gdk_pointer_grab __attribute((alias("IA__gdk_pointer_grab"), visibility("default"))); + +#undef gdk_window_beep +extern __typeof (gdk_window_beep) gdk_window_beep __attribute((alias("IA__gdk_window_beep"), visibility("default"))); + +#undef gdk_window_geometry_changed +extern __typeof (gdk_window_geometry_changed) gdk_window_geometry_changed __attribute((alias("IA__gdk_window_geometry_changed"), visibility("default"))); + +#undef gdk_window_ensure_native +extern __typeof (gdk_window_ensure_native) gdk_window_ensure_native __attribute((alias("IA__gdk_window_ensure_native"), visibility("default"))); + +#undef gdk_window_get_screen +extern __typeof (gdk_window_get_screen) gdk_window_get_screen __attribute((alias("IA__gdk_window_get_screen"), visibility("default"))); + +#undef gdk_window_get_display +extern __typeof (gdk_window_get_display) gdk_window_get_display __attribute((alias("IA__gdk_window_get_display"), visibility("default"))); + +#undef gdk_window_get_visual +extern __typeof (gdk_window_get_visual) gdk_window_get_visual __attribute((alias("IA__gdk_window_get_visual"), visibility("default"))); + +#undef gdk_window_get_width +extern __typeof (gdk_window_get_width) gdk_window_get_width __attribute((alias("IA__gdk_window_get_width"), visibility("default"))); + +#undef gdk_window_get_height +extern __typeof (gdk_window_get_height) gdk_window_get_height __attribute((alias("IA__gdk_window_get_height"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_WINDOW_H__) +#if IN_FILE(__GDK_OFFSCREEN_WINDOW_C__) +#undef gdk_offscreen_window_get_pixmap +extern __typeof (gdk_offscreen_window_get_pixmap) gdk_offscreen_window_get_pixmap __attribute((alias("IA__gdk_offscreen_window_get_pixmap"), visibility("default"))); + +#undef gdk_offscreen_window_set_embedder +extern __typeof (gdk_offscreen_window_set_embedder) gdk_offscreen_window_set_embedder __attribute((alias("IA__gdk_offscreen_window_set_embedder"), visibility("default"))); + +#undef gdk_offscreen_window_get_embedder +extern __typeof (gdk_offscreen_window_get_embedder) gdk_offscreen_window_get_embedder __attribute((alias("IA__gdk_offscreen_window_get_embedder"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_INTERNALS_H__) +#if IN_FILE(__GDK_OFFSCREEN_WINDOW_C__) +#undef gdk_offscreen_window_get_type +extern __typeof (gdk_offscreen_window_get_type) gdk_offscreen_window_get_type __attribute((alias("IA__gdk_offscreen_window_get_type"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_WINDOW_H__) +#if IN_FILE(__GDK_DND_X11_C__) +#undef gdk_window_register_dnd +extern __typeof (gdk_window_register_dnd) gdk_window_register_dnd __attribute((alias("IA__gdk_window_register_dnd"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_WINDOW_H__) +#if IN_FILE(__GDK_WINDOW_X11_C__) +#undef gdk_window_foreign_new_for_display +extern __typeof (gdk_window_foreign_new_for_display) gdk_window_foreign_new_for_display __attribute((alias("IA__gdk_window_foreign_new_for_display"), visibility("default"))); + +#undef gdk_window_focus +extern __typeof (gdk_window_focus) gdk_window_focus __attribute((alias("IA__gdk_window_focus"), visibility("default"))); + +#undef gdk_window_lookup +extern __typeof (gdk_window_lookup) gdk_window_lookup __attribute((alias("IA__gdk_window_lookup"), visibility("default"))); + +#undef gdk_window_lookup_for_display +extern __typeof (gdk_window_lookup_for_display) gdk_window_lookup_for_display __attribute((alias("IA__gdk_window_lookup_for_display"), visibility("default"))); + +#ifndef GDK_DISABLE_DEPRECATED +#undef gdk_window_set_hints +extern __typeof (gdk_window_set_hints) gdk_window_set_hints __attribute((alias("IA__gdk_window_set_hints"), visibility("default"))); + +#endif +#undef gdk_window_get_type_hint +extern __typeof (gdk_window_get_type_hint) gdk_window_get_type_hint __attribute((alias("IA__gdk_window_get_type_hint"), visibility("default"))); + +#undef gdk_window_set_type_hint +extern __typeof (gdk_window_set_type_hint) gdk_window_set_type_hint __attribute((alias("IA__gdk_window_set_type_hint"), visibility("default"))); + +#undef gdk_window_set_modal_hint +extern __typeof (gdk_window_set_modal_hint) gdk_window_set_modal_hint __attribute((alias("IA__gdk_window_set_modal_hint"), visibility("default"))); + +#undef gdk_window_set_skip_taskbar_hint +extern __typeof (gdk_window_set_skip_taskbar_hint) gdk_window_set_skip_taskbar_hint __attribute((alias("IA__gdk_window_set_skip_taskbar_hint"), visibility("default"))); + +#undef gdk_window_set_skip_pager_hint +extern __typeof (gdk_window_set_skip_pager_hint) gdk_window_set_skip_pager_hint __attribute((alias("IA__gdk_window_set_skip_pager_hint"), visibility("default"))); + +#undef gdk_window_set_urgency_hint +extern __typeof (gdk_window_set_urgency_hint) gdk_window_set_urgency_hint __attribute((alias("IA__gdk_window_set_urgency_hint"), visibility("default"))); + +#undef gdk_window_set_geometry_hints +extern __typeof (gdk_window_set_geometry_hints) gdk_window_set_geometry_hints __attribute((alias("IA__gdk_window_set_geometry_hints"), visibility("default"))); + +#undef gdk_window_set_title +extern __typeof (gdk_window_set_title) gdk_window_set_title __attribute((alias("IA__gdk_window_set_title"), visibility("default"))); + +#undef gdk_window_set_role +extern __typeof (gdk_window_set_role) gdk_window_set_role __attribute((alias("IA__gdk_window_set_role"), visibility("default"))); + +#undef gdk_window_set_startup_id +extern __typeof (gdk_window_set_startup_id) gdk_window_set_startup_id __attribute((alias("IA__gdk_window_set_startup_id"), visibility("default"))); + +#undef gdk_window_set_transient_for +extern __typeof (gdk_window_set_transient_for) gdk_window_set_transient_for __attribute((alias("IA__gdk_window_set_transient_for"), visibility("default"))); + +#undef gdk_window_get_root_origin +extern __typeof (gdk_window_get_root_origin) gdk_window_get_root_origin __attribute((alias("IA__gdk_window_get_root_origin"), visibility("default"))); + +#undef gdk_window_get_frame_extents +extern __typeof (gdk_window_get_frame_extents) gdk_window_get_frame_extents __attribute((alias("IA__gdk_window_get_frame_extents"), visibility("default"))); + +#undef gdk_window_set_override_redirect +extern __typeof (gdk_window_set_override_redirect) gdk_window_set_override_redirect __attribute((alias("IA__gdk_window_set_override_redirect"), visibility("default"))); + +#undef gdk_window_set_accept_focus +extern __typeof (gdk_window_set_accept_focus) gdk_window_set_accept_focus __attribute((alias("IA__gdk_window_set_accept_focus"), visibility("default"))); + +#undef gdk_window_set_focus_on_map +extern __typeof (gdk_window_set_focus_on_map) gdk_window_set_focus_on_map __attribute((alias("IA__gdk_window_set_focus_on_map"), visibility("default"))); + +#undef gdk_window_set_icon_list +extern __typeof (gdk_window_set_icon_list) gdk_window_set_icon_list __attribute((alias("IA__gdk_window_set_icon_list"), visibility("default"))); + +#undef gdk_window_set_icon +extern __typeof (gdk_window_set_icon) gdk_window_set_icon __attribute((alias("IA__gdk_window_set_icon"), visibility("default"))); + +#undef gdk_window_set_icon_name +extern __typeof (gdk_window_set_icon_name) gdk_window_set_icon_name __attribute((alias("IA__gdk_window_set_icon_name"), visibility("default"))); + +#undef gdk_window_set_opacity +extern __typeof (gdk_window_set_opacity) gdk_window_set_opacity __attribute((alias("IA__gdk_window_set_opacity"), visibility("default"))); + +#undef gdk_window_iconify +extern __typeof (gdk_window_iconify) gdk_window_iconify __attribute((alias("IA__gdk_window_iconify"), visibility("default"))); + +#undef gdk_window_deiconify +extern __typeof (gdk_window_deiconify) gdk_window_deiconify __attribute((alias("IA__gdk_window_deiconify"), visibility("default"))); + +#undef gdk_window_stick +extern __typeof (gdk_window_stick) gdk_window_stick __attribute((alias("IA__gdk_window_stick"), visibility("default"))); + +#undef gdk_window_unstick +extern __typeof (gdk_window_unstick) gdk_window_unstick __attribute((alias("IA__gdk_window_unstick"), visibility("default"))); + +#undef gdk_window_maximize +extern __typeof (gdk_window_maximize) gdk_window_maximize __attribute((alias("IA__gdk_window_maximize"), visibility("default"))); + +#undef gdk_window_unmaximize +extern __typeof (gdk_window_unmaximize) gdk_window_unmaximize __attribute((alias("IA__gdk_window_unmaximize"), visibility("default"))); + +#undef gdk_window_fullscreen +extern __typeof (gdk_window_fullscreen) gdk_window_fullscreen __attribute((alias("IA__gdk_window_fullscreen"), visibility("default"))); + +#undef gdk_window_unfullscreen +extern __typeof (gdk_window_unfullscreen) gdk_window_unfullscreen __attribute((alias("IA__gdk_window_unfullscreen"), visibility("default"))); + +#undef gdk_window_set_keep_above +extern __typeof (gdk_window_set_keep_above) gdk_window_set_keep_above __attribute((alias("IA__gdk_window_set_keep_above"), visibility("default"))); + +#undef gdk_window_set_keep_below +extern __typeof (gdk_window_set_keep_below) gdk_window_set_keep_below __attribute((alias("IA__gdk_window_set_keep_below"), visibility("default"))); + +#undef gdk_window_get_group +extern __typeof (gdk_window_get_group) gdk_window_get_group __attribute((alias("IA__gdk_window_get_group"), visibility("default"))); + +#undef gdk_window_set_group +extern __typeof (gdk_window_set_group) gdk_window_set_group __attribute((alias("IA__gdk_window_set_group"), visibility("default"))); + +#undef gdk_window_get_decorations +extern __typeof (gdk_window_get_decorations) gdk_window_get_decorations __attribute((alias("IA__gdk_window_get_decorations"), visibility("default"))); + +#undef gdk_window_set_decorations +extern __typeof (gdk_window_set_decorations) gdk_window_set_decorations __attribute((alias("IA__gdk_window_set_decorations"), visibility("default"))); + +#undef gdk_window_set_functions +extern __typeof (gdk_window_set_functions) gdk_window_set_functions __attribute((alias("IA__gdk_window_set_functions"), visibility("default"))); + +#undef gdk_window_begin_move_drag +extern __typeof (gdk_window_begin_move_drag) gdk_window_begin_move_drag __attribute((alias("IA__gdk_window_begin_move_drag"), visibility("default"))); + +#undef gdk_window_begin_resize_drag +extern __typeof (gdk_window_begin_resize_drag) gdk_window_begin_resize_drag __attribute((alias("IA__gdk_window_begin_resize_drag"), visibility("default"))); + +#undef gdk_window_enable_synchronized_configure +extern __typeof (gdk_window_enable_synchronized_configure) gdk_window_enable_synchronized_configure __attribute((alias("IA__gdk_window_enable_synchronized_configure"), visibility("default"))); + +#undef gdk_window_configure_finished +extern __typeof (gdk_window_configure_finished) gdk_window_configure_finished __attribute((alias("IA__gdk_window_configure_finished"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_IMAGE_H__) +#if IN_FILE(__GDK_IMAGE_C__) +#undef gdk_image_get_bits_per_pixel +extern __typeof (gdk_image_get_bits_per_pixel) gdk_image_get_bits_per_pixel __attribute((alias("IA__gdk_image_get_bits_per_pixel"), visibility("default"))); + +#undef gdk_image_get_bytes_per_pixel +extern __typeof (gdk_image_get_bytes_per_pixel) gdk_image_get_bytes_per_pixel __attribute((alias("IA__gdk_image_get_bytes_per_pixel"), visibility("default"))); + +#undef gdk_image_get_bytes_per_line +extern __typeof (gdk_image_get_bytes_per_line) gdk_image_get_bytes_per_line __attribute((alias("IA__gdk_image_get_bytes_per_line"), visibility("default"))); + +#undef gdk_image_get_byte_order +extern __typeof (gdk_image_get_byte_order) gdk_image_get_byte_order __attribute((alias("IA__gdk_image_get_byte_order"), visibility("default"))); + +#undef gdk_image_get_depth +extern __typeof (gdk_image_get_depth) gdk_image_get_depth __attribute((alias("IA__gdk_image_get_depth"), visibility("default"))); + +#undef gdk_image_get_height +extern __typeof (gdk_image_get_height) gdk_image_get_height __attribute((alias("IA__gdk_image_get_height"), visibility("default"))); + +#undef gdk_image_get_image_type +extern __typeof (gdk_image_get_image_type) gdk_image_get_image_type __attribute((alias("IA__gdk_image_get_image_type"), visibility("default"))); + +#undef gdk_image_get_visual +extern __typeof (gdk_image_get_visual) gdk_image_get_visual __attribute((alias("IA__gdk_image_get_visual"), visibility("default"))); + +#undef gdk_image_get_width +extern __typeof (gdk_image_get_width) gdk_image_get_width __attribute((alias("IA__gdk_image_get_width"), visibility("default"))); + +#ifndef GDK_DISABLE_DEPRECATED +#undef gdk_image_ref +extern __typeof (gdk_image_ref) gdk_image_ref __attribute((alias("IA__gdk_image_ref"), visibility("default"))); + +#undef gdk_image_unref +extern __typeof (gdk_image_unref) gdk_image_unref __attribute((alias("IA__gdk_image_unref"), visibility("default"))); + +#undef gdk_image_get +extern __typeof (gdk_image_get) gdk_image_get __attribute((alias("IA__gdk_image_get"), visibility("default"))); + +#endif +#undef gdk_image_get_pixels +extern __typeof (gdk_image_get_pixels) gdk_image_get_pixels __attribute((alias("IA__gdk_image_get_pixels"), visibility("default"))); + +#undef gdk_image_set_colormap +extern __typeof (gdk_image_set_colormap) gdk_image_set_colormap __attribute((alias("IA__gdk_image_set_colormap"), visibility("default"))); + +#undef gdk_image_get_colormap +extern __typeof (gdk_image_get_colormap) gdk_image_get_colormap __attribute((alias("IA__gdk_image_get_colormap"), visibility("default"))); + +#undef gdk_image_new +extern __typeof (gdk_image_new) gdk_image_new __attribute((alias("IA__gdk_image_new"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_IMAGE_H__) +#if IN_FILE(__GDK_IMAGE_X11_C__) +#ifdef GDK_ENABLE_BROKEN +#undef gdk_image_new_bitmap +extern __typeof (gdk_image_new_bitmap) gdk_image_new_bitmap __attribute((alias("IA__gdk_image_new_bitmap"), visibility("default"))); + +#endif +#undef gdk_image_get_pixel +extern __typeof (gdk_image_get_pixel) gdk_image_get_pixel __attribute((alias("IA__gdk_image_get_pixel"), visibility("default"))); + +#undef gdk_image_put_pixel +extern __typeof (gdk_image_put_pixel) gdk_image_put_pixel __attribute((alias("IA__gdk_image_put_pixel"), visibility("default"))); + +#undef gdk_image_get_type +extern __typeof (gdk_image_get_type) gdk_image_get_type __attribute((alias("IA__gdk_image_get_type"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_KEYS_H__) +#if IN_FILE(__GDK_KEYS_C__) +#undef gdk_keymap_get_default +extern __typeof (gdk_keymap_get_default) gdk_keymap_get_default __attribute((alias("IA__gdk_keymap_get_default"), visibility("default"))); + +#undef gdk_keymap_get_type +extern __typeof (gdk_keymap_get_type) gdk_keymap_get_type __attribute((alias("IA__gdk_keymap_get_type"), visibility("default"))); + +#undef gdk_keyval_is_lower +extern __typeof (gdk_keyval_is_lower) gdk_keyval_is_lower __attribute((alias("IA__gdk_keyval_is_lower"), visibility("default"))); + +#undef gdk_keyval_is_upper +extern __typeof (gdk_keyval_is_upper) gdk_keyval_is_upper __attribute((alias("IA__gdk_keyval_is_upper"), visibility("default"))); + +#undef gdk_keyval_to_lower +extern __typeof (gdk_keyval_to_lower) gdk_keyval_to_lower __attribute((alias("IA__gdk_keyval_to_lower"), visibility("default"))); + +#undef gdk_keyval_to_upper +extern __typeof (gdk_keyval_to_upper) gdk_keyval_to_upper __attribute((alias("IA__gdk_keyval_to_upper"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_KEYS_H__) +#if IN_FILE(__GDK_KEYUNI_C__) +#undef gdk_keyval_to_unicode +extern __typeof (gdk_keyval_to_unicode) gdk_keyval_to_unicode __attribute((alias("IA__gdk_keyval_to_unicode"), visibility("default"))); + +#undef gdk_unicode_to_keyval +extern __typeof (gdk_unicode_to_keyval) gdk_unicode_to_keyval __attribute((alias("IA__gdk_unicode_to_keyval"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_KEYS_H__) +#if IN_FILE(__GDK_KEYS_X11_C__) +#undef gdk_keymap_get_direction +extern __typeof (gdk_keymap_get_direction) gdk_keymap_get_direction __attribute((alias("IA__gdk_keymap_get_direction"), visibility("default"))); + +#undef gdk_keymap_get_entries_for_keycode +extern __typeof (gdk_keymap_get_entries_for_keycode) gdk_keymap_get_entries_for_keycode __attribute((alias("IA__gdk_keymap_get_entries_for_keycode"), visibility("default"))); + +#undef gdk_keymap_get_entries_for_keyval +extern __typeof (gdk_keymap_get_entries_for_keyval) gdk_keymap_get_entries_for_keyval __attribute((alias("IA__gdk_keymap_get_entries_for_keyval"), visibility("default"))); + +#undef gdk_keymap_get_for_display +extern __typeof (gdk_keymap_get_for_display) gdk_keymap_get_for_display __attribute((alias("IA__gdk_keymap_get_for_display"), visibility("default"))); + +#undef gdk_keymap_have_bidi_layouts +extern __typeof (gdk_keymap_have_bidi_layouts) gdk_keymap_have_bidi_layouts __attribute((alias("IA__gdk_keymap_have_bidi_layouts"), visibility("default"))); + +#undef gdk_keymap_get_caps_lock_state +extern __typeof (gdk_keymap_get_caps_lock_state) gdk_keymap_get_caps_lock_state __attribute((alias("IA__gdk_keymap_get_caps_lock_state"), visibility("default"))); + +#undef gdk_keymap_lookup_key +extern __typeof (gdk_keymap_lookup_key) gdk_keymap_lookup_key __attribute((alias("IA__gdk_keymap_lookup_key"), visibility("default"))); + +#undef gdk_keymap_translate_keyboard_state +extern __typeof (gdk_keymap_translate_keyboard_state) gdk_keymap_translate_keyboard_state __attribute((alias("IA__gdk_keymap_translate_keyboard_state"), visibility("default"))); + +#undef gdk_keymap_add_virtual_modifiers +extern __typeof (gdk_keymap_add_virtual_modifiers) gdk_keymap_add_virtual_modifiers __attribute((alias("IA__gdk_keymap_add_virtual_modifiers"), visibility("default"))); + +#undef gdk_keymap_map_virtual_modifiers +extern __typeof (gdk_keymap_map_virtual_modifiers) gdk_keymap_map_virtual_modifiers __attribute((alias("IA__gdk_keymap_map_virtual_modifiers"), visibility("default"))); + +#undef gdk_keyval_convert_case +extern __typeof (gdk_keyval_convert_case) gdk_keyval_convert_case __attribute((alias("IA__gdk_keyval_convert_case"), visibility("default"))); + +#undef gdk_keyval_from_name +extern __typeof (gdk_keyval_from_name) gdk_keyval_from_name __attribute((alias("IA__gdk_keyval_from_name"), visibility("default"))); + +#undef gdk_keyval_name +extern __typeof (gdk_keyval_name) gdk_keyval_name __attribute((alias("IA__gdk_keyval_name"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_KEYS_H__) +#if IN_FILE(__GDK_KEYS_DIRECTFB_C__) +#undef gdk_keymap_get_direction +extern __typeof (gdk_keymap_get_direction) gdk_keymap_get_direction __attribute((alias("IA__gdk_keymap_get_direction"), visibility("default"))); + +#undef gdk_keymap_get_entries_for_keycode +extern __typeof (gdk_keymap_get_entries_for_keycode) gdk_keymap_get_entries_for_keycode __attribute((alias("IA__gdk_keymap_get_entries_for_keycode"), visibility("default"))); + +#undef gdk_keymap_get_entries_for_keyval +extern __typeof (gdk_keymap_get_entries_for_keyval) gdk_keymap_get_entries_for_keyval __attribute((alias("IA__gdk_keymap_get_entries_for_keyval"), visibility("default"))); + +#undef gdk_keymap_get_for_display +extern __typeof (gdk_keymap_get_for_display) gdk_keymap_get_for_display __attribute((alias("IA__gdk_keymap_get_for_display"), visibility("default"))); + +#undef gdk_keymap_get_caps_lock_state +extern __typeof (gdk_keymap_get_caps_lock_state) gdk_keymap_get_caps_lock_state __attribute((alias("IA__gdk_keymap_get_caps_lock_state"), visibility("default"))); + +#undef gdk_keymap_lookup_key +extern __typeof (gdk_keymap_lookup_key) gdk_keymap_lookup_key __attribute((alias("IA__gdk_keymap_lookup_key"), visibility("default"))); + +#undef gdk_keymap_translate_keyboard_state +extern __typeof (gdk_keymap_translate_keyboard_state) gdk_keymap_translate_keyboard_state __attribute((alias("IA__gdk_keymap_translate_keyboard_state"), visibility("default"))); + +#undef gdk_keymap_add_virtual_modifiers +extern __typeof (gdk_keymap_add_virtual_modifiers) gdk_keymap_add_virtual_modifiers __attribute((alias("IA__gdk_keymap_add_virtual_modifiers"), visibility("default"))); + +#undef gdk_keymap_map_virtual_modifiers +extern __typeof (gdk_keymap_map_virtual_modifiers) gdk_keymap_map_virtual_modifiers __attribute((alias("IA__gdk_keymap_map_virtual_modifiers"), visibility("default"))); + +#undef gdk_keyval_from_name +extern __typeof (gdk_keyval_from_name) gdk_keyval_from_name __attribute((alias("IA__gdk_keyval_from_name"), visibility("default"))); + +#undef gdk_keyval_name +extern __typeof (gdk_keyval_name) gdk_keyval_name __attribute((alias("IA__gdk_keyval_name"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_VISUAL_H__) +#if IN_FILE(__GDK_VISUAL_C__) +#undef gdk_list_visuals +extern __typeof (gdk_list_visuals) gdk_list_visuals __attribute((alias("IA__gdk_list_visuals"), visibility("default"))); + +#undef gdk_visual_get_bits_per_rgb +extern __typeof (gdk_visual_get_bits_per_rgb) gdk_visual_get_bits_per_rgb __attribute((alias("IA__gdk_visual_get_bits_per_rgb"), visibility("default"))); + +#undef gdk_visual_get_blue_pixel_details +extern __typeof (gdk_visual_get_blue_pixel_details) gdk_visual_get_blue_pixel_details __attribute((alias("IA__gdk_visual_get_blue_pixel_details"), visibility("default"))); + +#undef gdk_visual_get_byte_order +extern __typeof (gdk_visual_get_byte_order) gdk_visual_get_byte_order __attribute((alias("IA__gdk_visual_get_byte_order"), visibility("default"))); + +#undef gdk_visual_get_colormap_size +extern __typeof (gdk_visual_get_colormap_size) gdk_visual_get_colormap_size __attribute((alias("IA__gdk_visual_get_colormap_size"), visibility("default"))); + +#undef gdk_visual_get_depth +extern __typeof (gdk_visual_get_depth) gdk_visual_get_depth __attribute((alias("IA__gdk_visual_get_depth"), visibility("default"))); + +#undef gdk_visual_get_green_pixel_details +extern __typeof (gdk_visual_get_green_pixel_details) gdk_visual_get_green_pixel_details __attribute((alias("IA__gdk_visual_get_green_pixel_details"), visibility("default"))); + +#undef gdk_visual_get_red_pixel_details +extern __typeof (gdk_visual_get_red_pixel_details) gdk_visual_get_red_pixel_details __attribute((alias("IA__gdk_visual_get_red_pixel_details"), visibility("default"))); + +#undef gdk_visual_get_system +extern __typeof (gdk_visual_get_system) gdk_visual_get_system __attribute((alias("IA__gdk_visual_get_system"), visibility("default"))); + +#undef gdk_visual_get_visual_type +extern __typeof (gdk_visual_get_visual_type) gdk_visual_get_visual_type __attribute((alias("IA__gdk_visual_get_visual_type"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_VISUAL_H__) +#if IN_FILE(__GDK_VISUAL_X11_C__) +#undef gdk_query_depths +extern __typeof (gdk_query_depths) gdk_query_depths __attribute((alias("IA__gdk_query_depths"), visibility("default"))); + +#undef gdk_query_visual_types +extern __typeof (gdk_query_visual_types) gdk_query_visual_types __attribute((alias("IA__gdk_query_visual_types"), visibility("default"))); + +#undef gdk_visual_get_best +extern __typeof (gdk_visual_get_best) gdk_visual_get_best __attribute((alias("IA__gdk_visual_get_best"), visibility("default"))); + +#undef gdk_visual_get_best_depth +extern __typeof (gdk_visual_get_best_depth) gdk_visual_get_best_depth __attribute((alias("IA__gdk_visual_get_best_depth"), visibility("default"))); + +#undef gdk_visual_get_best_type +extern __typeof (gdk_visual_get_best_type) gdk_visual_get_best_type __attribute((alias("IA__gdk_visual_get_best_type"), visibility("default"))); + +#undef gdk_visual_get_best_with_both +extern __typeof (gdk_visual_get_best_with_both) gdk_visual_get_best_with_both __attribute((alias("IA__gdk_visual_get_best_with_both"), visibility("default"))); + +#undef gdk_visual_get_best_with_depth +extern __typeof (gdk_visual_get_best_with_depth) gdk_visual_get_best_with_depth __attribute((alias("IA__gdk_visual_get_best_with_depth"), visibility("default"))); + +#undef gdk_visual_get_best_with_type +extern __typeof (gdk_visual_get_best_with_type) gdk_visual_get_best_with_type __attribute((alias("IA__gdk_visual_get_best_with_type"), visibility("default"))); + +#undef gdk_visual_get_screen +extern __typeof (gdk_visual_get_screen) gdk_visual_get_screen __attribute((alias("IA__gdk_visual_get_screen"), visibility("default"))); + +#undef gdk_visual_get_type +extern __typeof (gdk_visual_get_type) gdk_visual_get_type __attribute((alias("IA__gdk_visual_get_type"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_X_H__) +#if IN_FILE(__GDK_EVENTS_X11_C__) +#ifndef GDK_DISABLE_DEPRECATED +#undef gdk_net_wm_supports +extern __typeof (gdk_net_wm_supports) gdk_net_wm_supports __attribute((alias("IA__gdk_net_wm_supports"), visibility("default"))); + +#endif +#endif +#endif +#if IN_HEADER(__GDK_PANGO_H__) +#if IN_FILE(__GDK_PANGO_C__) +#undef gdk_pango_attr_emboss_color_new +extern __typeof (gdk_pango_attr_emboss_color_new) gdk_pango_attr_emboss_color_new __attribute((alias("IA__gdk_pango_attr_emboss_color_new"), visibility("default"))); + +#undef gdk_pango_attr_embossed_new +extern __typeof (gdk_pango_attr_embossed_new) gdk_pango_attr_embossed_new __attribute((alias("IA__gdk_pango_attr_embossed_new"), visibility("default"))); + +#undef gdk_pango_attr_stipple_new +extern __typeof (gdk_pango_attr_stipple_new) gdk_pango_attr_stipple_new __attribute((alias("IA__gdk_pango_attr_stipple_new"), visibility("default"))); + +#undef gdk_pango_context_get +extern __typeof (gdk_pango_context_get) gdk_pango_context_get __attribute((alias("IA__gdk_pango_context_get"), visibility("default"))); + +#undef gdk_pango_context_get_for_screen +extern __typeof (gdk_pango_context_get_for_screen) gdk_pango_context_get_for_screen __attribute((alias("IA__gdk_pango_context_get_for_screen"), visibility("default"))); + +#ifndef GDK_DISABLE_DEPRECATED +#undef gdk_pango_context_set_colormap +extern __typeof (gdk_pango_context_set_colormap) gdk_pango_context_set_colormap __attribute((alias("IA__gdk_pango_context_set_colormap"), visibility("default"))); + +#endif +#undef gdk_pango_layout_get_clip_region +extern __typeof (gdk_pango_layout_get_clip_region) gdk_pango_layout_get_clip_region __attribute((alias("IA__gdk_pango_layout_get_clip_region"), visibility("default"))); + +#undef gdk_pango_layout_line_get_clip_region +extern __typeof (gdk_pango_layout_line_get_clip_region) gdk_pango_layout_line_get_clip_region __attribute((alias("IA__gdk_pango_layout_line_get_clip_region"), visibility("default"))); + +#undef gdk_pango_renderer_get_default +extern __typeof (gdk_pango_renderer_get_default) gdk_pango_renderer_get_default __attribute((alias("IA__gdk_pango_renderer_get_default"), visibility("default"))); + +#undef gdk_pango_renderer_get_type +extern __typeof (gdk_pango_renderer_get_type) gdk_pango_renderer_get_type __attribute((alias("IA__gdk_pango_renderer_get_type"), visibility("default"))); + +#undef gdk_pango_renderer_new +extern __typeof (gdk_pango_renderer_new) gdk_pango_renderer_new __attribute((alias("IA__gdk_pango_renderer_new"), visibility("default"))); + +#undef gdk_pango_renderer_set_drawable +extern __typeof (gdk_pango_renderer_set_drawable) gdk_pango_renderer_set_drawable __attribute((alias("IA__gdk_pango_renderer_set_drawable"), visibility("default"))); + +#undef gdk_pango_renderer_set_gc +extern __typeof (gdk_pango_renderer_set_gc) gdk_pango_renderer_set_gc __attribute((alias("IA__gdk_pango_renderer_set_gc"), visibility("default"))); + +#undef gdk_pango_renderer_set_override_color +extern __typeof (gdk_pango_renderer_set_override_color) gdk_pango_renderer_set_override_color __attribute((alias("IA__gdk_pango_renderer_set_override_color"), visibility("default"))); + +#undef gdk_pango_renderer_set_stipple +extern __typeof (gdk_pango_renderer_set_stipple) gdk_pango_renderer_set_stipple __attribute((alias("IA__gdk_pango_renderer_set_stipple"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_PIXBUF_H__) +#if IN_FILE(__GDK_PIXBUF_DRAWABLE_C__) +#undef gdk_pixbuf_get_from_drawable +extern __typeof (gdk_pixbuf_get_from_drawable) gdk_pixbuf_get_from_drawable __attribute((alias("IA__gdk_pixbuf_get_from_drawable"), visibility("default"))); + +#undef gdk_pixbuf_get_from_image +extern __typeof (gdk_pixbuf_get_from_image) gdk_pixbuf_get_from_image __attribute((alias("IA__gdk_pixbuf_get_from_image"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_PIXBUF_H__) +#if IN_FILE(__GDK_PIXBUF_RENDER_C__) +#undef gdk_pixbuf_render_pixmap_and_mask +extern __typeof (gdk_pixbuf_render_pixmap_and_mask) gdk_pixbuf_render_pixmap_and_mask __attribute((alias("IA__gdk_pixbuf_render_pixmap_and_mask"), visibility("default"))); + +#undef gdk_pixbuf_render_pixmap_and_mask_for_colormap +extern __typeof (gdk_pixbuf_render_pixmap_and_mask_for_colormap) gdk_pixbuf_render_pixmap_and_mask_for_colormap __attribute((alias("IA__gdk_pixbuf_render_pixmap_and_mask_for_colormap"), visibility("default"))); + +#undef gdk_pixbuf_render_threshold_alpha +extern __typeof (gdk_pixbuf_render_threshold_alpha) gdk_pixbuf_render_threshold_alpha __attribute((alias("IA__gdk_pixbuf_render_threshold_alpha"), visibility("default"))); + +#ifndef GDK_DISABLE_DEPRECATED +#undef gdk_pixbuf_render_to_drawable +extern __typeof (gdk_pixbuf_render_to_drawable) gdk_pixbuf_render_to_drawable __attribute((alias("IA__gdk_pixbuf_render_to_drawable"), visibility("default"))); + +#undef gdk_pixbuf_render_to_drawable_alpha +extern __typeof (gdk_pixbuf_render_to_drawable_alpha) gdk_pixbuf_render_to_drawable_alpha __attribute((alias("IA__gdk_pixbuf_render_to_drawable_alpha"), visibility("default"))); + +#endif +#endif +#endif +#if IN_HEADER(__GDK_PIXMAP_H__) +#if IN_FILE(__GDK_PIXMAP_C__) +#undef gdk_bitmap_create_from_data +extern __typeof (gdk_bitmap_create_from_data) gdk_bitmap_create_from_data __attribute((alias("IA__gdk_bitmap_create_from_data"), visibility("default"))); + +#undef gdk_pixmap_colormap_create_from_xpm +extern __typeof (gdk_pixmap_colormap_create_from_xpm) gdk_pixmap_colormap_create_from_xpm __attribute((alias("IA__gdk_pixmap_colormap_create_from_xpm"), visibility("default"))); + +#undef gdk_pixmap_create_from_data +extern __typeof (gdk_pixmap_create_from_data) gdk_pixmap_create_from_data __attribute((alias("IA__gdk_pixmap_create_from_data"), visibility("default"))); + +#undef gdk_pixmap_create_from_xpm +extern __typeof (gdk_pixmap_create_from_xpm) gdk_pixmap_create_from_xpm __attribute((alias("IA__gdk_pixmap_create_from_xpm"), visibility("default"))); + +#undef gdk_pixmap_colormap_create_from_xpm_d +extern __typeof (gdk_pixmap_colormap_create_from_xpm_d) gdk_pixmap_colormap_create_from_xpm_d __attribute((alias("IA__gdk_pixmap_colormap_create_from_xpm_d"), visibility("default"))); + +#undef gdk_pixmap_create_from_xpm_d +extern __typeof (gdk_pixmap_create_from_xpm_d) gdk_pixmap_create_from_xpm_d __attribute((alias("IA__gdk_pixmap_create_from_xpm_d"), visibility("default"))); + +#undef gdk_pixmap_get_size +extern __typeof (gdk_pixmap_get_size) gdk_pixmap_get_size __attribute((alias("IA__gdk_pixmap_get_size"), visibility("default"))); + +#undef gdk_pixmap_get_type +extern __typeof (gdk_pixmap_get_type) gdk_pixmap_get_type __attribute((alias("IA__gdk_pixmap_get_type"), visibility("default"))); + +#undef gdk_pixmap_new +extern __typeof (gdk_pixmap_new) gdk_pixmap_new __attribute((alias("IA__gdk_pixmap_new"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_PIXMAP_H__) +#if IN_FILE(__GDK_PIXMAP_X11_C__) +#undef gdk_pixmap_foreign_new +extern __typeof (gdk_pixmap_foreign_new) gdk_pixmap_foreign_new __attribute((alias("IA__gdk_pixmap_foreign_new"), visibility("default"))); + +#undef gdk_pixmap_foreign_new_for_display +extern __typeof (gdk_pixmap_foreign_new_for_display) gdk_pixmap_foreign_new_for_display __attribute((alias("IA__gdk_pixmap_foreign_new_for_display"), visibility("default"))); + +#undef gdk_pixmap_foreign_new_for_screen +extern __typeof (gdk_pixmap_foreign_new_for_screen) gdk_pixmap_foreign_new_for_screen __attribute((alias("IA__gdk_pixmap_foreign_new_for_screen"), visibility("default"))); + +#undef gdk_pixmap_lookup +extern __typeof (gdk_pixmap_lookup) gdk_pixmap_lookup __attribute((alias("IA__gdk_pixmap_lookup"), visibility("default"))); + +#undef gdk_pixmap_lookup_for_display +extern __typeof (gdk_pixmap_lookup_for_display) gdk_pixmap_lookup_for_display __attribute((alias("IA__gdk_pixmap_lookup_for_display"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_REGION_H__) +#if IN_FILE(__GDK_REGION_GENERIC_C__) +#undef gdk_region_copy +extern __typeof (gdk_region_copy) gdk_region_copy __attribute((alias("IA__gdk_region_copy"), visibility("default"))); + +#undef gdk_region_destroy +extern __typeof (gdk_region_destroy) gdk_region_destroy __attribute((alias("IA__gdk_region_destroy"), visibility("default"))); + +#undef gdk_region_empty +extern __typeof (gdk_region_empty) gdk_region_empty __attribute((alias("IA__gdk_region_empty"), visibility("default"))); + +#undef gdk_region_equal +extern __typeof (gdk_region_equal) gdk_region_equal __attribute((alias("IA__gdk_region_equal"), visibility("default"))); + +#ifndef GDK_DISABLE_DEPRECATED +#undef gdk_region_rect_equal +extern __typeof (gdk_region_rect_equal) gdk_region_rect_equal __attribute((alias("IA__gdk_region_rect_equal"), visibility("default"))); + +#endif +#undef gdk_region_get_clipbox +extern __typeof (gdk_region_get_clipbox) gdk_region_get_clipbox __attribute((alias("IA__gdk_region_get_clipbox"), visibility("default"))); + +#undef gdk_region_get_rectangles +extern __typeof (gdk_region_get_rectangles) gdk_region_get_rectangles __attribute((alias("IA__gdk_region_get_rectangles"), visibility("default"))); + +#undef gdk_region_intersect +extern __typeof (gdk_region_intersect) gdk_region_intersect __attribute((alias("IA__gdk_region_intersect"), visibility("default"))); + +#undef gdk_region_new +extern __typeof (gdk_region_new) gdk_region_new __attribute((alias("IA__gdk_region_new"), visibility("default"))); + +#undef gdk_region_offset +extern __typeof (gdk_region_offset) gdk_region_offset __attribute((alias("IA__gdk_region_offset"), visibility("default"))); + +#undef gdk_region_point_in +extern __typeof (gdk_region_point_in) gdk_region_point_in __attribute((alias("IA__gdk_region_point_in"), visibility("default"))); + +#undef gdk_region_rectangle +extern __typeof (gdk_region_rectangle) gdk_region_rectangle __attribute((alias("IA__gdk_region_rectangle"), visibility("default"))); + +#undef gdk_region_rect_in +extern __typeof (gdk_region_rect_in) gdk_region_rect_in __attribute((alias("IA__gdk_region_rect_in"), visibility("default"))); + +#ifndef GDK_DISABLE_DEPRECATED +#undef gdk_region_shrink +extern __typeof (gdk_region_shrink) gdk_region_shrink __attribute((alias("IA__gdk_region_shrink"), visibility("default"))); + +#undef gdk_region_spans_intersect_foreach +extern __typeof (gdk_region_spans_intersect_foreach) gdk_region_spans_intersect_foreach __attribute((alias("IA__gdk_region_spans_intersect_foreach"), visibility("default"))); + +#endif +#undef gdk_region_subtract +extern __typeof (gdk_region_subtract) gdk_region_subtract __attribute((alias("IA__gdk_region_subtract"), visibility("default"))); + +#undef gdk_region_union +extern __typeof (gdk_region_union) gdk_region_union __attribute((alias("IA__gdk_region_union"), visibility("default"))); + +#undef gdk_region_union_with_rect +extern __typeof (gdk_region_union_with_rect) gdk_region_union_with_rect __attribute((alias("IA__gdk_region_union_with_rect"), visibility("default"))); + +#ifndef GDK_DISABLE_DEPRECATED +#undef gdk_region_xor +extern __typeof (gdk_region_xor) gdk_region_xor __attribute((alias("IA__gdk_region_xor"), visibility("default"))); + +#endif +#endif +#endif +#if IN_HEADER(__GDK_REGION_H__) +#if IN_FILE(__GDK_POLYREG_GENERIC_C__) +#ifndef GDK_DISABLE_DEPRECATED +#undef gdk_region_polygon +extern __typeof (gdk_region_polygon) gdk_region_polygon __attribute((alias("IA__gdk_region_polygon"), visibility("default"))); + +#endif +#endif +#endif +#if IN_HEADER(__GDK_RGB_H__) +#if IN_FILE(__GDK_RGB_C__) +#undef gdk_rgb_cmap_free +extern __typeof (gdk_rgb_cmap_free) gdk_rgb_cmap_free __attribute((alias("IA__gdk_rgb_cmap_free"), visibility("default"))); + +#undef gdk_rgb_cmap_new +extern __typeof (gdk_rgb_cmap_new) gdk_rgb_cmap_new __attribute((alias("IA__gdk_rgb_cmap_new"), visibility("default"))); + +#undef gdk_rgb_colormap_ditherable +extern __typeof (gdk_rgb_colormap_ditherable) gdk_rgb_colormap_ditherable __attribute((alias("IA__gdk_rgb_colormap_ditherable"), visibility("default"))); + +#undef gdk_rgb_ditherable +extern __typeof (gdk_rgb_ditherable) gdk_rgb_ditherable __attribute((alias("IA__gdk_rgb_ditherable"), visibility("default"))); + +#undef gdk_rgb_find_color +extern __typeof (gdk_rgb_find_color) gdk_rgb_find_color __attribute((alias("IA__gdk_rgb_find_color"), visibility("default"))); + +#undef gdk_rgb_get_colormap +extern __typeof (gdk_rgb_get_colormap) gdk_rgb_get_colormap __attribute((alias("IA__gdk_rgb_get_colormap"), visibility("default"))); + +#undef gdk_rgb_get_visual +extern __typeof (gdk_rgb_get_visual) gdk_rgb_get_visual __attribute((alias("IA__gdk_rgb_get_visual"), visibility("default"))); + +#ifndef GDK_DISABLE_DEPRECATED +#undef gdk_rgb_init +extern __typeof (gdk_rgb_init) gdk_rgb_init __attribute((alias("IA__gdk_rgb_init"), visibility("default"))); + +#undef gdk_rgb_xpixel_from_rgb +extern __typeof (gdk_rgb_xpixel_from_rgb) gdk_rgb_xpixel_from_rgb __attribute((alias("IA__gdk_rgb_xpixel_from_rgb"), visibility("default"))); + +#undef gdk_rgb_gc_set_background +extern __typeof (gdk_rgb_gc_set_background) gdk_rgb_gc_set_background __attribute((alias("IA__gdk_rgb_gc_set_background"), visibility("default"))); + +#undef gdk_rgb_gc_set_foreground +extern __typeof (gdk_rgb_gc_set_foreground) gdk_rgb_gc_set_foreground __attribute((alias("IA__gdk_rgb_gc_set_foreground"), visibility("default"))); + +#endif +#undef gdk_rgb_set_install +extern __typeof (gdk_rgb_set_install) gdk_rgb_set_install __attribute((alias("IA__gdk_rgb_set_install"), visibility("default"))); + +#undef gdk_rgb_set_min_colors +extern __typeof (gdk_rgb_set_min_colors) gdk_rgb_set_min_colors __attribute((alias("IA__gdk_rgb_set_min_colors"), visibility("default"))); + +#undef gdk_rgb_set_verbose +extern __typeof (gdk_rgb_set_verbose) gdk_rgb_set_verbose __attribute((alias("IA__gdk_rgb_set_verbose"), visibility("default"))); + +#undef gdk_draw_gray_image +extern __typeof (gdk_draw_gray_image) gdk_draw_gray_image __attribute((alias("IA__gdk_draw_gray_image"), visibility("default"))); + +#undef gdk_draw_indexed_image +extern __typeof (gdk_draw_indexed_image) gdk_draw_indexed_image __attribute((alias("IA__gdk_draw_indexed_image"), visibility("default"))); + +#undef gdk_draw_rgb_32_image +extern __typeof (gdk_draw_rgb_32_image) gdk_draw_rgb_32_image __attribute((alias("IA__gdk_draw_rgb_32_image"), visibility("default"))); + +#undef gdk_draw_rgb_32_image_dithalign +extern __typeof (gdk_draw_rgb_32_image_dithalign) gdk_draw_rgb_32_image_dithalign __attribute((alias("IA__gdk_draw_rgb_32_image_dithalign"), visibility("default"))); + +#undef gdk_draw_rgb_image +extern __typeof (gdk_draw_rgb_image) gdk_draw_rgb_image __attribute((alias("IA__gdk_draw_rgb_image"), visibility("default"))); + +#undef gdk_draw_rgb_image_dithalign +extern __typeof (gdk_draw_rgb_image_dithalign) gdk_draw_rgb_image_dithalign __attribute((alias("IA__gdk_draw_rgb_image_dithalign"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_SCREEN_H__) +#if IN_FILE(__GDK_SCREEN_C__) +#undef gdk_screen_get_type +extern __typeof (gdk_screen_get_type) gdk_screen_get_type __attribute((alias("IA__gdk_screen_get_type"), visibility("default"))); + +#undef gdk_screen_get_monitor_at_point +extern __typeof (gdk_screen_get_monitor_at_point) gdk_screen_get_monitor_at_point __attribute((alias("IA__gdk_screen_get_monitor_at_point"), visibility("default"))); + +#undef gdk_screen_get_monitor_at_window +extern __typeof (gdk_screen_get_monitor_at_window) gdk_screen_get_monitor_at_window __attribute((alias("IA__gdk_screen_get_monitor_at_window"), visibility("default"))); + +#undef gdk_screen_set_font_options +extern __typeof (gdk_screen_set_font_options) gdk_screen_set_font_options __attribute((alias("IA__gdk_screen_set_font_options"), visibility("default"))); + +#undef gdk_screen_get_font_options +extern __typeof (gdk_screen_get_font_options) gdk_screen_get_font_options __attribute((alias("IA__gdk_screen_get_font_options"), visibility("default"))); + +#undef gdk_screen_set_resolution +extern __typeof (gdk_screen_set_resolution) gdk_screen_set_resolution __attribute((alias("IA__gdk_screen_set_resolution"), visibility("default"))); + +#undef gdk_screen_get_resolution +extern __typeof (gdk_screen_get_resolution) gdk_screen_get_resolution __attribute((alias("IA__gdk_screen_get_resolution"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_SCREEN_H__) +#if IN_FILE(__GDK_DISPLAY_MANAGER_C__) +#undef gdk_screen_get_default +extern __typeof (gdk_screen_get_default) gdk_screen_get_default __attribute((alias("IA__gdk_screen_get_default"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_SCREEN_H__) +#if IN_FILE(__GDK_RGB_C__) +#undef gdk_screen_get_rgb_colormap +extern __typeof (gdk_screen_get_rgb_colormap) gdk_screen_get_rgb_colormap __attribute((alias("IA__gdk_screen_get_rgb_colormap"), visibility("default"))); + +#undef gdk_screen_get_rgb_visual +extern __typeof (gdk_screen_get_rgb_visual) gdk_screen_get_rgb_visual __attribute((alias("IA__gdk_screen_get_rgb_visual"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_SCREEN_H__) +#if IN_FILE(__GDK_EVENTS_X11_C__) +#undef gdk_screen_get_setting +extern __typeof (gdk_screen_get_setting) gdk_screen_get_setting __attribute((alias("IA__gdk_screen_get_setting"), visibility("default"))); + +#undef gdk_screen_broadcast_client_message +extern __typeof (gdk_screen_broadcast_client_message) gdk_screen_broadcast_client_message __attribute((alias("IA__gdk_screen_broadcast_client_message"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_SCREEN_H__) +#if IN_FILE(__GDK_VISUAL_X11_C__) +#undef gdk_screen_get_system_visual +extern __typeof (gdk_screen_get_system_visual) gdk_screen_get_system_visual __attribute((alias("IA__gdk_screen_get_system_visual"), visibility("default"))); + +#undef gdk_screen_list_visuals +extern __typeof (gdk_screen_list_visuals) gdk_screen_list_visuals __attribute((alias("IA__gdk_screen_list_visuals"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_SCREEN_H__) +#if IN_FILE(__GDK_WINDOW_C__) +#undef gdk_screen_get_toplevel_windows +extern __typeof (gdk_screen_get_toplevel_windows) gdk_screen_get_toplevel_windows __attribute((alias("IA__gdk_screen_get_toplevel_windows"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_SCREEN_H__) +#if IN_FILE(__GDK_SCREEN_X11_C__) +#undef gdk_screen_get_display +extern __typeof (gdk_screen_get_display) gdk_screen_get_display __attribute((alias("IA__gdk_screen_get_display"), visibility("default"))); + +#undef gdk_screen_get_width +extern __typeof (gdk_screen_get_width) gdk_screen_get_width __attribute((alias("IA__gdk_screen_get_width"), visibility("default"))); + +#undef gdk_screen_get_width_mm +extern __typeof (gdk_screen_get_width_mm) gdk_screen_get_width_mm __attribute((alias("IA__gdk_screen_get_width_mm"), visibility("default"))); + +#undef gdk_screen_get_height +extern __typeof (gdk_screen_get_height) gdk_screen_get_height __attribute((alias("IA__gdk_screen_get_height"), visibility("default"))); + +#undef gdk_screen_get_height_mm +extern __typeof (gdk_screen_get_height_mm) gdk_screen_get_height_mm __attribute((alias("IA__gdk_screen_get_height_mm"), visibility("default"))); + +#undef gdk_screen_get_number +extern __typeof (gdk_screen_get_number) gdk_screen_get_number __attribute((alias("IA__gdk_screen_get_number"), visibility("default"))); + +#undef gdk_screen_get_primary_monitor +extern __typeof (gdk_screen_get_primary_monitor) gdk_screen_get_primary_monitor __attribute((alias("IA__gdk_screen_get_primary_monitor"), visibility("default"))); + +#undef gdk_screen_get_root_window +extern __typeof (gdk_screen_get_root_window) gdk_screen_get_root_window __attribute((alias("IA__gdk_screen_get_root_window"), visibility("default"))); + +#undef gdk_screen_get_default_colormap +extern __typeof (gdk_screen_get_default_colormap) gdk_screen_get_default_colormap __attribute((alias("IA__gdk_screen_get_default_colormap"), visibility("default"))); + +#undef gdk_screen_set_default_colormap +extern __typeof (gdk_screen_set_default_colormap) gdk_screen_set_default_colormap __attribute((alias("IA__gdk_screen_set_default_colormap"), visibility("default"))); + +#undef gdk_screen_get_n_monitors +extern __typeof (gdk_screen_get_n_monitors) gdk_screen_get_n_monitors __attribute((alias("IA__gdk_screen_get_n_monitors"), visibility("default"))); + +#undef gdk_screen_get_monitor_geometry +extern __typeof (gdk_screen_get_monitor_geometry) gdk_screen_get_monitor_geometry __attribute((alias("IA__gdk_screen_get_monitor_geometry"), visibility("default"))); + +#undef gdk_screen_get_monitor_width_mm +extern __typeof (gdk_screen_get_monitor_width_mm) gdk_screen_get_monitor_width_mm __attribute((alias("IA__gdk_screen_get_monitor_width_mm"), visibility("default"))); + +#undef gdk_screen_get_monitor_height_mm +extern __typeof (gdk_screen_get_monitor_height_mm) gdk_screen_get_monitor_height_mm __attribute((alias("IA__gdk_screen_get_monitor_height_mm"), visibility("default"))); + +#undef gdk_screen_get_monitor_plug_name +extern __typeof (gdk_screen_get_monitor_plug_name) gdk_screen_get_monitor_plug_name __attribute((alias("IA__gdk_screen_get_monitor_plug_name"), visibility("default"))); + +#undef gdk_screen_get_rgba_colormap +extern __typeof (gdk_screen_get_rgba_colormap) gdk_screen_get_rgba_colormap __attribute((alias("IA__gdk_screen_get_rgba_colormap"), visibility("default"))); + +#undef gdk_screen_get_rgba_visual +extern __typeof (gdk_screen_get_rgba_visual) gdk_screen_get_rgba_visual __attribute((alias("IA__gdk_screen_get_rgba_visual"), visibility("default"))); + +#undef gdk_screen_get_active_window +extern __typeof (gdk_screen_get_active_window) gdk_screen_get_active_window __attribute((alias("IA__gdk_screen_get_active_window"), visibility("default"))); + +#undef gdk_screen_get_window_stack +extern __typeof (gdk_screen_get_window_stack) gdk_screen_get_window_stack __attribute((alias("IA__gdk_screen_get_window_stack"), visibility("default"))); + +#undef gdk_screen_is_composited +extern __typeof (gdk_screen_is_composited) gdk_screen_is_composited __attribute((alias("IA__gdk_screen_is_composited"), visibility("default"))); + +#undef gdk_screen_make_display_name +extern __typeof (gdk_screen_make_display_name) gdk_screen_make_display_name __attribute((alias("IA__gdk_screen_make_display_name"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_SCREEN_H__) +#if IN_FILE(__GDK_COLOR_X11_C__) +#undef gdk_screen_get_system_colormap +extern __typeof (gdk_screen_get_system_colormap) gdk_screen_get_system_colormap __attribute((alias("IA__gdk_screen_get_system_colormap"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_SELECTION_H__) +#if IN_FILE(__GDK_SELECTION_C__) +#undef gdk_selection_owner_set +extern __typeof (gdk_selection_owner_set) gdk_selection_owner_set __attribute((alias("IA__gdk_selection_owner_set"), visibility("default"))); + +#undef gdk_selection_owner_get +extern __typeof (gdk_selection_owner_get) gdk_selection_owner_get __attribute((alias("IA__gdk_selection_owner_get"), visibility("default"))); + +#undef gdk_selection_send_notify +extern __typeof (gdk_selection_send_notify) gdk_selection_send_notify __attribute((alias("IA__gdk_selection_send_notify"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_SELECTION_H__) +#if IN_FILE(__GDK_SELECTION_X11_C__) +#undef gdk_selection_convert +extern __typeof (gdk_selection_convert) gdk_selection_convert __attribute((alias("IA__gdk_selection_convert"), visibility("default"))); + +#undef gdk_selection_owner_get_for_display +extern __typeof (gdk_selection_owner_get_for_display) gdk_selection_owner_get_for_display __attribute((alias("IA__gdk_selection_owner_get_for_display"), visibility("default"))); + +#undef gdk_selection_owner_set_for_display +extern __typeof (gdk_selection_owner_set_for_display) gdk_selection_owner_set_for_display __attribute((alias("IA__gdk_selection_owner_set_for_display"), visibility("default"))); + +#undef gdk_selection_property_get +extern __typeof (gdk_selection_property_get) gdk_selection_property_get __attribute((alias("IA__gdk_selection_property_get"), visibility("default"))); + +#undef gdk_selection_send_notify_for_display +extern __typeof (gdk_selection_send_notify_for_display) gdk_selection_send_notify_for_display __attribute((alias("IA__gdk_selection_send_notify_for_display"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_WINDOW_H__) +#if IN_FILE(__GDK_DISPLAY_C__) +#undef gdk_set_sm_client_id +extern __typeof (gdk_set_sm_client_id) gdk_set_sm_client_id __attribute((alias("IA__gdk_set_sm_client_id"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_SPAWN_H__) +#if IN_FILE(__GDK_SPAWN_X11_C__) +#ifndef GDK_DISABLE_DEPRECATED +#undef gdk_spawn_command_line_on_screen +extern __typeof (gdk_spawn_command_line_on_screen) gdk_spawn_command_line_on_screen __attribute((alias("IA__gdk_spawn_command_line_on_screen"), visibility("default"))); + +#undef gdk_spawn_on_screen +extern __typeof (gdk_spawn_on_screen) gdk_spawn_on_screen __attribute((alias("IA__gdk_spawn_on_screen"), visibility("default"))); + +#undef gdk_spawn_on_screen_with_pipes +extern __typeof (gdk_spawn_on_screen_with_pipes) gdk_spawn_on_screen_with_pipes __attribute((alias("IA__gdk_spawn_on_screen_with_pipes"), visibility("default"))); + +#endif +#endif +#endif +#if IN_HEADER(__GDK_PRIVATE_H__) +#if IN_FILE(__GDK_EVENTS_C__) +#undef gdk_synthesize_window_state +extern __typeof (gdk_synthesize_window_state) gdk_synthesize_window_state __attribute((alias("IA__gdk_synthesize_window_state"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_PRIVATE_H__) +#if IN_FILE(__GDK_WINDOW_X11_C__) +#undef gdk_window_destroy_notify +extern __typeof (gdk_window_destroy_notify) gdk_window_destroy_notify __attribute((alias("IA__gdk_window_destroy_notify"), visibility("default"))); + +#endif +#endif +#ifdef GDK_WINDOWING_WIN32 +#if IN_HEADER(__GDK_WIN32_H__) +#if IN_FILE(__GDK_WINDOW_WIN32_C__) +#undef gdk_win32_window_is_win32 +extern __typeof (gdk_win32_window_is_win32) gdk_win32_window_is_win32 __attribute((alias("IA__gdk_win32_window_is_win32"), visibility("default"))); + +#undef gdk_win32_window_get_impl_hwnd +extern __typeof (gdk_win32_window_get_impl_hwnd) gdk_win32_window_get_impl_hwnd __attribute((alias("IA__gdk_win32_window_get_impl_hwnd"), visibility("default"))); + +#undef gdk_win32_begin_direct_draw_libgtk_only +extern __typeof (gdk_win32_begin_direct_draw_libgtk_only) gdk_win32_begin_direct_draw_libgtk_only __attribute((alias("IA__gdk_win32_begin_direct_draw_libgtk_only"), visibility("default"))); + +#undef gdk_win32_end_direct_draw_libgtk_only +extern __typeof (gdk_win32_end_direct_draw_libgtk_only) gdk_win32_end_direct_draw_libgtk_only __attribute((alias("IA__gdk_win32_end_direct_draw_libgtk_only"), visibility("default"))); + +#undef gdk_win32_window_lookup_for_display +extern __typeof (gdk_win32_window_lookup_for_display) gdk_win32_window_lookup_for_display __attribute((alias("IA__gdk_win32_window_lookup_for_display"), visibility("default"))); + +#undef gdk_win32_window_foreign_new_for_display +extern __typeof (gdk_win32_window_foreign_new_for_display) gdk_win32_window_foreign_new_for_display __attribute((alias("IA__gdk_win32_window_foreign_new_for_display"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_WIN32_H__) +#if IN_FILE(__GDK_WIN32ID_C__) +#undef gdk_win32_handle_table_lookup +extern __typeof (gdk_win32_handle_table_lookup) gdk_win32_handle_table_lookup __attribute((alias("IA__gdk_win32_handle_table_lookup"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_WIN32_H__) +#if IN_FILE(__GDK_CURSOR_WIN32_C__) +#undef gdk_win32_icon_to_pixbuf_libgtk_only +extern __typeof (gdk_win32_icon_to_pixbuf_libgtk_only) gdk_win32_icon_to_pixbuf_libgtk_only __attribute((alias("IA__gdk_win32_icon_to_pixbuf_libgtk_only"), visibility("default"))); + +#undef gdk_win32_pixbuf_to_hicon_libgtk_only +extern __typeof (gdk_win32_pixbuf_to_hicon_libgtk_only) gdk_win32_pixbuf_to_hicon_libgtk_only __attribute((alias("IA__gdk_win32_pixbuf_to_hicon_libgtk_only"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_WIN32_H__) +#if IN_FILE(__GDK_DRAWABLE_WIN32_C__) +#undef gdk_win32_drawable_get_handle +extern __typeof (gdk_win32_drawable_get_handle) gdk_win32_drawable_get_handle __attribute((alias("IA__gdk_win32_drawable_get_handle"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_WIN32_H__) +#if IN_FILE(__GDK_EVENTS_WIN32_C__) +#undef gdk_win32_set_modal_dialog_libgtk_only +extern __typeof (gdk_win32_set_modal_dialog_libgtk_only) gdk_win32_set_modal_dialog_libgtk_only __attribute((alias("IA__gdk_win32_set_modal_dialog_libgtk_only"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_WIN32_H__) +#if IN_FILE(__GDK_GC_WIN32_C__) +#undef gdk_win32_hdc_get +extern __typeof (gdk_win32_hdc_get) gdk_win32_hdc_get __attribute((alias("IA__gdk_win32_hdc_get"), visibility("default"))); + +#undef gdk_win32_hdc_release +extern __typeof (gdk_win32_hdc_release) gdk_win32_hdc_release __attribute((alias("IA__gdk_win32_hdc_release"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_WIN32_H__) +#if IN_FILE(__GDK_SELECTION_WIN32_C__) +#undef gdk_win32_selection_add_targets +extern __typeof (gdk_win32_selection_add_targets) gdk_win32_selection_add_targets __attribute((alias("IA__gdk_win32_selection_add_targets"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_WIN32_H__) +#if IN_FILE(__GDK_KEYS_WIN32_C__) +#undef gdk_win32_keymap_get_type +extern __typeof (gdk_win32_keymap_get_type) gdk_win32_keymap_get_type __attribute((alias("IA__gdk_win32_keymap_get_type"), visibility("default"))); + +#undef gdk_win32_keymap_check_compose +extern __typeof (gdk_win32_keymap_check_compose) gdk_win32_keymap_check_compose __attribute((alias("IA__gdk_win32_keymap_check_compose"), visibility("default"))); + +#endif +#endif +#endif +#ifdef GDK_WINDOWING_X11 +#if IN_HEADER(__GDK_X_H__) +#if IN_FILE(__GDK_PROPERTY_X11_C__) +#undef gdk_x11_atom_to_xatom +extern __typeof (gdk_x11_atom_to_xatom) gdk_x11_atom_to_xatom __attribute((alias("IA__gdk_x11_atom_to_xatom"), visibility("default"))); + +#undef gdk_x11_atom_to_xatom_for_display +extern __typeof (gdk_x11_atom_to_xatom_for_display) gdk_x11_atom_to_xatom_for_display __attribute((alias("IA__gdk_x11_atom_to_xatom_for_display"), visibility("default"))); + +#undef gdk_x11_get_xatom_by_name +extern __typeof (gdk_x11_get_xatom_by_name) gdk_x11_get_xatom_by_name __attribute((alias("IA__gdk_x11_get_xatom_by_name"), visibility("default"))); + +#undef gdk_x11_get_xatom_by_name_for_display +extern __typeof (gdk_x11_get_xatom_by_name_for_display) gdk_x11_get_xatom_by_name_for_display __attribute((alias("IA__gdk_x11_get_xatom_by_name_for_display"), visibility("default"))); + +#undef gdk_x11_get_xatom_name +extern __typeof (gdk_x11_get_xatom_name) gdk_x11_get_xatom_name __attribute((alias("IA__gdk_x11_get_xatom_name"), visibility("default"))); + +#undef gdk_x11_get_xatom_name_for_display +extern __typeof (gdk_x11_get_xatom_name_for_display) gdk_x11_get_xatom_name_for_display __attribute((alias("IA__gdk_x11_get_xatom_name_for_display"), visibility("default"))); + +#undef gdk_x11_xatom_to_atom +extern __typeof (gdk_x11_xatom_to_atom) gdk_x11_xatom_to_atom __attribute((alias("IA__gdk_x11_xatom_to_atom"), visibility("default"))); + +#undef gdk_x11_xatom_to_atom_for_display +extern __typeof (gdk_x11_xatom_to_atom_for_display) gdk_x11_xatom_to_atom_for_display __attribute((alias("IA__gdk_x11_xatom_to_atom_for_display"), visibility("default"))); + +#endif +#if IN_FILE(__GDK_COLOR_X11_C__) +#undef gdk_x11_colormap_foreign_new +extern __typeof (gdk_x11_colormap_foreign_new) gdk_x11_colormap_foreign_new __attribute((alias("IA__gdk_x11_colormap_foreign_new"), visibility("default"))); + +#undef gdk_x11_colormap_get_xcolormap +extern __typeof (gdk_x11_colormap_get_xcolormap) gdk_x11_colormap_get_xcolormap __attribute((alias("IA__gdk_x11_colormap_get_xcolormap"), visibility("default"))); + +#undef gdk_x11_colormap_get_xdisplay +extern __typeof (gdk_x11_colormap_get_xdisplay) gdk_x11_colormap_get_xdisplay __attribute((alias("IA__gdk_x11_colormap_get_xdisplay"), visibility("default"))); + +#ifdef GDK_ENABLE_BROKEN +#undef gdkx_colormap_get +extern __typeof (gdkx_colormap_get) gdkx_colormap_get __attribute((alias("IA__gdkx_colormap_get"), visibility("default"))); + +#endif +#endif +#if IN_FILE(__GDK_CURSOR_X11_C__) +#undef gdk_x11_cursor_get_xcursor +extern __typeof (gdk_x11_cursor_get_xcursor) gdk_x11_cursor_get_xcursor __attribute((alias("IA__gdk_x11_cursor_get_xcursor"), visibility("default"))); + +#undef gdk_x11_cursor_get_xdisplay +extern __typeof (gdk_x11_cursor_get_xdisplay) gdk_x11_cursor_get_xdisplay __attribute((alias("IA__gdk_x11_cursor_get_xdisplay"), visibility("default"))); + +#undef gdk_x11_display_set_cursor_theme +extern __typeof (gdk_x11_display_set_cursor_theme) gdk_x11_display_set_cursor_theme __attribute((alias("IA__gdk_x11_display_set_cursor_theme"), visibility("default"))); + +#endif +#if IN_FILE(__GDK_DISPLAY_X11_C__) +#undef gdk_x11_display_get_user_time +extern __typeof (gdk_x11_display_get_user_time) gdk_x11_display_get_user_time __attribute((alias("IA__gdk_x11_display_get_user_time"), visibility("default"))); + +#undef gdk_x11_display_get_xdisplay +extern __typeof (gdk_x11_display_get_xdisplay) gdk_x11_display_get_xdisplay __attribute((alias("IA__gdk_x11_display_get_xdisplay"), visibility("default"))); + +#undef gdk_x11_display_grab +extern __typeof (gdk_x11_display_grab) gdk_x11_display_grab __attribute((alias("IA__gdk_x11_display_grab"), visibility("default"))); + +#undef gdk_x11_display_ungrab +extern __typeof (gdk_x11_display_ungrab) gdk_x11_display_ungrab __attribute((alias("IA__gdk_x11_display_ungrab"), visibility("default"))); + +#undef gdk_x11_lookup_xdisplay +extern __typeof (gdk_x11_lookup_xdisplay) gdk_x11_lookup_xdisplay __attribute((alias("IA__gdk_x11_lookup_xdisplay"), visibility("default"))); + +#undef gdk_x11_display_broadcast_startup_message +extern __typeof (gdk_x11_display_broadcast_startup_message) gdk_x11_display_broadcast_startup_message __attribute((alias("IA__gdk_x11_display_broadcast_startup_message"), visibility("default"))); + +#undef gdk_x11_display_get_startup_notification_id +extern __typeof (gdk_x11_display_get_startup_notification_id) gdk_x11_display_get_startup_notification_id __attribute((alias("IA__gdk_x11_display_get_startup_notification_id"), visibility("default"))); + +#endif +#if IN_FILE(__GDK_DRAWABLE_X11_C__) +#undef gdk_x11_drawable_get_xdisplay +extern __typeof (gdk_x11_drawable_get_xdisplay) gdk_x11_drawable_get_xdisplay __attribute((alias("IA__gdk_x11_drawable_get_xdisplay"), visibility("default"))); + +#undef gdk_x11_drawable_get_xid +extern __typeof (gdk_x11_drawable_get_xid) gdk_x11_drawable_get_xid __attribute((alias("IA__gdk_x11_drawable_get_xid"), visibility("default"))); + +#undef gdk_x11_window_get_drawable_impl +extern __typeof (gdk_x11_window_get_drawable_impl) gdk_x11_window_get_drawable_impl __attribute((alias("IA__gdk_x11_window_get_drawable_impl"), visibility("default"))); + +#undef gdk_x11_pixmap_get_drawable_impl +extern __typeof (gdk_x11_pixmap_get_drawable_impl) gdk_x11_pixmap_get_drawable_impl __attribute((alias("IA__gdk_x11_pixmap_get_drawable_impl"), visibility("default"))); + +#endif +#if IN_FILE(__GDK_FONT_X11_C__) +#ifndef GDK_DISABLE_DEPRECATED +#undef gdk_x11_font_get_name +extern __typeof (gdk_x11_font_get_name) gdk_x11_font_get_name __attribute((alias("IA__gdk_x11_font_get_name"), visibility("default"))); + +#undef gdk_x11_font_get_xdisplay +extern __typeof (gdk_x11_font_get_xdisplay) gdk_x11_font_get_xdisplay __attribute((alias("IA__gdk_x11_font_get_xdisplay"), visibility("default"))); + +#endif +#undef gdk_x11_font_get_xfont +extern __typeof (gdk_x11_font_get_xfont) gdk_x11_font_get_xfont __attribute((alias("IA__gdk_x11_font_get_xfont"), visibility("default"))); + +#endif +#if IN_FILE(__GDK_GC_X11_C__) +#undef gdk_x11_gc_get_xdisplay +extern __typeof (gdk_x11_gc_get_xdisplay) gdk_x11_gc_get_xdisplay __attribute((alias("IA__gdk_x11_gc_get_xdisplay"), visibility("default"))); + +#undef gdk_x11_gc_get_xgc +extern __typeof (gdk_x11_gc_get_xgc) gdk_x11_gc_get_xgc __attribute((alias("IA__gdk_x11_gc_get_xgc"), visibility("default"))); + +#endif +#if IN_FILE(__GDK_MAIN_X11_C__) +#undef gdk_x11_get_default_root_xwindow +extern __typeof (gdk_x11_get_default_root_xwindow) gdk_x11_get_default_root_xwindow __attribute((alias("IA__gdk_x11_get_default_root_xwindow"), visibility("default"))); + +#undef gdk_x11_get_default_screen +extern __typeof (gdk_x11_get_default_screen) gdk_x11_get_default_screen __attribute((alias("IA__gdk_x11_get_default_screen"), visibility("default"))); + +#undef gdk_x11_get_default_xdisplay +extern __typeof (gdk_x11_get_default_xdisplay) gdk_x11_get_default_xdisplay __attribute((alias("IA__gdk_x11_get_default_xdisplay"), visibility("default"))); + +#undef gdk_x11_grab_server +extern __typeof (gdk_x11_grab_server) gdk_x11_grab_server __attribute((alias("IA__gdk_x11_grab_server"), visibility("default"))); + +#undef gdk_x11_ungrab_server +extern __typeof (gdk_x11_ungrab_server) gdk_x11_ungrab_server __attribute((alias("IA__gdk_x11_ungrab_server"), visibility("default"))); + +#undef gdk_x11_set_sm_client_id +extern __typeof (gdk_x11_set_sm_client_id) gdk_x11_set_sm_client_id __attribute((alias("IA__gdk_x11_set_sm_client_id"), visibility("default"))); + +#endif +#if IN_FILE(__GDK_EVENTS_X11_C__) +#undef gdk_x11_get_server_time +extern __typeof (gdk_x11_get_server_time) gdk_x11_get_server_time __attribute((alias("IA__gdk_x11_get_server_time"), visibility("default"))); + +#undef gdk_x11_register_standard_event_type +extern __typeof (gdk_x11_register_standard_event_type) gdk_x11_register_standard_event_type __attribute((alias("IA__gdk_x11_register_standard_event_type"), visibility("default"))); + +#undef gdk_x11_screen_get_window_manager_name +extern __typeof (gdk_x11_screen_get_window_manager_name) gdk_x11_screen_get_window_manager_name __attribute((alias("IA__gdk_x11_screen_get_window_manager_name"), visibility("default"))); + +#undef gdk_x11_screen_supports_net_wm_hint +extern __typeof (gdk_x11_screen_supports_net_wm_hint) gdk_x11_screen_supports_net_wm_hint __attribute((alias("IA__gdk_x11_screen_supports_net_wm_hint"), visibility("default"))); + +#endif +#if IN_FILE(__GDK_IMAGE_X11_C__) +#undef gdk_x11_image_get_xdisplay +extern __typeof (gdk_x11_image_get_xdisplay) gdk_x11_image_get_xdisplay __attribute((alias("IA__gdk_x11_image_get_xdisplay"), visibility("default"))); + +#undef gdk_x11_image_get_ximage +extern __typeof (gdk_x11_image_get_ximage) gdk_x11_image_get_ximage __attribute((alias("IA__gdk_x11_image_get_ximage"), visibility("default"))); + +#endif +#if IN_FILE(__GDK_SCREEN_X11_C__) +#undef gdk_x11_screen_get_screen_number +extern __typeof (gdk_x11_screen_get_screen_number) gdk_x11_screen_get_screen_number __attribute((alias("IA__gdk_x11_screen_get_screen_number"), visibility("default"))); + +#undef gdk_x11_screen_get_xscreen +extern __typeof (gdk_x11_screen_get_xscreen) gdk_x11_screen_get_xscreen __attribute((alias("IA__gdk_x11_screen_get_xscreen"), visibility("default"))); + +#undef gdk_x11_screen_get_monitor_output +extern __typeof (gdk_x11_screen_get_monitor_output) gdk_x11_screen_get_monitor_output __attribute((alias("IA__gdk_x11_screen_get_monitor_output"), visibility("default"))); + +#endif +#if IN_FILE(__GDK_VISUAL_X11_C__) +#undef gdk_x11_screen_lookup_visual +extern __typeof (gdk_x11_screen_lookup_visual) gdk_x11_screen_lookup_visual __attribute((alias("IA__gdk_x11_screen_lookup_visual"), visibility("default"))); + +#undef gdk_x11_visual_get_xvisual +extern __typeof (gdk_x11_visual_get_xvisual) gdk_x11_visual_get_xvisual __attribute((alias("IA__gdk_x11_visual_get_xvisual"), visibility("default"))); + +#ifndef GDK_DISABLE_DEPRECATED +#undef gdkx_visual_get +extern __typeof (gdkx_visual_get) gdkx_visual_get __attribute((alias("IA__gdkx_visual_get"), visibility("default"))); + +#endif +#endif +#if IN_FILE(__GDK_WINDOW_X11_C__) +#undef gdk_x11_window_set_user_time +extern __typeof (gdk_x11_window_set_user_time) gdk_x11_window_set_user_time __attribute((alias("IA__gdk_x11_window_set_user_time"), visibility("default"))); + +#undef gdk_x11_window_move_to_current_desktop +extern __typeof (gdk_x11_window_move_to_current_desktop) gdk_x11_window_move_to_current_desktop __attribute((alias("IA__gdk_x11_window_move_to_current_desktop"), visibility("default"))); + +#undef gdk_x11_window_foreign_new_for_display +extern __typeof (gdk_x11_window_foreign_new_for_display) gdk_x11_window_foreign_new_for_display __attribute((alias("IA__gdk_x11_window_foreign_new_for_display"), visibility("default"))); + +#undef gdk_x11_window_lookup_for_display +extern __typeof (gdk_x11_window_lookup_for_display) gdk_x11_window_lookup_for_display __attribute((alias("IA__gdk_x11_window_lookup_for_display"), visibility("default"))); + +#endif +#if IN_FILE(__GDK_XID_C__) +#undef gdk_xid_table_lookup +extern __typeof (gdk_xid_table_lookup) gdk_xid_table_lookup __attribute((alias("IA__gdk_xid_table_lookup"), visibility("default"))); + +#undef gdk_xid_table_lookup_for_display +extern __typeof (gdk_xid_table_lookup_for_display) gdk_xid_table_lookup_for_display __attribute((alias("IA__gdk_xid_table_lookup_for_display"), visibility("default"))); + +#endif +#endif +#endif +#if IN_HEADER(__GDK_APP_LAUNCH_CONTEXT_H__) +#if IN_FILE(__GDK_APP_LAUNCH_CONTEXT_C__) +#undef gdk_app_launch_context_get_type +extern __typeof (gdk_app_launch_context_get_type) gdk_app_launch_context_get_type __attribute((alias("IA__gdk_app_launch_context_get_type"), visibility("default"))); + +#undef gdk_app_launch_context_new +extern __typeof (gdk_app_launch_context_new) gdk_app_launch_context_new __attribute((alias("IA__gdk_app_launch_context_new"), visibility("default"))); + +#undef gdk_app_launch_context_set_display +extern __typeof (gdk_app_launch_context_set_display) gdk_app_launch_context_set_display __attribute((alias("IA__gdk_app_launch_context_set_display"), visibility("default"))); + +#undef gdk_app_launch_context_set_screen +extern __typeof (gdk_app_launch_context_set_screen) gdk_app_launch_context_set_screen __attribute((alias("IA__gdk_app_launch_context_set_screen"), visibility("default"))); + +#undef gdk_app_launch_context_set_desktop +extern __typeof (gdk_app_launch_context_set_desktop) gdk_app_launch_context_set_desktop __attribute((alias("IA__gdk_app_launch_context_set_desktop"), visibility("default"))); + +#undef gdk_app_launch_context_set_timestamp +extern __typeof (gdk_app_launch_context_set_timestamp) gdk_app_launch_context_set_timestamp __attribute((alias("IA__gdk_app_launch_context_set_timestamp"), visibility("default"))); + +#undef gdk_app_launch_context_set_icon +extern __typeof (gdk_app_launch_context_set_icon) gdk_app_launch_context_set_icon __attribute((alias("IA__gdk_app_launch_context_set_icon"), visibility("default"))); + +#undef gdk_app_launch_context_set_icon_name +extern __typeof (gdk_app_launch_context_set_icon_name) gdk_app_launch_context_set_icon_name __attribute((alias("IA__gdk_app_launch_context_set_icon_name"), visibility("default"))); + +#endif +#endif +#if IN_HEADER(__GDK_WINDOW_IMPL_H__) +#if IN_FILE(__GDK_WINDOW_IMPL_C__) +#undef gdk_window_impl_get_type +extern __typeof (gdk_window_impl_get_type) gdk_window_impl_get_type __attribute((alias("IA__gdk_window_impl_get_type"), visibility("default"))); + +#endif +#endif +#ifdef GDK_WINDOWING_X11 +#endif + +#endif /* G_HAVE_GNUC_VISIBILITY */ +#endif /* DISABLE_VISIBILITY */ diff --git a/libs/tk/ydk/gdkapplaunchcontext.c b/libs/tk/ydk/gdkapplaunchcontext.c new file mode 100644 index 0000000000..1653e97527 --- /dev/null +++ b/libs/tk/ydk/gdkapplaunchcontext.c @@ -0,0 +1,292 @@ +/* gdkapplaunchcontext.c - Gtk+ implementation for GAppLaunchContext + + Copyright (C) 2007 Red Hat, Inc. + + The Gnome 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 Gnome 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 Gnome 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: Alexander Larsson +*/ + +#include "config.h" + +#include "gdkapplaunchcontext.h" +#include "gdkinternals.h" +#include "gdkscreen.h" +#include "gdkintl.h" +#include "gdkalias.h" + + +static void gdk_app_launch_context_finalize (GObject *object); +static gchar * gdk_app_launch_context_get_display (GAppLaunchContext *context, + GAppInfo *info, + GList *files); + + +G_DEFINE_TYPE (GdkAppLaunchContext, gdk_app_launch_context, + G_TYPE_APP_LAUNCH_CONTEXT) + +static void +gdk_app_launch_context_class_init (GdkAppLaunchContextClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GAppLaunchContextClass *context_class = G_APP_LAUNCH_CONTEXT_CLASS (klass); + + gobject_class->finalize = gdk_app_launch_context_finalize; + + context_class->get_display = gdk_app_launch_context_get_display; + context_class->get_startup_notify_id = _gdk_windowing_get_startup_notify_id; + context_class->launch_failed = _gdk_windowing_launch_failed; + + g_type_class_add_private (klass, sizeof (GdkAppLaunchContextPrivate)); +} + +static void +gdk_app_launch_context_init (GdkAppLaunchContext *context) +{ + context->priv = G_TYPE_INSTANCE_GET_PRIVATE (context, + GDK_TYPE_APP_LAUNCH_CONTEXT, + GdkAppLaunchContextPrivate); + context->priv->workspace = -1; +} + +static void +gdk_app_launch_context_finalize (GObject *object) +{ + GdkAppLaunchContext *context; + GdkAppLaunchContextPrivate *priv; + + context = GDK_APP_LAUNCH_CONTEXT (object); + + priv = context->priv; + + if (priv->display) + g_object_unref (priv->display); + + if (priv->screen) + g_object_unref (priv->screen); + + if (priv->icon) + g_object_unref (priv->icon); + + g_free (priv->icon_name); + + G_OBJECT_CLASS (gdk_app_launch_context_parent_class)->finalize (object); +} + +static gchar * +gdk_app_launch_context_get_display (GAppLaunchContext *context, + GAppInfo *info, + GList *files) +{ + GdkDisplay *display; + GdkAppLaunchContextPrivate *priv; + + priv = GDK_APP_LAUNCH_CONTEXT (context)->priv; + + if (priv->screen) + return gdk_screen_make_display_name (priv->screen); + + if (priv->display) + display = priv->display; + else + display = gdk_display_get_default (); + + return g_strdup (gdk_display_get_name (display)); +} + +/** + * gdk_app_launch_context_set_display: + * @context: a #GdkAppLaunchContext + * @display: a #GdkDisplay + * + * Sets the display on which applications will be launched when + * using this context. See also gdk_app_launch_context_set_screen(). + * + * Since: 2.14 + */ +void +gdk_app_launch_context_set_display (GdkAppLaunchContext *context, + GdkDisplay *display) +{ + g_return_if_fail (GDK_IS_APP_LAUNCH_CONTEXT (context)); + g_return_if_fail (display == NULL || GDK_IS_DISPLAY (display)); + + if (context->priv->display) + { + g_object_unref (context->priv->display); + context->priv->display = NULL; + } + + if (display) + context->priv->display = g_object_ref (display); +} + +/** + * gdk_app_launch_context_set_screen: + * @context: a #GdkAppLaunchContext + * @screen: a #GdkScreen + * + * Sets the screen on which applications will be launched when + * using this context. See also gdk_app_launch_context_set_display(). + * + * If both @screen and @display are set, the @screen takes priority. + * If neither @screen or @display are set, the default screen and + * display are used. + * + * Since: 2.14 + */ +void +gdk_app_launch_context_set_screen (GdkAppLaunchContext *context, + GdkScreen *screen) +{ + g_return_if_fail (GDK_IS_APP_LAUNCH_CONTEXT (context)); + g_return_if_fail (screen == NULL || GDK_IS_SCREEN (screen)); + + if (context->priv->screen) + { + g_object_unref (context->priv->screen); + context->priv->screen = NULL; + } + + if (screen) + context->priv->screen = g_object_ref (screen); +} + +/** + * gdk_app_launch_context_set_desktop: + * @context: a #GdkAppLaunchContext + * @desktop: the number of a workspace, or -1 + * + * Sets the workspace on which applications will be launched when + * using this context when running under a window manager that + * supports multiple workspaces, as described in the + * Extended + * Window Manager Hints. + * + * When the workspace is not specified or @desktop is set to -1, + * it is up to the window manager to pick one, typically it will + * be the current workspace. + * + * Since: 2.14 + */ +void +gdk_app_launch_context_set_desktop (GdkAppLaunchContext *context, + gint desktop) +{ + g_return_if_fail (GDK_IS_APP_LAUNCH_CONTEXT (context)); + + context->priv->workspace = desktop; +} + +/** + * gdk_app_launch_context_set_timestamp: + * @context: a #GdkAppLaunchContext + * @timestamp: a timestamp + * + * Sets the timestamp of @context. The timestamp should ideally + * be taken from the event that triggered the launch. + * + * Window managers can use this information to avoid moving the + * focus to the newly launched application when the user is busy + * typing in another window. This is also known as 'focus stealing + * prevention'. + * + * Since: 2.14 + */ +void +gdk_app_launch_context_set_timestamp (GdkAppLaunchContext *context, + guint32 timestamp) +{ + g_return_if_fail (GDK_IS_APP_LAUNCH_CONTEXT (context)); + + context->priv->timestamp = timestamp; +} + +/** + * gdk_app_launch_context_set_icon: + * @context: a #GdkAppLaunchContext + * @icon: (allow-none): a #GIcon, or %NULL + * + * Sets the icon for applications that are launched with this + * context. + * + * Window Managers can use this information when displaying startup + * notification. + * + * See also gdk_app_launch_context_set_icon_name(). + * + * Since: 2.14 + */ +void +gdk_app_launch_context_set_icon (GdkAppLaunchContext *context, + GIcon *icon) +{ + g_return_if_fail (GDK_IS_APP_LAUNCH_CONTEXT (context)); + g_return_if_fail (icon == NULL || G_IS_ICON (icon)); + + if (context->priv->icon) + { + g_object_unref (context->priv->icon); + context->priv->icon = NULL; + } + + if (icon) + context->priv->icon = g_object_ref (icon); +} + +/** + * gdk_app_launch_context_set_icon_name: + * @context: a #GdkAppLaunchContext + * @icon_name: (allow-none): an icon name, or %NULL + * + * Sets the icon for applications that are launched with this context. + * The @icon_name will be interpreted in the same way as the Icon field + * in desktop files. See also gdk_app_launch_context_set_icon(). + * + * If both @icon and @icon_name are set, the @icon_name takes priority. + * If neither @icon or @icon_name is set, the icon is taken from either + * the file that is passed to launched application or from the #GAppInfo + * for the launched application itself. + * + * Since: 2.14 + */ +void +gdk_app_launch_context_set_icon_name (GdkAppLaunchContext *context, + const char *icon_name) +{ + g_return_if_fail (GDK_IS_APP_LAUNCH_CONTEXT (context)); + + g_free (context->priv->icon_name); + context->priv->icon_name = g_strdup (icon_name); +} + +/** + * gdk_app_launch_context_new: + * + * Creates a new #GdkAppLaunchContext. + * + * Returns: a new #GdkAppLaunchContext + * + * Since: 2.14 + */ +GdkAppLaunchContext * +gdk_app_launch_context_new (void) +{ + return g_object_new (GDK_TYPE_APP_LAUNCH_CONTEXT, NULL); +} + +#define __GDK_APP_LAUNCH_CONTEXT_C__ +#include "gdkaliasdef.c" diff --git a/libs/tk/ydk/gdkcairo.c b/libs/tk/ydk/gdkcairo.c new file mode 100644 index 0000000000..3fdb570c69 --- /dev/null +++ b/libs/tk/ydk/gdkcairo.c @@ -0,0 +1,353 @@ +/* GDK - The GIMP Drawing Kit + * Copyright (C) 2005 Red Hat, 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. + */ + +#include "gdkcairo.h" +#include "gdkdrawable.h" +#include "gdkinternals.h" +#include "gdkregion-generic.h" +#include "gdkalias.h" + +static void +gdk_ensure_surface_flush (gpointer surface) +{ + cairo_surface_flush (surface); + cairo_surface_destroy (surface); +} + +/** + * gdk_cairo_create: + * @drawable: a #GdkDrawable + * + * Creates a Cairo context for drawing to @drawable. + * + * + * Note that due to double-buffering, Cairo contexts created + * in a GTK+ expose event handler cannot be cached and reused + * between different expose events. + * + * + * Return value: A newly created Cairo context. Free with + * cairo_destroy() when you are done drawing. + * + * Since: 2.8 + **/ +cairo_t * +gdk_cairo_create (GdkDrawable *drawable) +{ + static const cairo_user_data_key_t key; + cairo_surface_t *surface; + cairo_t *cr; + + g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL); + + surface = _gdk_drawable_ref_cairo_surface (drawable); + cr = cairo_create (surface); + + if (GDK_DRAWABLE_GET_CLASS (drawable)->set_cairo_clip) + GDK_DRAWABLE_GET_CLASS (drawable)->set_cairo_clip (drawable, cr); + + /* Ugly workaround for GTK not ensuring to flush surfaces before + * directly accessing the drawable backed by the surface. Not visible + * on X11 (where flushing is a no-op). For details, see + * https://bugzilla.gnome.org/show_bug.cgi?id=628291 + */ + cairo_set_user_data (cr, &key, surface, gdk_ensure_surface_flush); + + return cr; +} + +/** + * gdk_cairo_reset_clip: + * @cr: a #cairo_t + * @drawable: a #GdkDrawable + * + * Resets the clip region for a Cairo context created by gdk_cairo_create(). + * + * This resets the clip region to the "empty" state for the given drawable. + * This is required for non-native windows since a direct call to + * cairo_reset_clip() would unset the clip region inherited from the + * drawable (i.e. the window clip region), and thus let you e.g. + * draw outside your window. + * + * This is rarely needed though, since most code just create a new cairo_t + * using gdk_cairo_create() each time they want to draw something. + * + * Since: 2.18 + **/ +void +gdk_cairo_reset_clip (cairo_t *cr, + GdkDrawable *drawable) +{ + cairo_reset_clip (cr); + + if (GDK_DRAWABLE_GET_CLASS (drawable)->set_cairo_clip) + GDK_DRAWABLE_GET_CLASS (drawable)->set_cairo_clip (drawable, cr); +} + +/** + * gdk_cairo_set_source_color: + * @cr: a #cairo_t + * @color: a #GdkColor + * + * Sets the specified #GdkColor as the source color of @cr. + * + * Since: 2.8 + **/ +void +gdk_cairo_set_source_color (cairo_t *cr, + const GdkColor *color) +{ + g_return_if_fail (cr != NULL); + g_return_if_fail (color != NULL); + + cairo_set_source_rgb (cr, + color->red / 65535., + color->green / 65535., + color->blue / 65535.); +} + +/** + * gdk_cairo_rectangle: + * @cr: a #cairo_t + * @rectangle: a #GdkRectangle + * + * Adds the given rectangle to the current path of @cr. + * + * Since: 2.8 + **/ +void +gdk_cairo_rectangle (cairo_t *cr, + const GdkRectangle *rectangle) +{ + g_return_if_fail (cr != NULL); + g_return_if_fail (rectangle != NULL); + + cairo_rectangle (cr, + rectangle->x, rectangle->y, + rectangle->width, rectangle->height); +} + +/** + * gdk_cairo_region: + * @cr: a #cairo_t + * @region: a #GdkRegion + * + * Adds the given region to the current path of @cr. + * + * Since: 2.8 + **/ +void +gdk_cairo_region (cairo_t *cr, + const GdkRegion *region) +{ + GdkRegionBox *boxes; + gint n_boxes, i; + + g_return_if_fail (cr != NULL); + g_return_if_fail (region != NULL); + + boxes = region->rects; + n_boxes = region->numRects; + + for (i = 0; i < n_boxes; i++) + cairo_rectangle (cr, + boxes[i].x1, + boxes[i].y1, + boxes[i].x2 - boxes[i].x1, + boxes[i].y2 - boxes[i].y1); +} + +/** + * gdk_cairo_set_source_pixbuf: + * @cr: a #Cairo context + * @pixbuf: a #GdkPixbuf + * @pixbuf_x: X coordinate of location to place upper left corner of @pixbuf + * @pixbuf_y: Y coordinate of location to place upper left corner of @pixbuf + * + * Sets the given pixbuf as the source pattern for the Cairo context. + * The pattern has an extend mode of %CAIRO_EXTEND_NONE and is aligned + * so that the origin of @pixbuf is @pixbuf_x, @pixbuf_y + * + * Since: 2.8 + **/ +void +gdk_cairo_set_source_pixbuf (cairo_t *cr, + const GdkPixbuf *pixbuf, + double pixbuf_x, + double pixbuf_y) +{ + gint width = gdk_pixbuf_get_width (pixbuf); + gint height = gdk_pixbuf_get_height (pixbuf); + guchar *gdk_pixels = gdk_pixbuf_get_pixels (pixbuf); + int gdk_rowstride = gdk_pixbuf_get_rowstride (pixbuf); + int n_channels = gdk_pixbuf_get_n_channels (pixbuf); + int cairo_stride; + guchar *cairo_pixels; + cairo_format_t format; + cairo_surface_t *surface; + static const cairo_user_data_key_t key; + cairo_status_t status; + int j; + + if (n_channels == 3) + format = CAIRO_FORMAT_RGB24; + else + format = CAIRO_FORMAT_ARGB32; + + cairo_stride = cairo_format_stride_for_width (format, width); + cairo_pixels = g_malloc_n (height, cairo_stride); + surface = cairo_image_surface_create_for_data ((unsigned char *)cairo_pixels, + format, + width, height, cairo_stride); + + status = cairo_surface_set_user_data (surface, &key, + cairo_pixels, (cairo_destroy_func_t)g_free); + if (status != CAIRO_STATUS_SUCCESS) + { + g_free (cairo_pixels); + goto out; + } + + for (j = height; j; j--) + { + guchar *p = gdk_pixels; + guchar *q = cairo_pixels; + + if (n_channels == 3) + { + guchar *end = p + 3 * width; + + while (p < end) + { +#if G_BYTE_ORDER == G_LITTLE_ENDIAN + q[0] = p[2]; + q[1] = p[1]; + q[2] = p[0]; +#else + q[1] = p[0]; + q[2] = p[1]; + q[3] = p[2]; +#endif + p += 3; + q += 4; + } + } + else + { + guchar *end = p + 4 * width; + guint t1,t2,t3; + +#define MULT(d,c,a,t) G_STMT_START { t = c * a + 0x80; d = ((t >> 8) + t) >> 8; } G_STMT_END + + while (p < end) + { +#if G_BYTE_ORDER == G_LITTLE_ENDIAN + MULT(q[0], p[2], p[3], t1); + MULT(q[1], p[1], p[3], t2); + MULT(q[2], p[0], p[3], t3); + q[3] = p[3]; +#else + q[0] = p[3]; + MULT(q[1], p[0], p[3], t1); + MULT(q[2], p[1], p[3], t2); + MULT(q[3], p[2], p[3], t3); +#endif + + p += 4; + q += 4; + } + +#undef MULT + } + + gdk_pixels += gdk_rowstride; + cairo_pixels += cairo_stride; + } + +out: + cairo_set_source_surface (cr, surface, pixbuf_x, pixbuf_y); + cairo_surface_destroy (surface); +} + +/** + * gdk_cairo_set_source_pixmap: + * @cr: a #Cairo context + * @pixmap: a #GdkPixmap + * @pixmap_x: X coordinate of location to place upper left corner of @pixmap + * @pixmap_y: Y coordinate of location to place upper left corner of @pixmap + * + * Sets the given pixmap as the source pattern for the Cairo context. + * The pattern has an extend mode of %CAIRO_EXTEND_NONE and is aligned + * so that the origin of @pixmap is @pixmap_x, @pixmap_y + * + * Since: 2.10 + * + * Deprecated: 2.24: This function is being removed in GTK+ 3 (together + * with #GdkPixmap). Instead, use gdk_cairo_set_source_window() where + * appropriate. + **/ +void +gdk_cairo_set_source_pixmap (cairo_t *cr, + GdkPixmap *pixmap, + double pixmap_x, + double pixmap_y) +{ + cairo_surface_t *surface; + + surface = _gdk_drawable_ref_cairo_surface (GDK_DRAWABLE (pixmap)); + cairo_set_source_surface (cr, surface, pixmap_x, pixmap_y); + cairo_surface_destroy (surface); +} + +/** + * gdk_cairo_set_source_window: + * @cr: a #Cairo context + * @window: a #GdkWindow + * @x: X coordinate of location to place upper left corner of @window + * @y: Y coordinate of location to place upper left corner of @window + * + * Sets the given window as the source pattern for the Cairo context. + * The pattern has an extend mode of %CAIRO_EXTEND_NONE and is aligned + * so that the origin of @window is @x, @y. The window contains all its + * subwindows when rendering. + * + * Note that the contents of @window are undefined outside of the + * visible part of @window, so use this function with care. + * + * Since: 2.24 + **/ +void +gdk_cairo_set_source_window (cairo_t *cr, + GdkWindow *window, + double x, + double y) +{ + cairo_surface_t *surface; + + g_return_if_fail (cr != NULL); + g_return_if_fail (GDK_IS_WINDOW (window)); + + surface = _gdk_drawable_ref_cairo_surface (GDK_DRAWABLE (window)); + cairo_set_source_surface (cr, surface, x, y); + cairo_surface_destroy (surface); +} + + +#define __GDK_CAIRO_C__ +#include "gdkaliasdef.c" diff --git a/libs/tk/ydk/gdkcolor.c b/libs/tk/ydk/gdkcolor.c new file mode 100644 index 0000000000..b718038d27 --- /dev/null +++ b/libs/tk/ydk/gdkcolor.c @@ -0,0 +1,398 @@ +/* GDK - The GIMP Drawing Kit + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, 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 "config.h" +#include + +#include "gdkscreen.h" +#include "gdkcolor.h" +#include "gdkinternals.h" +#include "gdkalias.h" + +/** + * gdk_colormap_ref: + * @cmap: a #GdkColormap + * + * Deprecated function; use g_object_ref() instead. + * + * Return value: the colormap + * + * Deprecated: 2.0: Use g_object_ref() instead. + **/ +GdkColormap* +gdk_colormap_ref (GdkColormap *cmap) +{ + return (GdkColormap *) g_object_ref (cmap); +} + +/** + * gdk_colormap_unref: + * @cmap: a #GdkColormap + * + * Deprecated function; use g_object_unref() instead. + * + * Deprecated: 2.0: Use g_object_unref() instead. + **/ +void +gdk_colormap_unref (GdkColormap *cmap) +{ + g_object_unref (cmap); +} + + +/** + * gdk_colormap_get_visual: + * @colormap: a #GdkColormap. + * + * Returns the visual for which a given colormap was created. + * + * Return value: the visual of the colormap. + **/ +GdkVisual * +gdk_colormap_get_visual (GdkColormap *colormap) +{ + g_return_val_if_fail (GDK_IS_COLORMAP (colormap), NULL); + + return colormap->visual; +} + +/** + * gdk_colors_store: + * @colormap: a #GdkColormap. + * @colors: the new color values. + * @ncolors: the number of colors to change. + * + * Changes the value of the first @ncolors colors in + * a private colormap. This function is obsolete and + * should not be used. See gdk_color_change(). + **/ +void +gdk_colors_store (GdkColormap *colormap, + GdkColor *colors, + gint ncolors) +{ + gint i; + + for (i = 0; i < ncolors; i++) + { + colormap->colors[i].pixel = colors[i].pixel; + colormap->colors[i].red = colors[i].red; + colormap->colors[i].green = colors[i].green; + colormap->colors[i].blue = colors[i].blue; + } + + gdk_colormap_change (colormap, ncolors); +} + +/** + * gdk_color_copy: + * @color: a #GdkColor. + * + * Makes a copy of a color structure. The result + * must be freed using gdk_color_free(). + * + * Return value: a copy of @color. + **/ +GdkColor* +gdk_color_copy (const GdkColor *color) +{ + GdkColor *new_color; + + g_return_val_if_fail (color != NULL, NULL); + + new_color = g_slice_new (GdkColor); + *new_color = *color; + return new_color; +} + +/** + * gdk_color_free: + * @color: a #GdkColor. + * + * Frees a color structure created with + * gdk_color_copy(). + **/ +void +gdk_color_free (GdkColor *color) +{ + g_return_if_fail (color != NULL); + + g_slice_free (GdkColor, color); +} + +/** + * gdk_color_white: + * @colormap: a #GdkColormap. + * @color: the location to store the color. + * + * Returns the white color for a given colormap. The resulting + * value has already allocated been allocated. + * + * Return value: %TRUE if the allocation succeeded. + **/ +gboolean +gdk_color_white (GdkColormap *colormap, + GdkColor *color) +{ + gint return_val; + + g_return_val_if_fail (colormap != NULL, FALSE); + + if (color) + { + color->red = 65535; + color->green = 65535; + color->blue = 65535; + + return_val = gdk_colormap_alloc_color (colormap, color, FALSE, TRUE); + } + else + return_val = FALSE; + + return return_val; +} + +/** + * gdk_color_black: + * @colormap: a #GdkColormap. + * @color: the location to store the color. + * + * Returns the black color for a given colormap. The resulting + * value has already been allocated. + * + * Return value: %TRUE if the allocation succeeded. + **/ +gboolean +gdk_color_black (GdkColormap *colormap, + GdkColor *color) +{ + gint return_val; + + g_return_val_if_fail (colormap != NULL, FALSE); + + if (color) + { + color->red = 0; + color->green = 0; + color->blue = 0; + + return_val = gdk_colormap_alloc_color (colormap, color, FALSE, TRUE); + } + else + return_val = FALSE; + + return return_val; +} + +/******************** + * Color allocation * + ********************/ + +/** + * gdk_colormap_alloc_color: + * @colormap: a #GdkColormap. + * @color: the color to allocate. On return the + * pixel field will be + * filled in if allocation succeeds. + * @writeable: If %TRUE, the color is allocated writeable + * (their values can later be changed using gdk_color_change()). + * Writeable colors cannot be shared between applications. + * @best_match: If %TRUE, GDK will attempt to do matching against + * existing colors if the color cannot be allocated as requested. + * + * Allocates a single color from a colormap. + * + * Return value: %TRUE if the allocation succeeded. + **/ +gboolean +gdk_colormap_alloc_color (GdkColormap *colormap, + GdkColor *color, + gboolean writeable, + gboolean best_match) +{ + gboolean success; + + gdk_colormap_alloc_colors (colormap, color, 1, writeable, best_match, + &success); + + return success; +} + +/** + * gdk_color_alloc: + * @colormap: a #GdkColormap. + * @color: The color to allocate. On return, the + * pixel field will be filled in. + * + * Allocates a single color from a colormap. + * + * Return value: %TRUE if the allocation succeeded. + * + * Deprecated: 2.2: Use gdk_colormap_alloc_color() instead. + **/ +gboolean +gdk_color_alloc (GdkColormap *colormap, + GdkColor *color) +{ + gboolean success; + + gdk_colormap_alloc_colors (colormap, color, 1, FALSE, TRUE, &success); + + return success; +} + +/** + * gdk_color_hash: + * @colora: a #GdkColor. + * + * A hash function suitable for using for a hash + * table that stores #GdkColor's. + * + * Return value: The hash function applied to @colora + **/ +guint +gdk_color_hash (const GdkColor *colora) +{ + return ((colora->red) + + (colora->green << 11) + + (colora->blue << 22) + + (colora->blue >> 6)); +} + +/** + * gdk_color_equal: + * @colora: a #GdkColor. + * @colorb: another #GdkColor. + * + * Compares two colors. + * + * Return value: %TRUE if the two colors compare equal + **/ +gboolean +gdk_color_equal (const GdkColor *colora, + const GdkColor *colorb) +{ + g_return_val_if_fail (colora != NULL, FALSE); + g_return_val_if_fail (colorb != NULL, FALSE); + + return ((colora->red == colorb->red) && + (colora->green == colorb->green) && + (colora->blue == colorb->blue)); +} + +GType +gdk_color_get_type (void) +{ + static GType our_type = 0; + + if (our_type == 0) + our_type = g_boxed_type_register_static (g_intern_static_string ("GdkColor"), + (GBoxedCopyFunc)gdk_color_copy, + (GBoxedFreeFunc)gdk_color_free); + return our_type; +} + +/** + * gdk_color_parse: + * @spec: the string specifying the color. + * @color: (out): the #GdkColor to fill in + * + * Parses a textual specification of a color and fill in the + * red, green, + * and blue fields of a #GdkColor + * structure. The color is not allocated, you + * must call gdk_colormap_alloc_color() yourself. The string can + * either one of a large set of standard names. (Taken from the X11 + * rgb.txt file), or it can be a hex value in the + * form '#rgb' '#rrggbb' '#rrrgggbbb' or + * '#rrrrggggbbbb' where 'r', 'g' and 'b' are hex digits of the + * red, green, and blue components of the color, respectively. (White + * in the four forms is '#fff' '#ffffff' '#fffffffff' and + * '#ffffffffffff') + * + * Return value: %TRUE if the parsing succeeded. + **/ +gboolean +gdk_color_parse (const gchar *spec, + GdkColor *color) +{ + PangoColor pango_color; + + if (pango_color_parse (&pango_color, spec)) + { + color->red = pango_color.red; + color->green = pango_color.green; + color->blue = pango_color.blue; + + return TRUE; + } + else + return FALSE; +} + +/** + * gdk_color_to_string: + * @color: a #GdkColor + * + * Returns a textual specification of @color in the hexadecimal form + * #rrrrggggbbbb, where r, + * g and b are hex digits + * representing the red, green and blue components respectively. + * + * Return value: a newly-allocated text string + * + * Since: 2.12 + **/ +gchar * +gdk_color_to_string (const GdkColor *color) +{ + PangoColor pango_color; + + g_return_val_if_fail (color != NULL, NULL); + + pango_color.red = color->red; + pango_color.green = color->green; + pango_color.blue = color->blue; + + return pango_color_to_string (&pango_color); +} + +/** + * gdk_colormap_get_system: + * + * Gets the system's default colormap for the default screen. (See + * gdk_colormap_get_system_for_screen ()) + * + * Return value: the default colormap. + **/ +GdkColormap* +gdk_colormap_get_system (void) +{ + return gdk_screen_get_system_colormap (gdk_screen_get_default ()); +} + +#define __GDK_COLOR_C__ +#include "gdkaliasdef.c" diff --git a/libs/tk/ydk/gdkcursor.c b/libs/tk/ydk/gdkcursor.c new file mode 100644 index 0000000000..906af1344c --- /dev/null +++ b/libs/tk/ydk/gdkcursor.c @@ -0,0 +1,119 @@ +/* GDK - The GIMP Drawing Kit + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, 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 "config.h" +#include "gdkcursor.h" +#include "gdkdisplay.h" +#include "gdkinternals.h" +#include "gdkalias.h" + +GType +gdk_cursor_get_type (void) +{ + static GType our_type = 0; + + if (our_type == 0) + our_type = g_boxed_type_register_static (g_intern_static_string ("GdkCursor"), + (GBoxedCopyFunc)gdk_cursor_ref, + (GBoxedFreeFunc)gdk_cursor_unref); + return our_type; +} + +/** + * gdk_cursor_ref: + * @cursor: a #GdkCursor + * + * Adds a reference to @cursor. + * + * Return value: (transfer full): Same @cursor that was passed in + **/ +GdkCursor* +gdk_cursor_ref (GdkCursor *cursor) +{ + g_return_val_if_fail (cursor != NULL, NULL); + g_return_val_if_fail (cursor->ref_count > 0, NULL); + + cursor->ref_count += 1; + + return cursor; +} + +/** + * gdk_cursor_unref: + * @cursor: a #GdkCursor + * + * Removes a reference from @cursor, deallocating the cursor + * if no references remain. + * + **/ +void +gdk_cursor_unref (GdkCursor *cursor) +{ + g_return_if_fail (cursor != NULL); + g_return_if_fail (cursor->ref_count > 0); + + cursor->ref_count -= 1; + + if (cursor->ref_count == 0) + _gdk_cursor_destroy (cursor); +} + +/** + * gdk_cursor_new: + * @cursor_type: cursor to create + * + * Creates a new cursor from the set of builtin cursors for the default display. + * See gdk_cursor_new_for_display(). + * + * To make the cursor invisible, use %GDK_BLANK_CURSOR. + * + * Return value: a new #GdkCursor + **/ +GdkCursor* +gdk_cursor_new (GdkCursorType cursor_type) +{ + return gdk_cursor_new_for_display (gdk_display_get_default(), cursor_type); +} + +/** + * gdk_cursor_get_cursor_type: + * @cursor: a #GdkCursor + * + * Returns the cursor type for this cursor. + * + * Return value: a #GdkCursorType + * + * Since: 2.22 + **/ +GdkCursorType +gdk_cursor_get_cursor_type (GdkCursor *cursor) +{ + g_return_val_if_fail (cursor != NULL, GDK_BLANK_CURSOR); + return cursor->type; +} + +#define __GDK_CURSOR_C__ +#include "gdkaliasdef.c" diff --git a/libs/tk/ydk/gdkdisplay.c b/libs/tk/ydk/gdkdisplay.c new file mode 100644 index 0000000000..f7b43cf874 --- /dev/null +++ b/libs/tk/ydk/gdkdisplay.c @@ -0,0 +1,1307 @@ +/* GDK - The GIMP Drawing Kit + * gdkdisplay.c + * + * Copyright 2001 Sun Microsystems Inc. + * + * Erwann Chenede + * + * 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 "gdk.h" /* gdk_event_send_client_message() */ +#include "gdkdisplay.h" +#include "gdkwindowimpl.h" +#include "gdkinternals.h" +#include "gdkmarshalers.h" +#include "gdkscreen.h" +#include "gdkalias.h" + +enum { + CLOSED, + LAST_SIGNAL +}; + +static void gdk_display_dispose (GObject *object); +static void gdk_display_finalize (GObject *object); + + +static void singlehead_get_pointer (GdkDisplay *display, + GdkScreen **screen, + gint *x, + gint *y, + GdkModifierType *mask); +static GdkWindow* singlehead_window_get_pointer (GdkDisplay *display, + GdkWindow *window, + gint *x, + gint *y, + GdkModifierType *mask); +static GdkWindow* singlehead_window_at_pointer (GdkDisplay *display, + gint *win_x, + gint *win_y); + +static GdkWindow* singlehead_default_window_get_pointer (GdkWindow *window, + gint *x, + gint *y, + GdkModifierType *mask); +static GdkWindow* singlehead_default_window_at_pointer (GdkScreen *screen, + gint *win_x, + gint *win_y); +static GdkWindow *gdk_window_real_window_get_pointer (GdkDisplay *display, + GdkWindow *window, + gint *x, + gint *y, + GdkModifierType *mask); +static GdkWindow *gdk_display_real_get_window_at_pointer (GdkDisplay *display, + gint *win_x, + gint *win_y); + +static guint signals[LAST_SIGNAL] = { 0 }; + +static char *gdk_sm_client_id; + +static const GdkDisplayPointerHooks default_pointer_hooks = { + _gdk_windowing_get_pointer, + gdk_window_real_window_get_pointer, + gdk_display_real_get_window_at_pointer +}; + +static const GdkDisplayPointerHooks singlehead_pointer_hooks = { + singlehead_get_pointer, + singlehead_window_get_pointer, + singlehead_window_at_pointer +}; + +static const GdkPointerHooks singlehead_default_pointer_hooks = { + singlehead_default_window_get_pointer, + singlehead_default_window_at_pointer +}; + +static const GdkPointerHooks *singlehead_current_pointer_hooks = &singlehead_default_pointer_hooks; + +G_DEFINE_TYPE (GdkDisplay, gdk_display, G_TYPE_OBJECT) + +static void +gdk_display_class_init (GdkDisplayClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + + object_class->finalize = gdk_display_finalize; + object_class->dispose = gdk_display_dispose; + + /** + * GdkDisplay::closed: + * @display: the object on which the signal is emitted + * @is_error: %TRUE if the display was closed due to an error + * + * The ::closed signal is emitted when the connection to the windowing + * system for @display is closed. + * + * Since: 2.2 + */ + signals[CLOSED] = + g_signal_new (g_intern_static_string ("closed"), + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GdkDisplayClass, closed), + NULL, NULL, + _gdk_marshal_VOID__BOOLEAN, + G_TYPE_NONE, + 1, + G_TYPE_BOOLEAN); +} + +static void +gdk_display_init (GdkDisplay *display) +{ + _gdk_displays = g_slist_prepend (_gdk_displays, display); + + display->button_click_time[0] = display->button_click_time[1] = 0; + display->button_window[0] = display->button_window[1] = NULL; + display->button_number[0] = display->button_number[1] = -1; + display->button_x[0] = display->button_x[1] = 0; + display->button_y[0] = display->button_y[1] = 0; + + display->double_click_time = 250; + display->double_click_distance = 5; + + display->pointer_hooks = &default_pointer_hooks; +} + +static void +gdk_display_dispose (GObject *object) +{ + GdkDisplay *display = GDK_DISPLAY_OBJECT (object); + + g_list_foreach (display->queued_events, (GFunc)gdk_event_free, NULL); + g_list_free (display->queued_events); + display->queued_events = NULL; + display->queued_tail = NULL; + + _gdk_displays = g_slist_remove (_gdk_displays, object); + + if (gdk_display_get_default() == display) + { + if (_gdk_displays) + gdk_display_manager_set_default_display (gdk_display_manager_get(), + _gdk_displays->data); + else + gdk_display_manager_set_default_display (gdk_display_manager_get(), + NULL); + } + + G_OBJECT_CLASS (gdk_display_parent_class)->dispose (object); +} + +static void +gdk_display_finalize (GObject *object) +{ + G_OBJECT_CLASS (gdk_display_parent_class)->finalize (object); +} + +/** + * gdk_display_close: + * @display: a #GdkDisplay + * + * Closes the connection to the windowing system for the given display, + * and cleans up associated resources. + * + * Since: 2.2 + */ +void +gdk_display_close (GdkDisplay *display) +{ + g_return_if_fail (GDK_IS_DISPLAY (display)); + + if (!display->closed) + { + display->closed = TRUE; + + g_signal_emit (display, signals[CLOSED], 0, FALSE); + g_object_run_dispose (G_OBJECT (display)); + + g_object_unref (display); + } +} + +/** + * gdk_display_is_closed: + * @display: a #GdkDisplay + * + * Finds out if the display has been closed. + * + * Returns: %TRUE if the display is closed. + * + * Since: 2.22 + */ +gboolean +gdk_display_is_closed (GdkDisplay *display) +{ + g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE); + + return display->closed; +} + +/** + * gdk_display_get_event: + * @display: a #GdkDisplay + * + * Gets the next #GdkEvent to be processed for @display, fetching events from the + * windowing system if necessary. + * + * Return value: the next #GdkEvent to be processed, or %NULL if no events + * are pending. The returned #GdkEvent should be freed with gdk_event_free(). + * + * Since: 2.2 + **/ +GdkEvent* +gdk_display_get_event (GdkDisplay *display) +{ + g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL); + + _gdk_events_queue (display); + return _gdk_event_unqueue (display); +} + +/** + * gdk_display_peek_event: + * @display: a #GdkDisplay + * + * Gets a copy of the first #GdkEvent in the @display's event queue, without + * removing the event from the queue. (Note that this function will + * not get more events from the windowing system. It only checks the events + * that have already been moved to the GDK event queue.) + * + * Return value: a copy of the first #GdkEvent on the event queue, or %NULL + * if no events are in the queue. The returned #GdkEvent should be freed with + * gdk_event_free(). + * + * Since: 2.2 + **/ +GdkEvent* +gdk_display_peek_event (GdkDisplay *display) +{ + GList *tmp_list; + + g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL); + + tmp_list = _gdk_event_queue_find_first (display); + + if (tmp_list) + return gdk_event_copy (tmp_list->data); + else + return NULL; +} + +/** + * gdk_display_put_event: + * @display: a #GdkDisplay + * @event: a #GdkEvent. + * + * Appends a copy of the given event onto the front of the event + * queue for @display. + * + * Since: 2.2 + **/ +void +gdk_display_put_event (GdkDisplay *display, + const GdkEvent *event) +{ + g_return_if_fail (GDK_IS_DISPLAY (display)); + g_return_if_fail (event != NULL); + + _gdk_event_queue_append (display, gdk_event_copy (event)); + /* If the main loop is blocking in a different thread, wake it up */ + g_main_context_wakeup (NULL); +} + +/** + * gdk_pointer_ungrab: + * @time_: a timestamp from a #GdkEvent, or %GDK_CURRENT_TIME if no + * timestamp is available. + * + * Ungrabs the pointer on the default display, if it is grabbed by this + * application. + **/ +void +gdk_pointer_ungrab (guint32 time) +{ + gdk_display_pointer_ungrab (gdk_display_get_default (), time); +} + +/** + * gdk_pointer_is_grabbed: + * + * Returns %TRUE if the pointer on the default display is currently + * grabbed by this application. + * + * Note that this does not take the inmplicit pointer grab on button + * presses into account. + + * Return value: %TRUE if the pointer is currently grabbed by this application.* + **/ +gboolean +gdk_pointer_is_grabbed (void) +{ + return gdk_display_pointer_is_grabbed (gdk_display_get_default ()); +} + +/** + * gdk_keyboard_ungrab: + * @time_: a timestamp from a #GdkEvent, or %GDK_CURRENT_TIME if no + * timestamp is available. + * + * Ungrabs the keyboard on the default display, if it is grabbed by this + * application. + **/ +void +gdk_keyboard_ungrab (guint32 time) +{ + gdk_display_keyboard_ungrab (gdk_display_get_default (), time); +} + +/** + * gdk_beep: + * + * Emits a short beep on the default display. + **/ +void +gdk_beep (void) +{ + gdk_display_beep (gdk_display_get_default ()); +} + +/** + * gdk_event_send_client_message: + * @event: the #GdkEvent to send, which should be a #GdkEventClient. + * @winid: the window to send the X ClientMessage event to. + * + * Sends an X ClientMessage event to a given window (which must be + * on the default #GdkDisplay.) + * This could be used for communicating between different applications, + * though the amount of data is limited to 20 bytes. + * + * Return value: non-zero on success. + **/ +gboolean +gdk_event_send_client_message (GdkEvent *event, + GdkNativeWindow winid) +{ + g_return_val_if_fail (event != NULL, FALSE); + + return gdk_event_send_client_message_for_display (gdk_display_get_default (), + event, winid); +} + +/** + * gdk_event_send_clientmessage_toall: + * @event: the #GdkEvent to send, which should be a #GdkEventClient. + * + * Sends an X ClientMessage event to all toplevel windows on the default + * #GdkScreen. + * + * Toplevel windows are determined by checking for the WM_STATE property, as + * described in the Inter-Client Communication Conventions Manual (ICCCM). + * If no windows are found with the WM_STATE property set, the message is sent + * to all children of the root window. + **/ +void +gdk_event_send_clientmessage_toall (GdkEvent *event) +{ + g_return_if_fail (event != NULL); + + gdk_screen_broadcast_client_message (gdk_screen_get_default (), event); +} + +/** + * gdk_device_get_core_pointer: + * + * Returns the core pointer device for the default display. + * + * Return value: the core pointer device; this is owned by the + * display and should not be freed. + **/ +GdkDevice * +gdk_device_get_core_pointer (void) +{ + return gdk_display_get_core_pointer (gdk_display_get_default ()); +} + +/** + * gdk_display_get_core_pointer: + * @display: a #GdkDisplay + * + * Returns the core pointer device for the given display + * + * Return value: the core pointer device; this is owned by the + * display and should not be freed. + * + * Since: 2.2 + **/ +GdkDevice * +gdk_display_get_core_pointer (GdkDisplay *display) +{ + return display->core_pointer; +} + +/** + * gdk_set_sm_client_id: + * @sm_client_id: the client id assigned by the session manager when the + * connection was opened, or %NULL to remove the property. + * + * Sets the SM_CLIENT_ID property on the application's leader window so that + * the window manager can save the application's state using the X11R6 ICCCM + * session management protocol. + * + * See the X Session Management Library documentation for more information on + * session management and the Inter-Client Communication Conventions Manual + * (ICCCM) for information on the WM_CLIENT_LEADER property. + * (Both documents are part of the X Window System distribution.) + * + * Deprecated:2.24: Use gdk_x11_set_sm_client_id() instead + **/ +void +gdk_set_sm_client_id (const gchar* sm_client_id) +{ + GSList *displays, *tmp_list; + + g_free (gdk_sm_client_id); + gdk_sm_client_id = g_strdup (sm_client_id); + + displays = gdk_display_manager_list_displays (gdk_display_manager_get ()); + for (tmp_list = displays; tmp_list; tmp_list = tmp_list->next) + _gdk_windowing_display_set_sm_client_id (tmp_list->data, sm_client_id); + + g_slist_free (displays); +} + +/** + * _gdk_get_sm_client_id: + * + * Gets the client ID set with gdk_set_sm_client_id(), if any. + * + * Return value: Session ID, or %NULL if gdk_set_sm_client_id() + * has never been called. + **/ +const char * +_gdk_get_sm_client_id (void) +{ + return gdk_sm_client_id; +} + +void +_gdk_display_enable_motion_hints (GdkDisplay *display) +{ + gulong serial; + + if (display->pointer_info.motion_hint_serial != 0) + { + serial = _gdk_windowing_window_get_next_serial (display); + /* We might not actually generate the next request, so + make sure this triggers always, this may cause it to + trigger slightly too early, but this is just a hint + anyway. */ + if (serial > 0) + serial--; + if (serial < display->pointer_info.motion_hint_serial) + display->pointer_info.motion_hint_serial = serial; + } +} + +/** + * gdk_display_get_pointer: + * @display: a #GdkDisplay + * @screen: (out) (allow-none): location to store the screen that the + * cursor is on, or %NULL. + * @x: (out) (allow-none): location to store root window X coordinate of pointer, or %NULL. + * @y: (out) (allow-none): location to store root window Y coordinate of pointer, or %NULL. + * @mask: (out) (allow-none): location to store current modifier mask, or %NULL + * + * Gets the current location of the pointer and the current modifier + * mask for a given display. + * + * Since: 2.2 + **/ +void +gdk_display_get_pointer (GdkDisplay *display, + GdkScreen **screen, + gint *x, + gint *y, + GdkModifierType *mask) +{ + GdkScreen *tmp_screen; + gint tmp_x, tmp_y; + GdkModifierType tmp_mask; + + g_return_if_fail (GDK_IS_DISPLAY (display)); + + display->pointer_hooks->get_pointer (display, &tmp_screen, &tmp_x, &tmp_y, &tmp_mask); + + if (screen) + *screen = tmp_screen; + if (x) + *x = tmp_x; + if (y) + *y = tmp_y; + if (mask) + *mask = tmp_mask; +} + +static GdkWindow * +gdk_display_real_get_window_at_pointer (GdkDisplay *display, + gint *win_x, + gint *win_y) +{ + GdkWindow *window; + gint x, y; + + window = _gdk_windowing_window_at_pointer (display, &x, &y, NULL, FALSE); + + /* This might need corrections, as the native window returned + may contain client side children */ + if (window) + { + double xx, yy; + + window = _gdk_window_find_descendant_at (window, + x, y, + &xx, &yy); + x = floor (xx + 0.5); + y = floor (yy + 0.5); + } + + *win_x = x; + *win_y = y; + + return window; +} + +static GdkWindow * +gdk_window_real_window_get_pointer (GdkDisplay *display, + GdkWindow *window, + gint *x, + gint *y, + GdkModifierType *mask) +{ + GdkWindowObject *private; + gint tmpx, tmpy; + GdkModifierType tmp_mask; + gboolean normal_child; + + private = (GdkWindowObject *) window; + + normal_child = GDK_WINDOW_IMPL_GET_IFACE (private->impl)->get_pointer (window, + &tmpx, &tmpy, + &tmp_mask); + /* We got the coords on the impl, convert to the window */ + tmpx -= private->abs_x; + tmpy -= private->abs_y; + + if (x) + *x = tmpx; + if (y) + *y = tmpy; + if (mask) + *mask = tmp_mask; + + if (normal_child) + return _gdk_window_find_child_at (window, tmpx, tmpy); + return NULL; +} + +/** + * gdk_display_get_window_at_pointer: + * @display: a #GdkDisplay + * @win_x: (out) (allow-none): return location for x coordinate of the pointer location relative + * to the window origin, or %NULL + * @win_y: (out) (allow-none): return location for y coordinate of the pointer location relative + & to the window origin, or %NULL + * + * Obtains the window underneath the mouse pointer, returning the location + * of the pointer in that window in @win_x, @win_y for @screen. Returns %NULL + * if the window under the mouse pointer is not known to GDK (for example, + * belongs to another application). + * + * Returns: (transfer none): the window under the mouse pointer, or %NULL + * + * Since: 2.2 + **/ +GdkWindow * +gdk_display_get_window_at_pointer (GdkDisplay *display, + gint *win_x, + gint *win_y) +{ + gint tmp_x, tmp_y; + GdkWindow *window; + + g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL); + + window = display->pointer_hooks->window_at_pointer (display, &tmp_x, &tmp_y); + + if (win_x) + *win_x = tmp_x; + if (win_y) + *win_y = tmp_y; + + return window; +} + +/** + * gdk_display_set_pointer_hooks: + * @display: a #GdkDisplay + * @new_hooks: a table of pointers to functions for getting + * quantities related to the current pointer position, + * or %NULL to restore the default table. + * + * This function allows for hooking into the operation + * of getting the current location of the pointer on a particular + * display. This is only useful for such low-level tools as an + * event recorder. Applications should never have any + * reason to use this facility. + * + * Return value: the previous pointer hook table + * + * Since: 2.2 + * + * Deprecated: 2.24: This function will go away in GTK 3 for lack of use cases. + **/ +GdkDisplayPointerHooks * +gdk_display_set_pointer_hooks (GdkDisplay *display, + const GdkDisplayPointerHooks *new_hooks) +{ + const GdkDisplayPointerHooks *result; + + g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL); + result = display->pointer_hooks; + + if (new_hooks) + display->pointer_hooks = new_hooks; + else + display->pointer_hooks = &default_pointer_hooks; + + return (GdkDisplayPointerHooks *)result; +} + +static void +singlehead_get_pointer (GdkDisplay *display, + GdkScreen **screen, + gint *x, + gint *y, + GdkModifierType *mask) +{ + GdkScreen *default_screen = gdk_display_get_default_screen (display); + GdkWindow *root_window = gdk_screen_get_root_window (default_screen); + + *screen = default_screen; + + singlehead_current_pointer_hooks->get_pointer (root_window, x, y, mask); +} + +static GdkWindow* +singlehead_window_get_pointer (GdkDisplay *display, + GdkWindow *window, + gint *x, + gint *y, + GdkModifierType *mask) +{ + return singlehead_current_pointer_hooks->get_pointer (window, x, y, mask); +} + +static GdkWindow* +singlehead_window_at_pointer (GdkDisplay *display, + gint *win_x, + gint *win_y) +{ + GdkScreen *default_screen = gdk_display_get_default_screen (display); + + return singlehead_current_pointer_hooks->window_at_pointer (default_screen, + win_x, win_y); +} + +static GdkWindow* +singlehead_default_window_get_pointer (GdkWindow *window, + gint *x, + gint *y, + GdkModifierType *mask) +{ + return gdk_window_real_window_get_pointer (gdk_drawable_get_display (window), + window, x, y, mask); +} + +static GdkWindow* +singlehead_default_window_at_pointer (GdkScreen *screen, + gint *win_x, + gint *win_y) +{ + return gdk_display_real_get_window_at_pointer (gdk_screen_get_display (screen), + win_x, win_y); +} + +/** + * gdk_set_pointer_hooks: + * @new_hooks: a table of pointers to functions for getting + * quantities related to the current pointer position, + * or %NULL to restore the default table. + * + * This function allows for hooking into the operation + * of getting the current location of the pointer. This + * is only useful for such low-level tools as an + * event recorder. Applications should never have any + * reason to use this facility. + * + * This function is not multihead safe. For multihead operation, + * see gdk_display_set_pointer_hooks(). + * + * Return value: the previous pointer hook table + * + * Deprecated: 2.24: This function will go away in GTK 3 for lack of use cases. + **/ +GdkPointerHooks * +gdk_set_pointer_hooks (const GdkPointerHooks *new_hooks) +{ + const GdkPointerHooks *result = singlehead_current_pointer_hooks; + + if (new_hooks) + singlehead_current_pointer_hooks = new_hooks; + else + singlehead_current_pointer_hooks = &singlehead_default_pointer_hooks; + + gdk_display_set_pointer_hooks (gdk_display_get_default (), + &singlehead_pointer_hooks); + + return (GdkPointerHooks *)result; +} + +static void +generate_grab_broken_event (GdkWindow *window, + gboolean keyboard, + gboolean implicit, + GdkWindow *grab_window) +{ + g_return_if_fail (window != NULL); + + if (!GDK_WINDOW_DESTROYED (window)) + { + GdkEvent event; + event.type = GDK_GRAB_BROKEN; + event.grab_broken.window = window; + event.grab_broken.send_event = 0; + event.grab_broken.keyboard = keyboard; + event.grab_broken.implicit = implicit; + event.grab_broken.grab_window = grab_window; + gdk_event_put (&event); + } +} + +GdkPointerGrabInfo * +_gdk_display_get_last_pointer_grab (GdkDisplay *display) +{ + GList *l; + + l = g_list_last (display->pointer_grabs); + + if (l == NULL) + return NULL; + else + return (GdkPointerGrabInfo *)l->data; +} + + +GdkPointerGrabInfo * +_gdk_display_add_pointer_grab (GdkDisplay *display, + GdkWindow *window, + GdkWindow *native_window, + gboolean owner_events, + GdkEventMask event_mask, + unsigned long serial_start, + guint32 time, + gboolean implicit) +{ + GdkPointerGrabInfo *info, *other_info; + GList *l; + + info = g_new0 (GdkPointerGrabInfo, 1); + + info->window = g_object_ref (window); + info->native_window = g_object_ref (native_window); + info->serial_start = serial_start; + info->serial_end = G_MAXULONG; + info->owner_events = owner_events; + info->event_mask = event_mask; + info->time = time; + info->implicit = implicit; + + /* Find the first grab that has a larger start time (if any) and insert + * before that. I.E we insert after already existing grabs with same + * start time */ + for (l = display->pointer_grabs; l != NULL; l = l->next) + { + other_info = l->data; + + if (info->serial_start < other_info->serial_start) + break; + } + display->pointer_grabs = + g_list_insert_before (display->pointer_grabs, l, info); + + /* Make sure the new grab end before next grab */ + if (l) + { + other_info = l->data; + info->serial_end = other_info->serial_start; + } + + /* Find any previous grab and update its end time */ + l = g_list_find (display->pointer_grabs, info); + l = l->prev; + if (l) + { + other_info = l->data; + other_info->serial_end = serial_start; + } + + return info; +} + +static void +free_pointer_grab (GdkPointerGrabInfo *info) +{ + g_object_unref (info->window); + g_object_unref (info->native_window); + g_free (info); +} + +/* _gdk_synthesize_crossing_events only works inside one toplevel. + This function splits things into two calls if needed, converting the + coordinates to the right toplevel */ +static void +synthesize_crossing_events (GdkDisplay *display, + GdkWindow *src_window, + GdkWindow *dest_window, + GdkCrossingMode crossing_mode, + guint32 time, + gulong serial) +{ + GdkWindow *src_toplevel, *dest_toplevel; + GdkModifierType state; + int x, y; + + /* We use the native crossing events if all native */ + if (_gdk_native_windows) + return; + + if (src_window) + src_toplevel = gdk_window_get_toplevel (src_window); + else + src_toplevel = NULL; + if (dest_window) + dest_toplevel = gdk_window_get_toplevel (dest_window); + else + dest_toplevel = NULL; + + if (src_toplevel == NULL && dest_toplevel == NULL) + return; + + if (src_toplevel == NULL || + src_toplevel == dest_toplevel) + { + /* Same toplevels */ + gdk_window_get_pointer (dest_toplevel, + &x, &y, &state); + _gdk_synthesize_crossing_events (display, + src_window, + dest_window, + crossing_mode, + x, y, state, + time, + NULL, + serial, FALSE); + } + else if (dest_toplevel == NULL) + { + gdk_window_get_pointer (src_toplevel, + &x, &y, &state); + _gdk_synthesize_crossing_events (display, + src_window, + NULL, + crossing_mode, + x, y, state, + time, + NULL, + serial, FALSE); + } + else + { + /* Different toplevels */ + gdk_window_get_pointer (src_toplevel, + &x, &y, &state); + _gdk_synthesize_crossing_events (display, + src_window, + NULL, + crossing_mode, + x, y, state, + time, + NULL, + serial, FALSE); + gdk_window_get_pointer (dest_toplevel, + &x, &y, &state); + _gdk_synthesize_crossing_events (display, + NULL, + dest_window, + crossing_mode, + x, y, state, + time, + NULL, + serial, FALSE); + } +} + +static GdkWindow * +get_current_toplevel (GdkDisplay *display, + int *x_out, int *y_out, + GdkModifierType *state_out) +{ + GdkWindow *pointer_window; + int x, y; + GdkModifierType state; + + pointer_window = _gdk_windowing_window_at_pointer (display, &x, &y, &state, TRUE); + if (pointer_window != NULL && + (GDK_WINDOW_DESTROYED (pointer_window) || + GDK_WINDOW_TYPE (pointer_window) == GDK_WINDOW_ROOT || + GDK_WINDOW_TYPE (pointer_window) == GDK_WINDOW_FOREIGN)) + pointer_window = NULL; + + *x_out = x; + *y_out = y; + *state_out = state; + return pointer_window; +} + +static void +switch_to_pointer_grab (GdkDisplay *display, + GdkPointerGrabInfo *grab, + GdkPointerGrabInfo *last_grab, + guint32 time, + gulong serial) +{ + GdkWindow *src_window, *pointer_window, *new_toplevel; + GList *old_grabs; + GdkModifierType state; + int x, y; + + /* Temporarily unset pointer to make sure we send the crossing events below */ + old_grabs = display->pointer_grabs; + display->pointer_grabs = NULL; + + if (grab) + { + /* New grab is in effect */ + + /* We need to generate crossing events for the grab. + * However, there are never any crossing events for implicit grabs + * TODO: ... Actually, this could happen if the pointer window + * doesn't have button mask so a parent gets the event... + */ + if (!grab->implicit) + { + /* We send GRAB crossing events from the window under the pointer to the + grab window. Except if there is an old grab then we start from that */ + if (last_grab) + src_window = last_grab->window; + else + src_window = display->pointer_info.window_under_pointer; + + if (src_window != grab->window) + { + synthesize_crossing_events (display, + src_window, grab->window, + GDK_CROSSING_GRAB, time, serial); + } + + /* !owner_event Grabbing a window that we're not inside, current status is + now NULL (i.e. outside grabbed window) */ + if (!grab->owner_events && display->pointer_info.window_under_pointer != grab->window) + _gdk_display_set_window_under_pointer (display, NULL); + } + + grab->activated = TRUE; + } + + if (last_grab) + { + new_toplevel = NULL; + + if (grab == NULL /* ungrab */ || + (!last_grab->owner_events && grab->owner_events) /* switched to owner_events */ ) + { + /* We force check what window we're in, and update the toplevel_under_pointer info, + * as that won't get told of this change with toplevel enter events. + */ + if (display->pointer_info.toplevel_under_pointer) + g_object_unref (display->pointer_info.toplevel_under_pointer); + display->pointer_info.toplevel_under_pointer = NULL; + + new_toplevel = get_current_toplevel (display, &x, &y, &state); + if (new_toplevel) + { + /* w is now toplevel and x,y in toplevel coords */ + display->pointer_info.toplevel_under_pointer = g_object_ref (new_toplevel); + display->pointer_info.toplevel_x = x; + display->pointer_info.toplevel_y = y; + display->pointer_info.state = state; + } + } + + if (grab == NULL) /* Ungrabbed, send events */ + { + pointer_window = NULL; + if (new_toplevel) + { + /* Find (possibly virtual) child window */ + pointer_window = + _gdk_window_find_descendant_at (new_toplevel, + x, y, + NULL, NULL); + } + + if (pointer_window != last_grab->window) + synthesize_crossing_events (display, + last_grab->window, pointer_window, + GDK_CROSSING_UNGRAB, time, serial); + + /* We're now ungrabbed, update the window_under_pointer */ + _gdk_display_set_window_under_pointer (display, pointer_window); + } + } + + display->pointer_grabs = old_grabs; + +} + +void +_gdk_display_pointer_grab_update (GdkDisplay *display, + gulong current_serial) +{ + GdkPointerGrabInfo *current_grab, *next_grab; + guint32 time; + + time = display->last_event_time; + + while (display->pointer_grabs != NULL) + { + current_grab = display->pointer_grabs->data; + + if (current_grab->serial_start > current_serial) + return; /* Hasn't started yet */ + + if (current_grab->serial_end > current_serial) + { + /* This one hasn't ended yet. + its the currently active one or scheduled to be active */ + + if (!current_grab->activated) + switch_to_pointer_grab (display, current_grab, NULL, time, current_serial); + + break; + } + + + next_grab = NULL; + if (display->pointer_grabs->next) + { + /* This is the next active grab */ + next_grab = display->pointer_grabs->next->data; + + if (next_grab->serial_start > current_serial) + next_grab = NULL; /* Actually its not yet active */ + } + + if ((next_grab == NULL && current_grab->implicit_ungrab) || + (next_grab != NULL && current_grab->window != next_grab->window)) + generate_grab_broken_event (GDK_WINDOW (current_grab->window), + FALSE, current_grab->implicit, + next_grab? next_grab->window : NULL); + + /* Remove old grab */ + display->pointer_grabs = + g_list_delete_link (display->pointer_grabs, + display->pointer_grabs); + + switch_to_pointer_grab (display, + next_grab, current_grab, + time, current_serial); + + free_pointer_grab (current_grab); + } +} + +static GList * +find_pointer_grab (GdkDisplay *display, + gulong serial) +{ + GdkPointerGrabInfo *grab; + GList *l; + + for (l = display->pointer_grabs; l != NULL; l = l->next) + { + grab = l->data; + + if (serial >= grab->serial_start && serial < grab->serial_end) + return l; + } + + return NULL; +} + + + +GdkPointerGrabInfo * +_gdk_display_has_pointer_grab (GdkDisplay *display, + gulong serial) +{ + GList *l; + + l = find_pointer_grab (display, serial); + if (l) + return l->data; + + return NULL; +} + +/* Returns true if last grab was ended + * If if_child is non-NULL, end the grab only if the grabbed + * window is the same as if_child or a descendant of it */ +gboolean +_gdk_display_end_pointer_grab (GdkDisplay *display, + gulong serial, + GdkWindow *if_child, + gboolean implicit) +{ + GdkPointerGrabInfo *grab; + GList *l; + + l = find_pointer_grab (display, serial); + + if (l == NULL) + return FALSE; + + grab = l->data; + if (grab && + (if_child == NULL || + _gdk_window_event_parent_of (if_child, grab->window))) + { + grab->serial_end = serial; + grab->implicit_ungrab = implicit; + return l->next == NULL; + } + + return FALSE; +} + +void +_gdk_display_set_has_keyboard_grab (GdkDisplay *display, + GdkWindow *window, + GdkWindow *native_window, + gboolean owner_events, + unsigned long serial, + guint32 time) +{ + if (display->keyboard_grab.window != NULL && + display->keyboard_grab.window != window) + generate_grab_broken_event (display->keyboard_grab.window, + TRUE, FALSE, window); + + display->keyboard_grab.window = window; + display->keyboard_grab.native_window = native_window; + display->keyboard_grab.owner_events = owner_events; + display->keyboard_grab.serial = serial; + display->keyboard_grab.time = time; +} + +void +_gdk_display_unset_has_keyboard_grab (GdkDisplay *display, + gboolean implicit) +{ + if (implicit) + generate_grab_broken_event (display->keyboard_grab.window, + TRUE, FALSE, NULL); + display->keyboard_grab.window = NULL; +} + +/** + * gdk_keyboard_grab_info_libgtk_only: + * @display: the display for which to get the grab information + * @grab_window: location to store current grab window + * @owner_events: location to store boolean indicating whether + * the @owner_events flag to gdk_keyboard_grab() was %TRUE. + * + * Determines information about the current keyboard grab. + * This is not public API and must not be used by applications. + * + * Return value: %TRUE if this application currently has the + * keyboard grabbed. + **/ +gboolean +gdk_keyboard_grab_info_libgtk_only (GdkDisplay *display, + GdkWindow **grab_window, + gboolean *owner_events) +{ + g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE); + + if (display->keyboard_grab.window) + { + if (grab_window) + *grab_window = display->keyboard_grab.window; + if (owner_events) + *owner_events = display->keyboard_grab.owner_events; + + return TRUE; + } + else + return FALSE; +} + +/** + * gdk_pointer_grab_info_libgtk_only: + * @display: the #GdkDisplay for which to get the grab information + * @grab_window: location to store current grab window + * @owner_events: location to store boolean indicating whether + * the @owner_events flag to gdk_pointer_grab() was %TRUE. + * + * Determines information about the current pointer grab. + * This is not public API and must not be used by applications. + * + * Return value: %TRUE if this application currently has the + * pointer grabbed. + **/ +gboolean +gdk_pointer_grab_info_libgtk_only (GdkDisplay *display, + GdkWindow **grab_window, + gboolean *owner_events) +{ + GdkPointerGrabInfo *info; + + g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE); + + /* What we're interested in is the steady state (ie last grab), + because we're interested e.g. if we grabbed so that we + can ungrab, even if our grab is not active just yet. */ + info = _gdk_display_get_last_pointer_grab (display); + + if (info) + { + if (grab_window) + *grab_window = info->window; + if (owner_events) + *owner_events = info->owner_events; + + return TRUE; + } + else + return FALSE; +} + + +/** + * gdk_display_pointer_is_grabbed: + * @display: a #GdkDisplay + * + * Test if the pointer is grabbed. + * + * Returns: %TRUE if an active X pointer grab is in effect + * + * Since: 2.2 + */ +gboolean +gdk_display_pointer_is_grabbed (GdkDisplay *display) +{ + GdkPointerGrabInfo *info; + + g_return_val_if_fail (GDK_IS_DISPLAY (display), TRUE); + + /* What we're interested in is the steady state (ie last grab), + because we're interested e.g. if we grabbed so that we + can ungrab, even if our grab is not active just yet. */ + info = _gdk_display_get_last_pointer_grab (display); + + return (info && !info->implicit); +} + +#define __GDK_DISPLAY_C__ +#include "gdkaliasdef.c" diff --git a/libs/tk/ydk/gdkdisplaymanager.c b/libs/tk/ydk/gdkdisplaymanager.c new file mode 100644 index 0000000000..c171524e4a --- /dev/null +++ b/libs/tk/ydk/gdkdisplaymanager.c @@ -0,0 +1,264 @@ +/* GDK - The GIMP Drawing Kit + * Copyright (C) 2000 Red Hat, 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. + */ + +/* + * 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 "config.h" + +#include "gdkscreen.h" +#include "gdkdisplay.h" +#include "gdkdisplaymanager.h" + +#include "gdkinternals.h" +#include "gdkmarshalers.h" + +#include "gdkintl.h" + +#include "gdkalias.h" + +struct _GdkDisplayManager +{ + GObject parent_instance; +}; + +enum { + PROP_0, + + PROP_DEFAULT_DISPLAY +}; + +enum { + DISPLAY_OPENED, + LAST_SIGNAL +}; + +static void gdk_display_manager_class_init (GdkDisplayManagerClass *klass); +static void gdk_display_manager_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static void gdk_display_manager_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); + +static guint signals[LAST_SIGNAL] = { 0 }; + +static GdkDisplay *default_display = NULL; + +G_DEFINE_TYPE (GdkDisplayManager, gdk_display_manager, G_TYPE_OBJECT) + +static void +gdk_display_manager_class_init (GdkDisplayManagerClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->set_property = gdk_display_manager_set_property; + object_class->get_property = gdk_display_manager_get_property; + + /** + * GdkDisplayManager::display-opened: + * @display_manager: the object on which the signal is emitted + * @display: the opened display + * + * The ::display_opened signal is emitted when a display is opened. + * + * Since: 2.2 + */ + signals[DISPLAY_OPENED] = + g_signal_new (g_intern_static_string ("display-opened"), + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GdkDisplayManagerClass, display_opened), + NULL, NULL, + _gdk_marshal_VOID__OBJECT, + G_TYPE_NONE, + 1, + GDK_TYPE_DISPLAY); + + g_object_class_install_property (object_class, + PROP_DEFAULT_DISPLAY, + g_param_spec_object ("default-display", + P_("Default Display"), + P_("The default display for GDK"), + GDK_TYPE_DISPLAY, + G_PARAM_READWRITE|G_PARAM_STATIC_NAME| + G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB)); +} + +static void +gdk_display_manager_init (GdkDisplayManager *manager) +{ +} + +static void +gdk_display_manager_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (prop_id) + { + case PROP_DEFAULT_DISPLAY: + gdk_display_manager_set_default_display (GDK_DISPLAY_MANAGER (object), + g_value_get_object (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gdk_display_manager_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + switch (prop_id) + { + case PROP_DEFAULT_DISPLAY: + g_value_set_object (value, default_display); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +/** + * gdk_display_manager_get: + * + * Gets the singleton #GdkDisplayManager object. + * + * Returns: (transfer none): The global #GdkDisplayManager singleton; gdk_parse_pargs(), + * gdk_init(), or gdk_init_check() must have been called first. + * + * Since: 2.2 + **/ +GdkDisplayManager* +gdk_display_manager_get (void) +{ + static GdkDisplayManager *display_manager = NULL; + + if (!display_manager) + display_manager = g_object_new (GDK_TYPE_DISPLAY_MANAGER, NULL); + + return display_manager; +} + +/** + * gdk_display_manager_get_default_display: + * @display_manager: a #GdkDisplayManager + * + * Gets the default #GdkDisplay. + * + * Returns: (transfer none): a #GdkDisplay, or %NULL if there is no default + * display. + * + * Since: 2.2 + */ +GdkDisplay * +gdk_display_manager_get_default_display (GdkDisplayManager *display_manager) +{ + return default_display; +} + +/** + * gdk_display_get_default: + * + * Gets the default #GdkDisplay. This is a convenience + * function for + * gdk_display_manager_get_default_display (gdk_display_manager_get ()). + * + * Returns: (transfer none): a #GdkDisplay, or %NULL if there is no default + * display. + * + * Since: 2.2 + */ +GdkDisplay * +gdk_display_get_default (void) +{ + return default_display; +} + +/** + * gdk_screen_get_default: + * + * Gets the default screen for the default display. (See + * gdk_display_get_default ()). + * + * Returns: (transfer none): a #GdkScreen, or %NULL if there is no default display. + * + * Since: 2.2 + */ +GdkScreen * +gdk_screen_get_default (void) +{ + if (default_display) + return gdk_display_get_default_screen (default_display); + else + return NULL; +} + +/** + * gdk_display_manager_set_default_display: + * @display_manager: a #GdkDisplayManager + * @display: a #GdkDisplay + * + * Sets @display as the default display. + * + * Since: 2.2 + **/ +void +gdk_display_manager_set_default_display (GdkDisplayManager *display_manager, + GdkDisplay *display) +{ + default_display = display; + + _gdk_windowing_set_default_display (display); + + g_object_notify (G_OBJECT (display_manager), "default-display"); +} + +/** + * gdk_display_manager_list_displays: + * @display_manager: a #GdkDisplayManager + * + * List all currently open displays. + * + * Return value: (transfer container) (element-type GdkDisplay): a newly allocated + * #GSList of #GdkDisplay objects. Free this list with g_slist_free() when you + * are done with it. + * + * Since: 2.2 + **/ +GSList * +gdk_display_manager_list_displays (GdkDisplayManager *display_manager) +{ + return g_slist_copy (_gdk_displays); +} + +#define __GDK_DISPLAY_MANAGER_C__ +#include "gdkaliasdef.c" diff --git a/libs/tk/ydk/gdkdnd.c b/libs/tk/ydk/gdkdnd.c new file mode 100644 index 0000000000..58d4452d4a --- /dev/null +++ b/libs/tk/ydk/gdkdnd.c @@ -0,0 +1,212 @@ +/* GDK - The GIMP Drawing Kit + * Copyright (C) 1995-1999 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, 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 "config.h" +#include +#include +#include +#include "gdkalias.h" + +/** + * gdk_drag_find_window: + * @context: a #GdkDragContext. + * @drag_window: a window which may be at the pointer position, but + * should be ignored, since it is put up by the drag source as an icon. + * @x_root: the x position of the pointer in root coordinates. + * @y_root: the y position of the pointer in root coordinates. + * @dest_window: (out): location to store the destination window in. + * @protocol: (out): location to store the DND protocol in. + * + * Finds the destination window and DND protocol to use at the + * given pointer position. + * + * This function is called by the drag source to obtain the + * @dest_window and @protocol parameters for gdk_drag_motion(). + * + * Deprecated: 2.24: Use gdk_drag_find_window_for_screen() instead. + **/ +void +gdk_drag_find_window (GdkDragContext *context, + GdkWindow *drag_window, + gint x_root, + gint y_root, + GdkWindow **dest_window, + GdkDragProtocol *protocol) +{ + gdk_drag_find_window_for_screen (context, drag_window, + gdk_drawable_get_screen (context->source_window), + x_root, y_root, dest_window, protocol); +} + +/** + * gdk_drag_get_protocol: + * @xid: the windowing system id of the destination window. + * @protocol: location where the supported DND protocol is returned. + * + * Finds out the DND protocol supported by a window. + * + * Return value: the windowing system specific id for the window where + * the drop should happen. This may be @xid or the id of a proxy + * window, or zero if @xid doesn't support Drag and Drop. + * + * Deprecated: 2.24: Use gdk_drag_get_protocol_for_display() instead + **/ +GdkNativeWindow +gdk_drag_get_protocol (GdkNativeWindow xid, + GdkDragProtocol *protocol) +{ + return gdk_drag_get_protocol_for_display (gdk_display_get_default (), xid, protocol); +} + +/** + * gdk_drag_context_list_targets: + * @context: a #GdkDragContext + * + * Retrieves the list of targets of the context. + * + * Return value: (transfer none) (element-type GdkAtom): a #GList of targets + * + * Since: 2.22 + **/ +GList * +gdk_drag_context_list_targets (GdkDragContext *context) +{ + g_return_val_if_fail (GDK_IS_DRAG_CONTEXT (context), NULL); + + return context->targets; +} + +/** + * gdk_drag_context_get_actions: + * @context: a #GdkDragContext + * + * Determines the bitmask of actions proposed by the source if + * gdk_drag_context_suggested_action() returns GDK_ACTION_ASK. + * + * Return value: the #GdkDragAction flags + * + * Since: 2.22 + **/ +GdkDragAction +gdk_drag_context_get_actions (GdkDragContext *context) +{ + g_return_val_if_fail (GDK_IS_DRAG_CONTEXT (context), GDK_ACTION_DEFAULT); + + return context->actions; +} + +/** + * gdk_drag_context_get_suggested_action: + * @context: a #GdkDragContext + * + * Determines the suggested drag action of the context. + * + * Return value: a #GdkDragAction value + * + * Since: 2.22 + **/ +GdkDragAction +gdk_drag_context_get_suggested_action (GdkDragContext *context) +{ + g_return_val_if_fail (GDK_IS_DRAG_CONTEXT (context), 0); + + return context->suggested_action; +} + +/** + * gdk_drag_context_get_selected_action: + * @context: a #GdkDragContext + * + * Determines the action chosen by the drag destination. + * + * Return value: a #GdkDragAction value + * + * Since: 2.22 + **/ +GdkDragAction +gdk_drag_context_get_selected_action (GdkDragContext *context) +{ + g_return_val_if_fail (GDK_IS_DRAG_CONTEXT (context), 0); + + return context->action; +} + +/** + * gdk_drag_context_get_source_window: + * @context: a #GdkDragContext + * + * Returns the #GdkWindow where the DND operation started. + * + * Return value: (transfer none): a #GdkWindow + * + * Since: 2.22 + **/ +GdkWindow * +gdk_drag_context_get_source_window (GdkDragContext *context) +{ + g_return_val_if_fail (GDK_IS_DRAG_CONTEXT (context), NULL); + + return context->source_window; +} + +/** + * gdk_drag_context_get_dest_window: + * @context: a #GdkDragContext + * + * Returns the destination windw for the DND operation. + * + * Return value: (transfer none): a #GdkWindow + * + * Since: 2.24 + */ +GdkWindow * +gdk_drag_context_get_dest_window (GdkDragContext *context) +{ + g_return_val_if_fail (GDK_IS_DRAG_CONTEXT (context), NULL); + + return context->dest_window; +} + +/** + * gdk_drag_context_get_protocol: + * @context: a #GdkDragContext + * + * Returns the drag protocol thats used by this context. + * + * Returns: the drag protocol + * + * Since: 2.24 + */ +GdkDragProtocol +gdk_drag_context_get_protocol (GdkDragContext *context) +{ + g_return_val_if_fail (GDK_IS_DRAG_CONTEXT (context), GDK_DRAG_PROTO_NONE); + + return context->protocol; +} + +#define __GDK_DND_C__ +#include "gdkaliasdef.c" diff --git a/libs/tk/ydk/gdkdraw.c b/libs/tk/ydk/gdkdraw.c new file mode 100644 index 0000000000..932de976f3 --- /dev/null +++ b/libs/tk/ydk/gdkdraw.c @@ -0,0 +1,1979 @@ +/* GDK - The GIMP Drawing Kit + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, 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 "config.h" +#include +#include +#include +#include "gdkcairo.h" +#include "gdkdrawable.h" +#include "gdkinternals.h" +#include "gdkwindow.h" +#include "gdkscreen.h" +#include "gdkpixbuf.h" +#include "gdkalias.h" + +static GdkImage* gdk_drawable_real_get_image (GdkDrawable *drawable, + gint x, + gint y, + gint width, + gint height); +static GdkDrawable* gdk_drawable_real_get_composite_drawable (GdkDrawable *drawable, + gint x, + gint y, + gint width, + gint height, + gint *composite_x_offset, + gint *composite_y_offset); +static GdkRegion * gdk_drawable_real_get_visible_region (GdkDrawable *drawable); +static void gdk_drawable_real_draw_pixbuf (GdkDrawable *drawable, + GdkGC *gc, + GdkPixbuf *pixbuf, + gint src_x, + gint src_y, + gint dest_x, + gint dest_y, + gint width, + gint height, + GdkRgbDither dither, + gint x_dither, + gint y_dither); +static void gdk_drawable_real_draw_drawable (GdkDrawable *drawable, + GdkGC *gc, + GdkDrawable *src, + gint xsrc, + gint ysrc, + gint xdest, + gint ydest, + gint width, + gint height); + + +G_DEFINE_ABSTRACT_TYPE (GdkDrawable, gdk_drawable, G_TYPE_OBJECT) + +static void +gdk_drawable_class_init (GdkDrawableClass *klass) +{ + klass->get_image = gdk_drawable_real_get_image; + klass->get_composite_drawable = gdk_drawable_real_get_composite_drawable; + /* Default implementation for clip and visible region is the same */ + klass->get_clip_region = gdk_drawable_real_get_visible_region; + klass->get_visible_region = gdk_drawable_real_get_visible_region; + klass->draw_pixbuf = gdk_drawable_real_draw_pixbuf; + klass->draw_drawable = gdk_drawable_real_draw_drawable; +} + +static void +gdk_drawable_init (GdkDrawable *drawable) +{ +} + +/* Manipulation of drawables + */ + +/** + * gdk_drawable_set_data: + * @drawable: a #GdkDrawable + * @key: name to store the data under + * @data: arbitrary data + * @destroy_func: (allow-none): function to free @data, or %NULL + * + * This function is equivalent to g_object_set_data(), + * the #GObject variant should be used instead. + * + **/ +void +gdk_drawable_set_data (GdkDrawable *drawable, + const gchar *key, + gpointer data, + GDestroyNotify destroy_func) +{ + g_return_if_fail (GDK_IS_DRAWABLE (drawable)); + + g_object_set_qdata_full (G_OBJECT (drawable), + g_quark_from_string (key), + data, + destroy_func); +} + +/** + * gdk_drawable_get_data: + * @drawable: a #GdkDrawable + * @key: name the data was stored under + * + * Equivalent to g_object_get_data(); the #GObject variant should be + * used instead. + * + * Return value: the data stored at @key + **/ +gpointer +gdk_drawable_get_data (GdkDrawable *drawable, + const gchar *key) +{ + g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL); + + return g_object_get_qdata (G_OBJECT (drawable), + g_quark_try_string (key)); +} + +/** + * gdk_drawable_get_size: + * @drawable: a #GdkDrawable + * @width: (out) (allow-none): location to store drawable's width, or %NULL + * @height: (out) (allow-none): location to store drawable's height, or %NULL + * + * Fills *@width and *@height with the size of @drawable. + * @width or @height can be %NULL if you only want the other one. + * + * On the X11 platform, if @drawable is a #GdkWindow, the returned + * size is the size reported in the most-recently-processed configure + * event, rather than the current size on the X server. + * + * Deprecated: 2.24: Use gdk_window_get_width() and gdk_window_get_height() for + * #GdkWindows. Use gdk_pixmap_get_size() for #GdkPixmaps. + */ +void +gdk_drawable_get_size (GdkDrawable *drawable, + gint *width, + gint *height) +{ + g_return_if_fail (GDK_IS_DRAWABLE (drawable)); + + GDK_DRAWABLE_GET_CLASS (drawable)->get_size (drawable, width, height); +} + +/** + * gdk_drawable_get_visual: + * @drawable: a #GdkDrawable + * + * Gets the #GdkVisual describing the pixel format of @drawable. + * + * Return value: a #GdkVisual + * + * Deprecated: 2.24: Use gdk_window_get_visual() + */ +GdkVisual* +gdk_drawable_get_visual (GdkDrawable *drawable) +{ + g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL); + + return GDK_DRAWABLE_GET_CLASS (drawable)->get_visual (drawable); +} + +/** + * gdk_drawable_get_depth: + * @drawable: a #GdkDrawable + * + * Obtains the bit depth of the drawable, that is, the number of bits + * that make up a pixel in the drawable's visual. Examples are 8 bits + * per pixel, 24 bits per pixel, etc. + * + * Return value: number of bits per pixel + **/ +gint +gdk_drawable_get_depth (GdkDrawable *drawable) +{ + g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), 0); + + return GDK_DRAWABLE_GET_CLASS (drawable)->get_depth (drawable); +} +/** + * gdk_drawable_get_screen: + * @drawable: a #GdkDrawable + * + * Gets the #GdkScreen associated with a #GdkDrawable. + * + * Return value: the #GdkScreen associated with @drawable + * + * Since: 2.2 + * + * Deprecated: 2.24: Use gdk_window_get_screen() instead + **/ +GdkScreen* +gdk_drawable_get_screen (GdkDrawable *drawable) +{ + g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL); + + return GDK_DRAWABLE_GET_CLASS (drawable)->get_screen (drawable); +} + +/** + * gdk_drawable_get_display: + * @drawable: a #GdkDrawable + * + * Gets the #GdkDisplay associated with a #GdkDrawable. + * + * Return value: the #GdkDisplay associated with @drawable + * + * Since: 2.2 + * + * Deprecated: 2.24: Use gdk_window_get_display() instead + **/ +GdkDisplay* +gdk_drawable_get_display (GdkDrawable *drawable) +{ + g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL); + + return gdk_screen_get_display (gdk_drawable_get_screen (drawable)); +} + +/** + * gdk_drawable_set_colormap: + * @drawable: a #GdkDrawable + * @colormap: a #GdkColormap + * + * Sets the colormap associated with @drawable. Normally this will + * happen automatically when the drawable is created; you only need to + * use this function if the drawable-creating function did not have a + * way to determine the colormap, and you then use drawable operations + * that require a colormap. The colormap for all drawables and + * graphics contexts you intend to use together should match. i.e. + * when using a #GdkGC to draw to a drawable, or copying one drawable + * to another, the colormaps should match. + * + **/ +void +gdk_drawable_set_colormap (GdkDrawable *drawable, + GdkColormap *cmap) +{ + g_return_if_fail (GDK_IS_DRAWABLE (drawable)); + g_return_if_fail (cmap == NULL || gdk_drawable_get_depth (drawable) + == cmap->visual->depth); + + GDK_DRAWABLE_GET_CLASS (drawable)->set_colormap (drawable, cmap); +} + +/** + * gdk_drawable_get_colormap: + * @drawable: a #GdkDrawable + * + * Gets the colormap for @drawable, if one is set; returns + * %NULL otherwise. + * + * Return value: the colormap, or %NULL + **/ +GdkColormap* +gdk_drawable_get_colormap (GdkDrawable *drawable) +{ + g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL); + + return GDK_DRAWABLE_GET_CLASS (drawable)->get_colormap (drawable); +} + +/** + * gdk_drawable_ref: + * @drawable: a #GdkDrawable + * + * Deprecated equivalent of calling g_object_ref() on @drawable. + * (Drawables were not objects in previous versions of GDK.) + * + * Return value: the same @drawable passed in + * + * Deprecated: 2.0: Use g_object_ref() instead. + **/ +GdkDrawable* +gdk_drawable_ref (GdkDrawable *drawable) +{ + return (GdkDrawable *) g_object_ref (drawable); +} + +/** + * gdk_drawable_unref: + * @drawable: a #GdkDrawable + * + * Deprecated equivalent of calling g_object_unref() on @drawable. + * + * Deprecated: 2.0: Use g_object_unref() instead. + **/ +void +gdk_drawable_unref (GdkDrawable *drawable) +{ + g_return_if_fail (GDK_IS_DRAWABLE (drawable)); + + g_object_unref (drawable); +} + +/* Drawing + */ + +/** + * gdk_draw_point: + * @drawable: a #GdkDrawable (a #GdkWindow or a #GdkPixmap). + * @gc: a #GdkGC. + * @x: the x coordinate of the point. + * @y: the y coordinate of the point. + * + * Draws a point, using the foreground color and other attributes of + * the #GdkGC. + * + * Deprecated: 2.22: Use cairo_rectangle() and cairo_fill() or + * cairo_move_to() and cairo_stroke() instead. + **/ +void +gdk_draw_point (GdkDrawable *drawable, + GdkGC *gc, + gint x, + gint y) +{ + GdkPoint point; + + g_return_if_fail (GDK_IS_DRAWABLE (drawable)); + g_return_if_fail (GDK_IS_GC (gc)); + + point.x = x; + point.y = y; + + GDK_DRAWABLE_GET_CLASS (drawable)->draw_points (drawable, gc, &point, 1); +} + +/** + * gdk_draw_line: + * @drawable: a #GdkDrawable (a #GdkWindow or a #GdkPixmap). + * @gc: a #GdkGC. + * @x1_: the x coordinate of the start point. + * @y1_: the y coordinate of the start point. + * @x2_: the x coordinate of the end point. + * @y2_: the y coordinate of the end point. + * + * Draws a line, using the foreground color and other attributes of + * the #GdkGC. + * + * Deprecated: 2.22: Use cairo_line_to() and cairo_stroke() instead. + * Be aware that the default line width in Cairo is 2 pixels and that your + * coordinates need to describe the center of the line. To draw a single + * pixel wide pixel-aligned line, you would use: + * |[cairo_set_line_width (cr, 1.0); + * cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE); + * cairo_move_to (cr, 0.5, 0.5); + * cairo_line_to (cr, 9.5, 0.5); + * cairo_stroke (cr);]| + * See also the Cairo + * FAQ on this topic. + **/ +void +gdk_draw_line (GdkDrawable *drawable, + GdkGC *gc, + gint x1, + gint y1, + gint x2, + gint y2) +{ + GdkSegment segment; + + g_return_if_fail (GDK_IS_DRAWABLE (drawable)); + g_return_if_fail (GDK_IS_GC (gc)); + + segment.x1 = x1; + segment.y1 = y1; + segment.x2 = x2; + segment.y2 = y2; + GDK_DRAWABLE_GET_CLASS (drawable)->draw_segments (drawable, gc, &segment, 1); +} + +/** + * gdk_draw_rectangle: + * @drawable: a #GdkDrawable (a #GdkWindow or a #GdkPixmap). + * @gc: a #GdkGC. + * @filled: %TRUE if the rectangle should be filled. + * @x: the x coordinate of the left edge of the rectangle. + * @y: the y coordinate of the top edge of the rectangle. + * @width: the width of the rectangle. + * @height: the height of the rectangle. + * + * Draws a rectangular outline or filled rectangle, using the foreground color + * and other attributes of the #GdkGC. + * + * A rectangle drawn filled is 1 pixel smaller in both dimensions than a + * rectangle outlined. Calling + * gdk_draw_rectangle (window, gc, TRUE, 0, 0, 20, 20) + * results in a filled rectangle 20 pixels wide and 20 pixels high. Calling + * gdk_draw_rectangle (window, gc, FALSE, 0, 0, 20, 20) + * results in an outlined rectangle with corners at (0, 0), (0, 20), (20, 20), + * and (20, 0), which makes it 21 pixels wide and 21 pixels high. + * + * Deprecated: 2.22: Use cairo_rectangle() and cairo_fill() or cairo_stroke() + * instead. For stroking, the same caveats for converting code apply as for + * gdk_draw_line(). + **/ +void +gdk_draw_rectangle (GdkDrawable *drawable, + GdkGC *gc, + gboolean filled, + gint x, + gint y, + gint width, + gint height) +{ + g_return_if_fail (GDK_IS_DRAWABLE (drawable)); + g_return_if_fail (GDK_IS_GC (gc)); + + if (width < 0 || height < 0) + { + gint real_width; + gint real_height; + + gdk_drawable_get_size (drawable, &real_width, &real_height); + + if (width < 0) + width = real_width; + if (height < 0) + height = real_height; + } + + GDK_DRAWABLE_GET_CLASS (drawable)->draw_rectangle (drawable, gc, filled, x, y, + width, height); +} + +/** + * gdk_draw_arc: + * @drawable: a #GdkDrawable (a #GdkWindow or a #GdkPixmap). + * @gc: a #GdkGC. + * @filled: %TRUE if the arc should be filled, producing a 'pie slice'. + * @x: the x coordinate of the left edge of the bounding rectangle. + * @y: the y coordinate of the top edge of the bounding rectangle. + * @width: the width of the bounding rectangle. + * @height: the height of the bounding rectangle. + * @angle1: the start angle of the arc, relative to the 3 o'clock position, + * counter-clockwise, in 1/64ths of a degree. + * @angle2: the end angle of the arc, relative to @angle1, in 1/64ths + * of a degree. + * + * Draws an arc or a filled 'pie slice'. The arc is defined by the bounding + * rectangle of the entire ellipse, and the start and end angles of the part + * of the ellipse to be drawn. + * + * Deprecated: 2.22: Use cairo_arc() and cairo_fill() or cairo_stroke() + * instead. Note that arcs just like any drawing operation in Cairo are + * antialiased unless you call cairo_set_antialias(). + **/ +void +gdk_draw_arc (GdkDrawable *drawable, + GdkGC *gc, + gboolean filled, + gint x, + gint y, + gint width, + gint height, + gint angle1, + gint angle2) +{ + g_return_if_fail (GDK_IS_DRAWABLE (drawable)); + g_return_if_fail (GDK_IS_GC (gc)); + + if (width < 0 || height < 0) + { + gint real_width; + gint real_height; + + gdk_drawable_get_size (drawable, &real_width, &real_height); + + if (width < 0) + width = real_width; + if (height < 0) + height = real_height; + } + + GDK_DRAWABLE_GET_CLASS (drawable)->draw_arc (drawable, gc, filled, + x, y, width, height, angle1, angle2); +} + +/** + * gdk_draw_polygon: + * @drawable: a #GdkDrawable (a #GdkWindow or a #GdkPixmap). + * @gc: a #GdkGC. + * @filled: %TRUE if the polygon should be filled. The polygon is closed + * automatically, connecting the last point to the first point if + * necessary. + * @points: an array of #GdkPoint structures specifying the points making + * up the polygon. + * @n_points: the number of points. + * + * Draws an outlined or filled polygon. + * + * Deprecated: 2.22: Use cairo_line_to() or cairo_append_path() and + * cairo_fill() or cairo_stroke() instead. + **/ +void +gdk_draw_polygon (GdkDrawable *drawable, + GdkGC *gc, + gboolean filled, + const GdkPoint *points, + gint n_points) +{ + g_return_if_fail (GDK_IS_DRAWABLE (drawable)); + g_return_if_fail (GDK_IS_GC (gc)); + + GDK_DRAWABLE_GET_CLASS (drawable)->draw_polygon (drawable, gc, filled, + (GdkPoint *) points, + n_points); +} + +/* gdk_draw_string + * + * Modified by Li-Da Lho to draw 16 bits and Multibyte strings + * + * Interface changed: add "GdkFont *font" to specify font or fontset explicitely + */ +/** + * gdk_draw_string: + * @drawable: a #GdkDrawable (a #GdkWindow or a #GdkPixmap). + * @font: a #GdkFont. + * @gc: a #GdkGC. + * @x: the x coordinate of the left edge of the text. + * @y: the y coordinate of the baseline of the text. + * @string: the string of characters to draw. + * + * Draws a string of characters in the given font or fontset. + * + * Deprecated: 2.4: Use gdk_draw_layout() instead. + **/ +void +gdk_draw_string (GdkDrawable *drawable, + GdkFont *font, + GdkGC *gc, + gint x, + gint y, + const gchar *string) +{ + gdk_draw_text (drawable, font, gc, x, y, string, _gdk_font_strlen (font, string)); +} + +/* gdk_draw_text + * + * Modified by Li-Da Lho to draw 16 bits and Multibyte strings + * + * Interface changed: add "GdkFont *font" to specify font or fontset explicitely + */ +/** + * gdk_draw_text: + * @drawable: a #GdkDrawable (a #GdkWindow or a #GdkPixmap). + * @font: a #GdkFont. + * @gc: a #GdkGC. + * @x: the x coordinate of the left edge of the text. + * @y: the y coordinate of the baseline of the text. + * @text: the characters to draw. + * @text_length: the number of characters of @text to draw. + * + * Draws a number of characters in the given font or fontset. + * + * Deprecated: 2.4: Use gdk_draw_layout() instead. + **/ +void +gdk_draw_text (GdkDrawable *drawable, + GdkFont *font, + GdkGC *gc, + gint x, + gint y, + const gchar *text, + gint text_length) +{ + g_return_if_fail (GDK_IS_DRAWABLE (drawable)); + g_return_if_fail (font != NULL); + g_return_if_fail (GDK_IS_GC (gc)); + g_return_if_fail (text != NULL); + + GDK_DRAWABLE_GET_CLASS (drawable)->draw_text (drawable, font, gc, x, y, text, text_length); +} + +/** + * gdk_draw_text_wc: + * @drawable: a #GdkDrawable (a #GdkWindow or a #GdkPixmap). + * @font: a #GdkFont. + * @gc: a #GdkGC. + * @x: the x coordinate of the left edge of the text. + * @y: the y coordinate of the baseline of the text. + * @text: the wide characters to draw. + * @text_length: the number of characters to draw. + * + * Draws a number of wide characters using the given font of fontset. + * If the font is a 1-byte font, the string is converted into 1-byte + * characters (discarding the high bytes) before output. + * + * Deprecated: 2.4: Use gdk_draw_layout() instead. + **/ +void +gdk_draw_text_wc (GdkDrawable *drawable, + GdkFont *font, + GdkGC *gc, + gint x, + gint y, + const GdkWChar *text, + gint text_length) +{ + g_return_if_fail (GDK_IS_DRAWABLE (drawable)); + g_return_if_fail (font != NULL); + g_return_if_fail (GDK_IS_GC (gc)); + g_return_if_fail (text != NULL); + + GDK_DRAWABLE_GET_CLASS (drawable)->draw_text_wc (drawable, font, gc, x, y, text, text_length); +} + +/** + * gdk_draw_drawable: + * @drawable: a #GdkDrawable + * @gc: a #GdkGC sharing the drawable's visual and colormap + * @src: the source #GdkDrawable, which may be the same as @drawable + * @xsrc: X position in @src of rectangle to draw + * @ysrc: Y position in @src of rectangle to draw + * @xdest: X position in @drawable where the rectangle should be drawn + * @ydest: Y position in @drawable where the rectangle should be drawn + * @width: width of rectangle to draw, or -1 for entire @src width + * @height: height of rectangle to draw, or -1 for entire @src height + * + * Copies the @width x @height region of @src at coordinates (@xsrc, + * @ysrc) to coordinates (@xdest, @ydest) in @drawable. + * @width and/or @height may be given as -1, in which case the entire + * @src drawable will be copied. + * + * Most fields in @gc are not used for this operation, but notably the + * clip mask or clip region will be honored. + * + * The source and destination drawables must have the same visual and + * colormap, or errors will result. (On X11, failure to match + * visual/colormap results in a BadMatch error from the X server.) + * A common cause of this problem is an attempt to draw a bitmap to + * a color drawable. The way to draw a bitmap is to set the bitmap as + * the stipple on the #GdkGC, set the fill mode to %GDK_STIPPLED, and + * then draw the rectangle. + * + * Deprecated: 2.22: Use gdk_cairo_set_source_pixmap(), cairo_rectangle() + * and cairo_fill() to draw pixmap on top of other drawables. Also keep + * in mind that the limitations on allowed sources do not apply to Cairo. + **/ +void +gdk_draw_drawable (GdkDrawable *drawable, + GdkGC *gc, + GdkDrawable *src, + gint xsrc, + gint ysrc, + gint xdest, + gint ydest, + gint width, + gint height) +{ + GdkDrawable *composite; + gint composite_x_offset = 0; + gint composite_y_offset = 0; + + g_return_if_fail (GDK_IS_DRAWABLE (drawable)); + g_return_if_fail (GDK_IS_DRAWABLE (src)); + g_return_if_fail (GDK_IS_GC (gc)); + + if (width < 0 || height < 0) + { + gint real_width; + gint real_height; + + gdk_drawable_get_size (src, &real_width, &real_height); + + if (width < 0) + width = real_width; + if (height < 0) + height = real_height; + } + + + composite = + GDK_DRAWABLE_GET_CLASS (src)->get_composite_drawable (src, + xsrc, ysrc, + width, height, + &composite_x_offset, + &composite_y_offset); + + /* TODO: For non-native windows this may copy stuff from other overlapping + windows. We should clip that and (for windows with bg != None) clear that + area in the destination instead. */ + + if (GDK_DRAWABLE_GET_CLASS (drawable)->draw_drawable_with_src) + GDK_DRAWABLE_GET_CLASS (drawable)->draw_drawable_with_src (drawable, gc, + composite, + xsrc - composite_x_offset, + ysrc - composite_y_offset, + xdest, ydest, + width, height, + src); + else /* backwards compat for old out-of-tree implementations of GdkDrawable (are there any?) */ + GDK_DRAWABLE_GET_CLASS (drawable)->draw_drawable (drawable, gc, + composite, + xsrc - composite_x_offset, + ysrc - composite_y_offset, + xdest, ydest, + width, height); + + g_object_unref (composite); +} + +/** + * gdk_draw_image: + * @drawable: a #GdkDrawable (a #GdkWindow or a #GdkPixmap). + * @gc: a #GdkGC. + * @image: the #GdkImage to draw. + * @xsrc: the left edge of the source rectangle within @image. + * @ysrc: the top of the source rectangle within @image. + * @xdest: the x coordinate of the destination within @drawable. + * @ydest: the y coordinate of the destination within @drawable. + * @width: the width of the area to be copied, or -1 to make the area + * extend to the right edge of @image. + * @height: the height of the area to be copied, or -1 to make the area + * extend to the bottom edge of @image. + * + * Draws a #GdkImage onto a drawable. + * The depth of the #GdkImage must match the depth of the #GdkDrawable. + * + * Deprecated: 2.22: Do not use #GdkImage anymore, instead use Cairo image + * surfaces. + **/ +void +gdk_draw_image (GdkDrawable *drawable, + GdkGC *gc, + GdkImage *image, + gint xsrc, + gint ysrc, + gint xdest, + gint ydest, + gint width, + gint height) +{ + g_return_if_fail (GDK_IS_DRAWABLE (drawable)); + g_return_if_fail (GDK_IS_IMAGE (image)); + g_return_if_fail (GDK_IS_GC (gc)); + + if (width == -1) + width = image->width; + if (height == -1) + height = image->height; + + GDK_DRAWABLE_GET_CLASS (drawable)->draw_image (drawable, gc, image, xsrc, ysrc, + xdest, ydest, width, height); +} + +/** + * gdk_draw_pixbuf: + * @drawable: Destination drawable. + * @gc: (allow-none): a #GdkGC, used for clipping, or %NULL + * @pixbuf: a #GdkPixbuf + * @src_x: Source X coordinate within pixbuf. + * @src_y: Source Y coordinates within pixbuf. + * @dest_x: Destination X coordinate within drawable. + * @dest_y: Destination Y coordinate within drawable. + * @width: Width of region to render, in pixels, or -1 to use pixbuf width. + * @height: Height of region to render, in pixels, or -1 to use pixbuf height. + * @dither: Dithering mode for #GdkRGB. + * @x_dither: X offset for dither. + * @y_dither: Y offset for dither. + * + * Renders a rectangular portion of a pixbuf to a drawable. The destination + * drawable must have a colormap. All windows have a colormap, however, pixmaps + * only have colormap by default if they were created with a non-%NULL window + * argument. Otherwise a colormap must be set on them with + * gdk_drawable_set_colormap(). + * + * On older X servers, rendering pixbufs with an alpha channel involves round + * trips to the X server, and may be somewhat slow. + * + * If GDK is built with the Sun mediaLib library, the gdk_draw_pixbuf + * function is accelerated using mediaLib, which provides hardware + * acceleration on Intel, AMD, and Sparc chipsets. If desired, mediaLib + * support can be turned off by setting the GDK_DISABLE_MEDIALIB environment + * variable. + * + * Since: 2.2 + * + * Deprecated: 2.22: Use gdk_cairo_set_source_pixbuf() and cairo_paint() or + * cairo_rectangle() and cairo_fill() instead. + **/ +void +gdk_draw_pixbuf (GdkDrawable *drawable, + GdkGC *gc, + const GdkPixbuf *pixbuf, + gint src_x, + gint src_y, + gint dest_x, + gint dest_y, + gint width, + gint height, + GdkRgbDither dither, + gint x_dither, + gint y_dither) +{ + g_return_if_fail (GDK_IS_DRAWABLE (drawable)); + g_return_if_fail (gc == NULL || GDK_IS_GC (gc)); + g_return_if_fail (GDK_IS_PIXBUF (pixbuf)); + + if (width == 0 || height == 0) + return; + + if (width == -1) + width = gdk_pixbuf_get_width (pixbuf); + if (height == -1) + height = gdk_pixbuf_get_height (pixbuf); + + GDK_DRAWABLE_GET_CLASS (drawable)->draw_pixbuf (drawable, gc, + (GdkPixbuf *) pixbuf, + src_x, src_y, dest_x, dest_y, + width, height, + dither, x_dither, y_dither); +} + +/** + * gdk_draw_points: + * @drawable: a #GdkDrawable (a #GdkWindow or a #GdkPixmap). + * @gc: a #GdkGC. + * @points: an array of #GdkPoint structures. + * @n_points: the number of points to be drawn. + * + * Draws a number of points, using the foreground color and other + * attributes of the #GdkGC. + * + * Deprecated: 2.22: Use @n_points calls to cairo_rectangle() and + * cairo_fill() instead. + **/ +void +gdk_draw_points (GdkDrawable *drawable, + GdkGC *gc, + const GdkPoint *points, + gint n_points) +{ + g_return_if_fail (GDK_IS_DRAWABLE (drawable)); + g_return_if_fail ((points != NULL) && (n_points > 0)); + g_return_if_fail (GDK_IS_GC (gc)); + g_return_if_fail (n_points >= 0); + + if (n_points == 0) + return; + + GDK_DRAWABLE_GET_CLASS (drawable)->draw_points (drawable, gc, + (GdkPoint *) points, n_points); +} + +/** + * gdk_draw_segments: + * @drawable: a #GdkDrawable (a #GdkWindow or a #GdkPixmap). + * @gc: a #GdkGC. + * @segs: an array of #GdkSegment structures specifying the start and + * end points of the lines to be drawn. + * @n_segs: the number of line segments to draw, i.e. the size of the + * @segs array. + * + * Draws a number of unconnected lines. + * + * Deprecated: 2.22: Use cairo_move_to(), cairo_line_to() and cairo_stroke() + * instead. See the documentation of gdk_draw_line() for notes on line drawing + * with Cairo. + **/ +void +gdk_draw_segments (GdkDrawable *drawable, + GdkGC *gc, + const GdkSegment *segs, + gint n_segs) +{ + g_return_if_fail (GDK_IS_DRAWABLE (drawable)); + + if (n_segs == 0) + return; + + g_return_if_fail (segs != NULL); + g_return_if_fail (GDK_IS_GC (gc)); + g_return_if_fail (n_segs >= 0); + + GDK_DRAWABLE_GET_CLASS (drawable)->draw_segments (drawable, gc, + (GdkSegment *) segs, n_segs); +} + +/** + * gdk_draw_lines: + * @drawable: a #GdkDrawable (a #GdkWindow or a #GdkPixmap). + * @gc: a #GdkGC. + * @points: an array of #GdkPoint structures specifying the endpoints of the + * @n_points: the size of the @points array. + * + * Draws a series of lines connecting the given points. + * The way in which joins between lines are draw is determined by the + * #GdkCapStyle value in the #GdkGC. This can be set with + * gdk_gc_set_line_attributes(). + * + * Deprecated: 2.22: Use cairo_line_to() and cairo_stroke() instead. See the + * documentation of gdk_draw_line() for notes on line drawing with Cairo. + **/ +void +gdk_draw_lines (GdkDrawable *drawable, + GdkGC *gc, + const GdkPoint *points, + gint n_points) +{ + g_return_if_fail (GDK_IS_DRAWABLE (drawable)); + g_return_if_fail (points != NULL); + g_return_if_fail (GDK_IS_GC (gc)); + g_return_if_fail (n_points >= 0); + + if (n_points == 0) + return; + + GDK_DRAWABLE_GET_CLASS (drawable)->draw_lines (drawable, gc, + (GdkPoint *) points, n_points); +} + +static void +real_draw_glyphs (GdkDrawable *drawable, + GdkGC *gc, + const PangoMatrix *matrix, + PangoFont *font, + gdouble x, + gdouble y, + PangoGlyphString *glyphs) +{ + cairo_t *cr; + + cr = gdk_cairo_create (drawable); + _gdk_gc_update_context (gc, cr, NULL, NULL, TRUE, drawable); + + if (matrix) + { + cairo_matrix_t cairo_matrix; + + cairo_matrix.xx = matrix->xx; + cairo_matrix.yx = matrix->yx; + cairo_matrix.xy = matrix->xy; + cairo_matrix.yy = matrix->yy; + cairo_matrix.x0 = matrix->x0; + cairo_matrix.y0 = matrix->y0; + + cairo_set_matrix (cr, &cairo_matrix); + } + + cairo_move_to (cr, x, y); + pango_cairo_show_glyph_string (cr, font, glyphs); + + cairo_destroy (cr); +} + +/** + * gdk_draw_glyphs: + * @drawable: a #GdkDrawable + * @gc: a #GdkGC + * @font: font to be used + * @x: X coordinate of baseline origin + * @y: Y coordinate of baseline origin + * @glyphs: the glyph string to draw + * + * This is a low-level function; 99% of text rendering should be done + * using gdk_draw_layout() instead. + * + * A glyph is a single image in a font. This function draws a sequence of + * glyphs. To obtain a sequence of glyphs you have to understand a + * lot about internationalized text handling, which you don't want to + * understand; thus, use gdk_draw_layout() instead of this function, + * gdk_draw_layout() handles the details. + * + * Deprecated: 2.22: Use pango_cairo_show_glyphs() instead. + **/ +void +gdk_draw_glyphs (GdkDrawable *drawable, + GdkGC *gc, + PangoFont *font, + gint x, + gint y, + PangoGlyphString *glyphs) +{ + g_return_if_fail (GDK_IS_DRAWABLE (drawable)); + g_return_if_fail (GDK_IS_GC (gc)); + + real_draw_glyphs (drawable, gc, NULL, font, + x, y, glyphs); +} + +/** + * gdk_draw_glyphs_transformed: + * @drawable: a #GdkDrawable + * @gc: a #GdkGC + * @matrix: (allow-none): a #PangoMatrix, or %NULL to use an identity transformation + * @font: the font in which to draw the string + * @x: the x position of the start of the string (in Pango + * units in user space coordinates) + * @y: the y position of the baseline (in Pango units + * in user space coordinates) + * @glyphs: the glyph string to draw + * + * Renders a #PangoGlyphString onto a drawable, possibly + * transforming the layed-out coordinates through a transformation + * matrix. Note that the transformation matrix for @font is not + * changed, so to produce correct rendering results, the @font + * must have been loaded using a #PangoContext with an identical + * transformation matrix to that passed in to this function. + * + * See also gdk_draw_glyphs(), gdk_draw_layout(). + * + * Since: 2.6 + * + * Deprecated: 2.22: Use pango_cairo_show_glyphs() instead. + **/ +void +gdk_draw_glyphs_transformed (GdkDrawable *drawable, + GdkGC *gc, + const PangoMatrix *matrix, + PangoFont *font, + gint x, + gint y, + PangoGlyphString *glyphs) +{ + g_return_if_fail (GDK_IS_DRAWABLE (drawable)); + g_return_if_fail (GDK_IS_GC (gc)); + + real_draw_glyphs (drawable, gc, matrix, font, + x / PANGO_SCALE, y / PANGO_SCALE, glyphs); +} + +/** + * gdk_draw_trapezoids: + * @drawable: a #GdkDrawable + * @gc: a #GdkGC + * @trapezoids: an array of #GdkTrapezoid structures + * @n_trapezoids: the number of trapezoids to draw + * + * Draws a set of anti-aliased trapezoids. The trapezoids are + * combined using saturation addition, then drawn over the background + * as a set. This is low level functionality used internally to implement + * rotated underlines and backgrouds when rendering a PangoLayout and is + * likely not useful for applications. + * + * Since: 2.6 + * + * Deprecated: 2.22: Use Cairo path contruction functions and cairo_fill() + * instead. + **/ +void +gdk_draw_trapezoids (GdkDrawable *drawable, + GdkGC *gc, + const GdkTrapezoid *trapezoids, + gint n_trapezoids) +{ + cairo_t *cr; + int i; + + g_return_if_fail (GDK_IS_DRAWABLE (drawable)); + g_return_if_fail (GDK_IS_GC (gc)); + g_return_if_fail (n_trapezoids == 0 || trapezoids != NULL); + + cr = gdk_cairo_create (drawable); + _gdk_gc_update_context (gc, cr, NULL, NULL, TRUE, drawable); + + for (i = 0; i < n_trapezoids; i++) + { + cairo_move_to (cr, trapezoids[i].x11, trapezoids[i].y1); + cairo_line_to (cr, trapezoids[i].x21, trapezoids[i].y1); + cairo_line_to (cr, trapezoids[i].x22, trapezoids[i].y2); + cairo_line_to (cr, trapezoids[i].x12, trapezoids[i].y2); + cairo_close_path (cr); + } + + cairo_fill (cr); + + cairo_destroy (cr); +} + +/** + * gdk_drawable_copy_to_image: + * @drawable: a #GdkDrawable + * @image: (allow-none): a #GdkDrawable, or %NULL if a new @image should be created. + * @src_x: x coordinate on @drawable + * @src_y: y coordinate on @drawable + * @dest_x: x coordinate within @image. Must be 0 if @image is %NULL + * @dest_y: y coordinate within @image. Must be 0 if @image is %NULL + * @width: width of region to get + * @height: height or region to get + * + * Copies a portion of @drawable into the client side image structure + * @image. If @image is %NULL, creates a new image of size @width x @height + * and copies into that. See gdk_drawable_get_image() for further details. + * + * Return value: @image, or a new a #GdkImage containing the contents + * of @drawable + * + * Since: 2.4 + * + * Deprecated: 2.22: Use @drawable as the source and draw to a Cairo image + * surface if you want to download contents to the client. + **/ +GdkImage* +gdk_drawable_copy_to_image (GdkDrawable *drawable, + GdkImage *image, + gint src_x, + gint src_y, + gint dest_x, + gint dest_y, + gint width, + gint height) +{ + GdkDrawable *composite; + gint composite_x_offset = 0; + gint composite_y_offset = 0; + GdkImage *retval; + GdkColormap *cmap; + + g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL); + g_return_val_if_fail (src_x >= 0, NULL); + g_return_val_if_fail (src_y >= 0, NULL); + + /* FIXME? Note race condition since we get the size then + * get the image, and the size may have changed. + */ + + if (width < 0 || height < 0) + gdk_drawable_get_size (drawable, + width < 0 ? &width : NULL, + height < 0 ? &height : NULL); + + composite = + GDK_DRAWABLE_GET_CLASS (drawable)->get_composite_drawable (drawable, + src_x, src_y, + width, height, + &composite_x_offset, + &composite_y_offset); + + retval = GDK_DRAWABLE_GET_CLASS (composite)->_copy_to_image (composite, + image, + src_x - composite_x_offset, + src_y - composite_y_offset, + dest_x, dest_y, + width, height); + + g_object_unref (composite); + + if (!image && retval) + { + cmap = gdk_drawable_get_colormap (drawable); + + if (cmap) + gdk_image_set_colormap (retval, cmap); + } + + return retval; +} + +/** + * gdk_drawable_get_image: + * @drawable: a #GdkDrawable + * @x: x coordinate on @drawable + * @y: y coordinate on @drawable + * @width: width of region to get + * @height: height or region to get + * + * A #GdkImage stores client-side image data (pixels). In contrast, + * #GdkPixmap and #GdkWindow are server-side + * objects. gdk_drawable_get_image() obtains the pixels from a + * server-side drawable as a client-side #GdkImage. The format of a + * #GdkImage depends on the #GdkVisual of the current display, which + * makes manipulating #GdkImage extremely difficult; therefore, in + * most cases you should use gdk_pixbuf_get_from_drawable() instead of + * this lower-level function. A #GdkPixbuf contains image data in a + * canonicalized RGB format, rather than a display-dependent format. + * Of course, there's a convenience vs. speed tradeoff here, so you'll + * want to think about what makes sense for your application. + * + * @x, @y, @width, and @height define the region of @drawable to + * obtain as an image. + * + * You would usually copy image data to the client side if you intend + * to examine the values of individual pixels, for example to darken + * an image or add a red tint. It would be prohibitively slow to + * make a round-trip request to the windowing system for each pixel, + * so instead you get all of them at once, modify them, then copy + * them all back at once. + * + * If the X server or other windowing system backend is on the local + * machine, this function may use shared memory to avoid copying + * the image data. + * + * If the source drawable is a #GdkWindow and partially offscreen + * or obscured, then the obscured portions of the returned image + * will contain undefined data. + * + * Return value: a #GdkImage containing the contents of @drawable + * + * Deprecated: 2.22: Use @drawable as the source and draw to a Cairo image + * surface if you want to download contents to the client. + **/ +GdkImage* +gdk_drawable_get_image (GdkDrawable *drawable, + gint x, + gint y, + gint width, + gint height) +{ + GdkDrawable *composite; + gint composite_x_offset = 0; + gint composite_y_offset = 0; + GdkImage *retval; + GdkColormap *cmap; + + g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL); + g_return_val_if_fail (x >= 0, NULL); + g_return_val_if_fail (y >= 0, NULL); + + /* FIXME? Note race condition since we get the size then + * get the image, and the size may have changed. + */ + + if (width < 0 || height < 0) + gdk_drawable_get_size (drawable, + width < 0 ? &width : NULL, + height < 0 ? &height : NULL); + + composite = + GDK_DRAWABLE_GET_CLASS (drawable)->get_composite_drawable (drawable, + x, y, + width, height, + &composite_x_offset, + &composite_y_offset); + + retval = GDK_DRAWABLE_GET_CLASS (composite)->get_image (composite, + x - composite_x_offset, + y - composite_y_offset, + width, height); + + g_object_unref (composite); + + cmap = gdk_drawable_get_colormap (drawable); + + if (retval && cmap) + gdk_image_set_colormap (retval, cmap); + + return retval; +} + +static GdkImage* +gdk_drawable_real_get_image (GdkDrawable *drawable, + gint x, + gint y, + gint width, + gint height) +{ + return gdk_drawable_copy_to_image (drawable, NULL, x, y, 0, 0, width, height); +} + +static GdkDrawable * +gdk_drawable_real_get_composite_drawable (GdkDrawable *drawable, + gint x, + gint y, + gint width, + gint height, + gint *composite_x_offset, + gint *composite_y_offset) +{ + g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL); + + *composite_x_offset = 0; + *composite_y_offset = 0; + + return g_object_ref (drawable); +} + +/** + * gdk_drawable_get_clip_region: + * @drawable: a #GdkDrawable + * + * Computes the region of a drawable that potentially can be written + * to by drawing primitives. This region will not take into account + * the clip region for the GC, and may also not take into account + * other factors such as if the window is obscured by other windows, + * but no area outside of this region will be affected by drawing + * primitives. + * + * Returns: a #GdkRegion. This must be freed with gdk_region_destroy() + * when you are done. + **/ +GdkRegion * +gdk_drawable_get_clip_region (GdkDrawable *drawable) +{ + g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL); + + return GDK_DRAWABLE_GET_CLASS (drawable)->get_clip_region (drawable); +} + +/** + * gdk_drawable_get_visible_region: + * @drawable: a #GdkDrawable + * + * Computes the region of a drawable that is potentially visible. + * This does not necessarily take into account if the window is + * obscured by other windows, but no area outside of this region + * is visible. + * + * Returns: a #GdkRegion. This must be freed with gdk_region_destroy() + * when you are done. + **/ +GdkRegion * +gdk_drawable_get_visible_region (GdkDrawable *drawable) +{ + g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL); + + return GDK_DRAWABLE_GET_CLASS (drawable)->get_visible_region (drawable); +} + +static GdkRegion * +gdk_drawable_real_get_visible_region (GdkDrawable *drawable) +{ + GdkRectangle rect; + + rect.x = 0; + rect.y = 0; + + gdk_drawable_get_size (drawable, &rect.width, &rect.height); + + return gdk_region_rectangle (&rect); +} + +/** + * _gdk_drawable_ref_cairo_surface: + * @drawable: a #GdkDrawable + * + * Obtains a #cairo_surface_t for the given drawable. If a + * #cairo_surface_t for the drawable already exists, it will be + * referenced, otherwise a new surface will be created. + * + * Return value: a newly referenced #cairo_surface_t that points + * to @drawable. Unref with cairo_surface_destroy() + **/ +cairo_surface_t * +_gdk_drawable_ref_cairo_surface (GdkDrawable *drawable) +{ + g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL); + + return GDK_DRAWABLE_GET_CLASS (drawable)->ref_cairo_surface (drawable); +} + +static void +composite (guchar *src_buf, + gint src_rowstride, + guchar *dest_buf, + gint dest_rowstride, + gint width, + gint height) +{ + guchar *src = src_buf; + guchar *dest = dest_buf; + + while (height--) + { + gint twidth = width; + guchar *p = src; + guchar *q = dest; + + while (twidth--) + { + guchar a = p[3]; + guint t; + + t = a * p[0] + (255 - a) * q[0] + 0x80; + q[0] = (t + (t >> 8)) >> 8; + t = a * p[1] + (255 - a) * q[1] + 0x80; + q[1] = (t + (t >> 8)) >> 8; + t = a * p[2] + (255 - a) * q[2] + 0x80; + q[2] = (t + (t >> 8)) >> 8; + + p += 4; + q += 3; + } + + src += src_rowstride; + dest += dest_rowstride; + } +} + +static void +composite_0888 (guchar *src_buf, + gint src_rowstride, + guchar *dest_buf, + gint dest_rowstride, + GdkByteOrder dest_byte_order, + gint width, + gint height) +{ + guchar *src = src_buf; + guchar *dest = dest_buf; + + while (height--) + { + gint twidth = width; + guchar *p = src; + guchar *q = dest; + + if (dest_byte_order == GDK_LSB_FIRST) + { + while (twidth--) + { + guint t; + + t = p[3] * p[2] + (255 - p[3]) * q[0] + 0x80; + q[0] = (t + (t >> 8)) >> 8; + t = p[3] * p[1] + (255 - p[3]) * q[1] + 0x80; + q[1] = (t + (t >> 8)) >> 8; + t = p[3] * p[0] + (255 - p[3]) * q[2] + 0x80; + q[2] = (t + (t >> 8)) >> 8; + p += 4; + q += 4; + } + } + else + { + while (twidth--) + { + guint t; + + t = p[3] * p[0] + (255 - p[3]) * q[1] + 0x80; + q[1] = (t + (t >> 8)) >> 8; + t = p[3] * p[1] + (255 - p[3]) * q[2] + 0x80; + q[2] = (t + (t >> 8)) >> 8; + t = p[3] * p[2] + (255 - p[3]) * q[3] + 0x80; + q[3] = (t + (t >> 8)) >> 8; + p += 4; + q += 4; + } + } + + src += src_rowstride; + dest += dest_rowstride; + } +} + +#ifdef USE_MEDIALIB +static void +composite_0888_medialib (guchar *src_buf, + gint src_rowstride, + guchar *dest_buf, + gint dest_rowstride, + GdkByteOrder dest_byte_order, + gint width, + gint height) +{ + guchar *src = src_buf; + guchar *dest = dest_buf; + + mlib_image img_src, img_dst; + + mlib_ImageSetStruct (&img_dst, + MLIB_BYTE, + 4, + width, + height, + dest_rowstride, + dest_buf); + + mlib_ImageSetStruct (&img_src, + MLIB_BYTE, + 4, + width, + height, + src_rowstride, + src_buf); + + if (dest_byte_order == GDK_LSB_FIRST) + mlib_ImageBlendRGBA2BGRA (&img_dst, &img_src); + else + mlib_ImageBlendRGBA2ARGB (&img_dst, &img_src); +} +#endif + +static void +composite_565 (guchar *src_buf, + gint src_rowstride, + guchar *dest_buf, + gint dest_rowstride, + GdkByteOrder dest_byte_order, + gint width, + gint height) +{ + guchar *src = src_buf; + guchar *dest = dest_buf; + + while (height--) + { + gint twidth = width; + guchar *p = src; + gushort *q = (gushort *)dest; + + while (twidth--) + { + guchar a = p[3]; + guint tr, tg, tb; + guint tr1, tg1, tb1; + guint tmp = *q; + +#if 1 + /* This is fast, and corresponds to what composite() above does + * if we converted to 8-bit first. + */ + tr = (tmp & 0xf800); + tr1 = a * p[0] + (255 - a) * ((tr >> 8) + (tr >> 13)) + 0x80; + tg = (tmp & 0x07e0); + tg1 = a * p[1] + (255 - a) * ((tg >> 3) + (tg >> 9)) + 0x80; + tb = (tmp & 0x001f); + tb1 = a * p[2] + (255 - a) * ((tb << 3) + (tb >> 2)) + 0x80; + + *q = (((tr1 + (tr1 >> 8)) & 0xf800) | + (((tg1 + (tg1 >> 8)) & 0xfc00) >> 5) | + ((tb1 + (tb1 >> 8)) >> 11)); +#else + /* This version correspond to the result we get with XRENDER - + * a bit of precision is lost since we convert to 8 bit after premultiplying + * instead of at the end + */ + guint tr2, tg2, tb2; + guint tr3, tg3, tb3; + + tr = (tmp & 0xf800); + tr1 = (255 - a) * ((tr >> 8) + (tr >> 13)) + 0x80; + tr2 = a * p[0] + 0x80; + tr3 = ((tr1 + (tr1 >> 8)) >> 8) + ((tr2 + (tr2 >> 8)) >> 8); + + tg = (tmp & 0x07e0); + tg1 = (255 - a) * ((tg >> 3) + (tg >> 9)) + 0x80; + tg2 = a * p[0] + 0x80; + tg3 = ((tg1 + (tg1 >> 8)) >> 8) + ((tg2 + (tg2 >> 8)) >> 8); + + tb = (tmp & 0x001f); + tb1 = (255 - a) * ((tb << 3) + (tb >> 2)) + 0x80; + tb2 = a * p[0] + 0x80; + tb3 = ((tb1 + (tb1 >> 8)) >> 8) + ((tb2 + (tb2 >> 8)) >> 8); + + *q = (((tr3 & 0xf8) << 8) | + ((tg3 & 0xfc) << 3) | + ((tb3 >> 3))); +#endif + + p += 4; + q++; + } + + src += src_rowstride; + dest += dest_rowstride; + } +} + +/* Implementation of the old vfunc in terms of the new one + in case someone calls it directly (which they shouldn't!) */ +static void +gdk_drawable_real_draw_drawable (GdkDrawable *drawable, + GdkGC *gc, + GdkDrawable *src, + gint xsrc, + gint ysrc, + gint xdest, + gint ydest, + gint width, + gint height) +{ + GDK_DRAWABLE_GET_CLASS (drawable)->draw_drawable_with_src (drawable, + gc, + src, + xsrc, + ysrc, + xdest, + ydest, + width, + height, + src); +} + +static void +gdk_drawable_real_draw_pixbuf (GdkDrawable *drawable, + GdkGC *gc, + GdkPixbuf *pixbuf, + gint src_x, + gint src_y, + gint dest_x, + gint dest_y, + gint width, + gint height, + GdkRgbDither dither, + gint x_dither, + gint y_dither) +{ + GdkPixbuf *composited = NULL; + gint dwidth, dheight; + GdkRegion *clip; + GdkRegion *drect; + GdkRectangle tmp_rect; + GdkDrawable *real_drawable; + + g_return_if_fail (GDK_IS_PIXBUF (pixbuf)); + g_return_if_fail (gdk_pixbuf_get_colorspace (pixbuf) == GDK_COLORSPACE_RGB); + g_return_if_fail (gdk_pixbuf_get_n_channels (pixbuf) == 3 || + gdk_pixbuf_get_n_channels (pixbuf) == 4); + g_return_if_fail (gdk_pixbuf_get_bits_per_sample (pixbuf) == 8); + + g_return_if_fail (drawable != NULL); + + if (width == -1) + width = gdk_pixbuf_get_width (pixbuf); + if (height == -1) + height = gdk_pixbuf_get_height (pixbuf); + + g_return_if_fail (width >= 0 && height >= 0); + g_return_if_fail (src_x >= 0 && src_x + width <= gdk_pixbuf_get_width (pixbuf)); + g_return_if_fail (src_y >= 0 && src_y + height <= gdk_pixbuf_get_height (pixbuf)); + + /* Clip to the drawable; this is required for get_from_drawable() so + * can't be done implicitly + */ + + if (dest_x < 0) + { + src_x -= dest_x; + width += dest_x; + dest_x = 0; + } + + if (dest_y < 0) + { + src_y -= dest_y; + height += dest_y; + dest_y = 0; + } + + gdk_drawable_get_size (drawable, &dwidth, &dheight); + + if ((dest_x + width) > dwidth) + width = dwidth - dest_x; + + if ((dest_y + height) > dheight) + height = dheight - dest_y; + + if (width <= 0 || height <= 0) + return; + + /* Clip to the clip region; this avoids getting more + * image data from the server than we need to. + */ + + tmp_rect.x = dest_x; + tmp_rect.y = dest_y; + tmp_rect.width = width; + tmp_rect.height = height; + + drect = gdk_region_rectangle (&tmp_rect); + clip = gdk_drawable_get_clip_region (drawable); + + gdk_region_intersect (drect, clip); + + gdk_region_get_clipbox (drect, &tmp_rect); + + gdk_region_destroy (drect); + gdk_region_destroy (clip); + + if (tmp_rect.width == 0 || + tmp_rect.height == 0) + return; + + /* Actually draw */ + if (!gc) + gc = _gdk_drawable_get_scratch_gc (drawable, FALSE); + + /* Drawable is a wrapper here, but at this time we + have already retargeted the destination to any + impl window and set the clip, so what we really + want to do is draw directly on the impl, ignoring + client side subwindows. We also use the impl + in the pixmap target case to avoid resetting the + already set clip on the GC. */ + if (GDK_IS_WINDOW (drawable)) + real_drawable = GDK_WINDOW_OBJECT (drawable)->impl; + else + real_drawable = GDK_PIXMAP_OBJECT (drawable)->impl; + + if (gdk_pixbuf_get_has_alpha (pixbuf)) + { + GdkVisual *visual = gdk_drawable_get_visual (drawable); + void (*composite_func) (guchar *src_buf, + gint src_rowstride, + guchar *dest_buf, + gint dest_rowstride, + GdkByteOrder dest_byte_order, + gint width, + gint height) = NULL; + + /* First we see if we have a visual-specific composition function that can composite + * the pixbuf data directly onto the image + */ + if (visual) + { + gint bits_per_pixel = _gdk_windowing_get_bits_for_depth (gdk_drawable_get_display (drawable), + visual->depth); + + if (visual->byte_order == (G_BYTE_ORDER == G_BIG_ENDIAN ? GDK_MSB_FIRST : GDK_LSB_FIRST) && + visual->depth == 16 && + visual->red_mask == 0xf800 && + visual->green_mask == 0x07e0 && + visual->blue_mask == 0x001f) + composite_func = composite_565; + else if (visual->depth == 24 && bits_per_pixel == 32 && + visual->red_mask == 0xff0000 && + visual->green_mask == 0x00ff00 && + visual->blue_mask == 0x0000ff) + { +#ifdef USE_MEDIALIB + if (_gdk_use_medialib ()) + composite_func = composite_0888_medialib; + else + composite_func = composite_0888; +#else + composite_func = composite_0888; +#endif + } + } + + /* We can't use our composite func if we are required to dither + */ + if (composite_func && !(dither == GDK_RGB_DITHER_MAX && visual->depth != 24)) + { + gint x0, y0; + for (y0 = 0; y0 < height; y0 += GDK_SCRATCH_IMAGE_HEIGHT) + { + gint height1 = MIN (height - y0, GDK_SCRATCH_IMAGE_HEIGHT); + for (x0 = 0; x0 < width; x0 += GDK_SCRATCH_IMAGE_WIDTH) + { + gint xs0, ys0; + + gint width1 = MIN (width - x0, GDK_SCRATCH_IMAGE_WIDTH); + + GdkImage *image = _gdk_image_get_scratch (gdk_drawable_get_screen (drawable), + width1, height1, + gdk_drawable_get_depth (drawable), &xs0, &ys0); + + gdk_drawable_copy_to_image (drawable, image, + dest_x + x0, dest_y + y0, + xs0, ys0, + width1, height1); + (*composite_func) (gdk_pixbuf_get_pixels (pixbuf) + (src_y + y0) * gdk_pixbuf_get_rowstride (pixbuf) + (src_x + x0) * 4, + gdk_pixbuf_get_rowstride (pixbuf), + (guchar*)image->mem + ys0 * image->bpl + xs0 * image->bpp, + image->bpl, + visual->byte_order, + width1, height1); + gdk_draw_image (real_drawable, gc, image, + xs0, ys0, + dest_x + x0, dest_y + y0, + width1, height1); + } + } + + goto out; + } + else + { + /* No special composition func, convert dest to 24 bit RGB data, composite against + * that, and convert back. + */ + composited = gdk_pixbuf_get_from_drawable (NULL, + drawable, + NULL, + dest_x, dest_y, + 0, 0, + width, height); + + if (composited) + composite (gdk_pixbuf_get_pixels (pixbuf) + src_y * gdk_pixbuf_get_rowstride (pixbuf) + src_x * 4, + gdk_pixbuf_get_rowstride (pixbuf), + gdk_pixbuf_get_pixels (composited), + gdk_pixbuf_get_rowstride (composited), + width, height); + } + } + + if (composited) + { + src_x = 0; + src_y = 0; + pixbuf = composited; + } + + if (gdk_pixbuf_get_n_channels (pixbuf) == 4) + { + guchar *buf = gdk_pixbuf_get_pixels (pixbuf) + src_y * gdk_pixbuf_get_rowstride (pixbuf) + src_x * 4; + + gdk_draw_rgb_32_image_dithalign (real_drawable, gc, + dest_x, dest_y, + width, height, + dither, + buf, gdk_pixbuf_get_rowstride (pixbuf), + x_dither, y_dither); + } + else /* n_channels == 3 */ + { + guchar *buf = gdk_pixbuf_get_pixels (pixbuf) + src_y * gdk_pixbuf_get_rowstride (pixbuf) + src_x * 3; + + gdk_draw_rgb_image_dithalign (real_drawable, gc, + dest_x, dest_y, + width, height, + dither, + buf, gdk_pixbuf_get_rowstride (pixbuf), + x_dither, y_dither); + } + + out: + if (composited) + g_object_unref (composited); +} + +/************************************************************************/ + +/** + * _gdk_drawable_get_scratch_gc: + * @drawable: A #GdkDrawable + * @graphics_exposures: Whether the returned #GdkGC should generate graphics exposures + * + * Returns a #GdkGC suitable for drawing on @drawable. The #GdkGC has + * the standard values for @drawable, except for the graphics_exposures + * field which is determined by the @graphics_exposures parameter. + * + * The foreground color of the returned #GdkGC is undefined. The #GdkGC + * must not be altered in any way, except to change its foreground color. + * + * Return value: A #GdkGC suitable for drawing on @drawable + * + * Since: 2.4 + **/ +GdkGC * +_gdk_drawable_get_scratch_gc (GdkDrawable *drawable, + gboolean graphics_exposures) +{ + GdkScreen *screen; + gint depth; + + g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL); + + screen = gdk_drawable_get_screen (drawable); + + g_return_val_if_fail (!screen->closed, NULL); + + depth = gdk_drawable_get_depth (drawable) - 1; + + if (graphics_exposures) + { + if (!screen->exposure_gcs[depth]) + { + GdkGCValues values; + GdkGCValuesMask mask; + + values.graphics_exposures = TRUE; + mask = GDK_GC_EXPOSURES; + + screen->exposure_gcs[depth] = + gdk_gc_new_with_values (drawable, &values, mask); + } + + return screen->exposure_gcs[depth]; + } + else + { + if (!screen->normal_gcs[depth]) + { + screen->normal_gcs[depth] = + gdk_gc_new (drawable); + } + + return screen->normal_gcs[depth]; + } +} + +/** + * _gdk_drawable_get_subwindow_scratch_gc: + * @drawable: A #GdkDrawable + * + * Returns a #GdkGC suitable for drawing on @drawable. The #GdkGC has + * the standard values for @drawable, except for the graphics_exposures + * field which is %TRUE and the subwindow mode which is %GDK_INCLUDE_INFERIORS. + * + * The foreground color of the returned #GdkGC is undefined. The #GdkGC + * must not be altered in any way, except to change its foreground color. + * + * Return value: A #GdkGC suitable for drawing on @drawable + * + * Since: 2.18 + **/ +GdkGC * +_gdk_drawable_get_subwindow_scratch_gc (GdkDrawable *drawable) +{ + GdkScreen *screen; + gint depth; + + g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL); + + screen = gdk_drawable_get_screen (drawable); + + g_return_val_if_fail (!screen->closed, NULL); + + depth = gdk_drawable_get_depth (drawable) - 1; + + if (!screen->subwindow_gcs[depth]) + { + GdkGCValues values; + GdkGCValuesMask mask; + + values.graphics_exposures = TRUE; + values.subwindow_mode = GDK_INCLUDE_INFERIORS; + mask = GDK_GC_EXPOSURES | GDK_GC_SUBWINDOW; + + screen->subwindow_gcs[depth] = + gdk_gc_new_with_values (drawable, &values, mask); + } + + return screen->subwindow_gcs[depth]; +} + + +/* + * _gdk_drawable_get_source_drawable: + * @drawable: a #GdkDrawable + * + * Returns a drawable for the passed @drawable that is guaranteed to be + * usable to create a pixmap (e.g.: not an offscreen window). + * + * Since: 2.16 + */ +GdkDrawable * +_gdk_drawable_get_source_drawable (GdkDrawable *drawable) +{ + g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL); + + if (GDK_DRAWABLE_GET_CLASS (drawable)->get_source_drawable) + return GDK_DRAWABLE_GET_CLASS (drawable)->get_source_drawable (drawable); + + return drawable; +} + +cairo_surface_t * +_gdk_drawable_create_cairo_surface (GdkDrawable *drawable, + int width, + int height) +{ + return GDK_DRAWABLE_GET_CLASS (drawable)->create_cairo_surface (drawable, + width, height); +} + + +#define __GDK_DRAW_C__ +#include "gdkaliasdef.c" diff --git a/libs/tk/ydk/gdkenumtypes.c b/libs/tk/ydk/gdkenumtypes.c new file mode 100644 index 0000000000..3309edcde8 --- /dev/null +++ b/libs/tk/ydk/gdkenumtypes.c @@ -0,0 +1,962 @@ + +/* This file is generated by glib-mkenums, do not modify it. This code is licensed under the same license as the containing project. Note that it links to GLib, so must comply with the LGPL linking clauses. */ + +#define GDK_ENABLE_BROKEN +#include "gdk.h" +#include "gdkalias.h" +/* enumerations from "gdkcursor.h" */ +GType +gdk_cursor_type_get_type (void) +{ + static GType etype = 0; + if (G_UNLIKELY(etype == 0)) { + static const GEnumValue values[] = { + { GDK_X_CURSOR, "GDK_X_CURSOR", "x-cursor" }, + { GDK_ARROW, "GDK_ARROW", "arrow" }, + { GDK_BASED_ARROW_DOWN, "GDK_BASED_ARROW_DOWN", "based-arrow-down" }, + { GDK_BASED_ARROW_UP, "GDK_BASED_ARROW_UP", "based-arrow-up" }, + { GDK_BOAT, "GDK_BOAT", "boat" }, + { GDK_BOGOSITY, "GDK_BOGOSITY", "bogosity" }, + { GDK_BOTTOM_LEFT_CORNER, "GDK_BOTTOM_LEFT_CORNER", "bottom-left-corner" }, + { GDK_BOTTOM_RIGHT_CORNER, "GDK_BOTTOM_RIGHT_CORNER", "bottom-right-corner" }, + { GDK_BOTTOM_SIDE, "GDK_BOTTOM_SIDE", "bottom-side" }, + { GDK_BOTTOM_TEE, "GDK_BOTTOM_TEE", "bottom-tee" }, + { GDK_BOX_SPIRAL, "GDK_BOX_SPIRAL", "box-spiral" }, + { GDK_CENTER_PTR, "GDK_CENTER_PTR", "center-ptr" }, + { GDK_CIRCLE, "GDK_CIRCLE", "circle" }, + { GDK_CLOCK, "GDK_CLOCK", "clock" }, + { GDK_COFFEE_MUG, "GDK_COFFEE_MUG", "coffee-mug" }, + { GDK_CROSS, "GDK_CROSS", "cross" }, + { GDK_CROSS_REVERSE, "GDK_CROSS_REVERSE", "cross-reverse" }, + { GDK_CROSSHAIR, "GDK_CROSSHAIR", "crosshair" }, + { GDK_DIAMOND_CROSS, "GDK_DIAMOND_CROSS", "diamond-cross" }, + { GDK_DOT, "GDK_DOT", "dot" }, + { GDK_DOTBOX, "GDK_DOTBOX", "dotbox" }, + { GDK_DOUBLE_ARROW, "GDK_DOUBLE_ARROW", "double-arrow" }, + { GDK_DRAFT_LARGE, "GDK_DRAFT_LARGE", "draft-large" }, + { GDK_DRAFT_SMALL, "GDK_DRAFT_SMALL", "draft-small" }, + { GDK_DRAPED_BOX, "GDK_DRAPED_BOX", "draped-box" }, + { GDK_EXCHANGE, "GDK_EXCHANGE", "exchange" }, + { GDK_FLEUR, "GDK_FLEUR", "fleur" }, + { GDK_GOBBLER, "GDK_GOBBLER", "gobbler" }, + { GDK_GUMBY, "GDK_GUMBY", "gumby" }, + { GDK_HAND1, "GDK_HAND1", "hand1" }, + { GDK_HAND2, "GDK_HAND2", "hand2" }, + { GDK_HEART, "GDK_HEART", "heart" }, + { GDK_ICON, "GDK_ICON", "icon" }, + { GDK_IRON_CROSS, "GDK_IRON_CROSS", "iron-cross" }, + { GDK_LEFT_PTR, "GDK_LEFT_PTR", "left-ptr" }, + { GDK_LEFT_SIDE, "GDK_LEFT_SIDE", "left-side" }, + { GDK_LEFT_TEE, "GDK_LEFT_TEE", "left-tee" }, + { GDK_LEFTBUTTON, "GDK_LEFTBUTTON", "leftbutton" }, + { GDK_LL_ANGLE, "GDK_LL_ANGLE", "ll-angle" }, + { GDK_LR_ANGLE, "GDK_LR_ANGLE", "lr-angle" }, + { GDK_MAN, "GDK_MAN", "man" }, + { GDK_MIDDLEBUTTON, "GDK_MIDDLEBUTTON", "middlebutton" }, + { GDK_MOUSE, "GDK_MOUSE", "mouse" }, + { GDK_PENCIL, "GDK_PENCIL", "pencil" }, + { GDK_PIRATE, "GDK_PIRATE", "pirate" }, + { GDK_PLUS, "GDK_PLUS", "plus" }, + { GDK_QUESTION_ARROW, "GDK_QUESTION_ARROW", "question-arrow" }, + { GDK_RIGHT_PTR, "GDK_RIGHT_PTR", "right-ptr" }, + { GDK_RIGHT_SIDE, "GDK_RIGHT_SIDE", "right-side" }, + { GDK_RIGHT_TEE, "GDK_RIGHT_TEE", "right-tee" }, + { GDK_RIGHTBUTTON, "GDK_RIGHTBUTTON", "rightbutton" }, + { GDK_RTL_LOGO, "GDK_RTL_LOGO", "rtl-logo" }, + { GDK_SAILBOAT, "GDK_SAILBOAT", "sailboat" }, + { GDK_SB_DOWN_ARROW, "GDK_SB_DOWN_ARROW", "sb-down-arrow" }, + { GDK_SB_H_DOUBLE_ARROW, "GDK_SB_H_DOUBLE_ARROW", "sb-h-double-arrow" }, + { GDK_SB_LEFT_ARROW, "GDK_SB_LEFT_ARROW", "sb-left-arrow" }, + { GDK_SB_RIGHT_ARROW, "GDK_SB_RIGHT_ARROW", "sb-right-arrow" }, + { GDK_SB_UP_ARROW, "GDK_SB_UP_ARROW", "sb-up-arrow" }, + { GDK_SB_V_DOUBLE_ARROW, "GDK_SB_V_DOUBLE_ARROW", "sb-v-double-arrow" }, + { GDK_SHUTTLE, "GDK_SHUTTLE", "shuttle" }, + { GDK_SIZING, "GDK_SIZING", "sizing" }, + { GDK_SPIDER, "GDK_SPIDER", "spider" }, + { GDK_SPRAYCAN, "GDK_SPRAYCAN", "spraycan" }, + { GDK_STAR, "GDK_STAR", "star" }, + { GDK_TARGET, "GDK_TARGET", "target" }, + { GDK_TCROSS, "GDK_TCROSS", "tcross" }, + { GDK_TOP_LEFT_ARROW, "GDK_TOP_LEFT_ARROW", "top-left-arrow" }, + { GDK_TOP_LEFT_CORNER, "GDK_TOP_LEFT_CORNER", "top-left-corner" }, + { GDK_TOP_RIGHT_CORNER, "GDK_TOP_RIGHT_CORNER", "top-right-corner" }, + { GDK_TOP_SIDE, "GDK_TOP_SIDE", "top-side" }, + { GDK_TOP_TEE, "GDK_TOP_TEE", "top-tee" }, + { GDK_TREK, "GDK_TREK", "trek" }, + { GDK_UL_ANGLE, "GDK_UL_ANGLE", "ul-angle" }, + { GDK_UMBRELLA, "GDK_UMBRELLA", "umbrella" }, + { GDK_UR_ANGLE, "GDK_UR_ANGLE", "ur-angle" }, + { GDK_WATCH, "GDK_WATCH", "watch" }, + { GDK_XTERM, "GDK_XTERM", "xterm" }, + { GDK_LAST_CURSOR, "GDK_LAST_CURSOR", "last-cursor" }, + { GDK_BLANK_CURSOR, "GDK_BLANK_CURSOR", "blank-cursor" }, + { GDK_CURSOR_IS_PIXMAP, "GDK_CURSOR_IS_PIXMAP", "cursor-is-pixmap" }, + { 0, NULL, NULL } + }; + etype = g_enum_register_static (g_intern_static_string ("GdkCursorType"), values); + } + return etype; +} +/* enumerations from "gdkdnd.h" */ +GType +gdk_drag_action_get_type (void) +{ + static GType etype = 0; + if (G_UNLIKELY(etype == 0)) { + static const GFlagsValue values[] = { + { GDK_ACTION_DEFAULT, "GDK_ACTION_DEFAULT", "default" }, + { GDK_ACTION_COPY, "GDK_ACTION_COPY", "copy" }, + { GDK_ACTION_MOVE, "GDK_ACTION_MOVE", "move" }, + { GDK_ACTION_LINK, "GDK_ACTION_LINK", "link" }, + { GDK_ACTION_PRIVATE, "GDK_ACTION_PRIVATE", "private" }, + { GDK_ACTION_ASK, "GDK_ACTION_ASK", "ask" }, + { 0, NULL, NULL } + }; + etype = g_flags_register_static (g_intern_static_string ("GdkDragAction"), values); + } + return etype; +} +GType +gdk_drag_protocol_get_type (void) +{ + static GType etype = 0; + if (G_UNLIKELY(etype == 0)) { + static const GEnumValue values[] = { + { GDK_DRAG_PROTO_MOTIF, "GDK_DRAG_PROTO_MOTIF", "motif" }, + { GDK_DRAG_PROTO_XDND, "GDK_DRAG_PROTO_XDND", "xdnd" }, + { GDK_DRAG_PROTO_ROOTWIN, "GDK_DRAG_PROTO_ROOTWIN", "rootwin" }, + { GDK_DRAG_PROTO_NONE, "GDK_DRAG_PROTO_NONE", "none" }, + { GDK_DRAG_PROTO_WIN32_DROPFILES, "GDK_DRAG_PROTO_WIN32_DROPFILES", "win32-dropfiles" }, + { GDK_DRAG_PROTO_OLE2, "GDK_DRAG_PROTO_OLE2", "ole2" }, + { GDK_DRAG_PROTO_LOCAL, "GDK_DRAG_PROTO_LOCAL", "local" }, + { 0, NULL, NULL } + }; + etype = g_enum_register_static (g_intern_static_string ("GdkDragProtocol"), values); + } + return etype; +} +/* enumerations from "gdkevents.h" */ +GType +gdk_filter_return_get_type (void) +{ + static GType etype = 0; + if (G_UNLIKELY(etype == 0)) { + static const GEnumValue values[] = { + { GDK_FILTER_CONTINUE, "GDK_FILTER_CONTINUE", "continue" }, + { GDK_FILTER_TRANSLATE, "GDK_FILTER_TRANSLATE", "translate" }, + { GDK_FILTER_REMOVE, "GDK_FILTER_REMOVE", "remove" }, + { 0, NULL, NULL } + }; + etype = g_enum_register_static (g_intern_static_string ("GdkFilterReturn"), values); + } + return etype; +} +GType +gdk_event_type_get_type (void) +{ + static GType etype = 0; + if (G_UNLIKELY(etype == 0)) { + static const GEnumValue values[] = { + { GDK_NOTHING, "GDK_NOTHING", "nothing" }, + { GDK_DELETE, "GDK_DELETE", "delete" }, + { GDK_DESTROY, "GDK_DESTROY", "destroy" }, + { GDK_EXPOSE, "GDK_EXPOSE", "expose" }, + { GDK_MOTION_NOTIFY, "GDK_MOTION_NOTIFY", "motion-notify" }, + { GDK_BUTTON_PRESS, "GDK_BUTTON_PRESS", "button-press" }, + { GDK_2BUTTON_PRESS, "GDK_2BUTTON_PRESS", "2button-press" }, + { GDK_3BUTTON_PRESS, "GDK_3BUTTON_PRESS", "3button-press" }, + { GDK_BUTTON_RELEASE, "GDK_BUTTON_RELEASE", "button-release" }, + { GDK_KEY_PRESS, "GDK_KEY_PRESS", "key-press" }, + { GDK_KEY_RELEASE, "GDK_KEY_RELEASE", "key-release" }, + { GDK_ENTER_NOTIFY, "GDK_ENTER_NOTIFY", "enter-notify" }, + { GDK_LEAVE_NOTIFY, "GDK_LEAVE_NOTIFY", "leave-notify" }, + { GDK_FOCUS_CHANGE, "GDK_FOCUS_CHANGE", "focus-change" }, + { GDK_CONFIGURE, "GDK_CONFIGURE", "configure" }, + { GDK_MAP, "GDK_MAP", "map" }, + { GDK_UNMAP, "GDK_UNMAP", "unmap" }, + { GDK_PROPERTY_NOTIFY, "GDK_PROPERTY_NOTIFY", "property-notify" }, + { GDK_SELECTION_CLEAR, "GDK_SELECTION_CLEAR", "selection-clear" }, + { GDK_SELECTION_REQUEST, "GDK_SELECTION_REQUEST", "selection-request" }, + { GDK_SELECTION_NOTIFY, "GDK_SELECTION_NOTIFY", "selection-notify" }, + { GDK_PROXIMITY_IN, "GDK_PROXIMITY_IN", "proximity-in" }, + { GDK_PROXIMITY_OUT, "GDK_PROXIMITY_OUT", "proximity-out" }, + { GDK_DRAG_ENTER, "GDK_DRAG_ENTER", "drag-enter" }, + { GDK_DRAG_LEAVE, "GDK_DRAG_LEAVE", "drag-leave" }, + { GDK_DRAG_MOTION, "GDK_DRAG_MOTION", "drag-motion" }, + { GDK_DRAG_STATUS, "GDK_DRAG_STATUS", "drag-status" }, + { GDK_DROP_START, "GDK_DROP_START", "drop-start" }, + { GDK_DROP_FINISHED, "GDK_DROP_FINISHED", "drop-finished" }, + { GDK_CLIENT_EVENT, "GDK_CLIENT_EVENT", "client-event" }, + { GDK_VISIBILITY_NOTIFY, "GDK_VISIBILITY_NOTIFY", "visibility-notify" }, + { GDK_NO_EXPOSE, "GDK_NO_EXPOSE", "no-expose" }, + { GDK_SCROLL, "GDK_SCROLL", "scroll" }, + { GDK_WINDOW_STATE, "GDK_WINDOW_STATE", "window-state" }, + { GDK_SETTING, "GDK_SETTING", "setting" }, + { GDK_OWNER_CHANGE, "GDK_OWNER_CHANGE", "owner-change" }, + { GDK_GRAB_BROKEN, "GDK_GRAB_BROKEN", "grab-broken" }, + { GDK_DAMAGE, "GDK_DAMAGE", "damage" }, + { GDK_EVENT_LAST, "GDK_EVENT_LAST", "event-last" }, + { 0, NULL, NULL } + }; + etype = g_enum_register_static (g_intern_static_string ("GdkEventType"), values); + } + return etype; +} +GType +gdk_event_mask_get_type (void) +{ + static GType etype = 0; + if (G_UNLIKELY(etype == 0)) { + static const GFlagsValue values[] = { + { GDK_EXPOSURE_MASK, "GDK_EXPOSURE_MASK", "exposure-mask" }, + { GDK_POINTER_MOTION_MASK, "GDK_POINTER_MOTION_MASK", "pointer-motion-mask" }, + { GDK_POINTER_MOTION_HINT_MASK, "GDK_POINTER_MOTION_HINT_MASK", "pointer-motion-hint-mask" }, + { GDK_BUTTON_MOTION_MASK, "GDK_BUTTON_MOTION_MASK", "button-motion-mask" }, + { GDK_BUTTON1_MOTION_MASK, "GDK_BUTTON1_MOTION_MASK", "button1-motion-mask" }, + { GDK_BUTTON2_MOTION_MASK, "GDK_BUTTON2_MOTION_MASK", "button2-motion-mask" }, + { GDK_BUTTON3_MOTION_MASK, "GDK_BUTTON3_MOTION_MASK", "button3-motion-mask" }, + { GDK_BUTTON_PRESS_MASK, "GDK_BUTTON_PRESS_MASK", "button-press-mask" }, + { GDK_BUTTON_RELEASE_MASK, "GDK_BUTTON_RELEASE_MASK", "button-release-mask" }, + { GDK_KEY_PRESS_MASK, "GDK_KEY_PRESS_MASK", "key-press-mask" }, + { GDK_KEY_RELEASE_MASK, "GDK_KEY_RELEASE_MASK", "key-release-mask" }, + { GDK_ENTER_NOTIFY_MASK, "GDK_ENTER_NOTIFY_MASK", "enter-notify-mask" }, + { GDK_LEAVE_NOTIFY_MASK, "GDK_LEAVE_NOTIFY_MASK", "leave-notify-mask" }, + { GDK_FOCUS_CHANGE_MASK, "GDK_FOCUS_CHANGE_MASK", "focus-change-mask" }, + { GDK_STRUCTURE_MASK, "GDK_STRUCTURE_MASK", "structure-mask" }, + { GDK_PROPERTY_CHANGE_MASK, "GDK_PROPERTY_CHANGE_MASK", "property-change-mask" }, + { GDK_VISIBILITY_NOTIFY_MASK, "GDK_VISIBILITY_NOTIFY_MASK", "visibility-notify-mask" }, + { GDK_PROXIMITY_IN_MASK, "GDK_PROXIMITY_IN_MASK", "proximity-in-mask" }, + { GDK_PROXIMITY_OUT_MASK, "GDK_PROXIMITY_OUT_MASK", "proximity-out-mask" }, + { GDK_SUBSTRUCTURE_MASK, "GDK_SUBSTRUCTURE_MASK", "substructure-mask" }, + { GDK_SCROLL_MASK, "GDK_SCROLL_MASK", "scroll-mask" }, + { GDK_ALL_EVENTS_MASK, "GDK_ALL_EVENTS_MASK", "all-events-mask" }, + { 0, NULL, NULL } + }; + etype = g_flags_register_static (g_intern_static_string ("GdkEventMask"), values); + } + return etype; +} +GType +gdk_visibility_state_get_type (void) +{ + static GType etype = 0; + if (G_UNLIKELY(etype == 0)) { + static const GEnumValue values[] = { + { GDK_VISIBILITY_UNOBSCURED, "GDK_VISIBILITY_UNOBSCURED", "unobscured" }, + { GDK_VISIBILITY_PARTIAL, "GDK_VISIBILITY_PARTIAL", "partial" }, + { GDK_VISIBILITY_FULLY_OBSCURED, "GDK_VISIBILITY_FULLY_OBSCURED", "fully-obscured" }, + { 0, NULL, NULL } + }; + etype = g_enum_register_static (g_intern_static_string ("GdkVisibilityState"), values); + } + return etype; +} +GType +gdk_scroll_direction_get_type (void) +{ + static GType etype = 0; + if (G_UNLIKELY(etype == 0)) { + static const GEnumValue values[] = { + { GDK_SCROLL_UP, "GDK_SCROLL_UP", "up" }, + { GDK_SCROLL_DOWN, "GDK_SCROLL_DOWN", "down" }, + { GDK_SCROLL_LEFT, "GDK_SCROLL_LEFT", "left" }, + { GDK_SCROLL_RIGHT, "GDK_SCROLL_RIGHT", "right" }, + { 0, NULL, NULL } + }; + etype = g_enum_register_static (g_intern_static_string ("GdkScrollDirection"), values); + } + return etype; +} +GType +gdk_notify_type_get_type (void) +{ + static GType etype = 0; + if (G_UNLIKELY(etype == 0)) { + static const GEnumValue values[] = { + { GDK_NOTIFY_ANCESTOR, "GDK_NOTIFY_ANCESTOR", "ancestor" }, + { GDK_NOTIFY_VIRTUAL, "GDK_NOTIFY_VIRTUAL", "virtual" }, + { GDK_NOTIFY_INFERIOR, "GDK_NOTIFY_INFERIOR", "inferior" }, + { GDK_NOTIFY_NONLINEAR, "GDK_NOTIFY_NONLINEAR", "nonlinear" }, + { GDK_NOTIFY_NONLINEAR_VIRTUAL, "GDK_NOTIFY_NONLINEAR_VIRTUAL", "nonlinear-virtual" }, + { GDK_NOTIFY_UNKNOWN, "GDK_NOTIFY_UNKNOWN", "unknown" }, + { 0, NULL, NULL } + }; + etype = g_enum_register_static (g_intern_static_string ("GdkNotifyType"), values); + } + return etype; +} +GType +gdk_crossing_mode_get_type (void) +{ + static GType etype = 0; + if (G_UNLIKELY(etype == 0)) { + static const GEnumValue values[] = { + { GDK_CROSSING_NORMAL, "GDK_CROSSING_NORMAL", "normal" }, + { GDK_CROSSING_GRAB, "GDK_CROSSING_GRAB", "grab" }, + { GDK_CROSSING_UNGRAB, "GDK_CROSSING_UNGRAB", "ungrab" }, + { GDK_CROSSING_GTK_GRAB, "GDK_CROSSING_GTK_GRAB", "gtk-grab" }, + { GDK_CROSSING_GTK_UNGRAB, "GDK_CROSSING_GTK_UNGRAB", "gtk-ungrab" }, + { GDK_CROSSING_STATE_CHANGED, "GDK_CROSSING_STATE_CHANGED", "state-changed" }, + { 0, NULL, NULL } + }; + etype = g_enum_register_static (g_intern_static_string ("GdkCrossingMode"), values); + } + return etype; +} +GType +gdk_property_state_get_type (void) +{ + static GType etype = 0; + if (G_UNLIKELY(etype == 0)) { + static const GEnumValue values[] = { + { GDK_PROPERTY_NEW_VALUE, "GDK_PROPERTY_NEW_VALUE", "new-value" }, + { GDK_PROPERTY_DELETE, "GDK_PROPERTY_DELETE", "delete" }, + { 0, NULL, NULL } + }; + etype = g_enum_register_static (g_intern_static_string ("GdkPropertyState"), values); + } + return etype; +} +GType +gdk_window_state_get_type (void) +{ + static GType etype = 0; + if (G_UNLIKELY(etype == 0)) { + static const GFlagsValue values[] = { + { GDK_WINDOW_STATE_WITHDRAWN, "GDK_WINDOW_STATE_WITHDRAWN", "withdrawn" }, + { GDK_WINDOW_STATE_ICONIFIED, "GDK_WINDOW_STATE_ICONIFIED", "iconified" }, + { GDK_WINDOW_STATE_MAXIMIZED, "GDK_WINDOW_STATE_MAXIMIZED", "maximized" }, + { GDK_WINDOW_STATE_STICKY, "GDK_WINDOW_STATE_STICKY", "sticky" }, + { GDK_WINDOW_STATE_FULLSCREEN, "GDK_WINDOW_STATE_FULLSCREEN", "fullscreen" }, + { GDK_WINDOW_STATE_ABOVE, "GDK_WINDOW_STATE_ABOVE", "above" }, + { GDK_WINDOW_STATE_BELOW, "GDK_WINDOW_STATE_BELOW", "below" }, + { 0, NULL, NULL } + }; + etype = g_flags_register_static (g_intern_static_string ("GdkWindowState"), values); + } + return etype; +} +GType +gdk_setting_action_get_type (void) +{ + static GType etype = 0; + if (G_UNLIKELY(etype == 0)) { + static const GEnumValue values[] = { + { GDK_SETTING_ACTION_NEW, "GDK_SETTING_ACTION_NEW", "new" }, + { GDK_SETTING_ACTION_CHANGED, "GDK_SETTING_ACTION_CHANGED", "changed" }, + { GDK_SETTING_ACTION_DELETED, "GDK_SETTING_ACTION_DELETED", "deleted" }, + { 0, NULL, NULL } + }; + etype = g_enum_register_static (g_intern_static_string ("GdkSettingAction"), values); + } + return etype; +} +GType +gdk_owner_change_get_type (void) +{ + static GType etype = 0; + if (G_UNLIKELY(etype == 0)) { + static const GEnumValue values[] = { + { GDK_OWNER_CHANGE_NEW_OWNER, "GDK_OWNER_CHANGE_NEW_OWNER", "new-owner" }, + { GDK_OWNER_CHANGE_DESTROY, "GDK_OWNER_CHANGE_DESTROY", "destroy" }, + { GDK_OWNER_CHANGE_CLOSE, "GDK_OWNER_CHANGE_CLOSE", "close" }, + { 0, NULL, NULL } + }; + etype = g_enum_register_static (g_intern_static_string ("GdkOwnerChange"), values); + } + return etype; +} +/* enumerations from "gdkfont.h" */ +GType +gdk_font_type_get_type (void) +{ + static GType etype = 0; + if (G_UNLIKELY(etype == 0)) { + static const GEnumValue values[] = { + { GDK_FONT_FONT, "GDK_FONT_FONT", "font" }, + { GDK_FONT_FONTSET, "GDK_FONT_FONTSET", "fontset" }, + { 0, NULL, NULL } + }; + etype = g_enum_register_static (g_intern_static_string ("GdkFontType"), values); + } + return etype; +} +/* enumerations from "gdkgc.h" */ +GType +gdk_cap_style_get_type (void) +{ + static GType etype = 0; + if (G_UNLIKELY(etype == 0)) { + static const GEnumValue values[] = { + { GDK_CAP_NOT_LAST, "GDK_CAP_NOT_LAST", "not-last" }, + { GDK_CAP_BUTT, "GDK_CAP_BUTT", "butt" }, + { GDK_CAP_ROUND, "GDK_CAP_ROUND", "round" }, + { GDK_CAP_PROJECTING, "GDK_CAP_PROJECTING", "projecting" }, + { 0, NULL, NULL } + }; + etype = g_enum_register_static (g_intern_static_string ("GdkCapStyle"), values); + } + return etype; +} +GType +gdk_fill_get_type (void) +{ + static GType etype = 0; + if (G_UNLIKELY(etype == 0)) { + static const GEnumValue values[] = { + { GDK_SOLID, "GDK_SOLID", "solid" }, + { GDK_TILED, "GDK_TILED", "tiled" }, + { GDK_STIPPLED, "GDK_STIPPLED", "stippled" }, + { GDK_OPAQUE_STIPPLED, "GDK_OPAQUE_STIPPLED", "opaque-stippled" }, + { 0, NULL, NULL } + }; + etype = g_enum_register_static (g_intern_static_string ("GdkFill"), values); + } + return etype; +} +GType +gdk_function_get_type (void) +{ + static GType etype = 0; + if (G_UNLIKELY(etype == 0)) { + static const GEnumValue values[] = { + { GDK_COPY, "GDK_COPY", "copy" }, + { GDK_INVERT, "GDK_INVERT", "invert" }, + { GDK_XOR, "GDK_XOR", "xor" }, + { GDK_CLEAR, "GDK_CLEAR", "clear" }, + { GDK_AND, "GDK_AND", "and" }, + { GDK_AND_REVERSE, "GDK_AND_REVERSE", "and-reverse" }, + { GDK_AND_INVERT, "GDK_AND_INVERT", "and-invert" }, + { GDK_NOOP, "GDK_NOOP", "noop" }, + { GDK_OR, "GDK_OR", "or" }, + { GDK_EQUIV, "GDK_EQUIV", "equiv" }, + { GDK_OR_REVERSE, "GDK_OR_REVERSE", "or-reverse" }, + { GDK_COPY_INVERT, "GDK_COPY_INVERT", "copy-invert" }, + { GDK_OR_INVERT, "GDK_OR_INVERT", "or-invert" }, + { GDK_NAND, "GDK_NAND", "nand" }, + { GDK_NOR, "GDK_NOR", "nor" }, + { GDK_SET, "GDK_SET", "set" }, + { 0, NULL, NULL } + }; + etype = g_enum_register_static (g_intern_static_string ("GdkFunction"), values); + } + return etype; +} +GType +gdk_join_style_get_type (void) +{ + static GType etype = 0; + if (G_UNLIKELY(etype == 0)) { + static const GEnumValue values[] = { + { GDK_JOIN_MITER, "GDK_JOIN_MITER", "miter" }, + { GDK_JOIN_ROUND, "GDK_JOIN_ROUND", "round" }, + { GDK_JOIN_BEVEL, "GDK_JOIN_BEVEL", "bevel" }, + { 0, NULL, NULL } + }; + etype = g_enum_register_static (g_intern_static_string ("GdkJoinStyle"), values); + } + return etype; +} +GType +gdk_line_style_get_type (void) +{ + static GType etype = 0; + if (G_UNLIKELY(etype == 0)) { + static const GEnumValue values[] = { + { GDK_LINE_SOLID, "GDK_LINE_SOLID", "solid" }, + { GDK_LINE_ON_OFF_DASH, "GDK_LINE_ON_OFF_DASH", "on-off-dash" }, + { GDK_LINE_DOUBLE_DASH, "GDK_LINE_DOUBLE_DASH", "double-dash" }, + { 0, NULL, NULL } + }; + etype = g_enum_register_static (g_intern_static_string ("GdkLineStyle"), values); + } + return etype; +} +GType +gdk_subwindow_mode_get_type (void) +{ + static GType etype = 0; + if (G_UNLIKELY(etype == 0)) { + static const GEnumValue values[] = { + { GDK_CLIP_BY_CHILDREN, "GDK_CLIP_BY_CHILDREN", "clip-by-children" }, + { GDK_INCLUDE_INFERIORS, "GDK_INCLUDE_INFERIORS", "include-inferiors" }, + { 0, NULL, NULL } + }; + etype = g_enum_register_static (g_intern_static_string ("GdkSubwindowMode"), values); + } + return etype; +} +GType +gdk_gc_values_mask_get_type (void) +{ + static GType etype = 0; + if (G_UNLIKELY(etype == 0)) { + static const GFlagsValue values[] = { + { GDK_GC_FOREGROUND, "GDK_GC_FOREGROUND", "foreground" }, + { GDK_GC_BACKGROUND, "GDK_GC_BACKGROUND", "background" }, + { GDK_GC_FONT, "GDK_GC_FONT", "font" }, + { GDK_GC_FUNCTION, "GDK_GC_FUNCTION", "function" }, + { GDK_GC_FILL, "GDK_GC_FILL", "fill" }, + { GDK_GC_TILE, "GDK_GC_TILE", "tile" }, + { GDK_GC_STIPPLE, "GDK_GC_STIPPLE", "stipple" }, + { GDK_GC_CLIP_MASK, "GDK_GC_CLIP_MASK", "clip-mask" }, + { GDK_GC_SUBWINDOW, "GDK_GC_SUBWINDOW", "subwindow" }, + { GDK_GC_TS_X_ORIGIN, "GDK_GC_TS_X_ORIGIN", "ts-x-origin" }, + { GDK_GC_TS_Y_ORIGIN, "GDK_GC_TS_Y_ORIGIN", "ts-y-origin" }, + { GDK_GC_CLIP_X_ORIGIN, "GDK_GC_CLIP_X_ORIGIN", "clip-x-origin" }, + { GDK_GC_CLIP_Y_ORIGIN, "GDK_GC_CLIP_Y_ORIGIN", "clip-y-origin" }, + { GDK_GC_EXPOSURES, "GDK_GC_EXPOSURES", "exposures" }, + { GDK_GC_LINE_WIDTH, "GDK_GC_LINE_WIDTH", "line-width" }, + { GDK_GC_LINE_STYLE, "GDK_GC_LINE_STYLE", "line-style" }, + { GDK_GC_CAP_STYLE, "GDK_GC_CAP_STYLE", "cap-style" }, + { GDK_GC_JOIN_STYLE, "GDK_GC_JOIN_STYLE", "join-style" }, + { 0, NULL, NULL } + }; + etype = g_flags_register_static (g_intern_static_string ("GdkGCValuesMask"), values); + } + return etype; +} +/* enumerations from "gdkimage.h" */ +GType +gdk_image_type_get_type (void) +{ + static GType etype = 0; + if (G_UNLIKELY(etype == 0)) { + static const GEnumValue values[] = { + { GDK_IMAGE_NORMAL, "GDK_IMAGE_NORMAL", "normal" }, + { GDK_IMAGE_SHARED, "GDK_IMAGE_SHARED", "shared" }, + { GDK_IMAGE_FASTEST, "GDK_IMAGE_FASTEST", "fastest" }, + { 0, NULL, NULL } + }; + etype = g_enum_register_static (g_intern_static_string ("GdkImageType"), values); + } + return etype; +} +/* enumerations from "gdkinput.h" */ +GType +gdk_extension_mode_get_type (void) +{ + static GType etype = 0; + if (G_UNLIKELY(etype == 0)) { + static const GEnumValue values[] = { + { GDK_EXTENSION_EVENTS_NONE, "GDK_EXTENSION_EVENTS_NONE", "none" }, + { GDK_EXTENSION_EVENTS_ALL, "GDK_EXTENSION_EVENTS_ALL", "all" }, + { GDK_EXTENSION_EVENTS_CURSOR, "GDK_EXTENSION_EVENTS_CURSOR", "cursor" }, + { 0, NULL, NULL } + }; + etype = g_enum_register_static (g_intern_static_string ("GdkExtensionMode"), values); + } + return etype; +} +GType +gdk_input_source_get_type (void) +{ + static GType etype = 0; + if (G_UNLIKELY(etype == 0)) { + static const GEnumValue values[] = { + { GDK_SOURCE_MOUSE, "GDK_SOURCE_MOUSE", "mouse" }, + { GDK_SOURCE_PEN, "GDK_SOURCE_PEN", "pen" }, + { GDK_SOURCE_ERASER, "GDK_SOURCE_ERASER", "eraser" }, + { GDK_SOURCE_CURSOR, "GDK_SOURCE_CURSOR", "cursor" }, + { 0, NULL, NULL } + }; + etype = g_enum_register_static (g_intern_static_string ("GdkInputSource"), values); + } + return etype; +} +GType +gdk_input_mode_get_type (void) +{ + static GType etype = 0; + if (G_UNLIKELY(etype == 0)) { + static const GEnumValue values[] = { + { GDK_MODE_DISABLED, "GDK_MODE_DISABLED", "disabled" }, + { GDK_MODE_SCREEN, "GDK_MODE_SCREEN", "screen" }, + { GDK_MODE_WINDOW, "GDK_MODE_WINDOW", "window" }, + { 0, NULL, NULL } + }; + etype = g_enum_register_static (g_intern_static_string ("GdkInputMode"), values); + } + return etype; +} +GType +gdk_axis_use_get_type (void) +{ + static GType etype = 0; + if (G_UNLIKELY(etype == 0)) { + static const GEnumValue values[] = { + { GDK_AXIS_IGNORE, "GDK_AXIS_IGNORE", "ignore" }, + { GDK_AXIS_X, "GDK_AXIS_X", "x" }, + { GDK_AXIS_Y, "GDK_AXIS_Y", "y" }, + { GDK_AXIS_PRESSURE, "GDK_AXIS_PRESSURE", "pressure" }, + { GDK_AXIS_XTILT, "GDK_AXIS_XTILT", "xtilt" }, + { GDK_AXIS_YTILT, "GDK_AXIS_YTILT", "ytilt" }, + { GDK_AXIS_WHEEL, "GDK_AXIS_WHEEL", "wheel" }, + { GDK_AXIS_LAST, "GDK_AXIS_LAST", "last" }, + { 0, NULL, NULL } + }; + etype = g_enum_register_static (g_intern_static_string ("GdkAxisUse"), values); + } + return etype; +} +/* enumerations from "gdkproperty.h" */ +GType +gdk_prop_mode_get_type (void) +{ + static GType etype = 0; + if (G_UNLIKELY(etype == 0)) { + static const GEnumValue values[] = { + { GDK_PROP_MODE_REPLACE, "GDK_PROP_MODE_REPLACE", "replace" }, + { GDK_PROP_MODE_PREPEND, "GDK_PROP_MODE_PREPEND", "prepend" }, + { GDK_PROP_MODE_APPEND, "GDK_PROP_MODE_APPEND", "append" }, + { 0, NULL, NULL } + }; + etype = g_enum_register_static (g_intern_static_string ("GdkPropMode"), values); + } + return etype; +} +/* enumerations from "gdkregion.h" */ +GType +gdk_fill_rule_get_type (void) +{ + static GType etype = 0; + if (G_UNLIKELY(etype == 0)) { + static const GEnumValue values[] = { + { GDK_EVEN_ODD_RULE, "GDK_EVEN_ODD_RULE", "even-odd-rule" }, + { GDK_WINDING_RULE, "GDK_WINDING_RULE", "winding-rule" }, + { 0, NULL, NULL } + }; + etype = g_enum_register_static (g_intern_static_string ("GdkFillRule"), values); + } + return etype; +} +GType +gdk_overlap_type_get_type (void) +{ + static GType etype = 0; + if (G_UNLIKELY(etype == 0)) { + static const GEnumValue values[] = { + { GDK_OVERLAP_RECTANGLE_IN, "GDK_OVERLAP_RECTANGLE_IN", "in" }, + { GDK_OVERLAP_RECTANGLE_OUT, "GDK_OVERLAP_RECTANGLE_OUT", "out" }, + { GDK_OVERLAP_RECTANGLE_PART, "GDK_OVERLAP_RECTANGLE_PART", "part" }, + { 0, NULL, NULL } + }; + etype = g_enum_register_static (g_intern_static_string ("GdkOverlapType"), values); + } + return etype; +} +/* enumerations from "gdkrgb.h" */ +GType +gdk_rgb_dither_get_type (void) +{ + static GType etype = 0; + if (G_UNLIKELY(etype == 0)) { + static const GEnumValue values[] = { + { GDK_RGB_DITHER_NONE, "GDK_RGB_DITHER_NONE", "none" }, + { GDK_RGB_DITHER_NORMAL, "GDK_RGB_DITHER_NORMAL", "normal" }, + { GDK_RGB_DITHER_MAX, "GDK_RGB_DITHER_MAX", "max" }, + { 0, NULL, NULL } + }; + etype = g_enum_register_static (g_intern_static_string ("GdkRgbDither"), values); + } + return etype; +} +/* enumerations from "gdktypes.h" */ +GType +gdk_byte_order_get_type (void) +{ + static GType etype = 0; + if (G_UNLIKELY(etype == 0)) { + static const GEnumValue values[] = { + { GDK_LSB_FIRST, "GDK_LSB_FIRST", "lsb-first" }, + { GDK_MSB_FIRST, "GDK_MSB_FIRST", "msb-first" }, + { 0, NULL, NULL } + }; + etype = g_enum_register_static (g_intern_static_string ("GdkByteOrder"), values); + } + return etype; +} +GType +gdk_modifier_type_get_type (void) +{ + static GType etype = 0; + if (G_UNLIKELY(etype == 0)) { + static const GFlagsValue values[] = { + { GDK_SHIFT_MASK, "GDK_SHIFT_MASK", "shift-mask" }, + { GDK_LOCK_MASK, "GDK_LOCK_MASK", "lock-mask" }, + { GDK_CONTROL_MASK, "GDK_CONTROL_MASK", "control-mask" }, + { GDK_MOD1_MASK, "GDK_MOD1_MASK", "mod1-mask" }, + { GDK_MOD2_MASK, "GDK_MOD2_MASK", "mod2-mask" }, + { GDK_MOD3_MASK, "GDK_MOD3_MASK", "mod3-mask" }, + { GDK_MOD4_MASK, "GDK_MOD4_MASK", "mod4-mask" }, + { GDK_MOD5_MASK, "GDK_MOD5_MASK", "mod5-mask" }, + { GDK_BUTTON1_MASK, "GDK_BUTTON1_MASK", "button1-mask" }, + { GDK_BUTTON2_MASK, "GDK_BUTTON2_MASK", "button2-mask" }, + { GDK_BUTTON3_MASK, "GDK_BUTTON3_MASK", "button3-mask" }, + { GDK_BUTTON4_MASK, "GDK_BUTTON4_MASK", "button4-mask" }, + { GDK_BUTTON5_MASK, "GDK_BUTTON5_MASK", "button5-mask" }, + { GDK_SUPER_MASK, "GDK_SUPER_MASK", "super-mask" }, + { GDK_HYPER_MASK, "GDK_HYPER_MASK", "hyper-mask" }, + { GDK_META_MASK, "GDK_META_MASK", "meta-mask" }, + { GDK_RELEASE_MASK, "GDK_RELEASE_MASK", "release-mask" }, + { GDK_MODIFIER_MASK, "GDK_MODIFIER_MASK", "modifier-mask" }, + { 0, NULL, NULL } + }; + etype = g_flags_register_static (g_intern_static_string ("GdkModifierType"), values); + } + return etype; +} +GType +gdk_input_condition_get_type (void) +{ + static GType etype = 0; + if (G_UNLIKELY(etype == 0)) { + static const GFlagsValue values[] = { + { GDK_INPUT_READ, "GDK_INPUT_READ", "read" }, + { GDK_INPUT_WRITE, "GDK_INPUT_WRITE", "write" }, + { GDK_INPUT_EXCEPTION, "GDK_INPUT_EXCEPTION", "exception" }, + { 0, NULL, NULL } + }; + etype = g_flags_register_static (g_intern_static_string ("GdkInputCondition"), values); + } + return etype; +} +GType +gdk_status_get_type (void) +{ + static GType etype = 0; + if (G_UNLIKELY(etype == 0)) { + static const GEnumValue values[] = { + { GDK_OK, "GDK_OK", "ok" }, + { GDK_ERROR, "GDK_ERROR", "error" }, + { GDK_ERROR_PARAM, "GDK_ERROR_PARAM", "error-param" }, + { GDK_ERROR_FILE, "GDK_ERROR_FILE", "error-file" }, + { GDK_ERROR_MEM, "GDK_ERROR_MEM", "error-mem" }, + { 0, NULL, NULL } + }; + etype = g_enum_register_static (g_intern_static_string ("GdkStatus"), values); + } + return etype; +} +GType +gdk_grab_status_get_type (void) +{ + static GType etype = 0; + if (G_UNLIKELY(etype == 0)) { + static const GEnumValue values[] = { + { GDK_GRAB_SUCCESS, "GDK_GRAB_SUCCESS", "success" }, + { GDK_GRAB_ALREADY_GRABBED, "GDK_GRAB_ALREADY_GRABBED", "already-grabbed" }, + { GDK_GRAB_INVALID_TIME, "GDK_GRAB_INVALID_TIME", "invalid-time" }, + { GDK_GRAB_NOT_VIEWABLE, "GDK_GRAB_NOT_VIEWABLE", "not-viewable" }, + { GDK_GRAB_FROZEN, "GDK_GRAB_FROZEN", "frozen" }, + { 0, NULL, NULL } + }; + etype = g_enum_register_static (g_intern_static_string ("GdkGrabStatus"), values); + } + return etype; +} +/* enumerations from "gdkvisual.h" */ +GType +gdk_visual_type_get_type (void) +{ + static GType etype = 0; + if (G_UNLIKELY(etype == 0)) { + static const GEnumValue values[] = { + { GDK_VISUAL_STATIC_GRAY, "GDK_VISUAL_STATIC_GRAY", "static-gray" }, + { GDK_VISUAL_GRAYSCALE, "GDK_VISUAL_GRAYSCALE", "grayscale" }, + { GDK_VISUAL_STATIC_COLOR, "GDK_VISUAL_STATIC_COLOR", "static-color" }, + { GDK_VISUAL_PSEUDO_COLOR, "GDK_VISUAL_PSEUDO_COLOR", "pseudo-color" }, + { GDK_VISUAL_TRUE_COLOR, "GDK_VISUAL_TRUE_COLOR", "true-color" }, + { GDK_VISUAL_DIRECT_COLOR, "GDK_VISUAL_DIRECT_COLOR", "direct-color" }, + { 0, NULL, NULL } + }; + etype = g_enum_register_static (g_intern_static_string ("GdkVisualType"), values); + } + return etype; +} +/* enumerations from "gdkwindow.h" */ +GType +gdk_window_class_get_type (void) +{ + static GType etype = 0; + if (G_UNLIKELY(etype == 0)) { + static const GEnumValue values[] = { + { GDK_INPUT_OUTPUT, "GDK_INPUT_OUTPUT", "output" }, + { GDK_INPUT_ONLY, "GDK_INPUT_ONLY", "only" }, + { 0, NULL, NULL } + }; + etype = g_enum_register_static (g_intern_static_string ("GdkWindowClass"), values); + } + return etype; +} +GType +gdk_window_type_get_type (void) +{ + static GType etype = 0; + if (G_UNLIKELY(etype == 0)) { + static const GEnumValue values[] = { + { GDK_WINDOW_ROOT, "GDK_WINDOW_ROOT", "root" }, + { GDK_WINDOW_TOPLEVEL, "GDK_WINDOW_TOPLEVEL", "toplevel" }, + { GDK_WINDOW_CHILD, "GDK_WINDOW_CHILD", "child" }, + { GDK_WINDOW_DIALOG, "GDK_WINDOW_DIALOG", "dialog" }, + { GDK_WINDOW_TEMP, "GDK_WINDOW_TEMP", "temp" }, + { GDK_WINDOW_FOREIGN, "GDK_WINDOW_FOREIGN", "foreign" }, + { GDK_WINDOW_OFFSCREEN, "GDK_WINDOW_OFFSCREEN", "offscreen" }, + { 0, NULL, NULL } + }; + etype = g_enum_register_static (g_intern_static_string ("GdkWindowType"), values); + } + return etype; +} +GType +gdk_window_attributes_type_get_type (void) +{ + static GType etype = 0; + if (G_UNLIKELY(etype == 0)) { + static const GFlagsValue values[] = { + { GDK_WA_TITLE, "GDK_WA_TITLE", "title" }, + { GDK_WA_X, "GDK_WA_X", "x" }, + { GDK_WA_Y, "GDK_WA_Y", "y" }, + { GDK_WA_CURSOR, "GDK_WA_CURSOR", "cursor" }, + { GDK_WA_COLORMAP, "GDK_WA_COLORMAP", "colormap" }, + { GDK_WA_VISUAL, "GDK_WA_VISUAL", "visual" }, + { GDK_WA_WMCLASS, "GDK_WA_WMCLASS", "wmclass" }, + { GDK_WA_NOREDIR, "GDK_WA_NOREDIR", "noredir" }, + { GDK_WA_TYPE_HINT, "GDK_WA_TYPE_HINT", "type-hint" }, + { 0, NULL, NULL } + }; + etype = g_flags_register_static (g_intern_static_string ("GdkWindowAttributesType"), values); + } + return etype; +} +GType +gdk_window_hints_get_type (void) +{ + static GType etype = 0; + if (G_UNLIKELY(etype == 0)) { + static const GFlagsValue values[] = { + { GDK_HINT_POS, "GDK_HINT_POS", "pos" }, + { GDK_HINT_MIN_SIZE, "GDK_HINT_MIN_SIZE", "min-size" }, + { GDK_HINT_MAX_SIZE, "GDK_HINT_MAX_SIZE", "max-size" }, + { GDK_HINT_BASE_SIZE, "GDK_HINT_BASE_SIZE", "base-size" }, + { GDK_HINT_ASPECT, "GDK_HINT_ASPECT", "aspect" }, + { GDK_HINT_RESIZE_INC, "GDK_HINT_RESIZE_INC", "resize-inc" }, + { GDK_HINT_WIN_GRAVITY, "GDK_HINT_WIN_GRAVITY", "win-gravity" }, + { GDK_HINT_USER_POS, "GDK_HINT_USER_POS", "user-pos" }, + { GDK_HINT_USER_SIZE, "GDK_HINT_USER_SIZE", "user-size" }, + { 0, NULL, NULL } + }; + etype = g_flags_register_static (g_intern_static_string ("GdkWindowHints"), values); + } + return etype; +} +GType +gdk_window_type_hint_get_type (void) +{ + static GType etype = 0; + if (G_UNLIKELY(etype == 0)) { + static const GEnumValue values[] = { + { GDK_WINDOW_TYPE_HINT_NORMAL, "GDK_WINDOW_TYPE_HINT_NORMAL", "normal" }, + { GDK_WINDOW_TYPE_HINT_DIALOG, "GDK_WINDOW_TYPE_HINT_DIALOG", "dialog" }, + { GDK_WINDOW_TYPE_HINT_MENU, "GDK_WINDOW_TYPE_HINT_MENU", "menu" }, + { GDK_WINDOW_TYPE_HINT_TOOLBAR, "GDK_WINDOW_TYPE_HINT_TOOLBAR", "toolbar" }, + { GDK_WINDOW_TYPE_HINT_SPLASHSCREEN, "GDK_WINDOW_TYPE_HINT_SPLASHSCREEN", "splashscreen" }, + { GDK_WINDOW_TYPE_HINT_UTILITY, "GDK_WINDOW_TYPE_HINT_UTILITY", "utility" }, + { GDK_WINDOW_TYPE_HINT_DOCK, "GDK_WINDOW_TYPE_HINT_DOCK", "dock" }, + { GDK_WINDOW_TYPE_HINT_DESKTOP, "GDK_WINDOW_TYPE_HINT_DESKTOP", "desktop" }, + { GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU, "GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU", "dropdown-menu" }, + { GDK_WINDOW_TYPE_HINT_POPUP_MENU, "GDK_WINDOW_TYPE_HINT_POPUP_MENU", "popup-menu" }, + { GDK_WINDOW_TYPE_HINT_TOOLTIP, "GDK_WINDOW_TYPE_HINT_TOOLTIP", "tooltip" }, + { GDK_WINDOW_TYPE_HINT_NOTIFICATION, "GDK_WINDOW_TYPE_HINT_NOTIFICATION", "notification" }, + { GDK_WINDOW_TYPE_HINT_COMBO, "GDK_WINDOW_TYPE_HINT_COMBO", "combo" }, + { GDK_WINDOW_TYPE_HINT_DND, "GDK_WINDOW_TYPE_HINT_DND", "dnd" }, + { 0, NULL, NULL } + }; + etype = g_enum_register_static (g_intern_static_string ("GdkWindowTypeHint"), values); + } + return etype; +} +GType +gdk_wm_decoration_get_type (void) +{ + static GType etype = 0; + if (G_UNLIKELY(etype == 0)) { + static const GFlagsValue values[] = { + { GDK_DECOR_ALL, "GDK_DECOR_ALL", "all" }, + { GDK_DECOR_BORDER, "GDK_DECOR_BORDER", "border" }, + { GDK_DECOR_RESIZEH, "GDK_DECOR_RESIZEH", "resizeh" }, + { GDK_DECOR_TITLE, "GDK_DECOR_TITLE", "title" }, + { GDK_DECOR_MENU, "GDK_DECOR_MENU", "menu" }, + { GDK_DECOR_MINIMIZE, "GDK_DECOR_MINIMIZE", "minimize" }, + { GDK_DECOR_MAXIMIZE, "GDK_DECOR_MAXIMIZE", "maximize" }, + { 0, NULL, NULL } + }; + etype = g_flags_register_static (g_intern_static_string ("GdkWMDecoration"), values); + } + return etype; +} +GType +gdk_wm_function_get_type (void) +{ + static GType etype = 0; + if (G_UNLIKELY(etype == 0)) { + static const GFlagsValue values[] = { + { GDK_FUNC_ALL, "GDK_FUNC_ALL", "all" }, + { GDK_FUNC_RESIZE, "GDK_FUNC_RESIZE", "resize" }, + { GDK_FUNC_MOVE, "GDK_FUNC_MOVE", "move" }, + { GDK_FUNC_MINIMIZE, "GDK_FUNC_MINIMIZE", "minimize" }, + { GDK_FUNC_MAXIMIZE, "GDK_FUNC_MAXIMIZE", "maximize" }, + { GDK_FUNC_CLOSE, "GDK_FUNC_CLOSE", "close" }, + { 0, NULL, NULL } + }; + etype = g_flags_register_static (g_intern_static_string ("GdkWMFunction"), values); + } + return etype; +} +GType +gdk_gravity_get_type (void) +{ + static GType etype = 0; + if (G_UNLIKELY(etype == 0)) { + static const GEnumValue values[] = { + { GDK_GRAVITY_NORTH_WEST, "GDK_GRAVITY_NORTH_WEST", "north-west" }, + { GDK_GRAVITY_NORTH, "GDK_GRAVITY_NORTH", "north" }, + { GDK_GRAVITY_NORTH_EAST, "GDK_GRAVITY_NORTH_EAST", "north-east" }, + { GDK_GRAVITY_WEST, "GDK_GRAVITY_WEST", "west" }, + { GDK_GRAVITY_CENTER, "GDK_GRAVITY_CENTER", "center" }, + { GDK_GRAVITY_EAST, "GDK_GRAVITY_EAST", "east" }, + { GDK_GRAVITY_SOUTH_WEST, "GDK_GRAVITY_SOUTH_WEST", "south-west" }, + { GDK_GRAVITY_SOUTH, "GDK_GRAVITY_SOUTH", "south" }, + { GDK_GRAVITY_SOUTH_EAST, "GDK_GRAVITY_SOUTH_EAST", "south-east" }, + { GDK_GRAVITY_STATIC, "GDK_GRAVITY_STATIC", "static" }, + { 0, NULL, NULL } + }; + etype = g_enum_register_static (g_intern_static_string ("GdkGravity"), values); + } + return etype; +} +GType +gdk_window_edge_get_type (void) +{ + static GType etype = 0; + if (G_UNLIKELY(etype == 0)) { + static const GEnumValue values[] = { + { GDK_WINDOW_EDGE_NORTH_WEST, "GDK_WINDOW_EDGE_NORTH_WEST", "north-west" }, + { GDK_WINDOW_EDGE_NORTH, "GDK_WINDOW_EDGE_NORTH", "north" }, + { GDK_WINDOW_EDGE_NORTH_EAST, "GDK_WINDOW_EDGE_NORTH_EAST", "north-east" }, + { GDK_WINDOW_EDGE_WEST, "GDK_WINDOW_EDGE_WEST", "west" }, + { GDK_WINDOW_EDGE_EAST, "GDK_WINDOW_EDGE_EAST", "east" }, + { GDK_WINDOW_EDGE_SOUTH_WEST, "GDK_WINDOW_EDGE_SOUTH_WEST", "south-west" }, + { GDK_WINDOW_EDGE_SOUTH, "GDK_WINDOW_EDGE_SOUTH", "south" }, + { GDK_WINDOW_EDGE_SOUTH_EAST, "GDK_WINDOW_EDGE_SOUTH_EAST", "south-east" }, + { 0, NULL, NULL } + }; + etype = g_enum_register_static (g_intern_static_string ("GdkWindowEdge"), values); + } + return etype; +} +#define __GDK_ENUM_TYPES_C__ +#include "gdkaliasdef.c" + +/* Generated data ends here */ + diff --git a/libs/tk/ydk/gdkevents.c b/libs/tk/ydk/gdkevents.c new file mode 100644 index 0000000000..0f8bba2f0a --- /dev/null +++ b/libs/tk/ydk/gdkevents.c @@ -0,0 +1,1412 @@ +/* GDK - The GIMP Drawing Kit + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, 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 "config.h" +#include /* For memset() */ + +#include "gdk.h" +#include "gdkinternals.h" +#include "gdkalias.h" + +typedef struct _GdkIOClosure GdkIOClosure; + +struct _GdkIOClosure +{ + GdkInputFunction function; + GdkInputCondition condition; + GDestroyNotify notify; + gpointer data; +}; + +/* Private variable declarations + */ + +GdkEventFunc _gdk_event_func = NULL; /* Callback for events */ +gpointer _gdk_event_data = NULL; +GDestroyNotify _gdk_event_notify = NULL; + +/********************************************* + * Functions for maintaining the event queue * + *********************************************/ + +/** + * _gdk_event_queue_find_first: + * @display: a #GdkDisplay + * + * Find the first event on the queue that is not still + * being filled in. + * + * Return value: Pointer to the list node for that event, or NULL. + **/ +GList* +_gdk_event_queue_find_first (GdkDisplay *display) +{ + GList *tmp_list = display->queued_events; + + while (tmp_list) + { + GdkEventPrivate *event = tmp_list->data; + if (!(event->flags & GDK_EVENT_PENDING)) + return tmp_list; + + tmp_list = g_list_next (tmp_list); + } + + return NULL; +} + +/** + * _gdk_event_queue_prepend: + * @display: a #GdkDisplay + * @event: Event to prepend. + * + * Prepends an event before the head of the event queue. + * + * Returns: the newly prepended list node. + **/ +GList* +_gdk_event_queue_prepend (GdkDisplay *display, + GdkEvent *event) +{ + display->queued_events = g_list_prepend (display->queued_events, event); + if (!display->queued_tail) + display->queued_tail = display->queued_events; + return display->queued_events; +} + +/** + * _gdk_event_queue_append: + * @display: a #GdkDisplay + * @event: Event to append. + * + * Appends an event onto the tail of the event queue. + * + * Returns: the newly appended list node. + **/ +GList * +_gdk_event_queue_append (GdkDisplay *display, + GdkEvent *event) +{ + display->queued_tail = g_list_append (display->queued_tail, event); + + if (!display->queued_events) + display->queued_events = display->queued_tail; + else + display->queued_tail = display->queued_tail->next; + + return display->queued_tail; +} + +/** + * _gdk_event_queue_insert_after: + * @display: a #GdkDisplay + * @sibling: Append after this event. + * @event: Event to append. + * + * Appends an event after the specified event, or if it isn't in + * the queue, onto the tail of the event queue. + * + * Returns: the newly appended list node. + * + * Since: 2.16 + */ +GList* +_gdk_event_queue_insert_after (GdkDisplay *display, + GdkEvent *sibling, + GdkEvent *event) +{ + GList *prev = g_list_find (display->queued_events, sibling); + if (prev && prev->next) + { + display->queued_events = g_list_insert_before (display->queued_events, prev->next, event); + return prev->next; + } + else + return _gdk_event_queue_append (display, event); +} + +/** + * _gdk_event_queue_insert_after: + * @display: a #GdkDisplay + * @sibling: Append after this event. + * @event: Event to append. + * + * Appends an event before the specified event, or if it isn't in + * the queue, onto the tail of the event queue. + * + * Returns: the newly appended list node. + * + * Since: 2.16 + */ +GList* +_gdk_event_queue_insert_before (GdkDisplay *display, + GdkEvent *sibling, + GdkEvent *event) +{ + GList *next = g_list_find (display->queued_events, sibling); + if (next) + { + display->queued_events = g_list_insert_before (display->queued_events, next, event); + return next->prev; + } + else + return _gdk_event_queue_append (display, event); +} + + +/** + * _gdk_event_queue_remove_link: + * @display: a #GdkDisplay + * @node: node to remove + * + * Removes a specified list node from the event queue. + **/ +void +_gdk_event_queue_remove_link (GdkDisplay *display, + GList *node) +{ + if (node->prev) + node->prev->next = node->next; + else + display->queued_events = node->next; + + if (node->next) + node->next->prev = node->prev; + else + display->queued_tail = node->prev; +} + +/** + * _gdk_event_unqueue: + * @display: a #GdkDisplay + * + * Removes and returns the first event from the event + * queue that is not still being filled in. + * + * Return value: the event, or %NULL. Ownership is transferred + * to the caller. + **/ +GdkEvent* +_gdk_event_unqueue (GdkDisplay *display) +{ + GdkEvent *event = NULL; + GList *tmp_list; + + tmp_list = _gdk_event_queue_find_first (display); + + if (tmp_list) + { + event = tmp_list->data; + _gdk_event_queue_remove_link (display, tmp_list); + g_list_free_1 (tmp_list); + } + + return event; +} + +/** + * gdk_event_handler_set: + * @func: the function to call to handle events from GDK. + * @data: user data to pass to the function. + * @notify: the function to call when the handler function is removed, i.e. when + * gdk_event_handler_set() is called with another event handler. + * + * Sets the function to call to handle all events from GDK. + * + * Note that GTK+ uses this to install its own event handler, so it is + * usually not useful for GTK+ applications. (Although an application + * can call this function then call gtk_main_do_event() to pass + * events to GTK+.) + **/ +void +gdk_event_handler_set (GdkEventFunc func, + gpointer data, + GDestroyNotify notify) +{ + if (_gdk_event_notify) + (*_gdk_event_notify) (_gdk_event_data); + + _gdk_event_func = func; + _gdk_event_data = data; + _gdk_event_notify = notify; +} + +/** + * gdk_event_get: + * + * Checks all open displays for a #GdkEvent to process,to be processed + * on, fetching events from the windowing system if necessary. + * See gdk_display_get_event(). + * + * Return value: the next #GdkEvent to be processed, or %NULL if no events + * are pending. The returned #GdkEvent should be freed with gdk_event_free(). + **/ +GdkEvent* +gdk_event_get (void) +{ + GSList *tmp_list; + + for (tmp_list = _gdk_displays; tmp_list; tmp_list = tmp_list->next) + { + GdkEvent *event = gdk_display_get_event (tmp_list->data); + if (event) + return event; + } + + return NULL; +} + +/** + * gdk_event_peek: + * + * If there is an event waiting in the event queue of some open + * display, returns a copy of it. See gdk_display_peek_event(). + * + * Return value: a copy of the first #GdkEvent on some event queue, or %NULL if no + * events are in any queues. The returned #GdkEvent should be freed with + * gdk_event_free(). + **/ +GdkEvent* +gdk_event_peek (void) +{ + GSList *tmp_list; + + for (tmp_list = _gdk_displays; tmp_list; tmp_list = tmp_list->next) + { + GdkEvent *event = gdk_display_peek_event (tmp_list->data); + if (event) + return event; + } + + return NULL; +} + +/** + * gdk_event_put: + * @event: a #GdkEvent. + * + * Appends a copy of the given event onto the front of the event + * queue for event->any.window's display, or the default event + * queue if event->any.window is %NULL. See gdk_display_put_event(). + **/ +void +gdk_event_put (const GdkEvent *event) +{ + GdkDisplay *display; + + g_return_if_fail (event != NULL); + + if (event->any.window) + display = gdk_drawable_get_display (event->any.window); + else + { + GDK_NOTE (MULTIHEAD, + g_message ("Falling back to default display for gdk_event_put()")); + display = gdk_display_get_default (); + } + + gdk_display_put_event (display, event); +} + +static GHashTable *event_hash = NULL; + +/** + * gdk_event_new: + * @type: a #GdkEventType + * + * Creates a new event of the given type. All fields are set to 0. + * + * Return value: a newly-allocated #GdkEvent. The returned #GdkEvent + * should be freed with gdk_event_free(). + * + * Since: 2.2 + **/ +GdkEvent* +gdk_event_new (GdkEventType type) +{ + GdkEventPrivate *new_private; + GdkEvent *new_event; + + if (!event_hash) + event_hash = g_hash_table_new (g_direct_hash, NULL); + + new_private = g_slice_new0 (GdkEventPrivate); + + new_private->flags = 0; + new_private->screen = NULL; + + g_hash_table_insert (event_hash, new_private, GUINT_TO_POINTER (1)); + + new_event = (GdkEvent *) new_private; + + new_event->any.type = type; + + /* + * Bytewise 0 initialization is reasonable for most of the + * current event types. Explicitely initialize double fields + * since I trust bytewise 0 == 0. less than for integers + * or pointers. + */ + switch (type) + { + case GDK_MOTION_NOTIFY: + new_event->motion.x = 0.; + new_event->motion.y = 0.; + new_event->motion.x_root = 0.; + new_event->motion.y_root = 0.; + break; + case GDK_BUTTON_PRESS: + case GDK_2BUTTON_PRESS: + case GDK_3BUTTON_PRESS: + case GDK_BUTTON_RELEASE: + new_event->button.x = 0.; + new_event->button.y = 0.; + new_event->button.x_root = 0.; + new_event->button.y_root = 0.; + break; + case GDK_SCROLL: + new_event->scroll.x = 0.; + new_event->scroll.y = 0.; + new_event->scroll.x_root = 0.; + new_event->scroll.y_root = 0.; + new_event->scroll.delta_x = 0.; + new_event->scroll.delta_y = 0.; + break; + case GDK_ENTER_NOTIFY: + case GDK_LEAVE_NOTIFY: + new_event->crossing.x = 0.; + new_event->crossing.y = 0.; + new_event->crossing.x_root = 0.; + new_event->crossing.y_root = 0.; + break; + default: + break; + } + + return new_event; +} + +static gboolean +gdk_event_is_allocated (const GdkEvent *event) +{ + if (event_hash) + return g_hash_table_lookup (event_hash, event) != NULL; + + return FALSE; +} + +/** + * gdk_event_copy: + * @event: a #GdkEvent + * + * Copies a #GdkEvent, copying or incrementing the reference count of the + * resources associated with it (e.g. #GdkWindow's and strings). + * + * Return value: a copy of @event. The returned #GdkEvent should be freed with + * gdk_event_free(). + **/ +GdkEvent* +gdk_event_copy (const GdkEvent *event) +{ + GdkEventPrivate *new_private; + GdkEvent *new_event; + + g_return_val_if_fail (event != NULL, NULL); + + new_event = gdk_event_new (GDK_NOTHING); + new_private = (GdkEventPrivate *)new_event; + + *new_event = *event; + if (new_event->any.window) + g_object_ref (new_event->any.window); + + if (gdk_event_is_allocated (event)) + { + GdkEventPrivate *private = (GdkEventPrivate *)event; + + new_private->screen = private->screen; + } + + switch (event->any.type) + { + case GDK_KEY_PRESS: + case GDK_KEY_RELEASE: + new_event->key.string = g_strdup (event->key.string); + break; + + case GDK_ENTER_NOTIFY: + case GDK_LEAVE_NOTIFY: + if (event->crossing.subwindow != NULL) + g_object_ref (event->crossing.subwindow); + break; + + case GDK_DRAG_ENTER: + case GDK_DRAG_LEAVE: + case GDK_DRAG_MOTION: + case GDK_DRAG_STATUS: + case GDK_DROP_START: + case GDK_DROP_FINISHED: + g_object_ref (event->dnd.context); + break; + + case GDK_EXPOSE: + case GDK_DAMAGE: + if (event->expose.region) + new_event->expose.region = gdk_region_copy (event->expose.region); + break; + + case GDK_SETTING: + new_event->setting.name = g_strdup (new_event->setting.name); + break; + + case GDK_BUTTON_PRESS: + case GDK_BUTTON_RELEASE: + if (event->button.axes) + new_event->button.axes = g_memdup (event->button.axes, + sizeof (gdouble) * event->button.device->num_axes); + break; + + case GDK_MOTION_NOTIFY: + if (event->motion.axes) + new_event->motion.axes = g_memdup (event->motion.axes, + sizeof (gdouble) * event->motion.device->num_axes); + + break; + + default: + break; + } + + if (gdk_event_is_allocated (event)) + _gdk_windowing_event_data_copy (event, new_event); + + return new_event; +} + +/** + * gdk_event_free: + * @event: a #GdkEvent. + * + * Frees a #GdkEvent, freeing or decrementing any resources associated with it. + * Note that this function should only be called with events returned from + * functions such as gdk_event_peek(), gdk_event_get(), + * gdk_event_get_graphics_expose() and gdk_event_copy() and gdk_event_new(). + **/ +void +gdk_event_free (GdkEvent *event) +{ + g_return_if_fail (event != NULL); + + if (event->any.window) + g_object_unref (event->any.window); + + switch (event->any.type) + { + case GDK_KEY_PRESS: + case GDK_KEY_RELEASE: + g_free (event->key.string); + break; + + case GDK_ENTER_NOTIFY: + case GDK_LEAVE_NOTIFY: + if (event->crossing.subwindow != NULL) + g_object_unref (event->crossing.subwindow); + break; + + case GDK_DRAG_ENTER: + case GDK_DRAG_LEAVE: + case GDK_DRAG_MOTION: + case GDK_DRAG_STATUS: + case GDK_DROP_START: + case GDK_DROP_FINISHED: + g_object_unref (event->dnd.context); + break; + + case GDK_BUTTON_PRESS: + case GDK_BUTTON_RELEASE: + g_free (event->button.axes); + break; + + case GDK_EXPOSE: + case GDK_DAMAGE: + if (event->expose.region) + gdk_region_destroy (event->expose.region); + break; + + case GDK_MOTION_NOTIFY: + g_free (event->motion.axes); + break; + + case GDK_SETTING: + g_free (event->setting.name); + break; + + default: + break; + } + + _gdk_windowing_event_data_free (event); + + g_hash_table_remove (event_hash, event); + g_slice_free (GdkEventPrivate, (GdkEventPrivate*) event); +} + +/** + * gdk_event_get_time: + * @event: a #GdkEvent + * + * Returns the time stamp from @event, if there is one; otherwise + * returns #GDK_CURRENT_TIME. If @event is %NULL, returns #GDK_CURRENT_TIME. + * + * Return value: time stamp field from @event + **/ +guint32 +gdk_event_get_time (const GdkEvent *event) +{ + if (event) + switch (event->type) + { + case GDK_MOTION_NOTIFY: + return event->motion.time; + case GDK_BUTTON_PRESS: + case GDK_2BUTTON_PRESS: + case GDK_3BUTTON_PRESS: + case GDK_BUTTON_RELEASE: + return event->button.time; + case GDK_SCROLL: + return event->scroll.time; + case GDK_KEY_PRESS: + case GDK_KEY_RELEASE: + return event->key.time; + case GDK_ENTER_NOTIFY: + case GDK_LEAVE_NOTIFY: + return event->crossing.time; + case GDK_PROPERTY_NOTIFY: + return event->property.time; + case GDK_SELECTION_CLEAR: + case GDK_SELECTION_REQUEST: + case GDK_SELECTION_NOTIFY: + return event->selection.time; + case GDK_PROXIMITY_IN: + case GDK_PROXIMITY_OUT: + return event->proximity.time; + case GDK_DRAG_ENTER: + case GDK_DRAG_LEAVE: + case GDK_DRAG_MOTION: + case GDK_DRAG_STATUS: + case GDK_DROP_START: + case GDK_DROP_FINISHED: + return event->dnd.time; + case GDK_CLIENT_EVENT: + case GDK_VISIBILITY_NOTIFY: + case GDK_NO_EXPOSE: + case GDK_CONFIGURE: + case GDK_FOCUS_CHANGE: + case GDK_NOTHING: + case GDK_DAMAGE: + case GDK_DELETE: + case GDK_DESTROY: + case GDK_EXPOSE: + case GDK_MAP: + case GDK_UNMAP: + case GDK_WINDOW_STATE: + case GDK_SETTING: + case GDK_OWNER_CHANGE: + case GDK_GRAB_BROKEN: + case GDK_EVENT_LAST: + /* return current time */ + break; + } + + return GDK_CURRENT_TIME; +} + +/** + * gdk_event_get_state: + * @event: a #GdkEvent or NULL + * @state: (out): return location for state + * + * If the event contains a "state" field, puts that field in @state. Otherwise + * stores an empty state (0). Returns %TRUE if there was a state field + * in the event. @event may be %NULL, in which case it's treated + * as if the event had no state field. + * + * Return value: %TRUE if there was a state field in the event + **/ +gboolean +gdk_event_get_state (const GdkEvent *event, + GdkModifierType *state) +{ + g_return_val_if_fail (state != NULL, FALSE); + + if (event) + switch (event->type) + { + case GDK_MOTION_NOTIFY: + *state = event->motion.state; + return TRUE; + case GDK_BUTTON_PRESS: + case GDK_2BUTTON_PRESS: + case GDK_3BUTTON_PRESS: + case GDK_BUTTON_RELEASE: + *state = event->button.state; + return TRUE; + case GDK_SCROLL: + *state = event->scroll.state; + return TRUE; + case GDK_KEY_PRESS: + case GDK_KEY_RELEASE: + *state = event->key.state; + return TRUE; + case GDK_ENTER_NOTIFY: + case GDK_LEAVE_NOTIFY: + *state = event->crossing.state; + return TRUE; + case GDK_PROPERTY_NOTIFY: + *state = event->property.state; + return TRUE; + case GDK_VISIBILITY_NOTIFY: + case GDK_CLIENT_EVENT: + case GDK_NO_EXPOSE: + case GDK_CONFIGURE: + case GDK_FOCUS_CHANGE: + case GDK_SELECTION_CLEAR: + case GDK_SELECTION_REQUEST: + case GDK_SELECTION_NOTIFY: + case GDK_PROXIMITY_IN: + case GDK_PROXIMITY_OUT: + case GDK_DAMAGE: + case GDK_DRAG_ENTER: + case GDK_DRAG_LEAVE: + case GDK_DRAG_MOTION: + case GDK_DRAG_STATUS: + case GDK_DROP_START: + case GDK_DROP_FINISHED: + case GDK_NOTHING: + case GDK_DELETE: + case GDK_DESTROY: + case GDK_EXPOSE: + case GDK_MAP: + case GDK_UNMAP: + case GDK_WINDOW_STATE: + case GDK_SETTING: + case GDK_OWNER_CHANGE: + case GDK_GRAB_BROKEN: + case GDK_EVENT_LAST: + /* no state field */ + break; + } + + *state = 0; + return FALSE; +} + +/** + * gdk_event_get_coords: + * @event: a #GdkEvent + * @x_win: (out): location to put event window x coordinate + * @y_win: (out): location to put event window y coordinate + * + * Extract the event window relative x/y coordinates from an event. + * + * Return value: %TRUE if the event delivered event window coordinates + **/ +gboolean +gdk_event_get_coords (const GdkEvent *event, + gdouble *x_win, + gdouble *y_win) +{ + gdouble x = 0, y = 0; + gboolean fetched = TRUE; + + g_return_val_if_fail (event != NULL, FALSE); + + switch (event->type) + { + case GDK_CONFIGURE: + x = event->configure.x; + y = event->configure.y; + break; + case GDK_ENTER_NOTIFY: + case GDK_LEAVE_NOTIFY: + x = event->crossing.x; + y = event->crossing.y; + break; + case GDK_SCROLL: + x = event->scroll.x; + y = event->scroll.y; + break; + case GDK_BUTTON_PRESS: + case GDK_2BUTTON_PRESS: + case GDK_3BUTTON_PRESS: + case GDK_BUTTON_RELEASE: + x = event->button.x; + y = event->button.y; + break; + case GDK_MOTION_NOTIFY: + x = event->motion.x; + y = event->motion.y; + break; + default: + fetched = FALSE; + break; + } + + if (x_win) + *x_win = x; + if (y_win) + *y_win = y; + + return fetched; +} + +/** + * gdk_event_get_root_coords: + * @event: a #GdkEvent + * @x_root: (out): location to put root window x coordinate + * @y_root: (out): location to put root window y coordinate + * + * Extract the root window relative x/y coordinates from an event. + * + * Return value: %TRUE if the event delivered root window coordinates + **/ +gboolean +gdk_event_get_root_coords (const GdkEvent *event, + gdouble *x_root, + gdouble *y_root) +{ + gdouble x = 0, y = 0; + gboolean fetched = TRUE; + + g_return_val_if_fail (event != NULL, FALSE); + + switch (event->type) + { + case GDK_MOTION_NOTIFY: + x = event->motion.x_root; + y = event->motion.y_root; + break; + case GDK_SCROLL: + x = event->scroll.x_root; + y = event->scroll.y_root; + break; + case GDK_BUTTON_PRESS: + case GDK_2BUTTON_PRESS: + case GDK_3BUTTON_PRESS: + case GDK_BUTTON_RELEASE: + x = event->button.x_root; + y = event->button.y_root; + break; + case GDK_ENTER_NOTIFY: + case GDK_LEAVE_NOTIFY: + x = event->crossing.x_root; + y = event->crossing.y_root; + break; + case GDK_DRAG_ENTER: + case GDK_DRAG_LEAVE: + case GDK_DRAG_MOTION: + case GDK_DRAG_STATUS: + case GDK_DROP_START: + case GDK_DROP_FINISHED: + x = event->dnd.x_root; + y = event->dnd.y_root; + break; + default: + fetched = FALSE; + break; + } + + if (x_root) + *x_root = x; + if (y_root) + *y_root = y; + + return fetched; +} + +gboolean +gdk_event_get_scroll_deltas (const GdkEvent *event, + gdouble *delta_x, + gdouble *delta_y) +{ + gboolean fetched = TRUE; + gdouble dx = 0.0; + gdouble dy = 0.0; + + switch (event->type) + { + case GDK_SCROLL: + fetched = event->scroll.has_deltas; + dx = event->scroll.delta_x; + dy = event->scroll.delta_y; + break; + default: + fetched = FALSE; + break; + } + + if (delta_x) + *delta_x = dx; + + if (delta_y) + *delta_y = dy; + + return fetched; +} + +/** + * gdk_event_get_axis: + * @event: a #GdkEvent + * @axis_use: the axis use to look for + * @value: (out): location to store the value found + * + * Extract the axis value for a particular axis use from + * an event structure. + * + * Return value: %TRUE if the specified axis was found, otherwise %FALSE + **/ +gboolean +gdk_event_get_axis (const GdkEvent *event, + GdkAxisUse axis_use, + gdouble *value) +{ + gdouble *axes; + GdkDevice *device; + + g_return_val_if_fail (event != NULL, FALSE); + + if (axis_use == GDK_AXIS_X || axis_use == GDK_AXIS_Y) + { + gdouble x, y; + + switch (event->type) + { + case GDK_MOTION_NOTIFY: + x = event->motion.x; + y = event->motion.y; + break; + case GDK_SCROLL: + x = event->scroll.x; + y = event->scroll.y; + break; + case GDK_BUTTON_PRESS: + case GDK_BUTTON_RELEASE: + x = event->button.x; + y = event->button.y; + break; + case GDK_ENTER_NOTIFY: + case GDK_LEAVE_NOTIFY: + x = event->crossing.x; + y = event->crossing.y; + break; + + default: + return FALSE; + } + + if (axis_use == GDK_AXIS_X && value) + *value = x; + if (axis_use == GDK_AXIS_Y && value) + *value = y; + + return TRUE; + } + else if (event->type == GDK_BUTTON_PRESS || + event->type == GDK_BUTTON_RELEASE) + { + device = event->button.device; + axes = event->button.axes; + } + else if (event->type == GDK_MOTION_NOTIFY) + { + device = event->motion.device; + axes = event->motion.axes; + } + else + return FALSE; + + return gdk_device_get_axis (device, axes, axis_use, value); +} + +/** + * gdk_event_request_motions: + * @event: a valid #GdkEvent + * + * Request more motion notifies if @event is a motion notify hint event. + * This function should be used instead of gdk_window_get_pointer() to + * request further motion notifies, because it also works for extension + * events where motion notifies are provided for devices other than the + * core pointer. Coordinate extraction, processing and requesting more + * motion events from a %GDK_MOTION_NOTIFY event usually works like this: + * + * |[ + * { + * /* motion_event handler */ + * x = motion_event->x; + * y = motion_event->y; + * /* handle (x,y) motion */ + * gdk_event_request_motions (motion_event); /* handles is_hint events */ + * } + * ]| + * + * Since: 2.12 + **/ +void +gdk_event_request_motions (const GdkEventMotion *event) +{ + GdkDisplay *display; + + g_return_if_fail (event != NULL); + + if (event->type == GDK_MOTION_NOTIFY && event->is_hint) + { + gdk_device_get_state (event->device, event->window, NULL, NULL); + + display = gdk_drawable_get_display (event->window); + _gdk_display_enable_motion_hints (display); + } +} + +/** + * gdk_event_set_screen: + * @event: a #GdkEvent + * @screen: a #GdkScreen + * + * Sets the screen for @event to @screen. The event must + * have been allocated by GTK+, for instance, by + * gdk_event_copy(). + * + * Since: 2.2 + **/ +void +gdk_event_set_screen (GdkEvent *event, + GdkScreen *screen) +{ + GdkEventPrivate *private; + + g_return_if_fail (gdk_event_is_allocated (event)); + + private = (GdkEventPrivate *)event; + + private->screen = screen; +} + +/** + * gdk_event_get_screen: + * @event: a #GdkEvent + * + * Returns the screen for the event. The screen is + * typically the screen for event->any.window, but + * for events such as mouse events, it is the screen + * where the pointer was when the event occurs - + * that is, the screen which has the root window + * to which event->motion.x_root and + * event->motion.y_root are relative. + * + * Return value: the screen for the event + * + * Since: 2.2 + **/ +GdkScreen * +gdk_event_get_screen (const GdkEvent *event) +{ + if (gdk_event_is_allocated (event)) + { + GdkEventPrivate *private = (GdkEventPrivate *)event; + + if (private->screen) + return private->screen; + } + + if (event->any.window) + return gdk_drawable_get_screen (event->any.window); + + return NULL; +} + +/** + * gdk_set_show_events: + * @show_events: %TRUE to output event debugging information. + * + * Sets whether a trace of received events is output. + * Note that GTK+ must be compiled with debugging (that is, + * configured using the option) + * to use this option. + **/ +void +gdk_set_show_events (gboolean show_events) +{ + if (show_events) + _gdk_debug_flags |= GDK_DEBUG_EVENTS; + else + _gdk_debug_flags &= ~GDK_DEBUG_EVENTS; +} + +/** + * gdk_get_show_events: + * + * Gets whether event debugging output is enabled. + * + * Return value: %TRUE if event debugging output is enabled. + **/ +gboolean +gdk_get_show_events (void) +{ + return (_gdk_debug_flags & GDK_DEBUG_EVENTS) != 0; +} + +static void +gdk_io_destroy (gpointer data) +{ + GdkIOClosure *closure = data; + + if (closure->notify) + closure->notify (closure->data); + + g_free (closure); +} + +/* What do we do with G_IO_NVAL? + */ +#define READ_CONDITION (G_IO_IN | G_IO_HUP | G_IO_ERR) +#define WRITE_CONDITION (G_IO_OUT | G_IO_ERR) +#define EXCEPTION_CONDITION (G_IO_PRI) + +static gboolean +gdk_io_invoke (GIOChannel *source, + GIOCondition condition, + gpointer data) +{ + GdkIOClosure *closure = data; + GdkInputCondition gdk_cond = 0; + + if (condition & READ_CONDITION) + gdk_cond |= GDK_INPUT_READ; + if (condition & WRITE_CONDITION) + gdk_cond |= GDK_INPUT_WRITE; + if (condition & EXCEPTION_CONDITION) + gdk_cond |= GDK_INPUT_EXCEPTION; + + if (closure->condition & gdk_cond) + closure->function (closure->data, g_io_channel_unix_get_fd (source), gdk_cond); + + return TRUE; +} + +/** + * gdk_input_add_full: + * @source: a file descriptor. + * @condition: the condition. + * @function: the callback function. + * @data: callback data passed to @function. + * @destroy: callback function to call with @data when the input + * handler is removed. + * + * Establish a callback when a condition becomes true on + * a file descriptor. + * + * Returns: a tag that can later be used as an argument to + * gdk_input_remove(). + * + * Deprecated: 2.14: Use g_io_add_watch_full() on a #GIOChannel + */ +gint +gdk_input_add_full (gint source, + GdkInputCondition condition, + GdkInputFunction function, + gpointer data, + GDestroyNotify destroy) +{ + guint result; + GdkIOClosure *closure = g_new (GdkIOClosure, 1); + GIOChannel *channel; + GIOCondition cond = 0; + + closure->function = function; + closure->condition = condition; + closure->notify = destroy; + closure->data = data; + + if (condition & GDK_INPUT_READ) + cond |= READ_CONDITION; + if (condition & GDK_INPUT_WRITE) + cond |= WRITE_CONDITION; + if (condition & GDK_INPUT_EXCEPTION) + cond |= EXCEPTION_CONDITION; + + channel = g_io_channel_unix_new (source); + result = g_io_add_watch_full (channel, G_PRIORITY_DEFAULT, cond, + gdk_io_invoke, + closure, gdk_io_destroy); + g_io_channel_unref (channel); + + return result; +} + +/** + * gdk_input_add: + * @source: a file descriptor. + * @condition: the condition. + * @function: the callback function. + * @data: callback data passed to @function. + * + * Establish a callback when a condition becomes true on + * a file descriptor. + * + * Returns: a tag that can later be used as an argument to + * gdk_input_remove(). + * + * Deprecated: 2.14: Use g_io_add_watch() on a #GIOChannel + */ +gint +gdk_input_add (gint source, + GdkInputCondition condition, + GdkInputFunction function, + gpointer data) +{ + return gdk_input_add_full (source, condition, function, data, NULL); +} + +void +gdk_input_remove (gint tag) +{ + g_source_remove (tag); +} + +static void +gdk_synthesize_click (GdkDisplay *display, + GdkEvent *event, + gint nclicks) +{ + GdkEvent temp_event; + GdkEvent *event_copy; + GList *link; + + g_return_if_fail (event != NULL); + + temp_event = *event; + temp_event.type = (nclicks == 2) ? GDK_2BUTTON_PRESS : GDK_3BUTTON_PRESS; + + event_copy = gdk_event_copy (&temp_event); + link = _gdk_event_queue_append (display, event_copy); +} + +void +_gdk_event_button_generate (GdkDisplay *display, + GdkEvent *event) +{ + if ((event->button.time < (display->button_click_time[1] + 2*display->double_click_time)) && + (event->button.window == display->button_window[1]) && + (event->button.button == display->button_number[1]) && + (ABS (event->button.x - display->button_x[1]) <= display->double_click_distance) && + (ABS (event->button.y - display->button_y[1]) <= display->double_click_distance)) +{ + gdk_synthesize_click (display, event, 3); + + display->button_click_time[1] = 0; + display->button_click_time[0] = 0; + display->button_window[1] = NULL; + display->button_window[0] = NULL; + display->button_number[1] = -1; + display->button_number[0] = -1; + display->button_x[0] = display->button_x[1] = 0; + display->button_y[0] = display->button_y[1] = 0; + } + else if ((event->button.time < (display->button_click_time[0] + display->double_click_time)) && + (event->button.window == display->button_window[0]) && + (event->button.button == display->button_number[0]) && + (ABS (event->button.x - display->button_x[0]) <= display->double_click_distance) && + (ABS (event->button.y - display->button_y[0]) <= display->double_click_distance)) + { + gdk_synthesize_click (display, event, 2); + + display->button_click_time[1] = display->button_click_time[0]; + display->button_click_time[0] = event->button.time; + display->button_window[1] = display->button_window[0]; + display->button_window[0] = event->button.window; + display->button_number[1] = display->button_number[0]; + display->button_number[0] = event->button.button; + display->button_x[1] = display->button_x[0]; + display->button_x[0] = event->button.x; + display->button_y[1] = display->button_y[0]; + display->button_y[0] = event->button.y; + } + else + { + display->button_click_time[1] = 0; + display->button_click_time[0] = event->button.time; + display->button_window[1] = NULL; + display->button_window[0] = event->button.window; + display->button_number[1] = -1; + display->button_number[0] = event->button.button; + display->button_x[1] = 0; + display->button_x[0] = event->button.x; + display->button_y[1] = 0; + display->button_y[0] = event->button.y; + } +} + +void +gdk_synthesize_window_state (GdkWindow *window, + GdkWindowState unset_flags, + GdkWindowState set_flags) +{ + GdkEvent temp_event; + GdkWindowState old; + + g_return_if_fail (window != NULL); + + temp_event.window_state.window = window; + temp_event.window_state.type = GDK_WINDOW_STATE; + temp_event.window_state.send_event = FALSE; + + old = ((GdkWindowObject*) temp_event.window_state.window)->state; + + temp_event.window_state.new_window_state = old; + temp_event.window_state.new_window_state |= set_flags; + temp_event.window_state.new_window_state &= ~unset_flags; + temp_event.window_state.changed_mask = temp_event.window_state.new_window_state ^ old; + + if (temp_event.window_state.new_window_state == old) + return; /* No actual work to do, nothing changed. */ + + /* Actually update the field in GdkWindow, this is sort of an odd + * place to do it, but seems like the safest since it ensures we expose no + * inconsistent state to the user. + */ + + ((GdkWindowObject*) window)->state = temp_event.window_state.new_window_state; + + if (temp_event.window_state.changed_mask & GDK_WINDOW_STATE_WITHDRAWN) + _gdk_window_update_viewable (window); + + /* We only really send the event to toplevels, since + * all the window states don't apply to non-toplevels. + * Non-toplevels do use the GDK_WINDOW_STATE_WITHDRAWN flag + * internally so we needed to update window->state. + */ + switch (((GdkWindowObject*) window)->window_type) + { + case GDK_WINDOW_TOPLEVEL: + case GDK_WINDOW_DIALOG: + case GDK_WINDOW_TEMP: /* ? */ + gdk_display_put_event (gdk_drawable_get_display (window), &temp_event); + break; + + case GDK_WINDOW_FOREIGN: + case GDK_WINDOW_ROOT: + case GDK_WINDOW_CHILD: + break; + } +} + +/** + * gdk_display_set_double_click_time: + * @display: a #GdkDisplay + * @msec: double click time in milliseconds (thousandths of a second) + * + * Sets the double click time (two clicks within this time interval + * count as a double click and result in a #GDK_2BUTTON_PRESS event). + * Applications should not set this, it is a global + * user-configured setting. + * + * Since: 2.2 + **/ +void +gdk_display_set_double_click_time (GdkDisplay *display, + guint msec) +{ + display->double_click_time = msec; +} + +/** + * gdk_set_double_click_time: + * @msec: double click time in milliseconds (thousandths of a second) + * + * Set the double click time for the default display. See + * gdk_display_set_double_click_time(). + * See also gdk_display_set_double_click_distance(). + * Applications should not set this, it is a + * global user-configured setting. + **/ +void +gdk_set_double_click_time (guint msec) +{ + gdk_display_set_double_click_time (gdk_display_get_default (), msec); +} + +/** + * gdk_display_set_double_click_distance: + * @display: a #GdkDisplay + * @distance: distance in pixels + * + * Sets the double click distance (two clicks within this distance + * count as a double click and result in a #GDK_2BUTTON_PRESS event). + * See also gdk_display_set_double_click_time(). + * Applications should not set this, it is a global + * user-configured setting. + * + * Since: 2.4 + **/ +void +gdk_display_set_double_click_distance (GdkDisplay *display, + guint distance) +{ + display->double_click_distance = distance; +} + +GType +gdk_event_get_type (void) +{ + static GType our_type = 0; + + if (our_type == 0) + our_type = g_boxed_type_register_static (g_intern_static_string ("GdkEvent"), + (GBoxedCopyFunc)gdk_event_copy, + (GBoxedFreeFunc)gdk_event_free); + return our_type; +} + +/** + * gdk_setting_get: + * @name: the name of the setting. + * @value: location to store the value of the setting. + * + * Obtains a desktop-wide setting, such as the double-click time, + * for the default screen. See gdk_screen_get_setting(). + * + * Returns: %TRUE if the setting existed and a value was stored + * in @value, %FALSE otherwise. + **/ +gboolean +gdk_setting_get (const gchar *name, + GValue *value) +{ + return gdk_screen_get_setting (gdk_screen_get_default (), name, value); +} + +#define __GDK_EVENTS_C__ +#include "gdkaliasdef.c" diff --git a/libs/tk/ydk/gdkfont.c b/libs/tk/ydk/gdkfont.c new file mode 100644 index 0000000000..8d98a0016e --- /dev/null +++ b/libs/tk/ydk/gdkfont.c @@ -0,0 +1,359 @@ +/* GDK - The GIMP Drawing Kit + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, 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/. + */ + +#undef GDK_DISABLE_DEPRECATED + +#include "config.h" +#include "gdkdisplay.h" +#include "gdkfont.h" +#include "gdkinternals.h" +#include "gdkalias.h" + +GType +gdk_font_get_type (void) +{ + static GType our_type = 0; + + if (our_type == 0) + our_type = g_boxed_type_register_static (g_intern_static_string ("GdkFont"), + (GBoxedCopyFunc)gdk_font_ref, + (GBoxedFreeFunc)gdk_font_unref); + return our_type; +} + +/** + * gdk_font_ref: + * @font: a #GdkFont + * + * Increases the reference count of a font by one. + * + * Return value: @font + **/ +GdkFont* +gdk_font_ref (GdkFont *font) +{ + GdkFontPrivate *private; + + g_return_val_if_fail (font != NULL, NULL); + + private = (GdkFontPrivate*) font; + private->ref_count += 1; + return font; +} + +/** + * gdk_font_unref: + * @font: a #GdkFont + * + * Decreases the reference count of a font by one. + * If the result is zero, destroys the font. + **/ +void +gdk_font_unref (GdkFont *font) +{ + GdkFontPrivate *private; + private = (GdkFontPrivate*) font; + + g_return_if_fail (font != NULL); + g_return_if_fail (private->ref_count > 0); + + private->ref_count -= 1; + if (private->ref_count == 0) + _gdk_font_destroy (font); +} + +/** + * gdk_string_width: + * @font: a #GdkFont + * @string: the nul-terminated string to measure + * + * Determines the width of a nul-terminated string. + * (The distance from the origin of the string to the + * point where the next string in a sequence of strings + * should be drawn) + * + * Return value: the width of the string in pixels. + **/ +gint +gdk_string_width (GdkFont *font, + const gchar *string) +{ + g_return_val_if_fail (font != NULL, -1); + g_return_val_if_fail (string != NULL, -1); + + return gdk_text_width (font, string, _gdk_font_strlen (font, string)); +} + +/** + * gdk_char_width: + * @font: a #GdkFont + * @character: the character to measure. + * + * Determines the width of a given character. + * + * Return value: the width of the character in pixels. + * + * Deprecated: 2.2: Use gdk_text_extents() instead. + **/ +gint +gdk_char_width (GdkFont *font, + gchar character) +{ + g_return_val_if_fail (font != NULL, -1); + + return gdk_text_width (font, &character, 1); +} + +/** + * gdk_char_width_wc: + * @font: a #GdkFont + * @character: the character to measure. + * + * Determines the width of a given wide character. (Encoded + * in the wide-character encoding of the current locale). + * + * Return value: the width of the character in pixels. + **/ +gint +gdk_char_width_wc (GdkFont *font, + GdkWChar character) +{ + g_return_val_if_fail (font != NULL, -1); + + return gdk_text_width_wc (font, &character, 1); +} + +/** + * gdk_string_measure: + * @font: a #GdkFont + * @string: the nul-terminated string to measure. + * + * Determines the distance from the origin to the rightmost + * portion of a nul-terminated string when drawn. This is not the + * correct value for determining the origin of the next + * portion when drawing text in multiple pieces. + * See gdk_string_width(). + * + * Return value: the right bearing of the string in pixels. + **/ +gint +gdk_string_measure (GdkFont *font, + const gchar *string) +{ + g_return_val_if_fail (font != NULL, -1); + g_return_val_if_fail (string != NULL, -1); + + return gdk_text_measure (font, string, _gdk_font_strlen (font, string)); +} + +/** + * gdk_string_extents: + * @font: a #GdkFont. + * @string: the nul-terminated string to measure. + * @lbearing: the left bearing of the string. + * @rbearing: the right bearing of the string. + * @width: the width of the string. + * @ascent: the ascent of the string. + * @descent: the descent of the string. + * + * Gets the metrics of a nul-terminated string. + **/ +void +gdk_string_extents (GdkFont *font, + const gchar *string, + gint *lbearing, + gint *rbearing, + gint *width, + gint *ascent, + gint *descent) +{ + g_return_if_fail (font != NULL); + g_return_if_fail (string != NULL); + + gdk_text_extents (font, string, _gdk_font_strlen (font, string), + lbearing, rbearing, width, ascent, descent); +} + + +/** + * gdk_text_measure: + * @font: a #GdkFont + * @text: the text to measure. + * @text_length: the length of the text in bytes. + * + * Determines the distance from the origin to the rightmost + * portion of a string when drawn. This is not the + * correct value for determining the origin of the next + * portion when drawing text in multiple pieces. + * See gdk_text_width(). + * + * Return value: the right bearing of the string in pixels. + **/ +gint +gdk_text_measure (GdkFont *font, + const gchar *text, + gint text_length) +{ + gint rbearing; + + g_return_val_if_fail (font != NULL, -1); + g_return_val_if_fail (text != NULL, -1); + + gdk_text_extents (font, text, text_length, NULL, &rbearing, NULL, NULL, NULL); + return rbearing; +} + +/** + * gdk_char_measure: + * @font: a #GdkFont + * @character: the character to measure. + * + * Determines the distance from the origin to the rightmost + * portion of a character when drawn. This is not the + * correct value for determining the origin of the next + * portion when drawing text in multiple pieces. + * + * Return value: the right bearing of the character in pixels. + **/ +gint +gdk_char_measure (GdkFont *font, + gchar character) +{ + g_return_val_if_fail (font != NULL, -1); + + return gdk_text_measure (font, &character, 1); +} + +/** + * gdk_string_height: + * @font: a #GdkFont + * @string: the nul-terminated string to measure. + * + * Determines the total height of a given nul-terminated + * string. This value is not generally useful, because you + * cannot determine how this total height will be drawn in + * relation to the baseline. See gdk_string_extents(). + * + * Return value: the height of the string in pixels. + **/ +gint +gdk_string_height (GdkFont *font, + const gchar *string) +{ + g_return_val_if_fail (font != NULL, -1); + g_return_val_if_fail (string != NULL, -1); + + return gdk_text_height (font, string, _gdk_font_strlen (font, string)); +} + +/** + * gdk_text_height: + * @font: a #GdkFont + * @text: the text to measure. + * @text_length: the length of the text in bytes. + * + * Determines the total height of a given string. + * This value is not generally useful, because you cannot + * determine how this total height will be drawn in + * relation to the baseline. See gdk_text_extents(). + * + * Return value: the height of the string in pixels. + **/ +gint +gdk_text_height (GdkFont *font, + const gchar *text, + gint text_length) +{ + gint ascent, descent; + + g_return_val_if_fail (font != NULL, -1); + g_return_val_if_fail (text != NULL, -1); + + gdk_text_extents (font, text, text_length, NULL, NULL, NULL, &ascent, &descent); + return ascent + descent; +} + +/** + * gdk_char_height: + * @font: a #GdkFont + * @character: the character to measure. + * + * Determines the total height of a given character. + * This value is not generally useful, because you cannot + * determine how this total height will be drawn in + * relation to the baseline. See gdk_text_extents(). + * + * Return value: the height of the character in pixels. + * + * Deprecated: 2.2: Use gdk_text_extents() instead. + **/ +gint +gdk_char_height (GdkFont *font, + gchar character) +{ + g_return_val_if_fail (font != NULL, -1); + + return gdk_text_height (font, &character, 1); +} + +/** + * gdk_font_from_description: + * @font_desc: a #PangoFontDescription. + * + * Load a #GdkFont based on a Pango font description. This font will + * only be an approximation of the Pango font, and + * internationalization will not be handled correctly. This function + * should only be used for legacy code that cannot be easily converted + * to use Pango. Using Pango directly will produce better results. + * + * Return value: the newly loaded font, or %NULL if the font + * cannot be loaded. + **/ +GdkFont* +gdk_font_from_description (PangoFontDescription *font_desc) +{ + return gdk_font_from_description_for_display (gdk_display_get_default (),font_desc); +} + +/** + * gdk_font_load: + * @font_name: a XLFD describing the font to load. + * + * Loads a font. + * + * The font may be newly loaded or looked up the font in a cache. + * You should make no assumptions about the initial reference count. + * + * Return value: a #GdkFont, or %NULL if the font could not be loaded. + **/ +GdkFont* +gdk_font_load (const gchar *font_name) +{ + return gdk_font_load_for_display (gdk_display_get_default(), font_name); +} + +#define __GDK_FONT_C__ +#include "gdkaliasdef.c" diff --git a/libs/tk/ydk/gdkgc.c b/libs/tk/ydk/gdkgc.c new file mode 100644 index 0000000000..587c20d952 --- /dev/null +++ b/libs/tk/ydk/gdkgc.c @@ -0,0 +1,1599 @@ +/* GDK - The GIMP Drawing Kit + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, 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 "config.h" +#include + +#include "gdkcairo.h" +#include "gdkgc.h" +#include "gdkinternals.h" +#include "gdkpixmap.h" +#include "gdkrgb.h" +#include "gdkprivate.h" +#include "gdkalias.h" + +static void gdk_gc_finalize (GObject *object); + +typedef struct _GdkGCPrivate GdkGCPrivate; + +struct _GdkGCPrivate +{ + GdkRegion *clip_region; + + guint32 region_tag_applied; + int region_tag_offset_x; + int region_tag_offset_y; + + GdkRegion *old_clip_region; + GdkPixmap *old_clip_mask; + + GdkBitmap *stipple; + GdkPixmap *tile; + + GdkPixmap *clip_mask; + + guint32 fg_pixel; + guint32 bg_pixel; + + guint subwindow_mode : 1; + guint fill : 2; + guint exposures : 2; +}; + +#define GDK_GC_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDK_TYPE_GC, GdkGCPrivate)) + +G_DEFINE_TYPE (GdkGC, gdk_gc, G_TYPE_OBJECT) + +static void +gdk_gc_class_init (GdkGCClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + + object_class->finalize = gdk_gc_finalize; + + g_type_class_add_private (object_class, sizeof (GdkGCPrivate)); +} + +static void +gdk_gc_init (GdkGC *gc) +{ + GdkGCPrivate *priv = GDK_GC_GET_PRIVATE (gc); + + priv->fill = GDK_SOLID; + + /* These are the default X11 value, which we match. They are clearly + * wrong for TrueColor displays, so apps have to change them. + */ + priv->fg_pixel = 0; + priv->bg_pixel = 1; +} + +/** + * gdk_gc_new: + * @drawable: a #GdkDrawable. The created GC must always be used + * with drawables of the same depth as this one. + * + * Create a new graphics context with default values. + * + * Returns: the new graphics context. + * + * Deprecated: 2.22: Use Cairo for rendering. + **/ +GdkGC* +gdk_gc_new (GdkDrawable *drawable) +{ + g_return_val_if_fail (drawable != NULL, NULL); + + return gdk_gc_new_with_values (drawable, NULL, 0); +} + +/** + * gdk_gc_new_with_values: + * @drawable: a #GdkDrawable. The created GC must always be used + * with drawables of the same depth as this one. + * @values: a structure containing initial values for the GC. + * @values_mask: a bit mask indicating which fields in @values + * are set. + * + * Create a new GC with the given initial values. + * + * Return value: the new graphics context. + * + * Deprecated: 2.22: Use Cairo for rendering. + **/ +GdkGC* +gdk_gc_new_with_values (GdkDrawable *drawable, + GdkGCValues *values, + GdkGCValuesMask values_mask) +{ + g_return_val_if_fail (drawable != NULL, NULL); + + return GDK_DRAWABLE_GET_CLASS (drawable)->create_gc (drawable, + values, + values_mask); +} + +/** + * _gdk_gc_init: + * @gc: a #GdkGC + * @drawable: a #GdkDrawable. + * @values: a structure containing initial values for the GC. + * @values_mask: a bit mask indicating which fields in @values + * are set. + * + * Does initialization of the generic portions of a #GdkGC + * created with the specified values and values_mask. This + * should be called out of the implementation of + * GdkDrawable.create_gc() immediately after creating the + * #GdkGC object. + * + * Deprecated: 2.22: Use Cairo for rendering. + **/ +void +_gdk_gc_init (GdkGC *gc, + GdkDrawable *drawable, + GdkGCValues *values, + GdkGCValuesMask values_mask) +{ + GdkGCPrivate *priv; + + g_return_if_fail (GDK_IS_GC (gc)); + + priv = GDK_GC_GET_PRIVATE (gc); + + if (values_mask & GDK_GC_CLIP_X_ORIGIN) + gc->clip_x_origin = values->clip_x_origin; + if (values_mask & GDK_GC_CLIP_Y_ORIGIN) + gc->clip_y_origin = values->clip_y_origin; + if ((values_mask & GDK_GC_CLIP_MASK) && values->clip_mask) + priv->clip_mask = g_object_ref (values->clip_mask); + if (values_mask & GDK_GC_TS_X_ORIGIN) + gc->ts_x_origin = values->ts_x_origin; + if (values_mask & GDK_GC_TS_Y_ORIGIN) + gc->ts_y_origin = values->ts_y_origin; + if (values_mask & GDK_GC_FILL) + priv->fill = values->fill; + if (values_mask & GDK_GC_STIPPLE) + { + priv->stipple = values->stipple; + if (priv->stipple) + g_object_ref (priv->stipple); + } + if (values_mask & GDK_GC_TILE) + { + priv->tile = values->tile; + if (priv->tile) + g_object_ref (priv->tile); + } + if (values_mask & GDK_GC_FOREGROUND) + priv->fg_pixel = values->foreground.pixel; + if (values_mask & GDK_GC_BACKGROUND) + priv->bg_pixel = values->background.pixel; + if (values_mask & GDK_GC_SUBWINDOW) + priv->subwindow_mode = values->subwindow_mode; + if (values_mask & GDK_GC_EXPOSURES) + priv->exposures = values->graphics_exposures; + else + priv->exposures = TRUE; + + gc->colormap = gdk_drawable_get_colormap (drawable); + if (gc->colormap) + g_object_ref (gc->colormap); +} + +static void +gdk_gc_finalize (GObject *object) +{ + GdkGC *gc = GDK_GC (object); + GdkGCPrivate *priv = GDK_GC_GET_PRIVATE (gc); + + if (priv->clip_region) + gdk_region_destroy (priv->clip_region); + if (priv->old_clip_region) + gdk_region_destroy (priv->old_clip_region); + if (priv->clip_mask) + g_object_unref (priv->clip_mask); + if (priv->old_clip_mask) + g_object_unref (priv->old_clip_mask); + if (gc->colormap) + g_object_unref (gc->colormap); + if (priv->tile) + g_object_unref (priv->tile); + if (priv->stipple) + g_object_unref (priv->stipple); + + G_OBJECT_CLASS (gdk_gc_parent_class)->finalize (object); +} + +/** + * gdk_gc_ref: + * @gc: a #GdkGC + * + * Deprecated function; use g_object_ref() instead. + * + * Return value: the gc. + * + * Deprecated: 2.0: Use g_object_ref() instead. + **/ +GdkGC * +gdk_gc_ref (GdkGC *gc) +{ + return (GdkGC *) g_object_ref (gc); +} + +/** + * gdk_gc_unref: + * @gc: a #GdkGC + * + * Decrement the reference count of @gc. + * + * Deprecated: 2.0: Use g_object_unref() instead. + **/ +void +gdk_gc_unref (GdkGC *gc) +{ + g_object_unref (gc); +} + +/** + * gdk_gc_get_values: + * @gc: a #GdkGC. + * @values: the #GdkGCValues structure in which to store the results. + * + * Retrieves the current values from a graphics context. Note that + * only the pixel values of the @values->foreground and @values->background + * are filled, use gdk_colormap_query_color() to obtain the rgb values + * if you need them. + * + * Deprecated: 2.22: Use Cairo for rendering. + **/ +void +gdk_gc_get_values (GdkGC *gc, + GdkGCValues *values) +{ + g_return_if_fail (GDK_IS_GC (gc)); + g_return_if_fail (values != NULL); + + GDK_GC_GET_CLASS (gc)->get_values (gc, values); +} + +/** + * gdk_gc_set_values: + * @gc: a #GdkGC + * @values: struct containing the new values + * @values_mask: mask indicating which struct fields are to be used + * + * Sets attributes of a graphics context in bulk. For each flag set in + * @values_mask, the corresponding field will be read from @values and + * set as the new value for @gc. If you're only setting a few values + * on @gc, calling individual "setter" functions is likely more + * convenient. + * + * Deprecated: 2.22: Use Cairo for rendering. + **/ +void +gdk_gc_set_values (GdkGC *gc, + GdkGCValues *values, + GdkGCValuesMask values_mask) +{ + GdkGCPrivate *priv; + + g_return_if_fail (GDK_IS_GC (gc)); + g_return_if_fail (values != NULL); + + priv = GDK_GC_GET_PRIVATE (gc); + + if ((values_mask & GDK_GC_CLIP_X_ORIGIN) || + (values_mask & GDK_GC_CLIP_Y_ORIGIN) || + (values_mask & GDK_GC_CLIP_MASK) || + (values_mask & GDK_GC_SUBWINDOW)) + _gdk_gc_remove_drawable_clip (gc); + + if (values_mask & GDK_GC_CLIP_X_ORIGIN) + gc->clip_x_origin = values->clip_x_origin; + if (values_mask & GDK_GC_CLIP_Y_ORIGIN) + gc->clip_y_origin = values->clip_y_origin; + if (values_mask & GDK_GC_TS_X_ORIGIN) + gc->ts_x_origin = values->ts_x_origin; + if (values_mask & GDK_GC_TS_Y_ORIGIN) + gc->ts_y_origin = values->ts_y_origin; + if (values_mask & GDK_GC_CLIP_MASK) + { + if (priv->clip_mask) + { + g_object_unref (priv->clip_mask); + priv->clip_mask = NULL; + } + if (values->clip_mask) + priv->clip_mask = g_object_ref (values->clip_mask); + + if (priv->clip_region) + { + gdk_region_destroy (priv->clip_region); + priv->clip_region = NULL; + } + } + if (values_mask & GDK_GC_FILL) + priv->fill = values->fill; + if (values_mask & GDK_GC_STIPPLE) + { + if (priv->stipple != values->stipple) + { + if (priv->stipple) + g_object_unref (priv->stipple); + priv->stipple = values->stipple; + if (priv->stipple) + g_object_ref (priv->stipple); + } + } + if (values_mask & GDK_GC_TILE) + { + if (priv->tile != values->tile) + { + if (priv->tile) + g_object_unref (priv->tile); + priv->tile = values->tile; + if (priv->tile) + g_object_ref (priv->tile); + } + } + if (values_mask & GDK_GC_FOREGROUND) + priv->fg_pixel = values->foreground.pixel; + if (values_mask & GDK_GC_BACKGROUND) + priv->bg_pixel = values->background.pixel; + if (values_mask & GDK_GC_SUBWINDOW) + priv->subwindow_mode = values->subwindow_mode; + if (values_mask & GDK_GC_EXPOSURES) + priv->exposures = values->graphics_exposures; + + GDK_GC_GET_CLASS (gc)->set_values (gc, values, values_mask); +} + +/** + * gdk_gc_set_foreground: + * @gc: a #GdkGC. + * @color: the new foreground color. + * + * Sets the foreground color for a graphics context. + * Note that this function uses @color->pixel, use + * gdk_gc_set_rgb_fg_color() to specify the foreground + * color as red, green, blue components. + * + * Deprecated: 2.22: Use gdk_cairo_set_source_color() to use a #GdkColor + * as the source in Cairo. + **/ +void +gdk_gc_set_foreground (GdkGC *gc, + const GdkColor *color) +{ + GdkGCValues values; + + g_return_if_fail (GDK_IS_GC (gc)); + g_return_if_fail (color != NULL); + + values.foreground = *color; + gdk_gc_set_values (gc, &values, GDK_GC_FOREGROUND); +} + +/** + * gdk_gc_set_background: + * @gc: a #GdkGC. + * @color: the new background color. + * + * Sets the background color for a graphics context. + * Note that this function uses @color->pixel, use + * gdk_gc_set_rgb_bg_color() to specify the background + * color as red, green, blue components. + * + * Deprecated: 2.22: Use gdk_cairo_set_source_color() to use a #GdkColor + * as the source in Cairo. Note that if you want to draw a background and a + * foreground in Cairo, you need to call drawing functions (like cairo_fill()) + * twice. + **/ +void +gdk_gc_set_background (GdkGC *gc, + const GdkColor *color) +{ + GdkGCValues values; + + g_return_if_fail (GDK_IS_GC (gc)); + g_return_if_fail (color != NULL); + + values.background = *color; + gdk_gc_set_values (gc, &values, GDK_GC_BACKGROUND); +} + +/** + * gdk_gc_set_font: + * @gc: a #GdkGC. + * @font: the new font. + * + * Sets the font for a graphics context. (Note that + * all text-drawing functions in GDK take a @font + * argument; the value set here is used when that + * argument is %NULL.) + **/ +void +gdk_gc_set_font (GdkGC *gc, + GdkFont *font) +{ + GdkGCValues values; + + g_return_if_fail (GDK_IS_GC (gc)); + g_return_if_fail (font != NULL); + + values.font = font; + gdk_gc_set_values (gc, &values, GDK_GC_FONT); +} + +/** + * gdk_gc_set_function: + * @gc: a #GdkGC. + * @function: the #GdkFunction to use + * + * Determines how the current pixel values and the + * pixel values being drawn are combined to produce + * the final pixel values. + * + * Deprecated: 2.22: Use cairo_set_operator() with Cairo. + **/ +void +gdk_gc_set_function (GdkGC *gc, + GdkFunction function) +{ + GdkGCValues values; + + g_return_if_fail (GDK_IS_GC (gc)); + + values.function = function; + gdk_gc_set_values (gc, &values, GDK_GC_FUNCTION); +} + +/** + * gdk_gc_set_fill: + * @gc: a #GdkGC. + * @fill: the new fill mode. + * + * Set the fill mode for a graphics context. + * + * Deprecated: 2.22: You can achieve tiling in Cairo by using + * cairo_pattern_set_extend() on the source. For stippling, see the + * deprecation comments on gdk_gc_set_stipple(). + **/ +void +gdk_gc_set_fill (GdkGC *gc, + GdkFill fill) +{ + GdkGCValues values; + + g_return_if_fail (GDK_IS_GC (gc)); + + values.fill = fill; + gdk_gc_set_values (gc, &values, GDK_GC_FILL); +} + +/** + * gdk_gc_set_tile: + * @gc: a #GdkGC. + * @tile: the new tile pixmap. + * + * Set a tile pixmap for a graphics context. + * This will only be used if the fill mode + * is %GDK_TILED. + * + * Deprecated: 2.22: The following code snippet sets a tiling #GdkPixmap + * as the source in Cairo: + * |[gdk_cairo_set_source_pixmap (cr, tile, ts_origin_x, ts_origin_y); + * cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_REPEAT);]| + **/ +void +gdk_gc_set_tile (GdkGC *gc, + GdkPixmap *tile) +{ + GdkGCValues values; + + g_return_if_fail (GDK_IS_GC (gc)); + + values.tile = tile; + gdk_gc_set_values (gc, &values, GDK_GC_TILE); +} + +/** + * gdk_gc_set_stipple: + * @gc: a #GdkGC. + * @stipple: the new stipple bitmap. + * + * Set the stipple bitmap for a graphics context. The + * stipple will only be used if the fill mode is + * %GDK_STIPPLED or %GDK_OPAQUE_STIPPLED. + * + * Deprecated: 2.22: Stippling has no direct replacement in Cairo. If you + * want to achieve an identical look, you can use the stipple bitmap as a + * mask. Most likely, this involves rendering the source to an intermediate + * surface using cairo_push_group() first, so that you can then use + * cairo_mask() to achieve the stippled look. + **/ +void +gdk_gc_set_stipple (GdkGC *gc, + GdkPixmap *stipple) +{ + GdkGCValues values; + + g_return_if_fail (GDK_IS_GC (gc)); + + values.stipple = stipple; + gdk_gc_set_values (gc, &values, GDK_GC_STIPPLE); +} + +/** + * gdk_gc_set_ts_origin: + * @gc: a #GdkGC. + * @x: the x-coordinate of the origin. + * @y: the y-coordinate of the origin. + * + * Set the origin when using tiles or stipples with + * the GC. The tile or stipple will be aligned such + * that the upper left corner of the tile or stipple + * will coincide with this point. + * + * Deprecated: 2.22: You can set the origin for tiles and stipples in Cairo + * by changing the source's matrix using cairo_pattern_set_matrix(). Or you + * can specify it with gdk_cairo_set_source_pixmap() as shown in the example + * for gdk_gc_set_tile(). + **/ +void +gdk_gc_set_ts_origin (GdkGC *gc, + gint x, + gint y) +{ + GdkGCValues values; + + g_return_if_fail (GDK_IS_GC (gc)); + + values.ts_x_origin = x; + values.ts_y_origin = y; + + gdk_gc_set_values (gc, &values, + GDK_GC_TS_X_ORIGIN | GDK_GC_TS_Y_ORIGIN); +} + +/** + * gdk_gc_set_clip_origin: + * @gc: a #GdkGC. + * @x: the x-coordinate of the origin. + * @y: the y-coordinate of the origin. + * + * Sets the origin of the clip mask. The coordinates are + * interpreted relative to the upper-left corner of + * the destination drawable of the current operation. + * + * Deprecated: 2.22: Use cairo_translate() before applying the clip path in + * Cairo. + **/ +void +gdk_gc_set_clip_origin (GdkGC *gc, + gint x, + gint y) +{ + GdkGCValues values; + + g_return_if_fail (GDK_IS_GC (gc)); + + values.clip_x_origin = x; + values.clip_y_origin = y; + + gdk_gc_set_values (gc, &values, + GDK_GC_CLIP_X_ORIGIN | GDK_GC_CLIP_Y_ORIGIN); +} + +/** + * gdk_gc_set_clip_mask: + * @gc: the #GdkGC. + * @mask: a bitmap. + * + * Sets the clip mask for a graphics context from a bitmap. + * The clip mask is interpreted relative to the clip + * origin. (See gdk_gc_set_clip_origin()). + * + * Deprecated: 2.22: Use cairo_mask() instead. + **/ +void +gdk_gc_set_clip_mask (GdkGC *gc, + GdkBitmap *mask) +{ + GdkGCValues values; + + g_return_if_fail (GDK_IS_GC (gc)); + + values.clip_mask = mask; + gdk_gc_set_values (gc, &values, GDK_GC_CLIP_MASK); +} + +/* Takes ownership of passed in region */ +static void +_gdk_gc_set_clip_region_real (GdkGC *gc, + GdkRegion *region, + gboolean reset_origin) +{ + GdkGCPrivate *priv = GDK_GC_GET_PRIVATE (gc); + + if (priv->clip_mask) + { + g_object_unref (priv->clip_mask); + priv->clip_mask = NULL; + } + + if (priv->clip_region) + gdk_region_destroy (priv->clip_region); + + priv->clip_region = region; + + _gdk_windowing_gc_set_clip_region (gc, region, reset_origin); +} + +/* Doesn't copy region, allows not to reset origin */ +void +_gdk_gc_set_clip_region_internal (GdkGC *gc, + GdkRegion *region, + gboolean reset_origin) +{ + _gdk_gc_remove_drawable_clip (gc); + _gdk_gc_set_clip_region_real (gc, region, reset_origin); +} + + +void +_gdk_gc_add_drawable_clip (GdkGC *gc, + guint32 region_tag, + GdkRegion *region, + int offset_x, + int offset_y) +{ + GdkGCPrivate *priv = GDK_GC_GET_PRIVATE (gc); + + if (priv->region_tag_applied == region_tag && + offset_x == priv->region_tag_offset_x && + offset_y == priv->region_tag_offset_y) + return; /* Already appied this drawable region */ + + if (priv->region_tag_applied) + _gdk_gc_remove_drawable_clip (gc); + + region = gdk_region_copy (region); + if (offset_x != 0 || offset_y != 0) + gdk_region_offset (region, offset_x, offset_y); + + if (priv->clip_mask) + { + int w, h; + GdkPixmap *new_mask; + GdkGC *tmp_gc; + GdkColor black = {0, 0, 0, 0}; + GdkRectangle r; + GdkOverlapType overlap; + + gdk_drawable_get_size (priv->clip_mask, &w, &h); + + r.x = 0; + r.y = 0; + r.width = w; + r.height = h; + + /* Its quite common to expose areas that are completely in or outside + * the region, so we try to avoid allocating bitmaps that are just fully + * set or completely unset. + */ + overlap = gdk_region_rect_in (region, &r); + if (overlap == GDK_OVERLAP_RECTANGLE_PART) + { + /* The region and the mask intersect, create a new clip mask that + includes both areas */ + priv->old_clip_mask = g_object_ref (priv->clip_mask); + new_mask = gdk_pixmap_new (priv->old_clip_mask, w, h, -1); + tmp_gc = _gdk_drawable_get_scratch_gc ((GdkDrawable *)new_mask, FALSE); + + gdk_gc_set_foreground (tmp_gc, &black); + gdk_draw_rectangle (new_mask, tmp_gc, TRUE, 0, 0, -1, -1); + _gdk_gc_set_clip_region_internal (tmp_gc, region, TRUE); /* Takes ownership of region */ + gdk_draw_drawable (new_mask, + tmp_gc, + priv->old_clip_mask, + 0, 0, + 0, 0, + -1, -1); + gdk_gc_set_clip_region (tmp_gc, NULL); + gdk_gc_set_clip_mask (gc, new_mask); + g_object_unref (new_mask); + } + else if (overlap == GDK_OVERLAP_RECTANGLE_OUT) + { + /* No intersection, set empty clip region */ + GdkRegion *empty = gdk_region_new (); + + gdk_region_destroy (region); + priv->old_clip_mask = g_object_ref (priv->clip_mask); + priv->clip_region = empty; + _gdk_windowing_gc_set_clip_region (gc, empty, FALSE); + } + else + { + /* Completely inside region, don't set unnecessary clip */ + gdk_region_destroy (region); + return; + } + } + else + { + priv->old_clip_region = priv->clip_region; + priv->clip_region = region; + if (priv->old_clip_region) + gdk_region_intersect (region, priv->old_clip_region); + + _gdk_windowing_gc_set_clip_region (gc, priv->clip_region, FALSE); + } + + priv->region_tag_applied = region_tag; + priv->region_tag_offset_x = offset_x; + priv->region_tag_offset_y = offset_y; +} + +void +_gdk_gc_remove_drawable_clip (GdkGC *gc) +{ + GdkGCPrivate *priv = GDK_GC_GET_PRIVATE (gc); + + if (priv->region_tag_applied) + { + priv->region_tag_applied = 0; + if (priv->old_clip_mask) + { + gdk_gc_set_clip_mask (gc, priv->old_clip_mask); + g_object_unref (priv->old_clip_mask); + priv->old_clip_mask = NULL; + + if (priv->clip_region) + { + g_object_unref (priv->clip_region); + priv->clip_region = NULL; + } + } + else + { + _gdk_gc_set_clip_region_real (gc, priv->old_clip_region, FALSE); + priv->old_clip_region = NULL; + } + } +} + +/** + * gdk_gc_set_clip_rectangle: + * @gc: a #GdkGC. + * @rectangle: the rectangle to clip to. + * + * Sets the clip mask for a graphics context from a + * rectangle. The clip mask is interpreted relative to the clip + * origin. (See gdk_gc_set_clip_origin()). + * + * Deprecated: 2.22: Use cairo_rectangle() and cairo_clip() in Cairo. + **/ +void +gdk_gc_set_clip_rectangle (GdkGC *gc, + const GdkRectangle *rectangle) +{ + GdkRegion *region; + + g_return_if_fail (GDK_IS_GC (gc)); + + _gdk_gc_remove_drawable_clip (gc); + + if (rectangle) + region = gdk_region_rectangle (rectangle); + else + region = NULL; + + _gdk_gc_set_clip_region_real (gc, region, TRUE); +} + +/** + * gdk_gc_set_clip_region: + * @gc: a #GdkGC. + * @region: the #GdkRegion. + * + * Sets the clip mask for a graphics context from a region structure. + * The clip mask is interpreted relative to the clip origin. (See + * gdk_gc_set_clip_origin()). + * + * Deprecated: 2.22: Use gdk_cairo_region() and cairo_clip() in Cairo. + **/ +void +gdk_gc_set_clip_region (GdkGC *gc, + const GdkRegion *region) +{ + GdkRegion *copy; + + g_return_if_fail (GDK_IS_GC (gc)); + + _gdk_gc_remove_drawable_clip (gc); + + if (region) + copy = gdk_region_copy (region); + else + copy = NULL; + + _gdk_gc_set_clip_region_real (gc, copy, TRUE); +} + +/** + * _gdk_gc_get_clip_region: + * @gc: a #GdkGC + * + * Gets the current clip region for @gc, if any. + * + * Return value: the clip region for the GC, or %NULL. + * (if a clip mask is set, the return will be %NULL) + * This value is owned by the GC and must not be freed. + **/ +GdkRegion * +_gdk_gc_get_clip_region (GdkGC *gc) +{ + g_return_val_if_fail (GDK_IS_GC (gc), NULL); + + return GDK_GC_GET_PRIVATE (gc)->clip_region; +} + +/** + * _gdk_gc_get_clip_mask: + * @gc: a #GdkGC + * + * Gets the current clip mask for @gc, if any. + * + * Return value: the clip mask for the GC, or %NULL. + * (if a clip region is set, the return will be %NULL) + * This value is owned by the GC and must not be freed. + **/ +GdkBitmap * +_gdk_gc_get_clip_mask (GdkGC *gc) +{ + g_return_val_if_fail (GDK_IS_GC (gc), NULL); + + return GDK_GC_GET_PRIVATE (gc)->clip_mask; +} + +/** + * _gdk_gc_get_fill: + * @gc: a #GdkGC + * + * Gets the current file style for the GC + * + * Return value: the file style for the GC + **/ +GdkFill +_gdk_gc_get_fill (GdkGC *gc) +{ + g_return_val_if_fail (GDK_IS_GC (gc), GDK_SOLID); + + return GDK_GC_GET_PRIVATE (gc)->fill; +} + +gboolean +_gdk_gc_get_exposures (GdkGC *gc) +{ + g_return_val_if_fail (GDK_IS_GC (gc), FALSE); + + return GDK_GC_GET_PRIVATE (gc)->exposures; +} + +/** + * _gdk_gc_get_tile: + * @gc: a #GdkGC + * + * Gets the tile pixmap for @gc, if any + * + * Return value: the tile set on the GC, or %NULL. The + * value is owned by the GC and must not be freed. + **/ +GdkPixmap * +_gdk_gc_get_tile (GdkGC *gc) +{ + g_return_val_if_fail (GDK_IS_GC (gc), NULL); + + return GDK_GC_GET_PRIVATE (gc)->tile; +} + +/** + * _gdk_gc_get_stipple: + * @gc: a #GdkGC + * + * Gets the stipple pixmap for @gc, if any + * + * Return value: the stipple set on the GC, or %NULL. The + * value is owned by the GC and must not be freed. + **/ +GdkBitmap * +_gdk_gc_get_stipple (GdkGC *gc) +{ + g_return_val_if_fail (GDK_IS_GC (gc), NULL); + + return GDK_GC_GET_PRIVATE (gc)->stipple; +} + +/** + * _gdk_gc_get_fg_pixel: + * @gc: a #GdkGC + * + * Gets the foreground pixel value for @gc. If the + * foreground pixel has never been set, returns the + * default value 0. + * + * Return value: the foreground pixel value of the GC + **/ +guint32 +_gdk_gc_get_fg_pixel (GdkGC *gc) +{ + g_return_val_if_fail (GDK_IS_GC (gc), 0); + + return GDK_GC_GET_PRIVATE (gc)->fg_pixel; +} + +/** + * _gdk_gc_get_bg_pixel: + * @gc: a #GdkGC + * + * Gets the background pixel value for @gc.If the + * foreground pixel has never been set, returns the + * default value 1. + * + * Return value: the foreground pixel value of the GC + **/ +guint32 +_gdk_gc_get_bg_pixel (GdkGC *gc) +{ + g_return_val_if_fail (GDK_IS_GC (gc), 0); + + return GDK_GC_GET_PRIVATE (gc)->bg_pixel; +} + +/** + * gdk_gc_set_subwindow: + * @gc: a #GdkGC. + * @mode: the subwindow mode. + * + * Sets how drawing with this GC on a window will affect child + * windows of that window. + * + * Deprecated: 2.22: There is no replacement. If you need to control + * subwindows, you must use drawing operations of the underlying window + * system manually. Cairo will always use %GDK_INCLUDE_INFERIORS on sources + * and masks and %GDK_CLIP_BY_CHILDREN on targets. + **/ +void +gdk_gc_set_subwindow (GdkGC *gc, + GdkSubwindowMode mode) +{ + GdkGCValues values; + GdkGCPrivate *priv = GDK_GC_GET_PRIVATE (gc); + + g_return_if_fail (GDK_IS_GC (gc)); + + /* This could get called a lot to reset the subwindow mode in + the client side clipping, so bail out early */ + if (priv->subwindow_mode == mode) + return; + + values.subwindow_mode = mode; + gdk_gc_set_values (gc, &values, GDK_GC_SUBWINDOW); +} + +GdkSubwindowMode +_gdk_gc_get_subwindow (GdkGC *gc) +{ + GdkGCPrivate *priv = GDK_GC_GET_PRIVATE (gc); + + return priv->subwindow_mode; +} + +/** + * gdk_gc_set_exposures: + * @gc: a #GdkGC. + * @exposures: if %TRUE, exposure events will be generated. + * + * Sets whether copying non-visible portions of a drawable + * using this graphics context generate exposure events + * for the corresponding regions of the destination + * drawable. (See gdk_draw_drawable()). + * + * Deprecated: 2.22: There is no replacement. If you need to control + * exposures, you must use drawing operations of the underlying window + * system or use gdk_window_invalidate_rect(). Cairo will never + * generate exposures. + **/ +void +gdk_gc_set_exposures (GdkGC *gc, + gboolean exposures) +{ + GdkGCValues values; + + g_return_if_fail (GDK_IS_GC (gc)); + + values.graphics_exposures = exposures; + gdk_gc_set_values (gc, &values, GDK_GC_EXPOSURES); +} + +/** + * gdk_gc_set_line_attributes: + * @gc: a #GdkGC. + * @line_width: the width of lines. + * @line_style: the dash-style for lines. + * @cap_style: the manner in which the ends of lines are drawn. + * @join_style: the in which lines are joined together. + * + * Sets various attributes of how lines are drawn. See + * the corresponding members of #GdkGCValues for full + * explanations of the arguments. + * + * Deprecated: 2.22: Use the Cairo functions cairo_set_line_width(), + * cairo_set_line_join(), cairo_set_line_cap() and cairo_set_dash() + * to affect the stroking behavior in Cairo. Keep in mind that the default + * attributes of a #cairo_t are different from the default attributes of + * a #GdkGC. + **/ +void +gdk_gc_set_line_attributes (GdkGC *gc, + gint line_width, + GdkLineStyle line_style, + GdkCapStyle cap_style, + GdkJoinStyle join_style) +{ + GdkGCValues values; + + values.line_width = line_width; + values.line_style = line_style; + values.cap_style = cap_style; + values.join_style = join_style; + + gdk_gc_set_values (gc, &values, + GDK_GC_LINE_WIDTH | + GDK_GC_LINE_STYLE | + GDK_GC_CAP_STYLE | + GDK_GC_JOIN_STYLE); +} + +/** + * gdk_gc_set_dashes: + * @gc: a #GdkGC. + * @dash_offset: the phase of the dash pattern. + * @dash_list: an array of dash lengths. + * @n: the number of elements in @dash_list. + * + * Sets the way dashed-lines are drawn. Lines will be + * drawn with alternating on and off segments of the + * lengths specified in @dash_list. The manner in + * which the on and off segments are drawn is determined + * by the @line_style value of the GC. (This can + * be changed with gdk_gc_set_line_attributes().) + * + * The @dash_offset defines the phase of the pattern, + * specifying how many pixels into the dash-list the pattern + * should actually begin. + * + * Deprecated: 2.22: Use cairo_set_dash() to set the dash in Cairo. + **/ +void +gdk_gc_set_dashes (GdkGC *gc, + gint dash_offset, + gint8 dash_list[], + gint n) +{ + g_return_if_fail (GDK_IS_GC (gc)); + g_return_if_fail (dash_list != NULL); + + GDK_GC_GET_CLASS (gc)->set_dashes (gc, dash_offset, dash_list, n); +} + +/** + * gdk_gc_offset: + * @gc: a #GdkGC + * @x_offset: amount by which to offset the GC in the X direction + * @y_offset: amount by which to offset the GC in the Y direction + * + * Offset attributes such as the clip and tile-stipple origins + * of the GC so that drawing at x - x_offset, y - y_offset with + * the offset GC has the same effect as drawing at x, y with the original + * GC. + * + * Deprecated: 2.22: There is no direct replacement, as this is just a + * convenience function for gdk_gc_set_ts_origin and gdk_gc_set_clip_origin(). + **/ +void +gdk_gc_offset (GdkGC *gc, + gint x_offset, + gint y_offset) +{ + if (x_offset != 0 || y_offset != 0) + { + GdkGCValues values; + + values.clip_x_origin = gc->clip_x_origin - x_offset; + values.clip_y_origin = gc->clip_y_origin - y_offset; + values.ts_x_origin = gc->ts_x_origin - x_offset; + values.ts_y_origin = gc->ts_y_origin - y_offset; + + gdk_gc_set_values (gc, &values, + GDK_GC_CLIP_X_ORIGIN | + GDK_GC_CLIP_Y_ORIGIN | + GDK_GC_TS_X_ORIGIN | + GDK_GC_TS_Y_ORIGIN); + } +} + +/** + * gdk_gc_copy: + * @dst_gc: the destination graphics context. + * @src_gc: the source graphics context. + * + * Copy the set of values from one graphics context + * onto another graphics context. + * + * Deprecated: 2.22: Use Cairo for drawing. cairo_save() and cairo_restore() + * can be helpful in cases where you'd have copied a #GdkGC. + **/ +void +gdk_gc_copy (GdkGC *dst_gc, + GdkGC *src_gc) +{ + GdkGCPrivate *dst_priv, *src_priv; + + g_return_if_fail (GDK_IS_GC (dst_gc)); + g_return_if_fail (GDK_IS_GC (src_gc)); + + dst_priv = GDK_GC_GET_PRIVATE (dst_gc); + src_priv = GDK_GC_GET_PRIVATE (src_gc); + + _gdk_windowing_gc_copy (dst_gc, src_gc); + + dst_gc->clip_x_origin = src_gc->clip_x_origin; + dst_gc->clip_y_origin = src_gc->clip_y_origin; + dst_gc->ts_x_origin = src_gc->ts_x_origin; + dst_gc->ts_y_origin = src_gc->ts_y_origin; + + if (src_gc->colormap) + g_object_ref (src_gc->colormap); + + if (dst_gc->colormap) + g_object_unref (dst_gc->colormap); + + dst_gc->colormap = src_gc->colormap; + + if (dst_priv->clip_region) + gdk_region_destroy (dst_priv->clip_region); + + if (src_priv->clip_region) + dst_priv->clip_region = gdk_region_copy (src_priv->clip_region); + else + dst_priv->clip_region = NULL; + + dst_priv->region_tag_applied = src_priv->region_tag_applied; + + if (dst_priv->old_clip_region) + gdk_region_destroy (dst_priv->old_clip_region); + + if (src_priv->old_clip_region) + dst_priv->old_clip_region = gdk_region_copy (src_priv->old_clip_region); + else + dst_priv->old_clip_region = NULL; + + if (src_priv->clip_mask) + dst_priv->clip_mask = g_object_ref (src_priv->clip_mask); + else + dst_priv->clip_mask = NULL; + + if (src_priv->old_clip_mask) + dst_priv->old_clip_mask = g_object_ref (src_priv->old_clip_mask); + else + dst_priv->old_clip_mask = NULL; + + dst_priv->fill = src_priv->fill; + + if (dst_priv->stipple) + g_object_unref (dst_priv->stipple); + dst_priv->stipple = src_priv->stipple; + if (dst_priv->stipple) + g_object_ref (dst_priv->stipple); + + if (dst_priv->tile) + g_object_unref (dst_priv->tile); + dst_priv->tile = src_priv->tile; + if (dst_priv->tile) + g_object_ref (dst_priv->tile); + + dst_priv->fg_pixel = src_priv->fg_pixel; + dst_priv->bg_pixel = src_priv->bg_pixel; + dst_priv->subwindow_mode = src_priv->subwindow_mode; + dst_priv->exposures = src_priv->exposures; +} + +/** + * gdk_gc_set_colormap: + * @gc: a #GdkGC + * @colormap: a #GdkColormap + * + * Sets the colormap for the GC to the given colormap. The depth + * of the colormap's visual must match the depth of the drawable + * for which the GC was created. + * + * Deprecated: 2.22: There is no replacement. Cairo handles colormaps + * automatically, so there is no need to care about them. + **/ +void +gdk_gc_set_colormap (GdkGC *gc, + GdkColormap *colormap) +{ + g_return_if_fail (GDK_IS_GC (gc)); + g_return_if_fail (GDK_IS_COLORMAP (colormap)); + + if (gc->colormap != colormap) + { + if (gc->colormap) + g_object_unref (gc->colormap); + + gc->colormap = colormap; + g_object_ref (gc->colormap); + } + +} + +/** + * gdk_gc_get_colormap: + * @gc: a #GdkGC + * + * Retrieves the colormap for a given GC, if it exists. + * A GC will have a colormap if the drawable for which it was created + * has a colormap, or if a colormap was set explicitely with + * gdk_gc_set_colormap. + * + * Return value: the colormap of @gc, or %NULL if @gc doesn't have one. + * + * Deprecated: 2.22: There is no replacement. Cairo handles colormaps + * automatically, so there is no need to care about them. + **/ +GdkColormap * +gdk_gc_get_colormap (GdkGC *gc) +{ + g_return_val_if_fail (GDK_IS_GC (gc), NULL); + + return gc->colormap; +} + +static GdkColormap * +gdk_gc_get_colormap_warn (GdkGC *gc) +{ + GdkColormap *colormap = gdk_gc_get_colormap (gc); + if (!colormap) + { + g_warning ("gdk_gc_set_rgb_fg_color() and gdk_gc_set_rgb_bg_color() can\n" + "only be used on GC's with a colormap. A GC will have a colormap\n" + "if it is created for a drawable with a colormap, or if a\n" + "colormap has been set explicitly with gdk_gc_set_colormap.\n"); + return NULL; + } + + return colormap; +} + +/** + * gdk_gc_set_rgb_fg_color: + * @gc: a #GdkGC + * @color: an unallocated #GdkColor. + * + * Set the foreground color of a GC using an unallocated color. The + * pixel value for the color will be determined using GdkRGB. If the + * colormap for the GC has not previously been initialized for GdkRGB, + * then for pseudo-color colormaps (colormaps with a small modifiable + * number of colors), a colorcube will be allocated in the colormap. + * + * Calling this function for a GC without a colormap is an error. + * + * Deprecated: 2.22: Use gdk_cairo_set_source_color() instead. + **/ +void +gdk_gc_set_rgb_fg_color (GdkGC *gc, + const GdkColor *color) +{ + GdkColormap *cmap; + GdkColor tmp_color; + + g_return_if_fail (GDK_IS_GC (gc)); + g_return_if_fail (color != NULL); + + cmap = gdk_gc_get_colormap_warn (gc); + if (!cmap) + return; + + tmp_color = *color; + gdk_rgb_find_color (cmap, &tmp_color); + gdk_gc_set_foreground (gc, &tmp_color); +} + +/** + * gdk_gc_set_rgb_bg_color: + * @gc: a #GdkGC + * @color: an unallocated #GdkColor. + * + * Set the background color of a GC using an unallocated color. The + * pixel value for the color will be determined using GdkRGB. If the + * colormap for the GC has not previously been initialized for GdkRGB, + * then for pseudo-color colormaps (colormaps with a small modifiable + * number of colors), a colorcube will be allocated in the colormap. + * + * Calling this function for a GC without a colormap is an error. + * + * Deprecated: 2.22: Use gdk_cairo_set_source_color() instead. + **/ +void +gdk_gc_set_rgb_bg_color (GdkGC *gc, + const GdkColor *color) +{ + GdkColormap *cmap; + GdkColor tmp_color; + + g_return_if_fail (GDK_IS_GC (gc)); + g_return_if_fail (color != NULL); + + cmap = gdk_gc_get_colormap_warn (gc); + if (!cmap) + return; + + tmp_color = *color; + gdk_rgb_find_color (cmap, &tmp_color); + gdk_gc_set_background (gc, &tmp_color); +} + +static cairo_surface_t * +make_stipple_tile_surface (cairo_t *cr, + GdkBitmap *stipple, + GdkColor *foreground, + GdkColor *background) +{ + cairo_t *tmp_cr; + cairo_surface_t *surface; + cairo_surface_t *alpha_surface; + gint width, height; + + gdk_drawable_get_size (stipple, + &width, &height); + + alpha_surface = _gdk_drawable_ref_cairo_surface (stipple); + + surface = cairo_surface_create_similar (cairo_get_target (cr), + CAIRO_CONTENT_COLOR_ALPHA, + width, height); + + tmp_cr = cairo_create (surface); + + cairo_set_operator (tmp_cr, CAIRO_OPERATOR_SOURCE); + + if (background) + gdk_cairo_set_source_color (tmp_cr, background); + else + cairo_set_source_rgba (tmp_cr, 0, 0, 0 ,0); + + cairo_paint (tmp_cr); + + cairo_set_operator (tmp_cr, CAIRO_OPERATOR_OVER); + + gdk_cairo_set_source_color (tmp_cr, foreground); + cairo_mask_surface (tmp_cr, alpha_surface, 0, 0); + + cairo_destroy (tmp_cr); + cairo_surface_destroy (alpha_surface); + + return surface; +} + +static void +gc_get_foreground (GdkGC *gc, + GdkColor *color) +{ + GdkGCPrivate *priv = GDK_GC_GET_PRIVATE (gc); + + color->pixel = priv->bg_pixel; + + if (gc->colormap) + gdk_colormap_query_color (gc->colormap, priv->fg_pixel, color); + else + g_warning ("No colormap in gc_get_foreground"); +} + +static void +gc_get_background (GdkGC *gc, + GdkColor *color) +{ + GdkGCPrivate *priv = GDK_GC_GET_PRIVATE (gc); + + color->pixel = priv->bg_pixel; + + if (gc->colormap) + gdk_colormap_query_color (gc->colormap, priv->bg_pixel, color); + else + g_warning ("No colormap in gc_get_background"); +} + +/** + * _gdk_gc_update_context: + * @gc: a #GdkGC + * @cr: a #cairo_t + * @override_foreground: a foreground color to use to override the + * foreground color of the GC + * @override_stipple: a stipple pattern to use to override the + * stipple from the GC. If this is present and the fill mode + * of the GC isn't %GDK_STIPPLED or %GDK_OPAQUE_STIPPLED + * the fill mode will be forced to %GDK_STIPPLED + * @gc_changed: pass %FALSE if the @gc has not changed since the + * last call to this function + * @target_drawable: The drawable you're drawing in. If passed in + * this is used for client side window clip emulation. + * + * Set the attributes of a cairo context to match those of a #GdkGC + * as far as possible. Some aspects of a #GdkGC, such as clip masks + * and functions other than %GDK_COPY are not currently handled. + **/ +void +_gdk_gc_update_context (GdkGC *gc, + cairo_t *cr, + const GdkColor *override_foreground, + GdkBitmap *override_stipple, + gboolean gc_changed, + GdkDrawable *target_drawable) +{ + GdkGCPrivate *priv; + GdkFill fill; + GdkColor foreground; + GdkColor background; + cairo_surface_t *tile_surface = NULL; + GdkBitmap *stipple = NULL; + + g_return_if_fail (GDK_IS_GC (gc)); + g_return_if_fail (cr != NULL); + g_return_if_fail (override_stipple == NULL || GDK_IS_PIXMAP (override_stipple)); + + priv = GDK_GC_GET_PRIVATE (gc); + + _gdk_gc_remove_drawable_clip (gc); + + fill = priv->fill; + if (override_stipple && fill != GDK_OPAQUE_STIPPLED) + fill = GDK_STIPPLED; + + if (fill != GDK_TILED) + { + if (override_foreground) + foreground = *override_foreground; + else + gc_get_foreground (gc, &foreground); + } + + if (fill == GDK_OPAQUE_STIPPLED) + gc_get_background (gc, &background); + + + switch (fill) + { + case GDK_SOLID: + break; + case GDK_TILED: + if (!priv->tile) + fill = GDK_SOLID; + break; + case GDK_STIPPLED: + case GDK_OPAQUE_STIPPLED: + if (override_stipple) + stipple = override_stipple; + else + stipple = priv->stipple; + + if (!stipple) + fill = GDK_SOLID; + break; + } + + switch (fill) + { + case GDK_SOLID: + gdk_cairo_set_source_color (cr, &foreground); + break; + case GDK_TILED: + tile_surface = _gdk_drawable_ref_cairo_surface (priv->tile); + break; + case GDK_STIPPLED: + tile_surface = make_stipple_tile_surface (cr, stipple, &foreground, NULL); + break; + case GDK_OPAQUE_STIPPLED: + tile_surface = make_stipple_tile_surface (cr, stipple, &foreground, &background); + break; + } + + /* Tiles, stipples, and clip regions are all specified in device space, + * not user space. For the clip region, we can simply change the matrix, + * clip, then clip back, but for the source pattern, we need to + * compute the right matrix. + * + * What we want is: + * + * CTM_inverse * Pattern_matrix = Translate(- ts_x, - ts_y) + * + * (So that ts_x, ts_y in device space is taken to 0,0 in pattern + * space). So, pattern_matrix = CTM * Translate(- ts_x, - tx_y); + */ + + if (tile_surface) + { + cairo_pattern_t *pattern = cairo_pattern_create_for_surface (tile_surface); + cairo_matrix_t user_to_device; + cairo_matrix_t user_to_pattern; + cairo_matrix_t device_to_pattern; + + cairo_get_matrix (cr, &user_to_device); + cairo_matrix_init_translate (&device_to_pattern, + - gc->ts_x_origin, - gc->ts_y_origin); + cairo_matrix_multiply (&user_to_pattern, + &user_to_device, &device_to_pattern); + + cairo_pattern_set_matrix (pattern, &user_to_pattern); + cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT); + cairo_set_source (cr, pattern); + + cairo_surface_destroy (tile_surface); + cairo_pattern_destroy (pattern); + } + + if (!gc_changed) + return; + + cairo_reset_clip (cr); + /* The reset above resets the window clip rect, so we want to re-set that */ + if (target_drawable && GDK_DRAWABLE_GET_CLASS (target_drawable)->set_cairo_clip) + GDK_DRAWABLE_GET_CLASS (target_drawable)->set_cairo_clip (target_drawable, cr); + + if (priv->clip_region) + { + cairo_save (cr); + + cairo_identity_matrix (cr); + cairo_translate (cr, gc->clip_x_origin, gc->clip_y_origin); + + cairo_new_path (cr); + gdk_cairo_region (cr, priv->clip_region); + + cairo_restore (cr); + + cairo_clip (cr); + } + +} + + +#define __GDK_GC_C__ +#include "gdkaliasdef.c" diff --git a/libs/tk/ydk/gdkglobals.c b/libs/tk/ydk/gdkglobals.c new file mode 100644 index 0000000000..4c3ad80956 --- /dev/null +++ b/libs/tk/ydk/gdkglobals.c @@ -0,0 +1,48 @@ +/* GDK - The GIMP Drawing Kit + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, 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 "config.h" + +#include + +#include "gdktypes.h" +#include "gdkprivate.h" +#include "gdkalias.h" + +guint _gdk_debug_flags = 0; +gint _gdk_error_code = 0; +gint _gdk_error_warnings = TRUE; +GList *_gdk_default_filters = NULL; +gchar *_gdk_display_name = NULL; +gint _gdk_screen_number = -1; +gchar *_gdk_display_arg_name = NULL; +gboolean _gdk_native_windows = FALSE; + +GSList *_gdk_displays = NULL; + +GMutex *gdk_threads_mutex = NULL; /* Global GDK lock */ +GCallback gdk_threads_lock = NULL; +GCallback gdk_threads_unlock = NULL; diff --git a/libs/tk/ydk/gdkimage.c b/libs/tk/ydk/gdkimage.c new file mode 100644 index 0000000000..8b5d0fdfec --- /dev/null +++ b/libs/tk/ydk/gdkimage.c @@ -0,0 +1,659 @@ +/* GDK - The GIMP Drawing Kit + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, 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 "config.h" +#include +#include + +#include "gdk.h" /* For gdk_flush() */ +#include "gdkimage.h" +#include "gdkprivate.h" +#include "gdkinternals.h" /* For scratch_image code */ +#include "gdkalias.h" + +/** + * gdk_image_ref: + * @image: a #GdkImage + * + * Deprecated function; use g_object_ref() instead. + * + * Return value: the image + * + * Deprecated: 2.0: Use g_object_ref() instead. + **/ +GdkImage * +gdk_image_ref (GdkImage *image) +{ + g_return_val_if_fail (GDK_IS_IMAGE (image), NULL); + + return g_object_ref (image); +} + +/** + * gdk_image_unref: + * @image: a #GdkImage + * + * Deprecated function; use g_object_unref() instead. + * + * Deprecated: 2.0: Use g_object_unref() instead. + **/ +void +gdk_image_unref (GdkImage *image) +{ + g_return_if_fail (GDK_IS_IMAGE (image)); + + g_object_unref (image); +} + +/** + * gdk_image_get: + * @drawable: a #GdkDrawable + * @x: x coordinate in @window + * @y: y coordinate in @window + * @width: width of area in @window + * @height: height of area in @window + * + * This is a deprecated wrapper for gdk_drawable_get_image(); + * gdk_drawable_get_image() should be used instead. Or even better: in + * most cases gdk_pixbuf_get_from_drawable() is the most convenient + * choice. + * + * Return value: a new #GdkImage or %NULL + **/ +GdkImage* +gdk_image_get (GdkWindow *drawable, + gint x, + gint y, + gint width, + gint height) +{ + g_return_val_if_fail (GDK_IS_DRAWABLE (drawable), NULL); + g_return_val_if_fail (x >= 0, NULL); + g_return_val_if_fail (y >= 0, NULL); + g_return_val_if_fail (width >= 0, NULL); + g_return_val_if_fail (height >= 0, NULL); + + return gdk_drawable_get_image (drawable, x, y, width, height); +} + +/** + * gdk_image_set_colormap: + * @image: a #GdkImage + * @colormap: a #GdkColormap + * + * Sets the colormap for the image to the given colormap. Normally + * there's no need to use this function, images are created with the + * correct colormap if you get the image from a drawable. If you + * create the image from scratch, use the colormap of the drawable you + * intend to render the image to. + * + * Deprecated: 2.22: #GdkImage should not be used anymore. + **/ +void +gdk_image_set_colormap (GdkImage *image, + GdkColormap *colormap) +{ + g_return_if_fail (GDK_IS_IMAGE (image)); + g_return_if_fail (GDK_IS_COLORMAP (colormap)); + + if (image->colormap != colormap) + { + if (image->colormap) + g_object_unref (image->colormap); + + image->colormap = colormap; + g_object_ref (image->colormap); + } +} + +/** + * gdk_image_get_colormap: + * @image: a #GdkImage + * + * Retrieves the colormap for a given image, if it exists. An image + * will have a colormap if the drawable from which it was created has + * a colormap, or if a colormap was set explicitely with + * gdk_image_set_colormap(). + * + * Return value: colormap for the image + * + * Deprecated: 2.22: #GdkImage should not be used anymore. + **/ +GdkColormap * +gdk_image_get_colormap (GdkImage *image) +{ + g_return_val_if_fail (GDK_IS_IMAGE (image), NULL); + + return image->colormap; +} + +/** + * gdk_image_get_image_type: + * @image: a #GdkImage + * + * Determines the type of a given image. + * + * Return value: the #GdkImageType of the image + * + * Since: 2.22 + * + * Deprecated: 2.22: #GdkImage should not be used anymore. + **/ +GdkImageType +gdk_image_get_image_type (GdkImage *image) +{ + g_return_val_if_fail (GDK_IS_IMAGE (image), 0); + + return image->type; +} + +/** + * gdk_image_get_visual: + * @image: a #GdkImage + * + * Determines the visual that was used to create the image. + * + * Return value: a #GdkVisual + * + * Since: 2.22 + * + * Deprecated: 2.22: #GdkImage should not be used anymore. + **/ +GdkVisual * +gdk_image_get_visual (GdkImage *image) +{ + g_return_val_if_fail (GDK_IS_IMAGE (image), NULL); + + return image->visual; +} + +/** + * gdk_image_get_byte_order: + * @image: a #GdkImage + * + * Determines the byte order of the image. + * + * Return value: a #GdkVisual + * + * Since: 2.22 + * + * Deprecated: 2.22: #GdkImage should not be used anymore. + **/ +GdkByteOrder +gdk_image_get_byte_order (GdkImage *image) +{ + g_return_val_if_fail (GDK_IS_IMAGE (image), 0); + + return image->byte_order; +} + +/** + * gdk_image_get_width: + * @image: a #GdkImage + * + * Determines the width of the image. + * + * Return value: the width + * + * Since: 2.22 + * + * Deprecated: 2.22: #GdkImage should not be used anymore. + **/ +gint +gdk_image_get_width (GdkImage *image) +{ + g_return_val_if_fail (GDK_IS_IMAGE (image), 0); + + return image->width; +} + +/** + * gdk_image_get_height: + * @image: a #GdkImage + * + * Determines the height of the image. + * + * Return value: the height + * + * Since: 2.22 + * + * Deprecated: 2.22: #GdkImage should not be used anymore. + **/ +gint +gdk_image_get_height (GdkImage *image) +{ + g_return_val_if_fail (GDK_IS_IMAGE (image), 0); + + return image->height; +} + +/** + * gdk_image_get_depth: + * @image: a #GdkImage + * + * Determines the depth of the image. + * + * Return value: the depth + * + * Since: 2.22 + * + * Deprecated: 2.22: #GdkImage should not be used anymore. + **/ +guint16 +gdk_image_get_depth (GdkImage *image) +{ + g_return_val_if_fail (GDK_IS_IMAGE (image), 0); + + return image->depth; +} + +/** + * gdk_image_get_bytes_per_pixel: + * @image: a #GdkImage + * + * Determines the number of bytes per pixel of the image. + * + * Return value: the bytes per pixel + * + * Since: 2.22 + * + * Deprecated: 2.22: #GdkImage should not be used anymore. + **/ +guint16 +gdk_image_get_bytes_per_pixel (GdkImage *image) +{ + g_return_val_if_fail (GDK_IS_IMAGE (image), 0); + + return image->bpp; +} + +/** + * gdk_image_get_bytes_per_line: + * @image: a #GdkImage + * + * Determines the number of bytes per line of the image. + * + * Return value: the bytes per line + * + * Since: 2.22 + * + * Deprecated: 2.22: #GdkImage should not be used anymore. + **/ +guint16 +gdk_image_get_bytes_per_line (GdkImage *image) +{ + g_return_val_if_fail (GDK_IS_IMAGE (image), 0); + + return image->bpl; +} + +/** + * gdk_image_get_bits_per_pixel: + * @image: a #GdkImage + * + * Determines the number of bits per pixel of the image. + * + * Return value: the bits per pixel + * + * Since: 2.22 + * + * Deprecated: 2.22: #GdkImage should not be used anymore. + **/ +guint16 +gdk_image_get_bits_per_pixel (GdkImage *image) +{ + g_return_val_if_fail (GDK_IS_IMAGE (image), 0); + + return image->bits_per_pixel; +} + +/** + * gdk_image_get_pixels: + * @image: a #GdkImage + * + * Returns a pointer to the pixel data of the image. + * + * Returns: the pixel data of the image + * + * Since: 2.22 + * + * Deprecated: 2.22: #GdkImage should not be used anymore. + */ +gpointer +gdk_image_get_pixels (GdkImage *image) +{ + g_return_val_if_fail (GDK_IS_IMAGE (image), NULL); + + return image->mem; +} + +/* We have N_REGION GDK_SCRATCH_IMAGE_WIDTH x GDK_SCRATCH_IMAGE_HEIGHT regions divided + * up between n_images different images. possible_n_images gives + * various divisors of N_REGIONS. The reason for allowing this + * flexibility is that we want to create as few images as possible, + * but we want to deal with the abberant systems that have a SHMMAX + * limit less than + * + * GDK_SCRATCH_IMAGE_WIDTH * GDK_SCRATCH_IMAGE_HEIGHT * N_REGIONS * 4 (384k) + * + * (Are there any such?) + */ +#define N_REGIONS 6 +static const int possible_n_images[] = { 1, 2, 3, 6 }; + +/* We allocate one GdkScratchImageInfo structure for each + * depth where we are allocating scratch images. (Future: one + * per depth, per display) + */ +typedef struct _GdkScratchImageInfo GdkScratchImageInfo; + +struct _GdkScratchImageInfo { + gint depth; + + gint n_images; + GdkImage *static_image[N_REGIONS]; + gint static_image_idx; + + /* In order to optimize filling fractions, we simultaneously fill in up + * to three regions of size GDK_SCRATCH_IMAGE_WIDTH * GDK_SCRATCH_IMAGE_HEIGHT: one + * for images that are taller than GDK_SCRATCH_IMAGE_HEIGHT / 2, and must + * be tiled horizontally. One for images that are wider than + * GDK_SCRATCH_IMAGE_WIDTH / 2 and must be tiled vertically, and a third + * for images smaller than GDK_SCRATCH_IMAGE_HEIGHT / 2 x GDK_SCRATCH_IMAGE_WIDTH x 2 + * that we tile in horizontal rows. + */ + gint horiz_idx; + gint horiz_y; + gint vert_idx; + gint vert_x; + + /* tile_y1 and tile_y2 define the horizontal band into + * which we are tiling images. tile_x is the x extent to + * which that is filled + */ + gint tile_idx; + gint tile_x; + gint tile_y1; + gint tile_y2; + + GdkScreen *screen; +}; + +static GSList *scratch_image_infos = NULL; + +static gboolean +allocate_scratch_images (GdkScratchImageInfo *info, + gint n_images, + gboolean shared) +{ + gint i; + + for (i = 0; i < n_images; i++) + { + info->static_image[i] = _gdk_image_new_for_depth (info->screen, + shared ? GDK_IMAGE_SHARED : GDK_IMAGE_NORMAL, + NULL, + GDK_SCRATCH_IMAGE_WIDTH * (N_REGIONS / n_images), + GDK_SCRATCH_IMAGE_HEIGHT, + info->depth); + + if (!info->static_image[i]) + { + gint j; + + for (j = 0; j < i; j++) + g_object_unref (info->static_image[j]); + + return FALSE; + } + } + + return TRUE; +} + +static void +scratch_image_info_display_closed (GdkDisplay *display, + gboolean is_error, + GdkScratchImageInfo *image_info) +{ + gint i; + + g_signal_handlers_disconnect_by_func (display, + scratch_image_info_display_closed, + image_info); + + scratch_image_infos = g_slist_remove (scratch_image_infos, image_info); + + for (i = 0; i < image_info->n_images; i++) + g_object_unref (image_info->static_image[i]); + + g_free (image_info); +} + +static GdkScratchImageInfo * +scratch_image_info_for_depth (GdkScreen *screen, + gint depth) +{ + GSList *tmp_list; + GdkScratchImageInfo *image_info; + gint i; + + tmp_list = scratch_image_infos; + while (tmp_list) + { + image_info = tmp_list->data; + if (image_info->depth == depth && image_info->screen == screen) + return image_info; + + tmp_list = tmp_list->next; + } + + image_info = g_new (GdkScratchImageInfo, 1); + + image_info->depth = depth; + image_info->screen = screen; + + g_signal_connect (gdk_screen_get_display (screen), "closed", + G_CALLBACK (scratch_image_info_display_closed), + image_info); + + /* Try to allocate as few possible shared images */ + for (i=0; i < G_N_ELEMENTS (possible_n_images); i++) + { + if (allocate_scratch_images (image_info, possible_n_images[i], TRUE)) + { + image_info->n_images = possible_n_images[i]; + break; + } + } + + /* If that fails, just allocate N_REGIONS normal images */ + if (i == G_N_ELEMENTS (possible_n_images)) + { + allocate_scratch_images (image_info, N_REGIONS, FALSE); + image_info->n_images = N_REGIONS; + } + + image_info->static_image_idx = 0; + + image_info->horiz_y = GDK_SCRATCH_IMAGE_HEIGHT; + image_info->vert_x = GDK_SCRATCH_IMAGE_WIDTH; + image_info->tile_x = GDK_SCRATCH_IMAGE_WIDTH; + image_info->tile_y1 = image_info->tile_y2 = GDK_SCRATCH_IMAGE_HEIGHT; + + scratch_image_infos = g_slist_prepend (scratch_image_infos, image_info); + + return image_info; +} + +/* Defining NO_FLUSH can cause inconsistent screen updates, but is useful + for performance evaluation. */ + +#undef NO_FLUSH + +#ifdef VERBOSE +static gint sincelast; +#endif + +static gint +alloc_scratch_image (GdkScratchImageInfo *image_info) +{ + if (image_info->static_image_idx == N_REGIONS) + { +#ifndef NO_FLUSH + gdk_flush (); +#endif +#ifdef VERBOSE + g_print ("flush, %d puts since last flush\n", sincelast); + sincelast = 0; +#endif + image_info->static_image_idx = 0; + + /* Mark all regions that we might be filling in as completely + * full, to force new tiles to be allocated for subsequent + * images + */ + image_info->horiz_y = GDK_SCRATCH_IMAGE_HEIGHT; + image_info->vert_x = GDK_SCRATCH_IMAGE_WIDTH; + image_info->tile_x = GDK_SCRATCH_IMAGE_WIDTH; + image_info->tile_y1 = image_info->tile_y2 = GDK_SCRATCH_IMAGE_HEIGHT; + } + return image_info->static_image_idx++; +} + +/** + * _gdk_image_get_scratch: + * @screen: a #GdkScreen + * @width: desired width + * @height: desired height + * @depth: depth of image + * @x: X location within returned image of scratch image + * @y: Y location within returned image of scratch image + * + * Allocates an image of size width/height, up to a maximum + * of GDK_SCRATCH_IMAGE_WIDTHxGDK_SCRATCH_IMAGE_HEIGHT that is + * suitable to use on @screen. + * + * Return value: a scratch image. This must be used by a + * call to gdk_image_put() before any other calls to + * _gdk_image_get_scratch() + **/ +GdkImage * +_gdk_image_get_scratch (GdkScreen *screen, + gint width, + gint height, + gint depth, + gint *x, + gint *y) +{ + GdkScratchImageInfo *image_info; + GdkImage *image; + gint idx; + + g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL); + + image_info = scratch_image_info_for_depth (screen, depth); + + if (width >= (GDK_SCRATCH_IMAGE_WIDTH >> 1)) + { + if (height >= (GDK_SCRATCH_IMAGE_HEIGHT >> 1)) + { + idx = alloc_scratch_image (image_info); + *x = 0; + *y = 0; + } + else + { + if (height + image_info->horiz_y > GDK_SCRATCH_IMAGE_HEIGHT) + { + image_info->horiz_idx = alloc_scratch_image (image_info); + image_info->horiz_y = 0; + } + idx = image_info->horiz_idx; + *x = 0; + *y = image_info->horiz_y; + image_info->horiz_y += height; + } + } + else + { + if (height >= (GDK_SCRATCH_IMAGE_HEIGHT >> 1)) + { + if (width + image_info->vert_x > GDK_SCRATCH_IMAGE_WIDTH) + { + image_info->vert_idx = alloc_scratch_image (image_info); + image_info->vert_x = 0; + } + idx = image_info->vert_idx; + *x = image_info->vert_x; + *y = 0; + /* using 3 and -4 would be slightly more efficient on 32-bit machines + with > 1bpp displays */ + image_info->vert_x += (width + 7) & -8; + } + else + { + if (width + image_info->tile_x > GDK_SCRATCH_IMAGE_WIDTH) + { + image_info->tile_y1 = image_info->tile_y2; + image_info->tile_x = 0; + } + if (height + image_info->tile_y1 > GDK_SCRATCH_IMAGE_HEIGHT) + { + image_info->tile_idx = alloc_scratch_image (image_info); + image_info->tile_x = 0; + image_info->tile_y1 = 0; + image_info->tile_y2 = 0; + } + if (height + image_info->tile_y1 > image_info->tile_y2) + image_info->tile_y2 = height + image_info->tile_y1; + idx = image_info->tile_idx; + *x = image_info->tile_x; + *y = image_info->tile_y1; + image_info->tile_x += (width + 7) & -8; + } + } + image = image_info->static_image[idx * image_info->n_images / N_REGIONS]; + *x += GDK_SCRATCH_IMAGE_WIDTH * (idx % (N_REGIONS / image_info->n_images)); +#ifdef VERBOSE + g_print ("index %d, x %d, y %d (%d x %d)\n", idx, *x, *y, width, height); + sincelast++; +#endif + return image; +} + +GdkImage* +gdk_image_new (GdkImageType type, + GdkVisual *visual, + gint width, + gint height) +{ + return _gdk_image_new_for_depth (gdk_visual_get_screen (visual), type, + visual, width, height, -1); +} + +#define __GDK_IMAGE_C__ +#include "gdkaliasdef.c" diff --git a/libs/tk/ydk/gdkkeynames.c b/libs/tk/ydk/gdkkeynames.c new file mode 100644 index 0000000000..18f289fbd8 --- /dev/null +++ b/libs/tk/ydk/gdkkeynames.c @@ -0,0 +1,133 @@ +/* GDK - The GIMP Drawing Kit + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, 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 "config.h" +#include +#include +#include + +#include "gdkkeysyms.h" +#include "gdkinternals.h" +#include "gdkalias.h" + +/* Key handling not part of the keymap */ + +#include "keyname-table.h" + +#define GDK_NUM_KEYS G_N_ELEMENTS (gdk_keys_by_keyval) + +static int +gdk_keys_keyval_compare (const void *pkey, const void *pbase) +{ + return (*(int *) pkey) - ((gdk_key *) pbase)->keyval; +} + +/** + * gdk_keyval_name: + * @keyval: a key value + * + * Converts a key value into a symbolic name. + * + * The names are the same as those in the + * <gdk/gdkkeysyms.h> header file + * but without the leading "GDK_KEY_". + * + * Return value: (transfer none): a string containing the name of the key, + * or %NULL if @keyval is not a valid key. The string should not be + * modified. + */ +gchar* +gdk_keyval_name (guint keyval) +{ + static gchar buf[100]; + gdk_key *found; + + /* Check for directly encoded 24-bit UCS characters: */ + if ((keyval & 0xff000000) == 0x01000000) + { + g_sprintf (buf, "U+%.04X", (keyval & 0x00ffffff)); + return buf; + } + + found = bsearch (&keyval, gdk_keys_by_keyval, + GDK_NUM_KEYS, sizeof (gdk_key), + gdk_keys_keyval_compare); + + if (found != NULL) + { + while ((found > gdk_keys_by_keyval) && + ((found - 1)->keyval == keyval)) + found--; + + return (gchar *) (keynames + found->offset); + } + else if (keyval != 0) + { + g_sprintf (buf, "%#x", keyval); + return buf; + } + + return NULL; +} + +static int +gdk_keys_name_compare (const void *pkey, const void *pbase) +{ + return strcmp ((const char *) pkey, + (const char *) (keynames + ((const gdk_key *) pbase)->offset)); +} + +/** + * gdk_keyval_from_name: + * @keyval_name: a key name + * + * Converts a key name to a key value. + * + * The names are the same as those in the + * <gdk/gdkkeysyms.h> header file + * but without the leading "GDK_KEY_". + * + * Returns: the corresponding key value, or %GDK_KEY_VoidSymbol + * if the key name is not a valid key + */ +guint +gdk_keyval_from_name (const gchar *keyval_name) +{ + gdk_key *found; + + g_return_val_if_fail (keyval_name != NULL, 0); + + found = bsearch (keyval_name, gdk_keys_by_name, + GDK_NUM_KEYS, sizeof (gdk_key), + gdk_keys_name_compare); + if (found != NULL) + return found->keyval; + else + return GDK_VoidSymbol; +} + +#define __GDK_KEYNAMES_C__ +#include "gdkaliasdef.c" diff --git a/libs/tk/ydk/gdkkeys.c b/libs/tk/ydk/gdkkeys.c new file mode 100644 index 0000000000..6953b46426 --- /dev/null +++ b/libs/tk/ydk/gdkkeys.c @@ -0,0 +1,316 @@ +/* GDK - The GIMP Drawing Kit + * Copyright (C) 2000 Red Hat, 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. + */ + +/* + * 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 "config.h" + +#include "gdkdisplay.h" +#include "gdkkeys.h" +#include "gdkalias.h" + +enum { + DIRECTION_CHANGED, + KEYS_CHANGED, + STATE_CHANGED, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +G_DEFINE_TYPE (GdkKeymap, gdk_keymap, G_TYPE_OBJECT) + +static void +gdk_keymap_class_init (GdkKeymapClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + /** + * GdkKeymap::direction-changed: + * @keymap: the object on which the signal is emitted + * + * The ::direction-changed signal gets emitted when the direction of + * the keymap changes. + * + * Since: 2.0 + */ + signals[DIRECTION_CHANGED] = + g_signal_new ("direction-changed", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GdkKeymapClass, direction_changed), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); + /** + * GdkKeymap::keys-changed: + * @keymap: the object on which the signal is emitted + * + * The ::keys-changed signal is emitted when the mapping represented by + * @keymap changes. + * + * Since: 2.2 + */ + signals[KEYS_CHANGED] = + g_signal_new ("keys-changed", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GdkKeymapClass, keys_changed), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); + + /** + * GdkKeymap::state-changed: + * @keymap: the object on which the signal is emitted + * + * The ::state-changed signal is emitted when the state of the + * keyboard changes, e.g when Caps Lock is turned on or off. + * See gdk_keymap_get_caps_lock_state(). + * + * Since: 2.16 + */ + signals[STATE_CHANGED] = + g_signal_new ("state_changed", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GdkKeymapClass, state_changed), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); +} + +static void +gdk_keymap_init (GdkKeymap *keymap) +{ +} + +/* Other key-handling stuff + */ + +#ifndef HAVE_XCONVERTCASE +#include "gdkkeysyms.h" + +/* compatibility function from X11R6.3, since XConvertCase is not + * supplied by X11R5. + */ +/** + * gdk_keyval_convert_case: + * @symbol: a keyval + * @lower: (out): return location for lowercase version of @symbol + * @upper: (out): return location for uppercase version of @symbol + * + * Obtains the upper- and lower-case versions of the keyval @symbol. + * Examples of keyvals are #GDK_a, #GDK_Enter, #GDK_F1, etc. + * + **/ +void +gdk_keyval_convert_case (guint symbol, + guint *lower, + guint *upper) +{ + guint xlower = symbol; + guint xupper = symbol; + + /* Check for directly encoded 24-bit UCS characters: */ + if ((symbol & 0xff000000) == 0x01000000) + { + if (lower) + *lower = gdk_unicode_to_keyval (g_unichar_tolower (symbol & 0x00ffffff)); + if (upper) + *upper = gdk_unicode_to_keyval (g_unichar_toupper (symbol & 0x00ffffff)); + return; + } + + switch (symbol >> 8) + { + case 0: /* Latin 1 */ + if ((symbol >= GDK_A) && (symbol <= GDK_Z)) + xlower += (GDK_a - GDK_A); + else if ((symbol >= GDK_a) && (symbol <= GDK_z)) + xupper -= (GDK_a - GDK_A); + else if ((symbol >= GDK_Agrave) && (symbol <= GDK_Odiaeresis)) + xlower += (GDK_agrave - GDK_Agrave); + else if ((symbol >= GDK_agrave) && (symbol <= GDK_odiaeresis)) + xupper -= (GDK_agrave - GDK_Agrave); + else if ((symbol >= GDK_Ooblique) && (symbol <= GDK_Thorn)) + xlower += (GDK_oslash - GDK_Ooblique); + else if ((symbol >= GDK_oslash) && (symbol <= GDK_thorn)) + xupper -= (GDK_oslash - GDK_Ooblique); + break; + + case 1: /* Latin 2 */ + /* Assume the KeySym is a legal value (ignore discontinuities) */ + if (symbol == GDK_Aogonek) + xlower = GDK_aogonek; + else if (symbol >= GDK_Lstroke && symbol <= GDK_Sacute) + xlower += (GDK_lstroke - GDK_Lstroke); + else if (symbol >= GDK_Scaron && symbol <= GDK_Zacute) + xlower += (GDK_scaron - GDK_Scaron); + else if (symbol >= GDK_Zcaron && symbol <= GDK_Zabovedot) + xlower += (GDK_zcaron - GDK_Zcaron); + else if (symbol == GDK_aogonek) + xupper = GDK_Aogonek; + else if (symbol >= GDK_lstroke && symbol <= GDK_sacute) + xupper -= (GDK_lstroke - GDK_Lstroke); + else if (symbol >= GDK_scaron && symbol <= GDK_zacute) + xupper -= (GDK_scaron - GDK_Scaron); + else if (symbol >= GDK_zcaron && symbol <= GDK_zabovedot) + xupper -= (GDK_zcaron - GDK_Zcaron); + else if (symbol >= GDK_Racute && symbol <= GDK_Tcedilla) + xlower += (GDK_racute - GDK_Racute); + else if (symbol >= GDK_racute && symbol <= GDK_tcedilla) + xupper -= (GDK_racute - GDK_Racute); + break; + + case 2: /* Latin 3 */ + /* Assume the KeySym is a legal value (ignore discontinuities) */ + if (symbol >= GDK_Hstroke && symbol <= GDK_Hcircumflex) + xlower += (GDK_hstroke - GDK_Hstroke); + else if (symbol >= GDK_Gbreve && symbol <= GDK_Jcircumflex) + xlower += (GDK_gbreve - GDK_Gbreve); + else if (symbol >= GDK_hstroke && symbol <= GDK_hcircumflex) + xupper -= (GDK_hstroke - GDK_Hstroke); + else if (symbol >= GDK_gbreve && symbol <= GDK_jcircumflex) + xupper -= (GDK_gbreve - GDK_Gbreve); + else if (symbol >= GDK_Cabovedot && symbol <= GDK_Scircumflex) + xlower += (GDK_cabovedot - GDK_Cabovedot); + else if (symbol >= GDK_cabovedot && symbol <= GDK_scircumflex) + xupper -= (GDK_cabovedot - GDK_Cabovedot); + break; + + case 3: /* Latin 4 */ + /* Assume the KeySym is a legal value (ignore discontinuities) */ + if (symbol >= GDK_Rcedilla && symbol <= GDK_Tslash) + xlower += (GDK_rcedilla - GDK_Rcedilla); + else if (symbol >= GDK_rcedilla && symbol <= GDK_tslash) + xupper -= (GDK_rcedilla - GDK_Rcedilla); + else if (symbol == GDK_ENG) + xlower = GDK_eng; + else if (symbol == GDK_eng) + xupper = GDK_ENG; + else if (symbol >= GDK_Amacron && symbol <= GDK_Umacron) + xlower += (GDK_amacron - GDK_Amacron); + else if (symbol >= GDK_amacron && symbol <= GDK_umacron) + xupper -= (GDK_amacron - GDK_Amacron); + break; + + case 6: /* Cyrillic */ + /* Assume the KeySym is a legal value (ignore discontinuities) */ + if (symbol >= GDK_Serbian_DJE && symbol <= GDK_Serbian_DZE) + xlower -= (GDK_Serbian_DJE - GDK_Serbian_dje); + else if (symbol >= GDK_Serbian_dje && symbol <= GDK_Serbian_dze) + xupper += (GDK_Serbian_DJE - GDK_Serbian_dje); + else if (symbol >= GDK_Cyrillic_YU && symbol <= GDK_Cyrillic_HARDSIGN) + xlower -= (GDK_Cyrillic_YU - GDK_Cyrillic_yu); + else if (symbol >= GDK_Cyrillic_yu && symbol <= GDK_Cyrillic_hardsign) + xupper += (GDK_Cyrillic_YU - GDK_Cyrillic_yu); + break; + + case 7: /* Greek */ + /* Assume the KeySym is a legal value (ignore discontinuities) */ + if (symbol >= GDK_Greek_ALPHAaccent && symbol <= GDK_Greek_OMEGAaccent) + xlower += (GDK_Greek_alphaaccent - GDK_Greek_ALPHAaccent); + else if (symbol >= GDK_Greek_alphaaccent && symbol <= GDK_Greek_omegaaccent && + symbol != GDK_Greek_iotaaccentdieresis && + symbol != GDK_Greek_upsilonaccentdieresis) + xupper -= (GDK_Greek_alphaaccent - GDK_Greek_ALPHAaccent); + else if (symbol >= GDK_Greek_ALPHA && symbol <= GDK_Greek_OMEGA) + xlower += (GDK_Greek_alpha - GDK_Greek_ALPHA); + else if (symbol >= GDK_Greek_alpha && symbol <= GDK_Greek_omega && + symbol != GDK_Greek_finalsmallsigma) + xupper -= (GDK_Greek_alpha - GDK_Greek_ALPHA); + break; + } + + if (lower) + *lower = xlower; + if (upper) + *upper = xupper; +} +#endif + +guint +gdk_keyval_to_upper (guint keyval) +{ + guint result; + + gdk_keyval_convert_case (keyval, NULL, &result); + + return result; +} + +guint +gdk_keyval_to_lower (guint keyval) +{ + guint result; + + gdk_keyval_convert_case (keyval, &result, NULL); + + return result; +} + +gboolean +gdk_keyval_is_upper (guint keyval) +{ + if (keyval) + { + guint upper_val = 0; + + gdk_keyval_convert_case (keyval, NULL, &upper_val); + return upper_val == keyval; + } + return FALSE; +} + +gboolean +gdk_keyval_is_lower (guint keyval) +{ + if (keyval) + { + guint lower_val = 0; + + gdk_keyval_convert_case (keyval, &lower_val, NULL); + return lower_val == keyval; + } + return FALSE; +} + +/** + * gdk_keymap_get_default: + * @returns: the #GdkKeymap attached to the default display. + * + * Returns the #GdkKeymap attached to the default display. + **/ +GdkKeymap* +gdk_keymap_get_default (void) +{ + return gdk_keymap_get_for_display (gdk_display_get_default ()); +} + +#define __GDK_KEYS_C__ +#include "gdkaliasdef.c" diff --git a/libs/tk/ydk/gdkkeyuni.c b/libs/tk/ydk/gdkkeyuni.c new file mode 100644 index 0000000000..42577fe59e --- /dev/null +++ b/libs/tk/ydk/gdkkeyuni.c @@ -0,0 +1,1713 @@ +/* GDK - The GIMP Drawing Kit + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, 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 "config.h" +#include "gdk.h" +#include "gdkalias.h" + +#ifdef GDK_WINDOWING_WIN32 +#include "win32/gdkprivate-win32.h" +#endif + +/* Thanks to Markus G. Kuhn for the ksysym<->Unicode + * mapping functions, from the xterm sources. + */ + +/* These tables could be compressed by contiguous ranges, but the benefit of doing so + * is smallish. It would save about ~1000 bytes total. + */ + +static const struct { + unsigned short keysym; + unsigned short ucs; +} gdk_keysym_to_unicode_tab[] = { + { 0x01a1, 0x0104 }, /* Aogonek Ä„ LATIN CAPITAL LETTER A WITH OGONEK */ + { 0x01a2, 0x02d8 }, /* breve ˘ BREVE */ + { 0x01a3, 0x0141 }, /* Lstroke Å LATIN CAPITAL LETTER L WITH STROKE */ + { 0x01a5, 0x013d }, /* Lcaron Ľ LATIN CAPITAL LETTER L WITH CARON */ + { 0x01a6, 0x015a }, /* Sacute Åš LATIN CAPITAL LETTER S WITH ACUTE */ + { 0x01a9, 0x0160 }, /* Scaron Å  LATIN CAPITAL LETTER S WITH CARON */ + { 0x01aa, 0x015e }, /* Scedilla Åž LATIN CAPITAL LETTER S WITH CEDILLA */ + { 0x01ab, 0x0164 }, /* Tcaron Ť LATIN CAPITAL LETTER T WITH CARON */ + { 0x01ac, 0x0179 }, /* Zacute Ź LATIN CAPITAL LETTER Z WITH ACUTE */ + { 0x01ae, 0x017d }, /* Zcaron Ž LATIN CAPITAL LETTER Z WITH CARON */ + { 0x01af, 0x017b }, /* Zabovedot Å» LATIN CAPITAL LETTER Z WITH DOT ABOVE */ + { 0x01b1, 0x0105 }, /* aogonek Ä… LATIN SMALL LETTER A WITH OGONEK */ + { 0x01b2, 0x02db }, /* ogonek Ë› OGONEK */ + { 0x01b3, 0x0142 }, /* lstroke Å‚ LATIN SMALL LETTER L WITH STROKE */ + { 0x01b5, 0x013e }, /* lcaron ľ LATIN SMALL LETTER L WITH CARON */ + { 0x01b6, 0x015b }, /* sacute Å› LATIN SMALL LETTER S WITH ACUTE */ + { 0x01b7, 0x02c7 }, /* caron ˇ CARON */ + { 0x01b9, 0x0161 }, /* scaron Å¡ LATIN SMALL LETTER S WITH CARON */ + { 0x01ba, 0x015f }, /* scedilla ÅŸ LATIN SMALL LETTER S WITH CEDILLA */ + { 0x01bb, 0x0165 }, /* tcaron Å¥ LATIN SMALL LETTER T WITH CARON */ + { 0x01bc, 0x017a }, /* zacute ź LATIN SMALL LETTER Z WITH ACUTE */ + { 0x01bd, 0x02dd }, /* doubleacute Ë DOUBLE ACUTE ACCENT */ + { 0x01be, 0x017e }, /* zcaron ž LATIN SMALL LETTER Z WITH CARON */ + { 0x01bf, 0x017c }, /* zabovedot ż LATIN SMALL LETTER Z WITH DOT ABOVE */ + { 0x01c0, 0x0154 }, /* Racute Å” LATIN CAPITAL LETTER R WITH ACUTE */ + { 0x01c3, 0x0102 }, /* Abreve Ä‚ LATIN CAPITAL LETTER A WITH BREVE */ + { 0x01c5, 0x0139 }, /* Lacute Ĺ LATIN CAPITAL LETTER L WITH ACUTE */ + { 0x01c6, 0x0106 }, /* Cacute Ć LATIN CAPITAL LETTER C WITH ACUTE */ + { 0x01c8, 0x010c }, /* Ccaron ÄŒ LATIN CAPITAL LETTER C WITH CARON */ + { 0x01ca, 0x0118 }, /* Eogonek Ę LATIN CAPITAL LETTER E WITH OGONEK */ + { 0x01cc, 0x011a }, /* Ecaron Äš LATIN CAPITAL LETTER E WITH CARON */ + { 0x01cf, 0x010e }, /* Dcaron ÄŽ LATIN CAPITAL LETTER D WITH CARON */ + { 0x01d0, 0x0110 }, /* Dstroke Ä LATIN CAPITAL LETTER D WITH STROKE */ + { 0x01d1, 0x0143 }, /* Nacute Ń LATIN CAPITAL LETTER N WITH ACUTE */ + { 0x01d2, 0x0147 }, /* Ncaron Ň LATIN CAPITAL LETTER N WITH CARON */ + { 0x01d5, 0x0150 }, /* Odoubleacute Å LATIN CAPITAL LETTER O WITH DOUBLE ACUTE */ + { 0x01d8, 0x0158 }, /* Rcaron Ř LATIN CAPITAL LETTER R WITH CARON */ + { 0x01d9, 0x016e }, /* Uring Å® LATIN CAPITAL LETTER U WITH RING ABOVE */ + { 0x01db, 0x0170 }, /* Udoubleacute Ű LATIN CAPITAL LETTER U WITH DOUBLE ACUTE */ + { 0x01de, 0x0162 }, /* Tcedilla Å¢ LATIN CAPITAL LETTER T WITH CEDILLA */ + { 0x01e0, 0x0155 }, /* racute Å• LATIN SMALL LETTER R WITH ACUTE */ + { 0x01e3, 0x0103 }, /* abreve ă LATIN SMALL LETTER A WITH BREVE */ + { 0x01e5, 0x013a }, /* lacute ĺ LATIN SMALL LETTER L WITH ACUTE */ + { 0x01e6, 0x0107 }, /* cacute ć LATIN SMALL LETTER C WITH ACUTE */ + { 0x01e8, 0x010d }, /* ccaron Ä LATIN SMALL LETTER C WITH CARON */ + { 0x01ea, 0x0119 }, /* eogonek Ä™ LATIN SMALL LETTER E WITH OGONEK */ + { 0x01ec, 0x011b }, /* ecaron Ä› LATIN SMALL LETTER E WITH CARON */ + { 0x01ef, 0x010f }, /* dcaron Ä LATIN SMALL LETTER D WITH CARON */ + { 0x01f0, 0x0111 }, /* dstroke Ä‘ LATIN SMALL LETTER D WITH STROKE */ + { 0x01f1, 0x0144 }, /* nacute Å„ LATIN SMALL LETTER N WITH ACUTE */ + { 0x01f2, 0x0148 }, /* ncaron ň LATIN SMALL LETTER N WITH CARON */ + { 0x01f5, 0x0151 }, /* odoubleacute Å‘ LATIN SMALL LETTER O WITH DOUBLE ACUTE */ + { 0x01f8, 0x0159 }, /* rcaron Å™ LATIN SMALL LETTER R WITH CARON */ + { 0x01f9, 0x016f }, /* uring ů LATIN SMALL LETTER U WITH RING ABOVE */ + { 0x01fb, 0x0171 }, /* udoubleacute ű LATIN SMALL LETTER U WITH DOUBLE ACUTE */ + { 0x01fe, 0x0163 }, /* tcedilla Å£ LATIN SMALL LETTER T WITH CEDILLA */ + { 0x01ff, 0x02d9 }, /* abovedot Ë™ DOT ABOVE */ + { 0x02a1, 0x0126 }, /* Hstroke Ħ LATIN CAPITAL LETTER H WITH STROKE */ + { 0x02a6, 0x0124 }, /* Hcircumflex Ĥ LATIN CAPITAL LETTER H WITH CIRCUMFLEX */ + { 0x02a9, 0x0130 }, /* Iabovedot İ LATIN CAPITAL LETTER I WITH DOT ABOVE */ + { 0x02ab, 0x011e }, /* Gbreve Äž LATIN CAPITAL LETTER G WITH BREVE */ + { 0x02ac, 0x0134 }, /* Jcircumflex Ä´ LATIN CAPITAL LETTER J WITH CIRCUMFLEX */ + { 0x02b1, 0x0127 }, /* hstroke ħ LATIN SMALL LETTER H WITH STROKE */ + { 0x02b6, 0x0125 }, /* hcircumflex Ä¥ LATIN SMALL LETTER H WITH CIRCUMFLEX */ + { 0x02b9, 0x0131 }, /* idotless ı LATIN SMALL LETTER DOTLESS I */ + { 0x02bb, 0x011f }, /* gbreve ÄŸ LATIN SMALL LETTER G WITH BREVE */ + { 0x02bc, 0x0135 }, /* jcircumflex ĵ LATIN SMALL LETTER J WITH CIRCUMFLEX */ + { 0x02c5, 0x010a }, /* Cabovedot ÄŠ LATIN CAPITAL LETTER C WITH DOT ABOVE */ + { 0x02c6, 0x0108 }, /* Ccircumflex Ĉ LATIN CAPITAL LETTER C WITH CIRCUMFLEX */ + { 0x02d5, 0x0120 }, /* Gabovedot Ä  LATIN CAPITAL LETTER G WITH DOT ABOVE */ + { 0x02d8, 0x011c }, /* Gcircumflex Äœ LATIN CAPITAL LETTER G WITH CIRCUMFLEX */ + { 0x02dd, 0x016c }, /* Ubreve Ŭ LATIN CAPITAL LETTER U WITH BREVE */ + { 0x02de, 0x015c }, /* Scircumflex Åœ LATIN CAPITAL LETTER S WITH CIRCUMFLEX */ + { 0x02e5, 0x010b }, /* cabovedot Ä‹ LATIN SMALL LETTER C WITH DOT ABOVE */ + { 0x02e6, 0x0109 }, /* ccircumflex ĉ LATIN SMALL LETTER C WITH CIRCUMFLEX */ + { 0x02f5, 0x0121 }, /* gabovedot Ä¡ LATIN SMALL LETTER G WITH DOT ABOVE */ + { 0x02f8, 0x011d }, /* gcircumflex Ä LATIN SMALL LETTER G WITH CIRCUMFLEX */ + { 0x02fd, 0x016d }, /* ubreve Å­ LATIN SMALL LETTER U WITH BREVE */ + { 0x02fe, 0x015d }, /* scircumflex Å LATIN SMALL LETTER S WITH CIRCUMFLEX */ + { 0x03a2, 0x0138 }, /* kra ĸ LATIN SMALL LETTER KRA */ + { 0x03a3, 0x0156 }, /* Rcedilla Å– LATIN CAPITAL LETTER R WITH CEDILLA */ + { 0x03a5, 0x0128 }, /* Itilde Ĩ LATIN CAPITAL LETTER I WITH TILDE */ + { 0x03a6, 0x013b }, /* Lcedilla Ä» LATIN CAPITAL LETTER L WITH CEDILLA */ + { 0x03aa, 0x0112 }, /* Emacron Ä’ LATIN CAPITAL LETTER E WITH MACRON */ + { 0x03ab, 0x0122 }, /* Gcedilla Ä¢ LATIN CAPITAL LETTER G WITH CEDILLA */ + { 0x03ac, 0x0166 }, /* Tslash Ŧ LATIN CAPITAL LETTER T WITH STROKE */ + { 0x03b3, 0x0157 }, /* rcedilla Å— LATIN SMALL LETTER R WITH CEDILLA */ + { 0x03b5, 0x0129 }, /* itilde Ä© LATIN SMALL LETTER I WITH TILDE */ + { 0x03b6, 0x013c }, /* lcedilla ļ LATIN SMALL LETTER L WITH CEDILLA */ + { 0x03ba, 0x0113 }, /* emacron Ä“ LATIN SMALL LETTER E WITH MACRON */ + { 0x03bb, 0x0123 }, /* gcedilla Ä£ LATIN SMALL LETTER G WITH CEDILLA */ + { 0x03bc, 0x0167 }, /* tslash ŧ LATIN SMALL LETTER T WITH STROKE */ + { 0x03bd, 0x014a }, /* ENG ÅŠ LATIN CAPITAL LETTER ENG */ + { 0x03bf, 0x014b }, /* eng Å‹ LATIN SMALL LETTER ENG */ + { 0x03c0, 0x0100 }, /* Amacron Ä€ LATIN CAPITAL LETTER A WITH MACRON */ + { 0x03c7, 0x012e }, /* Iogonek Ä® LATIN CAPITAL LETTER I WITH OGONEK */ + { 0x03cc, 0x0116 }, /* Eabovedot Ä– LATIN CAPITAL LETTER E WITH DOT ABOVE */ + { 0x03cf, 0x012a }, /* Imacron Ī LATIN CAPITAL LETTER I WITH MACRON */ + { 0x03d1, 0x0145 }, /* Ncedilla Å… LATIN CAPITAL LETTER N WITH CEDILLA */ + { 0x03d2, 0x014c }, /* Omacron ÅŒ LATIN CAPITAL LETTER O WITH MACRON */ + { 0x03d3, 0x0136 }, /* Kcedilla Ķ LATIN CAPITAL LETTER K WITH CEDILLA */ + { 0x03d9, 0x0172 }, /* Uogonek Ų LATIN CAPITAL LETTER U WITH OGONEK */ + { 0x03dd, 0x0168 }, /* Utilde Ũ LATIN CAPITAL LETTER U WITH TILDE */ + { 0x03de, 0x016a }, /* Umacron Ū LATIN CAPITAL LETTER U WITH MACRON */ + { 0x03e0, 0x0101 }, /* amacron Ä LATIN SMALL LETTER A WITH MACRON */ + { 0x03e7, 0x012f }, /* iogonek į LATIN SMALL LETTER I WITH OGONEK */ + { 0x03ec, 0x0117 }, /* eabovedot Ä— LATIN SMALL LETTER E WITH DOT ABOVE */ + { 0x03ef, 0x012b }, /* imacron Ä« LATIN SMALL LETTER I WITH MACRON */ + { 0x03f1, 0x0146 }, /* ncedilla ņ LATIN SMALL LETTER N WITH CEDILLA */ + { 0x03f2, 0x014d }, /* omacron Å LATIN SMALL LETTER O WITH MACRON */ + { 0x03f3, 0x0137 }, /* kcedilla Ä· LATIN SMALL LETTER K WITH CEDILLA */ + { 0x03f9, 0x0173 }, /* uogonek ų LATIN SMALL LETTER U WITH OGONEK */ + { 0x03fd, 0x0169 }, /* utilde Å© LATIN SMALL LETTER U WITH TILDE */ + { 0x03fe, 0x016b }, /* umacron Å« LATIN SMALL LETTER U WITH MACRON */ + { 0x047e, 0x203e }, /* overline ‾ OVERLINE */ + { 0x04a1, 0x3002 }, /* kana_fullstop 。 IDEOGRAPHIC FULL STOP */ + { 0x04a2, 0x300c }, /* kana_openingbracket 「 LEFT CORNER BRACKET */ + { 0x04a3, 0x300d }, /* kana_closingbracket 〠RIGHT CORNER BRACKET */ + { 0x04a4, 0x3001 }, /* kana_comma 〠IDEOGRAPHIC COMMA */ + { 0x04a5, 0x30fb }, /* kana_conjunctive ・ KATAKANA MIDDLE DOT */ + { 0x04a6, 0x30f2 }, /* kana_WO ヲ KATAKANA LETTER WO */ + { 0x04a7, 0x30a1 }, /* kana_a ã‚¡ KATAKANA LETTER SMALL A */ + { 0x04a8, 0x30a3 }, /* kana_i ã‚£ KATAKANA LETTER SMALL I */ + { 0x04a9, 0x30a5 }, /* kana_u ã‚¥ KATAKANA LETTER SMALL U */ + { 0x04aa, 0x30a7 }, /* kana_e ã‚§ KATAKANA LETTER SMALL E */ + { 0x04ab, 0x30a9 }, /* kana_o ã‚© KATAKANA LETTER SMALL O */ + { 0x04ac, 0x30e3 }, /* kana_ya ャ KATAKANA LETTER SMALL YA */ + { 0x04ad, 0x30e5 }, /* kana_yu ュ KATAKANA LETTER SMALL YU */ + { 0x04ae, 0x30e7 }, /* kana_yo ョ KATAKANA LETTER SMALL YO */ + { 0x04af, 0x30c3 }, /* kana_tsu ッ KATAKANA LETTER SMALL TU */ + { 0x04b0, 0x30fc }, /* prolongedsound ー KATAKANA-HIRAGANA PROLONGED SOUND MARK */ + { 0x04b1, 0x30a2 }, /* kana_A ã‚¢ KATAKANA LETTER A */ + { 0x04b2, 0x30a4 }, /* kana_I イ KATAKANA LETTER I */ + { 0x04b3, 0x30a6 }, /* kana_U ウ KATAKANA LETTER U */ + { 0x04b4, 0x30a8 }, /* kana_E エ KATAKANA LETTER E */ + { 0x04b5, 0x30aa }, /* kana_O オ KATAKANA LETTER O */ + { 0x04b6, 0x30ab }, /* kana_KA ã‚« KATAKANA LETTER KA */ + { 0x04b7, 0x30ad }, /* kana_KI ã‚­ KATAKANA LETTER KI */ + { 0x04b8, 0x30af }, /* kana_KU ク KATAKANA LETTER KU */ + { 0x04b9, 0x30b1 }, /* kana_KE ケ KATAKANA LETTER KE */ + { 0x04ba, 0x30b3 }, /* kana_KO コ KATAKANA LETTER KO */ + { 0x04bb, 0x30b5 }, /* kana_SA サ KATAKANA LETTER SA */ + { 0x04bc, 0x30b7 }, /* kana_SHI ã‚· KATAKANA LETTER SI */ + { 0x04bd, 0x30b9 }, /* kana_SU ス KATAKANA LETTER SU */ + { 0x04be, 0x30bb }, /* kana_SE ã‚» KATAKANA LETTER SE */ + { 0x04bf, 0x30bd }, /* kana_SO ソ KATAKANA LETTER SO */ + { 0x04c0, 0x30bf }, /* kana_TA ã‚¿ KATAKANA LETTER TA */ + { 0x04c1, 0x30c1 }, /* kana_CHI ムKATAKANA LETTER TI */ + { 0x04c2, 0x30c4 }, /* kana_TSU ツ KATAKANA LETTER TU */ + { 0x04c3, 0x30c6 }, /* kana_TE テ KATAKANA LETTER TE */ + { 0x04c4, 0x30c8 }, /* kana_TO ト KATAKANA LETTER TO */ + { 0x04c5, 0x30ca }, /* kana_NA ナ KATAKANA LETTER NA */ + { 0x04c6, 0x30cb }, /* kana_NI ニ KATAKANA LETTER NI */ + { 0x04c7, 0x30cc }, /* kana_NU ヌ KATAKANA LETTER NU */ + { 0x04c8, 0x30cd }, /* kana_NE ムKATAKANA LETTER NE */ + { 0x04c9, 0x30ce }, /* kana_NO ノ KATAKANA LETTER NO */ + { 0x04ca, 0x30cf }, /* kana_HA ムKATAKANA LETTER HA */ + { 0x04cb, 0x30d2 }, /* kana_HI ヒ KATAKANA LETTER HI */ + { 0x04cc, 0x30d5 }, /* kana_FU フ KATAKANA LETTER HU */ + { 0x04cd, 0x30d8 }, /* kana_HE ヘ KATAKANA LETTER HE */ + { 0x04ce, 0x30db }, /* kana_HO ホ KATAKANA LETTER HO */ + { 0x04cf, 0x30de }, /* kana_MA マ KATAKANA LETTER MA */ + { 0x04d0, 0x30df }, /* kana_MI ミ KATAKANA LETTER MI */ + { 0x04d1, 0x30e0 }, /* kana_MU ム KATAKANA LETTER MU */ + { 0x04d2, 0x30e1 }, /* kana_ME メ KATAKANA LETTER ME */ + { 0x04d3, 0x30e2 }, /* kana_MO モ KATAKANA LETTER MO */ + { 0x04d4, 0x30e4 }, /* kana_YA ヤ KATAKANA LETTER YA */ + { 0x04d5, 0x30e6 }, /* kana_YU ユ KATAKANA LETTER YU */ + { 0x04d6, 0x30e8 }, /* kana_YO ヨ KATAKANA LETTER YO */ + { 0x04d7, 0x30e9 }, /* kana_RA ラ KATAKANA LETTER RA */ + { 0x04d8, 0x30ea }, /* kana_RI リ KATAKANA LETTER RI */ + { 0x04d9, 0x30eb }, /* kana_RU ル KATAKANA LETTER RU */ + { 0x04da, 0x30ec }, /* kana_RE レ KATAKANA LETTER RE */ + { 0x04db, 0x30ed }, /* kana_RO ロ KATAKANA LETTER RO */ + { 0x04dc, 0x30ef }, /* kana_WA ワ KATAKANA LETTER WA */ + { 0x04dd, 0x30f3 }, /* kana_N ン KATAKANA LETTER N */ + { 0x04de, 0x309b }, /* voicedsound ã‚› KATAKANA-HIRAGANA VOICED SOUND MARK */ + { 0x04df, 0x309c }, /* semivoicedsound ゜ KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK */ + { 0x05ac, 0x060c }, /* Arabic_comma ØŒ ARABIC COMMA */ + { 0x05bb, 0x061b }, /* Arabic_semicolon Ø› ARABIC SEMICOLON */ + { 0x05bf, 0x061f }, /* Arabic_question_mark ØŸ ARABIC QUESTION MARK */ + { 0x05c1, 0x0621 }, /* Arabic_hamza Ø¡ ARABIC LETTER HAMZA */ + { 0x05c2, 0x0622 }, /* Arabic_maddaonalef Ø¢ ARABIC LETTER ALEF WITH MADDA ABOVE */ + { 0x05c3, 0x0623 }, /* Arabic_hamzaonalef Ø£ ARABIC LETTER ALEF WITH HAMZA ABOVE */ + { 0x05c4, 0x0624 }, /* Arabic_hamzaonwaw ؤ ARABIC LETTER WAW WITH HAMZA ABOVE */ + { 0x05c5, 0x0625 }, /* Arabic_hamzaunderalef Ø¥ ARABIC LETTER ALEF WITH HAMZA BELOW */ + { 0x05c6, 0x0626 }, /* Arabic_hamzaonyeh ئ ARABIC LETTER YEH WITH HAMZA ABOVE */ + { 0x05c7, 0x0627 }, /* Arabic_alef ا ARABIC LETTER ALEF */ + { 0x05c8, 0x0628 }, /* Arabic_beh ب ARABIC LETTER BEH */ + { 0x05c9, 0x0629 }, /* Arabic_tehmarbuta Ø© ARABIC LETTER TEH MARBUTA */ + { 0x05ca, 0x062a }, /* Arabic_teh ت ARABIC LETTER TEH */ + { 0x05cb, 0x062b }, /* Arabic_theh Ø« ARABIC LETTER THEH */ + { 0x05cc, 0x062c }, /* Arabic_jeem ج ARABIC LETTER JEEM */ + { 0x05cd, 0x062d }, /* Arabic_hah Ø­ ARABIC LETTER HAH */ + { 0x05ce, 0x062e }, /* Arabic_khah Ø® ARABIC LETTER KHAH */ + { 0x05cf, 0x062f }, /* Arabic_dal د ARABIC LETTER DAL */ + { 0x05d0, 0x0630 }, /* Arabic_thal ذ ARABIC LETTER THAL */ + { 0x05d1, 0x0631 }, /* Arabic_ra ر ARABIC LETTER REH */ + { 0x05d2, 0x0632 }, /* Arabic_zain ز ARABIC LETTER ZAIN */ + { 0x05d3, 0x0633 }, /* Arabic_seen س ARABIC LETTER SEEN */ + { 0x05d4, 0x0634 }, /* Arabic_sheen Ø´ ARABIC LETTER SHEEN */ + { 0x05d5, 0x0635 }, /* Arabic_sad ص ARABIC LETTER SAD */ + { 0x05d6, 0x0636 }, /* Arabic_dad ض ARABIC LETTER DAD */ + { 0x05d7, 0x0637 }, /* Arabic_tah Ø· ARABIC LETTER TAH */ + { 0x05d8, 0x0638 }, /* Arabic_zah ظ ARABIC LETTER ZAH */ + { 0x05d9, 0x0639 }, /* Arabic_ain ع ARABIC LETTER AIN */ + { 0x05da, 0x063a }, /* Arabic_ghain غ ARABIC LETTER GHAIN */ + { 0x05e0, 0x0640 }, /* Arabic_tatweel Ù€ ARABIC TATWEEL */ + { 0x05e1, 0x0641 }, /* Arabic_feh Ù ARABIC LETTER FEH */ + { 0x05e2, 0x0642 }, /* Arabic_qaf Ù‚ ARABIC LETTER QAF */ + { 0x05e3, 0x0643 }, /* Arabic_kaf Ùƒ ARABIC LETTER KAF */ + { 0x05e4, 0x0644 }, /* Arabic_lam Ù„ ARABIC LETTER LAM */ + { 0x05e5, 0x0645 }, /* Arabic_meem Ù… ARABIC LETTER MEEM */ + { 0x05e6, 0x0646 }, /* Arabic_noon Ù† ARABIC LETTER NOON */ + { 0x05e7, 0x0647 }, /* Arabic_ha Ù‡ ARABIC LETTER HEH */ + { 0x05e8, 0x0648 }, /* Arabic_waw Ùˆ ARABIC LETTER WAW */ + { 0x05e9, 0x0649 }, /* Arabic_alefmaksura Ù‰ ARABIC LETTER ALEF MAKSURA */ + { 0x05ea, 0x064a }, /* Arabic_yeh ÙŠ ARABIC LETTER YEH */ + { 0x05eb, 0x064b }, /* Arabic_fathatan Ù‹ ARABIC FATHATAN */ + { 0x05ec, 0x064c }, /* Arabic_dammatan ÙŒ ARABIC DAMMATAN */ + { 0x05ed, 0x064d }, /* Arabic_kasratan Ù ARABIC KASRATAN */ + { 0x05ee, 0x064e }, /* Arabic_fatha ÙŽ ARABIC FATHA */ + { 0x05ef, 0x064f }, /* Arabic_damma Ù ARABIC DAMMA */ + { 0x05f0, 0x0650 }, /* Arabic_kasra Ù ARABIC KASRA */ + { 0x05f1, 0x0651 }, /* Arabic_shadda Ù‘ ARABIC SHADDA */ + { 0x05f2, 0x0652 }, /* Arabic_sukun Ù’ ARABIC SUKUN */ + { 0x06a1, 0x0452 }, /* Serbian_dje Ñ’ CYRILLIC SMALL LETTER DJE */ + { 0x06a2, 0x0453 }, /* Macedonia_gje Ñ“ CYRILLIC SMALL LETTER GJE */ + { 0x06a3, 0x0451 }, /* Cyrillic_io Ñ‘ CYRILLIC SMALL LETTER IO */ + { 0x06a4, 0x0454 }, /* Ukrainian_ie Ñ” CYRILLIC SMALL LETTER UKRAINIAN IE */ + { 0x06a5, 0x0455 }, /* Macedonia_dse Ñ• CYRILLIC SMALL LETTER DZE */ + { 0x06a6, 0x0456 }, /* Ukrainian_i Ñ– CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I */ + { 0x06a7, 0x0457 }, /* Ukrainian_yi Ñ— CYRILLIC SMALL LETTER YI */ + { 0x06a8, 0x0458 }, /* Cyrillic_je ј CYRILLIC SMALL LETTER JE */ + { 0x06a9, 0x0459 }, /* Cyrillic_lje Ñ™ CYRILLIC SMALL LETTER LJE */ + { 0x06aa, 0x045a }, /* Cyrillic_nje Ñš CYRILLIC SMALL LETTER NJE */ + { 0x06ab, 0x045b }, /* Serbian_tshe Ñ› CYRILLIC SMALL LETTER TSHE */ + { 0x06ac, 0x045c }, /* Macedonia_kje Ñœ CYRILLIC SMALL LETTER KJE */ + { 0x06ad, 0x0491 }, /* Ukrainian_ghe_with_upturn Ò‘ CYRILLIC SMALL LETTER GHE WITH UPTURN */ + { 0x06ae, 0x045e }, /* Byelorussian_shortu Ñž CYRILLIC SMALL LETTER SHORT U */ + { 0x06af, 0x045f }, /* Cyrillic_dzhe ÑŸ CYRILLIC SMALL LETTER DZHE */ + { 0x06b0, 0x2116 }, /* numerosign â„– NUMERO SIGN */ + { 0x06b1, 0x0402 }, /* Serbian_DJE Ђ CYRILLIC CAPITAL LETTER DJE */ + { 0x06b2, 0x0403 }, /* Macedonia_GJE Ѓ CYRILLIC CAPITAL LETTER GJE */ + { 0x06b3, 0x0401 }, /* Cyrillic_IO Ð CYRILLIC CAPITAL LETTER IO */ + { 0x06b4, 0x0404 }, /* Ukrainian_IE Є CYRILLIC CAPITAL LETTER UKRAINIAN IE */ + { 0x06b5, 0x0405 }, /* Macedonia_DSE Ð… CYRILLIC CAPITAL LETTER DZE */ + { 0x06b6, 0x0406 }, /* Ukrainian_I І CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I */ + { 0x06b7, 0x0407 }, /* Ukrainian_YI Ї CYRILLIC CAPITAL LETTER YI */ + { 0x06b8, 0x0408 }, /* Cyrillic_JE Ј CYRILLIC CAPITAL LETTER JE */ + { 0x06b9, 0x0409 }, /* Cyrillic_LJE Љ CYRILLIC CAPITAL LETTER LJE */ + { 0x06ba, 0x040a }, /* Cyrillic_NJE Њ CYRILLIC CAPITAL LETTER NJE */ + { 0x06bb, 0x040b }, /* Serbian_TSHE Ћ CYRILLIC CAPITAL LETTER TSHE */ + { 0x06bc, 0x040c }, /* Macedonia_KJE ÐŒ CYRILLIC CAPITAL LETTER KJE */ + { 0x06bd, 0x0490 }, /* Ukrainian_GHE_WITH_UPTURN Ò CYRILLIC CAPITAL LETTER GHE WITH UPTURN */ + { 0x06be, 0x040e }, /* Byelorussian_SHORTU ÐŽ CYRILLIC CAPITAL LETTER SHORT U */ + { 0x06bf, 0x040f }, /* Cyrillic_DZHE Ð CYRILLIC CAPITAL LETTER DZHE */ + { 0x06c0, 0x044e }, /* Cyrillic_yu ÑŽ CYRILLIC SMALL LETTER YU */ + { 0x06c1, 0x0430 }, /* Cyrillic_a а CYRILLIC SMALL LETTER A */ + { 0x06c2, 0x0431 }, /* Cyrillic_be б CYRILLIC SMALL LETTER BE */ + { 0x06c3, 0x0446 }, /* Cyrillic_tse ц CYRILLIC SMALL LETTER TSE */ + { 0x06c4, 0x0434 }, /* Cyrillic_de д CYRILLIC SMALL LETTER DE */ + { 0x06c5, 0x0435 }, /* Cyrillic_ie е CYRILLIC SMALL LETTER IE */ + { 0x06c6, 0x0444 }, /* Cyrillic_ef Ñ„ CYRILLIC SMALL LETTER EF */ + { 0x06c7, 0x0433 }, /* Cyrillic_ghe г CYRILLIC SMALL LETTER GHE */ + { 0x06c8, 0x0445 }, /* Cyrillic_ha Ñ… CYRILLIC SMALL LETTER HA */ + { 0x06c9, 0x0438 }, /* Cyrillic_i и CYRILLIC SMALL LETTER I */ + { 0x06ca, 0x0439 }, /* Cyrillic_shorti й CYRILLIC SMALL LETTER SHORT I */ + { 0x06cb, 0x043a }, /* Cyrillic_ka к CYRILLIC SMALL LETTER KA */ + { 0x06cc, 0x043b }, /* Cyrillic_el л CYRILLIC SMALL LETTER EL */ + { 0x06cd, 0x043c }, /* Cyrillic_em м CYRILLIC SMALL LETTER EM */ + { 0x06ce, 0x043d }, /* Cyrillic_en н CYRILLIC SMALL LETTER EN */ + { 0x06cf, 0x043e }, /* Cyrillic_o о CYRILLIC SMALL LETTER O */ + { 0x06d0, 0x043f }, /* Cyrillic_pe п CYRILLIC SMALL LETTER PE */ + { 0x06d1, 0x044f }, /* Cyrillic_ya Ñ CYRILLIC SMALL LETTER YA */ + { 0x06d2, 0x0440 }, /* Cyrillic_er Ñ€ CYRILLIC SMALL LETTER ER */ + { 0x06d3, 0x0441 }, /* Cyrillic_es Ñ CYRILLIC SMALL LETTER ES */ + { 0x06d4, 0x0442 }, /* Cyrillic_te Ñ‚ CYRILLIC SMALL LETTER TE */ + { 0x06d5, 0x0443 }, /* Cyrillic_u у CYRILLIC SMALL LETTER U */ + { 0x06d6, 0x0436 }, /* Cyrillic_zhe ж CYRILLIC SMALL LETTER ZHE */ + { 0x06d7, 0x0432 }, /* Cyrillic_ve в CYRILLIC SMALL LETTER VE */ + { 0x06d8, 0x044c }, /* Cyrillic_softsign ÑŒ CYRILLIC SMALL LETTER SOFT SIGN */ + { 0x06d9, 0x044b }, /* Cyrillic_yeru Ñ‹ CYRILLIC SMALL LETTER YERU */ + { 0x06da, 0x0437 }, /* Cyrillic_ze з CYRILLIC SMALL LETTER ZE */ + { 0x06db, 0x0448 }, /* Cyrillic_sha ш CYRILLIC SMALL LETTER SHA */ + { 0x06dc, 0x044d }, /* Cyrillic_e Ñ CYRILLIC SMALL LETTER E */ + { 0x06dd, 0x0449 }, /* Cyrillic_shcha щ CYRILLIC SMALL LETTER SHCHA */ + { 0x06de, 0x0447 }, /* Cyrillic_che ч CYRILLIC SMALL LETTER CHE */ + { 0x06df, 0x044a }, /* Cyrillic_hardsign ÑŠ CYRILLIC SMALL LETTER HARD SIGN */ + { 0x06e0, 0x042e }, /* Cyrillic_YU Ю CYRILLIC CAPITAL LETTER YU */ + { 0x06e1, 0x0410 }, /* Cyrillic_A Ð CYRILLIC CAPITAL LETTER A */ + { 0x06e2, 0x0411 }, /* Cyrillic_BE Б CYRILLIC CAPITAL LETTER BE */ + { 0x06e3, 0x0426 }, /* Cyrillic_TSE Ц CYRILLIC CAPITAL LETTER TSE */ + { 0x06e4, 0x0414 }, /* Cyrillic_DE Д CYRILLIC CAPITAL LETTER DE */ + { 0x06e5, 0x0415 }, /* Cyrillic_IE Е CYRILLIC CAPITAL LETTER IE */ + { 0x06e6, 0x0424 }, /* Cyrillic_EF Ф CYRILLIC CAPITAL LETTER EF */ + { 0x06e7, 0x0413 }, /* Cyrillic_GHE Г CYRILLIC CAPITAL LETTER GHE */ + { 0x06e8, 0x0425 }, /* Cyrillic_HA Ð¥ CYRILLIC CAPITAL LETTER HA */ + { 0x06e9, 0x0418 }, /* Cyrillic_I И CYRILLIC CAPITAL LETTER I */ + { 0x06ea, 0x0419 }, /* Cyrillic_SHORTI Й CYRILLIC CAPITAL LETTER SHORT I */ + { 0x06eb, 0x041a }, /* Cyrillic_KA К CYRILLIC CAPITAL LETTER KA */ + { 0x06ec, 0x041b }, /* Cyrillic_EL Л CYRILLIC CAPITAL LETTER EL */ + { 0x06ed, 0x041c }, /* Cyrillic_EM М CYRILLIC CAPITAL LETTER EM */ + { 0x06ee, 0x041d }, /* Cyrillic_EN Ð CYRILLIC CAPITAL LETTER EN */ + { 0x06ef, 0x041e }, /* Cyrillic_O О CYRILLIC CAPITAL LETTER O */ + { 0x06f0, 0x041f }, /* Cyrillic_PE П CYRILLIC CAPITAL LETTER PE */ + { 0x06f1, 0x042f }, /* Cyrillic_YA Я CYRILLIC CAPITAL LETTER YA */ + { 0x06f2, 0x0420 }, /* Cyrillic_ER Р CYRILLIC CAPITAL LETTER ER */ + { 0x06f3, 0x0421 }, /* Cyrillic_ES С CYRILLIC CAPITAL LETTER ES */ + { 0x06f4, 0x0422 }, /* Cyrillic_TE Т CYRILLIC CAPITAL LETTER TE */ + { 0x06f5, 0x0423 }, /* Cyrillic_U У CYRILLIC CAPITAL LETTER U */ + { 0x06f6, 0x0416 }, /* Cyrillic_ZHE Ж CYRILLIC CAPITAL LETTER ZHE */ + { 0x06f7, 0x0412 }, /* Cyrillic_VE Ð’ CYRILLIC CAPITAL LETTER VE */ + { 0x06f8, 0x042c }, /* Cyrillic_SOFTSIGN Ь CYRILLIC CAPITAL LETTER SOFT SIGN */ + { 0x06f9, 0x042b }, /* Cyrillic_YERU Ы CYRILLIC CAPITAL LETTER YERU */ + { 0x06fa, 0x0417 }, /* Cyrillic_ZE З CYRILLIC CAPITAL LETTER ZE */ + { 0x06fb, 0x0428 }, /* Cyrillic_SHA Ш CYRILLIC CAPITAL LETTER SHA */ + { 0x06fc, 0x042d }, /* Cyrillic_E Э CYRILLIC CAPITAL LETTER E */ + { 0x06fd, 0x0429 }, /* Cyrillic_SHCHA Щ CYRILLIC CAPITAL LETTER SHCHA */ + { 0x06fe, 0x0427 }, /* Cyrillic_CHE Ч CYRILLIC CAPITAL LETTER CHE */ + { 0x06ff, 0x042a }, /* Cyrillic_HARDSIGN Ъ CYRILLIC CAPITAL LETTER HARD SIGN */ + { 0x07a1, 0x0386 }, /* Greek_ALPHAaccent Ά GREEK CAPITAL LETTER ALPHA WITH TONOS */ + { 0x07a2, 0x0388 }, /* Greek_EPSILONaccent Έ GREEK CAPITAL LETTER EPSILON WITH TONOS */ + { 0x07a3, 0x0389 }, /* Greek_ETAaccent Ή GREEK CAPITAL LETTER ETA WITH TONOS */ + { 0x07a4, 0x038a }, /* Greek_IOTAaccent Ί GREEK CAPITAL LETTER IOTA WITH TONOS */ + { 0x07a5, 0x03aa }, /* Greek_IOTAdieresis Ϊ GREEK CAPITAL LETTER IOTA WITH DIALYTIKA */ + { 0x07a7, 0x038c }, /* Greek_OMICRONaccent ÎŒ GREEK CAPITAL LETTER OMICRON WITH TONOS */ + { 0x07a8, 0x038e }, /* Greek_UPSILONaccent ÎŽ GREEK CAPITAL LETTER UPSILON WITH TONOS */ + { 0x07a9, 0x03ab }, /* Greek_UPSILONdieresis Ϋ GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA */ + { 0x07ab, 0x038f }, /* Greek_OMEGAaccent Î GREEK CAPITAL LETTER OMEGA WITH TONOS */ + { 0x07ae, 0x0385 }, /* Greek_accentdieresis Î… GREEK DIALYTIKA TONOS */ + { 0x07af, 0x2015 }, /* Greek_horizbar ― HORIZONTAL BAR */ + { 0x07b1, 0x03ac }, /* Greek_alphaaccent ά GREEK SMALL LETTER ALPHA WITH TONOS */ + { 0x07b2, 0x03ad }, /* Greek_epsilonaccent έ GREEK SMALL LETTER EPSILON WITH TONOS */ + { 0x07b3, 0x03ae }, /* Greek_etaaccent ή GREEK SMALL LETTER ETA WITH TONOS */ + { 0x07b4, 0x03af }, /* Greek_iotaaccent ί GREEK SMALL LETTER IOTA WITH TONOS */ + { 0x07b5, 0x03ca }, /* Greek_iotadieresis ÏŠ GREEK SMALL LETTER IOTA WITH DIALYTIKA */ + { 0x07b6, 0x0390 }, /* Greek_iotaaccentdieresis Î GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS */ + { 0x07b7, 0x03cc }, /* Greek_omicronaccent ÏŒ GREEK SMALL LETTER OMICRON WITH TONOS */ + { 0x07b8, 0x03cd }, /* Greek_upsilonaccent Ï GREEK SMALL LETTER UPSILON WITH TONOS */ + { 0x07b9, 0x03cb }, /* Greek_upsilondieresis Ï‹ GREEK SMALL LETTER UPSILON WITH DIALYTIKA */ + { 0x07ba, 0x03b0 }, /* Greek_upsilonaccentdieresis ΰ GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS */ + { 0x07bb, 0x03ce }, /* Greek_omegaaccent ÏŽ GREEK SMALL LETTER OMEGA WITH TONOS */ + { 0x07c1, 0x0391 }, /* Greek_ALPHA Α GREEK CAPITAL LETTER ALPHA */ + { 0x07c2, 0x0392 }, /* Greek_BETA Î’ GREEK CAPITAL LETTER BETA */ + { 0x07c3, 0x0393 }, /* Greek_GAMMA Γ GREEK CAPITAL LETTER GAMMA */ + { 0x07c4, 0x0394 }, /* Greek_DELTA Δ GREEK CAPITAL LETTER DELTA */ + { 0x07c5, 0x0395 }, /* Greek_EPSILON Ε GREEK CAPITAL LETTER EPSILON */ + { 0x07c6, 0x0396 }, /* Greek_ZETA Ζ GREEK CAPITAL LETTER ZETA */ + { 0x07c7, 0x0397 }, /* Greek_ETA Η GREEK CAPITAL LETTER ETA */ + { 0x07c8, 0x0398 }, /* Greek_THETA Θ GREEK CAPITAL LETTER THETA */ + { 0x07c9, 0x0399 }, /* Greek_IOTA Ι GREEK CAPITAL LETTER IOTA */ + { 0x07ca, 0x039a }, /* Greek_KAPPA Κ GREEK CAPITAL LETTER KAPPA */ + { 0x07cb, 0x039b }, /* Greek_LAMBDA Λ GREEK CAPITAL LETTER LAMDA */ + { 0x07cc, 0x039c }, /* Greek_MU Μ GREEK CAPITAL LETTER MU */ + { 0x07cd, 0x039d }, /* Greek_NU Î GREEK CAPITAL LETTER NU */ + { 0x07ce, 0x039e }, /* Greek_XI Ξ GREEK CAPITAL LETTER XI */ + { 0x07cf, 0x039f }, /* Greek_OMICRON Ο GREEK CAPITAL LETTER OMICRON */ + { 0x07d0, 0x03a0 }, /* Greek_PI Π GREEK CAPITAL LETTER PI */ + { 0x07d1, 0x03a1 }, /* Greek_RHO Ρ GREEK CAPITAL LETTER RHO */ + { 0x07d2, 0x03a3 }, /* Greek_SIGMA Σ GREEK CAPITAL LETTER SIGMA */ + { 0x07d4, 0x03a4 }, /* Greek_TAU Τ GREEK CAPITAL LETTER TAU */ + { 0x07d5, 0x03a5 }, /* Greek_UPSILON Î¥ GREEK CAPITAL LETTER UPSILON */ + { 0x07d6, 0x03a6 }, /* Greek_PHI Φ GREEK CAPITAL LETTER PHI */ + { 0x07d7, 0x03a7 }, /* Greek_CHI Χ GREEK CAPITAL LETTER CHI */ + { 0x07d8, 0x03a8 }, /* Greek_PSI Ψ GREEK CAPITAL LETTER PSI */ + { 0x07d9, 0x03a9 }, /* Greek_OMEGA Ω GREEK CAPITAL LETTER OMEGA */ + { 0x07e1, 0x03b1 }, /* Greek_alpha α GREEK SMALL LETTER ALPHA */ + { 0x07e2, 0x03b2 }, /* Greek_beta β GREEK SMALL LETTER BETA */ + { 0x07e3, 0x03b3 }, /* Greek_gamma γ GREEK SMALL LETTER GAMMA */ + { 0x07e4, 0x03b4 }, /* Greek_delta δ GREEK SMALL LETTER DELTA */ + { 0x07e5, 0x03b5 }, /* Greek_epsilon ε GREEK SMALL LETTER EPSILON */ + { 0x07e6, 0x03b6 }, /* Greek_zeta ζ GREEK SMALL LETTER ZETA */ + { 0x07e7, 0x03b7 }, /* Greek_eta η GREEK SMALL LETTER ETA */ + { 0x07e8, 0x03b8 }, /* Greek_theta θ GREEK SMALL LETTER THETA */ + { 0x07e9, 0x03b9 }, /* Greek_iota ι GREEK SMALL LETTER IOTA */ + { 0x07ea, 0x03ba }, /* Greek_kappa κ GREEK SMALL LETTER KAPPA */ + { 0x07eb, 0x03bb }, /* Greek_lambda λ GREEK SMALL LETTER LAMDA */ + { 0x07ec, 0x03bc }, /* Greek_mu μ GREEK SMALL LETTER MU */ + { 0x07ed, 0x03bd }, /* Greek_nu ν GREEK SMALL LETTER NU */ + { 0x07ee, 0x03be }, /* Greek_xi ξ GREEK SMALL LETTER XI */ + { 0x07ef, 0x03bf }, /* Greek_omicron ο GREEK SMALL LETTER OMICRON */ + { 0x07f0, 0x03c0 }, /* Greek_pi Ï€ GREEK SMALL LETTER PI */ + { 0x07f1, 0x03c1 }, /* Greek_rho Ï GREEK SMALL LETTER RHO */ + { 0x07f2, 0x03c3 }, /* Greek_sigma σ GREEK SMALL LETTER SIGMA */ + { 0x07f3, 0x03c2 }, /* Greek_finalsmallsigma Ï‚ GREEK SMALL LETTER FINAL SIGMA */ + { 0x07f4, 0x03c4 }, /* Greek_tau Ï„ GREEK SMALL LETTER TAU */ + { 0x07f5, 0x03c5 }, /* Greek_upsilon Ï… GREEK SMALL LETTER UPSILON */ + { 0x07f6, 0x03c6 }, /* Greek_phi φ GREEK SMALL LETTER PHI */ + { 0x07f7, 0x03c7 }, /* Greek_chi χ GREEK SMALL LETTER CHI */ + { 0x07f8, 0x03c8 }, /* Greek_psi ψ GREEK SMALL LETTER PSI */ + { 0x07f9, 0x03c9 }, /* Greek_omega ω GREEK SMALL LETTER OMEGA */ +/* 0x08a1 leftradical ? ??? */ +/* 0x08a2 topleftradical ? ??? */ +/* 0x08a3 horizconnector ? ??? */ + { 0x08a4, 0x2320 }, /* topintegral ⌠ TOP HALF INTEGRAL */ + { 0x08a5, 0x2321 }, /* botintegral ⌡ BOTTOM HALF INTEGRAL */ + { 0x08a6, 0x2502 }, /* vertconnector │ BOX DRAWINGS LIGHT VERTICAL */ +/* 0x08a7 topleftsqbracket ? ??? */ +/* 0x08a8 botleftsqbracket ? ??? */ +/* 0x08a9 toprightsqbracket ? ??? */ +/* 0x08aa botrightsqbracket ? ??? */ +/* 0x08ab topleftparens ? ??? */ +/* 0x08ac botleftparens ? ??? */ +/* 0x08ad toprightparens ? ??? */ +/* 0x08ae botrightparens ? ??? */ +/* 0x08af leftmiddlecurlybrace ? ??? */ +/* 0x08b0 rightmiddlecurlybrace ? ??? */ +/* 0x08b1 topleftsummation ? ??? */ +/* 0x08b2 botleftsummation ? ??? */ +/* 0x08b3 topvertsummationconnector ? ??? */ +/* 0x08b4 botvertsummationconnector ? ??? */ +/* 0x08b5 toprightsummation ? ??? */ +/* 0x08b6 botrightsummation ? ??? */ +/* 0x08b7 rightmiddlesummation ? ??? */ + { 0x08bc, 0x2264 }, /* lessthanequal ≤ LESS-THAN OR EQUAL TO */ + { 0x08bd, 0x2260 }, /* notequal ≠ NOT EQUAL TO */ + { 0x08be, 0x2265 }, /* greaterthanequal ≥ GREATER-THAN OR EQUAL TO */ + { 0x08bf, 0x222b }, /* integral ∫ INTEGRAL */ + { 0x08c0, 0x2234 }, /* therefore ∴ THEREFORE */ + { 0x08c1, 0x221d }, /* variation ∠PROPORTIONAL TO */ + { 0x08c2, 0x221e }, /* infinity ∞ INFINITY */ + { 0x08c5, 0x2207 }, /* nabla ∇ NABLA */ + { 0x08c8, 0x2245 }, /* approximate ≅ APPROXIMATELY EQUAL TO */ +/* 0x08c9 similarequal ? ??? */ + { 0x08cd, 0x21d4 }, /* ifonlyif ⇔ LEFT RIGHT DOUBLE ARROW */ + { 0x08ce, 0x21d2 }, /* implies ⇒ RIGHTWARDS DOUBLE ARROW */ + { 0x08cf, 0x2261 }, /* identical ≡ IDENTICAL TO */ + { 0x08d6, 0x221a }, /* radical √ SQUARE ROOT */ + { 0x08da, 0x2282 }, /* includedin ⊂ SUBSET OF */ + { 0x08db, 0x2283 }, /* includes ⊃ SUPERSET OF */ + { 0x08dc, 0x2229 }, /* intersection ∩ INTERSECTION */ + { 0x08dd, 0x222a }, /* union ∪ UNION */ + { 0x08de, 0x2227 }, /* logicaland ∧ LOGICAL AND */ + { 0x08df, 0x2228 }, /* logicalor ∨ LOGICAL OR */ + { 0x08ef, 0x2202 }, /* partialderivative ∂ PARTIAL DIFFERENTIAL */ + { 0x08f6, 0x0192 }, /* function Æ’ LATIN SMALL LETTER F WITH HOOK */ + { 0x08fb, 0x2190 }, /* leftarrow ↠LEFTWARDS ARROW */ + { 0x08fc, 0x2191 }, /* uparrow ↑ UPWARDS ARROW */ + { 0x08fd, 0x2192 }, /* rightarrow → RIGHTWARDS ARROW */ + { 0x08fe, 0x2193 }, /* downarrow ↓ DOWNWARDS ARROW */ + { 0x09df, 0x2422 }, /* blank ⢠BLANK SYMBOL */ + { 0x09e0, 0x25c6 }, /* soliddiamond â—† BLACK DIAMOND */ + { 0x09e1, 0x2592 }, /* checkerboard â–’ MEDIUM SHADE */ + { 0x09e2, 0x2409 }, /* ht ≠SYMBOL FOR HORIZONTAL TABULATION */ + { 0x09e3, 0x240c }, /* ff ⌠SYMBOL FOR FORM FEED */ + { 0x09e4, 0x240d }, /* cr â SYMBOL FOR CARRIAGE RETURN */ + { 0x09e5, 0x240a }, /* lf ⊠SYMBOL FOR LINE FEED */ + { 0x09e8, 0x2424 }, /* nl ⤠SYMBOL FOR NEWLINE */ + { 0x09e9, 0x240b }, /* vt â‹ SYMBOL FOR VERTICAL TABULATION */ + { 0x09ea, 0x2518 }, /* lowrightcorner ┘ BOX DRAWINGS LIGHT UP AND LEFT */ + { 0x09eb, 0x2510 }, /* uprightcorner â” BOX DRAWINGS LIGHT DOWN AND LEFT */ + { 0x09ec, 0x250c }, /* upleftcorner ┌ BOX DRAWINGS LIGHT DOWN AND RIGHT */ + { 0x09ed, 0x2514 }, /* lowleftcorner â”” BOX DRAWINGS LIGHT UP AND RIGHT */ + { 0x09ee, 0x253c }, /* crossinglines ┼ BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL */ +/* 0x09ef horizlinescan1 ? ??? */ +/* 0x09f0 horizlinescan3 ? ??? */ + { 0x09f1, 0x2500 }, /* horizlinescan5 ─ BOX DRAWINGS LIGHT HORIZONTAL */ +/* 0x09f2 horizlinescan7 ? ??? */ +/* 0x09f3 horizlinescan9 ? ??? */ + { 0x09f4, 0x251c }, /* leftt ├ BOX DRAWINGS LIGHT VERTICAL AND RIGHT */ + { 0x09f5, 0x2524 }, /* rightt ┤ BOX DRAWINGS LIGHT VERTICAL AND LEFT */ + { 0x09f6, 0x2534 }, /* bott â”´ BOX DRAWINGS LIGHT UP AND HORIZONTAL */ + { 0x09f7, 0x252c }, /* topt ┬ BOX DRAWINGS LIGHT DOWN AND HORIZONTAL */ + { 0x09f8, 0x2502 }, /* vertbar │ BOX DRAWINGS LIGHT VERTICAL */ + { 0x0aa1, 0x2003 }, /* emspace   EM SPACE */ + { 0x0aa2, 0x2002 }, /* enspace   EN SPACE */ + { 0x0aa3, 0x2004 }, /* em3space   THREE-PER-EM SPACE */ + { 0x0aa4, 0x2005 }, /* em4space   FOUR-PER-EM SPACE */ + { 0x0aa5, 0x2007 }, /* digitspace   FIGURE SPACE */ + { 0x0aa6, 0x2008 }, /* punctspace   PUNCTUATION SPACE */ + { 0x0aa7, 0x2009 }, /* thinspace   THIN SPACE */ + { 0x0aa8, 0x200a }, /* hairspace   HAIR SPACE */ + { 0x0aa9, 0x2014 }, /* emdash — EM DASH */ + { 0x0aaa, 0x2013 }, /* endash – EN DASH */ +/* 0x0aac signifblank ? ??? */ + { 0x0aae, 0x2026 }, /* ellipsis … HORIZONTAL ELLIPSIS */ +/* 0x0aaf doubbaselinedot ? ??? */ + { 0x0ab0, 0x2153 }, /* onethird â…“ VULGAR FRACTION ONE THIRD */ + { 0x0ab1, 0x2154 }, /* twothirds â…” VULGAR FRACTION TWO THIRDS */ + { 0x0ab2, 0x2155 }, /* onefifth â…• VULGAR FRACTION ONE FIFTH */ + { 0x0ab3, 0x2156 }, /* twofifths â…– VULGAR FRACTION TWO FIFTHS */ + { 0x0ab4, 0x2157 }, /* threefifths â…— VULGAR FRACTION THREE FIFTHS */ + { 0x0ab5, 0x2158 }, /* fourfifths â…˜ VULGAR FRACTION FOUR FIFTHS */ + { 0x0ab6, 0x2159 }, /* onesixth â…™ VULGAR FRACTION ONE SIXTH */ + { 0x0ab7, 0x215a }, /* fivesixths â…š VULGAR FRACTION FIVE SIXTHS */ + { 0x0ab8, 0x2105 }, /* careof â„… CARE OF */ + { 0x0abb, 0x2012 }, /* figdash ‒ FIGURE DASH */ + { 0x0abc, 0x2329 }, /* leftanglebracket 〈 LEFT-POINTING ANGLE BRACKET */ + { 0x0abd, 0x002e }, /* decimalpoint . FULL STOP */ + { 0x0abe, 0x232a }, /* rightanglebracket 〉 RIGHT-POINTING ANGLE BRACKET */ +/* 0x0abf marker ? ??? */ + { 0x0ac3, 0x215b }, /* oneeighth â…› VULGAR FRACTION ONE EIGHTH */ + { 0x0ac4, 0x215c }, /* threeeighths â…œ VULGAR FRACTION THREE EIGHTHS */ + { 0x0ac5, 0x215d }, /* fiveeighths â… VULGAR FRACTION FIVE EIGHTHS */ + { 0x0ac6, 0x215e }, /* seveneighths â…ž VULGAR FRACTION SEVEN EIGHTHS */ + { 0x0ac9, 0x2122 }, /* trademark â„¢ TRADE MARK SIGN */ + { 0x0aca, 0x2613 }, /* signaturemark ☓ SALTIRE */ +/* 0x0acb trademarkincircle ? ??? */ + { 0x0acc, 0x25c1 }, /* leftopentriangle â— WHITE LEFT-POINTING TRIANGLE */ + { 0x0acd, 0x25b7 }, /* rightopentriangle â–· WHITE RIGHT-POINTING TRIANGLE */ + { 0x0ace, 0x25cb }, /* emopencircle â—‹ WHITE CIRCLE */ + { 0x0acf, 0x25a1 }, /* emopenrectangle â–¡ WHITE SQUARE */ + { 0x0ad0, 0x2018 }, /* leftsinglequotemark ‘ LEFT SINGLE QUOTATION MARK */ + { 0x0ad1, 0x2019 }, /* rightsinglequotemark ’ RIGHT SINGLE QUOTATION MARK */ + { 0x0ad2, 0x201c }, /* leftdoublequotemark “ LEFT DOUBLE QUOTATION MARK */ + { 0x0ad3, 0x201d }, /* rightdoublequotemark †RIGHT DOUBLE QUOTATION MARK */ + { 0x0ad4, 0x211e }, /* prescription ℞ PRESCRIPTION TAKE */ + { 0x0ad6, 0x2032 }, /* minutes ′ PRIME */ + { 0x0ad7, 0x2033 }, /* seconds ″ DOUBLE PRIME */ + { 0x0ad9, 0x271d }, /* latincross ✠LATIN CROSS */ +/* 0x0ada hexagram ? ??? */ + { 0x0adb, 0x25ac }, /* filledrectbullet â–¬ BLACK RECTANGLE */ + { 0x0adc, 0x25c0 }, /* filledlefttribullet â—€ BLACK LEFT-POINTING TRIANGLE */ + { 0x0add, 0x25b6 }, /* filledrighttribullet â–¶ BLACK RIGHT-POINTING TRIANGLE */ + { 0x0ade, 0x25cf }, /* emfilledcircle â— BLACK CIRCLE */ + { 0x0adf, 0x25a0 }, /* emfilledrect â–  BLACK SQUARE */ + { 0x0ae0, 0x25e6 }, /* enopencircbullet â—¦ WHITE BULLET */ + { 0x0ae1, 0x25ab }, /* enopensquarebullet â–« WHITE SMALL SQUARE */ + { 0x0ae2, 0x25ad }, /* openrectbullet â–­ WHITE RECTANGLE */ + { 0x0ae3, 0x25b3 }, /* opentribulletup â–³ WHITE UP-POINTING TRIANGLE */ + { 0x0ae4, 0x25bd }, /* opentribulletdown â–½ WHITE DOWN-POINTING TRIANGLE */ + { 0x0ae5, 0x2606 }, /* openstar ☆ WHITE STAR */ + { 0x0ae6, 0x2022 }, /* enfilledcircbullet • BULLET */ + { 0x0ae7, 0x25aa }, /* enfilledsqbullet â–ª BLACK SMALL SQUARE */ + { 0x0ae8, 0x25b2 }, /* filledtribulletup â–² BLACK UP-POINTING TRIANGLE */ + { 0x0ae9, 0x25bc }, /* filledtribulletdown â–¼ BLACK DOWN-POINTING TRIANGLE */ + { 0x0aea, 0x261c }, /* leftpointer ☜ WHITE LEFT POINTING INDEX */ + { 0x0aeb, 0x261e }, /* rightpointer ☞ WHITE RIGHT POINTING INDEX */ + { 0x0aec, 0x2663 }, /* club ♣ BLACK CLUB SUIT */ + { 0x0aed, 0x2666 }, /* diamond ♦ BLACK DIAMOND SUIT */ + { 0x0aee, 0x2665 }, /* heart ♥ BLACK HEART SUIT */ + { 0x0af0, 0x2720 }, /* maltesecross ✠ MALTESE CROSS */ + { 0x0af1, 0x2020 }, /* dagger † DAGGER */ + { 0x0af2, 0x2021 }, /* doubledagger ‡ DOUBLE DAGGER */ + { 0x0af3, 0x2713 }, /* checkmark ✓ CHECK MARK */ + { 0x0af4, 0x2717 }, /* ballotcross ✗ BALLOT X */ + { 0x0af5, 0x266f }, /* musicalsharp ♯ MUSIC SHARP SIGN */ + { 0x0af6, 0x266d }, /* musicalflat â™­ MUSIC FLAT SIGN */ + { 0x0af7, 0x2642 }, /* malesymbol ♂ MALE SIGN */ + { 0x0af8, 0x2640 }, /* femalesymbol ♀ FEMALE SIGN */ + { 0x0af9, 0x260e }, /* telephone ☎ BLACK TELEPHONE */ + { 0x0afa, 0x2315 }, /* telephonerecorder ⌕ TELEPHONE RECORDER */ + { 0x0afb, 0x2117 }, /* phonographcopyright â„— SOUND RECORDING COPYRIGHT */ + { 0x0afc, 0x2038 }, /* caret ‸ CARET */ + { 0x0afd, 0x201a }, /* singlelowquotemark ‚ SINGLE LOW-9 QUOTATION MARK */ + { 0x0afe, 0x201e }, /* doublelowquotemark „ DOUBLE LOW-9 QUOTATION MARK */ +/* 0x0aff cursor ? ??? */ + { 0x0ba3, 0x003c }, /* leftcaret < LESS-THAN SIGN */ + { 0x0ba6, 0x003e }, /* rightcaret > GREATER-THAN SIGN */ + { 0x0ba8, 0x2228 }, /* downcaret ∨ LOGICAL OR */ + { 0x0ba9, 0x2227 }, /* upcaret ∧ LOGICAL AND */ + { 0x0bc0, 0x00af }, /* overbar ¯ MACRON */ + { 0x0bc2, 0x22a4 }, /* downtack ⊤ DOWN TACK */ + { 0x0bc3, 0x2229 }, /* upshoe ∩ INTERSECTION */ + { 0x0bc4, 0x230a }, /* downstile ⌊ LEFT FLOOR */ + { 0x0bc6, 0x005f }, /* underbar _ LOW LINE */ + { 0x0bca, 0x2218 }, /* jot ∘ RING OPERATOR */ + { 0x0bcc, 0x2395 }, /* quad ⎕ APL FUNCTIONAL SYMBOL QUAD (Unicode 3.0) */ + { 0x0bce, 0x22a5 }, /* uptack ⊥ UP TACK */ + { 0x0bcf, 0x25cb }, /* circle â—‹ WHITE CIRCLE */ + { 0x0bd3, 0x2308 }, /* upstile ⌈ LEFT CEILING */ + { 0x0bd6, 0x222a }, /* downshoe ∪ UNION */ + { 0x0bd8, 0x2283 }, /* rightshoe ⊃ SUPERSET OF */ + { 0x0bda, 0x2282 }, /* leftshoe ⊂ SUBSET OF */ + { 0x0bdc, 0x22a3 }, /* lefttack ⊣ LEFT TACK */ + { 0x0bfc, 0x22a2 }, /* righttack ⊢ RIGHT TACK */ + { 0x0cdf, 0x2017 }, /* hebrew_doublelowline ‗ DOUBLE LOW LINE */ + { 0x0ce0, 0x05d0 }, /* hebrew_aleph × HEBREW LETTER ALEF */ + { 0x0ce1, 0x05d1 }, /* hebrew_bet ב HEBREW LETTER BET */ + { 0x0ce2, 0x05d2 }, /* hebrew_gimel ×’ HEBREW LETTER GIMEL */ + { 0x0ce3, 0x05d3 }, /* hebrew_dalet ד HEBREW LETTER DALET */ + { 0x0ce4, 0x05d4 }, /* hebrew_he ×” HEBREW LETTER HE */ + { 0x0ce5, 0x05d5 }, /* hebrew_waw ו HEBREW LETTER VAV */ + { 0x0ce6, 0x05d6 }, /* hebrew_zain ×– HEBREW LETTER ZAYIN */ + { 0x0ce7, 0x05d7 }, /* hebrew_chet ×— HEBREW LETTER HET */ + { 0x0ce8, 0x05d8 }, /* hebrew_tet ט HEBREW LETTER TET */ + { 0x0ce9, 0x05d9 }, /* hebrew_yod ×™ HEBREW LETTER YOD */ + { 0x0cea, 0x05da }, /* hebrew_finalkaph ך HEBREW LETTER FINAL KAF */ + { 0x0ceb, 0x05db }, /* hebrew_kaph ×› HEBREW LETTER KAF */ + { 0x0cec, 0x05dc }, /* hebrew_lamed ל HEBREW LETTER LAMED */ + { 0x0ced, 0x05dd }, /* hebrew_finalmem × HEBREW LETTER FINAL MEM */ + { 0x0cee, 0x05de }, /* hebrew_mem מ HEBREW LETTER MEM */ + { 0x0cef, 0x05df }, /* hebrew_finalnun ן HEBREW LETTER FINAL NUN */ + { 0x0cf0, 0x05e0 }, /* hebrew_nun ×  HEBREW LETTER NUN */ + { 0x0cf1, 0x05e1 }, /* hebrew_samech ס HEBREW LETTER SAMEKH */ + { 0x0cf2, 0x05e2 }, /* hebrew_ayin ×¢ HEBREW LETTER AYIN */ + { 0x0cf3, 0x05e3 }, /* hebrew_finalpe ×£ HEBREW LETTER FINAL PE */ + { 0x0cf4, 0x05e4 }, /* hebrew_pe פ HEBREW LETTER PE */ + { 0x0cf5, 0x05e5 }, /* hebrew_finalzade ×¥ HEBREW LETTER FINAL TSADI */ + { 0x0cf6, 0x05e6 }, /* hebrew_zade צ HEBREW LETTER TSADI */ + { 0x0cf7, 0x05e7 }, /* hebrew_qoph ×§ HEBREW LETTER QOF */ + { 0x0cf8, 0x05e8 }, /* hebrew_resh ר HEBREW LETTER RESH */ + { 0x0cf9, 0x05e9 }, /* hebrew_shin ש HEBREW LETTER SHIN */ + { 0x0cfa, 0x05ea }, /* hebrew_taw ת HEBREW LETTER TAV */ + { 0x0da1, 0x0e01 }, /* Thai_kokai ภTHAI CHARACTER KO KAI */ + { 0x0da2, 0x0e02 }, /* Thai_khokhai ข THAI CHARACTER KHO KHAI */ + { 0x0da3, 0x0e03 }, /* Thai_khokhuat ฃ THAI CHARACTER KHO KHUAT */ + { 0x0da4, 0x0e04 }, /* Thai_khokhwai ค THAI CHARACTER KHO KHWAI */ + { 0x0da5, 0x0e05 }, /* Thai_khokhon ฅ THAI CHARACTER KHO KHON */ + { 0x0da6, 0x0e06 }, /* Thai_khorakhang ฆ THAI CHARACTER KHO RAKHANG */ + { 0x0da7, 0x0e07 }, /* Thai_ngongu ง THAI CHARACTER NGO NGU */ + { 0x0da8, 0x0e08 }, /* Thai_chochan จ THAI CHARACTER CHO CHAN */ + { 0x0da9, 0x0e09 }, /* Thai_choching ฉ THAI CHARACTER CHO CHING */ + { 0x0daa, 0x0e0a }, /* Thai_chochang ช THAI CHARACTER CHO CHANG */ + { 0x0dab, 0x0e0b }, /* Thai_soso ซ THAI CHARACTER SO SO */ + { 0x0dac, 0x0e0c }, /* Thai_chochoe ฌ THAI CHARACTER CHO CHOE */ + { 0x0dad, 0x0e0d }, /* Thai_yoying ภTHAI CHARACTER YO YING */ + { 0x0dae, 0x0e0e }, /* Thai_dochada ฎ THAI CHARACTER DO CHADA */ + { 0x0daf, 0x0e0f }, /* Thai_topatak ภTHAI CHARACTER TO PATAK */ + { 0x0db0, 0x0e10 }, /* Thai_thothan ภTHAI CHARACTER THO THAN */ + { 0x0db1, 0x0e11 }, /* Thai_thonangmontho ฑ THAI CHARACTER THO NANGMONTHO */ + { 0x0db2, 0x0e12 }, /* Thai_thophuthao ฒ THAI CHARACTER THO PHUTHAO */ + { 0x0db3, 0x0e13 }, /* Thai_nonen ณ THAI CHARACTER NO NEN */ + { 0x0db4, 0x0e14 }, /* Thai_dodek ด THAI CHARACTER DO DEK */ + { 0x0db5, 0x0e15 }, /* Thai_totao ต THAI CHARACTER TO TAO */ + { 0x0db6, 0x0e16 }, /* Thai_thothung ถ THAI CHARACTER THO THUNG */ + { 0x0db7, 0x0e17 }, /* Thai_thothahan ท THAI CHARACTER THO THAHAN */ + { 0x0db8, 0x0e18 }, /* Thai_thothong ธ THAI CHARACTER THO THONG */ + { 0x0db9, 0x0e19 }, /* Thai_nonu น THAI CHARACTER NO NU */ + { 0x0dba, 0x0e1a }, /* Thai_bobaimai บ THAI CHARACTER BO BAIMAI */ + { 0x0dbb, 0x0e1b }, /* Thai_popla ป THAI CHARACTER PO PLA */ + { 0x0dbc, 0x0e1c }, /* Thai_phophung ผ THAI CHARACTER PHO PHUNG */ + { 0x0dbd, 0x0e1d }, /* Thai_fofa ภTHAI CHARACTER FO FA */ + { 0x0dbe, 0x0e1e }, /* Thai_phophan พ THAI CHARACTER PHO PHAN */ + { 0x0dbf, 0x0e1f }, /* Thai_fofan ฟ THAI CHARACTER FO FAN */ + { 0x0dc0, 0x0e20 }, /* Thai_phosamphao ภ THAI CHARACTER PHO SAMPHAO */ + { 0x0dc1, 0x0e21 }, /* Thai_moma ม THAI CHARACTER MO MA */ + { 0x0dc2, 0x0e22 }, /* Thai_yoyak ย THAI CHARACTER YO YAK */ + { 0x0dc3, 0x0e23 }, /* Thai_rorua ร THAI CHARACTER RO RUA */ + { 0x0dc4, 0x0e24 }, /* Thai_ru ฤ THAI CHARACTER RU */ + { 0x0dc5, 0x0e25 }, /* Thai_loling ล THAI CHARACTER LO LING */ + { 0x0dc6, 0x0e26 }, /* Thai_lu ฦ THAI CHARACTER LU */ + { 0x0dc7, 0x0e27 }, /* Thai_wowaen ว THAI CHARACTER WO WAEN */ + { 0x0dc8, 0x0e28 }, /* Thai_sosala ศ THAI CHARACTER SO SALA */ + { 0x0dc9, 0x0e29 }, /* Thai_sorusi ษ THAI CHARACTER SO RUSI */ + { 0x0dca, 0x0e2a }, /* Thai_sosua ส THAI CHARACTER SO SUA */ + { 0x0dcb, 0x0e2b }, /* Thai_hohip ห THAI CHARACTER HO HIP */ + { 0x0dcc, 0x0e2c }, /* Thai_lochula ฬ THAI CHARACTER LO CHULA */ + { 0x0dcd, 0x0e2d }, /* Thai_oang อ THAI CHARACTER O ANG */ + { 0x0dce, 0x0e2e }, /* Thai_honokhuk ฮ THAI CHARACTER HO NOKHUK */ + { 0x0dcf, 0x0e2f }, /* Thai_paiyannoi ฯ THAI CHARACTER PAIYANNOI */ + { 0x0dd0, 0x0e30 }, /* Thai_saraa ะ THAI CHARACTER SARA A */ + { 0x0dd1, 0x0e31 }, /* Thai_maihanakat ั THAI CHARACTER MAI HAN-AKAT */ + { 0x0dd2, 0x0e32 }, /* Thai_saraaa า THAI CHARACTER SARA AA */ + { 0x0dd3, 0x0e33 }, /* Thai_saraam ำ THAI CHARACTER SARA AM */ + { 0x0dd4, 0x0e34 }, /* Thai_sarai ิ THAI CHARACTER SARA I */ + { 0x0dd5, 0x0e35 }, /* Thai_saraii ี THAI CHARACTER SARA II */ + { 0x0dd6, 0x0e36 }, /* Thai_saraue ึ THAI CHARACTER SARA UE */ + { 0x0dd7, 0x0e37 }, /* Thai_sarauee ื THAI CHARACTER SARA UEE */ + { 0x0dd8, 0x0e38 }, /* Thai_sarau ุ THAI CHARACTER SARA U */ + { 0x0dd9, 0x0e39 }, /* Thai_sarauu ู THAI CHARACTER SARA UU */ + { 0x0dda, 0x0e3a }, /* Thai_phinthu ฺ THAI CHARACTER PHINTHU */ + { 0x0dde, 0x0e3e }, /* Thai_maihanakat_maitho ฾ ??? */ + { 0x0ddf, 0x0e3f }, /* Thai_baht ฿ THAI CURRENCY SYMBOL BAHT */ + { 0x0de0, 0x0e40 }, /* Thai_sarae เ THAI CHARACTER SARA E */ + { 0x0de1, 0x0e41 }, /* Thai_saraae ๠THAI CHARACTER SARA AE */ + { 0x0de2, 0x0e42 }, /* Thai_sarao โ THAI CHARACTER SARA O */ + { 0x0de3, 0x0e43 }, /* Thai_saraaimaimuan ใ THAI CHARACTER SARA AI MAIMUAN */ + { 0x0de4, 0x0e44 }, /* Thai_saraaimaimalai ไ THAI CHARACTER SARA AI MAIMALAI */ + { 0x0de5, 0x0e45 }, /* Thai_lakkhangyao ๅ THAI CHARACTER LAKKHANGYAO */ + { 0x0de6, 0x0e46 }, /* Thai_maiyamok ๆ THAI CHARACTER MAIYAMOK */ + { 0x0de7, 0x0e47 }, /* Thai_maitaikhu ็ THAI CHARACTER MAITAIKHU */ + { 0x0de8, 0x0e48 }, /* Thai_maiek ่ THAI CHARACTER MAI EK */ + { 0x0de9, 0x0e49 }, /* Thai_maitho ้ THAI CHARACTER MAI THO */ + { 0x0dea, 0x0e4a }, /* Thai_maitri ๊ THAI CHARACTER MAI TRI */ + { 0x0deb, 0x0e4b }, /* Thai_maichattawa ๋ THAI CHARACTER MAI CHATTAWA */ + { 0x0dec, 0x0e4c }, /* Thai_thanthakhat ์ THAI CHARACTER THANTHAKHAT */ + { 0x0ded, 0x0e4d }, /* Thai_nikhahit ๠THAI CHARACTER NIKHAHIT */ + { 0x0df0, 0x0e50 }, /* Thai_leksun ๠THAI DIGIT ZERO */ + { 0x0df1, 0x0e51 }, /* Thai_leknung ๑ THAI DIGIT ONE */ + { 0x0df2, 0x0e52 }, /* Thai_leksong ๒ THAI DIGIT TWO */ + { 0x0df3, 0x0e53 }, /* Thai_leksam ๓ THAI DIGIT THREE */ + { 0x0df4, 0x0e54 }, /* Thai_leksi ๔ THAI DIGIT FOUR */ + { 0x0df5, 0x0e55 }, /* Thai_lekha ๕ THAI DIGIT FIVE */ + { 0x0df6, 0x0e56 }, /* Thai_lekhok ๖ THAI DIGIT SIX */ + { 0x0df7, 0x0e57 }, /* Thai_lekchet ๗ THAI DIGIT SEVEN */ + { 0x0df8, 0x0e58 }, /* Thai_lekpaet ๘ THAI DIGIT EIGHT */ + { 0x0df9, 0x0e59 }, /* Thai_lekkao ๙ THAI DIGIT NINE */ + { 0x0ea1, 0x3131 }, /* Hangul_Kiyeog ㄱ HANGUL LETTER KIYEOK */ + { 0x0ea2, 0x3132 }, /* Hangul_SsangKiyeog ㄲ HANGUL LETTER SSANGKIYEOK */ + { 0x0ea3, 0x3133 }, /* Hangul_KiyeogSios ㄳ HANGUL LETTER KIYEOK-SIOS */ + { 0x0ea4, 0x3134 }, /* Hangul_Nieun ã„´ HANGUL LETTER NIEUN */ + { 0x0ea5, 0x3135 }, /* Hangul_NieunJieuj ㄵ HANGUL LETTER NIEUN-CIEUC */ + { 0x0ea6, 0x3136 }, /* Hangul_NieunHieuh ã„¶ HANGUL LETTER NIEUN-HIEUH */ + { 0x0ea7, 0x3137 }, /* Hangul_Dikeud ã„· HANGUL LETTER TIKEUT */ + { 0x0ea8, 0x3138 }, /* Hangul_SsangDikeud ㄸ HANGUL LETTER SSANGTIKEUT */ + { 0x0ea9, 0x3139 }, /* Hangul_Rieul ㄹ HANGUL LETTER RIEUL */ + { 0x0eaa, 0x313a }, /* Hangul_RieulKiyeog ㄺ HANGUL LETTER RIEUL-KIYEOK */ + { 0x0eab, 0x313b }, /* Hangul_RieulMieum ã„» HANGUL LETTER RIEUL-MIEUM */ + { 0x0eac, 0x313c }, /* Hangul_RieulPieub ㄼ HANGUL LETTER RIEUL-PIEUP */ + { 0x0ead, 0x313d }, /* Hangul_RieulSios ㄽ HANGUL LETTER RIEUL-SIOS */ + { 0x0eae, 0x313e }, /* Hangul_RieulTieut ㄾ HANGUL LETTER RIEUL-THIEUTH */ + { 0x0eaf, 0x313f }, /* Hangul_RieulPhieuf ã„¿ HANGUL LETTER RIEUL-PHIEUPH */ + { 0x0eb0, 0x3140 }, /* Hangul_RieulHieuh ã…€ HANGUL LETTER RIEUL-HIEUH */ + { 0x0eb1, 0x3141 }, /* Hangul_Mieum ã… HANGUL LETTER MIEUM */ + { 0x0eb2, 0x3142 }, /* Hangul_Pieub ã…‚ HANGUL LETTER PIEUP */ + { 0x0eb3, 0x3143 }, /* Hangul_SsangPieub ã…ƒ HANGUL LETTER SSANGPIEUP */ + { 0x0eb4, 0x3144 }, /* Hangul_PieubSios ã…„ HANGUL LETTER PIEUP-SIOS */ + { 0x0eb5, 0x3145 }, /* Hangul_Sios ã…… HANGUL LETTER SIOS */ + { 0x0eb6, 0x3146 }, /* Hangul_SsangSios ã…† HANGUL LETTER SSANGSIOS */ + { 0x0eb7, 0x3147 }, /* Hangul_Ieung ã…‡ HANGUL LETTER IEUNG */ + { 0x0eb8, 0x3148 }, /* Hangul_Jieuj ã…ˆ HANGUL LETTER CIEUC */ + { 0x0eb9, 0x3149 }, /* Hangul_SsangJieuj ã…‰ HANGUL LETTER SSANGCIEUC */ + { 0x0eba, 0x314a }, /* Hangul_Cieuc ã…Š HANGUL LETTER CHIEUCH */ + { 0x0ebb, 0x314b }, /* Hangul_Khieuq ã…‹ HANGUL LETTER KHIEUKH */ + { 0x0ebc, 0x314c }, /* Hangul_Tieut ã…Œ HANGUL LETTER THIEUTH */ + { 0x0ebd, 0x314d }, /* Hangul_Phieuf ã… HANGUL LETTER PHIEUPH */ + { 0x0ebe, 0x314e }, /* Hangul_Hieuh ã…Ž HANGUL LETTER HIEUH */ + { 0x0ebf, 0x314f }, /* Hangul_A ã… HANGUL LETTER A */ + { 0x0ec0, 0x3150 }, /* Hangul_AE ã… HANGUL LETTER AE */ + { 0x0ec1, 0x3151 }, /* Hangul_YA ã…‘ HANGUL LETTER YA */ + { 0x0ec2, 0x3152 }, /* Hangul_YAE ã…’ HANGUL LETTER YAE */ + { 0x0ec3, 0x3153 }, /* Hangul_EO ã…“ HANGUL LETTER EO */ + { 0x0ec4, 0x3154 }, /* Hangul_E ã…” HANGUL LETTER E */ + { 0x0ec5, 0x3155 }, /* Hangul_YEO ã…• HANGUL LETTER YEO */ + { 0x0ec6, 0x3156 }, /* Hangul_YE ã…– HANGUL LETTER YE */ + { 0x0ec7, 0x3157 }, /* Hangul_O ã…— HANGUL LETTER O */ + { 0x0ec8, 0x3158 }, /* Hangul_WA ã…˜ HANGUL LETTER WA */ + { 0x0ec9, 0x3159 }, /* Hangul_WAE ã…™ HANGUL LETTER WAE */ + { 0x0eca, 0x315a }, /* Hangul_OE ã…š HANGUL LETTER OE */ + { 0x0ecb, 0x315b }, /* Hangul_YO ã…› HANGUL LETTER YO */ + { 0x0ecc, 0x315c }, /* Hangul_U ã…œ HANGUL LETTER U */ + { 0x0ecd, 0x315d }, /* Hangul_WEO ã… HANGUL LETTER WEO */ + { 0x0ece, 0x315e }, /* Hangul_WE ã…ž HANGUL LETTER WE */ + { 0x0ecf, 0x315f }, /* Hangul_WI ã…Ÿ HANGUL LETTER WI */ + { 0x0ed0, 0x3160 }, /* Hangul_YU ã…  HANGUL LETTER YU */ + { 0x0ed1, 0x3161 }, /* Hangul_EU ã…¡ HANGUL LETTER EU */ + { 0x0ed2, 0x3162 }, /* Hangul_YI ã…¢ HANGUL LETTER YI */ + { 0x0ed3, 0x3163 }, /* Hangul_I ã…£ HANGUL LETTER I */ + { 0x0ed4, 0x11a8 }, /* Hangul_J_Kiyeog ᆨ HANGUL JONGSEONG KIYEOK */ + { 0x0ed5, 0x11a9 }, /* Hangul_J_SsangKiyeog ᆩ HANGUL JONGSEONG SSANGKIYEOK */ + { 0x0ed6, 0x11aa }, /* Hangul_J_KiyeogSios ᆪ HANGUL JONGSEONG KIYEOK-SIOS */ + { 0x0ed7, 0x11ab }, /* Hangul_J_Nieun ᆫ HANGUL JONGSEONG NIEUN */ + { 0x0ed8, 0x11ac }, /* Hangul_J_NieunJieuj ᆬ HANGUL JONGSEONG NIEUN-CIEUC */ + { 0x0ed9, 0x11ad }, /* Hangul_J_NieunHieuh ᆭ HANGUL JONGSEONG NIEUN-HIEUH */ + { 0x0eda, 0x11ae }, /* Hangul_J_Dikeud ᆮ HANGUL JONGSEONG TIKEUT */ + { 0x0edb, 0x11af }, /* Hangul_J_Rieul ᆯ HANGUL JONGSEONG RIEUL */ + { 0x0edc, 0x11b0 }, /* Hangul_J_RieulKiyeog ᆰ HANGUL JONGSEONG RIEUL-KIYEOK */ + { 0x0edd, 0x11b1 }, /* Hangul_J_RieulMieum ᆱ HANGUL JONGSEONG RIEUL-MIEUM */ + { 0x0ede, 0x11b2 }, /* Hangul_J_RieulPieub ᆲ HANGUL JONGSEONG RIEUL-PIEUP */ + { 0x0edf, 0x11b3 }, /* Hangul_J_RieulSios ᆳ HANGUL JONGSEONG RIEUL-SIOS */ + { 0x0ee0, 0x11b4 }, /* Hangul_J_RieulTieut ᆴ HANGUL JONGSEONG RIEUL-THIEUTH */ + { 0x0ee1, 0x11b5 }, /* Hangul_J_RieulPhieuf ᆵ HANGUL JONGSEONG RIEUL-PHIEUPH */ + { 0x0ee2, 0x11b6 }, /* Hangul_J_RieulHieuh ᆶ HANGUL JONGSEONG RIEUL-HIEUH */ + { 0x0ee3, 0x11b7 }, /* Hangul_J_Mieum ᆷ HANGUL JONGSEONG MIEUM */ + { 0x0ee4, 0x11b8 }, /* Hangul_J_Pieub ᆸ HANGUL JONGSEONG PIEUP */ + { 0x0ee5, 0x11b9 }, /* Hangul_J_PieubSios ᆹ HANGUL JONGSEONG PIEUP-SIOS */ + { 0x0ee6, 0x11ba }, /* Hangul_J_Sios ᆺ HANGUL JONGSEONG SIOS */ + { 0x0ee7, 0x11bb }, /* Hangul_J_SsangSios ᆻ HANGUL JONGSEONG SSANGSIOS */ + { 0x0ee8, 0x11bc }, /* Hangul_J_Ieung ᆼ HANGUL JONGSEONG IEUNG */ + { 0x0ee9, 0x11bd }, /* Hangul_J_Jieuj ᆽ HANGUL JONGSEONG CIEUC */ + { 0x0eea, 0x11be }, /* Hangul_J_Cieuc ᆾ HANGUL JONGSEONG CHIEUCH */ + { 0x0eeb, 0x11bf }, /* Hangul_J_Khieuq ᆿ HANGUL JONGSEONG KHIEUKH */ + { 0x0eec, 0x11c0 }, /* Hangul_J_Tieut ᇀ HANGUL JONGSEONG THIEUTH */ + { 0x0eed, 0x11c1 }, /* Hangul_J_Phieuf ᇠHANGUL JONGSEONG PHIEUPH */ + { 0x0eee, 0x11c2 }, /* Hangul_J_Hieuh ᇂ HANGUL JONGSEONG HIEUH */ + { 0x0eef, 0x316d }, /* Hangul_RieulYeorinHieuh ã…­ HANGUL LETTER RIEUL-YEORINHIEUH */ + { 0x0ef0, 0x3171 }, /* Hangul_SunkyeongeumMieum ã…± HANGUL LETTER KAPYEOUNMIEUM */ + { 0x0ef1, 0x3178 }, /* Hangul_SunkyeongeumPieub ã…¸ HANGUL LETTER KAPYEOUNPIEUP */ + { 0x0ef2, 0x317f }, /* Hangul_PanSios ã…¿ HANGUL LETTER PANSIOS */ +/* 0x0ef3 Hangul_KkogjiDalrinIeung ? ??? */ + { 0x0ef4, 0x3184 }, /* Hangul_SunkyeongeumPhieuf ㆄ HANGUL LETTER KAPYEOUNPHIEUPH */ + { 0x0ef5, 0x3186 }, /* Hangul_YeorinHieuh ㆆ HANGUL LETTER YEORINHIEUH */ + { 0x0ef6, 0x318d }, /* Hangul_AraeA ㆠHANGUL LETTER ARAEA */ + { 0x0ef7, 0x318e }, /* Hangul_AraeAE ㆎ HANGUL LETTER ARAEAE */ + { 0x0ef8, 0x11eb }, /* Hangul_J_PanSios ᇫ HANGUL JONGSEONG PANSIOS */ +/* 0x0ef9 Hangul_J_KkogjiDalrinIeung ? ??? */ + { 0x0efa, 0x11f9 }, /* Hangul_J_YeorinHieuh ᇹ HANGUL JONGSEONG YEORINHIEUH */ + { 0x0eff, 0x20a9 }, /* Korean_Won â‚© WON SIGN */ + { 0x13bc, 0x0152 }, /* OE Å’ LATIN CAPITAL LIGATURE OE */ + { 0x13bd, 0x0153 }, /* oe Å“ LATIN SMALL LIGATURE OE */ + { 0x13be, 0x0178 }, /* Ydiaeresis Ÿ LATIN CAPITAL LETTER Y WITH DIAERESIS */ + { 0x20a0, 0x20a0 }, /* EcuSign â‚  EURO-CURRENCY SIGN */ + { 0x20a1, 0x20a1 }, /* ColonSign â‚¡ COLON SIGN */ + { 0x20a2, 0x20a2 }, /* CruzeiroSign â‚¢ CRUZEIRO SIGN */ + { 0x20a3, 0x20a3 }, /* FFrancSign â‚£ FRENCH FRANC SIGN */ + { 0x20a4, 0x20a4 }, /* LiraSign ₤ LIRA SIGN */ + { 0x20a5, 0x20a5 }, /* MillSign â‚¥ MILL SIGN */ + { 0x20a6, 0x20a6 }, /* NairaSign ₦ NAIRA SIGN */ + { 0x20a7, 0x20a7 }, /* PesetaSign â‚§ PESETA SIGN */ + { 0x20a8, 0x20a8 }, /* RupeeSign ₨ RUPEE SIGN */ + { 0x20a9, 0x20a9 }, /* WonSign â‚© WON SIGN */ + { 0x20aa, 0x20aa }, /* NewSheqelSign ₪ NEW SHEQEL SIGN */ + { 0x20ab, 0x20ab }, /* DongSign â‚« DONG SIGN */ + { 0x20ac, 0x20ac }, /* EuroSign € EURO SIGN */ + + + /* Following items added to GTK, not in the xterm table */ + + /* Numeric keypad */ + + { 0xFF80 /* Space */, ' ' }, + { 0xFFAA /* Multiply */, '*' }, + { 0xFFAB /* Add */, '+' }, + { 0xFFAC /* Separator */, ',' }, + { 0xFFAD /* Subtract */, '-' }, + { 0xFFAE /* Decimal */, '.' }, + { 0xFFAF /* Divide */, '/' }, + { 0xFFB0 /* 0 */, '0' }, + { 0xFFB1 /* 1 */, '1' }, + { 0xFFB2 /* 2 */, '2' }, + { 0xFFB3 /* 3 */, '3' }, + { 0xFFB4 /* 4 */, '4' }, + { 0xFFB5 /* 5 */, '5' }, + { 0xFFB6 /* 6 */, '6' }, + { 0xFFB7 /* 7 */, '7' }, + { 0xFFB8 /* 8 */, '8' }, + { 0xFFB9 /* 9 */, '9' }, + { 0xFFBD /* Equal */, '=' }, + + /* End numeric keypad */ +}; + +/** + * gdk_keyval_to_unicode: + * @keyval: a GDK key symbol + * + * Convert from a GDK key symbol to the corresponding ISO10646 (Unicode) + * character. + * + * Return value: the corresponding unicode character, or 0 if there + * is no corresponding character. + **/ +guint32 +gdk_keyval_to_unicode (guint keyval) +{ + int min = 0; + int max = G_N_ELEMENTS (gdk_keysym_to_unicode_tab) - 1; + int mid; + + /* First check for Latin-1 characters (1:1 mapping) */ + if ((keyval >= 0x0020 && keyval <= 0x007e) || + (keyval >= 0x00a0 && keyval <= 0x00ff)) + return keyval; + + /* Also check for directly encoded 24-bit UCS characters: + */ + if ((keyval & 0xff000000) == 0x01000000) + return keyval & 0x00ffffff; + +#if defined(GDK_WINDOWING_WIN32) + if (keyval == 0xffae) + { + GdkWin32Keymap *keymap = GDK_WIN32_KEYMAP (gdk_keymap_get_default ()); + + return (guint32) _gdk_win32_keymap_get_decimal_mark (keymap); + } +#endif + + /* binary search in table */ + while (max >= min) { + mid = (min + max) / 2; + if (gdk_keysym_to_unicode_tab[mid].keysym < keyval) + min = mid + 1; + else if (gdk_keysym_to_unicode_tab[mid].keysym > keyval) + max = mid - 1; + else { + /* found it */ + return gdk_keysym_to_unicode_tab[mid].ucs; + } + } + + /* No matching Unicode value found */ + return 0; +} + +static const struct { + unsigned short keysym; + unsigned short ucs; +} gdk_unicode_to_keysym_tab[] = { + { 0x0abd, 0x002e }, /* decimalpoint . FULL STOP */ + { 0x0ba3, 0x003c }, /* leftcaret < LESS-THAN SIGN */ + { 0x0ba6, 0x003e }, /* rightcaret > GREATER-THAN SIGN */ + { 0x0bc6, 0x005f }, /* underbar _ LOW LINE */ + { 0x0bc0, 0x00af }, /* overbar ¯ MACRON */ + { 0x03c0, 0x0100 }, /* Amacron Ä€ LATIN CAPITAL LETTER A WITH MACRON */ + { 0x03e0, 0x0101 }, /* amacron Ä LATIN SMALL LETTER A WITH MACRON */ + { 0x01c3, 0x0102 }, /* Abreve Ä‚ LATIN CAPITAL LETTER A WITH BREVE */ + { 0x01e3, 0x0103 }, /* abreve ă LATIN SMALL LETTER A WITH BREVE */ + { 0x01a1, 0x0104 }, /* Aogonek Ä„ LATIN CAPITAL LETTER A WITH OGONEK */ + { 0x01b1, 0x0105 }, /* aogonek Ä… LATIN SMALL LETTER A WITH OGONEK */ + { 0x01c6, 0x0106 }, /* Cacute Ć LATIN CAPITAL LETTER C WITH ACUTE */ + { 0x01e6, 0x0107 }, /* cacute ć LATIN SMALL LETTER C WITH ACUTE */ + { 0x02c6, 0x0108 }, /* Ccircumflex Ĉ LATIN CAPITAL LETTER C WITH CIRCUMFLEX */ + { 0x02e6, 0x0109 }, /* ccircumflex ĉ LATIN SMALL LETTER C WITH CIRCUMFLEX */ + { 0x02c5, 0x010a }, /* Cabovedot ÄŠ LATIN CAPITAL LETTER C WITH DOT ABOVE */ + { 0x02e5, 0x010b }, /* cabovedot Ä‹ LATIN SMALL LETTER C WITH DOT ABOVE */ + { 0x01c8, 0x010c }, /* Ccaron ÄŒ LATIN CAPITAL LETTER C WITH CARON */ + { 0x01e8, 0x010d }, /* ccaron Ä LATIN SMALL LETTER C WITH CARON */ + { 0x01cf, 0x010e }, /* Dcaron ÄŽ LATIN CAPITAL LETTER D WITH CARON */ + { 0x01ef, 0x010f }, /* dcaron Ä LATIN SMALL LETTER D WITH CARON */ + { 0x01d0, 0x0110 }, /* Dstroke Ä LATIN CAPITAL LETTER D WITH STROKE */ + { 0x01f0, 0x0111 }, /* dstroke Ä‘ LATIN SMALL LETTER D WITH STROKE */ + { 0x03aa, 0x0112 }, /* Emacron Ä’ LATIN CAPITAL LETTER E WITH MACRON */ + { 0x03ba, 0x0113 }, /* emacron Ä“ LATIN SMALL LETTER E WITH MACRON */ + { 0x03cc, 0x0116 }, /* Eabovedot Ä– LATIN CAPITAL LETTER E WITH DOT ABOVE */ + { 0x03ec, 0x0117 }, /* eabovedot Ä— LATIN SMALL LETTER E WITH DOT ABOVE */ + { 0x01ca, 0x0118 }, /* Eogonek Ę LATIN CAPITAL LETTER E WITH OGONEK */ + { 0x01ea, 0x0119 }, /* eogonek Ä™ LATIN SMALL LETTER E WITH OGONEK */ + { 0x01cc, 0x011a }, /* Ecaron Äš LATIN CAPITAL LETTER E WITH CARON */ + { 0x01ec, 0x011b }, /* ecaron Ä› LATIN SMALL LETTER E WITH CARON */ + { 0x02d8, 0x011c }, /* Gcircumflex Äœ LATIN CAPITAL LETTER G WITH CIRCUMFLEX */ + { 0x02f8, 0x011d }, /* gcircumflex Ä LATIN SMALL LETTER G WITH CIRCUMFLEX */ + { 0x02ab, 0x011e }, /* Gbreve Äž LATIN CAPITAL LETTER G WITH BREVE */ + { 0x02bb, 0x011f }, /* gbreve ÄŸ LATIN SMALL LETTER G WITH BREVE */ + { 0x02d5, 0x0120 }, /* Gabovedot Ä  LATIN CAPITAL LETTER G WITH DOT ABOVE */ + { 0x02f5, 0x0121 }, /* gabovedot Ä¡ LATIN SMALL LETTER G WITH DOT ABOVE */ + { 0x03ab, 0x0122 }, /* Gcedilla Ä¢ LATIN CAPITAL LETTER G WITH CEDILLA */ + { 0x03bb, 0x0123 }, /* gcedilla Ä£ LATIN SMALL LETTER G WITH CEDILLA */ + { 0x02a6, 0x0124 }, /* Hcircumflex Ĥ LATIN CAPITAL LETTER H WITH CIRCUMFLEX */ + { 0x02b6, 0x0125 }, /* hcircumflex Ä¥ LATIN SMALL LETTER H WITH CIRCUMFLEX */ + { 0x02a1, 0x0126 }, /* Hstroke Ħ LATIN CAPITAL LETTER H WITH STROKE */ + { 0x02b1, 0x0127 }, /* hstroke ħ LATIN SMALL LETTER H WITH STROKE */ + { 0x03a5, 0x0128 }, /* Itilde Ĩ LATIN CAPITAL LETTER I WITH TILDE */ + { 0x03b5, 0x0129 }, /* itilde Ä© LATIN SMALL LETTER I WITH TILDE */ + { 0x03cf, 0x012a }, /* Imacron Ī LATIN CAPITAL LETTER I WITH MACRON */ + { 0x03ef, 0x012b }, /* imacron Ä« LATIN SMALL LETTER I WITH MACRON */ + { 0x03c7, 0x012e }, /* Iogonek Ä® LATIN CAPITAL LETTER I WITH OGONEK */ + { 0x03e7, 0x012f }, /* iogonek į LATIN SMALL LETTER I WITH OGONEK */ + { 0x02a9, 0x0130 }, /* Iabovedot İ LATIN CAPITAL LETTER I WITH DOT ABOVE */ + { 0x02b9, 0x0131 }, /* idotless ı LATIN SMALL LETTER DOTLESS I */ + { 0x02ac, 0x0134 }, /* Jcircumflex Ä´ LATIN CAPITAL LETTER J WITH CIRCUMFLEX */ + { 0x02bc, 0x0135 }, /* jcircumflex ĵ LATIN SMALL LETTER J WITH CIRCUMFLEX */ + { 0x03d3, 0x0136 }, /* Kcedilla Ķ LATIN CAPITAL LETTER K WITH CEDILLA */ + { 0x03f3, 0x0137 }, /* kcedilla Ä· LATIN SMALL LETTER K WITH CEDILLA */ + { 0x03a2, 0x0138 }, /* kra ĸ LATIN SMALL LETTER KRA */ + { 0x01c5, 0x0139 }, /* Lacute Ĺ LATIN CAPITAL LETTER L WITH ACUTE */ + { 0x01e5, 0x013a }, /* lacute ĺ LATIN SMALL LETTER L WITH ACUTE */ + { 0x03a6, 0x013b }, /* Lcedilla Ä» LATIN CAPITAL LETTER L WITH CEDILLA */ + { 0x03b6, 0x013c }, /* lcedilla ļ LATIN SMALL LETTER L WITH CEDILLA */ + { 0x01a5, 0x013d }, /* Lcaron Ľ LATIN CAPITAL LETTER L WITH CARON */ + { 0x01b5, 0x013e }, /* lcaron ľ LATIN SMALL LETTER L WITH CARON */ + { 0x01a3, 0x0141 }, /* Lstroke Å LATIN CAPITAL LETTER L WITH STROKE */ + { 0x01b3, 0x0142 }, /* lstroke Å‚ LATIN SMALL LETTER L WITH STROKE */ + { 0x01d1, 0x0143 }, /* Nacute Ń LATIN CAPITAL LETTER N WITH ACUTE */ + { 0x01f1, 0x0144 }, /* nacute Å„ LATIN SMALL LETTER N WITH ACUTE */ + { 0x03d1, 0x0145 }, /* Ncedilla Å… LATIN CAPITAL LETTER N WITH CEDILLA */ + { 0x03f1, 0x0146 }, /* ncedilla ņ LATIN SMALL LETTER N WITH CEDILLA */ + { 0x01d2, 0x0147 }, /* Ncaron Ň LATIN CAPITAL LETTER N WITH CARON */ + { 0x01f2, 0x0148 }, /* ncaron ň LATIN SMALL LETTER N WITH CARON */ + { 0x03bd, 0x014a }, /* ENG ÅŠ LATIN CAPITAL LETTER ENG */ + { 0x03bf, 0x014b }, /* eng Å‹ LATIN SMALL LETTER ENG */ + { 0x03d2, 0x014c }, /* Omacron ÅŒ LATIN CAPITAL LETTER O WITH MACRON */ + { 0x03f2, 0x014d }, /* omacron Å LATIN SMALL LETTER O WITH MACRON */ + { 0x01d5, 0x0150 }, /* Odoubleacute Å LATIN CAPITAL LETTER O WITH DOUBLE ACUTE */ + { 0x01f5, 0x0151 }, /* odoubleacute Å‘ LATIN SMALL LETTER O WITH DOUBLE ACUTE */ + { 0x13bc, 0x0152 }, /* OE Å’ LATIN CAPITAL LIGATURE OE */ + { 0x13bd, 0x0153 }, /* oe Å“ LATIN SMALL LIGATURE OE */ + { 0x01c0, 0x0154 }, /* Racute Å” LATIN CAPITAL LETTER R WITH ACUTE */ + { 0x01e0, 0x0155 }, /* racute Å• LATIN SMALL LETTER R WITH ACUTE */ + { 0x03a3, 0x0156 }, /* Rcedilla Å– LATIN CAPITAL LETTER R WITH CEDILLA */ + { 0x03b3, 0x0157 }, /* rcedilla Å— LATIN SMALL LETTER R WITH CEDILLA */ + { 0x01d8, 0x0158 }, /* Rcaron Ř LATIN CAPITAL LETTER R WITH CARON */ + { 0x01f8, 0x0159 }, /* rcaron Å™ LATIN SMALL LETTER R WITH CARON */ + { 0x01a6, 0x015a }, /* Sacute Åš LATIN CAPITAL LETTER S WITH ACUTE */ + { 0x01b6, 0x015b }, /* sacute Å› LATIN SMALL LETTER S WITH ACUTE */ + { 0x02de, 0x015c }, /* Scircumflex Åœ LATIN CAPITAL LETTER S WITH CIRCUMFLEX */ + { 0x02fe, 0x015d }, /* scircumflex Å LATIN SMALL LETTER S WITH CIRCUMFLEX */ + { 0x01aa, 0x015e }, /* Scedilla Åž LATIN CAPITAL LETTER S WITH CEDILLA */ + { 0x01ba, 0x015f }, /* scedilla ÅŸ LATIN SMALL LETTER S WITH CEDILLA */ + { 0x01a9, 0x0160 }, /* Scaron Å  LATIN CAPITAL LETTER S WITH CARON */ + { 0x01b9, 0x0161 }, /* scaron Å¡ LATIN SMALL LETTER S WITH CARON */ + { 0x01de, 0x0162 }, /* Tcedilla Å¢ LATIN CAPITAL LETTER T WITH CEDILLA */ + { 0x01fe, 0x0163 }, /* tcedilla Å£ LATIN SMALL LETTER T WITH CEDILLA */ + { 0x01ab, 0x0164 }, /* Tcaron Ť LATIN CAPITAL LETTER T WITH CARON */ + { 0x01bb, 0x0165 }, /* tcaron Å¥ LATIN SMALL LETTER T WITH CARON */ + { 0x03ac, 0x0166 }, /* Tslash Ŧ LATIN CAPITAL LETTER T WITH STROKE */ + { 0x03bc, 0x0167 }, /* tslash ŧ LATIN SMALL LETTER T WITH STROKE */ + { 0x03dd, 0x0168 }, /* Utilde Ũ LATIN CAPITAL LETTER U WITH TILDE */ + { 0x03fd, 0x0169 }, /* utilde Å© LATIN SMALL LETTER U WITH TILDE */ + { 0x03de, 0x016a }, /* Umacron Ū LATIN CAPITAL LETTER U WITH MACRON */ + { 0x03fe, 0x016b }, /* umacron Å« LATIN SMALL LETTER U WITH MACRON */ + { 0x02dd, 0x016c }, /* Ubreve Ŭ LATIN CAPITAL LETTER U WITH BREVE */ + { 0x02fd, 0x016d }, /* ubreve Å­ LATIN SMALL LETTER U WITH BREVE */ + { 0x01d9, 0x016e }, /* Uring Å® LATIN CAPITAL LETTER U WITH RING ABOVE */ + { 0x01f9, 0x016f }, /* uring ů LATIN SMALL LETTER U WITH RING ABOVE */ + { 0x01db, 0x0170 }, /* Udoubleacute Ű LATIN CAPITAL LETTER U WITH DOUBLE ACUTE */ + { 0x01fb, 0x0171 }, /* udoubleacute ű LATIN SMALL LETTER U WITH DOUBLE ACUTE */ + { 0x03d9, 0x0172 }, /* Uogonek Ų LATIN CAPITAL LETTER U WITH OGONEK */ + { 0x03f9, 0x0173 }, /* uogonek ų LATIN SMALL LETTER U WITH OGONEK */ + { 0x13be, 0x0178 }, /* Ydiaeresis Ÿ LATIN CAPITAL LETTER Y WITH DIAERESIS */ + { 0x01ac, 0x0179 }, /* Zacute Ź LATIN CAPITAL LETTER Z WITH ACUTE */ + { 0x01bc, 0x017a }, /* zacute ź LATIN SMALL LETTER Z WITH ACUTE */ + { 0x01af, 0x017b }, /* Zabovedot Å» LATIN CAPITAL LETTER Z WITH DOT ABOVE */ + { 0x01bf, 0x017c }, /* zabovedot ż LATIN SMALL LETTER Z WITH DOT ABOVE */ + { 0x01ae, 0x017d }, /* Zcaron Ž LATIN CAPITAL LETTER Z WITH CARON */ + { 0x01be, 0x017e }, /* zcaron ž LATIN SMALL LETTER Z WITH CARON */ + { 0x08f6, 0x0192 }, /* function Æ’ LATIN SMALL LETTER F WITH HOOK */ + { 0x01b7, 0x02c7 }, /* caron ˇ CARON */ + { 0x01a2, 0x02d8 }, /* breve ˘ BREVE */ + { 0x01ff, 0x02d9 }, /* abovedot Ë™ DOT ABOVE */ + { 0x01b2, 0x02db }, /* ogonek Ë› OGONEK */ + { 0x01bd, 0x02dd }, /* doubleacute Ë DOUBLE ACUTE ACCENT */ + { 0x07ae, 0x0385 }, /* Greek_accentdieresis Î… GREEK DIALYTIKA TONOS */ + { 0x07a1, 0x0386 }, /* Greek_ALPHAaccent Ά GREEK CAPITAL LETTER ALPHA WITH TONOS */ + { 0x07a2, 0x0388 }, /* Greek_EPSILONaccent Έ GREEK CAPITAL LETTER EPSILON WITH TONOS */ + { 0x07a3, 0x0389 }, /* Greek_ETAaccent Ή GREEK CAPITAL LETTER ETA WITH TONOS */ + { 0x07a4, 0x038a }, /* Greek_IOTAaccent Ί GREEK CAPITAL LETTER IOTA WITH TONOS */ + { 0x07a7, 0x038c }, /* Greek_OMICRONaccent ÎŒ GREEK CAPITAL LETTER OMICRON WITH TONOS */ + { 0x07a8, 0x038e }, /* Greek_UPSILONaccent ÎŽ GREEK CAPITAL LETTER UPSILON WITH TONOS */ + { 0x07ab, 0x038f }, /* Greek_OMEGAaccent Î GREEK CAPITAL LETTER OMEGA WITH TONOS */ + { 0x07b6, 0x0390 }, /* Greek_iotaaccentdieresis Î GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS */ + { 0x07c1, 0x0391 }, /* Greek_ALPHA Α GREEK CAPITAL LETTER ALPHA */ + { 0x07c2, 0x0392 }, /* Greek_BETA Î’ GREEK CAPITAL LETTER BETA */ + { 0x07c3, 0x0393 }, /* Greek_GAMMA Γ GREEK CAPITAL LETTER GAMMA */ + { 0x07c4, 0x0394 }, /* Greek_DELTA Δ GREEK CAPITAL LETTER DELTA */ + { 0x07c5, 0x0395 }, /* Greek_EPSILON Ε GREEK CAPITAL LETTER EPSILON */ + { 0x07c6, 0x0396 }, /* Greek_ZETA Ζ GREEK CAPITAL LETTER ZETA */ + { 0x07c7, 0x0397 }, /* Greek_ETA Η GREEK CAPITAL LETTER ETA */ + { 0x07c8, 0x0398 }, /* Greek_THETA Θ GREEK CAPITAL LETTER THETA */ + { 0x07c9, 0x0399 }, /* Greek_IOTA Ι GREEK CAPITAL LETTER IOTA */ + { 0x07ca, 0x039a }, /* Greek_KAPPA Κ GREEK CAPITAL LETTER KAPPA */ + { 0x07cb, 0x039b }, /* Greek_LAMBDA Λ GREEK CAPITAL LETTER LAMDA */ + { 0x07cc, 0x039c }, /* Greek_MU Μ GREEK CAPITAL LETTER MU */ + { 0x07cd, 0x039d }, /* Greek_NU Î GREEK CAPITAL LETTER NU */ + { 0x07ce, 0x039e }, /* Greek_XI Ξ GREEK CAPITAL LETTER XI */ + { 0x07cf, 0x039f }, /* Greek_OMICRON Ο GREEK CAPITAL LETTER OMICRON */ + { 0x07d0, 0x03a0 }, /* Greek_PI Π GREEK CAPITAL LETTER PI */ + { 0x07d1, 0x03a1 }, /* Greek_RHO Ρ GREEK CAPITAL LETTER RHO */ + { 0x07d2, 0x03a3 }, /* Greek_SIGMA Σ GREEK CAPITAL LETTER SIGMA */ + { 0x07d4, 0x03a4 }, /* Greek_TAU Τ GREEK CAPITAL LETTER TAU */ + { 0x07d5, 0x03a5 }, /* Greek_UPSILON Î¥ GREEK CAPITAL LETTER UPSILON */ + { 0x07d6, 0x03a6 }, /* Greek_PHI Φ GREEK CAPITAL LETTER PHI */ + { 0x07d7, 0x03a7 }, /* Greek_CHI Χ GREEK CAPITAL LETTER CHI */ + { 0x07d8, 0x03a8 }, /* Greek_PSI Ψ GREEK CAPITAL LETTER PSI */ + { 0x07d9, 0x03a9 }, /* Greek_OMEGA Ω GREEK CAPITAL LETTER OMEGA */ + { 0x07a5, 0x03aa }, /* Greek_IOTAdieresis Ϊ GREEK CAPITAL LETTER IOTA WITH DIALYTIKA */ + { 0x07a9, 0x03ab }, /* Greek_UPSILONdieresis Ϋ GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA */ + { 0x07b1, 0x03ac }, /* Greek_alphaaccent ά GREEK SMALL LETTER ALPHA WITH TONOS */ + { 0x07b2, 0x03ad }, /* Greek_epsilonaccent έ GREEK SMALL LETTER EPSILON WITH TONOS */ + { 0x07b3, 0x03ae }, /* Greek_etaaccent ή GREEK SMALL LETTER ETA WITH TONOS */ + { 0x07b4, 0x03af }, /* Greek_iotaaccent ί GREEK SMALL LETTER IOTA WITH TONOS */ + { 0x07ba, 0x03b0 }, /* Greek_upsilonaccentdieresis ΰ GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS */ + { 0x07e1, 0x03b1 }, /* Greek_alpha α GREEK SMALL LETTER ALPHA */ + { 0x07e2, 0x03b2 }, /* Greek_beta β GREEK SMALL LETTER BETA */ + { 0x07e3, 0x03b3 }, /* Greek_gamma γ GREEK SMALL LETTER GAMMA */ + { 0x07e4, 0x03b4 }, /* Greek_delta δ GREEK SMALL LETTER DELTA */ + { 0x07e5, 0x03b5 }, /* Greek_epsilon ε GREEK SMALL LETTER EPSILON */ + { 0x07e6, 0x03b6 }, /* Greek_zeta ζ GREEK SMALL LETTER ZETA */ + { 0x07e7, 0x03b7 }, /* Greek_eta η GREEK SMALL LETTER ETA */ + { 0x07e8, 0x03b8 }, /* Greek_theta θ GREEK SMALL LETTER THETA */ + { 0x07e9, 0x03b9 }, /* Greek_iota ι GREEK SMALL LETTER IOTA */ + { 0x07ea, 0x03ba }, /* Greek_kappa κ GREEK SMALL LETTER KAPPA */ + { 0x07eb, 0x03bb }, /* Greek_lambda λ GREEK SMALL LETTER LAMDA */ + { 0x07ec, 0x03bc }, /* Greek_mu μ GREEK SMALL LETTER MU */ + { 0x07ed, 0x03bd }, /* Greek_nu ν GREEK SMALL LETTER NU */ + { 0x07ee, 0x03be }, /* Greek_xi ξ GREEK SMALL LETTER XI */ + { 0x07ef, 0x03bf }, /* Greek_omicron ο GREEK SMALL LETTER OMICRON */ + { 0x07f0, 0x03c0 }, /* Greek_pi Ï€ GREEK SMALL LETTER PI */ + { 0x07f1, 0x03c1 }, /* Greek_rho Ï GREEK SMALL LETTER RHO */ + { 0x07f3, 0x03c2 }, /* Greek_finalsmallsigma Ï‚ GREEK SMALL LETTER FINAL SIGMA */ + { 0x07f2, 0x03c3 }, /* Greek_sigma σ GREEK SMALL LETTER SIGMA */ + { 0x07f4, 0x03c4 }, /* Greek_tau Ï„ GREEK SMALL LETTER TAU */ + { 0x07f5, 0x03c5 }, /* Greek_upsilon Ï… GREEK SMALL LETTER UPSILON */ + { 0x07f6, 0x03c6 }, /* Greek_phi φ GREEK SMALL LETTER PHI */ + { 0x07f7, 0x03c7 }, /* Greek_chi χ GREEK SMALL LETTER CHI */ + { 0x07f8, 0x03c8 }, /* Greek_psi ψ GREEK SMALL LETTER PSI */ + { 0x07f9, 0x03c9 }, /* Greek_omega ω GREEK SMALL LETTER OMEGA */ + { 0x07b5, 0x03ca }, /* Greek_iotadieresis ÏŠ GREEK SMALL LETTER IOTA WITH DIALYTIKA */ + { 0x07b9, 0x03cb }, /* Greek_upsilondieresis Ï‹ GREEK SMALL LETTER UPSILON WITH DIALYTIKA */ + { 0x07b7, 0x03cc }, /* Greek_omicronaccent ÏŒ GREEK SMALL LETTER OMICRON WITH TONOS */ + { 0x07b8, 0x03cd }, /* Greek_upsilonaccent Ï GREEK SMALL LETTER UPSILON WITH TONOS */ + { 0x07bb, 0x03ce }, /* Greek_omegaaccent ÏŽ GREEK SMALL LETTER OMEGA WITH TONOS */ + { 0x06b3, 0x0401 }, /* Cyrillic_IO Ð CYRILLIC CAPITAL LETTER IO */ + { 0x06b1, 0x0402 }, /* Serbian_DJE Ђ CYRILLIC CAPITAL LETTER DJE */ + { 0x06b2, 0x0403 }, /* Macedonia_GJE Ѓ CYRILLIC CAPITAL LETTER GJE */ + { 0x06b4, 0x0404 }, /* Ukrainian_IE Є CYRILLIC CAPITAL LETTER UKRAINIAN IE */ + { 0x06b5, 0x0405 }, /* Macedonia_DSE Ð… CYRILLIC CAPITAL LETTER DZE */ + { 0x06b6, 0x0406 }, /* Ukrainian_I І CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I */ + { 0x06b7, 0x0407 }, /* Ukrainian_YI Ї CYRILLIC CAPITAL LETTER YI */ + { 0x06b8, 0x0408 }, /* Cyrillic_JE Ј CYRILLIC CAPITAL LETTER JE */ + { 0x06b9, 0x0409 }, /* Cyrillic_LJE Љ CYRILLIC CAPITAL LETTER LJE */ + { 0x06ba, 0x040a }, /* Cyrillic_NJE Њ CYRILLIC CAPITAL LETTER NJE */ + { 0x06bb, 0x040b }, /* Serbian_TSHE Ћ CYRILLIC CAPITAL LETTER TSHE */ + { 0x06bc, 0x040c }, /* Macedonia_KJE ÐŒ CYRILLIC CAPITAL LETTER KJE */ + { 0x06be, 0x040e }, /* Byelorussian_SHORTU ÐŽ CYRILLIC CAPITAL LETTER SHORT U */ + { 0x06bf, 0x040f }, /* Cyrillic_DZHE Ð CYRILLIC CAPITAL LETTER DZHE */ + { 0x06e1, 0x0410 }, /* Cyrillic_A Ð CYRILLIC CAPITAL LETTER A */ + { 0x06e2, 0x0411 }, /* Cyrillic_BE Б CYRILLIC CAPITAL LETTER BE */ + { 0x06f7, 0x0412 }, /* Cyrillic_VE Ð’ CYRILLIC CAPITAL LETTER VE */ + { 0x06e7, 0x0413 }, /* Cyrillic_GHE Г CYRILLIC CAPITAL LETTER GHE */ + { 0x06e4, 0x0414 }, /* Cyrillic_DE Д CYRILLIC CAPITAL LETTER DE */ + { 0x06e5, 0x0415 }, /* Cyrillic_IE Е CYRILLIC CAPITAL LETTER IE */ + { 0x06f6, 0x0416 }, /* Cyrillic_ZHE Ж CYRILLIC CAPITAL LETTER ZHE */ + { 0x06fa, 0x0417 }, /* Cyrillic_ZE З CYRILLIC CAPITAL LETTER ZE */ + { 0x06e9, 0x0418 }, /* Cyrillic_I И CYRILLIC CAPITAL LETTER I */ + { 0x06ea, 0x0419 }, /* Cyrillic_SHORTI Й CYRILLIC CAPITAL LETTER SHORT I */ + { 0x06eb, 0x041a }, /* Cyrillic_KA К CYRILLIC CAPITAL LETTER KA */ + { 0x06ec, 0x041b }, /* Cyrillic_EL Л CYRILLIC CAPITAL LETTER EL */ + { 0x06ed, 0x041c }, /* Cyrillic_EM М CYRILLIC CAPITAL LETTER EM */ + { 0x06ee, 0x041d }, /* Cyrillic_EN Ð CYRILLIC CAPITAL LETTER EN */ + { 0x06ef, 0x041e }, /* Cyrillic_O О CYRILLIC CAPITAL LETTER O */ + { 0x06f0, 0x041f }, /* Cyrillic_PE П CYRILLIC CAPITAL LETTER PE */ + { 0x06f2, 0x0420 }, /* Cyrillic_ER Р CYRILLIC CAPITAL LETTER ER */ + { 0x06f3, 0x0421 }, /* Cyrillic_ES С CYRILLIC CAPITAL LETTER ES */ + { 0x06f4, 0x0422 }, /* Cyrillic_TE Т CYRILLIC CAPITAL LETTER TE */ + { 0x06f5, 0x0423 }, /* Cyrillic_U У CYRILLIC CAPITAL LETTER U */ + { 0x06e6, 0x0424 }, /* Cyrillic_EF Ф CYRILLIC CAPITAL LETTER EF */ + { 0x06e8, 0x0425 }, /* Cyrillic_HA Ð¥ CYRILLIC CAPITAL LETTER HA */ + { 0x06e3, 0x0426 }, /* Cyrillic_TSE Ц CYRILLIC CAPITAL LETTER TSE */ + { 0x06fe, 0x0427 }, /* Cyrillic_CHE Ч CYRILLIC CAPITAL LETTER CHE */ + { 0x06fb, 0x0428 }, /* Cyrillic_SHA Ш CYRILLIC CAPITAL LETTER SHA */ + { 0x06fd, 0x0429 }, /* Cyrillic_SHCHA Щ CYRILLIC CAPITAL LETTER SHCHA */ + { 0x06ff, 0x042a }, /* Cyrillic_HARDSIGN Ъ CYRILLIC CAPITAL LETTER HARD SIGN */ + { 0x06f9, 0x042b }, /* Cyrillic_YERU Ы CYRILLIC CAPITAL LETTER YERU */ + { 0x06f8, 0x042c }, /* Cyrillic_SOFTSIGN Ь CYRILLIC CAPITAL LETTER SOFT SIGN */ + { 0x06fc, 0x042d }, /* Cyrillic_E Э CYRILLIC CAPITAL LETTER E */ + { 0x06e0, 0x042e }, /* Cyrillic_YU Ю CYRILLIC CAPITAL LETTER YU */ + { 0x06f1, 0x042f }, /* Cyrillic_YA Я CYRILLIC CAPITAL LETTER YA */ + { 0x06c1, 0x0430 }, /* Cyrillic_a а CYRILLIC SMALL LETTER A */ + { 0x06c2, 0x0431 }, /* Cyrillic_be б CYRILLIC SMALL LETTER BE */ + { 0x06d7, 0x0432 }, /* Cyrillic_ve в CYRILLIC SMALL LETTER VE */ + { 0x06c7, 0x0433 }, /* Cyrillic_ghe г CYRILLIC SMALL LETTER GHE */ + { 0x06c4, 0x0434 }, /* Cyrillic_de д CYRILLIC SMALL LETTER DE */ + { 0x06c5, 0x0435 }, /* Cyrillic_ie е CYRILLIC SMALL LETTER IE */ + { 0x06d6, 0x0436 }, /* Cyrillic_zhe ж CYRILLIC SMALL LETTER ZHE */ + { 0x06da, 0x0437 }, /* Cyrillic_ze з CYRILLIC SMALL LETTER ZE */ + { 0x06c9, 0x0438 }, /* Cyrillic_i и CYRILLIC SMALL LETTER I */ + { 0x06ca, 0x0439 }, /* Cyrillic_shorti й CYRILLIC SMALL LETTER SHORT I */ + { 0x06cb, 0x043a }, /* Cyrillic_ka к CYRILLIC SMALL LETTER KA */ + { 0x06cc, 0x043b }, /* Cyrillic_el л CYRILLIC SMALL LETTER EL */ + { 0x06cd, 0x043c }, /* Cyrillic_em м CYRILLIC SMALL LETTER EM */ + { 0x06ce, 0x043d }, /* Cyrillic_en н CYRILLIC SMALL LETTER EN */ + { 0x06cf, 0x043e }, /* Cyrillic_o о CYRILLIC SMALL LETTER O */ + { 0x06d0, 0x043f }, /* Cyrillic_pe п CYRILLIC SMALL LETTER PE */ + { 0x06d2, 0x0440 }, /* Cyrillic_er Ñ€ CYRILLIC SMALL LETTER ER */ + { 0x06d3, 0x0441 }, /* Cyrillic_es Ñ CYRILLIC SMALL LETTER ES */ + { 0x06d4, 0x0442 }, /* Cyrillic_te Ñ‚ CYRILLIC SMALL LETTER TE */ + { 0x06d5, 0x0443 }, /* Cyrillic_u у CYRILLIC SMALL LETTER U */ + { 0x06c6, 0x0444 }, /* Cyrillic_ef Ñ„ CYRILLIC SMALL LETTER EF */ + { 0x06c8, 0x0445 }, /* Cyrillic_ha Ñ… CYRILLIC SMALL LETTER HA */ + { 0x06c3, 0x0446 }, /* Cyrillic_tse ц CYRILLIC SMALL LETTER TSE */ + { 0x06de, 0x0447 }, /* Cyrillic_che ч CYRILLIC SMALL LETTER CHE */ + { 0x06db, 0x0448 }, /* Cyrillic_sha ш CYRILLIC SMALL LETTER SHA */ + { 0x06dd, 0x0449 }, /* Cyrillic_shcha щ CYRILLIC SMALL LETTER SHCHA */ + { 0x06df, 0x044a }, /* Cyrillic_hardsign ÑŠ CYRILLIC SMALL LETTER HARD SIGN */ + { 0x06d9, 0x044b }, /* Cyrillic_yeru Ñ‹ CYRILLIC SMALL LETTER YERU */ + { 0x06d8, 0x044c }, /* Cyrillic_softsign ÑŒ CYRILLIC SMALL LETTER SOFT SIGN */ + { 0x06dc, 0x044d }, /* Cyrillic_e Ñ CYRILLIC SMALL LETTER E */ + { 0x06c0, 0x044e }, /* Cyrillic_yu ÑŽ CYRILLIC SMALL LETTER YU */ + { 0x06d1, 0x044f }, /* Cyrillic_ya Ñ CYRILLIC SMALL LETTER YA */ + { 0x06a3, 0x0451 }, /* Cyrillic_io Ñ‘ CYRILLIC SMALL LETTER IO */ + { 0x06a1, 0x0452 }, /* Serbian_dje Ñ’ CYRILLIC SMALL LETTER DJE */ + { 0x06a2, 0x0453 }, /* Macedonia_gje Ñ“ CYRILLIC SMALL LETTER GJE */ + { 0x06a4, 0x0454 }, /* Ukrainian_ie Ñ” CYRILLIC SMALL LETTER UKRAINIAN IE */ + { 0x06a5, 0x0455 }, /* Macedonia_dse Ñ• CYRILLIC SMALL LETTER DZE */ + { 0x06a6, 0x0456 }, /* Ukrainian_i Ñ– CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I */ + { 0x06a7, 0x0457 }, /* Ukrainian_yi Ñ— CYRILLIC SMALL LETTER YI */ + { 0x06a8, 0x0458 }, /* Cyrillic_je ј CYRILLIC SMALL LETTER JE */ + { 0x06a9, 0x0459 }, /* Cyrillic_lje Ñ™ CYRILLIC SMALL LETTER LJE */ + { 0x06aa, 0x045a }, /* Cyrillic_nje Ñš CYRILLIC SMALL LETTER NJE */ + { 0x06ab, 0x045b }, /* Serbian_tshe Ñ› CYRILLIC SMALL LETTER TSHE */ + { 0x06ac, 0x045c }, /* Macedonia_kje Ñœ CYRILLIC SMALL LETTER KJE */ + { 0x06ae, 0x045e }, /* Byelorussian_shortu Ñž CYRILLIC SMALL LETTER SHORT U */ + { 0x06af, 0x045f }, /* Cyrillic_dzhe ÑŸ CYRILLIC SMALL LETTER DZHE */ + { 0x0ce0, 0x05d0 }, /* hebrew_aleph × HEBREW LETTER ALEF */ + { 0x0ce1, 0x05d1 }, /* hebrew_bet ב HEBREW LETTER BET */ + { 0x0ce2, 0x05d2 }, /* hebrew_gimel ×’ HEBREW LETTER GIMEL */ + { 0x0ce3, 0x05d3 }, /* hebrew_dalet ד HEBREW LETTER DALET */ + { 0x0ce4, 0x05d4 }, /* hebrew_he ×” HEBREW LETTER HE */ + { 0x0ce5, 0x05d5 }, /* hebrew_waw ו HEBREW LETTER VAV */ + { 0x0ce6, 0x05d6 }, /* hebrew_zain ×– HEBREW LETTER ZAYIN */ + { 0x0ce7, 0x05d7 }, /* hebrew_chet ×— HEBREW LETTER HET */ + { 0x0ce8, 0x05d8 }, /* hebrew_tet ט HEBREW LETTER TET */ + { 0x0ce9, 0x05d9 }, /* hebrew_yod ×™ HEBREW LETTER YOD */ + { 0x0cea, 0x05da }, /* hebrew_finalkaph ך HEBREW LETTER FINAL KAF */ + { 0x0ceb, 0x05db }, /* hebrew_kaph ×› HEBREW LETTER KAF */ + { 0x0cec, 0x05dc }, /* hebrew_lamed ל HEBREW LETTER LAMED */ + { 0x0ced, 0x05dd }, /* hebrew_finalmem × HEBREW LETTER FINAL MEM */ + { 0x0cee, 0x05de }, /* hebrew_mem מ HEBREW LETTER MEM */ + { 0x0cef, 0x05df }, /* hebrew_finalnun ן HEBREW LETTER FINAL NUN */ + { 0x0cf0, 0x05e0 }, /* hebrew_nun ×  HEBREW LETTER NUN */ + { 0x0cf1, 0x05e1 }, /* hebrew_samech ס HEBREW LETTER SAMEKH */ + { 0x0cf2, 0x05e2 }, /* hebrew_ayin ×¢ HEBREW LETTER AYIN */ + { 0x0cf3, 0x05e3 }, /* hebrew_finalpe ×£ HEBREW LETTER FINAL PE */ + { 0x0cf4, 0x05e4 }, /* hebrew_pe פ HEBREW LETTER PE */ + { 0x0cf5, 0x05e5 }, /* hebrew_finalzade ×¥ HEBREW LETTER FINAL TSADI */ + { 0x0cf6, 0x05e6 }, /* hebrew_zade צ HEBREW LETTER TSADI */ + { 0x0cf7, 0x05e7 }, /* hebrew_qoph ×§ HEBREW LETTER QOF */ + { 0x0cf8, 0x05e8 }, /* hebrew_resh ר HEBREW LETTER RESH */ + { 0x0cf9, 0x05e9 }, /* hebrew_shin ש HEBREW LETTER SHIN */ + { 0x0cfa, 0x05ea }, /* hebrew_taw ת HEBREW LETTER TAV */ + { 0x05ac, 0x060c }, /* Arabic_comma ØŒ ARABIC COMMA */ + { 0x05bb, 0x061b }, /* Arabic_semicolon Ø› ARABIC SEMICOLON */ + { 0x05bf, 0x061f }, /* Arabic_question_mark ØŸ ARABIC QUESTION MARK */ + { 0x05c1, 0x0621 }, /* Arabic_hamza Ø¡ ARABIC LETTER HAMZA */ + { 0x05c2, 0x0622 }, /* Arabic_maddaonalef Ø¢ ARABIC LETTER ALEF WITH MADDA ABOVE */ + { 0x05c3, 0x0623 }, /* Arabic_hamzaonalef Ø£ ARABIC LETTER ALEF WITH HAMZA ABOVE */ + { 0x05c4, 0x0624 }, /* Arabic_hamzaonwaw ؤ ARABIC LETTER WAW WITH HAMZA ABOVE */ + { 0x05c5, 0x0625 }, /* Arabic_hamzaunderalef Ø¥ ARABIC LETTER ALEF WITH HAMZA BELOW */ + { 0x05c6, 0x0626 }, /* Arabic_hamzaonyeh ئ ARABIC LETTER YEH WITH HAMZA ABOVE */ + { 0x05c7, 0x0627 }, /* Arabic_alef ا ARABIC LETTER ALEF */ + { 0x05c8, 0x0628 }, /* Arabic_beh ب ARABIC LETTER BEH */ + { 0x05c9, 0x0629 }, /* Arabic_tehmarbuta Ø© ARABIC LETTER TEH MARBUTA */ + { 0x05ca, 0x062a }, /* Arabic_teh ت ARABIC LETTER TEH */ + { 0x05cb, 0x062b }, /* Arabic_theh Ø« ARABIC LETTER THEH */ + { 0x05cc, 0x062c }, /* Arabic_jeem ج ARABIC LETTER JEEM */ + { 0x05cd, 0x062d }, /* Arabic_hah Ø­ ARABIC LETTER HAH */ + { 0x05ce, 0x062e }, /* Arabic_khah Ø® ARABIC LETTER KHAH */ + { 0x05cf, 0x062f }, /* Arabic_dal د ARABIC LETTER DAL */ + { 0x05d0, 0x0630 }, /* Arabic_thal ذ ARABIC LETTER THAL */ + { 0x05d1, 0x0631 }, /* Arabic_ra ر ARABIC LETTER REH */ + { 0x05d2, 0x0632 }, /* Arabic_zain ز ARABIC LETTER ZAIN */ + { 0x05d3, 0x0633 }, /* Arabic_seen س ARABIC LETTER SEEN */ + { 0x05d4, 0x0634 }, /* Arabic_sheen Ø´ ARABIC LETTER SHEEN */ + { 0x05d5, 0x0635 }, /* Arabic_sad ص ARABIC LETTER SAD */ + { 0x05d6, 0x0636 }, /* Arabic_dad ض ARABIC LETTER DAD */ + { 0x05d7, 0x0637 }, /* Arabic_tah Ø· ARABIC LETTER TAH */ + { 0x05d8, 0x0638 }, /* Arabic_zah ظ ARABIC LETTER ZAH */ + { 0x05d9, 0x0639 }, /* Arabic_ain ع ARABIC LETTER AIN */ + { 0x05da, 0x063a }, /* Arabic_ghain غ ARABIC LETTER GHAIN */ + { 0x05e0, 0x0640 }, /* Arabic_tatweel Ù€ ARABIC TATWEEL */ + { 0x05e1, 0x0641 }, /* Arabic_feh Ù ARABIC LETTER FEH */ + { 0x05e2, 0x0642 }, /* Arabic_qaf Ù‚ ARABIC LETTER QAF */ + { 0x05e3, 0x0643 }, /* Arabic_kaf Ùƒ ARABIC LETTER KAF */ + { 0x05e4, 0x0644 }, /* Arabic_lam Ù„ ARABIC LETTER LAM */ + { 0x05e5, 0x0645 }, /* Arabic_meem Ù… ARABIC LETTER MEEM */ + { 0x05e6, 0x0646 }, /* Arabic_noon Ù† ARABIC LETTER NOON */ + { 0x05e7, 0x0647 }, /* Arabic_ha Ù‡ ARABIC LETTER HEH */ + { 0x05e8, 0x0648 }, /* Arabic_waw Ùˆ ARABIC LETTER WAW */ + { 0x05e9, 0x0649 }, /* Arabic_alefmaksura Ù‰ ARABIC LETTER ALEF MAKSURA */ + { 0x05ea, 0x064a }, /* Arabic_yeh ÙŠ ARABIC LETTER YEH */ + { 0x05eb, 0x064b }, /* Arabic_fathatan Ù‹ ARABIC FATHATAN */ + { 0x05ec, 0x064c }, /* Arabic_dammatan ÙŒ ARABIC DAMMATAN */ + { 0x05ed, 0x064d }, /* Arabic_kasratan Ù ARABIC KASRATAN */ + { 0x05ee, 0x064e }, /* Arabic_fatha ÙŽ ARABIC FATHA */ + { 0x05ef, 0x064f }, /* Arabic_damma Ù ARABIC DAMMA */ + { 0x05f0, 0x0650 }, /* Arabic_kasra Ù ARABIC KASRA */ + { 0x05f1, 0x0651 }, /* Arabic_shadda Ù‘ ARABIC SHADDA */ + { 0x05f2, 0x0652 }, /* Arabic_sukun Ù’ ARABIC SUKUN */ + { 0x0da1, 0x0e01 }, /* Thai_kokai ภTHAI CHARACTER KO KAI */ + { 0x0da2, 0x0e02 }, /* Thai_khokhai ข THAI CHARACTER KHO KHAI */ + { 0x0da3, 0x0e03 }, /* Thai_khokhuat ฃ THAI CHARACTER KHO KHUAT */ + { 0x0da4, 0x0e04 }, /* Thai_khokhwai ค THAI CHARACTER KHO KHWAI */ + { 0x0da5, 0x0e05 }, /* Thai_khokhon ฅ THAI CHARACTER KHO KHON */ + { 0x0da6, 0x0e06 }, /* Thai_khorakhang ฆ THAI CHARACTER KHO RAKHANG */ + { 0x0da7, 0x0e07 }, /* Thai_ngongu ง THAI CHARACTER NGO NGU */ + { 0x0da8, 0x0e08 }, /* Thai_chochan จ THAI CHARACTER CHO CHAN */ + { 0x0da9, 0x0e09 }, /* Thai_choching ฉ THAI CHARACTER CHO CHING */ + { 0x0daa, 0x0e0a }, /* Thai_chochang ช THAI CHARACTER CHO CHANG */ + { 0x0dab, 0x0e0b }, /* Thai_soso ซ THAI CHARACTER SO SO */ + { 0x0dac, 0x0e0c }, /* Thai_chochoe ฌ THAI CHARACTER CHO CHOE */ + { 0x0dad, 0x0e0d }, /* Thai_yoying ภTHAI CHARACTER YO YING */ + { 0x0dae, 0x0e0e }, /* Thai_dochada ฎ THAI CHARACTER DO CHADA */ + { 0x0daf, 0x0e0f }, /* Thai_topatak ภTHAI CHARACTER TO PATAK */ + { 0x0db0, 0x0e10 }, /* Thai_thothan ภTHAI CHARACTER THO THAN */ + { 0x0db1, 0x0e11 }, /* Thai_thonangmontho ฑ THAI CHARACTER THO NANGMONTHO */ + { 0x0db2, 0x0e12 }, /* Thai_thophuthao ฒ THAI CHARACTER THO PHUTHAO */ + { 0x0db3, 0x0e13 }, /* Thai_nonen ณ THAI CHARACTER NO NEN */ + { 0x0db4, 0x0e14 }, /* Thai_dodek ด THAI CHARACTER DO DEK */ + { 0x0db5, 0x0e15 }, /* Thai_totao ต THAI CHARACTER TO TAO */ + { 0x0db6, 0x0e16 }, /* Thai_thothung ถ THAI CHARACTER THO THUNG */ + { 0x0db7, 0x0e17 }, /* Thai_thothahan ท THAI CHARACTER THO THAHAN */ + { 0x0db8, 0x0e18 }, /* Thai_thothong ธ THAI CHARACTER THO THONG */ + { 0x0db9, 0x0e19 }, /* Thai_nonu น THAI CHARACTER NO NU */ + { 0x0dba, 0x0e1a }, /* Thai_bobaimai บ THAI CHARACTER BO BAIMAI */ + { 0x0dbb, 0x0e1b }, /* Thai_popla ป THAI CHARACTER PO PLA */ + { 0x0dbc, 0x0e1c }, /* Thai_phophung ผ THAI CHARACTER PHO PHUNG */ + { 0x0dbd, 0x0e1d }, /* Thai_fofa ภTHAI CHARACTER FO FA */ + { 0x0dbe, 0x0e1e }, /* Thai_phophan พ THAI CHARACTER PHO PHAN */ + { 0x0dbf, 0x0e1f }, /* Thai_fofan ฟ THAI CHARACTER FO FAN */ + { 0x0dc0, 0x0e20 }, /* Thai_phosamphao ภ THAI CHARACTER PHO SAMPHAO */ + { 0x0dc1, 0x0e21 }, /* Thai_moma ม THAI CHARACTER MO MA */ + { 0x0dc2, 0x0e22 }, /* Thai_yoyak ย THAI CHARACTER YO YAK */ + { 0x0dc3, 0x0e23 }, /* Thai_rorua ร THAI CHARACTER RO RUA */ + { 0x0dc4, 0x0e24 }, /* Thai_ru ฤ THAI CHARACTER RU */ + { 0x0dc5, 0x0e25 }, /* Thai_loling ล THAI CHARACTER LO LING */ + { 0x0dc6, 0x0e26 }, /* Thai_lu ฦ THAI CHARACTER LU */ + { 0x0dc7, 0x0e27 }, /* Thai_wowaen ว THAI CHARACTER WO WAEN */ + { 0x0dc8, 0x0e28 }, /* Thai_sosala ศ THAI CHARACTER SO SALA */ + { 0x0dc9, 0x0e29 }, /* Thai_sorusi ษ THAI CHARACTER SO RUSI */ + { 0x0dca, 0x0e2a }, /* Thai_sosua ส THAI CHARACTER SO SUA */ + { 0x0dcb, 0x0e2b }, /* Thai_hohip ห THAI CHARACTER HO HIP */ + { 0x0dcc, 0x0e2c }, /* Thai_lochula ฬ THAI CHARACTER LO CHULA */ + { 0x0dcd, 0x0e2d }, /* Thai_oang อ THAI CHARACTER O ANG */ + { 0x0dce, 0x0e2e }, /* Thai_honokhuk ฮ THAI CHARACTER HO NOKHUK */ + { 0x0dcf, 0x0e2f }, /* Thai_paiyannoi ฯ THAI CHARACTER PAIYANNOI */ + { 0x0dd0, 0x0e30 }, /* Thai_saraa ะ THAI CHARACTER SARA A */ + { 0x0dd1, 0x0e31 }, /* Thai_maihanakat ั THAI CHARACTER MAI HAN-AKAT */ + { 0x0dd2, 0x0e32 }, /* Thai_saraaa า THAI CHARACTER SARA AA */ + { 0x0dd3, 0x0e33 }, /* Thai_saraam ำ THAI CHARACTER SARA AM */ + { 0x0dd4, 0x0e34 }, /* Thai_sarai ิ THAI CHARACTER SARA I */ + { 0x0dd5, 0x0e35 }, /* Thai_saraii ี THAI CHARACTER SARA II */ + { 0x0dd6, 0x0e36 }, /* Thai_saraue ึ THAI CHARACTER SARA UE */ + { 0x0dd7, 0x0e37 }, /* Thai_sarauee ื THAI CHARACTER SARA UEE */ + { 0x0dd8, 0x0e38 }, /* Thai_sarau ุ THAI CHARACTER SARA U */ + { 0x0dd9, 0x0e39 }, /* Thai_sarauu ู THAI CHARACTER SARA UU */ + { 0x0dda, 0x0e3a }, /* Thai_phinthu ฺ THAI CHARACTER PHINTHU */ + { 0x0ddf, 0x0e3f }, /* Thai_baht ฿ THAI CURRENCY SYMBOL BAHT */ + { 0x0de0, 0x0e40 }, /* Thai_sarae เ THAI CHARACTER SARA E */ + { 0x0de1, 0x0e41 }, /* Thai_saraae ๠THAI CHARACTER SARA AE */ + { 0x0de2, 0x0e42 }, /* Thai_sarao โ THAI CHARACTER SARA O */ + { 0x0de3, 0x0e43 }, /* Thai_saraaimaimuan ใ THAI CHARACTER SARA AI MAIMUAN */ + { 0x0de4, 0x0e44 }, /* Thai_saraaimaimalai ไ THAI CHARACTER SARA AI MAIMALAI */ + { 0x0de5, 0x0e45 }, /* Thai_lakkhangyao ๅ THAI CHARACTER LAKKHANGYAO */ + { 0x0de6, 0x0e46 }, /* Thai_maiyamok ๆ THAI CHARACTER MAIYAMOK */ + { 0x0de7, 0x0e47 }, /* Thai_maitaikhu ็ THAI CHARACTER MAITAIKHU */ + { 0x0de8, 0x0e48 }, /* Thai_maiek ่ THAI CHARACTER MAI EK */ + { 0x0de9, 0x0e49 }, /* Thai_maitho ้ THAI CHARACTER MAI THO */ + { 0x0dea, 0x0e4a }, /* Thai_maitri ๊ THAI CHARACTER MAI TRI */ + { 0x0deb, 0x0e4b }, /* Thai_maichattawa ๋ THAI CHARACTER MAI CHATTAWA */ + { 0x0dec, 0x0e4c }, /* Thai_thanthakhat ์ THAI CHARACTER THANTHAKHAT */ + { 0x0ded, 0x0e4d }, /* Thai_nikhahit ๠THAI CHARACTER NIKHAHIT */ + { 0x0df0, 0x0e50 }, /* Thai_leksun ๠THAI DIGIT ZERO */ + { 0x0df1, 0x0e51 }, /* Thai_leknung ๑ THAI DIGIT ONE */ + { 0x0df2, 0x0e52 }, /* Thai_leksong ๒ THAI DIGIT TWO */ + { 0x0df3, 0x0e53 }, /* Thai_leksam ๓ THAI DIGIT THREE */ + { 0x0df4, 0x0e54 }, /* Thai_leksi ๔ THAI DIGIT FOUR */ + { 0x0df5, 0x0e55 }, /* Thai_lekha ๕ THAI DIGIT FIVE */ + { 0x0df6, 0x0e56 }, /* Thai_lekhok ๖ THAI DIGIT SIX */ + { 0x0df7, 0x0e57 }, /* Thai_lekchet ๗ THAI DIGIT SEVEN */ + { 0x0df8, 0x0e58 }, /* Thai_lekpaet ๘ THAI DIGIT EIGHT */ + { 0x0df9, 0x0e59 }, /* Thai_lekkao ๙ THAI DIGIT NINE */ + { 0x0ed4, 0x11a8 }, /* Hangul_J_Kiyeog ᆨ HANGUL JONGSEONG KIYEOK */ + { 0x0ed5, 0x11a9 }, /* Hangul_J_SsangKiyeog ᆩ HANGUL JONGSEONG SSANGKIYEOK */ + { 0x0ed6, 0x11aa }, /* Hangul_J_KiyeogSios ᆪ HANGUL JONGSEONG KIYEOK-SIOS */ + { 0x0ed7, 0x11ab }, /* Hangul_J_Nieun ᆫ HANGUL JONGSEONG NIEUN */ + { 0x0ed8, 0x11ac }, /* Hangul_J_NieunJieuj ᆬ HANGUL JONGSEONG NIEUN-CIEUC */ + { 0x0ed9, 0x11ad }, /* Hangul_J_NieunHieuh ᆭ HANGUL JONGSEONG NIEUN-HIEUH */ + { 0x0eda, 0x11ae }, /* Hangul_J_Dikeud ᆮ HANGUL JONGSEONG TIKEUT */ + { 0x0edb, 0x11af }, /* Hangul_J_Rieul ᆯ HANGUL JONGSEONG RIEUL */ + { 0x0edc, 0x11b0 }, /* Hangul_J_RieulKiyeog ᆰ HANGUL JONGSEONG RIEUL-KIYEOK */ + { 0x0edd, 0x11b1 }, /* Hangul_J_RieulMieum ᆱ HANGUL JONGSEONG RIEUL-MIEUM */ + { 0x0ede, 0x11b2 }, /* Hangul_J_RieulPieub ᆲ HANGUL JONGSEONG RIEUL-PIEUP */ + { 0x0edf, 0x11b3 }, /* Hangul_J_RieulSios ᆳ HANGUL JONGSEONG RIEUL-SIOS */ + { 0x0ee0, 0x11b4 }, /* Hangul_J_RieulTieut ᆴ HANGUL JONGSEONG RIEUL-THIEUTH */ + { 0x0ee1, 0x11b5 }, /* Hangul_J_RieulPhieuf ᆵ HANGUL JONGSEONG RIEUL-PHIEUPH */ + { 0x0ee2, 0x11b6 }, /* Hangul_J_RieulHieuh ᆶ HANGUL JONGSEONG RIEUL-HIEUH */ + { 0x0ee3, 0x11b7 }, /* Hangul_J_Mieum ᆷ HANGUL JONGSEONG MIEUM */ + { 0x0ee4, 0x11b8 }, /* Hangul_J_Pieub ᆸ HANGUL JONGSEONG PIEUP */ + { 0x0ee5, 0x11b9 }, /* Hangul_J_PieubSios ᆹ HANGUL JONGSEONG PIEUP-SIOS */ + { 0x0ee6, 0x11ba }, /* Hangul_J_Sios ᆺ HANGUL JONGSEONG SIOS */ + { 0x0ee7, 0x11bb }, /* Hangul_J_SsangSios ᆻ HANGUL JONGSEONG SSANGSIOS */ + { 0x0ee8, 0x11bc }, /* Hangul_J_Ieung ᆼ HANGUL JONGSEONG IEUNG */ + { 0x0ee9, 0x11bd }, /* Hangul_J_Jieuj ᆽ HANGUL JONGSEONG CIEUC */ + { 0x0eea, 0x11be }, /* Hangul_J_Cieuc ᆾ HANGUL JONGSEONG CHIEUCH */ + { 0x0eeb, 0x11bf }, /* Hangul_J_Khieuq ᆿ HANGUL JONGSEONG KHIEUKH */ + { 0x0eec, 0x11c0 }, /* Hangul_J_Tieut ᇀ HANGUL JONGSEONG THIEUTH */ + { 0x0eed, 0x11c1 }, /* Hangul_J_Phieuf ᇠHANGUL JONGSEONG PHIEUPH */ + { 0x0eee, 0x11c2 }, /* Hangul_J_Hieuh ᇂ HANGUL JONGSEONG HIEUH */ + { 0x0ef8, 0x11eb }, /* Hangul_J_PanSios ᇫ HANGUL JONGSEONG PANSIOS */ + { 0x0efa, 0x11f9 }, /* Hangul_J_YeorinHieuh ᇹ HANGUL JONGSEONG YEORINHIEUH */ + { 0x0aa2, 0x2002 }, /* enspace   EN SPACE */ + { 0x0aa1, 0x2003 }, /* emspace   EM SPACE */ + { 0x0aa3, 0x2004 }, /* em3space   THREE-PER-EM SPACE */ + { 0x0aa4, 0x2005 }, /* em4space   FOUR-PER-EM SPACE */ + { 0x0aa5, 0x2007 }, /* digitspace   FIGURE SPACE */ + { 0x0aa6, 0x2008 }, /* punctspace   PUNCTUATION SPACE */ + { 0x0aa7, 0x2009 }, /* thinspace   THIN SPACE */ + { 0x0aa8, 0x200a }, /* hairspace   HAIR SPACE */ + { 0x0abb, 0x2012 }, /* figdash ‒ FIGURE DASH */ + { 0x0aaa, 0x2013 }, /* endash – EN DASH */ + { 0x0aa9, 0x2014 }, /* emdash — EM DASH */ + { 0x07af, 0x2015 }, /* Greek_horizbar ― HORIZONTAL BAR */ + { 0x0cdf, 0x2017 }, /* hebrew_doublelowline ‗ DOUBLE LOW LINE */ + { 0x0ad0, 0x2018 }, /* leftsinglequotemark ‘ LEFT SINGLE QUOTATION MARK */ + { 0x0ad1, 0x2019 }, /* rightsinglequotemark ’ RIGHT SINGLE QUOTATION MARK */ + { 0x0afd, 0x201a }, /* singlelowquotemark ‚ SINGLE LOW-9 QUOTATION MARK */ + { 0x0ad2, 0x201c }, /* leftdoublequotemark “ LEFT DOUBLE QUOTATION MARK */ + { 0x0ad3, 0x201d }, /* rightdoublequotemark †RIGHT DOUBLE QUOTATION MARK */ + { 0x0afe, 0x201e }, /* doublelowquotemark „ DOUBLE LOW-9 QUOTATION MARK */ + { 0x0af1, 0x2020 }, /* dagger † DAGGER */ + { 0x0af2, 0x2021 }, /* doubledagger ‡ DOUBLE DAGGER */ + { 0x0ae6, 0x2022 }, /* enfilledcircbullet • BULLET */ + { 0x0aae, 0x2026 }, /* ellipsis … HORIZONTAL ELLIPSIS */ + { 0x0ad6, 0x2032 }, /* minutes ′ PRIME */ + { 0x0ad7, 0x2033 }, /* seconds ″ DOUBLE PRIME */ + { 0x0afc, 0x2038 }, /* caret ‸ CARET */ + { 0x047e, 0x203e }, /* overline ‾ OVERLINE */ + { 0x20a0, 0x20a0 }, /* EcuSign â‚  EURO-CURRENCY SIGN */ + { 0x20a1, 0x20a1 }, /* ColonSign â‚¡ COLON SIGN */ + { 0x20a2, 0x20a2 }, /* CruzeiroSign â‚¢ CRUZEIRO SIGN */ + { 0x20a3, 0x20a3 }, /* FFrancSign â‚£ FRENCH FRANC SIGN */ + { 0x20a4, 0x20a4 }, /* LiraSign ₤ LIRA SIGN */ + { 0x20a5, 0x20a5 }, /* MillSign â‚¥ MILL SIGN */ + { 0x20a6, 0x20a6 }, /* NairaSign ₦ NAIRA SIGN */ + { 0x20a7, 0x20a7 }, /* PesetaSign â‚§ PESETA SIGN */ + { 0x20a8, 0x20a8 }, /* RupeeSign ₨ RUPEE SIGN */ + { 0x0eff, 0x20a9 }, /* Korean_Won â‚© WON SIGN */ + { 0x20a9, 0x20a9 }, /* WonSign â‚© WON SIGN */ + { 0x20aa, 0x20aa }, /* NewSheqelSign ₪ NEW SHEQEL SIGN */ + { 0x20ab, 0x20ab }, /* DongSign â‚« DONG SIGN */ + { 0x20ac, 0x20ac }, /* EuroSign € EURO SIGN */ + { 0x0ab8, 0x2105 }, /* careof â„… CARE OF */ + { 0x06b0, 0x2116 }, /* numerosign â„– NUMERO SIGN */ + { 0x0afb, 0x2117 }, /* phonographcopyright â„— SOUND RECORDING COPYRIGHT */ + { 0x0ad4, 0x211e }, /* prescription ℞ PRESCRIPTION TAKE */ + { 0x0ac9, 0x2122 }, /* trademark â„¢ TRADE MARK SIGN */ + { 0x0ab0, 0x2153 }, /* onethird â…“ VULGAR FRACTION ONE THIRD */ + { 0x0ab1, 0x2154 }, /* twothirds â…” VULGAR FRACTION TWO THIRDS */ + { 0x0ab2, 0x2155 }, /* onefifth â…• VULGAR FRACTION ONE FIFTH */ + { 0x0ab3, 0x2156 }, /* twofifths â…– VULGAR FRACTION TWO FIFTHS */ + { 0x0ab4, 0x2157 }, /* threefifths â…— VULGAR FRACTION THREE FIFTHS */ + { 0x0ab5, 0x2158 }, /* fourfifths â…˜ VULGAR FRACTION FOUR FIFTHS */ + { 0x0ab6, 0x2159 }, /* onesixth â…™ VULGAR FRACTION ONE SIXTH */ + { 0x0ab7, 0x215a }, /* fivesixths â…š VULGAR FRACTION FIVE SIXTHS */ + { 0x0ac3, 0x215b }, /* oneeighth â…› VULGAR FRACTION ONE EIGHTH */ + { 0x0ac4, 0x215c }, /* threeeighths â…œ VULGAR FRACTION THREE EIGHTHS */ + { 0x0ac5, 0x215d }, /* fiveeighths â… VULGAR FRACTION FIVE EIGHTHS */ + { 0x0ac6, 0x215e }, /* seveneighths â…ž VULGAR FRACTION SEVEN EIGHTHS */ + { 0x08fb, 0x2190 }, /* leftarrow ↠LEFTWARDS ARROW */ + { 0x08fc, 0x2191 }, /* uparrow ↑ UPWARDS ARROW */ + { 0x08fd, 0x2192 }, /* rightarrow → RIGHTWARDS ARROW */ + { 0x08fe, 0x2193 }, /* downarrow ↓ DOWNWARDS ARROW */ + { 0x08ce, 0x21d2 }, /* implies ⇒ RIGHTWARDS DOUBLE ARROW */ + { 0x08cd, 0x21d4 }, /* ifonlyif ⇔ LEFT RIGHT DOUBLE ARROW */ + { 0x08ef, 0x2202 }, /* partialderivative ∂ PARTIAL DIFFERENTIAL */ + { 0x08c5, 0x2207 }, /* nabla ∇ NABLA */ + { 0x0bca, 0x2218 }, /* jot ∘ RING OPERATOR */ + { 0x08d6, 0x221a }, /* radical √ SQUARE ROOT */ + { 0x08c1, 0x221d }, /* variation ∠PROPORTIONAL TO */ + { 0x08c2, 0x221e }, /* infinity ∞ INFINITY */ + { 0x08de, 0x2227 }, /* logicaland ∧ LOGICAL AND */ + { 0x0ba9, 0x2227 }, /* upcaret ∧ LOGICAL AND */ + { 0x08df, 0x2228 }, /* logicalor ∨ LOGICAL OR */ + { 0x0ba8, 0x2228 }, /* downcaret ∨ LOGICAL OR */ + { 0x08dc, 0x2229 }, /* intersection ∩ INTERSECTION */ + { 0x0bc3, 0x2229 }, /* upshoe ∩ INTERSECTION */ + { 0x08dd, 0x222a }, /* union ∪ UNION */ + { 0x0bd6, 0x222a }, /* downshoe ∪ UNION */ + { 0x08bf, 0x222b }, /* integral ∫ INTEGRAL */ + { 0x08c0, 0x2234 }, /* therefore ∴ THEREFORE */ + { 0x08c8, 0x2245 }, /* approximate ≅ APPROXIMATELY EQUAL TO */ + { 0x08bd, 0x2260 }, /* notequal ≠ NOT EQUAL TO */ + { 0x08cf, 0x2261 }, /* identical ≡ IDENTICAL TO */ + { 0x08bc, 0x2264 }, /* lessthanequal ≤ LESS-THAN OR EQUAL TO */ + { 0x08be, 0x2265 }, /* greaterthanequal ≥ GREATER-THAN OR EQUAL TO */ + { 0x08da, 0x2282 }, /* includedin ⊂ SUBSET OF */ + { 0x0bda, 0x2282 }, /* leftshoe ⊂ SUBSET OF */ + { 0x08db, 0x2283 }, /* includes ⊃ SUPERSET OF */ + { 0x0bd8, 0x2283 }, /* rightshoe ⊃ SUPERSET OF */ + { 0x0bfc, 0x22a2 }, /* righttack ⊢ RIGHT TACK */ + { 0x0bdc, 0x22a3 }, /* lefttack ⊣ LEFT TACK */ + { 0x0bc2, 0x22a4 }, /* downtack ⊤ DOWN TACK */ + { 0x0bce, 0x22a5 }, /* uptack ⊥ UP TACK */ + { 0x0bd3, 0x2308 }, /* upstile ⌈ LEFT CEILING */ + { 0x0bc4, 0x230a }, /* downstile ⌊ LEFT FLOOR */ + { 0x0afa, 0x2315 }, /* telephonerecorder ⌕ TELEPHONE RECORDER */ + { 0x08a4, 0x2320 }, /* topintegral ⌠ TOP HALF INTEGRAL */ + { 0x08a5, 0x2321 }, /* botintegral ⌡ BOTTOM HALF INTEGRAL */ + { 0x0abc, 0x2329 }, /* leftanglebracket 〈 LEFT-POINTING ANGLE BRACKET */ + { 0x0abe, 0x232a }, /* rightanglebracket 〉 RIGHT-POINTING ANGLE BRACKET */ + { 0x0bcc, 0x2395 }, /* quad ⎕ APL FUNCTIONAL SYMBOL QUAD (Unicode 3.0) */ + { 0x09e2, 0x2409 }, /* ht ≠SYMBOL FOR HORIZONTAL TABULATION */ + { 0x09e5, 0x240a }, /* lf ⊠SYMBOL FOR LINE FEED */ + { 0x09e9, 0x240b }, /* vt â‹ SYMBOL FOR VERTICAL TABULATION */ + { 0x09e3, 0x240c }, /* ff ⌠SYMBOL FOR FORM FEED */ + { 0x09e4, 0x240d }, /* cr â SYMBOL FOR CARRIAGE RETURN */ + { 0x09df, 0x2422 }, /* blank ⢠BLANK SYMBOL */ + { 0x09e8, 0x2424 }, /* nl ⤠SYMBOL FOR NEWLINE */ + { 0x09f1, 0x2500 }, /* horizlinescan5 ─ BOX DRAWINGS LIGHT HORIZONTAL */ + { 0x08a6, 0x2502 }, /* vertconnector │ BOX DRAWINGS LIGHT VERTICAL */ + { 0x09f8, 0x2502 }, /* vertbar │ BOX DRAWINGS LIGHT VERTICAL */ + { 0x09ec, 0x250c }, /* upleftcorner ┌ BOX DRAWINGS LIGHT DOWN AND RIGHT */ + { 0x09eb, 0x2510 }, /* uprightcorner â” BOX DRAWINGS LIGHT DOWN AND LEFT */ + { 0x09ed, 0x2514 }, /* lowleftcorner â”” BOX DRAWINGS LIGHT UP AND RIGHT */ + { 0x09ea, 0x2518 }, /* lowrightcorner ┘ BOX DRAWINGS LIGHT UP AND LEFT */ + { 0x09f4, 0x251c }, /* leftt ├ BOX DRAWINGS LIGHT VERTICAL AND RIGHT */ + { 0x09f5, 0x2524 }, /* rightt ┤ BOX DRAWINGS LIGHT VERTICAL AND LEFT */ + { 0x09f7, 0x252c }, /* topt ┬ BOX DRAWINGS LIGHT DOWN AND HORIZONTAL */ + { 0x09f6, 0x2534 }, /* bott â”´ BOX DRAWINGS LIGHT UP AND HORIZONTAL */ + { 0x09ee, 0x253c }, /* crossinglines ┼ BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL */ + { 0x09e1, 0x2592 }, /* checkerboard â–’ MEDIUM SHADE */ + { 0x0adf, 0x25a0 }, /* emfilledrect â–  BLACK SQUARE */ + { 0x0acf, 0x25a1 }, /* emopenrectangle â–¡ WHITE SQUARE */ + { 0x0ae7, 0x25aa }, /* enfilledsqbullet â–ª BLACK SMALL SQUARE */ + { 0x0ae1, 0x25ab }, /* enopensquarebullet â–« WHITE SMALL SQUARE */ + { 0x0adb, 0x25ac }, /* filledrectbullet â–¬ BLACK RECTANGLE */ + { 0x0ae2, 0x25ad }, /* openrectbullet â–­ WHITE RECTANGLE */ + { 0x0ae8, 0x25b2 }, /* filledtribulletup â–² BLACK UP-POINTING TRIANGLE */ + { 0x0ae3, 0x25b3 }, /* opentribulletup â–³ WHITE UP-POINTING TRIANGLE */ + { 0x0add, 0x25b6 }, /* filledrighttribullet â–¶ BLACK RIGHT-POINTING TRIANGLE */ + { 0x0acd, 0x25b7 }, /* rightopentriangle â–· WHITE RIGHT-POINTING TRIANGLE */ + { 0x0ae9, 0x25bc }, /* filledtribulletdown â–¼ BLACK DOWN-POINTING TRIANGLE */ + { 0x0ae4, 0x25bd }, /* opentribulletdown â–½ WHITE DOWN-POINTING TRIANGLE */ + { 0x0adc, 0x25c0 }, /* filledlefttribullet â—€ BLACK LEFT-POINTING TRIANGLE */ + { 0x0acc, 0x25c1 }, /* leftopentriangle â— WHITE LEFT-POINTING TRIANGLE */ + { 0x09e0, 0x25c6 }, /* soliddiamond â—† BLACK DIAMOND */ + { 0x0ace, 0x25cb }, /* emopencircle â—‹ WHITE CIRCLE */ + { 0x0bcf, 0x25cb }, /* circle â—‹ WHITE CIRCLE */ + { 0x0ade, 0x25cf }, /* emfilledcircle â— BLACK CIRCLE */ + { 0x0ae0, 0x25e6 }, /* enopencircbullet â—¦ WHITE BULLET */ + { 0x0ae5, 0x2606 }, /* openstar ☆ WHITE STAR */ + { 0x0af9, 0x260e }, /* telephone ☎ BLACK TELEPHONE */ + { 0x0aca, 0x2613 }, /* signaturemark ☓ SALTIRE */ + { 0x0aea, 0x261c }, /* leftpointer ☜ WHITE LEFT POINTING INDEX */ + { 0x0aeb, 0x261e }, /* rightpointer ☞ WHITE RIGHT POINTING INDEX */ + { 0x0af8, 0x2640 }, /* femalesymbol ♀ FEMALE SIGN */ + { 0x0af7, 0x2642 }, /* malesymbol ♂ MALE SIGN */ + { 0x0aec, 0x2663 }, /* club ♣ BLACK CLUB SUIT */ + { 0x0aee, 0x2665 }, /* heart ♥ BLACK HEART SUIT */ + { 0x0aed, 0x2666 }, /* diamond ♦ BLACK DIAMOND SUIT */ + { 0x0af6, 0x266d }, /* musicalflat â™­ MUSIC FLAT SIGN */ + { 0x0af5, 0x266f }, /* musicalsharp ♯ MUSIC SHARP SIGN */ + { 0x0af3, 0x2713 }, /* checkmark ✓ CHECK MARK */ + { 0x0af4, 0x2717 }, /* ballotcross ✗ BALLOT X */ + { 0x0ad9, 0x271d }, /* latincross ✠LATIN CROSS */ + { 0x0af0, 0x2720 }, /* maltesecross ✠ MALTESE CROSS */ + { 0x04a4, 0x3001 }, /* kana_comma 〠IDEOGRAPHIC COMMA */ + { 0x04a1, 0x3002 }, /* kana_fullstop 。 IDEOGRAPHIC FULL STOP */ + { 0x04a2, 0x300c }, /* kana_openingbracket 「 LEFT CORNER BRACKET */ + { 0x04a3, 0x300d }, /* kana_closingbracket 〠RIGHT CORNER BRACKET */ + { 0x04de, 0x309b }, /* voicedsound ã‚› KATAKANA-HIRAGANA VOICED SOUND MARK */ + { 0x04df, 0x309c }, /* semivoicedsound ゜ KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK */ + { 0x04a7, 0x30a1 }, /* kana_a ã‚¡ KATAKANA LETTER SMALL A */ + { 0x04b1, 0x30a2 }, /* kana_A ã‚¢ KATAKANA LETTER A */ + { 0x04a8, 0x30a3 }, /* kana_i ã‚£ KATAKANA LETTER SMALL I */ + { 0x04b2, 0x30a4 }, /* kana_I イ KATAKANA LETTER I */ + { 0x04a9, 0x30a5 }, /* kana_u ã‚¥ KATAKANA LETTER SMALL U */ + { 0x04b3, 0x30a6 }, /* kana_U ウ KATAKANA LETTER U */ + { 0x04aa, 0x30a7 }, /* kana_e ã‚§ KATAKANA LETTER SMALL E */ + { 0x04b4, 0x30a8 }, /* kana_E エ KATAKANA LETTER E */ + { 0x04ab, 0x30a9 }, /* kana_o ã‚© KATAKANA LETTER SMALL O */ + { 0x04b5, 0x30aa }, /* kana_O オ KATAKANA LETTER O */ + { 0x04b6, 0x30ab }, /* kana_KA ã‚« KATAKANA LETTER KA */ + { 0x04b7, 0x30ad }, /* kana_KI ã‚­ KATAKANA LETTER KI */ + { 0x04b8, 0x30af }, /* kana_KU ク KATAKANA LETTER KU */ + { 0x04b9, 0x30b1 }, /* kana_KE ケ KATAKANA LETTER KE */ + { 0x04ba, 0x30b3 }, /* kana_KO コ KATAKANA LETTER KO */ + { 0x04bb, 0x30b5 }, /* kana_SA サ KATAKANA LETTER SA */ + { 0x04bc, 0x30b7 }, /* kana_SHI ã‚· KATAKANA LETTER SI */ + { 0x04bd, 0x30b9 }, /* kana_SU ス KATAKANA LETTER SU */ + { 0x04be, 0x30bb }, /* kana_SE ã‚» KATAKANA LETTER SE */ + { 0x04bf, 0x30bd }, /* kana_SO ソ KATAKANA LETTER SO */ + { 0x04c0, 0x30bf }, /* kana_TA ã‚¿ KATAKANA LETTER TA */ + { 0x04c1, 0x30c1 }, /* kana_CHI ムKATAKANA LETTER TI */ + { 0x04af, 0x30c3 }, /* kana_tsu ッ KATAKANA LETTER SMALL TU */ + { 0x04c2, 0x30c4 }, /* kana_TSU ツ KATAKANA LETTER TU */ + { 0x04c3, 0x30c6 }, /* kana_TE テ KATAKANA LETTER TE */ + { 0x04c4, 0x30c8 }, /* kana_TO ト KATAKANA LETTER TO */ + { 0x04c5, 0x30ca }, /* kana_NA ナ KATAKANA LETTER NA */ + { 0x04c6, 0x30cb }, /* kana_NI ニ KATAKANA LETTER NI */ + { 0x04c7, 0x30cc }, /* kana_NU ヌ KATAKANA LETTER NU */ + { 0x04c8, 0x30cd }, /* kana_NE ムKATAKANA LETTER NE */ + { 0x04c9, 0x30ce }, /* kana_NO ノ KATAKANA LETTER NO */ + { 0x04ca, 0x30cf }, /* kana_HA ムKATAKANA LETTER HA */ + { 0x04cb, 0x30d2 }, /* kana_HI ヒ KATAKANA LETTER HI */ + { 0x04cc, 0x30d5 }, /* kana_FU フ KATAKANA LETTER HU */ + { 0x04cd, 0x30d8 }, /* kana_HE ヘ KATAKANA LETTER HE */ + { 0x04ce, 0x30db }, /* kana_HO ホ KATAKANA LETTER HO */ + { 0x04cf, 0x30de }, /* kana_MA マ KATAKANA LETTER MA */ + { 0x04d0, 0x30df }, /* kana_MI ミ KATAKANA LETTER MI */ + { 0x04d1, 0x30e0 }, /* kana_MU ム KATAKANA LETTER MU */ + { 0x04d2, 0x30e1 }, /* kana_ME メ KATAKANA LETTER ME */ + { 0x04d3, 0x30e2 }, /* kana_MO モ KATAKANA LETTER MO */ + { 0x04ac, 0x30e3 }, /* kana_ya ャ KATAKANA LETTER SMALL YA */ + { 0x04d4, 0x30e4 }, /* kana_YA ヤ KATAKANA LETTER YA */ + { 0x04ad, 0x30e5 }, /* kana_yu ュ KATAKANA LETTER SMALL YU */ + { 0x04d5, 0x30e6 }, /* kana_YU ユ KATAKANA LETTER YU */ + { 0x04ae, 0x30e7 }, /* kana_yo ョ KATAKANA LETTER SMALL YO */ + { 0x04d6, 0x30e8 }, /* kana_YO ヨ KATAKANA LETTER YO */ + { 0x04d7, 0x30e9 }, /* kana_RA ラ KATAKANA LETTER RA */ + { 0x04d8, 0x30ea }, /* kana_RI リ KATAKANA LETTER RI */ + { 0x04d9, 0x30eb }, /* kana_RU ル KATAKANA LETTER RU */ + { 0x04da, 0x30ec }, /* kana_RE レ KATAKANA LETTER RE */ + { 0x04db, 0x30ed }, /* kana_RO ロ KATAKANA LETTER RO */ + { 0x04dc, 0x30ef }, /* kana_WA ワ KATAKANA LETTER WA */ + { 0x04a6, 0x30f2 }, /* kana_WO ヲ KATAKANA LETTER WO */ + { 0x04dd, 0x30f3 }, /* kana_N ン KATAKANA LETTER N */ + { 0x04a5, 0x30fb }, /* kana_conjunctive ・ KATAKANA MIDDLE DOT */ + { 0x04b0, 0x30fc }, /* prolongedsound ー KATAKANA-HIRAGANA PROLONGED SOUND MARK */ + { 0x0ea1, 0x3131 }, /* Hangul_Kiyeog ㄱ HANGUL LETTER KIYEOK */ + { 0x0ea2, 0x3132 }, /* Hangul_SsangKiyeog ㄲ HANGUL LETTER SSANGKIYEOK */ + { 0x0ea3, 0x3133 }, /* Hangul_KiyeogSios ㄳ HANGUL LETTER KIYEOK-SIOS */ + { 0x0ea4, 0x3134 }, /* Hangul_Nieun ã„´ HANGUL LETTER NIEUN */ + { 0x0ea5, 0x3135 }, /* Hangul_NieunJieuj ㄵ HANGUL LETTER NIEUN-CIEUC */ + { 0x0ea6, 0x3136 }, /* Hangul_NieunHieuh ã„¶ HANGUL LETTER NIEUN-HIEUH */ + { 0x0ea7, 0x3137 }, /* Hangul_Dikeud ã„· HANGUL LETTER TIKEUT */ + { 0x0ea8, 0x3138 }, /* Hangul_SsangDikeud ㄸ HANGUL LETTER SSANGTIKEUT */ + { 0x0ea9, 0x3139 }, /* Hangul_Rieul ㄹ HANGUL LETTER RIEUL */ + { 0x0eaa, 0x313a }, /* Hangul_RieulKiyeog ㄺ HANGUL LETTER RIEUL-KIYEOK */ + { 0x0eab, 0x313b }, /* Hangul_RieulMieum ã„» HANGUL LETTER RIEUL-MIEUM */ + { 0x0eac, 0x313c }, /* Hangul_RieulPieub ㄼ HANGUL LETTER RIEUL-PIEUP */ + { 0x0ead, 0x313d }, /* Hangul_RieulSios ㄽ HANGUL LETTER RIEUL-SIOS */ + { 0x0eae, 0x313e }, /* Hangul_RieulTieut ㄾ HANGUL LETTER RIEUL-THIEUTH */ + { 0x0eaf, 0x313f }, /* Hangul_RieulPhieuf ã„¿ HANGUL LETTER RIEUL-PHIEUPH */ + { 0x0eb0, 0x3140 }, /* Hangul_RieulHieuh ã…€ HANGUL LETTER RIEUL-HIEUH */ + { 0x0eb1, 0x3141 }, /* Hangul_Mieum ã… HANGUL LETTER MIEUM */ + { 0x0eb2, 0x3142 }, /* Hangul_Pieub ã…‚ HANGUL LETTER PIEUP */ + { 0x0eb3, 0x3143 }, /* Hangul_SsangPieub ã…ƒ HANGUL LETTER SSANGPIEUP */ + { 0x0eb4, 0x3144 }, /* Hangul_PieubSios ã…„ HANGUL LETTER PIEUP-SIOS */ + { 0x0eb5, 0x3145 }, /* Hangul_Sios ã…… HANGUL LETTER SIOS */ + { 0x0eb6, 0x3146 }, /* Hangul_SsangSios ã…† HANGUL LETTER SSANGSIOS */ + { 0x0eb7, 0x3147 }, /* Hangul_Ieung ã…‡ HANGUL LETTER IEUNG */ + { 0x0eb8, 0x3148 }, /* Hangul_Jieuj ã…ˆ HANGUL LETTER CIEUC */ + { 0x0eb9, 0x3149 }, /* Hangul_SsangJieuj ã…‰ HANGUL LETTER SSANGCIEUC */ + { 0x0eba, 0x314a }, /* Hangul_Cieuc ã…Š HANGUL LETTER CHIEUCH */ + { 0x0ebb, 0x314b }, /* Hangul_Khieuq ã…‹ HANGUL LETTER KHIEUKH */ + { 0x0ebc, 0x314c }, /* Hangul_Tieut ã…Œ HANGUL LETTER THIEUTH */ + { 0x0ebd, 0x314d }, /* Hangul_Phieuf ã… HANGUL LETTER PHIEUPH */ + { 0x0ebe, 0x314e }, /* Hangul_Hieuh ã…Ž HANGUL LETTER HIEUH */ + { 0x0ebf, 0x314f }, /* Hangul_A ã… HANGUL LETTER A */ + { 0x0ec0, 0x3150 }, /* Hangul_AE ã… HANGUL LETTER AE */ + { 0x0ec1, 0x3151 }, /* Hangul_YA ã…‘ HANGUL LETTER YA */ + { 0x0ec2, 0x3152 }, /* Hangul_YAE ã…’ HANGUL LETTER YAE */ + { 0x0ec3, 0x3153 }, /* Hangul_EO ã…“ HANGUL LETTER EO */ + { 0x0ec4, 0x3154 }, /* Hangul_E ã…” HANGUL LETTER E */ + { 0x0ec5, 0x3155 }, /* Hangul_YEO ã…• HANGUL LETTER YEO */ + { 0x0ec6, 0x3156 }, /* Hangul_YE ã…– HANGUL LETTER YE */ + { 0x0ec7, 0x3157 }, /* Hangul_O ã…— HANGUL LETTER O */ + { 0x0ec8, 0x3158 }, /* Hangul_WA ã…˜ HANGUL LETTER WA */ + { 0x0ec9, 0x3159 }, /* Hangul_WAE ã…™ HANGUL LETTER WAE */ + { 0x0eca, 0x315a }, /* Hangul_OE ã…š HANGUL LETTER OE */ + { 0x0ecb, 0x315b }, /* Hangul_YO ã…› HANGUL LETTER YO */ + { 0x0ecc, 0x315c }, /* Hangul_U ã…œ HANGUL LETTER U */ + { 0x0ecd, 0x315d }, /* Hangul_WEO ã… HANGUL LETTER WEO */ + { 0x0ece, 0x315e }, /* Hangul_WE ã…ž HANGUL LETTER WE */ + { 0x0ecf, 0x315f }, /* Hangul_WI ã…Ÿ HANGUL LETTER WI */ + { 0x0ed0, 0x3160 }, /* Hangul_YU ã…  HANGUL LETTER YU */ + { 0x0ed1, 0x3161 }, /* Hangul_EU ã…¡ HANGUL LETTER EU */ + { 0x0ed2, 0x3162 }, /* Hangul_YI ã…¢ HANGUL LETTER YI */ + { 0x0ed3, 0x3163 }, /* Hangul_I ã…£ HANGUL LETTER I */ + { 0x0eef, 0x316d }, /* Hangul_RieulYeorinHieuh ã…­ HANGUL LETTER RIEUL-YEORINHIEUH */ + { 0x0ef0, 0x3171 }, /* Hangul_SunkyeongeumMieum ã…± HANGUL LETTER KAPYEOUNMIEUM */ + { 0x0ef1, 0x3178 }, /* Hangul_SunkyeongeumPieub ã…¸ HANGUL LETTER KAPYEOUNPIEUP */ + { 0x0ef2, 0x317f }, /* Hangul_PanSios ã…¿ HANGUL LETTER PANSIOS */ + { 0x0ef4, 0x3184 }, /* Hangul_SunkyeongeumPhieuf ㆄ HANGUL LETTER KAPYEOUNPHIEUPH */ + { 0x0ef5, 0x3186 }, /* Hangul_YeorinHieuh ㆆ HANGUL LETTER YEORINHIEUH */ + { 0x0ef6, 0x318d }, /* Hangul_AraeA ㆠHANGUL LETTER ARAEA */ + { 0x0ef7, 0x318e }, /* Hangul_AraeAE ㆎ HANGUL LETTER ARAEAE */ +}; + +/** + * gdk_unicode_to_keyval: + * @wc: a ISO10646 encoded character + * + * Convert from a ISO10646 character to a key symbol. + * + * Return value: the corresponding GDK key symbol, if one exists. + * or, if there is no corresponding symbol, + * wc | 0x01000000 + **/ +guint +gdk_unicode_to_keyval (guint32 wc) +{ + int min = 0; + int max = G_N_ELEMENTS (gdk_unicode_to_keysym_tab) - 1; + int mid; + + /* First check for Latin-1 characters (1:1 mapping) */ + if ((wc >= 0x0020 && wc <= 0x007e) || + (wc >= 0x00a0 && wc <= 0x00ff)) + return wc; + + /* Binary search in table */ + while (max >= min) { + mid = (min + max) / 2; + if (gdk_unicode_to_keysym_tab[mid].ucs < wc) + min = mid + 1; + else if (gdk_unicode_to_keysym_tab[mid].ucs > wc) + max = mid - 1; + else { + /* found it */ + return gdk_unicode_to_keysym_tab[mid].keysym; + } + } + + /* + * No matching keysym value found, return Unicode value plus 0x01000000 + * (a convention introduced in the UTF-8 work on xterm). + */ + return wc | 0x01000000; +} + +#define __GDK_KEYUNI_C__ +#include "gdkaliasdef.c" diff --git a/libs/tk/ydk/gdkmarshalers.c b/libs/tk/ydk/gdkmarshalers.c new file mode 100644 index 0000000000..e432b48746 --- /dev/null +++ b/libs/tk/ydk/gdkmarshalers.c @@ -0,0 +1,208 @@ +#include "gdkalias.h" +/* This file is generated by glib-genmarshal, do not modify it. This code is licensed under the same license as the containing project. Note that it links to GLib, so must comply with the LGPL linking clauses. */ +#include + +#ifdef G_ENABLE_DEBUG +#define g_marshal_value_peek_boolean(v) g_value_get_boolean (v) +#define g_marshal_value_peek_char(v) g_value_get_schar (v) +#define g_marshal_value_peek_uchar(v) g_value_get_uchar (v) +#define g_marshal_value_peek_int(v) g_value_get_int (v) +#define g_marshal_value_peek_uint(v) g_value_get_uint (v) +#define g_marshal_value_peek_long(v) g_value_get_long (v) +#define g_marshal_value_peek_ulong(v) g_value_get_ulong (v) +#define g_marshal_value_peek_int64(v) g_value_get_int64 (v) +#define g_marshal_value_peek_uint64(v) g_value_get_uint64 (v) +#define g_marshal_value_peek_enum(v) g_value_get_enum (v) +#define g_marshal_value_peek_flags(v) g_value_get_flags (v) +#define g_marshal_value_peek_float(v) g_value_get_float (v) +#define g_marshal_value_peek_double(v) g_value_get_double (v) +#define g_marshal_value_peek_string(v) (char*) g_value_get_string (v) +#define g_marshal_value_peek_param(v) g_value_get_param (v) +#define g_marshal_value_peek_boxed(v) g_value_get_boxed (v) +#define g_marshal_value_peek_pointer(v) g_value_get_pointer (v) +#define g_marshal_value_peek_object(v) g_value_get_object (v) +#define g_marshal_value_peek_variant(v) g_value_get_variant (v) +#else /* !G_ENABLE_DEBUG */ +/* WARNING: This code accesses GValues directly, which is UNSUPPORTED API. + * Do not access GValues directly in your code. Instead, use the + * g_value_get_*() functions + */ +#define g_marshal_value_peek_boolean(v) (v)->data[0].v_int +#define g_marshal_value_peek_char(v) (v)->data[0].v_int +#define g_marshal_value_peek_uchar(v) (v)->data[0].v_uint +#define g_marshal_value_peek_int(v) (v)->data[0].v_int +#define g_marshal_value_peek_uint(v) (v)->data[0].v_uint +#define g_marshal_value_peek_long(v) (v)->data[0].v_long +#define g_marshal_value_peek_ulong(v) (v)->data[0].v_ulong +#define g_marshal_value_peek_int64(v) (v)->data[0].v_int64 +#define g_marshal_value_peek_uint64(v) (v)->data[0].v_uint64 +#define g_marshal_value_peek_enum(v) (v)->data[0].v_long +#define g_marshal_value_peek_flags(v) (v)->data[0].v_ulong +#define g_marshal_value_peek_float(v) (v)->data[0].v_float +#define g_marshal_value_peek_double(v) (v)->data[0].v_double +#define g_marshal_value_peek_string(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_param(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_boxed(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_object(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_variant(v) (v)->data[0].v_pointer +#endif /* !G_ENABLE_DEBUG */ + +/* VOID:POINTER,POINTER,POINTER (./gdkmarshalers.list:3) */ +void +_gdk_marshal_VOID__POINTER_POINTER_POINTER (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__POINTER_POINTER_POINTER) (gpointer data1, + gpointer arg1, + gpointer arg2, + gpointer arg3, + gpointer data2); + GCClosure *cc = (GCClosure *) closure; + gpointer data1, data2; + GMarshalFunc_VOID__POINTER_POINTER_POINTER callback; + + g_return_if_fail (n_param_values == 4); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__POINTER_POINTER_POINTER) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_pointer (param_values + 1), + g_marshal_value_peek_pointer (param_values + 2), + g_marshal_value_peek_pointer (param_values + 3), + data2); +} + +/* OBJECT:VOID (./gdkmarshalers.list:4) */ +void +_gdk_marshal_OBJECT__VOID (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef GObject* (*GMarshalFunc_OBJECT__VOID) (gpointer data1, + gpointer data2); + GCClosure *cc = (GCClosure *) closure; + gpointer data1, data2; + GMarshalFunc_OBJECT__VOID callback; + GObject* v_return; + + g_return_if_fail (return_value != NULL); + g_return_if_fail (n_param_values == 1); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_OBJECT__VOID) (marshal_data ? marshal_data : cc->callback); + + v_return = callback (data1, + data2); + + g_value_take_object (return_value, v_return); +} + +/* OBJECT:DOUBLE,DOUBLE (./gdkmarshalers.list:5) */ +void +_gdk_marshal_OBJECT__DOUBLE_DOUBLE (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef GObject* (*GMarshalFunc_OBJECT__DOUBLE_DOUBLE) (gpointer data1, + gdouble arg1, + gdouble arg2, + gpointer data2); + GCClosure *cc = (GCClosure *) closure; + gpointer data1, data2; + GMarshalFunc_OBJECT__DOUBLE_DOUBLE callback; + GObject* v_return; + + g_return_if_fail (return_value != NULL); + g_return_if_fail (n_param_values == 3); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_OBJECT__DOUBLE_DOUBLE) (marshal_data ? marshal_data : cc->callback); + + v_return = callback (data1, + g_marshal_value_peek_double (param_values + 1), + g_marshal_value_peek_double (param_values + 2), + data2); + + g_value_take_object (return_value, v_return); +} + +/* VOID:DOUBLE,DOUBLE,POINTER,POINTER (./gdkmarshalers.list:6) */ +void +_gdk_marshal_VOID__DOUBLE_DOUBLE_POINTER_POINTER (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) +{ + typedef void (*GMarshalFunc_VOID__DOUBLE_DOUBLE_POINTER_POINTER) (gpointer data1, + gdouble arg1, + gdouble arg2, + gpointer arg3, + gpointer arg4, + gpointer data2); + GCClosure *cc = (GCClosure *) closure; + gpointer data1, data2; + GMarshalFunc_VOID__DOUBLE_DOUBLE_POINTER_POINTER callback; + + g_return_if_fail (n_param_values == 5); + + if (G_CCLOSURE_SWAP_DATA (closure)) + { + data1 = closure->data; + data2 = g_value_peek_pointer (param_values + 0); + } + else + { + data1 = g_value_peek_pointer (param_values + 0); + data2 = closure->data; + } + callback = (GMarshalFunc_VOID__DOUBLE_DOUBLE_POINTER_POINTER) (marshal_data ? marshal_data : cc->callback); + + callback (data1, + g_marshal_value_peek_double (param_values + 1), + g_marshal_value_peek_double (param_values + 2), + g_marshal_value_peek_pointer (param_values + 3), + g_marshal_value_peek_pointer (param_values + 4), + data2); +} + diff --git a/libs/tk/ydk/gdkmedialib.c b/libs/tk/ydk/gdkmedialib.c new file mode 100644 index 0000000000..effb89dd85 --- /dev/null +++ b/libs/tk/ydk/gdkmedialib.c @@ -0,0 +1,120 @@ +/* GDK - The GIMP Drawing Kit + * Copyright (C) 2001-2007 Sun Microsystems, Inc. All rights reserved. + * (Brian Cameron, Dmitriy Demin, James Cheng, Padraig O'Briain) + * + * 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. + */ + +/* + * Modified by the GTK+ Team and others 1997-2007. 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 "config.h" + +#include +#include + +#ifdef HAVE_STRINGS_H +#include +#endif + +#ifdef HAVE_STRING_H +#include +#endif + +#if defined(HAVE_SYS_SYSTEMINFO_H) +#include +#elif defined(HAVE_SYS_SYSINFO_H) +#include +#endif + +#include "gdkmedialib.h" + +typedef char * (*ml_version) (void); + +static ml_version medialib_version = mlib_version; + +gboolean +_gdk_use_medialib (void) +{ + char *mlib_version_string; + char sys_info[257]; + long count; + + /* + * Sun mediaLib(tm) support. + * + * http://www.sun.com/processors/vis/mlib.html + * + */ + if (getenv ("GDK_DISABLE_MEDIALIB")) + return FALSE; + + /* + * The imaging functions we want to use were added in mediaLib version 2. + * So turn off mediaLib support if the user has an older version. + * mlib_version returns a string in this format: + * + * mediaLib:0210:20011101:v8plusa + * ^^^^^^^^ ^^^^ ^^^^^^^^ ^^^^^^^ + * libname vers build ISALIST identifier + * date (in this case sparcv8plus+vis) + * + * The first 2 digits of the version are the major version. The 3rd digit + * is the minor version, and the 4th digit is the micro version. So the + * above string corresponds to version 2.1.0.In the following test we only + * care about the major version. + */ + mlib_version_string = medialib_version (); + + count = sysinfo (SI_ARCHITECTURE, &sys_info[0], 257); + + if (count != -1) + { + if (strcmp (sys_info, "i386") == 0) + { + char *mlib_target_isa = &mlib_version_string[23]; + + /* + * For x86 processors mediaLib generic C implementation + * does not give any performance advantage so disable it. + */ + if (strncmp (mlib_target_isa, "sse", 3) != 0) + { + return FALSE; + } + + /* + * For x86 processors use of libumem conflicts with + * mediaLib, so avoid using it. + */ + if (dlsym (RTLD_PROBE, "umem_alloc") != NULL) + { + return FALSE; + } + } + } + else + { + /* Failed to get system architecture, disable mediaLib */ + return FALSE; + } + + return TRUE; +} diff --git a/libs/tk/ydk/gdkoffscreenwindow.c b/libs/tk/ydk/gdkoffscreenwindow.c new file mode 100644 index 0000000000..9ed5d45ef7 --- /dev/null +++ b/libs/tk/ydk/gdkoffscreenwindow.c @@ -0,0 +1,1308 @@ +/* GDK - The GIMP Drawing Kit + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GTK+ Team and others 1997-2005. 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 "gdk.h" +#include "gdkwindow.h" +#include "gdkinternals.h" +#include "gdkwindowimpl.h" +#include "gdkpixmap.h" +#include "gdkdrawable.h" +#include "gdktypes.h" +#include "gdkscreen.h" +#include "gdkgc.h" +#include "gdkcolor.h" +#include "gdkcursor.h" +#include "gdkalias.h" + +/* LIMITATIONS: + * + * Offscreen windows can't be the child of a foreign window, + * nor contain foreign windows + * GDK_POINTER_MOTION_HINT_MASK isn't effective + */ + +typedef struct _GdkOffscreenWindowClass GdkOffscreenWindowClass; + +struct _GdkOffscreenWindow +{ + GdkDrawable parent_instance; + + GdkWindow *wrapper; + GdkCursor *cursor; + GdkColormap *colormap; + GdkScreen *screen; + + GdkPixmap *pixmap; + GdkWindow *embedder; +}; + +struct _GdkOffscreenWindowClass +{ + GdkDrawableClass parent_class; +}; + +#define GDK_OFFSCREEN_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_OFFSCREEN_WINDOW, GdkOffscreenWindowClass)) +#define GDK_IS_OFFSCREEN_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_OFFSCREEN_WINDOW)) +#define GDK_OFFSCREEN_WINDOW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_OFFSCREEN_WINDOW, GdkOffscreenWindowClass)) + +static void gdk_offscreen_window_impl_iface_init (GdkWindowImplIface *iface); +static void gdk_offscreen_window_hide (GdkWindow *window); + +G_DEFINE_TYPE_WITH_CODE (GdkOffscreenWindow, + gdk_offscreen_window, + GDK_TYPE_DRAWABLE, + G_IMPLEMENT_INTERFACE (GDK_TYPE_WINDOW_IMPL, + gdk_offscreen_window_impl_iface_init)); + + +static void +gdk_offscreen_window_finalize (GObject *object) +{ + GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (object); + + if (offscreen->cursor) + gdk_cursor_unref (offscreen->cursor); + + offscreen->cursor = NULL; + + g_object_unref (offscreen->pixmap); + + G_OBJECT_CLASS (gdk_offscreen_window_parent_class)->finalize (object); +} + +static void +gdk_offscreen_window_init (GdkOffscreenWindow *window) +{ +} + +static void +gdk_offscreen_window_destroy (GdkWindow *window, + gboolean recursing, + gboolean foreign_destroy) +{ + GdkWindowObject *private = GDK_WINDOW_OBJECT (window); + GdkOffscreenWindow *offscreen; + + offscreen = GDK_OFFSCREEN_WINDOW (private->impl); + + gdk_offscreen_window_set_embedder (window, NULL); + + if (!recursing) + gdk_offscreen_window_hide (window); + + g_object_unref (offscreen->colormap); + offscreen->colormap = NULL; +} + +static gboolean +is_parent_of (GdkWindow *parent, + GdkWindow *child) +{ + GdkWindow *w; + + w = child; + while (w != NULL) + { + if (w == parent) + return TRUE; + + w = gdk_window_get_parent (w); + } + + return FALSE; +} + +static GdkGC * +gdk_offscreen_window_create_gc (GdkDrawable *drawable, + GdkGCValues *values, + GdkGCValuesMask values_mask) +{ + GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable); + + return gdk_gc_new_with_values (offscreen->pixmap, values, values_mask); +} + +static GdkImage* +gdk_offscreen_window_copy_to_image (GdkDrawable *drawable, + GdkImage *image, + gint src_x, + gint src_y, + gint dest_x, + gint dest_y, + gint width, + gint height) +{ + GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable); + + return gdk_drawable_copy_to_image (offscreen->pixmap, + image, + src_x, + src_y, + dest_x, dest_y, + width, height); +} + +static cairo_surface_t * +gdk_offscreen_window_ref_cairo_surface (GdkDrawable *drawable) +{ + GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable); + + return _gdk_drawable_ref_cairo_surface (offscreen->pixmap); +} + +static GdkColormap* +gdk_offscreen_window_get_colormap (GdkDrawable *drawable) +{ + GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable); + + return offscreen->colormap; +} + +static void +gdk_offscreen_window_set_colormap (GdkDrawable *drawable, + GdkColormap*colormap) +{ + GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable); + + if (colormap && GDK_WINDOW_DESTROYED (offscreen->wrapper)) + return; + + if (offscreen->colormap == colormap) + return; + + if (offscreen->colormap) + g_object_unref (offscreen->colormap); + + offscreen->colormap = colormap; + if (offscreen->colormap) + g_object_ref (offscreen->colormap); +} + + +static gint +gdk_offscreen_window_get_depth (GdkDrawable *drawable) +{ + GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable); + + return gdk_drawable_get_depth (offscreen->wrapper); +} + +static GdkDrawable * +gdk_offscreen_window_get_source_drawable (GdkDrawable *drawable) +{ + GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable); + + return _gdk_drawable_get_source_drawable (offscreen->pixmap); +} + +static GdkDrawable * +gdk_offscreen_window_get_composite_drawable (GdkDrawable *drawable, + gint x, + gint y, + gint width, + gint height, + gint *composite_x_offset, + gint *composite_y_offset) +{ + GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable); + + return g_object_ref (offscreen->pixmap); +} + +static GdkScreen* +gdk_offscreen_window_get_screen (GdkDrawable *drawable) +{ + GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable); + + return offscreen->screen; +} + +static GdkVisual* +gdk_offscreen_window_get_visual (GdkDrawable *drawable) +{ + GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable); + + return gdk_drawable_get_visual (offscreen->wrapper); +} + +static void +add_damage (GdkOffscreenWindow *offscreen, + int x, int y, + int w, int h, + gboolean is_line) +{ + GdkRectangle rect; + GdkRegion *damage; + + rect.x = x; + rect.y = y; + rect.width = w; + rect.height = h; + + if (is_line) + { + /* This should really take into account line width, line + * joins (and miter) and line caps. But these are hard + * to compute, rarely used and generally a pain. And in + * the end a snug damage rectangle is not that important + * as multiple damages are generally created anyway. + * + * So, we just add some padding around the rect. + * We use a padding of 3 pixels, plus an extra row + * below and on the right for the normal line size. I.E. + * line from (0,0) to (2,0) gets h=0 but is really + * at least one pixel tall. + */ + rect.x -= 3; + rect.y -= 3; + rect.width += 7; + rect.height += 7; + } + + damage = gdk_region_rectangle (&rect); + _gdk_window_add_damage (offscreen->wrapper, damage); + gdk_region_destroy (damage); +} + +static GdkDrawable * +get_real_drawable (GdkOffscreenWindow *offscreen) +{ + GdkPixmapObject *pixmap; + pixmap = (GdkPixmapObject *) offscreen->pixmap; + return GDK_DRAWABLE (pixmap->impl); +} + +static void +gdk_offscreen_window_draw_drawable (GdkDrawable *drawable, + GdkGC *gc, + GdkPixmap *src, + gint xsrc, + gint ysrc, + gint xdest, + gint ydest, + gint width, + gint height, + GdkDrawable *original_src) +{ + GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable); + GdkDrawable *real_drawable = get_real_drawable (offscreen); + + gdk_draw_drawable (real_drawable, gc, + src, xsrc, ysrc, + xdest, ydest, + width, height); + + add_damage (offscreen, xdest, ydest, width, height, FALSE); +} + +static void +gdk_offscreen_window_draw_rectangle (GdkDrawable *drawable, + GdkGC *gc, + gboolean filled, + gint x, + gint y, + gint width, + gint height) +{ + GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable); + GdkDrawable *real_drawable = get_real_drawable (offscreen); + + gdk_draw_rectangle (real_drawable, + gc, filled, x, y, width, height); + + add_damage (offscreen, x, y, width, height, !filled); + +} + +static void +gdk_offscreen_window_draw_arc (GdkDrawable *drawable, + GdkGC *gc, + gboolean filled, + gint x, + gint y, + gint width, + gint height, + gint angle1, + gint angle2) +{ + GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable); + GdkDrawable *real_drawable = get_real_drawable (offscreen); + + gdk_draw_arc (real_drawable, + gc, + filled, + x, + y, + width, + height, + angle1, + angle2); + add_damage (offscreen, x, y, width, height, !filled); +} + +static void +gdk_offscreen_window_draw_polygon (GdkDrawable *drawable, + GdkGC *gc, + gboolean filled, + GdkPoint *points, + gint npoints) +{ + GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable); + GdkDrawable *real_drawable = get_real_drawable (offscreen); + + gdk_draw_polygon (real_drawable, + gc, + filled, + points, + npoints); + + if (npoints > 0) + { + int min_x, min_y, max_x, max_y, i; + + min_x = max_x = points[0].x; + min_y = max_y = points[0].y; + + for (i = 1; i < npoints; i++) + { + min_x = MIN (min_x, points[i].x); + max_x = MAX (max_x, points[i].x); + min_y = MIN (min_y, points[i].y); + max_y = MAX (max_y, points[i].y); + } + + add_damage (offscreen, min_x, min_y, + max_x - min_x, + max_y - min_y, !filled); + } +} + +static void +gdk_offscreen_window_draw_text (GdkDrawable *drawable, + GdkFont *font, + GdkGC *gc, + gint x, + gint y, + const gchar *text, + gint text_length) +{ + GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable); + GdkDrawable *real_drawable = get_real_drawable (offscreen); + GdkWindowObject *private = GDK_WINDOW_OBJECT (offscreen->wrapper); + + gdk_draw_text (real_drawable, + font, + gc, + x, + y, + text, + text_length); + + /* Hard to compute the minimal size, not that often used anyway. */ + add_damage (offscreen, 0, 0, private->width, private->height, FALSE); +} + +static void +gdk_offscreen_window_draw_text_wc (GdkDrawable *drawable, + GdkFont *font, + GdkGC *gc, + gint x, + gint y, + const GdkWChar *text, + gint text_length) +{ + GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable); + GdkDrawable *real_drawable = get_real_drawable (offscreen); + GdkWindowObject *private = GDK_WINDOW_OBJECT (offscreen->wrapper); + + gdk_draw_text_wc (real_drawable, + font, + gc, + x, + y, + text, + text_length); + + /* Hard to compute the minimal size, not that often used anyway. */ + add_damage (offscreen, 0, 0, private->width, private->height, FALSE); +} + +static void +gdk_offscreen_window_draw_points (GdkDrawable *drawable, + GdkGC *gc, + GdkPoint *points, + gint npoints) +{ + GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable); + GdkDrawable *real_drawable = get_real_drawable (offscreen); + + gdk_draw_points (real_drawable, + gc, + points, + npoints); + + + if (npoints > 0) + { + int min_x, min_y, max_x, max_y, i; + + min_x = max_x = points[0].x; + min_y = max_y = points[0].y; + + for (i = 1; i < npoints; i++) + { + min_x = MIN (min_x, points[i].x); + max_x = MAX (max_x, points[i].x); + min_y = MIN (min_y, points[i].y); + max_y = MAX (max_y, points[i].y); + } + + add_damage (offscreen, min_x, min_y, + max_x - min_x + 1, + max_y - min_y + 1, + FALSE); + } +} + +static void +gdk_offscreen_window_draw_segments (GdkDrawable *drawable, + GdkGC *gc, + GdkSegment *segs, + gint nsegs) +{ + GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable); + GdkDrawable *real_drawable = get_real_drawable (offscreen); + + gdk_draw_segments (real_drawable, + gc, + segs, + nsegs); + + if (nsegs > 0) + { + int min_x, min_y, max_x, max_y, i; + + min_x = max_x = segs[0].x1; + min_y = max_y = segs[0].y1; + + for (i = 0; i < nsegs; i++) + { + min_x = MIN (min_x, segs[i].x1); + max_x = MAX (max_x, segs[i].x1); + min_x = MIN (min_x, segs[i].x2); + max_x = MAX (max_x, segs[i].x2); + min_y = MIN (min_y, segs[i].y1); + max_y = MAX (max_y, segs[i].y1); + min_y = MIN (min_y, segs[i].y2); + max_y = MAX (max_y, segs[i].y2); + } + + add_damage (offscreen, min_x, min_y, + max_x - min_x, + max_y - min_y, TRUE); + } + +} + +static void +gdk_offscreen_window_draw_lines (GdkDrawable *drawable, + GdkGC *gc, + GdkPoint *points, + gint npoints) +{ + GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable); + GdkDrawable *real_drawable = get_real_drawable (offscreen); + GdkWindowObject *private = GDK_WINDOW_OBJECT (offscreen->wrapper); + + gdk_draw_lines (real_drawable, + gc, + points, + npoints); + + /* Hard to compute the minimal size, as we don't know the line + width, and since joins are hard to calculate. + Its not that often used anyway, damage it all */ + add_damage (offscreen, 0, 0, private->width, private->height, TRUE); +} + +static void +gdk_offscreen_window_draw_image (GdkDrawable *drawable, + GdkGC *gc, + GdkImage *image, + gint xsrc, + gint ysrc, + gint xdest, + gint ydest, + gint width, + gint height) +{ + GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable); + GdkDrawable *real_drawable = get_real_drawable (offscreen); + + gdk_draw_image (real_drawable, + gc, + image, + xsrc, + ysrc, + xdest, + ydest, + width, + height); + + add_damage (offscreen, xdest, ydest, width, height, FALSE); +} + + +static void +gdk_offscreen_window_draw_pixbuf (GdkDrawable *drawable, + GdkGC *gc, + GdkPixbuf *pixbuf, + gint src_x, + gint src_y, + gint dest_x, + gint dest_y, + gint width, + gint height, + GdkRgbDither dither, + gint x_dither, + gint y_dither) +{ + GdkOffscreenWindow *offscreen = GDK_OFFSCREEN_WINDOW (drawable); + GdkDrawable *real_drawable = get_real_drawable (offscreen); + + gdk_draw_pixbuf (real_drawable, + gc, + pixbuf, + src_x, + src_y, + dest_x, + dest_y, + width, + height, + dither, + x_dither, + y_dither); + + add_damage (offscreen, dest_x, dest_y, width, height, FALSE); + +} + +void +_gdk_offscreen_window_new (GdkWindow *window, + GdkScreen *screen, + GdkVisual *visual, + GdkWindowAttr *attributes, + gint attributes_mask) +{ + GdkWindowObject *private; + GdkOffscreenWindow *offscreen; + + g_return_if_fail (attributes != NULL); + + if (attributes->wclass != GDK_INPUT_OUTPUT) + return; /* Can't support input only offscreens */ + + private = (GdkWindowObject *)window; + + if (private->parent != NULL && GDK_WINDOW_DESTROYED (private->parent)) + return; + + private->impl = g_object_new (GDK_TYPE_OFFSCREEN_WINDOW, NULL); + offscreen = GDK_OFFSCREEN_WINDOW (private->impl); + offscreen->wrapper = window; + + offscreen->screen = screen; + + if (attributes_mask & GDK_WA_COLORMAP) + offscreen->colormap = g_object_ref (attributes->colormap); + else + { + if (gdk_screen_get_system_visual (screen) == visual) + { + offscreen->colormap = gdk_screen_get_system_colormap (screen); + g_object_ref (offscreen->colormap); + } + else + offscreen->colormap = gdk_colormap_new (visual, FALSE); + } + + offscreen->pixmap = gdk_pixmap_new ((GdkDrawable *)private->parent, + private->width, + private->height, + private->depth); + gdk_drawable_set_colormap (offscreen->pixmap, offscreen->colormap); +} + +static gboolean +gdk_offscreen_window_reparent (GdkWindow *window, + GdkWindow *new_parent, + gint x, + gint y) +{ + GdkWindowObject *private = (GdkWindowObject *)window; + GdkWindowObject *new_parent_private = (GdkWindowObject *)new_parent; + GdkWindowObject *old_parent; + gboolean was_mapped; + + if (new_parent) + { + /* No input-output children of input-only windows */ + if (new_parent_private->input_only && !private->input_only) + return FALSE; + + /* Don't create loops in hierarchy */ + if (is_parent_of (window, new_parent)) + return FALSE; + } + + was_mapped = GDK_WINDOW_IS_MAPPED (window); + + gdk_window_hide (window); + + if (private->parent) + private->parent->children = g_list_remove (private->parent->children, window); + + old_parent = private->parent; + private->parent = new_parent_private; + private->x = x; + private->y = y; + + if (new_parent_private) + private->parent->children = g_list_prepend (private->parent->children, window); + + _gdk_synthesize_crossing_events_for_geometry_change (window); + if (old_parent) + _gdk_synthesize_crossing_events_for_geometry_change (GDK_WINDOW (old_parent)); + + return was_mapped; +} + +static void +from_embedder (GdkWindow *window, + double embedder_x, double embedder_y, + double *offscreen_x, double *offscreen_y) +{ + GdkWindowObject *private; + + private = (GdkWindowObject *)window; + + g_signal_emit_by_name (private->impl_window, + "from-embedder", + embedder_x, embedder_y, + offscreen_x, offscreen_y, + NULL); +} + +static void +to_embedder (GdkWindow *window, + double offscreen_x, double offscreen_y, + double *embedder_x, double *embedder_y) +{ + GdkWindowObject *private; + + private = (GdkWindowObject *)window; + + g_signal_emit_by_name (private->impl_window, + "to-embedder", + offscreen_x, offscreen_y, + embedder_x, embedder_y, + NULL); +} + +static gint +gdk_offscreen_window_get_root_coords (GdkWindow *window, + gint x, + gint y, + gint *root_x, + gint *root_y) +{ + GdkWindowObject *private = GDK_WINDOW_OBJECT (window); + GdkOffscreenWindow *offscreen; + int tmpx, tmpy; + + tmpx = x; + tmpy = y; + + offscreen = GDK_OFFSCREEN_WINDOW (private->impl); + if (offscreen->embedder) + { + double dx, dy; + to_embedder (window, + x, y, + &dx, &dy); + tmpx = floor (dx + 0.5); + tmpy = floor (dy + 0.5); + gdk_window_get_root_coords (offscreen->embedder, + tmpx, tmpy, + &tmpx, &tmpy); + + } + + if (root_x) + *root_x = tmpx; + if (root_y) + *root_y = tmpy; + + return TRUE; +} + +static gint +gdk_offscreen_window_get_deskrelative_origin (GdkWindow *window, + gint *x, + gint *y) +{ + GdkWindowObject *private = GDK_WINDOW_OBJECT (window); + GdkOffscreenWindow *offscreen; + int tmpx, tmpy; + + tmpx = 0; + tmpy = 0; + + offscreen = GDK_OFFSCREEN_WINDOW (private->impl); + if (offscreen->embedder) + { + double dx, dy; + gdk_window_get_deskrelative_origin (offscreen->embedder, + &tmpx, &tmpy); + + to_embedder (window, + 0, 0, + &dx, &dy); + tmpx = floor (tmpx + dx + 0.5); + tmpy = floor (tmpy + dy + 0.5); + } + + + if (x) + *x = tmpx; + if (y) + *y = tmpy; + + return TRUE; +} + +static gboolean +gdk_offscreen_window_get_pointer (GdkWindow *window, + gint *x, + gint *y, + GdkModifierType *mask) +{ + GdkWindowObject *private = GDK_WINDOW_OBJECT (window); + GdkOffscreenWindow *offscreen; + int tmpx, tmpy; + double dtmpx, dtmpy; + GdkModifierType tmpmask; + + tmpx = 0; + tmpy = 0; + tmpmask = 0; + + offscreen = GDK_OFFSCREEN_WINDOW (private->impl); + if (offscreen->embedder != NULL) + { + gdk_window_get_pointer (offscreen->embedder, &tmpx, &tmpy, &tmpmask); + from_embedder (window, + tmpx, tmpy, + &dtmpx, &dtmpy); + tmpx = floor (dtmpx + 0.5); + tmpy = floor (dtmpy + 0.5); + } + + if (x) + *x = tmpx; + if (y) + *y = tmpy; + if (mask) + *mask = tmpmask; + return TRUE; +} + +GdkDrawable * +_gdk_offscreen_window_get_real_drawable (GdkOffscreenWindow *offscreen) +{ + return get_real_drawable (offscreen); +} + +/** + * gdk_offscreen_window_get_pixmap: + * @window: a #GdkWindow + * + * Gets the offscreen pixmap that an offscreen window renders into. + * If you need to keep this around over window resizes, you need to + * add a reference to it. + * + * Returns: The offscreen pixmap, or %NULL if not offscreen + * + * Since: 2.18 + */ +GdkPixmap * +gdk_offscreen_window_get_pixmap (GdkWindow *window) +{ + GdkWindowObject *private = (GdkWindowObject *)window; + GdkOffscreenWindow *offscreen; + + g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE); + + if (!GDK_IS_OFFSCREEN_WINDOW (private->impl)) + return NULL; + + offscreen = GDK_OFFSCREEN_WINDOW (private->impl); + return offscreen->pixmap; +} + +static void +gdk_offscreen_window_raise (GdkWindow *window) +{ + /* gdk_window_raise already changed the stacking order */ + _gdk_synthesize_crossing_events_for_geometry_change (window); +} + +static void +gdk_offscreen_window_lower (GdkWindow *window) +{ + /* gdk_window_lower already changed the stacking order */ + _gdk_synthesize_crossing_events_for_geometry_change (window); +} + +static void +gdk_offscreen_window_move_resize_internal (GdkWindow *window, + gint x, + gint y, + gint width, + gint height, + gboolean send_expose_events) +{ + GdkWindowObject *private = (GdkWindowObject *)window; + GdkOffscreenWindow *offscreen; + gint dx, dy, dw, dh; + GdkGC *gc; + GdkPixmap *old_pixmap; + + offscreen = GDK_OFFSCREEN_WINDOW (private->impl); + + if (width < 1) + width = 1; + if (height < 1) + height = 1; + + if (private->destroyed) + return; + + dx = x - private->x; + dy = y - private->y; + dw = width - private->width; + dh = height - private->height; + + private->x = x; + private->y = y; + + if (private->width != width || + private->height != height) + { + private->width = width; + private->height = height; + + old_pixmap = offscreen->pixmap; + offscreen->pixmap = gdk_pixmap_new (GDK_DRAWABLE (old_pixmap), + width, + height, + private->depth); + + gc = _gdk_drawable_get_scratch_gc (offscreen->pixmap, FALSE); + gdk_draw_drawable (offscreen->pixmap, + gc, + old_pixmap, + 0,0, 0, 0, + -1, -1); + g_object_unref (old_pixmap); + } + + if (GDK_WINDOW_IS_MAPPED (private)) + { + // TODO: Only invalidate new area, i.e. for larger windows + gdk_window_invalidate_rect (window, NULL, TRUE); + _gdk_synthesize_crossing_events_for_geometry_change (window); + } +} + +static void +gdk_offscreen_window_move_resize (GdkWindow *window, + gboolean with_move, + gint x, + gint y, + gint width, + gint height) +{ + GdkWindowObject *private = (GdkWindowObject *)window; + GdkOffscreenWindow *offscreen; + + offscreen = GDK_OFFSCREEN_WINDOW (private->impl); + + if (!with_move) + { + x = private->x; + y = private->y; + } + + if (width < 0) + width = private->width; + + if (height < 0) + height = private->height; + + gdk_offscreen_window_move_resize_internal (window, x, y, + width, height, + TRUE); +} + +static void +gdk_offscreen_window_show (GdkWindow *window, + gboolean already_mapped) +{ + GdkWindowObject *private = (GdkWindowObject *)window; + + gdk_window_clear_area_e (window, 0, 0, + private->width, private->height); +} + + +static void +gdk_offscreen_window_hide (GdkWindow *window) +{ + GdkWindowObject *private; + GdkOffscreenWindow *offscreen; + GdkDisplay *display; + + g_return_if_fail (window != NULL); + + private = (GdkWindowObject*) window; + offscreen = GDK_OFFSCREEN_WINDOW (private->impl); + + /* May need to break grabs on children */ + display = gdk_drawable_get_display (window); + + /* TODO: This needs updating to the new grab world */ +#if 0 + if (display->pointer_grab.window != NULL) + { + if (is_parent_of (window, display->pointer_grab.window)) + { + /* Call this ourselves, even though gdk_display_pointer_ungrab + does so too, since we want to pass implicit == TRUE so the + broken grab event is generated */ + _gdk_display_unset_has_pointer_grab (display, + TRUE, + FALSE, + GDK_CURRENT_TIME); + gdk_display_pointer_ungrab (display, GDK_CURRENT_TIME); + } + } +#endif +} + +static void +gdk_offscreen_window_withdraw (GdkWindow *window) +{ +} + +static GdkEventMask +gdk_offscreen_window_get_events (GdkWindow *window) +{ + return 0; +} + +static void +gdk_offscreen_window_set_events (GdkWindow *window, + GdkEventMask event_mask) +{ +} + +static void +gdk_offscreen_window_set_background (GdkWindow *window, + const GdkColor *color) +{ + GdkWindowObject *private = (GdkWindowObject *)window; + GdkColormap *colormap = gdk_drawable_get_colormap (window); + + private->bg_color = *color; + gdk_colormap_query_color (colormap, private->bg_color.pixel, &private->bg_color); + + if (private->bg_pixmap && + private->bg_pixmap != GDK_PARENT_RELATIVE_BG && + private->bg_pixmap != GDK_NO_BG) + g_object_unref (private->bg_pixmap); + + private->bg_pixmap = NULL; +} + +static void +gdk_offscreen_window_set_back_pixmap (GdkWindow *window, + GdkPixmap *pixmap) +{ + GdkWindowObject *private = (GdkWindowObject *)window; + + if (pixmap && + private->bg_pixmap != GDK_PARENT_RELATIVE_BG && + private->bg_pixmap != GDK_NO_BG && + !gdk_drawable_get_colormap (pixmap)) + { + g_warning ("gdk_window_set_back_pixmap(): pixmap must have a colormap"); + return; + } + + if (private->bg_pixmap && + private->bg_pixmap != GDK_PARENT_RELATIVE_BG && + private->bg_pixmap != GDK_NO_BG) + g_object_unref (private->bg_pixmap); + + private->bg_pixmap = pixmap; + + if (pixmap && + private->bg_pixmap != GDK_PARENT_RELATIVE_BG && + private->bg_pixmap != GDK_NO_BG) + g_object_ref (pixmap); +} + +static void +gdk_offscreen_window_shape_combine_region (GdkWindow *window, + const GdkRegion *shape_region, + gint offset_x, + gint offset_y) +{ +} + +static void +gdk_offscreen_window_input_shape_combine_region (GdkWindow *window, + const GdkRegion *shape_region, + gint offset_x, + gint offset_y) +{ +} + +static gboolean +gdk_offscreen_window_set_static_gravities (GdkWindow *window, + gboolean use_static) +{ + return TRUE; +} + +static void +gdk_offscreen_window_set_cursor (GdkWindow *window, + GdkCursor *cursor) +{ + GdkWindowObject *private = (GdkWindowObject *)window; + GdkOffscreenWindow *offscreen; + + offscreen = GDK_OFFSCREEN_WINDOW (private->impl); + + if (offscreen->cursor) + { + gdk_cursor_unref (offscreen->cursor); + offscreen->cursor = NULL; + } + + if (cursor) + offscreen->cursor = gdk_cursor_ref (cursor); + + /* TODO: The cursor is never actually used... */ +} + +static void +gdk_offscreen_window_get_geometry (GdkWindow *window, + gint *x, + gint *y, + gint *width, + gint *height, + gint *depth) +{ + GdkWindowObject *private = (GdkWindowObject *)window; + + g_return_if_fail (window == NULL || GDK_IS_WINDOW (window)); + + if (!GDK_WINDOW_DESTROYED (window)) + { + if (x) + *x = private->x; + if (y) + *y = private->y; + if (width) + *width = private->width; + if (height) + *height = private->height; + if (depth) + *depth = private->depth; + } +} + +static gboolean +gdk_offscreen_window_queue_antiexpose (GdkWindow *window, + GdkRegion *area) +{ + return FALSE; +} + +static void +gdk_offscreen_window_queue_translation (GdkWindow *window, + GdkGC *gc, + GdkRegion *area, + gint dx, + gint dy) +{ +} + +/** + * gdk_offscreen_window_set_embedder: + * @window: a #GdkWindow + * @embedder: the #GdkWindow that @window gets embedded in + * + * Sets @window to be embedded in @embedder. + * + * To fully embed an offscreen window, in addition to calling this + * function, it is also necessary to handle the #GdkWindow::pick-embedded-child + * signal on the @embedder and the #GdkWindow::to-embedder and + * #GdkWindow::from-embedder signals on @window. + * + * Since: 2.18 + */ +void +gdk_offscreen_window_set_embedder (GdkWindow *window, + GdkWindow *embedder) +{ + GdkWindowObject *private = (GdkWindowObject *)window; + GdkOffscreenWindow *offscreen; + + g_return_if_fail (GDK_IS_WINDOW (window)); + + if (!GDK_IS_OFFSCREEN_WINDOW (private->impl)) + return; + + offscreen = GDK_OFFSCREEN_WINDOW (private->impl); + + if (embedder) + { + g_object_ref (embedder); + GDK_WINDOW_OBJECT (embedder)->num_offscreen_children++; + } + + if (offscreen->embedder) + { + g_object_unref (offscreen->embedder); + GDK_WINDOW_OBJECT (offscreen->embedder)->num_offscreen_children--; + } + + offscreen->embedder = embedder; +} + +/** + * gdk_offscreen_window_get_embedder: + * @window: a #GdkWindow + * + * Gets the window that @window is embedded in. + * + * Returns: the embedding #GdkWindow, or %NULL if @window is not an + * embedded offscreen window + * + * Since: 2.18 + */ +GdkWindow * +gdk_offscreen_window_get_embedder (GdkWindow *window) +{ + GdkWindowObject *private = (GdkWindowObject *)window; + GdkOffscreenWindow *offscreen; + + g_return_val_if_fail (GDK_IS_WINDOW (window), NULL); + + if (!GDK_IS_OFFSCREEN_WINDOW (private->impl)) + return NULL; + + offscreen = GDK_OFFSCREEN_WINDOW (private->impl); + + return offscreen->embedder; +} + +static void +gdk_offscreen_window_class_init (GdkOffscreenWindowClass *klass) +{ + GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = gdk_offscreen_window_finalize; + + drawable_class->create_gc = gdk_offscreen_window_create_gc; + drawable_class->_copy_to_image = gdk_offscreen_window_copy_to_image; + drawable_class->ref_cairo_surface = gdk_offscreen_window_ref_cairo_surface; + drawable_class->set_colormap = gdk_offscreen_window_set_colormap; + drawable_class->get_colormap = gdk_offscreen_window_get_colormap; + drawable_class->get_depth = gdk_offscreen_window_get_depth; + drawable_class->get_screen = gdk_offscreen_window_get_screen; + drawable_class->get_visual = gdk_offscreen_window_get_visual; + drawable_class->get_source_drawable = gdk_offscreen_window_get_source_drawable; + drawable_class->get_composite_drawable = gdk_offscreen_window_get_composite_drawable; + + drawable_class->draw_rectangle = gdk_offscreen_window_draw_rectangle; + drawable_class->draw_arc = gdk_offscreen_window_draw_arc; + drawable_class->draw_polygon = gdk_offscreen_window_draw_polygon; + drawable_class->draw_text = gdk_offscreen_window_draw_text; + drawable_class->draw_text_wc = gdk_offscreen_window_draw_text_wc; + drawable_class->draw_drawable_with_src = gdk_offscreen_window_draw_drawable; + drawable_class->draw_points = gdk_offscreen_window_draw_points; + drawable_class->draw_segments = gdk_offscreen_window_draw_segments; + drawable_class->draw_lines = gdk_offscreen_window_draw_lines; + drawable_class->draw_image = gdk_offscreen_window_draw_image; + drawable_class->draw_pixbuf = gdk_offscreen_window_draw_pixbuf; +} + +static void +gdk_offscreen_window_impl_iface_init (GdkWindowImplIface *iface) +{ + iface->show = gdk_offscreen_window_show; + iface->hide = gdk_offscreen_window_hide; + iface->withdraw = gdk_offscreen_window_withdraw; + iface->raise = gdk_offscreen_window_raise; + iface->lower = gdk_offscreen_window_lower; + iface->move_resize = gdk_offscreen_window_move_resize; + iface->set_background = gdk_offscreen_window_set_background; + iface->set_back_pixmap = gdk_offscreen_window_set_back_pixmap; + iface->get_events = gdk_offscreen_window_get_events; + iface->set_events = gdk_offscreen_window_set_events; + iface->reparent = gdk_offscreen_window_reparent; + iface->set_cursor = gdk_offscreen_window_set_cursor; + iface->get_geometry = gdk_offscreen_window_get_geometry; + iface->shape_combine_region = gdk_offscreen_window_shape_combine_region; + iface->input_shape_combine_region = gdk_offscreen_window_input_shape_combine_region; + iface->set_static_gravities = gdk_offscreen_window_set_static_gravities; + iface->queue_antiexpose = gdk_offscreen_window_queue_antiexpose; + iface->queue_translation = gdk_offscreen_window_queue_translation; + iface->get_root_coords = gdk_offscreen_window_get_root_coords; + iface->get_deskrelative_origin = gdk_offscreen_window_get_deskrelative_origin; + iface->get_pointer = gdk_offscreen_window_get_pointer; + iface->destroy = gdk_offscreen_window_destroy; +} + +#define __GDK_OFFSCREEN_WINDOW_C__ +#include "gdkaliasdef.c" diff --git a/libs/tk/ydk/gdkpango.c b/libs/tk/ydk/gdkpango.c new file mode 100644 index 0000000000..6407ab2501 --- /dev/null +++ b/libs/tk/ydk/gdkpango.c @@ -0,0 +1,1500 @@ +/* GDK - The GIMP Drawing Kit + * Copyright (C) 2000 Red Hat, 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. + */ + +#include "config.h" +#include +#include +#include "gdkcairo.h" +#include "gdkcolor.h" +#include "gdkgc.h" +#include "gdkinternals.h" +#include "gdkpango.h" +#include "gdkrgb.h" +#include "gdkprivate.h" +#include "gdkscreen.h" +#include "gdkintl.h" +#include "gdkalias.h" + +#define GDK_INFO_KEY "gdk-info" + +/* We have various arrays indexed by render part; if PangoRenderPart + * is extended, we want to make sure not to overwrite the end of + * those arrays. + */ +#define MAX_RENDER_PART PANGO_RENDER_PART_STRIKETHROUGH + +struct _GdkPangoRendererPrivate +{ + GdkScreen *screen; + + /* GdkPangoRenderer specific state */ + PangoColor override_color[MAX_RENDER_PART + 1]; + gboolean override_color_set[MAX_RENDER_PART + 1]; + + GdkBitmap *stipple[MAX_RENDER_PART + 1]; + PangoColor emboss_color; + gboolean embossed; + + cairo_t *cr; + PangoRenderPart last_part; + + /* Current target */ + GdkDrawable *drawable; + GdkGC *base_gc; + + gboolean gc_changed; +}; + +static PangoAttrType gdk_pango_attr_stipple_type; +static PangoAttrType gdk_pango_attr_embossed_type; +static PangoAttrType gdk_pango_attr_emboss_color_type; + +enum { + PROP_0, + PROP_SCREEN +}; + +G_DEFINE_TYPE (GdkPangoRenderer, gdk_pango_renderer, PANGO_TYPE_RENDERER) + +static void +gdk_pango_renderer_finalize (GObject *object) +{ + GdkPangoRenderer *gdk_renderer = GDK_PANGO_RENDERER (object); + GdkPangoRendererPrivate *priv = gdk_renderer->priv; + int i; + + if (priv->base_gc) + g_object_unref (priv->base_gc); + if (priv->drawable) + g_object_unref (priv->drawable); + + for (i = 0; i <= MAX_RENDER_PART; i++) + if (priv->stipple[i]) + g_object_unref (priv->stipple[i]); + + G_OBJECT_CLASS (gdk_pango_renderer_parent_class)->finalize (object); +} + +static GObject* +gdk_pango_renderer_constructor (GType type, + guint n_construct_properties, + GObjectConstructParam *construct_params) +{ + GObject *object; + GdkPangoRenderer *gdk_renderer; + + object = G_OBJECT_CLASS (gdk_pango_renderer_parent_class)->constructor (type, + n_construct_properties, + construct_params); + + gdk_renderer = GDK_PANGO_RENDERER (object); + + if (!gdk_renderer->priv->screen) + { + g_warning ("Screen must be specified at construct time for GdkPangoRenderer"); + gdk_renderer->priv->screen = gdk_screen_get_default (); + } + + return object; +} + +/* Adjusts matrix and color for the renderer to draw the secondary + * "shadow" copy for embossed text */ +static void +emboss_context (GdkPangoRenderer *renderer, cairo_t *cr) +{ + GdkPangoRendererPrivate *priv = renderer->priv; + cairo_matrix_t tmp_matrix; + double red, green, blue; + + /* The gymnastics here to adjust the matrix are because we want + * to offset by +1,+1 in device-space, not in user-space, + * so we can't just draw the layout at x + 1, y + 1 + */ + cairo_get_matrix (cr, &tmp_matrix); + tmp_matrix.x0 += 1.0; + tmp_matrix.y0 += 1.0; + cairo_set_matrix (cr, &tmp_matrix); + + red = (double) priv->emboss_color.red / 65535.; + green = (double) priv->emboss_color.green / 65535.; + blue = (double) priv->emboss_color.blue / 65535.; + + cairo_set_source_rgb (cr, red, green, blue); +} + +static inline gboolean +color_equal (const PangoColor *c1, const PangoColor *c2) +{ + if (!c1 && !c2) + return TRUE; + + if (c1 && c2 && + c1->red == c2->red && + c1->green == c2->green && + c1->blue == c2->blue) + return TRUE; + + return FALSE; +} + +static cairo_t * +get_cairo_context (GdkPangoRenderer *gdk_renderer, + PangoRenderPart part) +{ + PangoRenderer *renderer = PANGO_RENDERER (gdk_renderer); + GdkPangoRendererPrivate *priv = gdk_renderer->priv; + + if (!priv->cr) + { + const PangoMatrix *matrix; + + priv->cr = gdk_cairo_create (priv->drawable); + + matrix = pango_renderer_get_matrix (renderer); + if (matrix) + { + cairo_matrix_t cairo_matrix; + + cairo_matrix_init (&cairo_matrix, + matrix->xx, matrix->yx, + matrix->xy, matrix->yy, + matrix->x0, matrix->y0); + cairo_set_matrix (priv->cr, &cairo_matrix); + } + } + + if (part != priv->last_part) + { + PangoColor *pango_color; + GdkColor *color; + GdkColor tmp_color; + gboolean changed; + + pango_color = pango_renderer_get_color (renderer, part); + + if (priv->last_part != -1) + changed = priv->gc_changed || + priv->stipple[priv->last_part] != priv->stipple[part] || + !color_equal (pango_color, + pango_renderer_get_color (renderer, priv->last_part)); + else + changed = TRUE; + + if (changed) + { + if (pango_color) + { + tmp_color.red = pango_color->red; + tmp_color.green = pango_color->green; + tmp_color.blue = pango_color->blue; + + color = &tmp_color; + } + else + color = NULL; + + _gdk_gc_update_context (priv->base_gc, + priv->cr, + color, + priv->stipple[part], + priv->gc_changed, + priv->drawable); + } + + priv->last_part = part; + priv->gc_changed = FALSE; + } + + return priv->cr; +} + +static void +gdk_pango_renderer_draw_glyphs (PangoRenderer *renderer, + PangoFont *font, + PangoGlyphString *glyphs, + int x, + int y) +{ + GdkPangoRenderer *gdk_renderer = GDK_PANGO_RENDERER (renderer); + GdkPangoRendererPrivate *priv = gdk_renderer->priv; + cairo_t *cr; + + cr = get_cairo_context (gdk_renderer, + PANGO_RENDER_PART_FOREGROUND); + + if (priv->embossed) + { + cairo_save (cr); + emboss_context (gdk_renderer, cr); + cairo_move_to (cr, (double)x / PANGO_SCALE, (double)y / PANGO_SCALE); + pango_cairo_show_glyph_string (cr, font, glyphs); + cairo_restore (cr); + } + + cairo_move_to (cr, (double)x / PANGO_SCALE, (double)y / PANGO_SCALE); + pango_cairo_show_glyph_string (cr, font, glyphs); +} + +static void +gdk_pango_renderer_draw_rectangle (PangoRenderer *renderer, + PangoRenderPart part, + int x, + int y, + int width, + int height) +{ + GdkPangoRenderer *gdk_renderer = GDK_PANGO_RENDERER (renderer); + GdkPangoRendererPrivate *priv = gdk_renderer->priv; + cairo_t *cr; + + cr = get_cairo_context (gdk_renderer, part); + + if (priv->embossed && part != PANGO_RENDER_PART_BACKGROUND) + { + cairo_save (cr); + emboss_context (gdk_renderer, cr); + cairo_rectangle (cr, + (double)x / PANGO_SCALE, (double)y / PANGO_SCALE, + (double)width / PANGO_SCALE, (double)height / PANGO_SCALE); + + cairo_fill (cr); + cairo_restore (cr); + } + + cairo_rectangle (cr, + (double)x / PANGO_SCALE, (double)y / PANGO_SCALE, + (double)width / PANGO_SCALE, (double)height / PANGO_SCALE); + cairo_fill (cr); +} + +static void +gdk_pango_renderer_draw_error_underline (PangoRenderer *renderer, + int x, + int y, + int width, + int height) +{ + GdkPangoRenderer *gdk_renderer = GDK_PANGO_RENDERER (renderer); + GdkPangoRendererPrivate *priv = gdk_renderer->priv; + cairo_t *cr; + + cr = get_cairo_context (gdk_renderer, PANGO_RENDER_PART_UNDERLINE); + + if (priv->embossed) + { + cairo_save (cr); + emboss_context (gdk_renderer, cr); + pango_cairo_show_error_underline (cr, + (double)x / PANGO_SCALE, (double)y / PANGO_SCALE, + (double)width / PANGO_SCALE, (double)height / PANGO_SCALE); + cairo_restore (cr); + } + + pango_cairo_show_error_underline (cr, + (double)x / PANGO_SCALE, (double)y / PANGO_SCALE, + (double)width / PANGO_SCALE, (double)height / PANGO_SCALE); +} + +static void +gdk_pango_renderer_draw_shape (PangoRenderer *renderer, + PangoAttrShape *attr, + int x, + int y) +{ + GdkPangoRenderer *gdk_renderer = GDK_PANGO_RENDERER (renderer); + GdkPangoRendererPrivate *priv = gdk_renderer->priv; + PangoLayout *layout; + PangoCairoShapeRendererFunc shape_renderer; + gpointer shape_renderer_data; + cairo_t *cr; + double dx = (double)x / PANGO_SCALE, dy = (double)y / PANGO_SCALE; + + layout = pango_renderer_get_layout (renderer); + + if (!layout) + return; + + shape_renderer = pango_cairo_context_get_shape_renderer (pango_layout_get_context (layout), + &shape_renderer_data); + + if (!shape_renderer) + return; + + cr = get_cairo_context (gdk_renderer, PANGO_RENDER_PART_FOREGROUND); + + cairo_save (cr); + + if (priv->embossed) + { + cairo_save (cr); + emboss_context (gdk_renderer, cr); + + cairo_move_to (cr, dx, dy); + shape_renderer (cr, attr, FALSE, shape_renderer_data); + + cairo_restore (cr); + } + + cairo_move_to (cr, dx, dy); + shape_renderer (cr, attr, FALSE, shape_renderer_data); + + cairo_restore (cr); +} + +static void +gdk_pango_renderer_part_changed (PangoRenderer *renderer, + PangoRenderPart part) +{ + GdkPangoRenderer *gdk_renderer = GDK_PANGO_RENDERER (renderer); + + if (gdk_renderer->priv->last_part == part) + gdk_renderer->priv->last_part = (PangoRenderPart)-1; +} + +static void +gdk_pango_renderer_begin (PangoRenderer *renderer) +{ + GdkPangoRenderer *gdk_renderer = GDK_PANGO_RENDERER (renderer); + GdkPangoRendererPrivate *priv = gdk_renderer->priv; + + if (!priv->drawable || !priv->base_gc) + { + g_warning ("gdk_pango_renderer_set_drawable() and gdk_pango_renderer_set_drawable()" + "must be used to set the target drawable and GC before using the renderer\n"); + } +} + +static void +gdk_pango_renderer_end (PangoRenderer *renderer) +{ + GdkPangoRenderer *gdk_renderer = GDK_PANGO_RENDERER (renderer); + GdkPangoRendererPrivate *priv = gdk_renderer->priv; + + if (priv->cr) + { + cairo_destroy (priv->cr); + priv->cr = NULL; + } + priv->last_part = (PangoRenderPart)-1; +} + +static void +gdk_pango_renderer_prepare_run (PangoRenderer *renderer, + PangoLayoutRun *run) +{ + GdkPangoRenderer *gdk_renderer = GDK_PANGO_RENDERER (renderer); + gboolean embossed = FALSE; + GdkBitmap *stipple = NULL; + gboolean changed = FALSE; + PangoColor emboss_color; + GSList *l; + int i; + + emboss_color.red = 0xffff; + emboss_color.green = 0xffff; + emboss_color.blue = 0xffff; + + for (l = run->item->analysis.extra_attrs; l; l = l->next) + { + PangoAttribute *attr = l->data; + + /* stipple_type and embossed_type aren't necessarily + * initialized, but they are 0, which is an + * invalid type so won't occur. + */ + if (attr->klass->type == gdk_pango_attr_stipple_type) + { + stipple = ((GdkPangoAttrStipple*)attr)->stipple; + } + else if (attr->klass->type == gdk_pango_attr_embossed_type) + { + embossed = ((GdkPangoAttrEmbossed*)attr)->embossed; + } + else if (attr->klass->type == gdk_pango_attr_emboss_color_type) + { + emboss_color = ((GdkPangoAttrEmbossColor*)attr)->color; + } + } + + gdk_pango_renderer_set_stipple (gdk_renderer, PANGO_RENDER_PART_FOREGROUND, stipple); + gdk_pango_renderer_set_stipple (gdk_renderer, PANGO_RENDER_PART_BACKGROUND, stipple); + gdk_pango_renderer_set_stipple (gdk_renderer, PANGO_RENDER_PART_UNDERLINE, stipple); + gdk_pango_renderer_set_stipple (gdk_renderer, PANGO_RENDER_PART_STRIKETHROUGH, stipple); + + if (embossed != gdk_renderer->priv->embossed) + { + gdk_renderer->priv->embossed = embossed; + changed = TRUE; + } + + if (!color_equal (&gdk_renderer->priv->emboss_color, &emboss_color)) + { + gdk_renderer->priv->emboss_color = emboss_color; + changed = TRUE; + } + + if (changed) + pango_renderer_part_changed (renderer, PANGO_RENDER_PART_FOREGROUND); + + PANGO_RENDERER_CLASS (gdk_pango_renderer_parent_class)->prepare_run (renderer, run); + + for (i = 0; i <= MAX_RENDER_PART; i++) + { + if (gdk_renderer->priv->override_color_set[i]) + pango_renderer_set_color (renderer, i, &gdk_renderer->priv->override_color[i]); + } +} + +static void +gdk_pango_renderer_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GdkPangoRenderer *gdk_renderer = GDK_PANGO_RENDERER (object); + + switch (prop_id) + { + case PROP_SCREEN: + gdk_renderer->priv->screen = g_value_get_object (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gdk_pango_renderer_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GdkPangoRenderer *gdk_renderer = GDK_PANGO_RENDERER (object); + + switch (prop_id) + { + case PROP_SCREEN: + g_value_set_object (value, gdk_renderer->priv->screen); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gdk_pango_renderer_init (GdkPangoRenderer *renderer) +{ + renderer->priv = G_TYPE_INSTANCE_GET_PRIVATE (renderer, + GDK_TYPE_PANGO_RENDERER, + GdkPangoRendererPrivate); + + renderer->priv->last_part = (PangoRenderPart)-1; + renderer->priv->gc_changed = TRUE; +} + +static void +gdk_pango_renderer_class_init (GdkPangoRendererClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + PangoRendererClass *renderer_class = PANGO_RENDERER_CLASS (klass); + + renderer_class->draw_glyphs = gdk_pango_renderer_draw_glyphs; + renderer_class->draw_rectangle = gdk_pango_renderer_draw_rectangle; + renderer_class->draw_error_underline = gdk_pango_renderer_draw_error_underline; + renderer_class->draw_shape = gdk_pango_renderer_draw_shape; + renderer_class->part_changed = gdk_pango_renderer_part_changed; + renderer_class->begin = gdk_pango_renderer_begin; + renderer_class->end = gdk_pango_renderer_end; + renderer_class->prepare_run = gdk_pango_renderer_prepare_run; + + object_class->finalize = gdk_pango_renderer_finalize; + object_class->constructor = gdk_pango_renderer_constructor; + object_class->set_property = gdk_pango_renderer_set_property; + object_class->get_property = gdk_pango_renderer_get_property; + + g_object_class_install_property (object_class, + PROP_SCREEN, + g_param_spec_object ("screen", + P_("Screen"), + P_("the GdkScreen for the renderer"), + GDK_TYPE_SCREEN, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | + G_PARAM_STATIC_BLURB)); + + g_type_class_add_private (object_class, sizeof (GdkPangoRendererPrivate)); +} + +/** + * gdk_pango_renderer_new: + * @screen: a #GdkScreen + * + * Creates a new #PangoRenderer for @screen. Normally you can use the + * results of gdk_pango_renderer_get_default() rather than creating a new + * renderer. + * + * Return value: a newly created #PangoRenderer. Free with g_object_unref(). + * + * Since: 2.6 + **/ +PangoRenderer * +gdk_pango_renderer_new (GdkScreen *screen) +{ + g_return_val_if_fail (screen != NULL, NULL); + + return g_object_new (GDK_TYPE_PANGO_RENDERER, + "screen", screen, + NULL); +} + +static void +on_renderer_display_closed (GdkDisplay *display, + gboolean is_error, + GdkPangoRenderer *renderer) +{ + g_signal_handlers_disconnect_by_func (display, + on_renderer_display_closed, + renderer); + g_object_set_data (G_OBJECT (renderer->priv->screen), + g_intern_static_string ("gdk-pango-renderer"), NULL); +} + +/** + * gdk_pango_renderer_get_default: + * @screen: a #GdkScreen + * + * Gets the default #PangoRenderer for a screen. This default renderer + * is shared by all users of the display, so properties such as the color + * or transformation matrix set for the renderer may be overwritten + * by functions such as gdk_draw_layout(). + * + * Before using the renderer, you need to call gdk_pango_renderer_set_drawable() + * and gdk_pango_renderer_set_gc() to set the drawable and graphics context + * to use for drawing. + * + * Return value: the default #PangoRenderer for @screen. The + * renderer is owned by GTK+ and will be kept around until the + * screen is closed. + * + * Since: 2.6 + **/ +PangoRenderer * +gdk_pango_renderer_get_default (GdkScreen *screen) +{ + PangoRenderer *renderer; + + g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL); + + renderer = g_object_get_data (G_OBJECT (screen), "gdk-pango-renderer"); + if (!renderer) + { + renderer = gdk_pango_renderer_new (screen); + g_object_set_data_full (G_OBJECT (screen), + g_intern_static_string ("gdk-pango-renderer"), renderer, + (GDestroyNotify)g_object_unref); + + g_signal_connect (gdk_screen_get_display (screen), "closed", + G_CALLBACK (on_renderer_display_closed), renderer); + } + + return renderer; +} + +/** + * gdk_pango_renderer_set_drawable: + * @gdk_renderer: a #GdkPangoRenderer + * @drawable: (allow-none): the new target drawable, or %NULL + * + * Sets the drawable the renderer draws to. + * + * Since: 2.6 + **/ +void +gdk_pango_renderer_set_drawable (GdkPangoRenderer *gdk_renderer, + GdkDrawable *drawable) +{ + GdkPangoRendererPrivate *priv; + + g_return_if_fail (GDK_IS_PANGO_RENDERER (gdk_renderer)); + g_return_if_fail (drawable == NULL || GDK_IS_DRAWABLE (drawable)); + + priv = gdk_renderer->priv; + + if (priv->drawable != drawable) + { + if (priv->drawable) + g_object_unref (priv->drawable); + priv->drawable = drawable; + if (priv->drawable) + g_object_ref (priv->drawable); + } +} + +/** + * gdk_pango_renderer_set_gc: + * @gdk_renderer: a #GdkPangoRenderer + * @gc: (allow-none): the new GC to use for drawing, or %NULL + * + * Sets the GC the renderer draws with. Note that the GC must not be + * modified until it is unset by calling the function again with + * %NULL for the @gc parameter, since GDK may make internal copies + * of the GC which won't be updated to follow changes to the + * original GC. + * + * Since: 2.6 + **/ +void +gdk_pango_renderer_set_gc (GdkPangoRenderer *gdk_renderer, + GdkGC *gc) +{ + GdkPangoRendererPrivate *priv; + + g_return_if_fail (GDK_IS_PANGO_RENDERER (gdk_renderer)); + g_return_if_fail (gc == NULL || GDK_IS_GC (gc)); + + priv = gdk_renderer->priv; + + if (priv->base_gc != gc) + { + if (priv->base_gc) + g_object_unref (priv->base_gc); + priv->base_gc = gc; + if (priv->base_gc) + g_object_ref (priv->base_gc); + + priv->gc_changed = TRUE; + } +} + + +/** + * gdk_pango_renderer_set_stipple: + * @gdk_renderer: a #GdkPangoRenderer + * @part: the part to render with the stipple + * @stipple: the new stipple value. + * + * Sets the stipple for one render part (foreground, background, underline, + * etc.) Note that this is overwritten when iterating through the individual + * styled runs of a #PangoLayout or #PangoLayoutLine. This function is thus + * only useful when you call low level functions like pango_renderer_draw_glyphs() + * directly, or in the 'prepare_run' virtual function of a subclass of + * #GdkPangoRenderer. + * + * Since: 2.6 + **/ +void +gdk_pango_renderer_set_stipple (GdkPangoRenderer *gdk_renderer, + PangoRenderPart part, + GdkBitmap *stipple) +{ + g_return_if_fail (GDK_IS_PANGO_RENDERER (gdk_renderer)); + + if (part > MAX_RENDER_PART) /* Silently ignore unknown parts */ + return; + + if (stipple != gdk_renderer->priv->stipple[part]) + { + if (gdk_renderer->priv->stipple[part]) + g_object_unref (gdk_renderer->priv->stipple[part]); + + gdk_renderer->priv->stipple[part] = stipple; + + if (gdk_renderer->priv->stipple[part]) + g_object_ref (gdk_renderer->priv->stipple[part]); + + pango_renderer_part_changed (PANGO_RENDERER (gdk_renderer), part); + } +} + +/** + * gdk_pango_renderer_set_override_color: + * @gdk_renderer: a #GdkPangoRenderer + * @part: the part to render to set the color of + * @color: (allow-none): the color to use, or %NULL to unset a previously + * set override color. + * + * Sets the color for a particular render part (foreground, + * background, underline, etc.), overriding any attributes on the layouts + * renderered with this renderer. + * + * Since: 2.6 + **/ +void +gdk_pango_renderer_set_override_color (GdkPangoRenderer *gdk_renderer, + PangoRenderPart part, + const GdkColor *color) +{ + GdkPangoRendererPrivate *priv; + + g_return_if_fail (GDK_IS_PANGO_RENDERER (gdk_renderer)); + + priv = gdk_renderer->priv; + + if (part > MAX_RENDER_PART) /* Silently ignore unknown parts */ + return; + + if (color) + { + priv->override_color[part].red = color->red; + priv->override_color[part].green = color->green; + priv->override_color[part].blue = color->blue; + priv->override_color_set[part] = TRUE; + } + else + priv->override_color_set[part] = FALSE; +} + +/** + * gdk_pango_context_set_colormap: + * @context: a #PangoContext + * @colormap: a #GdkColormap + * + * This function used to set the colormap to be used for drawing with + * @context. The colormap is now always derived from the graphics + * context used for drawing, so calling this function is no longer + * necessary. + **/ +void +gdk_pango_context_set_colormap (PangoContext *context, + GdkColormap *colormap) +{ + g_return_if_fail (PANGO_IS_CONTEXT (context)); + g_return_if_fail (colormap == NULL || GDK_IS_COLORMAP (colormap)); +} + +/* Gets a renderer to draw with, setting the properties of the + * renderer and activating it. Note that since we activate the + * renderer here, the implicit setting of the matrix that + * pango_renderer_draw_layout_[line] normally do when they + * activate the renderer is suppressed. */ +static PangoRenderer * +get_renderer (GdkDrawable *drawable, + GdkGC *gc, + const GdkColor *foreground, + const GdkColor *background) +{ + GdkScreen *screen = gdk_drawable_get_screen (drawable); + PangoRenderer *renderer = gdk_pango_renderer_get_default (screen); + GdkPangoRenderer *gdk_renderer = GDK_PANGO_RENDERER (renderer); + + gdk_pango_renderer_set_drawable (gdk_renderer, drawable); + gdk_pango_renderer_set_gc (gdk_renderer, gc); + + gdk_pango_renderer_set_override_color (gdk_renderer, + PANGO_RENDER_PART_FOREGROUND, + foreground); + gdk_pango_renderer_set_override_color (gdk_renderer, + PANGO_RENDER_PART_UNDERLINE, + foreground); + gdk_pango_renderer_set_override_color (gdk_renderer, + PANGO_RENDER_PART_STRIKETHROUGH, + foreground); + + gdk_pango_renderer_set_override_color (gdk_renderer, + PANGO_RENDER_PART_BACKGROUND, + background); + + pango_renderer_activate (renderer); + + return renderer; +} + +/* Cleans up the renderer obtained with get_renderer() */ +static void +release_renderer (PangoRenderer *renderer) +{ + GdkPangoRenderer *gdk_renderer = GDK_PANGO_RENDERER (renderer); + + pango_renderer_deactivate (renderer); + + gdk_pango_renderer_set_override_color (gdk_renderer, + PANGO_RENDER_PART_FOREGROUND, + NULL); + gdk_pango_renderer_set_override_color (gdk_renderer, + PANGO_RENDER_PART_UNDERLINE, + NULL); + gdk_pango_renderer_set_override_color (gdk_renderer, + PANGO_RENDER_PART_STRIKETHROUGH, + NULL); + gdk_pango_renderer_set_override_color (gdk_renderer, + PANGO_RENDER_PART_BACKGROUND, + NULL); + + gdk_pango_renderer_set_drawable (gdk_renderer, NULL); + gdk_pango_renderer_set_gc (gdk_renderer, NULL); +} + +/** + * gdk_draw_layout_line_with_colors: + * @drawable: the drawable on which to draw the line + * @gc: base graphics to use + * @x: the x position of start of string (in pixels) + * @y: the y position of baseline (in pixels) + * @line: a #PangoLayoutLine + * @foreground: (allow-none): foreground override color, or %NULL for none + * @background: (allow-none): background override color, or %NULL for none + * + * Render a #PangoLayoutLine onto a #GdkDrawable, overriding the + * layout's normal colors with @foreground and/or @background. + * @foreground and @background need not be allocated. + * + * If the layout's #PangoContext has a transformation matrix set, then + * @x and @y specify the position of the left edge of the baseline + * (left is in before-tranform user coordinates) in after-transform + * device coordinates. + */ +void +gdk_draw_layout_line_with_colors (GdkDrawable *drawable, + GdkGC *gc, + gint x, + gint y, + PangoLayoutLine *line, + const GdkColor *foreground, + const GdkColor *background) +{ + PangoRenderer *renderer; + const PangoMatrix *matrix; + + g_return_if_fail (GDK_IS_DRAWABLE (drawable)); + g_return_if_fail (GDK_IS_GC (gc)); + g_return_if_fail (line != NULL); + + renderer = get_renderer (drawable, gc, foreground, background); + + /* When we have a matrix, we do positioning by adjusting the matrix, and + * clamp just pass x=0, y=0 to the lower levels. We don't want to introduce + * a matrix when the caller didn't provide one, however, since that adds + * lots of floating point arithmetic for each glyph. + */ + matrix = pango_context_get_matrix (pango_layout_get_context (line->layout)); + if (matrix) + { + PangoMatrix tmp_matrix; + + tmp_matrix = *matrix; + tmp_matrix.x0 += x; + tmp_matrix.y0 += y; + pango_renderer_set_matrix (renderer, &tmp_matrix); + + x = 0; + y = 0; + } + /* Fall back to introduce a matrix if the coords would scale out of range. + * The x and y here will be added to in-layout coordinates. So we cannot + * support the entire range here safely. So, we just accept the middle half + * and use fallback for the rest. */ + else if (GDK_PANGO_UNITS_OVERFLOWS (x, y)) + { + PangoMatrix tmp_matrix = PANGO_MATRIX_INIT; + tmp_matrix.x0 += x; + tmp_matrix.y0 += y; + pango_renderer_set_matrix (renderer, &tmp_matrix); + + x = 0; + y = 0; + } + else + pango_renderer_set_matrix (renderer, NULL); + + pango_renderer_draw_layout_line (renderer, line, x * PANGO_SCALE, y * PANGO_SCALE); + + release_renderer (renderer); +} + +/** + * gdk_draw_layout_with_colors: + * @drawable: the drawable on which to draw string + * @gc: base graphics context to use + * @x: the X position of the left of the layout (in pixels) + * @y: the Y position of the top of the layout (in pixels) + * @layout: a #PangoLayout + * @foreground: (allow-none): foreground override color, or %NULL for none + * @background: (allow-none): background override color, or %NULL for none + * + * Render a #PangoLayout onto a #GdkDrawable, overriding the + * layout's normal colors with @foreground and/or @background. + * @foreground and @background need not be allocated. + * + * If the layout's #PangoContext has a transformation matrix set, then + * @x and @y specify the position of the top left corner of the + * bounding box (in device space) of the transformed layout. + * + * If you're using GTK+, the ususal way to obtain a #PangoLayout + * is gtk_widget_create_pango_layout(). + */ +void +gdk_draw_layout_with_colors (GdkDrawable *drawable, + GdkGC *gc, + int x, + int y, + PangoLayout *layout, + const GdkColor *foreground, + const GdkColor *background) +{ + PangoRenderer *renderer; + const PangoMatrix *matrix; + + g_return_if_fail (GDK_IS_DRAWABLE (drawable)); + g_return_if_fail (GDK_IS_GC (gc)); + g_return_if_fail (PANGO_IS_LAYOUT (layout)); + + renderer = get_renderer (drawable, gc, foreground, background); + + /* When we have a matrix, we do positioning by adjusting the matrix, and + * clamp just pass x=0, y=0 to the lower levels. We don't want to introduce + * a matrix when the caller didn't provide one, however, since that adds + * lots of floating point arithmetic for each glyph. + */ + matrix = pango_context_get_matrix (pango_layout_get_context (layout)); + if (matrix) + { + PangoMatrix tmp_matrix; + PangoRectangle rect; + + pango_layout_get_extents (layout, NULL, &rect); + pango_matrix_transform_rectangle (matrix, &rect); + pango_extents_to_pixels (&rect, NULL); + + tmp_matrix = *matrix; + tmp_matrix.x0 += x - rect.x; + tmp_matrix.y0 += y - rect.y; + pango_renderer_set_matrix (renderer, &tmp_matrix); + + x = 0; + y = 0; + } + else if (GDK_PANGO_UNITS_OVERFLOWS (x, y)) + { + PangoMatrix tmp_matrix = PANGO_MATRIX_INIT; + tmp_matrix.x0 = x; + tmp_matrix.y0 = y; + pango_renderer_set_matrix (renderer, &tmp_matrix); + + x = 0; + y = 0; + } + else + pango_renderer_set_matrix (renderer, NULL); + + pango_renderer_draw_layout (renderer, layout, x * PANGO_SCALE, y * PANGO_SCALE); + + release_renderer (renderer); +} + +/** + * gdk_draw_layout_line: + * @drawable: the drawable on which to draw the line + * @gc: base graphics to use + * @x: the x position of start of string (in pixels) + * @y: the y position of baseline (in pixels) + * @line: a #PangoLayoutLine + * + * Render a #PangoLayoutLine onto an GDK drawable + * + * If the layout's #PangoContext has a transformation matrix set, then + * @x and @y specify the position of the left edge of the baseline + * (left is in before-tranform user coordinates) in after-transform + * device coordinates. + */ +void +gdk_draw_layout_line (GdkDrawable *drawable, + GdkGC *gc, + gint x, + gint y, + PangoLayoutLine *line) +{ + g_return_if_fail (GDK_IS_DRAWABLE (drawable)); + g_return_if_fail (GDK_IS_GC (gc)); + g_return_if_fail (line != NULL); + + gdk_draw_layout_line_with_colors (drawable, gc, x, y, line, NULL, NULL); +} + +/** + * gdk_draw_layout: + * @drawable: the drawable on which to draw string + * @gc: base graphics context to use + * @x: the X position of the left of the layout (in pixels) + * @y: the Y position of the top of the layout (in pixels) + * @layout: a #PangoLayout + * + * Render a #PangoLayout onto a GDK drawable + * + * If the layout's #PangoContext has a transformation matrix set, then + * @x and @y specify the position of the top left corner of the + * bounding box (in device space) of the transformed layout. + * + * If you're using GTK+, the usual way to obtain a #PangoLayout + * is gtk_widget_create_pango_layout(). + */ +void +gdk_draw_layout (GdkDrawable *drawable, + GdkGC *gc, + int x, + int y, + PangoLayout *layout) +{ + g_return_if_fail (GDK_IS_DRAWABLE (drawable)); + g_return_if_fail (GDK_IS_GC (gc)); + g_return_if_fail (PANGO_IS_LAYOUT (layout)); + + gdk_draw_layout_with_colors (drawable, gc, x, y, layout, NULL, NULL); +} + +/* GdkPangoAttrStipple */ + +static PangoAttribute * +gdk_pango_attr_stipple_copy (const PangoAttribute *attr) +{ + const GdkPangoAttrStipple *src = (const GdkPangoAttrStipple*) attr; + + return gdk_pango_attr_stipple_new (src->stipple); +} + +static void +gdk_pango_attr_stipple_destroy (PangoAttribute *attr) +{ + GdkPangoAttrStipple *st = (GdkPangoAttrStipple*) attr; + + if (st->stipple) + g_object_unref (st->stipple); + + g_free (attr); +} + +static gboolean +gdk_pango_attr_stipple_compare (const PangoAttribute *attr1, + const PangoAttribute *attr2) +{ + const GdkPangoAttrStipple *a = (const GdkPangoAttrStipple*) attr1; + const GdkPangoAttrStipple *b = (const GdkPangoAttrStipple*) attr2; + + return a->stipple == b->stipple; +} + +/** + * gdk_pango_attr_stipple_new: + * @stipple: a bitmap to be set as stipple + * + * Creates a new attribute containing a stipple bitmap to be used when + * rendering the text. + * + * Return value: new #PangoAttribute + **/ + +PangoAttribute * +gdk_pango_attr_stipple_new (GdkBitmap *stipple) +{ + GdkPangoAttrStipple *result; + + static PangoAttrClass klass = { + 0, + gdk_pango_attr_stipple_copy, + gdk_pango_attr_stipple_destroy, + gdk_pango_attr_stipple_compare + }; + + if (!klass.type) + klass.type = gdk_pango_attr_stipple_type = + pango_attr_type_register ("GdkPangoAttrStipple"); + + result = g_new (GdkPangoAttrStipple, 1); + result->attr.klass = &klass; + + if (stipple) + g_object_ref (stipple); + + result->stipple = stipple; + + return (PangoAttribute *)result; +} + +/* GdkPangoAttrEmbossed */ + +static PangoAttribute * +gdk_pango_attr_embossed_copy (const PangoAttribute *attr) +{ + const GdkPangoAttrEmbossed *e = (const GdkPangoAttrEmbossed*) attr; + + return gdk_pango_attr_embossed_new (e->embossed); +} + +static void +gdk_pango_attr_embossed_destroy (PangoAttribute *attr) +{ + g_free (attr); +} + +static gboolean +gdk_pango_attr_embossed_compare (const PangoAttribute *attr1, + const PangoAttribute *attr2) +{ + const GdkPangoAttrEmbossed *e1 = (const GdkPangoAttrEmbossed*) attr1; + const GdkPangoAttrEmbossed *e2 = (const GdkPangoAttrEmbossed*) attr2; + + return e1->embossed == e2->embossed; +} + +/** + * gdk_pango_attr_embossed_new: + * @embossed: if the region should be embossed + * + * Creates a new attribute flagging a region as embossed or not. + * + * Return value: new #PangoAttribute + **/ + +PangoAttribute * +gdk_pango_attr_embossed_new (gboolean embossed) +{ + GdkPangoAttrEmbossed *result; + + static PangoAttrClass klass = { + 0, + gdk_pango_attr_embossed_copy, + gdk_pango_attr_embossed_destroy, + gdk_pango_attr_embossed_compare + }; + + if (!klass.type) + klass.type = gdk_pango_attr_embossed_type = + pango_attr_type_register ("GdkPangoAttrEmbossed"); + + result = g_new (GdkPangoAttrEmbossed, 1); + result->attr.klass = &klass; + result->embossed = embossed; + + return (PangoAttribute *)result; +} + +/* GdkPangoAttrEmbossColor */ + +static PangoAttribute * +gdk_pango_attr_emboss_color_copy (const PangoAttribute *attr) +{ + const GdkPangoAttrEmbossColor *old = (const GdkPangoAttrEmbossColor*) attr; + GdkPangoAttrEmbossColor *copy; + + copy = g_new (GdkPangoAttrEmbossColor, 1); + copy->attr.klass = old->attr.klass; + copy->color = old->color; + + return (PangoAttribute *) copy; +} + +static void +gdk_pango_attr_emboss_color_destroy (PangoAttribute *attr) +{ + g_free (attr); +} + +static gboolean +gdk_pango_attr_emboss_color_compare (const PangoAttribute *attr1, + const PangoAttribute *attr2) +{ + const GdkPangoAttrEmbossColor *c1 = (const GdkPangoAttrEmbossColor*) attr1; + const GdkPangoAttrEmbossColor *c2 = (const GdkPangoAttrEmbossColor*) attr2; + + return color_equal (&c1->color, &c2->color); +} + +/** + * gdk_pango_attr_emboss_color_new: + * @color: a GdkColor representing the color to emboss with + * + * Creates a new attribute specifying the color to emboss text with. + * + * Return value: new #PangoAttribute + * + * Since: 2.12 + **/ +PangoAttribute * +gdk_pango_attr_emboss_color_new (const GdkColor *color) +{ + GdkPangoAttrEmbossColor *result; + + static PangoAttrClass klass = { + 0, + gdk_pango_attr_emboss_color_copy, + gdk_pango_attr_emboss_color_destroy, + gdk_pango_attr_emboss_color_compare + }; + + if (!klass.type) + klass.type = gdk_pango_attr_emboss_color_type = + pango_attr_type_register ("GdkPangoAttrEmbossColor"); + + result = g_new (GdkPangoAttrEmbossColor, 1); + result->attr.klass = &klass; + result->color.red = color->red; + result->color.green = color->green; + result->color.blue = color->blue; + + return (PangoAttribute *) result; +} + +/* Get a clip region to draw only part of a layout. index_ranges + * contains alternating range starts/stops. The region is the + * region which contains the given ranges, i.e. if you draw with the + * region as clip, only the given ranges are drawn. + */ +static GdkRegion* +layout_iter_get_line_clip_region (PangoLayoutIter *iter, + gint x_origin, + gint y_origin, + const gint *index_ranges, + gint n_ranges) +{ + PangoLayoutLine *line; + GdkRegion *clip_region; + PangoRectangle logical_rect; + gint baseline; + gint i; + + line = pango_layout_iter_get_line_readonly (iter); + + clip_region = gdk_region_new (); + + pango_layout_iter_get_line_extents (iter, NULL, &logical_rect); + baseline = pango_layout_iter_get_baseline (iter); + + i = 0; + while (i < n_ranges) + { + gint *pixel_ranges = NULL; + gint n_pixel_ranges = 0; + gint j; + + /* Note that get_x_ranges returns layout coordinates + */ + if (index_ranges[i*2+1] >= line->start_index && + index_ranges[i*2] < line->start_index + line->length) + pango_layout_line_get_x_ranges (line, + index_ranges[i*2], + index_ranges[i*2+1], + &pixel_ranges, &n_pixel_ranges); + + for (j = 0; j < n_pixel_ranges; j++) + { + GdkRectangle rect; + int x_off, y_off; + + x_off = PANGO_PIXELS (pixel_ranges[2*j] - logical_rect.x); + y_off = PANGO_PIXELS (baseline - logical_rect.y); + + rect.x = x_origin + x_off; + rect.y = y_origin - y_off; + rect.width = PANGO_PIXELS (pixel_ranges[2*j + 1] - logical_rect.x) - x_off; + rect.height = PANGO_PIXELS (baseline - logical_rect.y + logical_rect.height) - y_off; + + gdk_region_union_with_rect (clip_region, &rect); + } + + g_free (pixel_ranges); + ++i; + } + return clip_region; +} + +/** + * gdk_pango_layout_line_get_clip_region: + * @line: a #PangoLayoutLine + * @x_origin: X pixel where you intend to draw the layout line with this clip + * @y_origin: baseline pixel where you intend to draw the layout line with this clip + * @index_ranges: array of byte indexes into the layout, where even members of array are start indexes and odd elements are end indexes + * @n_ranges: number of ranges in @index_ranges, i.e. half the size of @index_ranges + * + * Obtains a clip region which contains the areas where the given + * ranges of text would be drawn. @x_origin and @y_origin are the same + * position you would pass to gdk_draw_layout_line(). @index_ranges + * should contain ranges of bytes in the layout's text. The clip + * region will include space to the left or right of the line (to the + * layout bounding box) if you have indexes above or below the indexes + * contained inside the line. This is to draw the selection all the way + * to the side of the layout. However, the clip region is in line coordinates, + * not layout coordinates. + * + * Note that the regions returned correspond to logical extents of the text + * ranges, not ink extents. So the drawn line may in fact touch areas out of + * the clip region. The clip region is mainly useful for highlightling parts + * of text, such as when text is selected. + * + * Return value: a clip region containing the given ranges + **/ +GdkRegion* +gdk_pango_layout_line_get_clip_region (PangoLayoutLine *line, + gint x_origin, + gint y_origin, + const gint *index_ranges, + gint n_ranges) +{ + GdkRegion *clip_region; + PangoLayoutIter *iter; + + g_return_val_if_fail (line != NULL, NULL); + g_return_val_if_fail (index_ranges != NULL, NULL); + + iter = pango_layout_get_iter (line->layout); + while (pango_layout_iter_get_line_readonly (iter) != line) + pango_layout_iter_next_line (iter); + + clip_region = layout_iter_get_line_clip_region(iter, x_origin, y_origin, index_ranges, n_ranges); + + pango_layout_iter_free (iter); + + return clip_region; +} + +/** + * gdk_pango_layout_get_clip_region: + * @layout: a #PangoLayout + * @x_origin: X pixel where you intend to draw the layout with this clip + * @y_origin: Y pixel where you intend to draw the layout with this clip + * @index_ranges: array of byte indexes into the layout, where even members of array are start indexes and odd elements are end indexes + * @n_ranges: number of ranges in @index_ranges, i.e. half the size of @index_ranges + * + * Obtains a clip region which contains the areas where the given ranges + * of text would be drawn. @x_origin and @y_origin are the same position + * you would pass to gdk_draw_layout_line(). @index_ranges should contain + * ranges of bytes in the layout's text. + * + * Note that the regions returned correspond to logical extents of the text + * ranges, not ink extents. So the drawn layout may in fact touch areas out of + * the clip region. The clip region is mainly useful for highlightling parts + * of text, such as when text is selected. + * + * Return value: a clip region containing the given ranges + **/ +GdkRegion* +gdk_pango_layout_get_clip_region (PangoLayout *layout, + gint x_origin, + gint y_origin, + const gint *index_ranges, + gint n_ranges) +{ + PangoLayoutIter *iter; + GdkRegion *clip_region; + + g_return_val_if_fail (PANGO_IS_LAYOUT (layout), NULL); + g_return_val_if_fail (index_ranges != NULL, NULL); + + clip_region = gdk_region_new (); + + iter = pango_layout_get_iter (layout); + + do + { + PangoRectangle logical_rect; + GdkRegion *line_region; + gint baseline; + + pango_layout_iter_get_line_extents (iter, NULL, &logical_rect); + baseline = pango_layout_iter_get_baseline (iter); + + line_region = layout_iter_get_line_clip_region(iter, + x_origin + PANGO_PIXELS (logical_rect.x), + y_origin + PANGO_PIXELS (baseline), + index_ranges, + n_ranges); + + gdk_region_union (clip_region, line_region); + gdk_region_destroy (line_region); + } + while (pango_layout_iter_next_line (iter)); + + pango_layout_iter_free (iter); + + return clip_region; +} + +/** + * gdk_pango_context_get: + * + * Creates a #PangoContext for the default GDK screen. + * + * The context must be freed when you're finished with it. + * + * When using GTK+, normally you should use gtk_widget_get_pango_context() + * instead of this function, to get the appropriate context for + * the widget you intend to render text onto. + * + * The newly created context will have the default font options (see + * #cairo_font_options_t) for the default screen; if these options + * change it will not be updated. Using gtk_widget_get_pango_context() + * is more convenient if you want to keep a context around and track + * changes to the screen's font rendering settings. + * + * Return value: a new #PangoContext for the default display + **/ +PangoContext * +gdk_pango_context_get (void) +{ + return gdk_pango_context_get_for_screen (gdk_screen_get_default ()); +} + +/** + * gdk_pango_context_get_for_screen: + * @screen: the #GdkScreen for which the context is to be created. + * + * Creates a #PangoContext for @screen. + * + * The context must be freed when you're finished with it. + * + * When using GTK+, normally you should use gtk_widget_get_pango_context() + * instead of this function, to get the appropriate context for + * the widget you intend to render text onto. + * + * The newly created context will have the default font options + * (see #cairo_font_options_t) for the screen; if these options + * change it will not be updated. Using gtk_widget_get_pango_context() + * is more convenient if you want to keep a context around and track + * changes to the screen's font rendering settings. + * + * Return value: a new #PangoContext for @screen + * + * Since: 2.2 + **/ +PangoContext * +gdk_pango_context_get_for_screen (GdkScreen *screen) +{ + PangoFontMap *fontmap; + PangoContext *context; + const cairo_font_options_t *options; + double dpi; + + g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL); + + fontmap = pango_cairo_font_map_get_default (); + context = pango_font_map_create_context (fontmap); + + options = gdk_screen_get_font_options (screen); + pango_cairo_context_set_font_options (context, options); + + dpi = gdk_screen_get_resolution (screen); + pango_cairo_context_set_resolution (context, dpi); + + return context; +} + +#define __GDK_PANGO_C__ +#include "gdkaliasdef.c" diff --git a/libs/tk/ydk/gdkpixbuf-drawable.c b/libs/tk/ydk/gdkpixbuf-drawable.c new file mode 100644 index 0000000000..ff85cb7e7a --- /dev/null +++ b/libs/tk/ydk/gdkpixbuf-drawable.c @@ -0,0 +1,1418 @@ +/* GdkPixbuf library - convert X drawable information to RGB + * + * Copyright (C) 1999 Michael Zucchi + * + * Authors: Michael Zucchi + * Cody Russell + * Federico Mena-Quintero + * + * 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. + */ + +#include "config.h" +#include +#include +#include + +#include "gdkcolor.h" +#include "gdkimage.h" +#include "gdkvisual.h" +#include "gdkwindow.h" +#include "gdkpixbuf.h" +#include "gdkpixmap.h" +#include "gdkinternals.h" +#include "gdkalias.h" + +/* Some convenient names + */ +#if (G_BYTE_ORDER == G_LITTLE_ENDIAN) +#define LITTLE +#undef BIG +#else +#define BIG +#undef LITTLE +#endif +#define d(x) + +#define SWAP16(d) GUINT16_SWAP_LE_BE(d) + + + +static const guint32 mask_table[] = { + 0x00000000, 0x00000001, 0x00000003, 0x00000007, + 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f, + 0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff, + 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff, + 0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff, + 0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff, + 0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff, + 0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff, + 0xffffffff +}; + + + +/* + * convert bitmap data to pixbuf without alpha, + * without using a colormap + */ +static void +bitmap1 (GdkImage *image, + guchar *pixels, + int rowstride, + int x1, + int y1, + int x2, + int y2) +{ + int xx, yy; + int bpl; + register guint8 data; + guint8 *o; + guint8 *srow = (guint8*)image->mem + y1 * image->bpl, *orow = pixels; + + d (printf ("bitmap, no alpha\n")); + + bpl = image->bpl; + + for (yy = y1; yy < y2; yy++) + { + o = orow; + + for (xx = x1; xx < x2; xx ++) + { + /* top 29 bits of xx (xx >> 3) indicate the byte the bit is inside, + * bottom 3 bits (xx & 7) indicate bit inside that byte, + * we don't bother to canonicalize data to 1 or 0, just + * leave the relevant bit in-place. + */ + data = srow[xx >> 3] & (image->byte_order == GDK_MSB_FIRST ? + (0x80 >> (xx & 7)) : + (1 << (xx & 7))); + + if (data) + { + *o++ = 255; + *o++ = 255; + *o++ = 255; + } + else + { + *o++ = 0; + *o++ = 0; + *o++ = 0; + } + } + srow += bpl; + orow += rowstride; + } +} + +/* + * convert bitmap data to pixbuf with alpha, + * without using a colormap + */ +static void +bitmap1a (GdkImage *image, + guchar *pixels, + int rowstride, + int x1, + int y1, + int x2, + int y2) +{ + int xx, yy; + int bpl; + register guint8 data; + guint8 *o; + guint8 *srow = (guint8*)image->mem + y1 * image->bpl, *orow = pixels; + + d (printf ("bitmap, with alpha\n")); + + bpl = image->bpl; + + for (yy = y1; yy < y2; yy++) + { + o = orow; + + for (xx = x1; xx < x2; xx ++) + { + /* see comment in bitmap1() */ + data = srow[xx >> 3] & (image->byte_order == GDK_MSB_FIRST ? + (0x80 >> (xx & 7)) : + (1 << (xx & 7))); + + if (data) + { + *o++ = 255; + *o++ = 255; + *o++ = 255; + *o++ = 255; + } + else + { + *o++ = 0; + *o++ = 0; + *o++ = 0; + *o++ = 0; + } + } + srow += bpl; + orow += rowstride; + } +} + +/* + * convert 1 bits-pixel data + * no alpha + */ +static void +rgb1 (GdkImage *image, + guchar *pixels, + int rowstride, + int x1, + int y1, + int x2, + int y2, + GdkColormap *colormap) +{ + int xx, yy; + int bpl; + register guint8 data; + guint8 *o; + guint8 *srow = (guint8*)image->mem + y1 * image->bpl, *orow = pixels; + + d (printf ("1 bits/pixel\n")); + + /* convert upto 8 pixels/time */ + /* its probably not worth trying to make this run very fast, who uses + * 1 bit displays anymore? + */ + bpl = image->bpl; + + for (yy = y1; yy < y2; yy++) + { + o = orow; + + for (xx = x1; xx < x2; xx ++) + { + /* see comment in bitmap1() */ + data = srow[xx >> 3] & (image->byte_order == GDK_MSB_FIRST ? + (0x80 >> (xx & 7)) : + (1 << (xx & 7))); + + *o++ = colormap->colors[data].red >> 8; + *o++ = colormap->colors[data].green >> 8; + *o++ = colormap->colors[data].blue >> 8; + } + srow += bpl; + orow += rowstride; + } +} + +/* + * convert 1 bits/pixel data + * with alpha + */ +static void +rgb1a (GdkImage *image, + guchar *pixels, + int rowstride, + int x1, + int y1, + int x2, + int y2, + GdkColormap *colormap) +{ + int xx, yy; + int bpl; + register guint8 data; + guint8 *o; + guint8 *srow = (guint8*)image->mem + y1 * image->bpl, *orow = pixels; + + d (printf ("1 bits/pixel\n")); + + /* convert upto 8 pixels/time */ + /* its probably not worth trying to make this run very fast, who uses + * 1 bit displays anymore? */ + bpl = image->bpl; + + for (yy = y1; yy < y2; yy++) + { + o = orow; + + for (xx = x1; xx < x2; xx ++) + { + /* see comment in bitmap1() */ + data = srow[xx >> 3] & (image->byte_order == GDK_MSB_FIRST ? + (0x80 >> (xx & 7)) : + (1 << (xx & 7))); + + *o++ = colormap->colors[data].red >> 8; + *o++ = colormap->colors[data].green >> 8; + *o++ = colormap->colors[data].blue >> 8; + *o++ = 255; + } + srow += bpl; + orow += rowstride; + } +} + +/* + * convert 8 bits/pixel data + * no alpha + */ +static void +rgb8 (GdkImage *image, + guchar *pixels, + int rowstride, + int x1, + int y1, + int x2, + int y2, + GdkColormap *colormap) +{ + int xx, yy; + int bpl; + guint32 mask; + register guint32 data; + guint8 *srow = (guint8*)image->mem + y1 * image->bpl + x1 * image->bpp, *orow = pixels; + register guint8 *s; + register guint8 *o; + + bpl = image->bpl; + + d (printf ("8 bit, no alpha output\n")); + + mask = mask_table[image->depth]; + + for (yy = y1; yy < y2; yy++) + { + s = srow; + o = orow; + for (xx = x1; xx < x2; xx++) + { + data = *s++ & mask; + *o++ = colormap->colors[data].red >> 8; + *o++ = colormap->colors[data].green >> 8; + *o++ = colormap->colors[data].blue >> 8; + } + srow += bpl; + orow += rowstride; + } +} + +/* + * convert 8 bits/pixel data + * with alpha + */ +static void +rgb8a (GdkImage *image, + guchar *pixels, + int rowstride, + int x1, + int y1, + int x2, + int y2, + GdkColormap *colormap) +{ + int xx, yy; + int bpl; + guint32 mask; + register guint32 data; + guint32 remap[256]; + register guint8 *s; /* read 2 pixels at once */ + register guint32 *o; + guint8 *srow = (guint8*)image->mem + y1 * image->bpl + x1 * image->bpp, *orow = pixels; + + bpl = image->bpl; + + d (printf ("8 bit, with alpha output\n")); + + mask = mask_table[image->depth]; + + for (xx = x1; xx < colormap->size; xx++) + { +#ifdef LITTLE + remap[xx] = 0xff000000 + | (colormap->colors[xx].blue & 0xff00) << 8 + | (colormap->colors[xx].green & 0xff00) + | (colormap->colors[xx].red >> 8); +#else + remap[xx] = 0xff + | (colormap->colors[xx].red & 0xff00) << 16 + | (colormap->colors[xx].green & 0xff00) << 8 + | (colormap->colors[xx].blue & 0xff00); +#endif + } + + for (yy = y1; yy < y2; yy++) + { + s = srow; + o = (guint32 *) orow; + for (xx = x1; xx < x2; xx ++) + { + data = *s++ & mask; + *o++ = remap[data]; + } + srow += bpl; + orow += rowstride; + } +} + +/* Bit shifting for 565 and 555 conversion routines + * + * RGB565 == rrrr rggg gggb bbbb, 16 bit native endian + * RGB555 == xrrr rrgg gggb bbbb + * ABGR8888: ARGB, 32-bit native endian + * RGBA8888: RGBA, 32-bit native endian + */ +#define R8fromRGB565(d) ((((d) >> 8) & 0xf8) | (((d) >> 13) & 0x7)) +#define G8fromRGB565(d) ((((d) >> 3) & 0xfc) | (((d) >> 9) & 0x3)) +#define B8fromRGB565(d) ((((d) << 3) & 0xf8) | (((d) >> 2) & 0x7)) + +#define ABGR8888fromRGB565(d) ( ((d) & 0xf800) >> 8 | ((d) & 0xe000) >> 13 \ + | ((d) & 0x07e0) << 5 | ((d) & 0x0600) >> 1 \ + | ((d) & 0x001f) << 19 | ((d) & 0x001c) << 14 \ + | 0xff000000) +#define RGBA8888fromRGB565(d) ( ((d) & 0xf800) << 16 | ((d) & 0xe000) << 11 \ + | ((d) & 0x07e0) << 13 | ((d) & 0x0600) << 7 \ + | ((d) & 0x001f) << 11 | ((d) & 0x001c) << 6 \ + | 0xff) + +#define R8fromRGB555(d) (((d) & 0x7c00) >> 7 | ((d) & 0x7000) >> 12) +#define G8fromRGB555(d) (((d) & 0x03e0) >> 2 | ((d) & 0x0380) >> 7) +#define B8fromRGB555(d) (((d) & 0x001f) << 3 | ((d) & 0x001c) >> 2) + +#define ABGR8888fromRGB555(d) ( ((d) & 0x7c00) >> 7 | ((d) & 0x7000) >> 12 \ + | ((d) & 0x03e0) << 6 | ((d) & 0x0380) << 1 \ + | ((d) & 0x001f) << 19 | ((d) & 0x001c) << 14 \ + | 0xff000000) +#define RGBA8888fromRGB555(d) ( ((d) & 0x7c00) << 17 | ((d) & 0x7000) << 12 \ + | ((d) & 0x03e0) << 14 | ((d) & 0x0380) << 9 \ + | ((d) & 0x001f) << 11 | ((d) & 0x001c) << 6 \ + | 0xff) + +/* + * convert 16 bits/pixel data + * no alpha + * data in lsb format + */ +static void +rgb565lsb (GdkImage *image, + guchar *pixels, + int rowstride, + int x1, + int y1, + int x2, + int y2, + GdkColormap *colormap) +{ + int xx, yy; + int bpl; + + register guint16 *s; + register guint8 *o; + + guint8 *srow = (guint8*)image->mem + y1 * image->bpl + x1 * image->bpp, *orow = pixels; + + bpl = image->bpl; + + for (yy = y1; yy < y2; yy++) + { + s = (guint16 *) srow; + o = (guint8 *) orow; + for (xx = x1; xx < x2; xx ++) + { + register guint32 data = *s++; +#ifdef BIG + data = SWAP16 (data); +#endif + *o++ = R8fromRGB565 (data); + *o++ = G8fromRGB565 (data); + *o++ = B8fromRGB565 (data); + } + srow += bpl; + orow += rowstride; + } +} + +/* + * convert 16 bits/pixel data + * no alpha + * data in msb format + */ +static void +rgb565msb (GdkImage *image, + guchar *pixels, + int rowstride, + int x1, + int y1, + int x2, + int y2, + GdkColormap *colormap) +{ + int xx, yy; + int bpl; + + register guint16 *s; + register guint8 *o; + + guint8 *srow = (guint8*)image->mem + y1 * image->bpl + x1 * image->bpp, *orow = pixels; + + bpl = image->bpl; + + for (yy = y1; yy < y2; yy++) + { + s = (guint16 *) srow; + o = (guint8 *) orow; + for (xx = x1; xx < x2; xx ++) + { + register guint32 data = *s++; +#ifdef LITTLE + data = SWAP16 (data); +#endif + *o++ = R8fromRGB565 (data); + *o++ = G8fromRGB565 (data); + *o++ = B8fromRGB565 (data); + } + srow += bpl; + orow += rowstride; + } +} + +/* + * convert 16 bits/pixel data + * with alpha + * data in lsb format + */ +static void +rgb565alsb (GdkImage *image, + guchar *pixels, + int rowstride, + int x1, + int y1, + int x2, + int y2, + GdkColormap *colormap) +{ + int xx, yy; + int bpl; + + register guint16 *s; + register guint32 *o; + + guint8 *srow = (guint8*)image->mem + y1 * image->bpl + x1 * image->bpp, *orow = pixels; + + bpl = image->bpl; + + for (yy = y1; yy < y2; yy++) + { + s = (guint16 *) srow; + o = (guint32 *) orow; + for (xx = x1; xx < x2; xx ++) + { + register guint32 data = *s++; +#ifdef LITTLE + *o++ = ABGR8888fromRGB565 (data); +#else + data = SWAP16 (data); + *o++ = RGBA8888fromRGB565 (data); +#endif + } + srow += bpl; + orow += rowstride; + } +} + +/* + * convert 16 bits/pixel data + * with alpha + * data in msb format + */ +static void +rgb565amsb (GdkImage *image, + guchar *pixels, + int rowstride, + int x1, + int y1, + int x2, + int y2, + GdkColormap *colormap) +{ + int xx, yy; + int bpl; + + register guint16 *s; + register guint32 *o; + + guint8 *srow = (guint8*)image->mem + y1 * image->bpl + x1 * image->bpp, *orow = pixels; + + bpl = image->bpl; + + for (yy = y1; yy < y2; yy++) + { + s = (guint16 *) srow; + o = (guint32 *) orow; + for (xx = x1; xx < x2; xx ++) + { + register guint32 data = *s++; +#ifdef LITTLE + data = SWAP16 (data); + *o++ = ABGR8888fromRGB565 (data); +#else + *o++ = RGBA8888fromRGB565 (data); +#endif + } + srow += bpl; + orow += rowstride; + } +} + +/* + * convert 15 bits/pixel data + * no alpha + * data in lsb format + */ +static void +rgb555lsb (GdkImage *image, + guchar *pixels, + int rowstride, + int x1, + int y1, + int x2, + int y2, + GdkColormap *colormap) +{ + int xx, yy; + int bpl; + + register guint16 *s; + register guint8 *o; + + guint8 *srow = (guint8*)image->mem + y1 * image->bpl + x1 * image->bpp, *orow = pixels; + + bpl = image->bpl; + + for (yy = y1; yy < y2; yy++) + { + s = (guint16 *) srow; + o = (guint8 *) orow; + for (xx = x1; xx < x2; xx ++) + { + register guint32 data = *s++; +#ifdef BIG + data = SWAP16 (data); +#endif + *o++ = R8fromRGB555 (data); + *o++ = G8fromRGB555 (data); + *o++ = B8fromRGB555 (data); + } + srow += bpl; + orow += rowstride; + } +} + +/* + * convert 15 bits/pixel data + * no alpha + * data in msb format + */ +static void +rgb555msb (GdkImage *image, + guchar *pixels, + int rowstride, + int x1, + int y1, + int x2, + int y2, + GdkColormap *colormap) +{ + int xx, yy; + int bpl; + + register guint16 *s; + register guint8 *o; + + guint8 *srow = (guint8*)image->mem + y1 * image->bpl + x1 * image->bpp, *orow = pixels; + + bpl = image->bpl; + + for (yy = y1; yy < y2; yy++) + { + s = (guint16 *) srow; + o = (guint8 *) orow; + for (xx = x1; xx < x2; xx ++) + { + register guint32 data = *s++; +#ifdef LITTLE + data = SWAP16 (data); +#endif + *o++ = R8fromRGB555 (data); + *o++ = G8fromRGB555 (data); + *o++ = B8fromRGB555 (data); + } + srow += bpl; + orow += rowstride; + } +} + +/* + * convert 15 bits/pixel data + * with alpha + * data in lsb format + */ +static void +rgb555alsb (GdkImage *image, + guchar *pixels, + int rowstride, + int x1, + int y1, + int x2, + int y2, + GdkColormap *colormap) +{ + int xx, yy; + int bpl; + + register guint16 *s; /* read 1 pixels at once */ + register guint32 *o; + + guint8 *srow = (guint8*)image->mem + y1 * image->bpl + x1 * image->bpp, *orow = pixels; + + bpl = image->bpl; + + for (yy = y1; yy < y2; yy++) + { + s = (guint16 *) srow; + o = (guint32 *) orow; + for (xx = x1; xx < x2; xx++) + { + register guint32 data = *s++; +#ifdef LITTLE + *o++ = ABGR8888fromRGB555 (data); +#else + data = SWAP16 (data); + *o++ = RGBA8888fromRGB555 (data); +#endif + } + srow += bpl; + orow += rowstride; + } +} + +/* + * convert 15 bits/pixel data + * with alpha + * data in msb format + */ +static void +rgb555amsb (GdkImage *image, + guchar *pixels, + int rowstride, + int x1, + int y1, + int x2, + int y2, + GdkColormap *colormap) +{ + int xx, yy; + int bpl; + + register guint16 *s; + register guint32 *o; + + guint8 *srow = (guint8*)image->mem + y1 * image->bpl + x1 * image->bpp, *orow = pixels; + + bpl = image->bpl; + + for (yy = y1; yy < y2; yy++) + { + s = (guint16 *) srow; + o = (guint32 *) orow; + for (xx = x1; xx < x2; xx++) + { + register guint32 data = *s++; +#ifdef LITTLE + data = SWAP16 (data); + *o++ = ABGR8888fromRGB555 (data); +#else + *o++ = RGBA8888fromRGB555 (data); +#endif + } + srow += bpl; + orow += rowstride; + } +} + + +static void +rgb888alsb (GdkImage *image, + guchar *pixels, + int rowstride, + int x1, + int y1, + int x2, + int y2, + GdkColormap *colormap) +{ + int xx, yy; + int bpl; + + guint8 *s; /* for byte order swapping */ + guint8 *o; + guint8 *srow = (guint8*)image->mem + y1 * image->bpl + x1 * image->bpp, *orow = pixels; + + bpl = image->bpl; + + d (printf ("32 bits/pixel with alpha\n")); + + /* lsb data */ + for (yy = y1; yy < y2; yy++) + { + s = srow; + o = orow; + for (xx = x1; xx < x2; xx++) + { + *o++ = s[2]; + *o++ = s[1]; + *o++ = s[0]; + *o++ = 0xff; + s += 4; + } + srow += bpl; + orow += rowstride; + } +} + +static void +rgb888lsb (GdkImage *image, + guchar *pixels, + int rowstride, + int x1, + int y1, + int x2, + int y2, + GdkColormap *colormap) +{ + int xx, yy; + int bpl; + + guint8 *srow = (guint8*)image->mem + y1 * image->bpl + x1 * image->bpp, *orow = pixels; + guint8 *o, *s; + + bpl = image->bpl; + + d (printf ("32 bit, lsb, no alpha\n")); + + for (yy = y1; yy < y2; yy++) + { + s = srow; + o = orow; + for (xx = x1; xx < x2; xx++) + { + *o++ = s[2]; + *o++ = s[1]; + *o++ = s[0]; + s += 4; + } + srow += bpl; + orow += rowstride; + } +} + +static void +rgb888amsb (GdkImage *image, + guchar *pixels, + int rowstride, + int x1, + int y1, + int x2, + int y2, + GdkColormap *colormap) +{ + int xx, yy; + int bpl; + + guint8 *srow = (guint8*)image->mem + y1 * image->bpl + x1 * image->bpp, *orow = pixels; + guint32 *o; + guint32 *s; + + d (printf ("32 bit, msb, with alpha\n")); + + bpl = image->bpl; + + /* msb data */ + for (yy = y1; yy < y2; yy++) + { + s = (guint32 *) srow; + o = (guint32 *) orow; + for (xx = x1; xx < x2; xx++) + { +#ifdef LITTLE + *o++ = (*s++ >> 8) | 0xff000000; +#else + *o++ = (*s++ << 8) | 0xff; +#endif + } + srow += bpl; + orow += rowstride; + } +} + +static void +rgb888msb (GdkImage *image, + guchar *pixels, + int rowstride, + int x1, + int y1, + int x2, + int y2, + GdkColormap *colormap) +{ + int xx, yy; + int bpl; + + guint8 *srow = (guint8*)image->mem + y1 * image->bpl + x1 * image->bpp, *orow = pixels; + guint8 *s; + guint8 *o; + + d (printf ("32 bit, msb, no alpha\n")); + + bpl = image->bpl; + + for (yy = y1; yy < y2; yy++) + { + s = srow; + o = orow; + for (xx = x1; xx < x2; xx++) + { + *o++ = s[1]; + *o++ = s[2]; + *o++ = s[3]; + s += 4; + } + srow += bpl; + orow += rowstride; + } +} + +/* + * This should work correctly with any display/any endianness, but will probably + * run quite slow + */ +static void +convert_real_slow (GdkImage *image, + guchar *pixels, + int rowstride, + int x1, + int y1, + int x2, + int y2, + GdkColormap *cmap, + gboolean alpha) +{ + int xx, yy; + guint8 *orow = pixels; + guint8 *o; + guint32 pixel; + GdkVisual *v; + guint8 component; + int i; + + v = gdk_colormap_get_visual (cmap); + + if (image->depth != v->depth) + { + g_warning ("%s: The depth of the source image (%d) doesn't " + "match the depth of the colormap passed in (%d).", + G_STRLOC, image->depth, v->depth); + return; + } + + d(printf("rgb mask/shift/prec = %x:%x:%x %d:%d:%d %d:%d:%d\n", + v->red_mask, v->green_mask, v->blue_mask, + v->red_shift, v->green_shift, v->blue_shift, + v->red_prec, v->green_prec, v->blue_prec)); + + for (yy = y1; yy < y2; yy++) + { + o = orow; + for (xx = x1; xx < x2; xx++) + { + pixel = gdk_image_get_pixel (image, xx, yy); + switch (v->type) + { + /* I assume this is right for static & greyscale's too? */ + case GDK_VISUAL_STATIC_GRAY: + case GDK_VISUAL_GRAYSCALE: + case GDK_VISUAL_STATIC_COLOR: + case GDK_VISUAL_PSEUDO_COLOR: + *o++ = cmap->colors[pixel].red >> 8; + *o++ = cmap->colors[pixel].green >> 8; + *o++ = cmap->colors[pixel].blue >> 8; + break; + case GDK_VISUAL_TRUE_COLOR: + /* This is odd because it must sometimes shift left (otherwise + * I'd just shift >> (*_shift - 8 + *_prec + <0-7>). This logic + * should work for all bit sizes/shifts/etc. + */ + component = 0; + for (i = 24; i < 32; i += v->red_prec) + component |= ((pixel & v->red_mask) << (32 - v->red_shift - v->red_prec)) >> i; + *o++ = component; + component = 0; + for (i = 24; i < 32; i += v->green_prec) + component |= ((pixel & v->green_mask) << (32 - v->green_shift - v->green_prec)) >> i; + *o++ = component; + component = 0; + for (i = 24; i < 32; i += v->blue_prec) + component |= ((pixel & v->blue_mask) << (32 - v->blue_shift - v->blue_prec)) >> i; + *o++ = component; + break; + case GDK_VISUAL_DIRECT_COLOR: + *o++ = cmap->colors[((pixel & v->red_mask) << (32 - v->red_shift - v->red_prec)) >> 24].red >> 8; + *o++ = cmap->colors[((pixel & v->green_mask) << (32 - v->green_shift - v->green_prec)) >> 24].green >> 8; + *o++ = cmap->colors[((pixel & v->blue_mask) << (32 - v->blue_shift - v->blue_prec)) >> 24].blue >> 8; + break; + } + if (alpha) + *o++ = 0xff; + } + orow += rowstride; + } +} + +typedef void (* cfunc) (GdkImage *image, + guchar *pixels, + int rowstride, + int x1, + int y1, + int x2, + int y2, + GdkColormap *cmap); + +static const cfunc convert_map[] = { + rgb1,rgb1,rgb1a,rgb1a, + rgb8,rgb8,rgb8a,rgb8a, + rgb555lsb,rgb555msb,rgb555alsb,rgb555amsb, + rgb565lsb,rgb565msb,rgb565alsb,rgb565amsb, + rgb888lsb,rgb888msb,rgb888alsb,rgb888amsb +}; + +/* + * perform actual conversion + * + * If we can, try and use the optimised code versions, but as a default + * fallback, and always for direct colour, use the generic/slow but complete + * conversion function. + */ +static void +rgbconvert (GdkImage *image, + guchar *pixels, + int rowstride, + gboolean alpha, + int x, + int y, + int width, + int height, + GdkColormap *cmap) +{ + int index; + int bank; + GdkVisual *v; + + g_assert ((x + width) <= image->width); + g_assert ((y + height) <= image->height); + + if (cmap == NULL) + { + /* Only allowed for bitmaps */ + g_return_if_fail (image->depth == 1); + + if (alpha) + bitmap1a (image, pixels, rowstride, + x, y, x + width, y + height); + else + bitmap1 (image, pixels, rowstride, + x, y, x + width, y + height); + + return; + } + + v = gdk_colormap_get_visual (cmap); + + if (image->depth != v->depth) + { + g_warning ("%s: The depth of the source image (%d) doesn't " + "match the depth of the colormap passed in (%d).", + G_STRLOC, image->depth, v->depth); + return; + } + + bank = 5; /* default fallback converter */ + index = (image->byte_order == GDK_MSB_FIRST) | (alpha != 0) << 1; + + d(printf("masks = %x:%x:%x\n", v->red_mask, v->green_mask, v->blue_mask)); + d(printf("image depth = %d, bits per pixel = %d\n", image->depth, image->bits_per_pixel)); + + switch (v->type) + { + /* I assume this is right for static & greyscale's too? */ + case GDK_VISUAL_STATIC_GRAY: + case GDK_VISUAL_GRAYSCALE: + case GDK_VISUAL_STATIC_COLOR: + case GDK_VISUAL_PSEUDO_COLOR: + switch (image->bits_per_pixel) + { + case 1: + bank = 0; + break; + case 8: + if (image->depth == 8) + bank = 1; + break; + } + break; + case GDK_VISUAL_TRUE_COLOR: + switch (image->depth) + { + case 15: + if (v->red_mask == 0x7c00 && v->green_mask == 0x3e0 && v->blue_mask == 0x1f + && image->bits_per_pixel == 16) + bank = 2; + break; + case 16: + if (v->red_mask == 0xf800 && v->green_mask == 0x7e0 && v->blue_mask == 0x1f + && image->bits_per_pixel == 16) + bank = 3; + break; + case 24: + case 32: + if (v->red_mask == 0xff0000 && v->green_mask == 0xff00 && v->blue_mask == 0xff + && image->bits_per_pixel == 32) + bank = 4; + break; + } + break; + case GDK_VISUAL_DIRECT_COLOR: + /* always use the slow version */ + break; + } + + d (g_print ("converting using conversion function in bank %d\n", bank)); + + if (bank == 5) + { + convert_real_slow (image, pixels, rowstride, + x, y, x + width, y + height, + cmap, alpha); + } + else + { + index |= bank << 2; + d (g_print ("converting with index %d\n", index)); + (* convert_map[index]) (image, pixels, rowstride, + x, y, x + width, y + height, + cmap); + } +} + + +/* Exported functions */ + +/** + * gdk_pixbuf_get_from_drawable: + * @dest: (allow-none): Destination pixbuf, or %NULL if a new pixbuf should be created. + * @src: Source drawable. + * @cmap: A colormap if @src doesn't have one set. + * @src_x: Source X coordinate within drawable. + * @src_y: Source Y coordinate within drawable. + * @dest_x: Destination X coordinate in pixbuf, or 0 if @dest is NULL. + * @dest_y: Destination Y coordinate in pixbuf, or 0 if @dest is NULL. + * @width: Width in pixels of region to get. + * @height: Height in pixels of region to get. + * + * Transfers image data from a #GdkDrawable and converts it to an RGB(A) + * representation inside a #GdkPixbuf. In other words, copies + * image data from a server-side drawable to a client-side RGB(A) buffer. + * This allows you to efficiently read individual pixels on the client side. + * + * If the drawable @src has no colormap (gdk_drawable_get_colormap() + * returns %NULL), then a suitable colormap must be specified. + * Typically a #GdkWindow or a pixmap created by passing a #GdkWindow + * to gdk_pixmap_new() will already have a colormap associated with + * it. If the drawable has a colormap, the @cmap argument will be + * ignored. If the drawable is a bitmap (1 bit per pixel pixmap), + * then a colormap is not required; pixels with a value of 1 are + * assumed to be white, and pixels with a value of 0 are assumed to be + * black. For taking screenshots, gdk_colormap_get_system() returns + * the correct colormap to use. + * + * If the specified destination pixbuf @dest is %NULL, then this + * function will create an RGB pixbuf with 8 bits per channel and no + * alpha, with the same size specified by the @width and @height + * arguments. In this case, the @dest_x and @dest_y arguments must be + * specified as 0. If the specified destination pixbuf is not %NULL + * and it contains alpha information, then the filled pixels will be + * set to full opacity (alpha = 255). + * + * If the specified drawable is a pixmap, then the requested source + * rectangle must be completely contained within the pixmap, otherwise + * the function will return %NULL. For pixmaps only (not for windows) + * passing -1 for width or height is allowed to mean the full width + * or height of the pixmap. + * + * If the specified drawable is a window, and the window is off the + * screen, then there is no image data in the obscured/offscreen + * regions to be placed in the pixbuf. The contents of portions of the + * pixbuf corresponding to the offscreen region are undefined. + * + * If the window you're obtaining data from is partially obscured by + * other windows, then the contents of the pixbuf areas corresponding + * to the obscured regions are undefined. + * + * If the target drawable is not mapped (typically because it's + * iconified/minimized or not on the current workspace), then %NULL + * will be returned. + * + * If memory can't be allocated for the return value, %NULL will be returned + * instead. + * + * (In short, there are several ways this function can fail, and if it fails + * it returns %NULL; so check the return value.) + * + * This function calls gdk_drawable_get_image() internally and + * converts the resulting image to a #GdkPixbuf, so the + * documentation for gdk_drawable_get_image() may also be relevant. + * + * Return value: The same pixbuf as @dest if it was non-%NULL, or a newly-created + * pixbuf with a reference count of 1 if no destination pixbuf was specified, or %NULL on error + **/ +GdkPixbuf * +gdk_pixbuf_get_from_drawable (GdkPixbuf *dest, + GdkDrawable *src, + GdkColormap *cmap, + int src_x, int src_y, + int dest_x, int dest_y, + int width, int height) +{ + int src_width, src_height; + GdkImage *image; + int depth; + int x0, y0; + + /* General sanity checks */ + + g_return_val_if_fail (src != NULL, NULL); + + if (GDK_IS_WINDOW (src)) + /* FIXME: this is not perfect, since is_viewable() only tests + * recursively up the Gdk parent window tree, but stops at + * foreign windows or Gdk toplevels. I.e. if a window manager + * unmapped one of its own windows, this won't work. + */ + g_return_val_if_fail (gdk_window_is_viewable (src), NULL); + + if (!dest) + g_return_val_if_fail (dest_x == 0 && dest_y == 0, NULL); + else + { + g_return_val_if_fail (gdk_pixbuf_get_colorspace (dest) == GDK_COLORSPACE_RGB, NULL); + g_return_val_if_fail (gdk_pixbuf_get_n_channels (dest) == 3 || + gdk_pixbuf_get_n_channels (dest) == 4, NULL); + g_return_val_if_fail (gdk_pixbuf_get_bits_per_sample (dest) == 8, NULL); + } + + if (cmap == NULL) + cmap = gdk_drawable_get_colormap (src); + + depth = gdk_drawable_get_depth (src); + + if (depth != 1 && cmap == NULL) + { + g_warning ("%s: Source drawable has no colormap; either pass " + "in a colormap, or set the colormap on the drawable " + "with gdk_drawable_set_colormap()", G_STRLOC); + return NULL; + } + + if (cmap != NULL && depth != cmap->visual->depth) + { + g_warning ("%s: Depth of the source drawable is %d where as " + "the visual depth of the colormap passed is %d", + G_STRLOC, depth, cmap->visual->depth); + return NULL; + } + + /* Coordinate sanity checks */ + + if (GDK_IS_PIXMAP (src)) + { + gdk_drawable_get_size (src, &src_width, &src_height); + if (width < 0) + width = src_width; + if (height < 0) + height = src_height; + + g_return_val_if_fail (src_x >= 0 && src_y >= 0, NULL); + g_return_val_if_fail (src_x + width <= src_width && src_y + height <= src_height, NULL); + } + + /* Create the pixbuf if needed */ + if (!dest) + { + dest = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, width, height); + if (dest == NULL) + return NULL; + } + + if (dest) + { + g_return_val_if_fail (dest_x >= 0 && dest_y >= 0, NULL); + g_return_val_if_fail (dest_x + width <= gdk_pixbuf_get_width (dest), NULL); + g_return_val_if_fail (dest_y + height <= gdk_pixbuf_get_height (dest), NULL); + } + + for (y0 = 0; y0 < height; y0 += GDK_SCRATCH_IMAGE_HEIGHT) + { + gint height1 = MIN (height - y0, GDK_SCRATCH_IMAGE_HEIGHT); + for (x0 = 0; x0 < width; x0 += GDK_SCRATCH_IMAGE_WIDTH) + { + gint xs0, ys0; + + gint width1 = MIN (width - x0, GDK_SCRATCH_IMAGE_WIDTH); + + image = _gdk_image_get_scratch (gdk_drawable_get_screen (src), + width1, height1, depth, &xs0, &ys0); + + gdk_drawable_copy_to_image (src, image, + src_x + x0, src_y + y0, + xs0, ys0, width1, height1); + + gdk_pixbuf_get_from_image (dest, image, cmap, + xs0, ys0, dest_x + x0, dest_y + y0, + width1, height1); + } + } + + return dest; +} + +/** + * gdk_pixbuf_get_from_image: + * @dest: (allow-none): Destination pixbuf, or %NULL if a new pixbuf should be created. + * @src: Source #GdkImage. + * @cmap: (allow-none): A colormap, or %NULL to use the one for @src + * @src_x: Source X coordinate within drawable. + * @src_y: Source Y coordinate within drawable. + * @dest_x: Destination X coordinate in pixbuf, or 0 if @dest is NULL. + * @dest_y: Destination Y coordinate in pixbuf, or 0 if @dest is NULL. + * @width: Width in pixels of region to get. + * @height: Height in pixels of region to get. + * + * Same as gdk_pixbuf_get_from_drawable() but gets the pixbuf from + * an image. + * + * Return value: @dest, newly-created pixbuf if @dest was %NULL, %NULL on error + **/ +GdkPixbuf* +gdk_pixbuf_get_from_image (GdkPixbuf *dest, + GdkImage *src, + GdkColormap *cmap, + int src_x, + int src_y, + int dest_x, + int dest_y, + int width, + int height) +{ + int rowstride, bpp, alpha; + + /* General sanity checks */ + + g_return_val_if_fail (GDK_IS_IMAGE (src), NULL); + + if (!dest) + g_return_val_if_fail (dest_x == 0 && dest_y == 0, NULL); + else + { + g_return_val_if_fail (gdk_pixbuf_get_colorspace (dest) == GDK_COLORSPACE_RGB, NULL); + g_return_val_if_fail (gdk_pixbuf_get_n_channels (dest) == 3 || + gdk_pixbuf_get_n_channels (dest) == 4, NULL); + g_return_val_if_fail (gdk_pixbuf_get_bits_per_sample (dest) == 8, NULL); + } + + if (cmap == NULL) + cmap = gdk_image_get_colormap (src); + + if (src->depth != 1 && cmap == NULL) + { + g_warning ("%s: Source image has no colormap; either pass " + "in a colormap, or set the colormap on the image " + "with gdk_image_set_colormap()", G_STRLOC); + return NULL; + } + + if (cmap != NULL && src->depth != cmap->visual->depth) + { + g_warning ("%s: Depth of the Source image is %d where as " + "the visual depth of the colormap passed is %d", + G_STRLOC, src->depth, cmap->visual->depth); + return NULL; + } + + /* Coordinate sanity checks */ + + g_return_val_if_fail (src_x >= 0 && src_y >= 0, NULL); + g_return_val_if_fail (src_x + width <= src->width && src_y + height <= src->height, NULL); + + if (dest) + { + g_return_val_if_fail (dest_x >= 0 && dest_y >= 0, NULL); + g_return_val_if_fail (dest_x + width <= gdk_pixbuf_get_width (dest), NULL); + g_return_val_if_fail (dest_y + height <= gdk_pixbuf_get_height (dest), NULL); + } + + /* Create the pixbuf if needed */ + if (!dest) + { + dest = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, width, height); + if (dest == NULL) + return NULL; + } + + alpha = gdk_pixbuf_get_has_alpha (dest); + rowstride = gdk_pixbuf_get_rowstride (dest); + bpp = alpha ? 4 : 3; + + /* we offset into the image data based on the position we are + * retrieving from + */ + rgbconvert (src, gdk_pixbuf_get_pixels (dest) + + (dest_y * rowstride) + (dest_x * bpp), + rowstride, + alpha, + src_x, src_y, + width, + height, + cmap); + + return dest; +} + +#define __GDK_PIXBUF_DRAWABLE_C__ +#include "gdkaliasdef.c" diff --git a/libs/tk/ydk/gdkpixbuf-render.c b/libs/tk/ydk/gdkpixbuf-render.c new file mode 100644 index 0000000000..cf0121b084 --- /dev/null +++ b/libs/tk/ydk/gdkpixbuf-render.c @@ -0,0 +1,350 @@ +/* GdkPixbuf library - Rendering functions + * + * Copyright (C) 1999 The Free Software Foundation + * + * Author: Federico Mena-Quintero + * + * 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. + */ + +#include "config.h" +#include +#include +#include "gdkpixbuf.h" +#include "gdkscreen.h" +#include "gdkinternals.h" +#include "gdkalias.h" + + + +/** + * gdk_pixbuf_render_threshold_alpha: + * @pixbuf: A pixbuf. + * @bitmap: Bitmap where the bilevel mask will be painted to. + * @src_x: Source X coordinate. + * @src_y: source Y coordinate. + * @dest_x: Destination X coordinate. + * @dest_y: Destination Y coordinate. + * @width: Width of region to threshold, or -1 to use pixbuf width + * @height: Height of region to threshold, or -1 to use pixbuf height + * @alpha_threshold: Opacity values below this will be painted as zero; all + * other values will be painted as one. + * + * Takes the opacity values in a rectangular portion of a pixbuf and thresholds + * them to produce a bi-level alpha mask that can be used as a clipping mask for + * a drawable. + * + **/ +void +gdk_pixbuf_render_threshold_alpha (GdkPixbuf *pixbuf, + GdkBitmap *bitmap, + int src_x, + int src_y, + int dest_x, + int dest_y, + int width, + int height, + int alpha_threshold) +{ + GdkGC *gc; + GdkColor color; + int x, y; + guchar *p; + int start, start_status; + int status; + + g_return_if_fail (gdk_pixbuf_get_colorspace (pixbuf) == GDK_COLORSPACE_RGB); + g_return_if_fail (gdk_pixbuf_get_n_channels (pixbuf) == 3 || + gdk_pixbuf_get_n_channels (pixbuf) == 4); + g_return_if_fail (gdk_pixbuf_get_bits_per_sample (pixbuf) == 8); + + if (width == -1) + width = gdk_pixbuf_get_width (pixbuf); + if (height == -1) + height = gdk_pixbuf_get_height (pixbuf); + + g_return_if_fail (bitmap != NULL); + g_return_if_fail (width >= 0 && height >= 0); + g_return_if_fail (src_x >= 0 && src_x + width <= gdk_pixbuf_get_width (pixbuf)); + g_return_if_fail (src_y >= 0 && src_y + height <= gdk_pixbuf_get_height (pixbuf)); + + g_return_if_fail (alpha_threshold >= 0 && alpha_threshold <= 255); + + if (width == 0 || height == 0) + return; + + gc = _gdk_drawable_get_scratch_gc (bitmap, FALSE); + + if (!gdk_pixbuf_get_has_alpha (pixbuf)) + { + color.pixel = (alpha_threshold == 255) ? 0 : 1; + gdk_gc_set_foreground (gc, &color); + gdk_draw_rectangle (bitmap, gc, TRUE, dest_x, dest_y, width, height); + return; + } + + color.pixel = 0; + gdk_gc_set_foreground (gc, &color); + gdk_draw_rectangle (bitmap, gc, TRUE, dest_x, dest_y, width, height); + + color.pixel = 1; + gdk_gc_set_foreground (gc, &color); + + for (y = 0; y < height; y++) + { + p = (gdk_pixbuf_get_pixels (pixbuf) + (y + src_y) * gdk_pixbuf_get_rowstride (pixbuf) + src_x * gdk_pixbuf_get_n_channels (pixbuf) + + gdk_pixbuf_get_n_channels (pixbuf) - 1); + + start = 0; + start_status = *p < alpha_threshold; + + for (x = 0; x < width; x++) + { + status = *p < alpha_threshold; + + if (status != start_status) + { + if (!start_status) + gdk_draw_line (bitmap, gc, + start + dest_x, y + dest_y, + x - 1 + dest_x, y + dest_y); + + start = x; + start_status = status; + } + + p += gdk_pixbuf_get_n_channels (pixbuf); + } + + if (!start_status) + gdk_draw_line (bitmap, gc, + start + dest_x, y + dest_y, + x - 1 + dest_x, y + dest_y); + } +} + + + +/** + * gdk_pixbuf_render_to_drawable: + * @pixbuf: A pixbuf. + * @drawable: Destination drawable. + * @gc: GC used for rendering. + * @src_x: Source X coordinate within pixbuf. + * @src_y: Source Y coordinate within pixbuf. + * @dest_x: Destination X coordinate within drawable. + * @dest_y: Destination Y coordinate within drawable. + * @width: Width of region to render, in pixels, or -1 to use pixbuf width + * @height: Height of region to render, in pixels, or -1 to use pixbuf height + * @dither: Dithering mode for GdkRGB. + * @x_dither: X offset for dither. + * @y_dither: Y offset for dither. + * + * Renders a rectangular portion of a pixbuf to a drawable while using the + * specified GC. This is done using GdkRGB, so the specified drawable must have + * the GdkRGB visual and colormap. Note that this function will ignore the + * opacity information for images with an alpha channel; the GC must already + * have the clipping mask set if you want transparent regions to show through. + * + * For an explanation of dither offsets, see the GdkRGB documentation. In + * brief, the dither offset is important when re-rendering partial regions of an + * image to a rendered version of the full image, or for when the offsets to a + * base position change, as in scrolling. The dither matrix has to be shifted + * for consistent visual results. If you do not have any of these cases, the + * dither offsets can be both zero. + * + * Deprecated: 2.4: This function is obsolete. Use gdk_draw_pixbuf() instead. + **/ +void +gdk_pixbuf_render_to_drawable (GdkPixbuf *pixbuf, + GdkDrawable *drawable, + GdkGC *gc, + int src_x, int src_y, + int dest_x, int dest_y, + int width, int height, + GdkRgbDither dither, + int x_dither, int y_dither) +{ + gdk_draw_pixbuf (drawable, gc, pixbuf, + src_x, src_y, dest_x, dest_y, width, height, + dither, x_dither, y_dither); +} + + + +/** + * gdk_pixbuf_render_to_drawable_alpha: + * @pixbuf: A pixbuf. + * @drawable: Destination drawable. + * @src_x: Source X coordinate within pixbuf. + * @src_y: Source Y coordinates within pixbuf. + * @dest_x: Destination X coordinate within drawable. + * @dest_y: Destination Y coordinate within drawable. + * @width: Width of region to render, in pixels, or -1 to use pixbuf width. + * @height: Height of region to render, in pixels, or -1 to use pixbuf height. + * @alpha_mode: Ignored. Present for backwards compatibility. + * @alpha_threshold: Ignored. Present for backwards compatibility + * @dither: Dithering mode for GdkRGB. + * @x_dither: X offset for dither. + * @y_dither: Y offset for dither. + * + * Renders a rectangular portion of a pixbuf to a drawable. The destination + * drawable must have a colormap. All windows have a colormap, however, pixmaps + * only have colormap by default if they were created with a non-%NULL window argument. + * Otherwise a colormap must be set on them with gdk_drawable_set_colormap. + * + * On older X servers, rendering pixbufs with an alpha channel involves round trips + * to the X server, and may be somewhat slow. + * + * Deprecated: 2.4: This function is obsolete. Use gdk_draw_pixbuf() instead. + **/ +void +gdk_pixbuf_render_to_drawable_alpha (GdkPixbuf *pixbuf, + GdkDrawable *drawable, + int src_x, int src_y, + int dest_x, int dest_y, + int width, int height, + GdkPixbufAlphaMode alpha_mode, + int alpha_threshold, + GdkRgbDither dither, + int x_dither, int y_dither) +{ + gdk_draw_pixbuf (drawable, NULL, pixbuf, + src_x, src_y, dest_x, dest_y, width, height, + dither, x_dither, y_dither); +} + +/** + * gdk_pixbuf_render_pixmap_and_mask: + * @pixbuf: A pixbuf. + * @pixmap_return: Location to store a pointer to the created pixmap, + * or %NULL if the pixmap is not needed. + * @mask_return: Location to store a pointer to the created mask, + * or %NULL if the mask is not needed. + * @alpha_threshold: Threshold value for opacity values. + * + * Creates a pixmap and a mask bitmap which are returned in the @pixmap_return + * and @mask_return arguments, respectively, and renders a pixbuf and its + * corresponding thresholded alpha mask to them. This is merely a convenience + * function; applications that need to render pixbufs with dither offsets or to + * given drawables should use gdk_draw_pixbuf() and gdk_pixbuf_render_threshold_alpha(). + * + * The pixmap that is created is created for the colormap returned + * by gdk_rgb_get_colormap(). You normally will want to instead use + * the actual colormap for a widget, and use + * gdk_pixbuf_render_pixmap_and_mask_for_colormap(). + * + * If the pixbuf does not have an alpha channel, then *@mask_return will be set + * to %NULL. + **/ +void +gdk_pixbuf_render_pixmap_and_mask (GdkPixbuf *pixbuf, + GdkPixmap **pixmap_return, + GdkBitmap **mask_return, + int alpha_threshold) +{ + gdk_pixbuf_render_pixmap_and_mask_for_colormap (pixbuf, + gdk_rgb_get_colormap (), + pixmap_return, mask_return, + alpha_threshold); +} + +/** + * gdk_pixbuf_render_pixmap_and_mask_for_colormap: + * @pixbuf: A pixbuf. + * @colormap: A #GdkColormap + * @pixmap_return: Location to store a pointer to the created pixmap, + * or %NULL if the pixmap is not needed. + * @mask_return: Location to store a pointer to the created mask, + * or %NULL if the mask is not needed. + * @alpha_threshold: Threshold value for opacity values. + * + * Creates a pixmap and a mask bitmap which are returned in the @pixmap_return + * and @mask_return arguments, respectively, and renders a pixbuf and its + * corresponding tresholded alpha mask to them. This is merely a convenience + * function; applications that need to render pixbufs with dither offsets or to + * given drawables should use gdk_draw_pixbuf(), and gdk_pixbuf_render_threshold_alpha(). + * + * The pixmap that is created uses the #GdkColormap specified by @colormap. + * This colormap must match the colormap of the window where the pixmap + * will eventually be used or an error will result. + * + * If the pixbuf does not have an alpha channel, then *@mask_return will be set + * to %NULL. + **/ +void +gdk_pixbuf_render_pixmap_and_mask_for_colormap (GdkPixbuf *pixbuf, + GdkColormap *colormap, + GdkPixmap **pixmap_return, + GdkBitmap **mask_return, + int alpha_threshold) +{ + GdkScreen *screen; + + g_return_if_fail (GDK_IS_PIXBUF (pixbuf)); + g_return_if_fail (GDK_IS_COLORMAP (colormap)); + + screen = gdk_colormap_get_screen (colormap); + + if (pixmap_return) + { + GdkGC *gc; + *pixmap_return = gdk_pixmap_new (gdk_screen_get_root_window (screen), + gdk_pixbuf_get_width (pixbuf), gdk_pixbuf_get_height (pixbuf), + gdk_colormap_get_visual (colormap)->depth); + + gdk_drawable_set_colormap (GDK_DRAWABLE (*pixmap_return), colormap); + gc = _gdk_drawable_get_scratch_gc (*pixmap_return, FALSE); + + /* If the pixbuf has an alpha channel, using gdk_pixbuf_draw would give + * random pixel values in the area that are within the mask, but semi- + * transparent. So we treat the pixbuf like a pixbuf without alpha channel; + * see bug #487865. + */ + if (gdk_pixbuf_get_has_alpha (pixbuf)) + gdk_draw_rgb_32_image (*pixmap_return, gc, + 0, 0, + gdk_pixbuf_get_width (pixbuf), gdk_pixbuf_get_height (pixbuf), + GDK_RGB_DITHER_NORMAL, + gdk_pixbuf_get_pixels (pixbuf), gdk_pixbuf_get_rowstride (pixbuf)); + else + gdk_draw_pixbuf (*pixmap_return, gc, pixbuf, + 0, 0, 0, 0, + gdk_pixbuf_get_width (pixbuf), gdk_pixbuf_get_height (pixbuf), + GDK_RGB_DITHER_NORMAL, + 0, 0); + } + + if (mask_return) + { + if (gdk_pixbuf_get_has_alpha (pixbuf)) + { + *mask_return = gdk_pixmap_new (gdk_screen_get_root_window (screen), + gdk_pixbuf_get_width (pixbuf), gdk_pixbuf_get_height (pixbuf), 1); + + gdk_pixbuf_render_threshold_alpha (pixbuf, *mask_return, + 0, 0, 0, 0, + gdk_pixbuf_get_width (pixbuf), gdk_pixbuf_get_height (pixbuf), + alpha_threshold); + } + else + *mask_return = NULL; + } +} + +#define __GDK_PIXBUF_RENDER_C__ +#include "gdkaliasdef.c" + diff --git a/libs/tk/ydk/gdkpixmap.c b/libs/tk/ydk/gdkpixmap.c new file mode 100644 index 0000000000..67ab96cd96 --- /dev/null +++ b/libs/tk/ydk/gdkpixmap.c @@ -0,0 +1,869 @@ +/* GDK - The GIMP Drawing Kit + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, 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 "config.h" +#include "gdkpixmap.h" +#include "gdkinternals.h" +#include "gdkpixbuf.h" +#include "gdkscreen.h" +#include "gdkalias.h" + +static GdkGC *gdk_pixmap_create_gc (GdkDrawable *drawable, + GdkGCValues *values, + GdkGCValuesMask mask); +static void gdk_pixmap_draw_rectangle (GdkDrawable *drawable, + GdkGC *gc, + gboolean filled, + gint x, + gint y, + gint width, + gint height); +static void gdk_pixmap_draw_arc (GdkDrawable *drawable, + GdkGC *gc, + gboolean filled, + gint x, + gint y, + gint width, + gint height, + gint angle1, + gint angle2); +static void gdk_pixmap_draw_polygon (GdkDrawable *drawable, + GdkGC *gc, + gboolean filled, + GdkPoint *points, + gint npoints); +static void gdk_pixmap_draw_text (GdkDrawable *drawable, + GdkFont *font, + GdkGC *gc, + gint x, + gint y, + const gchar *text, + gint text_length); +static void gdk_pixmap_draw_text_wc (GdkDrawable *drawable, + GdkFont *font, + GdkGC *gc, + gint x, + gint y, + const GdkWChar *text, + gint text_length); +static void gdk_pixmap_draw_drawable (GdkDrawable *drawable, + GdkGC *gc, + GdkPixmap *src, + gint xsrc, + gint ysrc, + gint xdest, + gint ydest, + gint width, + gint height, + GdkPixmap *original_src); +static void gdk_pixmap_draw_points (GdkDrawable *drawable, + GdkGC *gc, + GdkPoint *points, + gint npoints); +static void gdk_pixmap_draw_segments (GdkDrawable *drawable, + GdkGC *gc, + GdkSegment *segs, + gint nsegs); +static void gdk_pixmap_draw_lines (GdkDrawable *drawable, + GdkGC *gc, + GdkPoint *points, + gint npoints); + +static void gdk_pixmap_draw_glyphs (GdkDrawable *drawable, + GdkGC *gc, + PangoFont *font, + gint x, + gint y, + PangoGlyphString *glyphs); +static void gdk_pixmap_draw_glyphs_transformed (GdkDrawable *drawable, + GdkGC *gc, + PangoMatrix *matrix, + PangoFont *font, + gint x, + gint y, + PangoGlyphString *glyphs); + +static void gdk_pixmap_draw_image (GdkDrawable *drawable, + GdkGC *gc, + GdkImage *image, + gint xsrc, + gint ysrc, + gint xdest, + gint ydest, + gint width, + gint height); +static void gdk_pixmap_draw_pixbuf (GdkDrawable *drawable, + GdkGC *gc, + GdkPixbuf *pixbuf, + gint src_x, + gint src_y, + gint dest_x, + gint dest_y, + gint width, + gint height, + GdkRgbDither dither, + gint x_dither, + gint y_dither); +static void gdk_pixmap_draw_trapezoids (GdkDrawable *drawable, + GdkGC *gc, + GdkTrapezoid *trapezoids, + gint n_trapezoids); + +static void gdk_pixmap_real_get_size (GdkDrawable *drawable, + gint *width, + gint *height); + +static GdkImage* gdk_pixmap_copy_to_image (GdkDrawable *drawable, + GdkImage *image, + gint src_x, + gint src_y, + gint dest_x, + gint dest_y, + gint width, + gint height); + +static cairo_surface_t *gdk_pixmap_ref_cairo_surface (GdkDrawable *drawable); +static cairo_surface_t *gdk_pixmap_create_cairo_surface (GdkDrawable *drawable, + int width, + int height); + +static GdkVisual* gdk_pixmap_real_get_visual (GdkDrawable *drawable); +static gint gdk_pixmap_real_get_depth (GdkDrawable *drawable); +static void gdk_pixmap_real_set_colormap (GdkDrawable *drawable, + GdkColormap *cmap); +static GdkColormap* gdk_pixmap_real_get_colormap (GdkDrawable *drawable); +static GdkScreen* gdk_pixmap_real_get_screen (GdkDrawable *drawable); + +static void gdk_pixmap_init (GdkPixmapObject *pixmap); +static void gdk_pixmap_class_init (GdkPixmapObjectClass *klass); +static void gdk_pixmap_finalize (GObject *object); + +static gpointer parent_class = NULL; + +GType +gdk_pixmap_get_type (void) +{ + static GType object_type = 0; + + if (!object_type) + object_type = g_type_register_static_simple (GDK_TYPE_DRAWABLE, + "GdkPixmap", + sizeof (GdkPixmapObjectClass), + (GClassInitFunc) gdk_pixmap_class_init, + sizeof (GdkPixmapObject), + (GInstanceInitFunc) gdk_pixmap_init, + 0); + + return object_type; +} + +static void +gdk_pixmap_init (GdkPixmapObject *pixmap) +{ + /* 0-initialization is good for all other fields. */ + pixmap->impl = g_object_new (_gdk_pixmap_impl_get_type (), NULL); +} + +static void +gdk_pixmap_class_init (GdkPixmapObjectClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass); + + parent_class = g_type_class_peek_parent (klass); + + object_class->finalize = gdk_pixmap_finalize; + + drawable_class->create_gc = gdk_pixmap_create_gc; + drawable_class->draw_rectangle = gdk_pixmap_draw_rectangle; + drawable_class->draw_arc = gdk_pixmap_draw_arc; + drawable_class->draw_polygon = gdk_pixmap_draw_polygon; + drawable_class->draw_text = gdk_pixmap_draw_text; + drawable_class->draw_text_wc = gdk_pixmap_draw_text_wc; + drawable_class->draw_drawable_with_src = gdk_pixmap_draw_drawable; + drawable_class->draw_points = gdk_pixmap_draw_points; + drawable_class->draw_segments = gdk_pixmap_draw_segments; + drawable_class->draw_lines = gdk_pixmap_draw_lines; + drawable_class->draw_glyphs = gdk_pixmap_draw_glyphs; + drawable_class->draw_glyphs_transformed = gdk_pixmap_draw_glyphs_transformed; + drawable_class->draw_image = gdk_pixmap_draw_image; + drawable_class->draw_pixbuf = gdk_pixmap_draw_pixbuf; + drawable_class->draw_trapezoids = gdk_pixmap_draw_trapezoids; + drawable_class->get_depth = gdk_pixmap_real_get_depth; + drawable_class->get_screen = gdk_pixmap_real_get_screen; + drawable_class->get_size = gdk_pixmap_real_get_size; + drawable_class->set_colormap = gdk_pixmap_real_set_colormap; + drawable_class->get_colormap = gdk_pixmap_real_get_colormap; + drawable_class->get_visual = gdk_pixmap_real_get_visual; + drawable_class->_copy_to_image = gdk_pixmap_copy_to_image; + drawable_class->ref_cairo_surface = gdk_pixmap_ref_cairo_surface; + drawable_class->create_cairo_surface = gdk_pixmap_create_cairo_surface; +} + +static void +gdk_pixmap_finalize (GObject *object) +{ + GdkPixmapObject *obj = (GdkPixmapObject *) object; + + g_object_unref (obj->impl); + obj->impl = NULL; + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +GdkPixmap * +gdk_pixmap_new (GdkDrawable *drawable, + gint width, + gint height, + gint depth) +{ + GdkDrawable *source_drawable; + + if (drawable) + source_drawable = _gdk_drawable_get_source_drawable (drawable); + else + source_drawable = NULL; + return _gdk_pixmap_new (source_drawable, width, height, depth); +} + +GdkPixmap * +gdk_bitmap_create_from_data (GdkDrawable *drawable, + const gchar *data, + gint width, + gint height) +{ + GdkDrawable *source_drawable; + + if (drawable) + source_drawable = _gdk_drawable_get_source_drawable (drawable); + else + source_drawable = NULL; + return _gdk_bitmap_create_from_data (source_drawable, data, width, height); +} + +GdkPixmap* +gdk_pixmap_create_from_data (GdkDrawable *drawable, + const gchar *data, + gint width, + gint height, + gint depth, + const GdkColor *fg, + const GdkColor *bg) +{ + GdkDrawable *source_drawable; + + source_drawable = _gdk_drawable_get_source_drawable (drawable); + return _gdk_pixmap_create_from_data (source_drawable, + data, width, height, + depth, fg,bg); +} + + +static GdkGC * +gdk_pixmap_create_gc (GdkDrawable *drawable, + GdkGCValues *values, + GdkGCValuesMask mask) +{ + return gdk_gc_new_with_values (((GdkPixmapObject *) drawable)->impl, + values, mask); +} + +static void +gdk_pixmap_draw_rectangle (GdkDrawable *drawable, + GdkGC *gc, + gboolean filled, + gint x, + gint y, + gint width, + gint height) +{ + GdkPixmapObject *private = (GdkPixmapObject *)drawable; + + _gdk_gc_remove_drawable_clip (gc); + gdk_draw_rectangle (private->impl, gc, filled, + x, y, width, height); +} + +static void +gdk_pixmap_draw_arc (GdkDrawable *drawable, + GdkGC *gc, + gboolean filled, + gint x, + gint y, + gint width, + gint height, + gint angle1, + gint angle2) +{ + GdkPixmapObject *private = (GdkPixmapObject *)drawable; + + _gdk_gc_remove_drawable_clip (gc); + gdk_draw_arc (private->impl, gc, filled, + x, y, + width, height, angle1, angle2); +} + +static void +gdk_pixmap_draw_polygon (GdkDrawable *drawable, + GdkGC *gc, + gboolean filled, + GdkPoint *points, + gint npoints) +{ + GdkPixmapObject *private = (GdkPixmapObject *)drawable; + + _gdk_gc_remove_drawable_clip (gc); + gdk_draw_polygon (private->impl, gc, filled, points, npoints); +} + +static void +gdk_pixmap_draw_text (GdkDrawable *drawable, + GdkFont *font, + GdkGC *gc, + gint x, + gint y, + const gchar *text, + gint text_length) +{ + GdkPixmapObject *private = (GdkPixmapObject *)drawable; + + _gdk_gc_remove_drawable_clip (gc); + gdk_draw_text (private->impl, font, gc, + x, y, text, text_length); +} + +static void +gdk_pixmap_draw_text_wc (GdkDrawable *drawable, + GdkFont *font, + GdkGC *gc, + gint x, + gint y, + const GdkWChar *text, + gint text_length) +{ + GdkPixmapObject *private = (GdkPixmapObject *)drawable; + + _gdk_gc_remove_drawable_clip (gc); + gdk_draw_text_wc (private->impl, font, gc, + x, y, text, text_length); +} + +static void +gdk_pixmap_draw_drawable (GdkDrawable *drawable, + GdkGC *gc, + GdkPixmap *src, + gint xsrc, + gint ysrc, + gint xdest, + gint ydest, + gint width, + gint height, + GdkPixmap *original_src) +{ + GdkPixmapObject *private = (GdkPixmapObject *)drawable; + + _gdk_gc_remove_drawable_clip (gc); + /* Call the method directly to avoid getting the composite drawable again */ + GDK_DRAWABLE_GET_CLASS (private->impl)->draw_drawable_with_src (private->impl, gc, + src, + xsrc, ysrc, + xdest, ydest, + width, height, + original_src); +} + +static void +gdk_pixmap_draw_points (GdkDrawable *drawable, + GdkGC *gc, + GdkPoint *points, + gint npoints) +{ + GdkPixmapObject *private = (GdkPixmapObject *)drawable; + + _gdk_gc_remove_drawable_clip (gc); + gdk_draw_points (private->impl, gc, points, npoints); +} + +static void +gdk_pixmap_draw_segments (GdkDrawable *drawable, + GdkGC *gc, + GdkSegment *segs, + gint nsegs) +{ + GdkPixmapObject *private = (GdkPixmapObject *)drawable; + + _gdk_gc_remove_drawable_clip (gc); + gdk_draw_segments (private->impl, gc, segs, nsegs); +} + +static void +gdk_pixmap_draw_lines (GdkDrawable *drawable, + GdkGC *gc, + GdkPoint *points, + gint npoints) +{ + GdkPixmapObject *private = (GdkPixmapObject *)drawable; + + _gdk_gc_remove_drawable_clip (gc); + gdk_draw_lines (private->impl, gc, points, npoints); +} + +static void +gdk_pixmap_draw_glyphs (GdkDrawable *drawable, + GdkGC *gc, + PangoFont *font, + gint x, + gint y, + PangoGlyphString *glyphs) +{ + GdkPixmapObject *private = (GdkPixmapObject *)drawable; + + _gdk_gc_remove_drawable_clip (gc); + gdk_draw_glyphs (private->impl, gc, font, x, y, glyphs); +} + +static void +gdk_pixmap_draw_glyphs_transformed (GdkDrawable *drawable, + GdkGC *gc, + PangoMatrix *matrix, + PangoFont *font, + gint x, + gint y, + PangoGlyphString *glyphs) +{ + GdkPixmapObject *private = (GdkPixmapObject *)drawable; + + _gdk_gc_remove_drawable_clip (gc); + gdk_draw_glyphs_transformed (private->impl, gc, matrix, font, x, y, glyphs); +} + +static void +gdk_pixmap_draw_image (GdkDrawable *drawable, + GdkGC *gc, + GdkImage *image, + gint xsrc, + gint ysrc, + gint xdest, + gint ydest, + gint width, + gint height) +{ + GdkPixmapObject *private = (GdkPixmapObject *)drawable; + + _gdk_gc_remove_drawable_clip (gc); + gdk_draw_image (private->impl, gc, image, xsrc, ysrc, xdest, ydest, + width, height); +} + +static void +gdk_pixmap_draw_pixbuf (GdkDrawable *drawable, + GdkGC *gc, + GdkPixbuf *pixbuf, + gint src_x, + gint src_y, + gint dest_x, + gint dest_y, + gint width, + gint height, + GdkRgbDither dither, + gint x_dither, + gint y_dither) +{ + GdkPixmapObject *private = (GdkPixmapObject *)drawable; + + if (gc) + _gdk_gc_remove_drawable_clip (gc); + gdk_draw_pixbuf (private->impl, gc, pixbuf, + src_x, src_y, dest_x, dest_y, width, height, + dither, x_dither, y_dither); +} + +static void +gdk_pixmap_draw_trapezoids (GdkDrawable *drawable, + GdkGC *gc, + GdkTrapezoid *trapezoids, + gint n_trapezoids) +{ + GdkPixmapObject *private = (GdkPixmapObject *)drawable; + + _gdk_gc_remove_drawable_clip (gc); + gdk_draw_trapezoids (private->impl, gc, trapezoids, n_trapezoids); +} + +static void +gdk_pixmap_real_get_size (GdkDrawable *drawable, + gint *width, + gint *height) +{ + g_return_if_fail (GDK_IS_PIXMAP (drawable)); + + gdk_drawable_get_size (GDK_DRAWABLE (((GdkPixmapObject*)drawable)->impl), + width, height); +} + +static GdkVisual* +gdk_pixmap_real_get_visual (GdkDrawable *drawable) +{ + GdkColormap *colormap; + + g_return_val_if_fail (GDK_IS_PIXMAP (drawable), NULL); + + colormap = gdk_drawable_get_colormap (drawable); + return colormap ? gdk_colormap_get_visual (colormap) : NULL; +} + +static gint +gdk_pixmap_real_get_depth (GdkDrawable *drawable) +{ + gint depth; + + g_return_val_if_fail (GDK_IS_PIXMAP (drawable), 0); + + depth = GDK_PIXMAP_OBJECT (drawable)->depth; + + return depth; +} + +static void +gdk_pixmap_real_set_colormap (GdkDrawable *drawable, + GdkColormap *cmap) +{ + g_return_if_fail (GDK_IS_PIXMAP (drawable)); + + gdk_drawable_set_colormap (((GdkPixmapObject*)drawable)->impl, cmap); +} + +static GdkColormap* +gdk_pixmap_real_get_colormap (GdkDrawable *drawable) +{ + g_return_val_if_fail (GDK_IS_PIXMAP (drawable), NULL); + + return gdk_drawable_get_colormap (((GdkPixmapObject*)drawable)->impl); +} + +static GdkImage* +gdk_pixmap_copy_to_image (GdkDrawable *drawable, + GdkImage *image, + gint src_x, + gint src_y, + gint dest_x, + gint dest_y, + gint width, + gint height) +{ + g_return_val_if_fail (GDK_IS_PIXMAP (drawable), NULL); + + return gdk_drawable_copy_to_image (((GdkPixmapObject*)drawable)->impl, + image, + src_x, src_y, dest_x, dest_y, + width, height); +} + +static cairo_surface_t * +gdk_pixmap_ref_cairo_surface (GdkDrawable *drawable) +{ + return _gdk_drawable_ref_cairo_surface (((GdkPixmapObject*)drawable)->impl); +} + +static cairo_surface_t * +gdk_pixmap_create_cairo_surface (GdkDrawable *drawable, + int width, + int height) +{ + return _gdk_windowing_create_cairo_surface (GDK_PIXMAP_OBJECT(drawable)->impl, + width, height); +} + + + +static GdkBitmap * +make_solid_mask (GdkScreen *screen, gint width, gint height) +{ + GdkBitmap *bitmap; + GdkGC *gc; + GdkGCValues gc_values; + + bitmap = gdk_pixmap_new (gdk_screen_get_root_window (screen), + width, height, 1); + + gc_values.foreground.pixel = 1; + gc = gdk_gc_new_with_values (bitmap, &gc_values, GDK_GC_FOREGROUND); + + gdk_draw_rectangle (bitmap, gc, TRUE, 0, 0, width, height); + + g_object_unref (gc); + + return bitmap; +} + +#define PACKED_COLOR(c) ((((c)->red & 0xff00) << 8) | \ + ((c)->green & 0xff00) | \ + ((c)->blue >> 8)) + +static GdkPixmap * +gdk_pixmap_colormap_new_from_pixbuf (GdkColormap *colormap, + GdkBitmap **mask, + const GdkColor *transparent_color, + GdkPixbuf *pixbuf) +{ + GdkPixmap *pixmap; + GdkPixbuf *render_pixbuf; + GdkGC *tmp_gc; + GdkScreen *screen = gdk_colormap_get_screen (colormap); + + pixmap = gdk_pixmap_new (gdk_screen_get_root_window (screen), + gdk_pixbuf_get_width (pixbuf), + gdk_pixbuf_get_height (pixbuf), + gdk_colormap_get_visual (colormap)->depth); + gdk_drawable_set_colormap (pixmap, colormap); + + if (transparent_color) + { + guint32 packed_color = PACKED_COLOR (transparent_color); + render_pixbuf = gdk_pixbuf_composite_color_simple (pixbuf, + gdk_pixbuf_get_width (pixbuf), + gdk_pixbuf_get_height (pixbuf), + GDK_INTERP_NEAREST, + 255, 16, packed_color, packed_color); + } + else + render_pixbuf = pixbuf; + + tmp_gc = _gdk_drawable_get_scratch_gc (pixmap, FALSE); + gdk_draw_pixbuf (pixmap, tmp_gc, render_pixbuf, 0, 0, 0, 0, + gdk_pixbuf_get_width (render_pixbuf), + gdk_pixbuf_get_height (render_pixbuf), + GDK_RGB_DITHER_NORMAL, 0, 0); + + if (render_pixbuf != pixbuf) + g_object_unref (render_pixbuf); + + if (mask) + gdk_pixbuf_render_pixmap_and_mask_for_colormap (pixbuf, colormap, NULL, mask, 128); + + if (mask && !*mask) + *mask = make_solid_mask (screen, + gdk_pixbuf_get_width (pixbuf), + gdk_pixbuf_get_height (pixbuf)); + + return pixmap; +} + +/** + * gdk_pixmap_colormap_create_from_xpm: + * @drawable: a #GdkDrawable, used to determine default values + * for the new pixmap. Can be %NULL if @colormap is given. + * @colormap: the #GdkColormap that the new pixmap will be use. + * If omitted, the colormap for @window will be used. + * @mask: a pointer to a place to store a bitmap representing + * the transparency mask of the XPM file. Can be %NULL, + * in which case transparency will be ignored. + * @transparent_color: the color to be used for the pixels + * that are transparent in the input file. Can be %NULL, + * in which case a default color will be used. + * @filename: the filename of a file containing XPM data. + * + * Create a pixmap from a XPM file using a particular colormap. + * + * Returns: (transfer none): the #GdkPixmap. + * + * Deprecated: 2.22: Use a #GdkPixbuf instead. You can use + * gdk_pixbuf_new_from_file() to create it. + * If you must use a pixmap, use gdk_pixmap_new() to + * create it and Cairo to draw the pixbuf onto it. + */ +GdkPixmap* +gdk_pixmap_colormap_create_from_xpm (GdkDrawable *drawable, + GdkColormap *colormap, + GdkBitmap **mask, + const GdkColor *transparent_color, + const gchar *filename) +{ + GdkPixbuf *pixbuf; + GdkPixmap *pixmap; + + g_return_val_if_fail (drawable != NULL || colormap != NULL, NULL); + g_return_val_if_fail (drawable == NULL || GDK_IS_DRAWABLE (drawable), NULL); + g_return_val_if_fail (colormap == NULL || GDK_IS_COLORMAP (colormap), NULL); + + if (colormap == NULL) + colormap = gdk_drawable_get_colormap (drawable); + + pixbuf = gdk_pixbuf_new_from_file (filename, NULL); + if (!pixbuf) + return NULL; + + pixmap = gdk_pixmap_colormap_new_from_pixbuf (colormap, mask, transparent_color, pixbuf); + + g_object_unref (pixbuf); + + return pixmap; +} + +/** + * gdk_pixmap_create_from_xpm: + * @drawable: a #GdkDrawable, used to determine default values + * for the new pixmap. + * @mask: (out) a pointer to a place to store a bitmap representing + * the transparency mask of the XPM file. Can be %NULL, + * in which case transparency will be ignored. + * @transparent_color: the color to be used for the pixels + * that are transparent in the input file. Can be %NULL, + * in which case a default color will be used. + * @filename: the filename of a file containing XPM data. + * + * Create a pixmap from a XPM file. + * + * Returns: (transfer none): the #GdkPixmap + * + * Deprecated: 2.22: Use a #GdkPixbuf instead. You can use + * gdk_pixbuf_new_from_file() to create it. + * If you must use a pixmap, use gdk_pixmap_new() to + * create it and Cairo to draw the pixbuf onto it. + */ +GdkPixmap* +gdk_pixmap_create_from_xpm (GdkDrawable *drawable, + GdkBitmap **mask, + const GdkColor *transparent_color, + const gchar *filename) +{ + return gdk_pixmap_colormap_create_from_xpm (drawable, NULL, mask, + transparent_color, filename); +} + +/** + * gdk_pixmap_colormap_create_from_xpm_d: + * @drawable: a #GdkDrawable, used to determine default values + * for the new pixmap. Can be %NULL if @colormap is given. + * @colormap: the #GdkColormap that the new pixmap will be use. + * If omitted, the colormap for @window will be used. + * @mask: a pointer to a place to store a bitmap representing + * the transparency mask of the XPM file. Can be %NULL, + * in which case transparency will be ignored. + * @transparent_color: the color to be used for the pixels + * that are transparent in the input file. Can be %NULL, + * in which case a default color will be used. + * @data: Pointer to a string containing the XPM data. + * + * Create a pixmap from data in XPM format using a particular + * colormap. + * + * Returns: (transfer none): the #GdkPixmap. + * + * Deprecated: 2.22: Use a #GdkPixbuf instead. You can use + * gdk_pixbuf_new_from_xpm_data() to create it. + * If you must use a pixmap, use gdk_pixmap_new() to + * create it and Cairo to draw the pixbuf onto it. + */ +GdkPixmap* +gdk_pixmap_colormap_create_from_xpm_d (GdkDrawable *drawable, + GdkColormap *colormap, + GdkBitmap **mask, + const GdkColor *transparent_color, + gchar **data) +{ + GdkPixbuf *pixbuf; + GdkPixmap *pixmap; + + g_return_val_if_fail (drawable != NULL || colormap != NULL, NULL); + g_return_val_if_fail (drawable == NULL || GDK_IS_DRAWABLE (drawable), NULL); + g_return_val_if_fail (colormap == NULL || GDK_IS_COLORMAP (colormap), NULL); + + if (colormap == NULL) + colormap = gdk_drawable_get_colormap (drawable); + + pixbuf = gdk_pixbuf_new_from_xpm_data ((const char **)data); + if (!pixbuf) + return NULL; + + pixmap = gdk_pixmap_colormap_new_from_pixbuf (colormap, mask, transparent_color, pixbuf); + + g_object_unref (pixbuf); + + return pixmap; +} + +/** + * gdk_pixmap_create_from_xpm_d: + * @drawable: a #GdkDrawable, used to determine default values + * for the new pixmap. + * @mask: (out): Pointer to a place to store a bitmap representing + * the transparency mask of the XPM file. Can be %NULL, + * in which case transparency will be ignored. + * @transparent_color: This color will be used for the pixels + * that are transparent in the input file. Can be %NULL + * in which case a default color will be used. + * @data: Pointer to a string containing the XPM data. + * + * Create a pixmap from data in XPM format. + * + * Returns: (transfer none): the #GdkPixmap. + * + * Deprecated: 2.22: Use a #GdkPixbuf instead. You can use + * gdk_pixbuf_new_from_xpm_data() to create it. + * If you must use a pixmap, use gdk_pixmap_new() to + * create it and Cairo to draw the pixbuf onto it. + */ +GdkPixmap* +gdk_pixmap_create_from_xpm_d (GdkDrawable *drawable, + GdkBitmap **mask, + const GdkColor *transparent_color, + gchar **data) +{ + return gdk_pixmap_colormap_create_from_xpm_d (drawable, NULL, mask, + transparent_color, data); +} + +static GdkScreen* +gdk_pixmap_real_get_screen (GdkDrawable *drawable) +{ + return gdk_drawable_get_screen (GDK_PIXMAP_OBJECT (drawable)->impl); +} + +/** + * gdk_pixmap_get_size: + * @pixmap: a #GdkPixmap + * @width: (out) (allow-none): location to store @pixmap's width, or %NULL + * @height: (out) (allow-none): location to store @pixmap's height, or %NULL + * + * This function is purely to make it possible to query the size of pixmaps + * even when compiling without deprecated symbols and you must use pixmaps. + * It is identical to gdk_drawable_get_size(), but for pixmaps. + * + * Since: 2.24 + **/ +void +gdk_pixmap_get_size (GdkPixmap *pixmap, + gint *width, + gint *height) +{ + g_return_if_fail (GDK_IS_PIXMAP (pixmap)); + + gdk_drawable_get_size (pixmap, width, height); +} + +#define __GDK_PIXMAP_C__ +#include "gdkaliasdef.c" diff --git a/libs/tk/ydk/gdkpolyreg-generic.c b/libs/tk/ydk/gdkpolyreg-generic.c new file mode 100644 index 0000000000..dd2ff89522 --- /dev/null +++ b/libs/tk/ydk/gdkpolyreg-generic.c @@ -0,0 +1,627 @@ +/* $TOG: PolyReg.c /main/15 1998/02/06 17:47:08 kaleb $ */ +/************************************************************************ + +Copyright 1987, 1998 The Open Group + +All Rights Reserved. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +************************************************************************/ +/* $XFree86: xc/lib/X11/PolyReg.c,v 1.4 1998/10/03 08:41:21 dawes Exp $ */ + +#define LARGE_COORDINATE 1000000 +#define SMALL_COORDINATE -LARGE_COORDINATE + +#include "config.h" +#include +#include "gdkregion-generic.h" +#include "gdkpoly-generic.h" +#include "gdkalias.h" + +/* + * InsertEdgeInET + * + * Insert the given edge into the edge table. + * First we must find the correct bucket in the + * Edge table, then find the right slot in the + * bucket. Finally, we can insert it. + * + */ +static void +InsertEdgeInET (EdgeTable *ET, + EdgeTableEntry *ETE, + int scanline, + ScanLineListBlock **SLLBlock, + int *iSLLBlock) +{ + EdgeTableEntry *start, *prev; + ScanLineList *pSLL, *pPrevSLL; + ScanLineListBlock *tmpSLLBlock; + + /* + * find the right bucket to put the edge into + */ + pPrevSLL = &ET->scanlines; + pSLL = pPrevSLL->next; + while (pSLL && (pSLL->scanline < scanline)) + { + pPrevSLL = pSLL; + pSLL = pSLL->next; + } + + /* + * reassign pSLL (pointer to ScanLineList) if necessary + */ + if ((!pSLL) || (pSLL->scanline > scanline)) + { + if (*iSLLBlock > SLLSPERBLOCK-1) + { + tmpSLLBlock = + (ScanLineListBlock *)g_malloc(sizeof(ScanLineListBlock)); + (*SLLBlock)->next = tmpSLLBlock; + tmpSLLBlock->next = (ScanLineListBlock *)NULL; + *SLLBlock = tmpSLLBlock; + *iSLLBlock = 0; + } + pSLL = &((*SLLBlock)->SLLs[(*iSLLBlock)++]); + + pSLL->next = pPrevSLL->next; + pSLL->edgelist = (EdgeTableEntry *)NULL; + pPrevSLL->next = pSLL; + } + pSLL->scanline = scanline; + + /* + * now insert the edge in the right bucket + */ + prev = (EdgeTableEntry *)NULL; + start = pSLL->edgelist; + while (start && (start->bres.minor_axis < ETE->bres.minor_axis)) + { + prev = start; + start = start->next; + } + ETE->next = start; + + if (prev) + prev->next = ETE; + else + pSLL->edgelist = ETE; +} + +/* + * CreateEdgeTable + * + * This routine creates the edge table for + * scan converting polygons. + * The Edge Table (ET) looks like: + * + * EdgeTable + * -------- + * | ymax | ScanLineLists + * |scanline|-->------------>-------------->... + * -------- |scanline| |scanline| + * |edgelist| |edgelist| + * --------- --------- + * | | + * | | + * V V + * list of ETEs list of ETEs + * + * where ETE is an EdgeTableEntry data structure, + * and there is one ScanLineList per scanline at + * which an edge is initially entered. + * + */ + +static void +CreateETandAET (int count, + const GdkPoint *pts, + EdgeTable *ET, + EdgeTableEntry *AET, + EdgeTableEntry *pETEs, + ScanLineListBlock *pSLLBlock) +{ + const GdkPoint *top, *bottom; + const GdkPoint *PrevPt, *CurrPt; + int iSLLBlock = 0; + int dy; + + if (count < 2) return; + + /* + * initialize the Active Edge Table + */ + AET->next = (EdgeTableEntry *)NULL; + AET->back = (EdgeTableEntry *)NULL; + AET->nextWETE = (EdgeTableEntry *)NULL; + AET->bres.minor_axis = SMALL_COORDINATE; + + /* + * initialize the Edge Table. + */ + ET->scanlines.next = (ScanLineList *)NULL; + ET->ymax = SMALL_COORDINATE; + ET->ymin = LARGE_COORDINATE; + pSLLBlock->next = (ScanLineListBlock *)NULL; + + PrevPt = &pts[count-1]; + + /* + * for each vertex in the array of points. + * In this loop we are dealing with two vertices at + * a time -- these make up one edge of the polygon. + */ + while (count--) + { + CurrPt = pts++; + + /* + * find out which point is above and which is below. + */ + if (PrevPt->y > CurrPt->y) + { + bottom = PrevPt, top = CurrPt; + pETEs->ClockWise = 0; + } + else + { + bottom = CurrPt, top = PrevPt; + pETEs->ClockWise = 1; + } + + /* + * don't add horizontal edges to the Edge table. + */ + if (bottom->y != top->y) + { + pETEs->ymax = bottom->y-1; /* -1 so we don't get last scanline */ + + /* + * initialize integer edge algorithm + */ + dy = bottom->y - top->y; + BRESINITPGONSTRUCT(dy, top->x, bottom->x, pETEs->bres); + + InsertEdgeInET(ET, pETEs, top->y, &pSLLBlock, &iSLLBlock); + + if (PrevPt->y > ET->ymax) + ET->ymax = PrevPt->y; + if (PrevPt->y < ET->ymin) + ET->ymin = PrevPt->y; + pETEs++; + } + + PrevPt = CurrPt; + } +} + +/* + * loadAET + * + * This routine moves EdgeTableEntries from the + * EdgeTable into the Active Edge Table, + * leaving them sorted by smaller x coordinate. + * + */ + +static void +loadAET(EdgeTableEntry *AET, + EdgeTableEntry *ETEs) +{ + EdgeTableEntry *pPrevAET; + EdgeTableEntry *tmp; + + pPrevAET = AET; + AET = AET->next; + while (ETEs) + { + while (AET && (AET->bres.minor_axis < ETEs->bres.minor_axis)) + { + pPrevAET = AET; + AET = AET->next; + } + tmp = ETEs->next; + ETEs->next = AET; + if (AET) + AET->back = ETEs; + ETEs->back = pPrevAET; + pPrevAET->next = ETEs; + pPrevAET = ETEs; + + ETEs = tmp; + } +} + +/* + * computeWAET + * + * This routine links the AET by the + * nextWETE (winding EdgeTableEntry) link for + * use by the winding number rule. The final + * Active Edge Table (AET) might look something + * like: + * + * AET + * ---------- --------- --------- + * |ymax | |ymax | |ymax | + * | ... | |... | |... | + * |next |->|next |->|next |->... + * |nextWETE| |nextWETE| |nextWETE| + * --------- --------- ^-------- + * | | | + * V-------------------> V---> ... + * + */ +static void +computeWAET (EdgeTableEntry *AET) +{ + EdgeTableEntry *pWETE; + int inside = 1; + int isInside = 0; + + AET->nextWETE = (EdgeTableEntry *)NULL; + pWETE = AET; + AET = AET->next; + while (AET) + { + if (AET->ClockWise) + isInside++; + else + isInside--; + + if ((!inside && !isInside) || + ( inside && isInside)) + { + pWETE->nextWETE = AET; + pWETE = AET; + inside = !inside; + } + AET = AET->next; + } + pWETE->nextWETE = (EdgeTableEntry *)NULL; +} + +/* + * InsertionSort + * + * Just a simple insertion sort using + * pointers and back pointers to sort the Active + * Edge Table. + * + */ + +static int +InsertionSort (EdgeTableEntry *AET) +{ + EdgeTableEntry *pETEchase; + EdgeTableEntry *pETEinsert; + EdgeTableEntry *pETEchaseBackTMP; + int changed = 0; + + AET = AET->next; + while (AET) + { + pETEinsert = AET; + pETEchase = AET; + while (pETEchase->back->bres.minor_axis > AET->bres.minor_axis) + pETEchase = pETEchase->back; + + AET = AET->next; + if (pETEchase != pETEinsert) + { + pETEchaseBackTMP = pETEchase->back; + pETEinsert->back->next = AET; + if (AET) + AET->back = pETEinsert->back; + pETEinsert->next = pETEchase; + pETEchase->back->next = pETEinsert; + pETEchase->back = pETEinsert; + pETEinsert->back = pETEchaseBackTMP; + changed = 1; + } + } + return(changed); +} + +/* + * Clean up our act. + */ +static void +FreeStorage (ScanLineListBlock *pSLLBlock) +{ + ScanLineListBlock *tmpSLLBlock; + + while (pSLLBlock) + { + tmpSLLBlock = pSLLBlock->next; + g_free (pSLLBlock); + pSLLBlock = tmpSLLBlock; + } +} + +/* + * Create an array of rectangles from a list of points. + * If indeed these things (POINTS, RECTS) are the same, + * then this proc is still needed, because it allocates + * storage for the array, which was allocated on the + * stack by the calling procedure. + * + */ +static int +PtsToRegion (int numFullPtBlocks, + int iCurPtBlock, + POINTBLOCK *FirstPtBlock, + GdkRegion *reg) +{ + GdkRegionBox *rects; + GdkPoint *pts; + POINTBLOCK *CurPtBlock; + int i; + GdkRegionBox *extents; + int numRects; + + extents = ®->extents; + + numRects = ((numFullPtBlocks * NUMPTSTOBUFFER) + iCurPtBlock) >> 1; + + GROWREGION(reg, numRects); + + CurPtBlock = FirstPtBlock; + rects = reg->rects - 1; + numRects = 0; + extents->x1 = G_MAXSHORT, extents->x2 = G_MINSHORT; + + for ( ; numFullPtBlocks >= 0; numFullPtBlocks--) { + /* the loop uses 2 points per iteration */ + i = NUMPTSTOBUFFER >> 1; + if (!numFullPtBlocks) + i = iCurPtBlock >> 1; + for (pts = CurPtBlock->pts; i--; pts += 2) { + if (pts->x == pts[1].x) + continue; + if (numRects && pts->x == rects->x1 && pts->y == rects->y2 && + pts[1].x == rects->x2 && + (numRects == 1 || rects[-1].y1 != rects->y1) && + (i && pts[2].y > pts[1].y)) { + rects->y2 = pts[1].y + 1; + continue; + } + numRects++; + rects++; + rects->x1 = pts->x; rects->y1 = pts->y; + rects->x2 = pts[1].x; rects->y2 = pts[1].y + 1; + if (rects->x1 < extents->x1) + extents->x1 = rects->x1; + if (rects->x2 > extents->x2) + extents->x2 = rects->x2; + } + CurPtBlock = CurPtBlock->next; + } + + if (numRects) { + extents->y1 = reg->rects->y1; + extents->y2 = rects->y2; + } else { + extents->x1 = 0; + extents->y1 = 0; + extents->x2 = 0; + extents->y2 = 0; + } + reg->numRects = numRects; + + return(TRUE); +} + +/** + * gdk_region_polygon: + * @points: an array of #GdkPoint structs + * @n_points: the number of elements in the @points array + * @fill_rule: specifies which pixels are included in the region when the + * polygon overlaps itself. + * + * Creates a new #GdkRegion using the polygon defined by a + * number of points. + * + * Returns: a new #GdkRegion based on the given polygon + * + * Deprecated: 2.22: There is no replacement. For working with paths, please + * use Cairo. + */ +GdkRegion * +gdk_region_polygon (const GdkPoint *points, + gint n_points, + GdkFillRule fill_rule) +{ + GdkRegion *region; + EdgeTableEntry *pAET; /* Active Edge Table */ + int y; /* current scanline */ + int iPts = 0; /* number of pts in buffer */ + EdgeTableEntry *pWETE; /* Winding Edge Table Entry*/ + ScanLineList *pSLL; /* current scanLineList */ + GdkPoint *pts; /* output buffer */ + EdgeTableEntry *pPrevAET; /* ptr to previous AET */ + EdgeTable ET; /* header node for ET */ + EdgeTableEntry AET; /* header node for AET */ + EdgeTableEntry *pETEs; /* EdgeTableEntries pool */ + ScanLineListBlock SLLBlock; /* header for scanlinelist */ + int fixWAET = FALSE; + POINTBLOCK FirstPtBlock, *curPtBlock; /* PtBlock buffers */ + POINTBLOCK *tmpPtBlock; + int numFullPtBlocks = 0; + + region = gdk_region_new (); + + /* special case a rectangle */ + if (((n_points == 4) || + ((n_points == 5) && (points[4].x == points[0].x) && (points[4].y == points[0].y))) && + (((points[0].y == points[1].y) && + (points[1].x == points[2].x) && + (points[2].y == points[3].y) && + (points[3].x == points[0].x)) || + ((points[0].x == points[1].x) && + (points[1].y == points[2].y) && + (points[2].x == points[3].x) && + (points[3].y == points[0].y)))) { + region->extents.x1 = MIN(points[0].x, points[2].x); + region->extents.y1 = MIN(points[0].y, points[2].y); + region->extents.x2 = MAX(points[0].x, points[2].x); + region->extents.y2 = MAX(points[0].y, points[2].y); + if ((region->extents.x1 != region->extents.x2) && + (region->extents.y1 != region->extents.y2)) { + region->numRects = 1; + *(region->rects) = region->extents; + } + return(region); + } + + pETEs = g_new (EdgeTableEntry, n_points); + + pts = FirstPtBlock.pts; + CreateETandAET(n_points, points, &ET, &AET, pETEs, &SLLBlock); + pSLL = ET.scanlines.next; + curPtBlock = &FirstPtBlock; + + if (fill_rule == GDK_EVEN_ODD_RULE) { + /* + * for each scanline + */ + for (y = ET.ymin; y < ET.ymax; y++) { + /* + * Add a new edge to the active edge table when we + * get to the next edge. + */ + if (pSLL != NULL && y == pSLL->scanline) { + loadAET(&AET, pSLL->edgelist); + pSLL = pSLL->next; + } + pPrevAET = &AET; + pAET = AET.next; + + /* + * for each active edge + */ + while (pAET) { + pts->x = pAET->bres.minor_axis, pts->y = y; + pts++, iPts++; + + /* + * send out the buffer + */ + if (iPts == NUMPTSTOBUFFER) { + tmpPtBlock = (POINTBLOCK *)g_malloc(sizeof(POINTBLOCK)); + tmpPtBlock->next = NULL; + curPtBlock->next = tmpPtBlock; + curPtBlock = tmpPtBlock; + pts = curPtBlock->pts; + numFullPtBlocks++; + iPts = 0; + } + EVALUATEEDGEEVENODD(pAET, pPrevAET, y); + } + (void) InsertionSort(&AET); + } + } + else { + /* + * for each scanline + */ + for (y = ET.ymin; y < ET.ymax; y++) { + /* + * Add a new edge to the active edge table when we + * get to the next edge. + */ + if (pSLL != NULL && y == pSLL->scanline) { + loadAET(&AET, pSLL->edgelist); + computeWAET(&AET); + pSLL = pSLL->next; + } + pPrevAET = &AET; + pAET = AET.next; + pWETE = pAET; + + /* + * for each active edge + */ + while (pAET) { + /* + * add to the buffer only those edges that + * are in the Winding active edge table. + */ + if (pWETE == pAET) { + pts->x = pAET->bres.minor_axis, pts->y = y; + pts++, iPts++; + + /* + * send out the buffer + */ + if (iPts == NUMPTSTOBUFFER) { + tmpPtBlock = (POINTBLOCK *)g_malloc(sizeof(POINTBLOCK)); + tmpPtBlock->next = NULL; + curPtBlock->next = tmpPtBlock; + curPtBlock = tmpPtBlock; + pts = curPtBlock->pts; + numFullPtBlocks++; iPts = 0; + } + pWETE = pWETE->nextWETE; + } + EVALUATEEDGEWINDING(pAET, pPrevAET, y, fixWAET); + } + + /* + * recompute the winding active edge table if + * we just resorted or have exited an edge. + */ + if (InsertionSort(&AET) || fixWAET) { + computeWAET(&AET); + fixWAET = FALSE; + } + } + } + FreeStorage(SLLBlock.next); + (void) PtsToRegion(numFullPtBlocks, iPts, &FirstPtBlock, region); + for (curPtBlock = FirstPtBlock.next; --numFullPtBlocks >= 0;) { + tmpPtBlock = curPtBlock->next; + g_free (curPtBlock); + curPtBlock = tmpPtBlock; + } + g_free (pETEs); + return(region); +} + +#define __GDK_POLYREG_GENERIC_C__ +#include "gdkaliasdef.c" diff --git a/libs/tk/ydk/gdkrectangle.c b/libs/tk/ydk/gdkrectangle.c new file mode 100644 index 0000000000..f50fc05897 --- /dev/null +++ b/libs/tk/ydk/gdkrectangle.c @@ -0,0 +1,139 @@ +/* GDK - The GIMP Drawing Kit + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, 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 "config.h" +#include +#include "gdkalias.h" + +/** + * gdk_rectangle_union: + * @src1: a #GdkRectangle + * @src2: a #GdkRectangle + * @dest: (out): return location for the union of @src1 and @src2 + * + * Calculates the union of two rectangles. + * The union of rectangles @src1 and @src2 is the smallest rectangle which + * includes both @src1 and @src2 within it. + * It is allowed for @dest to be the same as either @src1 or @src2. + */ +void +gdk_rectangle_union (const GdkRectangle *src1, + const GdkRectangle *src2, + GdkRectangle *dest) +{ + gint dest_x, dest_y; + + g_return_if_fail (src1 != NULL); + g_return_if_fail (src2 != NULL); + g_return_if_fail (dest != NULL); + + dest_x = MIN (src1->x, src2->x); + dest_y = MIN (src1->y, src2->y); + dest->width = MAX (src1->x + src1->width, src2->x + src2->width) - dest_x; + dest->height = MAX (src1->y + src1->height, src2->y + src2->height) - dest_y; + dest->x = dest_x; + dest->y = dest_y; +} + +/** + * gdk_rectangle_intersect: + * @src1: a #GdkRectangle + * @src2: a #GdkRectangle + * @dest: (out caller-allocates) (allow-none): return location for the + * intersection of @src1 and @src2, or %NULL + * + * Calculates the intersection of two rectangles. It is allowed for + * @dest to be the same as either @src1 or @src2. If the rectangles + * do not intersect, @dest's width and height is set to 0 and its x + * and y values are undefined. If you are only interested in whether + * the rectangles intersect, but not in the intersecting area itself, + * pass %NULL for @dest. + * + * Returns: %TRUE if the rectangles intersect. + */ +gboolean +gdk_rectangle_intersect (const GdkRectangle *src1, + const GdkRectangle *src2, + GdkRectangle *dest) +{ + gint dest_x, dest_y; + gint dest_x2, dest_y2; + gint return_val; + + g_return_val_if_fail (src1 != NULL, FALSE); + g_return_val_if_fail (src2 != NULL, FALSE); + + return_val = FALSE; + + dest_x = MAX (src1->x, src2->x); + dest_y = MAX (src1->y, src2->y); + dest_x2 = MIN (src1->x + src1->width, src2->x + src2->width); + dest_y2 = MIN (src1->y + src1->height, src2->y + src2->height); + + if (dest_x2 > dest_x && dest_y2 > dest_y) + { + if (dest) + { + dest->x = dest_x; + dest->y = dest_y; + dest->width = dest_x2 - dest_x; + dest->height = dest_y2 - dest_y; + } + return_val = TRUE; + } + else if (dest) + { + dest->width = 0; + dest->height = 0; + } + + return return_val; +} + +static GdkRectangle * +gdk_rectangle_copy (const GdkRectangle *rectangle) +{ + GdkRectangle *result = g_new (GdkRectangle, 1); + *result = *rectangle; + + return result; +} + +GType +gdk_rectangle_get_type (void) +{ + static GType our_type = 0; + + if (our_type == 0) + our_type = g_boxed_type_register_static (g_intern_static_string ("GdkRectangle"), + (GBoxedCopyFunc)gdk_rectangle_copy, + (GBoxedFreeFunc)g_free); + return our_type; +} + + +#define __GDK_RECTANGLE_C__ +#include "gdkaliasdef.c" diff --git a/libs/tk/ydk/gdkregion-generic.c b/libs/tk/ydk/gdkregion-generic.c new file mode 100644 index 0000000000..2581ff12d2 --- /dev/null +++ b/libs/tk/ydk/gdkregion-generic.c @@ -0,0 +1,1909 @@ +/* $TOG: Region.c /main/31 1998/02/06 17:50:22 kaleb $ */ +/************************************************************************ + +Copyright 1987, 1988, 1998 The Open Group + +All Rights Reserved. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +************************************************************************/ +/* $XFree86: xc/lib/X11/Region.c,v 1.5 1999/05/09 10:50:01 dawes Exp $ */ +/* + * The functions in this file implement the Region abstraction, similar to one + * used in the X11 sample server. A Region is simply an area, as the name + * implies, and is implemented as a "y-x-banded" array of rectangles. To + * explain: Each Region is made up of a certain number of rectangles sorted + * by y coordinate first, and then by x coordinate. + * + * Furthermore, the rectangles are banded such that every rectangle with a + * given upper-left y coordinate (y1) will have the same lower-right y + * coordinate (y2) and vice versa. If a rectangle has scanlines in a band, it + * will span the entire vertical distance of the band. This means that some + * areas that could be merged into a taller rectangle will be represented as + * several shorter rectangles to account for shorter rectangles to its left + * or right but within its "vertical scope". + * + * An added constraint on the rectangles is that they must cover as much + * horizontal area as possible. E.g. no two rectangles in a band are allowed + * to touch. + * + * Whenever possible, bands will be merged together to cover a greater vertical + * distance (and thus reduce the number of rectangles). Two bands can be merged + * only if the bottom of one touches the top of the other and they have + * rectangles in the same places (of the same width, of course). This maintains + * the y-x-banding that's so nice to have... + */ + +#include "config.h" +#include +#include +#include +#include "gdkregion-generic.h" +#include "gdkalias.h" + +typedef void (* overlapFunc) (GdkRegion *pReg, + GdkRegionBox *r1, + GdkRegionBox *r1End, + GdkRegionBox *r2, + GdkRegionBox *r2End, + gint y1, + gint y2); +typedef void (* nonOverlapFunc) (GdkRegion *pReg, + GdkRegionBox *r, + GdkRegionBox *rEnd, + gint y1, + gint y2); + +static void miRegionCopy (GdkRegion *dstrgn, + const GdkRegion *rgn); +static void miRegionOp (GdkRegion *newReg, + GdkRegion *reg1, + const GdkRegion *reg2, + overlapFunc overlapFn, + nonOverlapFunc nonOverlap1Fn, + nonOverlapFunc nonOverlap2Fn); +static void miSetExtents (GdkRegion *pReg); + +/** + * gdk_region_new: + * + * Creates a new empty #GdkRegion. + * + * Returns: a new empty #GdkRegion + */ +GdkRegion * +gdk_region_new (void) +{ + GdkRegion *temp; + + temp = g_slice_new (GdkRegion); + + temp->numRects = 0; + temp->rects = &temp->extents; + temp->extents.x1 = 0; + temp->extents.y1 = 0; + temp->extents.x2 = 0; + temp->extents.y2 = 0; + temp->size = 1; + + return temp; +} + +GdkRegion * +_gdk_region_new_from_yxbanded_rects (GdkRectangle *rects, + int num_rects) +{ + GdkRegion *temp; + int i; + + temp = g_slice_new (GdkRegion); + + temp->rects = g_new (GdkRegionBox, num_rects); + temp->size = num_rects; + temp->numRects = num_rects; + for (i = 0; i < num_rects; i++) + { + temp->rects[i].x1 = rects[i].x; + temp->rects[i].y1 = rects[i].y; + temp->rects[i].x2 = rects[i].x + rects[i].width; + temp->rects[i].y2 = rects[i].y + rects[i].height; + } + miSetExtents (temp); + + return temp; +} + + +/** + * gdk_region_rectangle: + * @rectangle: a #GdkRectangle + * + * Creates a new region containing the area @rectangle. + * + * Return value: a new region + **/ +GdkRegion * +gdk_region_rectangle (const GdkRectangle *rectangle) +{ + GdkRegion *temp; + + g_return_val_if_fail (rectangle != NULL, NULL); + + if (rectangle->width <= 0 || rectangle->height <= 0) + return gdk_region_new(); + + temp = g_slice_new (GdkRegion); + + temp->numRects = 1; + temp->rects = &temp->extents; + temp->extents.x1 = rectangle->x; + temp->extents.y1 = rectangle->y; + temp->extents.x2 = rectangle->x + rectangle->width; + temp->extents.y2 = rectangle->y + rectangle->height; + temp->size = 1; + + return temp; +} + +/** + * gdk_region_copy: + * @region: a #GdkRegion + * + * Copies @region, creating an identical new region. + * + * Return value: a new region identical to @region + **/ +GdkRegion * +gdk_region_copy (const GdkRegion *region) +{ + GdkRegion *temp; + + g_return_val_if_fail (region != NULL, NULL); + + temp = gdk_region_new (); + + miRegionCopy (temp, region); + + return temp; +} + +/** + * gdk_region_get_clipbox: + * @region: a #GdkRegion + * @rectangle: return location for the clipbox + * + * Obtains the smallest rectangle which includes the entire #GdkRegion. + * + */ +void +gdk_region_get_clipbox (const GdkRegion *region, + GdkRectangle *rectangle) +{ + g_return_if_fail (region != NULL); + g_return_if_fail (rectangle != NULL); + + rectangle->x = region->extents.x1; + rectangle->y = region->extents.y1; + rectangle->width = region->extents.x2 - region->extents.x1; + rectangle->height = region->extents.y2 - region->extents.y1; +} + + +/** + * gdk_region_get_rectangles: + * @region: a #GdkRegion + * @rectangles: (array length=n_rectangles) (transfer container): return location for an array of rectangles + * @n_rectangles: length of returned array + * + * Obtains the area covered by the region as a list of rectangles. + * The array returned in @rectangles must be freed with g_free(). + **/ +void +gdk_region_get_rectangles (const GdkRegion *region, + GdkRectangle **rectangles, + gint *n_rectangles) +{ + gint i; + + g_return_if_fail (region != NULL); + g_return_if_fail (rectangles != NULL); + g_return_if_fail (n_rectangles != NULL); + + *n_rectangles = region->numRects; + *rectangles = g_new (GdkRectangle, region->numRects); + + for (i = 0; i < region->numRects; i++) + { + GdkRegionBox rect; + rect = region->rects[i]; + (*rectangles)[i].x = rect.x1; + (*rectangles)[i].y = rect.y1; + (*rectangles)[i].width = rect.x2 - rect.x1; + (*rectangles)[i].height = rect.y2 - rect.y1; + } +} + +/** + * gdk_region_union_with_rect: + * @region: a #GdkRegion. + * @rect: a #GdkRectangle. + * + * Sets the area of @region to the union of the areas of @region and + * @rect. The resulting area is the set of pixels contained in + * either @region or @rect. + **/ +void +gdk_region_union_with_rect (GdkRegion *region, + const GdkRectangle *rect) +{ + GdkRegion tmp_region; + + g_return_if_fail (region != NULL); + g_return_if_fail (rect != NULL); + + if (rect->width <= 0 || rect->height <= 0) + return; + + tmp_region.rects = &tmp_region.extents; + tmp_region.numRects = 1; + tmp_region.extents.x1 = rect->x; + tmp_region.extents.y1 = rect->y; + tmp_region.extents.x2 = rect->x + rect->width; + tmp_region.extents.y2 = rect->y + rect->height; + tmp_region.size = 1; + + gdk_region_union (region, &tmp_region); +} + +/*- + *----------------------------------------------------------------------- + * miSetExtents -- + * Reset the extents of a region to what they should be. Called by + * miSubtract and miIntersect b/c they can't figure it out along the + * way or do so easily, as miUnion can. + * + * Results: + * None. + * + * Side Effects: + * The region's 'extents' structure is overwritten. + * + *----------------------------------------------------------------------- + */ +static void +miSetExtents (GdkRegion *pReg) +{ + GdkRegionBox *pBox, *pBoxEnd, *pExtents; + + if (pReg->numRects == 0) + { + pReg->extents.x1 = 0; + pReg->extents.y1 = 0; + pReg->extents.x2 = 0; + pReg->extents.y2 = 0; + return; + } + + pExtents = &pReg->extents; + pBox = pReg->rects; + pBoxEnd = &pBox[pReg->numRects - 1]; + + /* + * Since pBox is the first rectangle in the region, it must have the + * smallest y1 and since pBoxEnd is the last rectangle in the region, + * it must have the largest y2, because of banding. Initialize x1 and + * x2 from pBox and pBoxEnd, resp., as good things to initialize them + * to... + */ + pExtents->x1 = pBox->x1; + pExtents->y1 = pBox->y1; + pExtents->x2 = pBoxEnd->x2; + pExtents->y2 = pBoxEnd->y2; + + g_assert(pExtents->y1 < pExtents->y2); + while (pBox <= pBoxEnd) + { + if (pBox->x1 < pExtents->x1) + { + pExtents->x1 = pBox->x1; + } + if (pBox->x2 > pExtents->x2) + { + pExtents->x2 = pBox->x2; + } + pBox++; + } + g_assert(pExtents->x1 < pExtents->x2); +} + +/** + * gdk_region_destroy: + * @region: a #GdkRegion + * + * Destroys a #GdkRegion. + */ +void +gdk_region_destroy (GdkRegion *region) +{ + g_return_if_fail (region != NULL); + + if (region->rects != ®ion->extents) + g_free (region->rects); + g_slice_free (GdkRegion, region); +} + + +/** + * gdk_region_offset: + * @region: a #GdkRegion + * @dx: the distance to move the region horizontally + * @dy: the distance to move the region vertically + * + * Moves a region the specified distance. + */ +void +gdk_region_offset (GdkRegion *region, + gint x, + gint y) +{ + int nbox; + GdkRegionBox *pbox; + + g_return_if_fail (region != NULL); + + pbox = region->rects; + nbox = region->numRects; + + while(nbox--) + { + pbox->x1 += x; + pbox->x2 += x; + pbox->y1 += y; + pbox->y2 += y; + pbox++; + } + if (region->rects != ®ion->extents) + { + region->extents.x1 += x; + region->extents.x2 += x; + region->extents.y1 += y; + region->extents.y2 += y; + } +} + +/* + Utility procedure Compress: + Replace r by the region r', where + p in r' iff (Quantifer m <= dx) (p + m in r), and + Quantifier is Exists if grow is TRUE, For all if grow is FALSE, and + (x,y) + m = (x+m,y) if xdir is TRUE; (x,y+m) if xdir is FALSE. + + Thus, if xdir is TRUE and grow is FALSE, r is replaced by the region + of all points p such that p and the next dx points on the same + horizontal scan line are all in r. We do this using by noting + that p is the head of a run of length 2^i + k iff p is the head + of a run of length 2^i and p+2^i is the head of a run of length + k. Thus, the loop invariant: s contains the region corresponding + to the runs of length shift. r contains the region corresponding + to the runs of length 1 + dxo & (shift-1), where dxo is the original + value of dx. dx = dxo & ~(shift-1). As parameters, s and t are + scratch regions, so that we don't have to allocate them on every + call. +*/ + +#define ZOpRegion(a,b) if (grow) gdk_region_union (a, b); \ + else gdk_region_intersect (a,b) +#define ZShiftRegion(a,b) if (xdir) gdk_region_offset (a,b,0); \ + else gdk_region_offset (a,0,b) + +static void +Compress(GdkRegion *r, + GdkRegion *s, + GdkRegion *t, + guint dx, + int xdir, + int grow) +{ + guint shift = 1; + + miRegionCopy (s, r); + while (dx) + { + if (dx & shift) + { + ZShiftRegion(r, -(int)shift); + ZOpRegion(r, s); + dx -= shift; + if (!dx) break; + } + miRegionCopy (t, s); + ZShiftRegion(s, -(int)shift); + ZOpRegion(s, t); + shift <<= 1; + } +} + +#undef ZOpRegion +#undef ZShiftRegion +#undef ZCopyRegion + +/** + * gdk_region_shrink: + * @region: a #GdkRegion + * @dx: the number of pixels to shrink the region horizontally + * @dy: the number of pixels to shrink the region vertically + * + * Resizes a region by the specified amount. + * Positive values shrink the region. Negative values expand it. + * + * Deprecated: 2.22: There is no replacement for this function. + */ +void +gdk_region_shrink (GdkRegion *region, + int dx, + int dy) +{ + GdkRegion *s, *t; + int grow; + + g_return_if_fail (region != NULL); + + if (!dx && !dy) + return; + + s = gdk_region_new (); + t = gdk_region_new (); + + grow = (dx < 0); + if (grow) + dx = -dx; + if (dx) + Compress(region, s, t, (unsigned) 2*dx, TRUE, grow); + + grow = (dy < 0); + if (grow) + dy = -dy; + if (dy) + Compress(region, s, t, (unsigned) 2*dy, FALSE, grow); + + gdk_region_offset (region, dx, dy); + gdk_region_destroy (s); + gdk_region_destroy (t); +} + + +/*====================================================================== + * Region Intersection + *====================================================================*/ +/*- + *----------------------------------------------------------------------- + * miIntersectO -- + * Handle an overlapping band for miIntersect. + * + * Results: + * None. + * + * Side Effects: + * Rectangles may be added to the region. + * + *----------------------------------------------------------------------- + */ +/* static void*/ +static void +miIntersectO (GdkRegion *pReg, + GdkRegionBox *r1, + GdkRegionBox *r1End, + GdkRegionBox *r2, + GdkRegionBox *r2End, + gint y1, + gint y2) +{ + int x1; + int x2; + GdkRegionBox *pNextRect; + + pNextRect = &pReg->rects[pReg->numRects]; + + while ((r1 != r1End) && (r2 != r2End)) + { + x1 = MAX (r1->x1,r2->x1); + x2 = MIN (r1->x2,r2->x2); + + /* + * If there's any overlap between the two rectangles, add that + * overlap to the new region. + * There's no need to check for subsumption because the only way + * such a need could arise is if some region has two rectangles + * right next to each other. Since that should never happen... + */ + if (x1 < x2) + { + g_assert (y1rects); + pNextRect->x1 = x1; + pNextRect->y1 = y1; + pNextRect->x2 = x2; + pNextRect->y2 = y2; + pReg->numRects += 1; + pNextRect++; + g_assert (pReg->numRects <= pReg->size); + } + + /* + * Need to advance the pointers. Shift the one that extends + * to the right the least, since the other still has a chance to + * overlap with that region's next rectangle, if you see what I mean. + */ + if (r1->x2 < r2->x2) + { + r1++; + } + else if (r2->x2 < r1->x2) + { + r2++; + } + else + { + r1++; + r2++; + } + } +} + +/** + * gdk_region_intersect: + * @source1: a #GdkRegion + * @source2: another #GdkRegion + * + * Sets the area of @source1 to the intersection of the areas of @source1 + * and @source2. The resulting area is the set of pixels contained in + * both @source1 and @source2. + **/ +void +gdk_region_intersect (GdkRegion *source1, + const GdkRegion *source2) +{ + g_return_if_fail (source1 != NULL); + g_return_if_fail (source2 != NULL); + + /* check for trivial reject */ + if ((!(source1->numRects)) || (!(source2->numRects)) || + (!EXTENTCHECK(&source1->extents, &source2->extents))) + source1->numRects = 0; + else + miRegionOp (source1, source1, source2, + miIntersectO, (nonOverlapFunc) NULL, (nonOverlapFunc) NULL); + + /* + * Can't alter source1's extents before miRegionOp depends on the + * extents of the regions being unchanged. Besides, this way there's + * no checking against rectangles that will be nuked due to + * coalescing, so we have to examine fewer rectangles. + */ + miSetExtents(source1); +} + +static void +miRegionCopy (GdkRegion *dstrgn, + const GdkRegion *rgn) +{ + if (dstrgn != rgn) /* don't want to copy to itself */ + { + if (dstrgn->size < rgn->numRects) + { + if (dstrgn->rects != &dstrgn->extents) + g_free (dstrgn->rects); + + dstrgn->rects = g_new (GdkRegionBox, rgn->numRects); + dstrgn->size = rgn->numRects; + } + + dstrgn->numRects = rgn->numRects; + dstrgn->extents = rgn->extents; + + memcpy (dstrgn->rects, rgn->rects, rgn->numRects * sizeof (GdkRegionBox)); + } +} + + +/*====================================================================== + * Generic Region Operator + *====================================================================*/ + +/*- + *----------------------------------------------------------------------- + * miCoalesce -- + * Attempt to merge the boxes in the current band with those in the + * previous one. Used only by miRegionOp. + * + * Results: + * The new index for the previous band. + * + * Side Effects: + * If coalescing takes place: + * - rectangles in the previous band will have their y2 fields + * altered. + * - pReg->numRects will be decreased. + * + *----------------------------------------------------------------------- + */ +/* static int*/ +static int +miCoalesce (GdkRegion *pReg, /* Region to coalesce */ + gint prevStart, /* Index of start of previous band */ + gint curStart) /* Index of start of current band */ +{ + GdkRegionBox *pPrevBox; /* Current box in previous band */ + GdkRegionBox *pCurBox; /* Current box in current band */ + GdkRegionBox *pRegEnd; /* End of region */ + int curNumRects; /* Number of rectangles in current + * band */ + int prevNumRects; /* Number of rectangles in previous + * band */ + int bandY1; /* Y1 coordinate for current band */ + + pRegEnd = &pReg->rects[pReg->numRects]; + + pPrevBox = &pReg->rects[prevStart]; + prevNumRects = curStart - prevStart; + + /* + * Figure out how many rectangles are in the current band. Have to do + * this because multiple bands could have been added in miRegionOp + * at the end when one region has been exhausted. + */ + pCurBox = &pReg->rects[curStart]; + bandY1 = pCurBox->y1; + for (curNumRects = 0; + (pCurBox != pRegEnd) && (pCurBox->y1 == bandY1); + curNumRects++) + { + pCurBox++; + } + + if (pCurBox != pRegEnd) + { + /* + * If more than one band was added, we have to find the start + * of the last band added so the next coalescing job can start + * at the right place... (given when multiple bands are added, + * this may be pointless -- see above). + */ + pRegEnd--; + while (pRegEnd[-1].y1 == pRegEnd->y1) + { + pRegEnd--; + } + curStart = pRegEnd - pReg->rects; + pRegEnd = pReg->rects + pReg->numRects; + } + + if ((curNumRects == prevNumRects) && (curNumRects != 0)) { + pCurBox -= curNumRects; + /* + * The bands may only be coalesced if the bottom of the previous + * matches the top scanline of the current. + */ + if (pPrevBox->y2 == pCurBox->y1) + { + /* + * Make sure the bands have boxes in the same places. This + * assumes that boxes have been added in such a way that they + * cover the most area possible. I.e. two boxes in a band must + * have some horizontal space between them. + */ + do + { + if ((pPrevBox->x1 != pCurBox->x1) || + (pPrevBox->x2 != pCurBox->x2)) + { + /* + * The bands don't line up so they can't be coalesced. + */ + return (curStart); + } + pPrevBox++; + pCurBox++; + prevNumRects -= 1; + } while (prevNumRects != 0); + + pReg->numRects -= curNumRects; + pCurBox -= curNumRects; + pPrevBox -= curNumRects; + + /* + * The bands may be merged, so set the bottom y of each box + * in the previous band to that of the corresponding box in + * the current band. + */ + do + { + pPrevBox->y2 = pCurBox->y2; + pPrevBox++; + pCurBox++; + curNumRects -= 1; + } + while (curNumRects != 0); + + /* + * If only one band was added to the region, we have to backup + * curStart to the start of the previous band. + * + * If more than one band was added to the region, copy the + * other bands down. The assumption here is that the other bands + * came from the same region as the current one and no further + * coalescing can be done on them since it's all been done + * already... curStart is already in the right place. + */ + if (pCurBox == pRegEnd) + { + curStart = prevStart; + } + else + { + do + { + *pPrevBox++ = *pCurBox++; + } + while (pCurBox != pRegEnd); + } + + } + } + return curStart; +} + +/*- + *----------------------------------------------------------------------- + * miRegionOp -- + * Apply an operation to two regions. Called by miUnion, miInverse, + * miSubtract, miIntersect... + * + * Results: + * None. + * + * Side Effects: + * The new region is overwritten. + * + * Notes: + * The idea behind this function is to view the two regions as sets. + * Together they cover a rectangle of area that this function divides + * into horizontal bands where points are covered only by one region + * or by both. For the first case, the nonOverlapFunc is called with + * each the band and the band's upper and lower extents. For the + * second, the overlapFunc is called to process the entire band. It + * is responsible for clipping the rectangles in the band, though + * this function provides the boundaries. + * At the end of each band, the new region is coalesced, if possible, + * to reduce the number of rectangles in the region. + * + *----------------------------------------------------------------------- + */ +/* static void*/ +static void +miRegionOp(GdkRegion *newReg, + GdkRegion *reg1, + const GdkRegion *reg2, + overlapFunc overlapFn, /* Function to call for over- + * lapping bands */ + nonOverlapFunc nonOverlap1Fn, /* Function to call for non- + * overlapping bands in region + * 1 */ + nonOverlapFunc nonOverlap2Fn) /* Function to call for non- + * overlapping bands in region + * 2 */ +{ + GdkRegionBox *r1; /* Pointer into first region */ + GdkRegionBox *r2; /* Pointer into 2d region */ + GdkRegionBox *r1End; /* End of 1st region */ + GdkRegionBox *r2End; /* End of 2d region */ + int ybot; /* Bottom of intersection */ + int ytop; /* Top of intersection */ + GdkRegionBox *oldRects; /* Old rects for newReg */ + int prevBand; /* Index of start of + * previous band in newReg */ + int curBand; /* Index of start of current + * band in newReg */ + GdkRegionBox *r1BandEnd; /* End of current band in r1 */ + GdkRegionBox *r2BandEnd; /* End of current band in r2 */ + int top; /* Top of non-overlapping + * band */ + int bot; /* Bottom of non-overlapping + * band */ + + /* + * Initialization: + * set r1, r2, r1End and r2End appropriately, preserve the important + * parts of the destination region until the end in case it's one of + * the two source regions, then mark the "new" region empty, allocating + * another array of rectangles for it to use. + */ + r1 = reg1->rects; + r2 = reg2->rects; + r1End = r1 + reg1->numRects; + r2End = r2 + reg2->numRects; + + oldRects = newReg->rects; + + EMPTY_REGION(newReg); + + /* + * Allocate a reasonable number of rectangles for the new region. The idea + * is to allocate enough so the individual functions don't need to + * reallocate and copy the array, which is time consuming, yet we don't + * have to worry about using too much memory. I hope to be able to + * nuke the Xrealloc() at the end of this function eventually. + */ + newReg->size = MAX (reg1->numRects, reg2->numRects) * 2; + newReg->rects = g_new (GdkRegionBox, newReg->size); + + /* + * Initialize ybot and ytop. + * In the upcoming loop, ybot and ytop serve different functions depending + * on whether the band being handled is an overlapping or non-overlapping + * band. + * In the case of a non-overlapping band (only one of the regions + * has points in the band), ybot is the bottom of the most recent + * intersection and thus clips the top of the rectangles in that band. + * ytop is the top of the next intersection between the two regions and + * serves to clip the bottom of the rectangles in the current band. + * For an overlapping band (where the two regions intersect), ytop clips + * the top of the rectangles of both regions and ybot clips the bottoms. + */ + if (reg1->extents.y1 < reg2->extents.y1) + ybot = reg1->extents.y1; + else + ybot = reg2->extents.y1; + + /* + * prevBand serves to mark the start of the previous band so rectangles + * can be coalesced into larger rectangles. qv. miCoalesce, above. + * In the beginning, there is no previous band, so prevBand == curBand + * (curBand is set later on, of course, but the first band will always + * start at index 0). prevBand and curBand must be indices because of + * the possible expansion, and resultant moving, of the new region's + * array of rectangles. + */ + prevBand = 0; + + do + { + curBand = newReg->numRects; + + /* + * This algorithm proceeds one source-band (as opposed to a + * destination band, which is determined by where the two regions + * intersect) at a time. r1BandEnd and r2BandEnd serve to mark the + * rectangle after the last one in the current band for their + * respective regions. + */ + r1BandEnd = r1; + while ((r1BandEnd != r1End) && (r1BandEnd->y1 == r1->y1)) + { + r1BandEnd++; + } + + r2BandEnd = r2; + while ((r2BandEnd != r2End) && (r2BandEnd->y1 == r2->y1)) + { + r2BandEnd++; + } + + /* + * First handle the band that doesn't intersect, if any. + * + * Note that attention is restricted to one band in the + * non-intersecting region at once, so if a region has n + * bands between the current position and the next place it overlaps + * the other, this entire loop will be passed through n times. + */ + if (r1->y1 < r2->y1) + { + top = MAX (r1->y1,ybot); + bot = MIN (r1->y2,r2->y1); + + if ((top != bot) && (nonOverlap1Fn != (void (*)())NULL)) + { + (* nonOverlap1Fn) (newReg, r1, r1BandEnd, top, bot); + } + + ytop = r2->y1; + } + else if (r2->y1 < r1->y1) + { + top = MAX (r2->y1,ybot); + bot = MIN (r2->y2,r1->y1); + + if ((top != bot) && (nonOverlap2Fn != (void (*)())NULL)) + { + (* nonOverlap2Fn) (newReg, r2, r2BandEnd, top, bot); + } + + ytop = r1->y1; + } + else + { + ytop = r1->y1; + } + + /* + * If any rectangles got added to the region, try and coalesce them + * with rectangles from the previous band. Note we could just do + * this test in miCoalesce, but some machines incur a not + * inconsiderable cost for function calls, so... + */ + if (newReg->numRects != curBand) + { + prevBand = miCoalesce (newReg, prevBand, curBand); + } + + /* + * Now see if we've hit an intersecting band. The two bands only + * intersect if ybot > ytop + */ + ybot = MIN (r1->y2, r2->y2); + curBand = newReg->numRects; + if (ybot > ytop) + { + (* overlapFn) (newReg, r1, r1BandEnd, r2, r2BandEnd, ytop, ybot); + + } + + if (newReg->numRects != curBand) + { + prevBand = miCoalesce (newReg, prevBand, curBand); + } + + /* + * If we've finished with a band (y2 == ybot) we skip forward + * in the region to the next band. + */ + if (r1->y2 == ybot) + { + r1 = r1BandEnd; + } + if (r2->y2 == ybot) + { + r2 = r2BandEnd; + } + } while ((r1 != r1End) && (r2 != r2End)); + + /* + * Deal with whichever region still has rectangles left. + */ + curBand = newReg->numRects; + if (r1 != r1End) + { + if (nonOverlap1Fn != (nonOverlapFunc )NULL) + { + do + { + r1BandEnd = r1; + while ((r1BandEnd < r1End) && (r1BandEnd->y1 == r1->y1)) + { + r1BandEnd++; + } + (* nonOverlap1Fn) (newReg, r1, r1BandEnd, + MAX (r1->y1,ybot), r1->y2); + r1 = r1BandEnd; + } while (r1 != r1End); + } + } + else if ((r2 != r2End) && (nonOverlap2Fn != (nonOverlapFunc) NULL)) + { + do + { + r2BandEnd = r2; + while ((r2BandEnd < r2End) && (r2BandEnd->y1 == r2->y1)) + { + r2BandEnd++; + } + (* nonOverlap2Fn) (newReg, r2, r2BandEnd, + MAX (r2->y1,ybot), r2->y2); + r2 = r2BandEnd; + } while (r2 != r2End); + } + + if (newReg->numRects != curBand) + { + (void) miCoalesce (newReg, prevBand, curBand); + } + + /* + * A bit of cleanup. To keep regions from growing without bound, + * we shrink the array of rectangles to match the new number of + * rectangles in the region. This never goes to 0, however... + * + * Only do this stuff if the number of rectangles allocated is more than + * twice the number of rectangles in the region (a simple optimization...). + */ + if (newReg->numRects < (newReg->size >> 1)) + { + if (REGION_NOT_EMPTY (newReg)) + { + newReg->size = newReg->numRects; + newReg->rects = g_renew (GdkRegionBox, newReg->rects, newReg->size); + } + else + { + /* + * No point in doing the extra work involved in an Xrealloc if + * the region is empty + */ + newReg->size = 1; + g_free (newReg->rects); + newReg->rects = &newReg->extents; + } + } + + if (oldRects != &newReg->extents) + g_free (oldRects); +} + + +/*====================================================================== + * Region Union + *====================================================================*/ + +/*- + *----------------------------------------------------------------------- + * miUnionNonO -- + * Handle a non-overlapping band for the union operation. Just + * Adds the rectangles into the region. Doesn't have to check for + * subsumption or anything. + * + * Results: + * None. + * + * Side Effects: + * pReg->numRects is incremented and the final rectangles overwritten + * with the rectangles we're passed. + * + *----------------------------------------------------------------------- + */ +static void +miUnionNonO (GdkRegion *pReg, + GdkRegionBox *r, + GdkRegionBox *rEnd, + gint y1, + gint y2) +{ + GdkRegionBox *pNextRect; + + pNextRect = &pReg->rects[pReg->numRects]; + + g_assert(y1 < y2); + + while (r != rEnd) + { + g_assert(r->x1 < r->x2); + MEMCHECK(pReg, pNextRect, pReg->rects); + pNextRect->x1 = r->x1; + pNextRect->y1 = y1; + pNextRect->x2 = r->x2; + pNextRect->y2 = y2; + pReg->numRects += 1; + pNextRect++; + + g_assert(pReg->numRects<=pReg->size); + r++; + } +} + + +/*- + *----------------------------------------------------------------------- + * miUnionO -- + * Handle an overlapping band for the union operation. Picks the + * left-most rectangle each time and merges it into the region. + * + * Results: + * None. + * + * Side Effects: + * Rectangles are overwritten in pReg->rects and pReg->numRects will + * be changed. + * + *----------------------------------------------------------------------- + */ + +/* static void*/ +static void +miUnionO (GdkRegion *pReg, + GdkRegionBox *r1, + GdkRegionBox *r1End, + GdkRegionBox *r2, + GdkRegionBox *r2End, + gint y1, + gint y2) +{ + GdkRegionBox * pNextRect; + + pNextRect = &pReg->rects[pReg->numRects]; + +#define MERGERECT(r) \ + if ((pReg->numRects != 0) && \ + (pNextRect[-1].y1 == y1) && \ + (pNextRect[-1].y2 == y2) && \ + (pNextRect[-1].x2 >= r->x1)) \ + { \ + if (pNextRect[-1].x2 < r->x2) \ + { \ + pNextRect[-1].x2 = r->x2; \ + g_assert(pNextRect[-1].x1rects); \ + pNextRect->y1 = y1; \ + pNextRect->y2 = y2; \ + pNextRect->x1 = r->x1; \ + pNextRect->x2 = r->x2; \ + pReg->numRects += 1; \ + pNextRect += 1; \ + } \ + g_assert(pReg->numRects<=pReg->size); \ + r++; + + g_assert (y1x1 < r2->x1) + { + MERGERECT(r1); + } + else + { + MERGERECT(r2); + } + } + + if (r1 != r1End) + { + do + { + MERGERECT(r1); + } while (r1 != r1End); + } + else while (r2 != r2End) + { + MERGERECT(r2); + } +} + +/** + * gdk_region_union: + * @source1: a #GdkRegion + * @source2: a #GdkRegion + * + * Sets the area of @source1 to the union of the areas of @source1 and + * @source2. The resulting area is the set of pixels contained in + * either @source1 or @source2. + **/ +void +gdk_region_union (GdkRegion *source1, + const GdkRegion *source2) +{ + g_return_if_fail (source1 != NULL); + g_return_if_fail (source2 != NULL); + + /* checks all the simple cases */ + + /* + * source1 and source2 are the same or source2 is empty + */ + if ((source1 == source2) || (!(source2->numRects))) + return; + + /* + * source1 is empty + */ + if (!(source1->numRects)) + { + miRegionCopy (source1, source2); + return; + } + + /* + * source1 completely subsumes source2 + */ + if ((source1->numRects == 1) && + (source1->extents.x1 <= source2->extents.x1) && + (source1->extents.y1 <= source2->extents.y1) && + (source1->extents.x2 >= source2->extents.x2) && + (source1->extents.y2 >= source2->extents.y2)) + return; + + /* + * source2 completely subsumes source1 + */ + if ((source2->numRects == 1) && + (source2->extents.x1 <= source1->extents.x1) && + (source2->extents.y1 <= source1->extents.y1) && + (source2->extents.x2 >= source1->extents.x2) && + (source2->extents.y2 >= source1->extents.y2)) + { + miRegionCopy(source1, source2); + return; + } + + miRegionOp (source1, source1, source2, miUnionO, + miUnionNonO, miUnionNonO); + + source1->extents.x1 = MIN (source1->extents.x1, source2->extents.x1); + source1->extents.y1 = MIN (source1->extents.y1, source2->extents.y1); + source1->extents.x2 = MAX (source1->extents.x2, source2->extents.x2); + source1->extents.y2 = MAX (source1->extents.y2, source2->extents.y2); +} + + +/*====================================================================== + * Region Subtraction + *====================================================================*/ + +/*- + *----------------------------------------------------------------------- + * miSubtractNonO -- + * Deal with non-overlapping band for subtraction. Any parts from + * region 2 we discard. Anything from region 1 we add to the region. + * + * Results: + * None. + * + * Side Effects: + * pReg may be affected. + * + *----------------------------------------------------------------------- + */ +/* static void*/ +static void +miSubtractNonO1 (GdkRegion *pReg, + GdkRegionBox *r, + GdkRegionBox *rEnd, + gint y1, + gint y2) +{ + GdkRegionBox * pNextRect; + + pNextRect = &pReg->rects[pReg->numRects]; + + g_assert(y1x1x2); + MEMCHECK (pReg, pNextRect, pReg->rects); + pNextRect->x1 = r->x1; + pNextRect->y1 = y1; + pNextRect->x2 = r->x2; + pNextRect->y2 = y2; + pReg->numRects += 1; + pNextRect++; + + g_assert (pReg->numRects <= pReg->size); + + r++; + } +} + +/*- + *----------------------------------------------------------------------- + * miSubtractO -- + * Overlapping band subtraction. x1 is the left-most point not yet + * checked. + * + * Results: + * None. + * + * Side Effects: + * pReg may have rectangles added to it. + * + *----------------------------------------------------------------------- + */ +/* static void*/ +static void +miSubtractO (GdkRegion *pReg, + GdkRegionBox *r1, + GdkRegionBox *r1End, + GdkRegionBox *r2, + GdkRegionBox *r2End, + gint y1, + gint y2) +{ + GdkRegionBox * pNextRect; + int x1; + + x1 = r1->x1; + + g_assert(y1rects[pReg->numRects]; + + while ((r1 != r1End) && (r2 != r2End)) + { + if (r2->x2 <= x1) + { + /* + * Subtrahend missed the boat: go to next subtrahend. + */ + r2++; + } + else if (r2->x1 <= x1) + { + /* + * Subtrahend preceeds minuend: nuke left edge of minuend. + */ + x1 = r2->x2; + if (x1 >= r1->x2) + { + /* + * Minuend completely covered: advance to next minuend and + * reset left fence to edge of new minuend. + */ + r1++; + if (r1 != r1End) + x1 = r1->x1; + } + else + { + /* + * Subtrahend now used up since it doesn't extend beyond + * minuend + */ + r2++; + } + } + else if (r2->x1 < r1->x2) + { + /* + * Left part of subtrahend covers part of minuend: add uncovered + * part of minuend to region and skip to next subtrahend. + */ + g_assert(x1x1); + MEMCHECK(pReg, pNextRect, pReg->rects); + pNextRect->x1 = x1; + pNextRect->y1 = y1; + pNextRect->x2 = r2->x1; + pNextRect->y2 = y2; + pReg->numRects += 1; + pNextRect++; + + g_assert(pReg->numRects<=pReg->size); + + x1 = r2->x2; + if (x1 >= r1->x2) + { + /* + * Minuend used up: advance to new... + */ + r1++; + if (r1 != r1End) + x1 = r1->x1; + } + else + { + /* + * Subtrahend used up + */ + r2++; + } + } + else + { + /* + * Minuend used up: add any remaining piece before advancing. + */ + if (r1->x2 > x1) + { + MEMCHECK(pReg, pNextRect, pReg->rects); + pNextRect->x1 = x1; + pNextRect->y1 = y1; + pNextRect->x2 = r1->x2; + pNextRect->y2 = y2; + pReg->numRects += 1; + pNextRect++; + g_assert(pReg->numRects<=pReg->size); + } + r1++; + if (r1 != r1End) + x1 = r1->x1; + } + } + + /* + * Add remaining minuend rectangles to region. + */ + while (r1 != r1End) + { + g_assert(x1x2); + MEMCHECK(pReg, pNextRect, pReg->rects); + pNextRect->x1 = x1; + pNextRect->y1 = y1; + pNextRect->x2 = r1->x2; + pNextRect->y2 = y2; + pReg->numRects += 1; + pNextRect++; + + g_assert(pReg->numRects<=pReg->size); + + r1++; + if (r1 != r1End) + { + x1 = r1->x1; + } + } +} + +/** + * gdk_region_subtract: + * @source1: a #GdkRegion + * @source2: another #GdkRegion + * + * Subtracts the area of @source2 from the area @source1. The resulting + * area is the set of pixels contained in @source1 but not in @source2. + **/ +void +gdk_region_subtract (GdkRegion *source1, + const GdkRegion *source2) +{ + g_return_if_fail (source1 != NULL); + g_return_if_fail (source2 != NULL); + + /* check for trivial reject */ + if ((!(source1->numRects)) || (!(source2->numRects)) || + (!EXTENTCHECK(&source1->extents, &source2->extents))) + return; + + miRegionOp (source1, source1, source2, miSubtractO, + miSubtractNonO1, (nonOverlapFunc) NULL); + + /* + * Can't alter source1's extents before we call miRegionOp because miRegionOp + * depends on the extents of those regions being the unaltered. Besides, this + * way there's no checking against rectangles that will be nuked + * due to coalescing, so we have to examine fewer rectangles. + */ + miSetExtents (source1); +} + +/** + * gdk_region_xor: + * @source1: a #GdkRegion + * @source2: another #GdkRegion + * + * Sets the area of @source1 to the exclusive-OR of the areas of @source1 + * and @source2. The resulting area is the set of pixels contained in one + * or the other of the two sources but not in both. + **/ +void +gdk_region_xor (GdkRegion *source1, + const GdkRegion *source2) +{ + GdkRegion *trb; + + g_return_if_fail (source1 != NULL); + g_return_if_fail (source2 != NULL); + + trb = gdk_region_copy (source2); + + gdk_region_subtract (trb, source1); + gdk_region_subtract (source1, source2); + + gdk_region_union (source1, trb); + + gdk_region_destroy (trb); +} + +/** + * gdk_region_empty: + * @region: a #GdkRegion + * + * Finds out if the #GdkRegion is empty. + * + * Returns: %TRUE if @region is empty. + */ +gboolean +gdk_region_empty (const GdkRegion *region) +{ + g_return_val_if_fail (region != NULL, FALSE); + + if (region->numRects == 0) + return TRUE; + else + return FALSE; +} + +/** + * gdk_region_equal: + * @region1: a #GdkRegion + * @region2: a #GdkRegion + * + * Finds out if the two regions are the same. + * + * Returns: %TRUE if @region1 and @region2 are equal. + */ +gboolean +gdk_region_equal (const GdkRegion *region1, + const GdkRegion *region2) +{ + int i; + + g_return_val_if_fail (region1 != NULL, FALSE); + g_return_val_if_fail (region2 != NULL, FALSE); + + if (region1->numRects != region2->numRects) return FALSE; + else if (region1->numRects == 0) return TRUE; + else if (region1->extents.x1 != region2->extents.x1) return FALSE; + else if (region1->extents.x2 != region2->extents.x2) return FALSE; + else if (region1->extents.y1 != region2->extents.y1) return FALSE; + else if (region1->extents.y2 != region2->extents.y2) return FALSE; + else + for(i = 0; i < region1->numRects; i++ ) + { + if (region1->rects[i].x1 != region2->rects[i].x1) return FALSE; + else if (region1->rects[i].x2 != region2->rects[i].x2) return FALSE; + else if (region1->rects[i].y1 != region2->rects[i].y1) return FALSE; + else if (region1->rects[i].y2 != region2->rects[i].y2) return FALSE; + } + return TRUE; +} + +/** + * gdk_region_rect_equal: + * @region: a #GdkRegion + * @rectangle: a #GdkRectangle + * + * Finds out if a regions is the same as a rectangle. + * + * Returns: %TRUE if @region and @rectangle are equal. + * + * Since: 2.18 + * + * Deprecated: 2.22: Use gdk_region_new_rect() and gdk_region_equal() to + * achieve the same effect. + */ +gboolean +gdk_region_rect_equal (const GdkRegion *region, + const GdkRectangle *rectangle) +{ + g_return_val_if_fail (region != NULL, FALSE); + g_return_val_if_fail (rectangle != NULL, FALSE); + + if (region->numRects != 1) return FALSE; + else if (region->extents.x1 != rectangle->x) return FALSE; + else if (region->extents.y1 != rectangle->y) return FALSE; + else if (region->extents.x2 != rectangle->x + rectangle->width) return FALSE; + else if (region->extents.y2 != rectangle->y + rectangle->height) return FALSE; + return TRUE; +} + +/** + * gdk_region_point_in: + * @region: a #GdkRegion + * @x: the x coordinate of a point + * @y: the y coordinate of a point + * + * Finds out if a point is in a region. + * + * Returns: %TRUE if the point is in @region. + */ +gboolean +gdk_region_point_in (const GdkRegion *region, + int x, + int y) +{ + int i; + + g_return_val_if_fail (region != NULL, FALSE); + + if (region->numRects == 0) + return FALSE; + if (!INBOX(region->extents, x, y)) + return FALSE; + for (i = 0; i < region->numRects; i++) + { + if (INBOX (region->rects[i], x, y)) + return TRUE; + } + return FALSE; +} + +/** + * gdk_region_rect_in: + * @region: a #GdkRegion. + * @rectangle: a #GdkRectangle. + * + * Tests whether a rectangle is within a region. + * + * Returns: %GDK_OVERLAP_RECTANGLE_IN, %GDK_OVERLAP_RECTANGLE_OUT, or + * %GDK_OVERLAP_RECTANGLE_PART, depending on whether the rectangle is inside, + * outside, or partly inside the #GdkRegion, respectively. + */ +GdkOverlapType +gdk_region_rect_in (const GdkRegion *region, + const GdkRectangle *rectangle) +{ + GdkRegionBox *pbox; + GdkRegionBox *pboxEnd; + GdkRegionBox rect; + GdkRegionBox *prect = ▭ + gboolean partIn, partOut; + gint rx, ry; + + g_return_val_if_fail (region != NULL, GDK_OVERLAP_RECTANGLE_OUT); + g_return_val_if_fail (rectangle != NULL, GDK_OVERLAP_RECTANGLE_OUT); + + rx = rectangle->x; + ry = rectangle->y; + + prect->x1 = rx; + prect->y1 = ry; + prect->x2 = rx + rectangle->width; + prect->y2 = ry + rectangle->height; + + /* this is (just) a useful optimization */ + if ((region->numRects == 0) || !EXTENTCHECK (®ion->extents, prect)) + return GDK_OVERLAP_RECTANGLE_OUT; + + partOut = FALSE; + partIn = FALSE; + + /* can stop when both partOut and partIn are TRUE, or we reach prect->y2 */ + for (pbox = region->rects, pboxEnd = pbox + region->numRects; + pbox < pboxEnd; + pbox++) + { + + if (pbox->y2 <= ry) + continue; /* getting up to speed or skipping remainder of band */ + + if (pbox->y1 > ry) + { + partOut = TRUE; /* missed part of rectangle above */ + if (partIn || (pbox->y1 >= prect->y2)) + break; + ry = pbox->y1; /* x guaranteed to be == prect->x1 */ + } + + if (pbox->x2 <= rx) + continue; /* not far enough over yet */ + + if (pbox->x1 > rx) + { + partOut = TRUE; /* missed part of rectangle to left */ + if (partIn) + break; + } + + if (pbox->x1 < prect->x2) + { + partIn = TRUE; /* definitely overlap */ + if (partOut) + break; + } + + if (pbox->x2 >= prect->x2) + { + ry = pbox->y2; /* finished with this band */ + if (ry >= prect->y2) + break; + rx = prect->x1; /* reset x out to left again */ + } + else + { + /* + * Because boxes in a band are maximal width, if the first box + * to overlap the rectangle doesn't completely cover it in that + * band, the rectangle must be partially out, since some of it + * will be uncovered in that band. partIn will have been set true + * by now... + */ + break; + } + + } + + return (partIn ? + ((ry < prect->y2) ? + GDK_OVERLAP_RECTANGLE_PART : GDK_OVERLAP_RECTANGLE_IN) : + GDK_OVERLAP_RECTANGLE_OUT); +} + + +static void +gdk_region_unsorted_spans_intersect_foreach (GdkRegion *region, + const GdkSpan *spans, + int n_spans, + GdkSpanFunc function, + gpointer data) +{ + gint i, left, right, y; + gint clipped_left, clipped_right; + GdkRegionBox *pbox; + GdkRegionBox *pboxEnd; + + if (!region->numRects) + return; + + for (i=0;iextents.y1 <= y) && + (region->extents.y2 > y) && + (region->extents.x1 < right) && + (region->extents.x2 > left)) ) + continue; + + /* can stop when we passed y */ + for (pbox = region->rects, pboxEnd = pbox + region->numRects; + pbox < pboxEnd; + pbox++) + { + if (pbox->y2 <= y) + continue; /* Not quite there yet */ + + if (pbox->y1 > y) + break; /* passed the spanline */ + + if ((right > pbox->x1) && (left < pbox->x2)) + { + GdkSpan out_span; + + clipped_left = MAX (left, pbox->x1); + clipped_right = MIN (right, pbox->x2); + + out_span.y = y; + out_span.x = clipped_left; + out_span.width = clipped_right - clipped_left; + (*function) (&out_span, data); + } + } + } +} + +/** + * gdk_region_spans_intersect_foreach: + * @region: a #GdkRegion + * @spans: an array of #GdkSpans + * @n_spans: the length of @spans + * @sorted: %TRUE if @spans is sorted wrt. the y coordinate + * @function: function to call on each span in the intersection + * @data: data to pass to @function + * + * Calls a function on each span in the intersection of @region and @spans. + * + * Deprecated: 2.22: There is no replacement. + */ +void +gdk_region_spans_intersect_foreach (GdkRegion *region, + const GdkSpan *spans, + int n_spans, + gboolean sorted, + GdkSpanFunc function, + gpointer data) +{ + gint left, right, y; + gint clipped_left, clipped_right; + GdkRegionBox *pbox; + GdkRegionBox *pboxEnd; + const GdkSpan *span, *tmpspan; + const GdkSpan *end_span; + + g_return_if_fail (region != NULL); + g_return_if_fail (spans != NULL); + + if (!sorted) + { + gdk_region_unsorted_spans_intersect_foreach (region, + spans, + n_spans, + function, + data); + return; + } + + if ((!region->numRects) || (n_spans == 0)) + return; + + /* The main method here is to step along the + * sorted rectangles and spans in lock step, and + * clipping the spans that are in the current + * rectangle before going on to the next rectangle. + */ + + span = spans; + end_span = spans + n_spans; + pbox = region->rects; + pboxEnd = pbox + region->numRects; + while (pbox < pboxEnd) + { + while ((pbox->y2 < span->y) || (span->y < pbox->y1)) + { + /* Skip any rectangles that are above the current span */ + if (pbox->y2 < span->y) + { + pbox++; + if (pbox == pboxEnd) + return; + } + /* Skip any spans that are above the current rectangle */ + if (span->y < pbox->y1) + { + span++; + if (span == end_span) + return; + } + } + + /* Ok, we got at least one span that might intersect this rectangle. */ + tmpspan = span; + while ((tmpspan < end_span) && + (tmpspan->y < pbox->y2)) + { + y = tmpspan->y; + left = tmpspan->x; + right = left + tmpspan->width; /* right is not in the span! */ + + if ((right > pbox->x1) && (left < pbox->x2)) + { + GdkSpan out_span; + + clipped_left = MAX (left, pbox->x1); + clipped_right = MIN (right, pbox->x2); + + out_span.y = y; + out_span.x = clipped_left; + out_span.width = clipped_right - clipped_left; + (*function) (&out_span, data); + } + + tmpspan++; + } + + /* Finished this rectangle. + * The spans could still intersect the next one + */ + pbox++; + } +} + +#define __GDK_REGION_GENERIC_C__ +#include "gdkaliasdef.c" diff --git a/libs/tk/ydk/gdkrgb.c b/libs/tk/ydk/gdkrgb.c new file mode 100644 index 0000000000..6e32bab94c --- /dev/null +++ b/libs/tk/ydk/gdkrgb.c @@ -0,0 +1,3770 @@ +/* GDK - The GIMP Drawing Kit + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* For more information on GdkRgb, see http://www.levien.com/gdkrgb/ + + Raph Levien + */ + +/* + * 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 "config.h" +#include +#include +#include + +#define ENABLE_GRAYSCALE + +#include "gdkinternals.h" /* _gdk_windowing_get_bits_for_depth() */ + +#include "gdkrgb.h" +#include "gdkscreen.h" +#include "gdkalias.h" +#include + +typedef struct _GdkRgbInfo GdkRgbInfo; +typedef struct _GdkRgbCmapInfo GdkRgbCmapInfo; + +typedef void (*GdkRgbConvFunc) (GdkRgbInfo *image_info, GdkImage *image, + gint x0, gint y0, + gint width, gint height, + const guchar *buf, int rowstride, + gint x_align, gint y_align, + GdkRgbCmap *cmap); + +#define STAGE_ROWSTRIDE (GDK_SCRATCH_IMAGE_WIDTH * 3) + +/* Some of these fields should go, as they're not being used at all. (?) + */ +struct _GdkRgbInfo +{ + GdkVisual *visual; + GdkColormap *cmap; + + guint nred_shades; + guint ngreen_shades; + guint nblue_shades; + guint ngray_shades; + guint nreserved; + + guint bpp; + gint cmap_alloced; + gdouble gamma; + + /* Generally, the stage buffer is used to convert 32bit RGB, gray, + and indexed images into 24 bit packed RGB. */ + guchar *stage_buf; + + GdkRgbCmap *gray_cmap; + + gboolean dith_default; + + gboolean bitmap; /* set true if in 1 bit per pixel mode */ + GdkGC *own_gc; + + /* Convert functions */ + GdkRgbConvFunc conv; + GdkRgbConvFunc conv_d; + + GdkRgbConvFunc conv_32; + GdkRgbConvFunc conv_32_d; + + GdkRgbConvFunc conv_gray; + GdkRgbConvFunc conv_gray_d; + + GdkRgbConvFunc conv_indexed; + GdkRgbConvFunc conv_indexed_d; + + guchar *colorcube; + guchar *colorcube_d; + + /* We need to track LUT's for pairs of GdkRgbInfo / GdkRgbCmap, so we + * keep a list of pointers to GdkRgbCmapInfo on both structures so we + * can remove as necessary when freeing a GdkRgbInfo or GdkRgbCmap + */ + GSList *cmap_info_list; +}; + +struct _GdkRgbCmapInfo +{ + GdkRgbInfo *image_info; + GdkRgbCmap *cmap; + + guchar lut[256]; /* For 8-bit modes */ +}; + +static GdkRgbCmapInfo *gdk_rgb_cmap_get_info (GdkRgbCmap *cmap, GdkRgbInfo *image_info); + +static const char gdk_rgb_key[] = "gdk-rgb-info"; +static GQuark gdk_rgb_quark = 0; + +static gboolean gdk_rgb_install_cmap = FALSE; +static gint gdk_rgb_min_colors = 5 * 5 * 5; +static gboolean gdk_rgb_verbose = FALSE; + +static gint +gdk_rgb_cmap_fail (const char *msg, GdkColormap *cmap, gulong *pixels) +{ + GdkColor free_colors[256]; + gint n_free; + gint i; + +#ifdef VERBOSE + g_print ("%s", msg); +#endif + n_free = 0; + for (i = 0; i < 256; i++) + if (pixels[i] < 256) + free_colors[n_free++].pixel = pixels[i]; + if (n_free) + gdk_colormap_free_colors (cmap, free_colors, n_free); + return 0; +} + +static void +gdk_rgb_make_colorcube (GdkRgbInfo *image_info, gulong *pixels, + gint nr, gint ng, gint nb) +{ + guchar rt[16], gt[16], bt[16]; + gint i; + + image_info->colorcube = g_new (guchar, 4096); + for (i = 0; i < 16; i++) + { + rt[i] = ng * nb * ((i * 17 * (nr - 1) + 128) >> 8); + gt[i] = nb * ((i * 17 * (ng - 1) + 128) >> 8); + bt[i] = ((i * 17 * (nb - 1) + 128) >> 8); + } + + for (i = 0; i < 4096; i++) + { + image_info->colorcube[i] = pixels[rt[i >> 8] + gt[(i >> 4) & 0x0f] + bt[i & 0x0f]]; +#ifdef VERBOSE + g_print ("%03x %02x %x %x %x\n", i, image_info->colorcube[i], rt[i >> 8], gt[(i >> 4) & 0x0f], bt[i & 0x0f]); +#endif + } +} + +/* this is the colorcube suitable for dithering */ +static void +gdk_rgb_make_colorcube_d (GdkRgbInfo *image_info, gulong *pixels, + gint nr, gint ng, gint nb) +{ + gint r, g, b; + gint i; + + image_info->colorcube_d = g_new (guchar, 512); + for (i = 0; i < 512; i++) + { + r = MIN (nr - 1, i >> 6); + g = MIN (ng - 1, (i >> 3) & 7); + b = MIN (nb - 1, i & 7); + image_info->colorcube_d[i] = pixels[(r * ng + g) * nb + b]; + } +} + +/* Try installing a color cube of the specified size. + Make the colorcube and return TRUE on success */ +static gboolean +gdk_rgb_try_colormap (GdkRgbInfo *image_info, gboolean force, + gint nr, gint ng, gint nb) +{ + gint r, g, b; + gint ri, gi, bi; + gint r0, g0, b0; + GdkColormap *cmap; + GdkColor color; + gulong pixels[256]; + gint i; + gint d2; + gint colors_needed; + gint idx; + gint best[256]; + GdkScreen *screen; + + if (!force && nr * ng * nb < gdk_rgb_min_colors) + return FALSE; + + screen = gdk_visual_get_screen (image_info->visual); + + if (image_info->cmap) + cmap = image_info->cmap; + else + cmap = gdk_screen_get_system_colormap (screen); + + colors_needed = nr * ng * nb; + for (i = 0; i < 256; i++) + { + best[i] = 192; + pixels[i] = 256; + } + +#ifndef GAMMA + if (cmap == gdk_screen_get_system_colormap (screen)) + /* find color cube colors that are already present */ + for (i = 0; i < MIN (256, cmap->size); i++) + { + r = cmap->colors[i].red >> 8; + g = cmap->colors[i].green >> 8; + b = cmap->colors[i].blue >> 8; + ri = (r * (nr - 1) + 128) >> 8; + gi = (g * (ng - 1) + 128) >> 8; + bi = (b * (nb - 1) + 128) >> 8; + r0 = ri * 255 / (nr - 1); + g0 = gi * 255 / (ng - 1); + b0 = bi * 255 / (nb - 1); + idx = ((ri * nr) + gi) * nb + bi; + d2 = (r - r0) * (r - r0) + (g - g0) * (g - g0) + (b - b0) * (b - b0); + if (d2 < best[idx]) + { + if (pixels[idx] < 256) + { + color.pixel = pixels[idx]; + gdk_colormap_free_colors (cmap, &color, 1); + } + else + colors_needed--; + color = cmap->colors[i]; + if (!gdk_colormap_alloc_color (cmap, &color, FALSE, FALSE)) + return gdk_rgb_cmap_fail ("error allocating system color\n", + cmap, pixels); + pixels[idx] = color.pixel; /* which is almost certainly i */ + best[idx] = d2; + } + } +#endif + + for (r = 0, i = 0; r < nr; r++) + for (g = 0; g < ng; g++) + for (b = 0; b < nb; b++, i++) + { + if (pixels[i] == 256) + { + color.red = r * 65535 / (nr - 1); + color.green = g * 65535 / (ng - 1); + color.blue = b * 65535 / (nb - 1); + +#ifdef GAMMA + color.red = 65535 * pow (color.red / 65535.0, 0.5); + color.green = 65535 * pow (color.green / 65535.0, 0.5); + color.blue = 65535 * pow (color.blue / 65535.0, 0.5); +#endif + + if (!gdk_colormap_alloc_color (cmap, &color, FALSE, force)) + { + char tmp_str[80]; + + g_snprintf (tmp_str, 80, "%d %d %d colormap failed\n", + nr, ng, nb); + return gdk_rgb_cmap_fail (tmp_str, + cmap, pixels); + } + pixels[i] = color.pixel; + } +#ifdef VERBOSE + g_print ("%d: %lx\n", i, pixels[i]); +#endif + } + + image_info->nred_shades = nr; + image_info->ngreen_shades = ng; + image_info->nblue_shades = nb; + gdk_rgb_make_colorcube (image_info, pixels, nr, ng, nb); + gdk_rgb_make_colorcube_d (image_info, pixels, nr, ng, nb); + return TRUE; +} + +/* Return TRUE on success. */ +static gboolean +gdk_rgb_do_colormaps (GdkRgbInfo *image_info, gboolean force) +{ + static const gint sizes[][3] = { + /* { 6, 7, 6 }, */ + { 6, 6, 6 }, + { 6, 6, 5 }, + { 6, 6, 4 }, + { 5, 5, 5 }, + { 5, 5, 4 }, + { 4, 4, 4 }, + { 4, 4, 3 }, + { 3, 3, 3 }, + { 2, 2, 2 } + }; + static const gint n_sizes = G_N_ELEMENTS (sizes); + gint i; + + /* Try the possible sizes. If the force parameter is set to TRUE + * and all larger sizes fail, force the larger size to succeed - + * this will involve allowing closest matches when allocating the + * colors + */ + for (i = 0; i < n_sizes; i++) + if (gdk_rgb_try_colormap (image_info, + (i == n_sizes - 1 ) && force, + sizes[i][0], sizes[i][1], sizes[i][2])) + return TRUE; + return FALSE; +} + +/* Make a 2 x 2 x 2 colorcube */ +static void +gdk_rgb_colorcube_222 (GdkRgbInfo *image_info) +{ + int i; + GdkColor color; + + image_info->colorcube_d = g_new (guchar, 512); + + for (i = 0; i < 8; i++) + { + color.red = ((i & 4) >> 2) * 65535; + color.green = ((i & 2) >> 1) * 65535; + color.blue = (i & 1) * 65535; + gdk_colormap_alloc_color (image_info->cmap, &color, FALSE, TRUE); + image_info->colorcube_d[((i & 4) << 4) | ((i & 2) << 2) | (i & 1)] = color.pixel; + } +} + +void +gdk_rgb_set_verbose (gboolean verbose) +{ + gdk_rgb_verbose = verbose; +} + +void +gdk_rgb_set_install (gboolean install) +{ + gdk_rgb_install_cmap = install; +} + +void +gdk_rgb_set_min_colors (gint min_colors) +{ + gdk_rgb_min_colors = min_colors; +} + +/* Return a "score" based on the following criteria (in hex): + + x000 is the quality - 1 is 1bpp, 2 is 4bpp, + 4 is 8bpp, + 7 is 15bpp truecolor, 8 is 16bpp truecolor, + 9 is 24bpp truecolor. + 0x00 is the speed - 1 is the normal case, + 2 means faster than normal + 00x0 gets a point for being the system visual + 000x gets a point for being pseudocolor + + A caveat: in the 8bpp modes, being the system visual seems to be + quite important. Thus, all of the 8bpp modes should be ranked at + the same speed. +*/ +static guint32 +gdk_rgb_score_visual (GdkVisual *visual) +{ + guint32 quality, speed, sys, pseudo; + + quality = 0; + speed = 1; + sys = 0; + if (visual->type == GDK_VISUAL_TRUE_COLOR || + visual->type == GDK_VISUAL_DIRECT_COLOR) + { + if (visual->depth == 24) + { + quality = 9; + /* Should test for MSB visual here, and set speed if so. */ + } + else if (visual->depth == 16) + quality = 8; + else if (visual->depth == 15) + quality = 7; + else if (visual->depth == 8) + quality = 4; + } + else if (visual->type == GDK_VISUAL_PSEUDO_COLOR || + visual->type == GDK_VISUAL_STATIC_COLOR) + { + if (visual->depth == 8) + quality = 4; + else if (visual->depth == 4) + quality = 2; + else if (visual->depth == 1) + quality = 1; + } + else if (visual->type == GDK_VISUAL_STATIC_GRAY +#ifdef ENABLE_GRAYSCALE + || visual->type == GDK_VISUAL_GRAYSCALE +#endif + ) + { + if (visual->depth == 8) + quality = 4; + else if (visual->depth == 4) + quality = 2; + else if (visual->depth == 1) + quality = 1; + } + + if (quality == 0) + return 0; + + sys = (visual == gdk_screen_get_system_visual (gdk_visual_get_screen (visual))); + + pseudo = (visual->type == GDK_VISUAL_PSEUDO_COLOR || visual->type == GDK_VISUAL_TRUE_COLOR); + + if (gdk_rgb_verbose) + g_print ("Visual type = %d, depth = %d, %x:%x:%x%s; score=%x\n", + visual->type, + visual->depth, + visual->red_mask, + visual->green_mask, + visual->blue_mask, + sys ? " (system)" : "", + (quality << 12) | (speed << 8) | (sys << 4) | pseudo); + + return (quality << 12) | (speed << 8) | (sys << 4) | pseudo; +} + +static GdkVisual * +gdk_rgb_choose_visual (GdkScreen *screen) +{ + GList *visuals, *tmp_list; + guint32 score, best_score; + GdkVisual *visual, *best_visual; + + visuals = gdk_screen_list_visuals (screen); + tmp_list = visuals; + + best_visual = tmp_list->data; + best_score = gdk_rgb_score_visual (best_visual); + tmp_list = tmp_list->next; + while (tmp_list) + { + visual = tmp_list->data; + score = gdk_rgb_score_visual (visual); + if (score > best_score) + { + best_score = score; + best_visual = visual; + } + tmp_list = tmp_list->next; + } + + g_list_free (visuals); + + return best_visual; +} + +static void gdk_rgb_select_conv (GdkRgbInfo *image_info); + +static void +gdk_rgb_set_gray_cmap (GdkRgbInfo *image_info, + GdkColormap *cmap) +{ + gint i; + GdkColor color; + gboolean status; + gulong pixels[256]; + gint r, g, b, gray; + + for (i = 0; i < 256; i++) + { + color.pixel = i; + color.red = i * 257; + color.green = i * 257; + color.blue = i * 257; + status = gdk_colormap_alloc_color (cmap, &color, FALSE, TRUE); + pixels[i] = color.pixel; +#ifdef VERBOSE + g_print ("allocating pixel %d, %x %x %x, result %d\n", + color.pixel, color.red, color.green, color.blue, status); +#endif + } + + /* Now, we make fake colorcubes - we ultimately just use the pseudocolor + methods. */ + + image_info->colorcube = g_new (guchar, 4096); + + for (i = 0; i < 4096; i++) + { + r = (i >> 4) & 0xf0; + r = r | r >> 4; + g = i & 0xf0; + g = g | g >> 4; + b = (i << 4 & 0xf0); + b = b | b >> 4; + gray = (g + ((r + b) >> 1)) >> 1; + image_info->colorcube[i] = pixels[gray]; + } +} + +static void +gdk_rgb_free_info (GdkRgbInfo *image_info) +{ + GSList *tmp_list; + + g_free (image_info->stage_buf); + + if (image_info->gray_cmap) + gdk_rgb_cmap_free (image_info->gray_cmap); + + if (image_info->own_gc) + g_object_unref (image_info->own_gc); + + g_free (image_info->colorcube); + + g_free (image_info->colorcube_d); + + tmp_list = image_info->cmap_info_list; + while (tmp_list) + { + GdkRgbCmapInfo *cmap_info = tmp_list->data; + cmap_info->cmap->info_list = g_slist_remove (cmap_info->cmap->info_list, cmap_info); + g_free (cmap_info); + } + g_slist_free (image_info->cmap_info_list); + + g_free (image_info); +} + +/* Create a GdkRgbInfo for the given visual/colormap pair. If colormap + * is NULL, it will be determined and stored in image_info->cmap. + * In this case, image_info->cmap will have an extra refcount which + * is owned by the caller. + */ +static GdkRgbInfo * +gdk_rgb_create_info (GdkVisual *visual, GdkColormap *colormap) +{ + GdkRgbInfo *image_info; + GdkScreen *screen = gdk_visual_get_screen (visual); + + image_info = g_new0 (GdkRgbInfo, 1); + + image_info->visual = visual; + image_info->cmap = NULL; + + image_info->nred_shades = 6; + image_info->ngreen_shades = 6; + image_info->nblue_shades = 4; + image_info->ngray_shades = 24; + image_info->nreserved = 0; + + image_info->bpp = 0; + image_info->cmap_alloced = FALSE; + image_info->gamma = 1.0; + + image_info->stage_buf = NULL; + + image_info->own_gc = NULL; + + image_info->cmap = colormap; + + /* We used to use the 2x2x2 color cube for pseudo-color with depths + * 5, 6, 7 as well but now only use it for depths (3 and) 4 in + * pseudo-color. The reason for this is that on Win32 we let the + * user restrict the color allocation for PSEUDO_COLOR visuals + * (i.e., 256-color mode) and we probably want to do the full + * gdk_rgb_do_colormaps() if we are doing that. (Though the color + * sharing code won't really be right.) + * + * (The actual usefulness of this user-requested restriction remains + * to be seen, but the code is there in gdkvisual-win32.c. The + * thought is that it might occasionally be useful to restrict the + * palette size in a GTK application in order to reduce color + * flashing.) + */ + if ((image_info->visual->type == GDK_VISUAL_PSEUDO_COLOR && + image_info->visual->depth <= 4 && + image_info->visual->depth >= 3) || + (image_info->visual->type == GDK_VISUAL_STATIC_COLOR && + image_info->visual->depth < 8 && + image_info->visual->depth >= 3)) + { + if (!image_info->cmap) + image_info->cmap = g_object_ref (gdk_screen_get_system_colormap (screen)); + + gdk_rgb_colorcube_222 (image_info); + } + else if (image_info->visual->type == GDK_VISUAL_PSEUDO_COLOR + || image_info->visual->type == GDK_VISUAL_STATIC_COLOR) + { + if (!image_info->cmap && + (gdk_rgb_install_cmap || image_info->visual != gdk_screen_get_system_visual (screen))) + { + image_info->cmap = gdk_colormap_new (image_info->visual, FALSE); + image_info->cmap_alloced = TRUE; + } + if (!gdk_rgb_do_colormaps (image_info, image_info->cmap != NULL)) + { + image_info->cmap = gdk_colormap_new (image_info->visual, FALSE); + image_info->cmap_alloced = TRUE; + gdk_rgb_do_colormaps (image_info, TRUE); + } + if (gdk_rgb_verbose) + g_print ("color cube: %d x %d x %d\n", + image_info->nred_shades, + image_info->ngreen_shades, + image_info->nblue_shades); + + if (!image_info->cmap) + image_info->cmap = g_object_ref (gdk_screen_get_system_colormap (screen)); + } +#ifdef ENABLE_GRAYSCALE + else if (image_info->visual->type == GDK_VISUAL_GRAYSCALE) + { + if (!image_info->cmap) + { + image_info->cmap = gdk_colormap_new (image_info->visual, FALSE); + image_info->cmap_alloced = TRUE; + } + + gdk_rgb_set_gray_cmap (image_info, image_info->cmap); + } +#endif + else + { + if (!image_info->cmap) + { + /* Always install colormap in direct color. */ + if (image_info->visual->type != GDK_VISUAL_DIRECT_COLOR && + image_info->visual == gdk_screen_get_system_visual (screen)) + image_info->cmap = g_object_ref (gdk_screen_get_system_colormap (screen)); + else + { + image_info->cmap = gdk_colormap_new (image_info->visual, FALSE); + image_info->cmap_alloced = TRUE; + } + } + } + + image_info->bitmap = (image_info->visual->depth == 1); + + image_info->bpp = (_gdk_windowing_get_bits_for_depth (gdk_screen_get_display (screen), image_info->visual->depth) + 7) / 8; + gdk_rgb_select_conv (image_info); + + if (!gdk_rgb_quark) + gdk_rgb_quark = g_quark_from_static_string (gdk_rgb_key); + + g_object_set_qdata_full (G_OBJECT (image_info->cmap), gdk_rgb_quark, + image_info, (GDestroyNotify)gdk_rgb_free_info); + return image_info; +} + +void +gdk_rgb_init (void) +{ + static const gint byte_order[1] = { 1 }; + + /* check endian sanity */ +#if G_BYTE_ORDER == G_BIG_ENDIAN + if (((char *)byte_order)[0] == 1) + g_error ("gdk_rgb_init: compiled for big endian, but this is a little endian machine.\n\n"); +#else + if (((char *)byte_order)[0] != 1) + g_error ("gdk_rgb_init: compiled for little endian, but this is a big endian machine.\n\n"); +#endif +} + +static GdkRgbInfo * +gdk_rgb_get_info_from_colormap (GdkColormap *cmap) +{ + GdkRgbInfo *image_info; + + if (!gdk_rgb_quark) + gdk_rgb_quark = g_quark_from_static_string (gdk_rgb_key); + + image_info = g_object_get_qdata (G_OBJECT (cmap), gdk_rgb_quark); + if (!image_info) + image_info = gdk_rgb_create_info (gdk_colormap_get_visual (cmap), cmap); + + return image_info; +} + +static guint32 +gdk_rgb_alpha_mask (GdkRgbInfo *image_info) +{ + guint padding; + + /* Shifting by >= width-of-type isn't defined in C */ + if (image_info->visual->depth >= 32) + padding = 0; + else + padding = ((~(guint32)0)) << image_info->visual->depth; + + return ~(image_info->visual->red_mask | + image_info->visual->green_mask | + image_info->visual->blue_mask | + padding); +} + +static gulong +gdk_rgb_xpixel_from_rgb_internal (GdkColormap *colormap, + guint16 r, guint16 g, guint16 b) +{ + gulong pixel = 0; + + GdkRgbInfo *image_info = gdk_rgb_get_info_from_colormap (colormap); + + if (image_info->bitmap) + { + return (r + (g << 1) + b) > 131070; + } + else if (image_info->visual->type == GDK_VISUAL_PSEUDO_COLOR) + pixel = image_info->colorcube[((r & 0xf000) >> 4) | + ((g & 0xf000) >> 8) | + ((b & 0xf000) >> 12)]; + else if (image_info->visual->depth < 8 && + image_info->visual->type == GDK_VISUAL_STATIC_COLOR) + { + pixel = image_info->colorcube_d[((r & 0x8000) >> 9) | + ((g & 0x8000) >> 12) | + ((b & 0x8000) >> 15)]; + } + else if (image_info->visual->type == GDK_VISUAL_TRUE_COLOR || + image_info->visual->type == GDK_VISUAL_DIRECT_COLOR) + { + guint32 unused; + +#ifdef VERBOSE + g_print ("shift, prec: r %d %d g %d %d b %d %d\n", + image_info->visual->red_shift, + image_info->visual->red_prec, + image_info->visual->green_shift, + image_info->visual->green_prec, + image_info->visual->blue_shift, + image_info->visual->blue_prec); +#endif + /* If bits not used for color are used for something other than padding, + * it's likely alpha, so we set them to 1s. + */ + unused = ~ (image_info->visual->red_mask | + image_info->visual->green_mask | + image_info->visual->blue_mask | + (((~(guint32)0)) << image_info->visual->depth)); + + pixel = (unused + ((r >> (16 - image_info->visual->red_prec)) << image_info->visual->red_shift) + + ((g >> (16 - image_info->visual->green_prec)) << image_info->visual->green_shift) + + ((b >> (16 - image_info->visual->blue_prec)) << image_info->visual->blue_shift)); + pixel |= gdk_rgb_alpha_mask (image_info); + } + else if (image_info->visual->type == GDK_VISUAL_STATIC_GRAY || + image_info->visual->type == GDK_VISUAL_GRAYSCALE) + { + int gray = r + g * 2 + b; + return gray >> (18 - image_info->visual->depth); + } + + return pixel; +} + +/* convert an rgb value into an X pixel code */ +gulong +gdk_rgb_xpixel_from_rgb (guint32 rgb) +{ + guint32 r = rgb & 0xff0000; + guint32 g = rgb & 0xff00; + guint32 b = rgb & 0xff; + + return gdk_rgb_xpixel_from_rgb_internal (gdk_screen_get_rgb_colormap (gdk_screen_get_default ()), + (r >> 8) + (r >> 16), g + (g >> 8), b + (b << 8)); +} + +void +gdk_rgb_gc_set_foreground (GdkGC *gc, guint32 rgb) +{ + GdkColor color; + + color.pixel = gdk_rgb_xpixel_from_rgb (rgb); + gdk_gc_set_foreground (gc, &color); +} + +void +gdk_rgb_gc_set_background (GdkGC *gc, guint32 rgb) +{ + GdkColor color; + + color.pixel = gdk_rgb_xpixel_from_rgb (rgb); + gdk_gc_set_background (gc, &color); +} + +/** + * gdk_rgb_find_color: + * @colormap: a #GdkColormap + * @color: a #GdkColor + * + * @colormap should be the colormap for the graphics context and + * drawable you're using to draw. If you're drawing to a #GtkWidget, + * call gtk_widget_get_colormap(). + * + * @color should have its %red, %green, and %blue fields initialized; + * gdk_rgb_find_color() will fill in the %pixel field with the best + * matching pixel from a color cube. The color is then ready to be + * used for drawing, e.g. you can call gdk_gc_set_foreground() which + * expects %pixel to be initialized. + * + * In many cases, you can avoid this whole issue by calling + * gdk_gc_set_rgb_fg_color() or gdk_gc_set_rgb_bg_color(), which + * do not expect %pixel to be initialized in advance. If you use those + * functions, there's no need for gdk_rgb_find_color(). + * + * Deprecated: 2.22: Cairo handles colors automatically. + **/ +void +gdk_rgb_find_color (GdkColormap *colormap, GdkColor *color) +{ + color->pixel = gdk_rgb_xpixel_from_rgb_internal (colormap, + color->red, color->green, color->blue); +} + +#if G_BYTE_ORDER == G_LITTLE_ENDIAN +#define HAIRY_CONVERT_8 +#endif + +#ifdef HAIRY_CONVERT_8 +static void +gdk_rgb_convert_8 (GdkRgbInfo *image_info, GdkImage *image, + gint x0, gint y0, gint width, gint height, + const guchar *buf, int rowstride, + gint x_align, gint y_align, GdkRgbCmap *cmap) +{ + int x, y; + gint bpl; + guchar *obuf, *obptr; + const guchar *bptr, *bp2; + gint r, g, b; + guchar *colorcube = image_info->colorcube; + + bptr = buf; + bpl = image->bpl; + obuf = ((guchar *)image->mem) + y0 * bpl + x0; + for (y = 0; y < height; y++) + { + bp2 = bptr; + obptr = obuf; + if (((guintptr)obuf | (guintptr) bp2) & 3) + { + for (x = 0; x < width; x++) + { + r = *bp2++; + g = *bp2++; + b = *bp2++; + obptr[0] = colorcube[((r & 0xf0) << 4) | + (g & 0xf0) | + (b >> 4)]; + obptr++; + } + } + else + { + for (x = 0; x < width - 3; x += 4) + { + guint32 r1b0g0r0; + guint32 g2r2b1g1; + guint32 b3g3r3b2; + + r1b0g0r0 = ((guint32 *)bp2)[0]; + g2r2b1g1 = ((guint32 *)bp2)[1]; + b3g3r3b2 = ((guint32 *)bp2)[2]; + ((guint32 *)obptr)[0] = + colorcube[((r1b0g0r0 & 0xf0) << 4) | + ((r1b0g0r0 & 0xf000) >> 8) | + ((r1b0g0r0 & 0xf00000) >> 20)] | + (colorcube[((r1b0g0r0 & 0xf0000000) >> 20) | + (g2r2b1g1 & 0xf0) | + ((g2r2b1g1 & 0xf000) >> 12)] << 8) | + (colorcube[((g2r2b1g1 & 0xf00000) >> 12) | + ((g2r2b1g1 & 0xf0000000) >> 24) | + ((b3g3r3b2 & 0xf0) >> 4)] << 16) | + (colorcube[((b3g3r3b2 & 0xf000) >> 4) | + ((b3g3r3b2 & 0xf00000) >> 16) | + (b3g3r3b2 >> 28)] << 24); + bp2 += 12; + obptr += 4; + } + for (; x < width; x++) + { + r = *bp2++; + g = *bp2++; + b = *bp2++; + obptr[0] = colorcube[((r & 0xf0) << 4) | + (g & 0xf0) | + (b >> 4)]; + obptr++; + } + } + bptr += rowstride; + obuf += bpl; + } +} +#else +static void +gdk_rgb_convert_8 (GdkRgbInfo *image_info, GdkImage *image, + gint x0, gint y0, gint width, gint height, + const guchar *buf, int rowstride, + gint x_align, gint y_align, GdkRgbCmap *cmap) +{ + int x, y; + gint bpl; + guchar *obuf, *obptr; + const guchar *bptr, *bp2; + gint r, g, b; + guchar *colorcube = image_info->colorcube; + + bptr = buf; + bpl = image->bpl; + obuf = ((guchar *)image->mem) + y0 * bpl + x0; + for (y = 0; y < height; y++) + { + bp2 = bptr; + obptr = obuf; + for (x = 0; x < width; x++) + { + r = *bp2++; + g = *bp2++; + b = *bp2++; + obptr[0] = colorcube[((r & 0xf0) << 4) | + (g & 0xf0) | + (b >> 4)]; + obptr++; + } + bptr += rowstride; + obuf += bpl; + } +} +#endif + + + +/* Dither matrices + * --------------- + * + * The original matrices are called "DM" below. The preprocessed matrices for + * 5-6-5 RGB displays are called "DM_565". These preprocessed tables can be + * generated with the gdk_rgb_preprocess_dm_565() function below. + */ + +#if 1 + +/* This dither table was generated by Raph Levien using patented + technology (US Patent 5,276,535). The dither table itself is in the + public domain. */ + +#define DM_WIDTH 128 +#define DM_WIDTH_SHIFT 7 +#define DM_HEIGHT 128 +static const guchar DM[128][128] = +{ + { 0, 41, 23, 5, 17, 39, 7, 15, 62, 23, 40, 51, 31, 47, 9, 32, 52, 27, 57, 25, 6, 61, 27, 52, 37, 7, 40, 63, 18, 36, 10, 42, 25, 62, 45, 34, 20, 42, 37, 14, 35, 29, 50, 10, 61, 2, 40, 8, 37, 12, 58, 22, 5, 41, 10, 39, 0, 60, 11, 46, 2, 55, 38, 17, 36, 59, 13, 54, 37, 56, 8, 29, 16, 13, 63, 22, 41, 55, 7, 20, 49, 14, 23, 55, 37, 23, 19, 36, 15, 49, 23, 63, 30, 14, 38, 27, 53, 13, 22, 41, 19, 31, 7, 19, 50, 30, 49, 16, 3, 32, 56, 40, 29, 34, 8, 48, 19, 45, 4, 51, 12, 46, 35, 49, 16, 42, 12, 62 }, + { 30, 57, 36, 54, 47, 34, 52, 27, 43, 4, 28, 7, 17, 36, 62, 13, 44, 7, 18, 48, 33, 21, 44, 14, 30, 47, 12, 33, 5, 55, 31, 58, 13, 30, 4, 17, 52, 10, 60, 26, 46, 0, 39, 27, 42, 22, 47, 25, 60, 32, 9, 38, 48, 17, 59, 30, 49, 18, 34, 25, 51, 19, 5, 48, 21, 8, 28, 46, 1, 32, 41, 19, 54, 47, 37, 18, 28, 11, 44, 30, 39, 56, 2, 33, 8, 42, 61, 28, 58, 8, 46, 9, 41, 4, 58, 7, 21, 48, 59, 10, 52, 14, 42, 57, 12, 25, 7, 53, 42, 24, 11, 50, 17, 59, 42, 2, 36, 60, 32, 17, 63, 29, 21, 7, 59, 32, 24, 39 }, + { 22, 8, 16, 32, 3, 25, 13, 57, 18, 45, 58, 39, 55, 20, 5, 42, 23, 34, 63, 1, 51, 10, 58, 4, 60, 23, 53, 27, 44, 21, 3, 48, 8, 50, 43, 54, 27, 32, 5, 55, 21, 58, 12, 53, 6, 36, 14, 50, 17, 29, 53, 15, 24, 52, 7, 36, 13, 42, 4, 53, 9, 35, 61, 26, 56, 32, 49, 15, 62, 23, 6, 60, 2, 31, 4, 48, 58, 38, 15, 61, 5, 25, 47, 28, 50, 15, 7, 40, 3, 32, 33, 52, 25, 50, 35, 42, 61, 3, 28, 36, 23, 63, 4, 33, 46, 62, 36, 23, 60, 6, 54, 28, 4, 37, 23, 55, 25, 8, 42, 54, 14, 6, 56, 38, 19, 52, 4, 46 }, + { 48, 53, 43, 12, 45, 63, 30, 37, 9, 34, 21, 1, 25, 47, 29, 58, 3, 54, 15, 39, 29, 17, 38, 35, 20, 43, 1, 49, 15, 59, 29, 39, 22, 35, 16, 23, 1, 47, 39, 18, 8, 44, 25, 31, 57, 19, 63, 4, 45, 3, 42, 61, 1, 31, 45, 20, 57, 29, 62, 21, 32, 41, 14, 44, 3, 39, 5, 34, 10, 43, 51, 35, 23, 52, 40, 10, 21, 1, 53, 18, 51, 43, 12, 62, 18, 54, 26, 51, 20, 57, 14, 1, 62, 16, 11, 18, 32, 39, 17, 44, 1, 48, 26, 37, 18, 2, 51, 14, 28, 45, 35, 18, 57, 13, 47, 11, 51, 20, 2, 39, 31, 47, 25, 1, 50, 11, 60, 7 }, + { 18, 28, 1, 56, 21, 10, 51, 2, 46, 54, 14, 61, 11, 50, 13, 38, 19, 31, 45, 9, 55, 24, 47, 5, 54, 9, 62, 11, 35, 8, 51, 14, 57, 6, 63, 40, 58, 14, 51, 28, 62, 34, 15, 48, 1, 41, 30, 35, 55, 21, 34, 11, 49, 37, 8, 52, 4, 23, 15, 43, 1, 58, 11, 23, 53, 16, 55, 26, 58, 18, 27, 12, 45, 14, 25, 63, 42, 33, 27, 35, 9, 31, 21, 38, 1, 44, 34, 12, 48, 38, 21, 44, 29, 47, 26, 53, 1, 46, 54, 8, 59, 29, 11, 55, 22, 41, 33, 20, 39, 1, 48, 9, 44, 32, 5, 62, 29, 44, 57, 23, 10, 58, 34, 43, 15, 37, 26, 33 }, + { 51, 38, 59, 24, 35, 42, 19, 60, 5, 32, 41, 26, 43, 33, 7, 53, 48, 11, 59, 23, 42, 2, 61, 30, 16, 40, 32, 24, 56, 41, 19, 33, 37, 26, 47, 9, 31, 22, 2, 45, 9, 54, 4, 37, 21, 52, 11, 23, 7, 57, 16, 25, 55, 18, 63, 27, 46, 39, 56, 10, 50, 37, 29, 47, 19, 63, 24, 9, 46, 2, 39, 60, 9, 57, 30, 7, 49, 11, 59, 3, 45, 57, 5, 60, 29, 22, 5, 60, 30, 9, 59, 18, 40, 6, 57, 36, 30, 12, 24, 34, 15, 40, 52, 6, 49, 9, 58, 4, 63, 12, 26, 61, 22, 53, 38, 16, 35, 14, 28, 50, 42, 17, 5, 28, 62, 20, 54, 12 }, + { 26, 6, 31, 15, 49, 6, 38, 27, 22, 49, 16, 56, 2, 62, 30, 21, 0, 36, 28, 6, 49, 32, 13, 52, 26, 50, 19, 46, 3, 26, 62, 0, 53, 12, 29, 3, 53, 41, 60, 24, 38, 13, 58, 16, 43, 9, 59, 39, 46, 28, 44, 40, 2, 33, 13, 41, 16, 6, 47, 31, 26, 17, 57, 6, 38, 0, 42, 36, 29, 52, 20, 31, 48, 0, 34, 56, 20, 36, 23, 54, 14, 41, 24, 37, 10, 55, 46, 25, 16, 45, 36, 4, 55, 23, 15, 8, 50, 62, 5, 56, 44, 20, 13, 28, 59, 31, 24, 47, 31, 52, 37, 17, 40, 0, 26, 49, 3, 60, 7, 33, 0, 61, 53, 40, 8, 45, 2, 41 }, + { 16, 63, 43, 4, 61, 24, 56, 13, 53, 8, 36, 12, 24, 41, 16, 46, 60, 26, 52, 39, 14, 57, 21, 37, 0, 45, 7, 59, 38, 17, 43, 10, 45, 20, 61, 43, 19, 11, 33, 17, 50, 32, 23, 61, 28, 49, 26, 0, 18, 51, 5, 60, 22, 58, 29, 0, 59, 34, 19, 62, 3, 52, 7, 44, 30, 59, 13, 50, 15, 62, 7, 17, 38, 22, 44, 15, 40, 4, 47, 28, 33, 17, 49, 16, 51, 40, 10, 56, 0, 53, 13, 49, 28, 38, 60, 21, 43, 19, 37, 27, 3, 51, 34, 39, 0, 45, 15, 43, 10, 21, 3, 55, 8, 33, 59, 10, 41, 18, 52, 24, 46, 20, 30, 13, 58, 22, 36, 57 }, + { 50, 34, 11, 47, 29, 17, 44, 0, 33, 63, 28, 46, 52, 5, 57, 10, 42, 18, 4, 63, 20, 8, 44, 10, 56, 34, 14, 29, 5, 54, 23, 59, 32, 49, 7, 34, 49, 27, 56, 0, 42, 7, 46, 3, 40, 6, 54, 32, 62, 13, 36, 10, 47, 8, 35, 49, 24, 51, 12, 40, 22, 35, 60, 12, 22, 51, 33, 4, 40, 25, 43, 55, 5, 54, 12, 61, 26, 51, 8, 62, 0, 53, 7, 63, 2, 32, 19, 34, 42, 24, 31, 63, 2, 10, 45, 33, 0, 48, 9, 61, 22, 47, 8, 62, 18, 56, 7, 54, 27, 57, 46, 30, 50, 19, 45, 30, 56, 36, 22, 47, 11, 38, 3, 51, 32, 48, 18, 9 }, + { 0, 21, 40, 19, 52, 9, 37, 48, 20, 40, 3, 18, 27, 38, 35, 22, 31, 56, 13, 35, 46, 28, 60, 40, 27, 18, 61, 50, 41, 30, 7, 36, 2, 25, 16, 57, 5, 15, 47, 29, 55, 19, 30, 52, 15, 34, 20, 12, 43, 30, 20, 54, 25, 44, 53, 12, 38, 5, 55, 27, 48, 15, 33, 27, 45, 8, 19, 28, 56, 11, 33, 49, 18, 36, 29, 2, 45, 16, 39, 19, 31, 43, 27, 35, 20, 52, 26, 6, 61, 11, 41, 17, 29, 51, 20, 56, 25, 32, 41, 17, 53, 31, 25, 14, 42, 23, 35, 16, 38, 6, 34, 12, 15, 62, 6, 21, 13, 1, 63, 9, 55, 27, 43, 25, 14, 4, 31, 55 }, + { 44, 29, 61, 2, 35, 58, 26, 15, 60, 10, 51, 59, 14, 55, 8, 50, 2, 44, 25, 51, 1, 33, 16, 4, 48, 36, 2, 21, 12, 57, 48, 13, 51, 55, 40, 28, 37, 62, 8, 39, 12, 63, 36, 10, 59, 24, 56, 47, 9, 50, 41, 1, 32, 17, 6, 21, 61, 30, 9, 43, 1, 54, 41, 2, 54, 37, 48, 61, 1, 46, 21, 3, 58, 24, 50, 32, 60, 10, 57, 25, 46, 12, 59, 4, 45, 13, 57, 47, 27, 39, 5, 58, 47, 14, 35, 4, 52, 13, 60, 6, 36, 10, 45, 55, 4, 50, 29, 2, 61, 50, 25, 58, 44, 24, 36, 42, 54, 28, 40, 32, 16, 56, 6, 62, 46, 39, 60, 23 }, + { 7, 48, 14, 54, 23, 40, 4, 45, 30, 22, 42, 32, 1, 44, 20, 29, 58, 8, 37, 19, 41, 54, 24, 58, 9, 53, 25, 46, 34, 16, 23, 38, 27, 11, 18, 1, 52, 21, 35, 22, 48, 5, 25, 45, 18, 38, 2, 27, 35, 4, 57, 15, 62, 39, 57, 28, 42, 16, 36, 60, 24, 18, 10, 63, 20, 5, 16, 23, 37, 14, 59, 27, 41, 8, 13, 42, 21, 35, 6, 50, 3, 38, 15, 48, 30, 39, 17, 3, 49, 14, 53, 33, 24, 7, 61, 44, 11, 39, 23, 49, 19, 58, 1, 32, 36, 12, 60, 41, 20, 13, 41, 4, 39, 1, 48, 8, 18, 51, 14, 44, 5, 37, 21, 34, 1, 26, 10, 37 }, + { 53, 36, 27, 9, 50, 12, 32, 55, 2, 57, 7, 17, 48, 34, 63, 15, 40, 26, 62, 11, 49, 6, 31, 39, 22, 42, 6, 63, 1, 39, 60, 4, 42, 61, 32, 45, 24, 44, 2, 60, 16, 41, 53, 1, 33, 61, 49, 17, 63, 23, 45, 26, 33, 3, 23, 46, 2, 50, 20, 4, 45, 34, 49, 30, 39, 58, 44, 31, 53, 34, 6, 52, 30, 47, 63, 1, 53, 22, 42, 31, 58, 23, 54, 22, 61, 8, 36, 59, 22, 35, 21, 1, 55, 40, 27, 16, 30, 54, 2, 29, 43, 16, 39, 63, 21, 46, 26, 10, 48, 32, 19, 53, 30, 56, 26, 60, 33, 4, 61, 23, 49, 59, 15, 53, 19, 58, 42, 16 }, + { 20, 5, 59, 46, 25, 62, 7, 19, 43, 25, 37, 61, 11, 24, 4, 54, 12, 52, 3, 32, 17, 61, 12, 47, 15, 55, 18, 31, 53, 28, 9, 50, 21, 6, 55, 9, 58, 14, 54, 26, 33, 7, 31, 58, 13, 21, 8, 42, 29, 6, 37, 11, 48, 52, 14, 60, 11, 39, 56, 32, 14, 58, 7, 26, 17, 4, 42, 8, 11, 47, 19, 38, 10, 17, 26, 37, 9, 55, 28, 13, 18, 40, 6, 33, 1, 43, 25, 11, 51, 7, 62, 43, 18, 37, 3, 57, 45, 9, 38, 58, 5, 52, 27, 7, 17, 53, 5, 57, 37, 2, 63, 9, 22, 15, 11, 38, 25, 45, 35, 0, 28, 10, 41, 30, 50, 8, 31, 57 }, + { 49, 33, 16, 38, 1, 42, 51, 34, 53, 14, 28, 49, 30, 56, 36, 23, 43, 20, 38, 56, 22, 45, 28, 0, 62, 35, 26, 44, 11, 19, 52, 35, 44, 15, 30, 38, 10, 31, 40, 4, 46, 50, 20, 40, 27, 44, 51, 14, 56, 53, 19, 59, 7, 29, 41, 19, 35, 25, 8, 52, 22, 44, 13, 53, 50, 32, 61, 24, 56, 25, 63, 0, 45, 57, 33, 59, 16, 46, 4, 62, 50, 11, 60, 37, 52, 19, 55, 29, 37, 46, 13, 26, 48, 10, 50, 34, 21, 63, 26, 13, 42, 33, 22, 55, 35, 28, 43, 15, 24, 51, 27, 34, 46, 49, 58, 3, 52, 9, 57, 19, 48, 55, 3, 35, 12, 45, 24, 3 }, + { 41, 11, 56, 28, 18, 31, 22, 10, 37, 6, 47, 13, 3, 41, 9, 46, 0, 48, 29, 6, 34, 10, 55, 37, 20, 8, 49, 3, 41, 59, 14, 25, 0, 63, 19, 47, 27, 51, 17, 57, 23, 10, 61, 6, 54, 3, 38, 31, 0, 22, 34, 43, 20, 55, 31, 0, 49, 63, 29, 38, 3, 62, 28, 40, 0, 22, 14, 35, 2, 48, 15, 43, 23, 14, 3, 29, 49, 20, 39, 34, 0, 44, 29, 9, 15, 47, 5, 42, 0, 31, 58, 5, 31, 61, 23, 15, 0, 47, 19, 50, 24, 3, 59, 11, 44, 0, 31, 59, 6, 42, 17, 60, 0, 39, 20, 31, 43, 17, 29, 40, 12, 25, 60, 22, 52, 15, 63, 29 }, + { 20, 52, 8, 44, 62, 4, 59, 49, 17, 63, 21, 39, 60, 18, 52, 27, 33, 59, 14, 51, 59, 43, 24, 5, 51, 30, 57, 17, 32, 5, 37, 56, 48, 34, 42, 3, 60, 5, 36, 13, 43, 37, 18, 34, 25, 12, 59, 24, 47, 36, 11, 50, 3, 38, 9, 58, 16, 5, 43, 18, 47, 10, 37, 18, 59, 46, 29, 52, 40, 12, 34, 28, 56, 36, 53, 7, 43, 8, 24, 52, 26, 17, 56, 43, 24, 32, 63, 20, 57, 16, 22, 52, 36, 8, 41, 56, 29, 32, 54, 7, 35, 57, 14, 48, 20, 62, 13, 39, 53, 29, 8, 45, 13, 29, 7, 61, 14, 54, 6, 63, 38, 32, 18, 43, 2, 39, 6, 47 }, + { 0, 58, 23, 35, 13, 46, 12, 39, 0, 31, 55, 24, 5, 35, 15, 61, 17, 5, 39, 25, 18, 2, 50, 33, 41, 13, 39, 23, 62, 46, 29, 12, 22, 8, 56, 25, 20, 49, 32, 62, 0, 56, 11, 46, 63, 42, 9, 16, 55, 5, 60, 15, 62, 26, 45, 21, 36, 51, 13, 57, 31, 24, 55, 6, 35, 9, 57, 5, 20, 60, 7, 51, 5, 19, 40, 25, 61, 32, 56, 12, 36, 48, 21, 2, 58, 12, 39, 28, 9, 50, 40, 12, 44, 18, 25, 49, 6, 38, 11, 62, 18, 46, 30, 9, 40, 25, 49, 19, 10, 36, 55, 22, 33, 52, 41, 18, 37, 27, 49, 21, 2, 46, 7, 53, 33, 61, 27, 35 }, + { 41, 31, 5, 39, 51, 26, 33, 57, 27, 41, 9, 44, 54, 29, 48, 7, 44, 36, 57, 10, 31, 63, 16, 45, 11, 60, 1, 47, 7, 20, 43, 3, 58, 36, 13, 52, 39, 7, 15, 28, 22, 48, 30, 21, 1, 29, 49, 44, 27, 17, 40, 30, 24, 42, 12, 53, 33, 7, 47, 20, 1, 42, 11, 49, 25, 43, 17, 32, 45, 27, 41, 21, 31, 62, 11, 49, 2, 15, 42, 5, 63, 7, 41, 27, 49, 6, 54, 23, 46, 34, 2, 28, 54, 3, 59, 12, 46, 17, 42, 28, 40, 1, 37, 51, 5, 55, 2, 34, 47, 16, 3, 62, 47, 5, 23, 56, 1, 44, 12, 34, 51, 16, 57, 11, 25, 17, 54, 13 }, + { 60, 26, 55, 18, 3, 60, 20, 6, 52, 15, 50, 19, 32, 11, 23, 53, 26, 21, 1, 47, 42, 27, 8, 58, 21, 27, 53, 36, 26, 54, 31, 50, 17, 30, 45, 1, 29, 59, 44, 53, 41, 4, 35, 58, 51, 19, 32, 4, 52, 34, 48, 8, 51, 5, 56, 2, 25, 61, 27, 38, 54, 27, 62, 21, 51, 1, 39, 62, 10, 50, 1, 58, 13, 47, 38, 18, 35, 54, 22, 51, 30, 19, 59, 34, 14, 32, 44, 4, 60, 15, 52, 62, 20, 43, 30, 35, 21, 60, 4, 52, 12, 24, 61, 18, 30, 42, 23, 61, 25, 50, 27, 38, 11, 59, 12, 35, 50, 30, 59, 24, 8, 42, 28, 37, 48, 9, 44, 21 }, + { 10, 47, 15, 50, 30, 43, 8, 45, 29, 2, 36, 59, 1, 58, 41, 3, 63, 31, 54, 20, 13, 55, 35, 38, 4, 44, 15, 9, 61, 2, 14, 38, 61, 10, 23, 54, 18, 12, 24, 2, 14, 55, 16, 8, 38, 14, 41, 60, 10, 23, 1, 58, 32, 17, 28, 37, 41, 15, 3, 60, 15, 33, 4, 36, 16, 59, 28, 14, 23, 55, 37, 18, 44, 28, 2, 57, 30, 10, 27, 46, 14, 38, 3, 53, 21, 61, 17, 35, 10, 41, 26, 7, 33, 9, 57, 1, 53, 37, 26, 20, 56, 48, 9, 33, 58, 16, 37, 7, 45, 1, 57, 15, 32, 26, 42, 23, 7, 20, 4, 54, 31, 62, 22, 1, 59, 30, 4, 51 }, + { 36, 2, 38, 11, 24, 36, 54, 22, 62, 47, 25, 8, 28, 45, 16, 38, 12, 43, 9, 37, 49, 3, 23, 52, 18, 30, 50, 33, 19, 42, 49, 26, 6, 40, 47, 35, 63, 38, 50, 33, 60, 26, 36, 47, 24, 57, 6, 26, 39, 63, 19, 44, 14, 46, 61, 9, 50, 30, 45, 23, 10, 50, 44, 8, 31, 54, 6, 46, 36, 4, 30, 54, 8, 52, 22, 41, 4, 60, 40, 0, 58, 24, 45, 10, 37, 1, 48, 30, 56, 17, 38, 48, 24, 47, 19, 39, 14, 8, 45, 32, 2, 34, 27, 44, 4, 52, 11, 56, 31, 21, 40, 19, 44, 51, 2, 63, 46, 58, 36, 43, 14, 5, 50, 38, 14, 56, 40, 23 }, + { 61, 46, 32, 63, 54, 1, 14, 34, 12, 40, 18, 49, 37, 10, 61, 30, 51, 24, 60, 7, 29, 40, 62, 11, 46, 58, 6, 56, 24, 10, 34, 52, 21, 59, 16, 3, 27, 5, 20, 46, 9, 40, 7, 62, 2, 30, 53, 15, 48, 10, 28, 35, 54, 6, 21, 34, 18, 55, 7, 40, 57, 19, 26, 60, 41, 13, 24, 51, 19, 61, 9, 25, 34, 15, 63, 11, 45, 17, 20, 47, 33, 8, 31, 62, 43, 26, 53, 7, 24, 59, 0, 13, 55, 4, 62, 27, 51, 31, 63, 15, 58, 7, 54, 14, 46, 22, 28, 43, 12, 63, 8, 54, 5, 17, 39, 33, 15, 10, 27, 17, 47, 34, 19, 45, 27, 12, 33, 17 }, + { 5, 28, 21, 7, 17, 48, 42, 58, 23, 4, 63, 14, 55, 21, 34, 5, 19, 0, 45, 17, 52, 15, 25, 32, 0, 22, 40, 13, 45, 62, 18, 0, 43, 11, 33, 55, 30, 42, 57, 19, 51, 31, 22, 43, 18, 45, 34, 0, 43, 31, 56, 3, 23, 40, 59, 0, 44, 13, 48, 35, 2, 32, 46, 0, 21, 48, 35, 3, 40, 32, 43, 59, 0, 48, 33, 26, 53, 36, 55, 12, 51, 16, 55, 5, 18, 29, 11, 39, 51, 19, 45, 31, 42, 21, 35, 6, 22, 47, 10, 38, 23, 50, 20, 36, 0, 60, 38, 4, 50, 35, 48, 34, 24, 57, 9, 53, 28, 48, 61, 0, 56, 24, 53, 3, 63, 6, 42, 57 }, + { 13, 53, 45, 40, 58, 27, 6, 16, 38, 51, 33, 30, 43, 2, 47, 56, 40, 50, 33, 57, 27, 5, 47, 42, 60, 36, 16, 54, 28, 4, 37, 57, 28, 51, 22, 8, 45, 14, 6, 39, 0, 54, 11, 59, 28, 12, 50, 21, 61, 13, 19, 38, 49, 11, 25, 37, 58, 29, 22, 63, 14, 56, 12, 53, 30, 63, 9, 57, 26, 12, 47, 16, 23, 39, 50, 6, 31, 2, 25, 6, 28, 41, 36, 22, 50, 57, 42, 3, 34, 8, 28, 61, 11, 50, 16, 54, 41, 0, 55, 43, 5, 29, 41, 63, 25, 16, 53, 18, 26, 10, 21, 0, 61, 30, 41, 22, 3, 38, 20, 39, 29, 8, 41, 16, 36, 52, 22, 19 }, + { 55, 34, 0, 25, 10, 32, 56, 44, 28, 0, 57, 7, 26, 53, 23, 8, 13, 35, 22, 12, 36, 60, 20, 8, 14, 29, 48, 2, 41, 49, 23, 13, 39, 7, 48, 58, 25, 53, 34, 62, 28, 16, 48, 4, 37, 56, 27, 5, 36, 52, 46, 7, 62, 33, 52, 11, 17, 53, 5, 28, 41, 24, 38, 17, 5, 39, 20, 45, 15, 56, 5, 38, 60, 8, 14, 57, 21, 48, 62, 39, 59, 13, 1, 60, 9, 32, 16, 63, 44, 25, 52, 15, 36, 2, 60, 29, 12, 33, 25, 17, 59, 45, 13, 8, 49, 32, 6, 40, 59, 29, 45, 37, 13, 47, 6, 55, 30, 45, 9, 52, 13, 59, 25, 47, 32, 1, 49, 30 }, + { 9, 39, 14, 61, 49, 37, 3, 20, 50, 13, 41, 19, 46, 17, 38, 59, 28, 62, 4, 44, 54, 1, 34, 51, 55, 7, 63, 32, 21, 8, 56, 31, 62, 19, 36, 1, 41, 17, 24, 12, 42, 35, 25, 52, 20, 8, 44, 59, 25, 2, 22, 42, 16, 29, 4, 46, 20, 36, 43, 9, 51, 8, 49, 26, 58, 33, 54, 1, 37, 29, 52, 20, 27, 45, 19, 35, 42, 16, 10, 32, 20, 49, 46, 27, 40, 4, 47, 22, 13, 55, 4, 47, 26, 44, 23, 40, 58, 19, 48, 13, 31, 2, 57, 34, 42, 19, 61, 32, 14, 55, 5, 51, 26, 19, 58, 16, 49, 14, 62, 5, 33, 44, 21, 7, 60, 26, 11, 41 }, + { 62, 24, 47, 29, 8, 19, 53, 11, 60, 24, 32, 61, 4, 55, 31, 2, 49, 16, 39, 9, 31, 24, 43, 17, 26, 38, 11, 25, 58, 43, 12, 35, 3, 46, 15, 32, 63, 4, 49, 56, 2, 60, 10, 32, 63, 17, 39, 12, 55, 30, 57, 9, 48, 55, 39, 24, 60, 2, 58, 31, 19, 61, 34, 3, 42, 11, 22, 46, 7, 61, 10, 42, 3, 55, 32, 1, 58, 28, 44, 54, 4, 34, 23, 15, 56, 20, 37, 58, 6, 30, 38, 18, 63, 9, 32, 5, 51, 3, 62, 37, 52, 18, 39, 23, 3, 51, 9, 47, 1, 23, 43, 15, 60, 35, 11, 40, 1, 36, 31, 26, 57, 2, 37, 54, 18, 44, 58, 16 }, + { 5, 51, 3, 33, 43, 62, 21, 42, 35, 9, 48, 15, 36, 10, 22, 42, 20, 46, 26, 56, 50, 12, 59, 3, 48, 19, 45, 53, 1, 27, 47, 17, 52, 24, 56, 11, 51, 21, 37, 30, 20, 46, 14, 41, 1, 47, 33, 7, 41, 17, 35, 27, 20, 1, 14, 54, 26, 33, 18, 47, 1, 44, 14, 59, 16, 52, 28, 18, 49, 31, 25, 34, 63, 13, 51, 24, 9, 50, 3, 23, 38, 63, 7, 52, 29, 46, 11, 33, 50, 22, 57, 36, 1, 57, 49, 17, 39, 28, 9, 35, 6, 27, 53, 15, 55, 30, 24, 58, 36, 41, 11, 52, 32, 3, 44, 25, 62, 23, 51, 15, 42, 22, 50, 10, 39, 4, 31, 35 }, + { 46, 22, 57, 17, 12, 39, 26, 5, 31, 59, 1, 45, 27, 62, 52, 7, 58, 33, 6, 18, 39, 22, 33, 41, 57, 5, 35, 18, 40, 16, 60, 5, 29, 42, 7, 39, 27, 44, 9, 47, 8, 26, 54, 22, 51, 29, 24, 49, 15, 61, 4, 51, 31, 63, 43, 6, 50, 8, 39, 12, 53, 37, 23, 30, 40, 6, 62, 43, 14, 53, 2, 49, 7, 36, 17, 41, 61, 37, 18, 56, 11, 18, 44, 35, 2, 19, 61, 0, 41, 14, 8, 30, 43, 12, 24, 46, 14, 54, 42, 21, 44, 61, 10, 46, 37, 11, 44, 7, 18, 63, 20, 29, 7, 49, 28, 54, 8, 43, 4, 48, 18, 63, 12, 29, 48, 24, 59, 20 }, + { 13, 36, 28, 54, 35, 2, 56, 46, 16, 49, 22, 40, 11, 34, 14, 43, 29, 12, 63, 48, 2, 61, 7, 15, 28, 30, 50, 9, 61, 33, 38, 23, 54, 13, 61, 33, 3, 59, 16, 35, 58, 40, 5, 38, 13, 57, 3, 58, 37, 21, 45, 12, 39, 7, 35, 30, 13, 56, 22, 62, 27, 6, 55, 10, 48, 21, 33, 2, 38, 23, 40, 20, 44, 29, 59, 4, 26, 12, 33, 47, 28, 53, 31, 13, 59, 41, 27, 49, 26, 54, 45, 16, 53, 21, 35, 7, 59, 26, 11, 56, 1, 24, 33, 4, 28, 62, 21, 49, 31, 2, 56, 39, 24, 58, 13, 17, 37, 21, 56, 10, 38, 0, 34, 55, 15, 43, 1, 52 }, + { 42, 9, 50, 6, 25, 60, 14, 38, 10, 29, 53, 18, 57, 3, 25, 51, 0, 53, 25, 17, 29, 37, 52, 46, 0, 62, 14, 37, 4, 50, 10, 44, 0, 46, 20, 25, 50, 19, 55, 0, 23, 31, 62, 34, 11, 45, 19, 32, 0, 53, 10, 59, 23, 47, 18, 60, 42, 28, 37, 3, 50, 15, 35, 44, 0, 51, 27, 60, 9, 57, 16, 58, 11, 22, 46, 15, 53, 48, 7, 42, 0, 60, 5, 49, 24, 54, 9, 17, 39, 5, 34, 62, 3, 40, 60, 31, 0, 47, 29, 16, 49, 39, 59, 17, 50, 0, 40, 13, 53, 38, 16, 46, 0, 42, 34, 60, 2, 53, 29, 31, 58, 46, 27, 6, 61, 8, 37, 28 }, + { 0, 63, 21, 40, 45, 18, 51, 23, 63, 34, 6, 43, 28, 38, 55, 19, 40, 35, 8, 41, 54, 10, 21, 32, 39, 23, 53, 26, 55, 28, 22, 63, 30, 34, 9, 48, 6, 38, 29, 43, 49, 6, 18, 52, 27, 61, 9, 43, 28, 42, 33, 26, 56, 3, 51, 23, 0, 48, 16, 45, 32, 25, 63, 20, 57, 17, 42, 12, 35, 47, 5, 31, 39, 56, 6, 30, 34, 21, 61, 25, 14, 40, 22, 38, 15, 6, 36, 56, 20, 60, 25, 12, 51, 27, 10, 56, 42, 20, 36, 63, 32, 6, 21, 41, 12, 34, 60, 26, 5, 48, 27, 10, 62, 19, 6, 47, 39, 14, 45, 7, 24, 17, 41, 32, 23, 51, 19, 56 }, + { 45, 31, 15, 59, 4, 33, 7, 47, 0, 41, 13, 61, 4, 47, 9, 23, 60, 14, 57, 31, 4, 45, 59, 6, 58, 10, 44, 20, 8, 42, 15, 6, 55, 17, 58, 31, 53, 12, 61, 10, 15, 57, 43, 2, 23, 35, 48, 14, 54, 6, 18, 49, 15, 38, 11, 34, 62, 9, 21, 58, 11, 41, 4, 31, 38, 8, 29, 55, 19, 36, 27, 52, 0, 25, 50, 43, 1, 39, 8, 55, 35, 51, 10, 30, 45, 62, 29, 2, 46, 10, 32, 48, 18, 38, 5, 22, 33, 8, 51, 3, 14, 44, 54, 25, 57, 30, 18, 52, 33, 22, 59, 28, 36, 52, 32, 21, 26, 50, 5, 55, 35, 60, 14, 54, 4, 40, 16, 33 }, + { 27, 3, 49, 10, 30, 40, 55, 27, 57, 24, 52, 21, 32, 17, 60, 30, 5, 44, 27, 49, 19, 34, 13, 24, 43, 36, 3, 49, 31, 59, 37, 48, 26, 41, 2, 41, 14, 36, 21, 32, 40, 26, 13, 49, 55, 5, 16, 40, 25, 60, 36, 1, 63, 29, 17, 44, 25, 40, 52, 5, 29, 47, 54, 13, 46, 24, 60, 4, 51, 22, 63, 14, 45, 18, 12, 62, 17, 57, 19, 42, 3, 26, 58, 48, 1, 21, 40, 52, 23, 37, 44, 1, 29, 58, 43, 50, 15, 61, 19, 45, 58, 28, 7, 48, 2, 46, 8, 42, 3, 55, 8, 50, 12, 4, 55, 10, 63, 33, 20, 40, 11, 3, 46, 20, 48, 26, 61, 11 }, + { 44, 56, 24, 36, 53, 19, 12, 37, 16, 44, 7, 36, 49, 54, 11, 37, 48, 21, 15, 1, 62, 25, 47, 56, 16, 18, 51, 12, 40, 1, 24, 11, 52, 16, 23, 59, 28, 1, 45, 53, 4, 60, 37, 21, 39, 30, 63, 20, 52, 10, 30, 45, 8, 41, 54, 4, 57, 7, 34, 55, 36, 18, 23, 59, 2, 48, 11, 32, 44, 1, 41, 8, 33, 54, 38, 23, 30, 46, 6, 29, 62, 18, 32, 16, 55, 34, 14, 11, 61, 7, 55, 16, 53, 13, 23, 2, 55, 37, 26, 10, 33, 23, 36, 16, 38, 22, 56, 15, 24, 43, 35, 17, 44, 40, 25, 46, 16, 1, 57, 25, 49, 36, 28, 62, 9, 35, 7, 53 }, + { 17, 38, 8, 61, 1, 50, 26, 62, 3, 31, 56, 15, 1, 26, 40, 2, 34, 51, 56, 36, 42, 9, 38, 2, 29, 60, 32, 57, 19, 62, 34, 47, 4, 57, 39, 7, 44, 63, 24, 18, 46, 28, 8, 54, 1, 34, 7, 46, 3, 37, 50, 23, 57, 21, 13, 46, 31, 20, 43, 15, 1, 61, 8, 33, 37, 17, 56, 26, 15, 49, 24, 59, 28, 3, 56, 9, 52, 32, 13, 49, 10, 43, 5, 45, 8, 25, 59, 42, 28, 33, 19, 40, 8, 63, 35, 47, 25, 4, 40, 52, 1, 60, 12, 53, 63, 9, 29, 60, 37, 19, 1, 62, 31, 20, 58, 12, 41, 30, 43, 9, 18, 52, 22, 1, 39, 30, 58, 21 }, + { 13, 47, 29, 18, 43, 34, 5, 48, 20, 42, 10, 45, 30, 58, 20, 63, 24, 11, 6, 28, 54, 14, 22, 52, 41, 7, 26, 5, 45, 15, 53, 13, 35, 27, 18, 50, 12, 33, 5, 56, 10, 17, 45, 24, 59, 15, 50, 26, 56, 13, 19, 5, 32, 52, 27, 36, 2, 61, 12, 26, 49, 40, 27, 52, 13, 50, 6, 39, 61, 34, 10, 37, 48, 20, 41, 27, 2, 36, 59, 24, 54, 33, 63, 20, 38, 50, 3, 17, 52, 4, 58, 27, 45, 21, 32, 11, 48, 17, 57, 20, 46, 38, 25, 43, 4, 34, 51, 6, 13, 45, 57, 26, 6, 48, 2, 35, 53, 23, 61, 34, 59, 6, 42, 56, 13, 51, 2, 41 }, + { 32, 5, 55, 23, 58, 14, 22, 52, 29, 15, 61, 25, 51, 8, 43, 13, 53, 41, 46, 20, 3, 33, 63, 11, 48, 21, 54, 38, 28, 3, 30, 43, 21, 62, 9, 31, 55, 22, 51, 29, 37, 62, 32, 12, 42, 29, 41, 9, 33, 44, 62, 28, 43, 1, 59, 19, 48, 30, 51, 39, 24, 4, 58, 19, 42, 29, 22, 43, 3, 18, 53, 5, 13, 50, 16, 60, 45, 21, 7, 40, 15, 0, 26, 53, 13, 31, 43, 24, 47, 31, 15, 49, 2, 41, 6, 59, 29, 42, 9, 30, 14, 7, 49, 18, 31, 47, 20, 39, 49, 32, 11, 41, 54, 15, 61, 18, 7, 38, 4, 13, 44, 28, 15, 32, 45, 19, 27, 49 }, + { 63, 34, 11, 39, 2, 45, 37, 8, 59, 39, 33, 4, 36, 17, 48, 5, 29, 18, 32, 61, 39, 50, 5, 27, 35, 0, 46, 12, 22, 49, 60, 6, 54, 0, 38, 49, 2, 42, 15, 40, 0, 47, 20, 51, 3, 57, 18, 61, 22, 0, 39, 16, 55, 12, 35, 8, 41, 22, 6, 59, 16, 45, 10, 36, 0, 62, 9, 54, 30, 58, 21, 43, 63, 31, 7, 35, 12, 48, 58, 28, 47, 37, 41, 9, 57, 20, 61, 0, 36, 11, 57, 35, 23, 52, 37, 18, 0, 62, 22, 55, 35, 62, 27, 54, 0, 15, 61, 28, 2, 59, 22, 9, 37, 27, 33, 51, 29, 48, 19, 50, 25, 37, 10, 57, 5, 37, 60, 8 }, + { 20, 25, 46, 52, 31, 60, 12, 55, 0, 19, 11, 46, 62, 35, 23, 38, 57, 0, 55, 10, 16, 30, 58, 44, 17, 59, 29, 63, 42, 8, 36, 20, 33, 46, 16, 61, 25, 35, 8, 54, 26, 7, 58, 22, 34, 6, 47, 14, 53, 31, 48, 9, 37, 25, 49, 63, 16, 55, 45, 14, 34, 63, 21, 53, 25, 33, 46, 16, 35, 7, 46, 29, 0, 39, 25, 55, 22, 34, 18, 4, 56, 11, 23, 51, 28, 6, 39, 14, 62, 44, 19, 8, 60, 12, 56, 28, 50, 34, 39, 5, 51, 3, 41, 12, 57, 35, 10, 53, 25, 17, 52, 30, 47, 0, 43, 14, 5, 57, 31, 55, 0, 63, 47, 23, 54, 24, 14, 43 }, + { 0, 57, 16, 6, 26, 19, 35, 28, 49, 42, 54, 26, 21, 1, 59, 27, 9, 47, 26, 44, 50, 22, 13, 40, 8, 37, 10, 34, 17, 56, 25, 58, 13, 27, 44, 9, 20, 58, 31, 17, 60, 36, 10, 41, 53, 25, 36, 39, 4, 24, 58, 17, 60, 4, 22, 38, 10, 32, 0, 50, 31, 7, 28, 47, 12, 57, 5, 26, 52, 23, 14, 40, 57, 17, 47, 5, 53, 1, 44, 31, 19, 60, 46, 2, 35, 48, 30, 54, 22, 5, 51, 39, 25, 31, 4, 43, 14, 9, 45, 16, 24, 44, 19, 29, 40, 23, 44, 7, 38, 42, 4, 63, 12, 54, 23, 59, 22, 42, 8, 15, 40, 21, 8, 34, 3, 41, 30, 50 }, + { 39, 10, 48, 33, 41, 54, 5, 47, 23, 13, 32, 7, 52, 44, 14, 39, 58, 18, 35, 6, 37, 2, 60, 24, 55, 19, 53, 2, 51, 32, 1, 41, 51, 4, 40, 29, 47, 3, 52, 44, 13, 49, 28, 16, 1, 62, 11, 27, 52, 35, 5, 42, 29, 47, 14, 56, 28, 53, 26, 38, 9, 56, 40, 3, 38, 15, 41, 60, 1, 37, 50, 25, 11, 28, 61, 19, 42, 62, 10, 52, 39, 6, 32, 14, 58, 17, 7, 26, 42, 34, 27, 10, 54, 40, 20, 63, 26, 53, 21, 61, 32, 7, 59, 48, 3, 56, 18, 31, 58, 14, 49, 21, 36, 16, 45, 9, 36, 24, 62, 45, 27, 31, 53, 17, 49, 12, 62, 18 }, + { 28, 59, 21, 58, 2, 16, 38, 9, 62, 3, 56, 41, 10, 31, 50, 4, 32, 52, 12, 63, 23, 46, 33, 31, 4, 48, 25, 43, 14, 23, 47, 11, 22, 55, 14, 60, 23, 37, 11, 39, 23, 2, 45, 56, 31, 43, 19, 55, 16, 46, 21, 51, 11, 33, 44, 2, 41, 18, 5, 52, 23, 44, 17, 60, 27, 49, 11, 32, 44, 10, 54, 2, 56, 33, 8, 38, 13, 29, 36, 16, 24, 63, 27, 51, 21, 43, 56, 12, 49, 3, 59, 48, 1, 15, 46, 7, 36, 2, 47, 11, 50, 27, 37, 13, 33, 8, 51, 46, 1, 34, 28, 40, 3, 33, 60, 29, 47, 1, 35, 11, 59, 42, 2, 60, 26, 46, 6, 35 }, + { 4, 43, 9, 29, 36, 63, 24, 44, 20, 50, 30, 17, 60, 22, 16, 43, 25, 3, 42, 19, 51, 15, 8, 54, 42, 15, 61, 5, 39, 57, 18, 61, 31, 48, 34, 2, 50, 19, 57, 5, 63, 33, 19, 38, 13, 27, 48, 7, 32, 61, 2, 26, 58, 6, 24, 50, 13, 61, 42, 20, 62, 2, 35, 20, 51, 4, 62, 18, 23, 58, 20, 31, 43, 15, 51, 45, 26, 50, 4, 55, 45, 3, 35, 9, 38, 1, 32, 61, 20, 45, 17, 33, 24, 57, 29, 51, 22, 58, 38, 30, 15, 1, 54, 21, 63, 43, 26, 12, 24, 56, 8, 60, 50, 19, 5, 52, 13, 54, 17, 50, 4, 16, 36, 12, 32, 56, 22, 54 }, + { 51, 25, 40, 53, 12, 49, 15, 57, 34, 7, 38, 47, 2, 36, 55, 8, 61, 30, 56, 7, 28, 59, 48, 11, 27, 35, 21, 45, 28, 36, 9, 38, 6, 16, 24, 63, 10, 32, 28, 43, 21, 53, 5, 60, 8, 57, 3, 45, 11, 37, 15, 54, 40, 20, 62, 36, 27, 34, 11, 48, 30, 15, 54, 8, 30, 42, 22, 34, 48, 13, 35, 63, 4, 37, 22, 2, 59, 9, 41, 23, 13, 41, 49, 18, 59, 24, 40, 5, 37, 30, 9, 61, 44, 6, 37, 11, 33, 17, 5, 55, 41, 60, 23, 39, 17, 5, 30, 62, 41, 16, 46, 25, 11, 56, 39, 26, 20, 38, 29, 39, 22, 52, 44, 20, 48, 1, 38, 14 }, + { 15, 33, 2, 18, 44, 6, 27, 0, 32, 61, 25, 12, 58, 28, 40, 20, 47, 13, 34, 43, 38, 1, 23, 62, 40, 0, 51, 10, 63, 3, 52, 26, 44, 30, 45, 6, 41, 54, 0, 51, 12, 30, 46, 24, 49, 22, 40, 33, 63, 23, 43, 30, 9, 47, 0, 17, 54, 7, 57, 3, 37, 47, 24, 46, 13, 55, 7, 52, 2, 42, 6, 26, 49, 18, 60, 34, 16, 57, 33, 20, 61, 30, 8, 54, 14, 46, 12, 53, 16, 55, 38, 13, 22, 53, 18, 59, 46, 27, 43, 19, 32, 10, 45, 6, 49, 36, 52, 2, 20, 55, 6, 39, 32, 15, 44, 3, 58, 10, 63, 6, 56, 30, 7, 58, 9, 40, 19, 63 }, + { 10, 47, 61, 23, 55, 31, 52, 42, 17, 45, 4, 51, 27, 6, 15, 53, 0, 49, 26, 10, 56, 18, 36, 6, 20, 58, 32, 30, 13, 49, 19, 56, 0, 59, 12, 53, 27, 17, 38, 25, 48, 9, 15, 36, 14, 30, 59, 17, 0, 50, 8, 58, 18, 56, 31, 45, 21, 41, 29, 19, 60, 6, 32, 59, 0, 36, 29, 39, 19, 59, 46, 12, 55, 30, 10, 47, 24, 3, 28, 48, 0, 55, 44, 27, 33, 4, 63, 29, 49, 0, 26, 50, 34, 2, 42, 14, 0, 62, 9, 56, 3, 52, 28, 34, 58, 9, 20, 48, 37, 32, 22, 53, 0, 62, 27, 49, 34, 46, 21, 33, 41, 14, 25, 37, 53, 29, 31, 45 }, + { 56, 28, 7, 37, 11, 36, 20, 9, 54, 14, 39, 19, 34, 63, 45, 37, 24, 17, 60, 31, 21, 45, 53, 29, 47, 15, 7, 55, 40, 23, 34, 14, 42, 20, 37, 35, 15, 59, 7, 62, 34, 40, 59, 1, 51, 42, 10, 28, 54, 21, 35, 5, 38, 13, 36, 4, 59, 12, 39, 53, 15, 43, 9, 21, 39, 62, 16, 56, 25, 9, 32, 38, 0, 41, 14, 51, 40, 53, 43, 11, 37, 17, 5, 22, 57, 39, 19, 7, 42, 21, 60, 10, 31, 63, 25, 52, 30, 49, 36, 25, 48, 17, 61, 14, 22, 42, 29, 13, 60, 11, 47, 18, 35, 41, 7, 23, 4, 16, 51, 11, 0, 48, 61, 3, 17, 50, 5, 24 }, + { 0, 42, 21, 49, 60, 3, 57, 40, 29, 48, 23, 56, 42, 11, 22, 5, 59, 39, 4, 50, 3, 41, 12, 57, 25, 50, 44, 18, 4, 46, 7, 62, 33, 50, 4, 56, 21, 32, 43, 18, 3, 23, 55, 34, 20, 4, 53, 38, 12, 46, 29, 52, 25, 61, 23, 51, 26, 46, 1, 34, 25, 57, 28, 51, 26, 11, 50, 3, 44, 28, 53, 21, 57, 27, 62, 6, 31, 19, 8, 63, 26, 59, 36, 47, 15, 29, 50, 25, 35, 47, 18, 41, 4, 48, 8, 40, 12, 23, 6, 44, 13, 40, 1, 31, 55, 0, 61, 43, 4, 50, 26, 58, 9, 53, 24, 61, 42, 55, 31, 43, 57, 20, 34, 27, 43, 8, 59, 39 }, + { 18, 51, 30, 13, 26, 16, 46, 22, 2, 59, 8, 30, 1, 48, 33, 51, 29, 9, 46, 16, 62, 14, 33, 2, 38, 9, 27, 60, 37, 26, 53, 17, 28, 10, 24, 46, 2, 49, 8, 57, 29, 45, 6, 26, 62, 44, 18, 25, 61, 3, 42, 14, 49, 10, 43, 6, 17, 32, 63, 10, 49, 4, 40, 14, 45, 33, 22, 37, 12, 61, 5, 17, 43, 7, 23, 37, 15, 58, 49, 13, 39, 21, 10, 52, 1, 62, 9, 56, 12, 2, 58, 28, 36, 16, 56, 28, 56, 35, 20, 63, 24, 37, 51, 8, 45, 25, 16, 33, 27, 38, 2, 44, 13, 30, 17, 36, 12, 26, 5, 18, 28, 47, 13, 60, 23, 45, 13, 33 }, + { 55, 4, 62, 34, 52, 38, 7, 63, 32, 37, 13, 53, 25, 62, 18, 12, 55, 41, 27, 35, 24, 49, 31, 52, 17, 63, 34, 1, 56, 12, 41, 2, 48, 58, 39, 16, 61, 27, 41, 52, 13, 19, 50, 39, 11, 31, 57, 6, 32, 40, 20, 55, 1, 28, 33, 57, 48, 8, 37, 22, 44, 18, 53, 1, 61, 5, 54, 16, 47, 36, 50, 24, 55, 34, 48, 45, 1, 30, 33, 46, 2, 50, 32, 42, 25, 34, 43, 21, 38, 52, 23, 45, 14, 54, 21, 4, 44, 16, 53, 29, 10, 47, 19, 57, 12, 54, 39, 10, 51, 15, 63, 21, 57, 40, 51, 1, 48, 57, 37, 62, 2, 38, 9, 52, 1, 35, 58, 22 }, + { 36, 46, 10, 42, 1, 27, 43, 15, 50, 21, 45, 16, 41, 3, 35, 44, 20, 1, 57, 11, 55, 7, 43, 8, 22, 42, 13, 46, 21, 39, 31, 60, 22, 5, 29, 44, 11, 35, 20, 4, 36, 58, 32, 15, 47, 2, 36, 48, 16, 60, 8, 35, 44, 63, 16, 2, 40, 26, 55, 14, 58, 35, 24, 31, 19, 42, 31, 58, 1, 29, 10, 40, 2, 19, 12, 54, 22, 61, 7, 24, 56, 5, 28, 16, 54, 3, 15, 58, 6, 30, 8, 62, 1, 43, 31, 47, 7, 59, 1, 38, 58, 4, 34, 27, 38, 5, 31, 59, 7, 46, 30, 3, 34, 6, 28, 59, 20, 8, 32, 15, 53, 24, 55, 31, 19, 49, 11, 26 }, + { 2, 24, 16, 58, 19, 55, 5, 35, 10, 61, 4, 28, 57, 24, 58, 7, 31, 47, 22, 38, 19, 28, 61, 36, 54, 5, 59, 29, 6, 52, 15, 11, 43, 36, 8, 54, 52, 1, 62, 25, 47, 9, 1, 60, 28, 53, 24, 14, 46, 27, 51, 22, 12, 24, 38, 53, 20, 11, 51, 3, 29, 7, 48, 63, 8, 49, 9, 21, 52, 14, 63, 32, 46, 60, 35, 4, 41, 16, 52, 35, 18, 42, 59, 7, 36, 61, 45, 27, 33, 51, 19, 39, 34, 11, 61, 18, 33, 41, 28, 15, 54, 22, 42, 3, 49, 21, 47, 18, 36, 23, 55, 19, 48, 24, 45, 10, 33, 44, 50, 40, 7, 35, 15, 41, 63, 6, 40, 54 }, + { 62, 41, 32, 8, 47, 28, 60, 24, 44, 30, 38, 49, 9, 33, 14, 40, 50, 14, 60, 2, 54, 40, 0, 20, 25, 39, 16, 49, 24, 35, 57, 47, 19, 61, 33, 18, 23, 37, 13, 55, 31, 43, 22, 41, 17, 8, 42, 58, 0, 37, 5, 56, 31, 54, 7, 30, 60, 33, 42, 17, 59, 39, 12, 27, 38, 17, 35, 41, 27, 45, 20, 7, 25, 15, 29, 58, 27, 47, 11, 40, 14, 54, 23, 46, 19, 31, 11, 40, 13, 49, 5, 58, 24, 51, 26, 6, 50, 20, 49, 9, 32, 46, 17, 60, 14, 63, 24, 1, 57, 41, 9, 43, 14, 62, 16, 52, 3, 27, 14, 22, 61, 45, 4, 28, 9, 47, 29, 17 }, + { 5, 50, 12, 53, 38, 18, 11, 51, 0, 55, 17, 6, 47, 54, 19, 63, 5, 26, 34, 45, 13, 30, 47, 58, 10, 48, 32, 3, 62, 9, 26, 0, 25, 14, 50, 3, 47, 30, 42, 16, 6, 63, 12, 49, 33, 55, 21, 10, 34, 63, 18, 41, 3, 47, 19, 43, 0, 49, 8, 28, 46, 20, 52, 0, 56, 24, 60, 3, 59, 5, 39, 57, 48, 52, 9, 38, 3, 21, 26, 60, 0, 32, 12, 38, 4, 48, 53, 0, 60, 15, 29, 44, 18, 10, 38, 57, 13, 60, 2, 26, 62, 7, 50, 29, 35, 8, 40, 53, 28, 12, 60, 33, 38, 5, 37, 29, 60, 39, 56, 0, 30, 18, 50, 34, 59, 25, 14, 44 }, + { 20, 31, 60, 22, 3, 49, 33, 25, 40, 13, 34, 59, 22, 36, 0, 28, 37, 56, 8, 18, 51, 16, 4, 45, 27, 12, 53, 42, 18, 44, 51, 31, 55, 40, 28, 58, 7, 60, 10, 51, 27, 37, 24, 56, 5, 26, 44, 29, 50, 23, 45, 11, 34, 15, 59, 27, 13, 23, 62, 37, 4, 57, 15, 32, 42, 6, 47, 11, 30, 43, 23, 13, 0, 36, 18, 44, 63, 51, 37, 29, 49, 20, 57, 27, 62, 9, 24, 35, 23, 53, 37, 3, 42, 55, 0, 36, 23, 39, 31, 43, 17, 37, 24, 11, 52, 43, 19, 32, 5, 50, 26, 0, 56, 21, 54, 11, 19, 6, 47, 25, 59, 42, 12, 54, 21, 3, 38, 57 }, + { 48, 0, 35, 27, 44, 14, 59, 7, 57, 46, 26, 2, 42, 12, 52, 43, 10, 27, 53, 42, 32, 62, 37, 21, 34, 61, 7, 23, 36, 4, 38, 12, 41, 5, 17, 45, 22, 27, 39, 21, 59, 0, 45, 18, 39, 62, 3, 38, 14, 7, 54, 26, 61, 39, 9, 52, 45, 36, 18, 50, 10, 34, 44, 22, 50, 14, 36, 55, 17, 34, 53, 62, 33, 26, 56, 6, 31, 12, 6, 53, 9, 44, 2, 50, 20, 40, 55, 17, 47, 7, 26, 63, 22, 32, 48, 16, 46, 8, 52, 12, 57, 41, 0, 56, 25, 3, 61, 14, 45, 35, 18, 44, 12, 46, 23, 42, 32, 51, 35, 10, 17, 36, 23, 1, 45, 52, 32, 10 }, + { 37, 15, 43, 8, 63, 39, 21, 31, 16, 37, 19, 62, 30, 46, 17, 60, 21, 48, 1, 23, 6, 25, 11, 56, 1, 40, 30, 58, 15, 54, 21, 59, 9, 63, 35, 56, 11, 51, 2, 46, 34, 14, 53, 7, 30, 11, 51, 19, 60, 40, 30, 1, 24, 50, 20, 32, 3, 56, 5, 25, 31, 13, 61, 2, 29, 60, 25, 20, 51, 2, 27, 8, 18, 42, 10, 45, 21, 34, 43, 17, 62, 29, 41, 14, 34, 6, 30, 43, 2, 57, 33, 13, 45, 12, 27, 62, 4, 55, 21, 35, 5, 27, 45, 33, 16, 47, 30, 54, 22, 10, 51, 27, 63, 7, 49, 1, 58, 22, 15, 43, 53, 7, 57, 39, 27, 12, 61, 24 }, + { 56, 51, 26, 56, 19, 2, 41, 54, 5, 52, 9, 48, 6, 23, 39, 4, 32, 15, 63, 35, 59, 49, 43, 15, 52, 19, 50, 9, 46, 33, 1, 29, 48, 20, 32, 1, 38, 33, 19, 54, 9, 32, 24, 48, 58, 35, 16, 48, 4, 52, 13, 57, 33, 5, 45, 59, 15, 29, 41, 55, 47, 39, 23, 53, 9, 40, 4, 57, 10, 44, 48, 40, 50, 14, 61, 24, 55, 1, 59, 22, 33, 8, 51, 25, 58, 46, 11, 59, 20, 41, 17, 51, 6, 56, 35, 25, 42, 30, 15, 58, 48, 18, 61, 9, 58, 39, 13, 2, 37, 59, 40, 2, 31, 16, 34, 41, 8, 30, 62, 3, 29, 48, 33, 5, 63, 16, 41, 7 }, + { 22, 4, 46, 11, 33, 51, 29, 10, 62, 24, 43, 27, 15, 58, 50, 25, 54, 44, 9, 38, 18, 3, 29, 57, 32, 5, 26, 43, 17, 61, 24, 52, 8, 42, 23, 53, 15, 61, 7, 28, 57, 43, 4, 40, 20, 2, 43, 25, 32, 35, 21, 43, 17, 48, 10, 22, 38, 54, 11, 21, 1, 58, 16, 30, 48, 18, 46, 32, 38, 13, 22, 4, 59, 35, 2, 51, 30, 39, 15, 47, 4, 56, 13, 37, 1, 28, 16, 52, 32, 9, 61, 29, 38, 19, 3, 52, 10, 48, 1, 32, 11, 40, 20, 36, 6, 22, 49, 29, 55, 6, 20, 56, 36, 52, 19, 60, 26, 46, 18, 54, 40, 13, 20, 46, 35, 19, 49, 29 }, + { 61, 17, 34, 53, 23, 6, 48, 35, 20, 40, 1, 56, 36, 29, 11, 34, 7, 41, 14, 30, 55, 20, 46, 8, 24, 38, 63, 2, 37, 10, 45, 14, 34, 49, 6, 13, 44, 25, 49, 41, 21, 12, 61, 15, 54, 29, 63, 12, 56, 8, 49, 2, 62, 36, 28, 61, 0, 25, 41, 63, 35, 8, 44, 6, 37, 62, 7, 21, 63, 28, 55, 31, 16, 24, 41, 19, 9, 57, 27, 36, 18, 42, 31, 62, 22, 55, 38, 4, 27, 47, 1, 40, 14, 54, 43, 20, 60, 23, 38, 63, 25, 51, 2, 53, 26, 63, 10, 42, 17, 34, 47, 25, 13, 5, 44, 11, 55, 2, 38, 27, 6, 60, 52, 25, 9, 55, 1, 40 }, + { 8, 30, 58, 3, 42, 61, 17, 38, 13, 59, 32, 10, 54, 3, 51, 20, 61, 26, 57, 2, 46, 33, 12, 60, 41, 13, 48, 29, 55, 20, 39, 27, 57, 18, 62, 29, 55, 2, 31, 16, 37, 50, 26, 36, 6, 46, 9, 41, 27, 57, 23, 39, 26, 6, 51, 12, 31, 46, 7, 16, 27, 52, 19, 56, 26, 12, 33, 53, 1, 41, 8, 57, 46, 7, 54, 32, 47, 5, 49, 11, 60, 23, 5, 48, 10, 43, 19, 63, 35, 24, 49, 21, 59, 5, 31, 37, 14, 44, 7, 42, 6, 30, 46, 13, 44, 32, 19, 50, 4, 58, 8, 30, 62, 38, 28, 53, 21, 36, 13, 50, 21, 33, 15, 2, 44, 31, 14, 47 }, + { 37, 13, 39, 16, 28, 9, 57, 0, 25, 49, 21, 45, 18, 47, 12, 42, 0, 49, 22, 39, 16, 53, 25, 36, 0, 52, 22, 16, 6, 60, 4, 51, 0, 26, 37, 47, 10, 36, 63, 5, 57, 0, 18, 59, 23, 33, 51, 19, 0, 44, 15, 11, 54, 17, 42, 35, 53, 18, 58, 33, 49, 4, 34, 42, 0, 50, 43, 25, 16, 49, 34, 20, 37, 28, 12, 63, 16, 38, 25, 44, 0, 40, 52, 17, 35, 3, 50, 14, 8, 53, 11, 36, 25, 45, 9, 62, 0, 54, 28, 17, 50, 55, 15, 24, 57, 0, 53, 34, 23, 41, 15, 45, 0, 49, 16, 4, 48, 9, 63, 45, 0, 42, 58, 37, 61, 22, 54, 26 }, + { 0, 50, 21, 47, 54, 36, 27, 45, 52, 4, 34, 15, 63, 29, 37, 59, 17, 31, 6, 61, 28, 5, 48, 18, 59, 27, 34, 56, 44, 31, 35, 12, 41, 59, 16, 3, 40, 20, 50, 22, 30, 40, 52, 10, 45, 3, 59, 22, 37, 61, 29, 46, 31, 58, 2, 22, 9, 43, 3, 39, 14, 61, 24, 54, 15, 29, 11, 60, 39, 17, 5, 61, 0, 44, 50, 3, 31, 14, 58, 21, 54, 28, 15, 45, 60, 26, 33, 58, 44, 22, 60, 2, 57, 34, 49, 27, 18, 34, 21, 59, 29, 4, 36, 41, 8, 39, 28, 11, 62, 26, 53, 20, 35, 24, 59, 32, 29, 39, 24, 31, 57, 23, 11, 28, 5, 36, 11, 59 }, + { 44, 32, 63, 5, 20, 12, 41, 7, 30, 61, 42, 8, 39, 5, 33, 8, 24, 53, 45, 11, 37, 58, 7, 44, 10, 50, 3, 40, 8, 22, 53, 19, 46, 9, 33, 52, 24, 58, 8, 44, 13, 47, 8, 34, 38, 30, 14, 47, 7, 34, 4, 55, 9, 19, 40, 49, 56, 26, 60, 21, 30, 45, 10, 19, 40, 58, 23, 36, 3, 52, 45, 23, 54, 13, 22, 42, 53, 45, 7, 33, 10, 36, 57, 6, 29, 12, 41, 0, 30, 15, 41, 30, 17, 7, 16, 53, 40, 56, 2, 39, 12, 61, 10, 52, 31, 60, 16, 45, 1, 37, 7, 61, 40, 10, 43, 17, 58, 7, 54, 14, 4, 51, 39, 49, 18, 56, 42, 20 }, + { 14, 6, 24, 36, 56, 49, 22, 60, 18, 14, 23, 51, 26, 57, 21, 52, 41, 14, 35, 50, 19, 31, 40, 23, 33, 14, 63, 17, 32, 47, 7, 62, 23, 30, 56, 11, 42, 27, 14, 60, 35, 19, 28, 61, 17, 55, 25, 39, 53, 17, 42, 21, 38, 63, 25, 5, 14, 36, 12, 50, 1, 37, 59, 32, 2, 51, 6, 56, 27, 32, 11, 30, 38, 26, 60, 8, 26, 19, 62, 39, 50, 2, 21, 39, 53, 23, 56, 19, 49, 39, 5, 46, 55, 23, 42, 4, 31, 11, 47, 26, 45, 22, 48, 18, 21, 5, 48, 25, 57, 14, 47, 30, 3, 56, 12, 50, 1, 42, 19, 47, 35, 17, 8, 30, 45, 25, 4, 51 }, + { 28, 58, 43, 1, 31, 8, 33, 2, 44, 55, 32, 1, 60, 12, 46, 27, 4, 62, 23, 1, 56, 13, 62, 2, 54, 36, 25, 51, 1, 57, 26, 42, 3, 49, 17, 38, 1, 48, 31, 4, 54, 3, 50, 24, 1, 49, 5, 63, 13, 27, 52, 1, 48, 13, 45, 33, 52, 30, 46, 20, 55, 28, 6, 48, 24, 38, 20, 47, 14, 62, 48, 9, 58, 4, 36, 30, 56, 1, 34, 12, 18, 63, 25, 48, 4, 16, 37, 7, 62, 10, 52, 28, 13, 50, 36, 63, 24, 51, 15, 58, 8, 33, 1, 38, 56, 35, 42, 9, 33, 51, 22, 18, 48, 32, 27, 37, 23, 61, 33, 11, 59, 29, 62, 1, 53, 10, 60, 33 }, + { 12, 39, 17, 52, 26, 46, 53, 38, 25, 11, 48, 36, 16, 43, 2, 35, 55, 17, 39, 29, 43, 9, 28, 45, 20, 5, 46, 12, 42, 28, 13, 52, 36, 6, 60, 22, 54, 17, 62, 39, 25, 42, 15, 55, 44, 20, 31, 10, 35, 57, 24, 32, 29, 6, 59, 18, 7, 62, 3, 41, 10, 44, 16, 54, 13, 62, 31, 9, 41, 1, 21, 43, 18, 47, 15, 40, 11, 49, 28, 55, 46, 30, 8, 43, 32, 61, 28, 47, 25, 34, 21, 61, 32, 1, 20, 9, 46, 6, 35, 19, 41, 54, 27, 63, 14, 3, 51, 20, 62, 2, 38, 55, 8, 21, 63, 6, 46, 9, 26, 51, 3, 24, 43, 34, 16, 41, 18, 48 }, + { 62, 23, 55, 9, 15, 62, 19, 13, 58, 40, 6, 30, 54, 19, 50, 31, 10, 44, 6, 59, 21, 47, 51, 15, 60, 39, 30, 54, 21, 61, 19, 33, 14, 29, 43, 11, 34, 45, 7, 21, 10, 56, 36, 6, 38, 11, 58, 42, 2, 47, 11, 60, 50, 16, 41, 28, 38, 23, 47, 17, 35, 63, 22, 33, 42, 5, 45, 17, 53, 35, 25, 56, 33, 6, 51, 19, 60, 23, 43, 15, 5, 40, 58, 13, 51, 1, 45, 11, 54, 3, 43, 8, 37, 48, 59, 29, 39, 21, 61, 43, 3, 31, 10, 44, 24, 29, 60, 12, 28, 40, 11, 25, 43, 52, 14, 41, 16, 57, 44, 20, 40, 55, 12, 21, 57, 27, 35, 2 }, + { 37, 6, 31, 42, 40, 4, 29, 50, 0, 20, 63, 28, 9, 58, 14, 24, 63, 26, 48, 16, 34, 4, 32, 38, 23, 11, 58, 4, 37, 9, 45, 5, 63, 48, 26, 57, 2, 28, 32, 51, 46, 29, 13, 62, 27, 46, 28, 18, 50, 15, 40, 4, 19, 34, 54, 0, 53, 9, 26, 58, 28, 5, 49, 0, 57, 27, 19, 60, 29, 8, 59, 12, 37, 63, 24, 46, 3, 37, 6, 52, 26, 32, 20, 36, 9, 22, 59, 18, 35, 51, 14, 57, 17, 24, 12, 44, 56, 0, 30, 13, 59, 20, 49, 17, 54, 43, 6, 34, 46, 17, 58, 36, 0, 34, 29, 54, 25, 2, 36, 15, 60, 6, 37, 46, 4, 50, 9, 45 }, + { 19, 59, 48, 3, 24, 60, 44, 22, 34, 51, 15, 45, 41, 5, 33, 47, 0, 37, 12, 55, 25, 54, 8, 57, 0, 47, 18, 34, 49, 15, 55, 24, 40, 20, 8, 35, 53, 13, 41, 18, 0, 59, 22, 33, 4, 52, 8, 60, 24, 36, 31, 56, 45, 26, 10, 43, 15, 56, 36, 4, 51, 14, 39, 30, 12, 55, 36, 2, 39, 49, 4, 44, 17, 0, 32, 13, 53, 35, 59, 17, 62, 0, 55, 24, 52, 38, 31, 6, 42, 19, 29, 40, 4, 54, 33, 5, 16, 27, 52, 37, 23, 55, 7, 37, 0, 39, 23, 49, 4, 53, 31, 15, 59, 10, 50, 4, 60, 34, 48, 7, 31, 49, 27, 14, 62, 22, 53, 29 }, + { 46, 21, 14, 51, 36, 17, 7, 57, 10, 32, 3, 37, 22, 60, 39, 18, 56, 20, 42, 3, 36, 10, 44, 26, 41, 29, 53, 27, 2, 39, 30, 52, 0, 59, 15, 48, 23, 61, 6, 58, 37, 12, 40, 49, 16, 39, 20, 44, 0, 62, 8, 21, 3, 59, 23, 32, 49, 31, 12, 44, 22, 59, 18, 50, 24, 7, 43, 52, 15, 23, 41, 26, 51, 28, 55, 39, 21, 27, 10, 42, 12, 45, 27, 47, 3, 15, 63, 26, 55, 0, 60, 26, 45, 18, 62, 38, 58, 49, 8, 47, 4, 33, 46, 29, 57, 13, 56, 16, 59, 21, 5, 47, 23, 39, 18, 44, 13, 22, 28, 53, 19, 0, 58, 32, 41, 7, 26, 13 }, + { 0, 56, 34, 28, 11, 55, 31, 47, 26, 41, 56, 13, 53, 28, 11, 49, 7, 52, 32, 61, 50, 22, 63, 17, 13, 56, 7, 19, 43, 62, 10, 21, 37, 32, 43, 4, 38, 19, 44, 25, 31, 54, 5, 23, 61, 30, 53, 12, 35, 22, 43, 53, 37, 48, 7, 62, 20, 2, 61, 41, 8, 34, 47, 9, 63, 34, 28, 10, 55, 33, 14, 57, 7, 47, 9, 61, 4, 49, 31, 50, 21, 38, 8, 16, 57, 44, 33, 5, 49, 36, 12, 50, 7, 34, 10, 25, 2, 22, 36, 15, 26, 61, 18, 9, 22, 46, 32, 8, 27, 37, 44, 30, 55, 3, 62, 24, 38, 56, 5, 45, 38, 24, 43, 10, 19, 54, 39, 61 }, + { 41, 30, 8, 63, 43, 23, 38, 3, 62, 19, 8, 49, 25, 1, 58, 30, 23, 40, 9, 28, 18, 40, 6, 38, 49, 22, 35, 59, 8, 27, 50, 5, 56, 17, 11, 50, 30, 9, 55, 2, 51, 19, 34, 47, 9, 41, 6, 26, 48, 57, 14, 28, 17, 12, 39, 13, 37, 46, 25, 19, 54, 27, 1, 37, 16, 45, 20, 60, 1, 48, 20, 38, 31, 22, 42, 15, 19, 44, 1, 61, 6, 34, 56, 40, 29, 10, 20, 46, 13, 22, 41, 23, 59, 42, 30, 51, 45, 13, 63, 53, 42, 12, 51, 38, 62, 2, 26, 41, 50, 1, 61, 10, 19, 42, 31, 8, 49, 32, 12, 63, 9, 52, 16, 56, 36, 2, 31, 16 }, + { 52, 5, 47, 20, 1, 53, 12, 50, 16, 35, 43, 21, 33, 43, 16, 44, 3, 59, 14, 46, 1, 30, 60, 33, 2, 45, 12, 42, 31, 47, 14, 33, 46, 25, 55, 27, 60, 36, 16, 42, 14, 46, 26, 1, 55, 15, 63, 32, 2, 38, 5, 47, 33, 61, 30, 52, 4, 57, 6, 38, 11, 43, 61, 24, 52, 3, 31, 22, 42, 10, 62, 3, 59, 11, 35, 57, 33, 54, 24, 14, 29, 48, 18, 2, 60, 41, 53, 24, 32, 62, 3, 53, 15, 1, 55, 17, 32, 40, 6, 31, 1, 40, 28, 5, 35, 52, 19, 63, 13, 33, 17, 41, 52, 26, 15, 57, 1, 20, 42, 17, 35, 27, 48, 5, 25, 50, 44, 11 }, + { 35, 25, 38, 57, 33, 17, 40, 6, 59, 27, 54, 5, 61, 10, 52, 26, 36, 19, 51, 35, 57, 48, 11, 20, 54, 25, 61, 16, 1, 58, 24, 61, 3, 39, 7, 47, 1, 22, 49, 28, 63, 10, 58, 32, 17, 36, 45, 19, 51, 29, 59, 10, 50, 1, 23, 42, 18, 29, 51, 21, 56, 32, 14, 5, 40, 58, 47, 13, 54, 35, 29, 45, 18, 52, 26, 2, 38, 8, 46, 36, 58, 11, 52, 35, 17, 28, 1, 58, 9, 39, 17, 28, 37, 48, 20, 9, 57, 24, 50, 19, 58, 16, 48, 25, 43, 11, 35, 6, 45, 24, 56, 4, 36, 7, 47, 35, 52, 28, 59, 30, 2, 61, 21, 33, 63, 12, 18, 59 }, + { 3, 49, 15, 10, 27, 61, 25, 45, 30, 0, 14, 47, 31, 38, 17, 62, 7, 55, 27, 4, 15, 24, 42, 52, 10, 34, 5, 51, 36, 18, 41, 11, 35, 21, 62, 13, 33, 57, 8, 35, 5, 40, 21, 43, 52, 3, 24, 56, 11, 16, 33, 25, 41, 20, 55, 8, 60, 35, 15, 48, 2, 57, 30, 49, 18, 25, 6, 39, 17, 57, 7, 25, 43, 5, 49, 16, 62, 22, 55, 4, 25, 43, 23, 7, 50, 11, 37, 48, 14, 51, 33, 57, 7, 27, 39, 46, 4, 29, 11, 43, 34, 56, 7, 60, 20, 54, 30, 57, 22, 49, 9, 33, 54, 14, 63, 23, 6, 43, 10, 40, 50, 13, 44, 8, 38, 33, 46, 23 }, + { 55, 39, 22, 50, 44, 4, 36, 9, 52, 23, 37, 59, 21, 2, 46, 13, 31, 41, 11, 45, 62, 29, 6, 37, 19, 48, 30, 23, 44, 7, 53, 28, 54, 16, 41, 29, 44, 18, 52, 24, 60, 15, 48, 7, 27, 59, 9, 34, 42, 54, 7, 63, 4, 46, 31, 27, 45, 0, 40, 26, 34, 17, 37, 10, 53, 29, 36, 50, 2, 27, 51, 11, 61, 37, 23, 41, 30, 7, 18, 50, 39, 14, 63, 32, 45, 61, 19, 30, 25, 44, 2, 47, 23, 63, 11, 34, 59, 37, 60, 3, 22, 14, 44, 30, 15, 0, 47, 15, 3, 38, 61, 20, 27, 45, 11, 39, 51, 16, 55, 3, 22, 54, 29, 58, 1, 57, 6, 29 }, + { 9, 17, 60, 2, 34, 56, 20, 62, 39, 12, 49, 6, 29, 56, 34, 48, 0, 58, 22, 38, 18, 43, 56, 0, 63, 14, 55, 3, 59, 31, 15, 45, 0, 49, 6, 58, 3, 38, 12, 45, 0, 37, 29, 57, 13, 39, 30, 49, 0, 23, 44, 36, 16, 57, 13, 54, 11, 24, 63, 9, 53, 7, 62, 42, 0, 59, 15, 23, 63, 34, 40, 16, 32, 0, 53, 12, 48, 28, 59, 33, 0, 53, 9, 27, 3, 22, 54, 5, 56, 9, 61, 13, 42, 14, 52, 19, 0, 21, 47, 27, 53, 36, 3, 50, 39, 58, 25, 40, 53, 28, 12, 50, 0, 59, 32, 2, 21, 34, 26, 46, 37, 7, 18, 47, 24, 14, 53, 42 }, + { 61, 32, 13, 54, 29, 7, 46, 13, 28, 57, 18, 41, 53, 15, 9, 39, 24, 49, 33, 3, 53, 9, 26, 32, 40, 28, 46, 39, 25, 9, 56, 21, 63, 37, 26, 22, 51, 27, 17, 56, 31, 53, 4, 43, 22, 46, 12, 18, 60, 40, 20, 26, 50, 21, 39, 5, 49, 33, 16, 44, 22, 46, 20, 32, 24, 45, 8, 43, 12, 46, 4, 48, 56, 20, 29, 58, 3, 40, 10, 42, 31, 21, 47, 41, 56, 38, 15, 42, 36, 27, 20, 33, 55, 3, 26, 44, 31, 54, 12, 35, 9, 63, 28, 10, 21, 32, 9, 60, 17, 8, 43, 29, 40, 16, 36, 48, 60, 7, 57, 14, 62, 31, 42, 15, 36, 40, 20, 26 }, + { 0, 37, 47, 23, 41, 18, 32, 48, 1, 35, 8, 25, 4, 26, 63, 20, 54, 8, 16, 61, 35, 23, 51, 15, 58, 7, 12, 20, 50, 34, 42, 4, 38, 10, 32, 47, 8, 60, 41, 20, 9, 25, 50, 19, 62, 1, 37, 56, 28, 8, 53, 11, 3, 58, 34, 43, 19, 60, 38, 4, 58, 31, 3, 51, 11, 55, 38, 30, 21, 58, 19, 26, 9, 44, 36, 13, 46, 20, 62, 24, 13, 60, 5, 28, 12, 34, 7, 59, 0, 53, 45, 6, 38, 30, 50, 7, 62, 16, 41, 5, 46, 18, 55, 42, 51, 5, 45, 23, 34, 48, 19, 58, 5, 25, 54, 19, 13, 41, 28, 21, 0, 49, 10, 60, 4, 51, 9, 45 }, + { 19, 28, 6, 58, 10, 51, 4, 22, 55, 42, 60, 45, 34, 51, 42, 5, 30, 45, 27, 40, 13, 47, 4, 49, 21, 38, 60, 29, 2, 57, 17, 27, 52, 19, 61, 14, 30, 34, 2, 44, 63, 33, 11, 35, 16, 51, 25, 6, 14, 47, 31, 61, 37, 29, 18, 8, 52, 2, 28, 54, 13, 41, 15, 62, 35, 18, 2, 60, 6, 33, 41, 61, 31, 6, 56, 17, 34, 50, 6, 52, 44, 35, 16, 51, 59, 24, 48, 18, 31, 40, 16, 49, 21, 60, 17, 39, 10, 49, 32, 57, 24, 39, 1, 25, 18, 62, 37, 12, 56, 1, 37, 11, 52, 44, 9, 30, 47, 4, 51, 40, 55, 25, 34, 27, 56, 30, 32, 54 }, + { 63, 40, 49, 15, 43, 26, 63, 38, 16, 20, 30, 12, 57, 14, 19, 60, 36, 12, 59, 2, 57, 17, 42, 31, 1, 44, 16, 35, 47, 11, 32, 48, 13, 43, 1, 39, 51, 12, 57, 23, 6, 40, 53, 3, 55, 31, 39, 60, 35, 44, 5, 15, 45, 1, 62, 41, 26, 14, 47, 22, 36, 27, 50, 9, 26, 47, 52, 28, 54, 16, 1, 13, 51, 39, 23, 63, 1, 30, 15, 26, 2, 57, 19, 37, 1, 44, 21, 50, 13, 63, 8, 24, 56, 1, 35, 25, 58, 20, 2, 28, 14, 51, 33, 59, 13, 30, 4, 49, 31, 24, 63, 26, 33, 3, 58, 38, 62, 24, 32, 8, 17, 45, 5, 48, 18, 3, 43, 11 }, + { 21, 4, 24, 34, 59, 1, 37, 11, 53, 5, 47, 2, 22, 40, 32, 1, 24, 50, 21, 29, 38, 25, 63, 8, 55, 24, 53, 6, 62, 23, 59, 3, 54, 20, 58, 24, 5, 46, 15, 38, 48, 14, 27, 42, 23, 7, 46, 10, 17, 58, 25, 52, 23, 32, 49, 12, 55, 30, 40, 7, 59, 1, 56, 21, 39, 4, 23, 15, 37, 46, 55, 42, 21, 4, 48, 8, 45, 54, 37, 55, 32, 8, 46, 10, 30, 54, 4, 41, 25, 29, 36, 48, 11, 43, 14, 47, 5, 43, 53, 36, 61, 10, 45, 6, 41, 54, 27, 43, 16, 55, 6, 46, 18, 42, 23, 15, 1, 45, 12, 60, 37, 22, 62, 12, 39, 59, 16, 52 }, + { 47, 35, 56, 7, 19, 46, 31, 50, 33, 24, 61, 35, 50, 7, 53, 44, 55, 6, 46, 10, 52, 5, 21, 43, 36, 10, 18, 41, 26, 37, 8, 29, 40, 36, 9, 49, 34, 26, 61, 21, 7, 59, 18, 62, 29, 54, 20, 32, 51, 0, 40, 10, 55, 6, 20, 36, 9, 61, 5, 51, 44, 19, 33, 43, 13, 57, 40, 63, 8, 24, 29, 10, 60, 34, 27, 40, 25, 18, 10, 42, 21, 49, 26, 62, 38, 12, 33, 61, 5, 57, 2, 19, 54, 28, 62, 22, 38, 31, 16, 7, 22, 47, 29, 17, 35, 8, 20, 51, 2, 40, 22, 50, 13, 61, 28, 53, 35, 20, 56, 30, 2, 53, 14, 41, 23, 34, 8, 31 }, + { 12, 2, 42, 29, 52, 13, 21, 8, 55, 14, 41, 17, 28, 58, 23, 11, 17, 36, 31, 62, 17, 34, 50, 14, 28, 61, 33, 52, 2, 51, 17, 45, 7, 25, 62, 30, 18, 55, 0, 42, 30, 35, 45, 1, 12, 48, 3, 63, 21, 36, 30, 48, 19, 59, 43, 27, 46, 17, 34, 25, 12, 29, 53, 6, 48, 31, 11, 34, 49, 3, 36, 50, 19, 47, 14, 61, 11, 36, 58, 4, 60, 14, 39, 22, 6, 52, 15, 35, 17, 46, 31, 42, 9, 34, 3, 52, 12, 60, 26, 56, 40, 2, 53, 23, 57, 38, 62, 14, 36, 59, 10, 31, 39, 6, 49, 9, 41, 26, 5, 48, 43, 27, 33, 58, 1, 50, 25, 57 }, + { 61, 37, 15, 61, 3, 39, 58, 43, 26, 0, 44, 10, 47, 3, 37, 63, 28, 43, 13, 39, 3, 57, 30, 59, 0, 48, 5, 43, 13, 22, 60, 33, 55, 15, 42, 4, 52, 10, 45, 13, 54, 4, 24, 49, 37, 26, 41, 14, 42, 9, 61, 13, 38, 23, 3, 53, 0, 58, 21, 42, 63, 10, 17, 61, 25, 0, 58, 28, 17, 44, 57, 12, 27, 0, 55, 5, 52, 28, 23, 47, 29, 0, 43, 17, 58, 28, 47, 23, 55, 10, 58, 23, 51, 40, 18, 33, 45, 0, 49, 8, 32, 61, 19, 48, 0, 26, 7, 47, 29, 18, 44, 0, 56, 34, 20, 59, 15, 51, 37, 18, 10, 52, 7, 20, 46, 9, 38, 17 }, + { 6, 27, 48, 23, 45, 29, 5, 18, 38, 62, 27, 56, 20, 32, 15, 9, 48, 0, 54, 22, 45, 20, 7, 41, 23, 39, 19, 27, 58, 31, 44, 0, 12, 50, 23, 56, 20, 39, 32, 59, 16, 52, 33, 9, 57, 22, 6, 58, 28, 50, 24, 2, 56, 35, 16, 45, 32, 38, 15, 54, 2, 38, 46, 22, 35, 45, 20, 5, 52, 25, 7, 35, 59, 32, 22, 43, 38, 3, 51, 16, 34, 53, 32, 50, 3, 40, 8, 43, 0, 39, 27, 4, 14, 61, 8, 55, 15, 41, 20, 44, 27, 13, 39, 11, 46, 42, 54, 33, 4, 52, 23, 61, 14, 25, 43, 2, 33, 11, 63, 29, 61, 17, 40, 55, 22, 62, 28, 44 }, + { 20, 54, 8, 56, 35, 10, 63, 31, 52, 12, 48, 6, 59, 41, 52, 33, 19, 58, 25, 49, 11, 37, 47, 12, 54, 15, 56, 35, 7, 47, 16, 53, 28, 34, 5, 37, 28, 8, 48, 3, 28, 38, 18, 61, 16, 43, 53, 32, 4, 17, 47, 27, 44, 8, 63, 10, 25, 49, 6, 37, 24, 52, 32, 3, 50, 12, 41, 56, 38, 14, 62, 20, 40, 16, 53, 31, 18, 63, 41, 9, 59, 7, 13, 25, 57, 20, 63, 26, 53, 18, 48, 62, 30, 46, 21, 25, 58, 29, 36, 4, 55, 34, 6, 60, 31, 16, 21, 12, 58, 38, 9, 29, 47, 7, 52, 30, 57, 44, 22, 0, 35, 45, 3, 31, 14, 36, 0, 51 }, + { 42, 14, 33, 24, 16, 49, 40, 2, 22, 33, 16, 36, 25, 1, 21, 61, 38, 8, 33, 4, 62, 26, 29, 60, 6, 46, 30, 11, 63, 4, 36, 40, 19, 57, 46, 11, 41, 63, 22, 25, 58, 10, 46, 2, 34, 27, 11, 38, 56, 34, 12, 53, 18, 33, 41, 51, 13, 28, 60, 20, 47, 14, 29, 59, 16, 62, 8, 22, 32, 47, 9, 49, 2, 44, 7, 12, 45, 6, 20, 27, 45, 24, 62, 42, 36, 11, 33, 15, 37, 7, 32, 10, 37, 1, 35, 50, 6, 11, 63, 24, 52, 15, 50, 24, 3, 37, 56, 27, 34, 22, 49, 16, 36, 62, 17, 39, 4, 15, 54, 24, 50, 8, 58, 26, 49, 54, 11, 30 }, + { 4, 59, 41, 1, 53, 12, 25, 45, 59, 7, 51, 39, 54, 14, 46, 4, 27, 53, 16, 44, 18, 51, 1, 32, 25, 2, 50, 40, 20, 54, 24, 9, 62, 2, 27, 60, 1, 17, 36, 50, 6, 40, 30, 55, 41, 19, 49, 1, 21, 60, 40, 5, 62, 1, 22, 30, 57, 4, 43, 31, 1, 55, 40, 7, 27, 37, 30, 54, 1, 19, 42, 30, 56, 26, 62, 49, 24, 57, 37, 56, 2, 39, 16, 5, 30, 55, 3, 49, 60, 23, 56, 44, 17, 52, 13, 42, 28, 48, 18, 45, 9, 37, 21, 41, 58, 10, 48, 1, 63, 5, 41, 57, 2, 24, 12, 48, 27, 42, 32, 46, 13, 38, 19, 34, 5, 41, 25, 60 }, + { 39, 28, 21, 46, 32, 57, 36, 9, 19, 42, 4, 29, 11, 43, 30, 49, 13, 42, 35, 56, 9, 39, 15, 52, 36, 61, 18, 26, 45, 14, 31, 48, 21, 43, 14, 33, 49, 54, 14, 44, 21, 62, 13, 23, 8, 62, 15, 51, 44, 7, 30, 37, 20, 42, 56, 7, 39, 18, 50, 11, 61, 9, 19, 43, 57, 2, 48, 11, 39, 60, 28, 4, 37, 17, 35, 1, 33, 11, 31, 14, 48, 19, 35, 51, 46, 21, 44, 29, 12, 41, 2, 22, 58, 26, 54, 4, 59, 38, 2, 33, 57, 1, 63, 13, 28, 51, 15, 40, 18, 45, 8, 30, 43, 37, 54, 19, 8, 59, 21, 6, 60, 29, 55, 10, 63, 15, 47, 17 }, + { 3, 50, 10, 62, 18, 5, 27, 49, 60, 23, 55, 18, 62, 24, 56, 10, 59, 28, 2, 23, 34, 59, 43, 20, 10, 42, 8, 49, 1, 37, 57, 6, 51, 29, 53, 7, 23, 31, 5, 32, 51, 0, 35, 54, 45, 31, 5, 26, 36, 24, 55, 15, 48, 29, 14, 48, 26, 60, 21, 41, 36, 26, 50, 33, 14, 44, 17, 24, 52, 15, 46, 23, 54, 6, 47, 21, 60, 50, 4, 53, 29, 61, 8, 23, 1, 60, 19, 6, 53, 16, 47, 34, 6, 39, 16, 31, 12, 20, 53, 22, 30, 43, 25, 46, 35, 6, 44, 32, 53, 26, 55, 19, 11, 59, 5, 33, 51, 1, 35, 53, 25, 3, 42, 23, 44, 32, 7, 53 }, + { 22, 44, 37, 6, 26, 51, 38, 0, 34, 13, 31, 46, 3, 37, 6, 19, 40, 21, 47, 63, 12, 5, 29, 55, 22, 58, 34, 28, 60, 22, 11, 41, 17, 38, 9, 44, 59, 39, 56, 19, 11, 47, 25, 15, 3, 39, 57, 17, 61, 11, 46, 3, 58, 9, 54, 35, 2, 34, 8, 45, 15, 56, 5, 23, 53, 33, 63, 35, 4, 59, 10, 51, 13, 61, 29, 41, 15, 25, 43, 19, 40, 10, 54, 33, 41, 12, 38, 51, 31, 26, 61, 9, 30, 45, 24, 62, 49, 40, 10, 61, 14, 49, 5, 17, 54, 20, 60, 23, 3, 13, 35, 50, 32, 23, 46, 27, 38, 63, 16, 12, 39, 48, 18, 51, 1, 27, 56, 35 }, + { 63, 15, 30, 55, 43, 14, 57, 17, 53, 44, 7, 48, 26, 50, 32, 60, 0, 53, 14, 31, 50, 24, 46, 0, 38, 13, 4, 52, 16, 45, 30, 59, 0, 25, 55, 35, 16, 10, 26, 42, 58, 29, 60, 38, 50, 22, 28, 47, 0, 50, 28, 19, 33, 39, 11, 44, 16, 52, 24, 59, 3, 38, 27, 51, 0, 21, 7, 42, 26, 34, 21, 40, 33, 18, 39, 3, 54, 38, 8, 59, 0, 44, 27, 15, 58, 28, 57, 9, 43, 0, 36, 50, 20, 59, 8, 34, 0, 27, 47, 7, 36, 19, 56, 32, 0, 38, 11, 29, 62, 47, 6, 61, 0, 41, 14, 56, 10, 23, 45, 31, 57, 8, 36, 13, 58, 38, 11, 19 }, + { 0, 34, 12, 47, 21, 2, 40, 30, 11, 25, 61, 20, 40, 15, 35, 22, 45, 36, 7, 41, 17, 57, 9, 48, 32, 62, 44, 24, 35, 3, 54, 13, 33, 63, 19, 4, 48, 22, 62, 2, 37, 8, 33, 6, 20, 52, 9, 32, 43, 13, 39, 63, 25, 4, 49, 23, 62, 32, 9, 30, 48, 18, 63, 12, 46, 29, 58, 13, 48, 8, 57, 31, 0, 51, 9, 58, 12, 22, 47, 29, 35, 22, 49, 5, 46, 4, 34, 20, 63, 24, 56, 11, 41, 3, 51, 19, 56, 35, 17, 58, 28, 42, 9, 45, 59, 26, 51, 42, 17, 36, 25, 15, 53, 21, 44, 3, 30, 55, 5, 50, 21, 28, 61, 32, 6, 49, 28, 46 }, + { 58, 42, 60, 4, 31, 59, 22, 63, 35, 38, 9, 54, 1, 57, 8, 51, 16, 58, 27, 53, 3, 38, 30, 15, 27, 6, 19, 56, 10, 50, 21, 36, 47, 5, 43, 28, 51, 32, 13, 46, 18, 54, 16, 43, 63, 12, 36, 59, 22, 34, 5, 52, 17, 59, 27, 41, 0, 19, 55, 37, 13, 43, 6, 34, 41, 10, 36, 55, 19, 44, 3, 16, 58, 27, 49, 25, 32, 62, 17, 55, 13, 63, 18, 52, 25, 37, 17, 48, 13, 32, 5, 46, 28, 37, 14, 43, 25, 5, 51, 39, 3, 52, 33, 22, 8, 40, 12, 4, 57, 9, 46, 39, 28, 58, 13, 62, 17, 42, 19, 36, 0, 47, 16, 43, 24, 21, 54, 13 }, + { 25, 9, 23, 50, 36, 8, 45, 14, 3, 51, 16, 28, 44, 12, 42, 29, 4, 26, 10, 47, 22, 61, 18, 54, 51, 39, 46, 13, 41, 26, 58, 7, 18, 39, 12, 57, 15, 1, 52, 27, 41, 23, 48, 1, 27, 45, 18, 2, 57, 26, 55, 8, 43, 31, 6, 58, 14, 51, 40, 5, 61, 31, 24, 54, 17, 60, 22, 1, 39, 30, 53, 45, 36, 13, 43, 5, 45, 2, 37, 6, 34, 42, 2, 39, 10, 62, 7, 54, 40, 18, 60, 15, 52, 21, 63, 8, 55, 46, 15, 30, 23, 13, 62, 16, 50, 24, 58, 31, 48, 21, 34, 2, 49, 7, 31, 37, 26, 48, 9, 61, 40, 11, 52, 2, 60, 40, 4, 37 }, + { 52, 28, 39, 16, 54, 19, 29, 55, 42, 20, 58, 33, 24, 63, 18, 55, 39, 62, 43, 34, 12, 40, 6, 35, 2, 25, 8, 62, 34, 1, 31, 42, 61, 27, 53, 24, 40, 61, 34, 8, 59, 4, 30, 56, 40, 6, 53, 42, 10, 48, 16, 37, 12, 46, 21, 36, 47, 11, 28, 45, 22, 10, 57, 2, 49, 31, 14, 44, 61, 11, 25, 6, 23, 63, 18, 36, 28, 56, 20, 51, 11, 48, 27, 56, 32, 22, 45, 30, 2, 42, 27, 39, 1, 44, 23, 31, 38, 22, 11, 61, 43, 54, 4, 47, 35, 2, 44, 16, 28, 54, 12, 62, 18, 43, 10, 52, 1, 58, 33, 15, 29, 56, 20, 34, 9, 30, 48, 17 }, + { 46, 2, 56, 11, 41, 1, 49, 6, 27, 47, 2, 48, 5, 32, 37, 3, 13, 19, 32, 1, 55, 28, 60, 17, 43, 59, 32, 20, 49, 16, 55, 23, 14, 46, 2, 36, 6, 30, 20, 49, 12, 47, 35, 14, 21, 60, 29, 14, 35, 24, 46, 1, 56, 29, 53, 8, 33, 23, 56, 1, 35, 46, 20, 39, 26, 4, 53, 28, 17, 38, 60, 34, 48, 9, 55, 15, 46, 7, 41, 31, 60, 24, 16, 36, 1, 59, 19, 52, 35, 6, 55, 11, 59, 33, 7, 57, 4, 29, 48, 1, 19, 26, 37, 30, 18, 63, 37, 6, 59, 1, 40, 24, 56, 33, 46, 22, 35, 7, 24, 53, 39, 5, 26, 45, 55, 18, 62, 7 }, + { 20, 60, 29, 34, 20, 62, 33, 52, 10, 36, 13, 60, 41, 21, 50, 27, 56, 49, 8, 51, 21, 45, 11, 48, 8, 23, 53, 3, 29, 44, 5, 52, 9, 32, 50, 17, 43, 56, 3, 38, 24, 10, 62, 25, 51, 9, 33, 49, 61, 7, 30, 62, 22, 19, 2, 42, 63, 5, 49, 18, 60, 15, 52, 7, 43, 56, 23, 50, 5, 50, 2, 20, 41, 30, 1, 52, 22, 61, 14, 26, 3, 43, 53, 7, 47, 28, 11, 14, 23, 58, 33, 25, 47, 13, 50, 17, 40, 54, 34, 60, 41, 6, 59, 14, 50, 7, 25, 55, 20, 42, 51, 8, 27, 4, 16, 60, 28, 50, 44, 3, 22, 49, 63, 12, 33, 1, 43, 31 }, + { 36, 5, 46, 8, 44, 24, 13, 39, 25, 57, 31, 18, 8, 52, 10, 45, 6, 30, 36, 24, 63, 4, 33, 26, 57, 40, 15, 56, 37, 12, 40, 25, 37, 58, 11, 63, 21, 45, 16, 60, 31, 53, 18, 33, 3, 45, 23, 0, 20, 54, 40, 15, 50, 38, 60, 16, 25, 42, 29, 38, 7, 41, 25, 62, 18, 33, 8, 35, 42, 16, 32, 56, 12, 39, 59, 19, 34, 9, 49, 38, 57, 12, 21, 50, 14, 40, 61, 44, 50, 9, 49, 19, 3, 29, 35, 62, 12, 24, 7, 18, 52, 32, 10, 46, 21, 41, 32, 11, 36, 29, 14, 34, 60, 38, 54, 11, 41, 14, 19, 57, 32, 16, 7, 41, 51, 25, 14, 57 }, + { 53, 18, 26, 50, 15, 58, 4, 63, 17, 43, 7, 40, 61, 35, 15, 41, 23, 60, 16, 38, 14, 42, 19, 50, 0, 31, 10, 46, 27, 63, 18, 60, 0, 20, 29, 39, 8, 26, 37, 5, 42, 0, 44, 39, 57, 17, 58, 41, 28, 37, 4, 32, 9, 44, 12, 31, 54, 10, 59, 14, 27, 53, 12, 36, 0, 47, 13, 63, 21, 58, 10, 24, 50, 27, 4, 26, 44, 53, 31, 0, 18, 42, 29, 33, 57, 4, 32, 26, 0, 38, 16, 61, 41, 53, 20, 0, 42, 44, 49, 27, 10, 56, 39, 0, 57, 15, 53, 49, 3, 61, 22, 47, 17, 5, 49, 26, 2, 63, 39, 10, 47, 27, 37, 23, 4, 59, 38, 10 }, + { 23, 39, 61, 3, 37, 28, 48, 31, 0, 34, 51, 23, 2, 26, 58, 0, 53, 11, 46, 1, 57, 29, 52, 14, 37, 61, 21, 35, 2, 49, 7, 34, 47, 55, 4, 33, 54, 13, 58, 52, 19, 50, 22, 7, 13, 29, 36, 11, 51, 17, 60, 25, 55, 4, 34, 51, 0, 35, 20, 48, 32, 3, 51, 30, 59, 28, 40, 3, 46, 29, 54, 43, 7, 62, 47, 11, 39, 4, 23, 46, 55, 8, 63, 5, 25, 37, 18, 46, 21, 56, 31, 5, 36, 8, 45, 58, 26, 15, 2, 36, 47, 21, 29, 44, 25, 34, 3, 27, 43, 10, 52, 0, 45, 30, 24, 36, 43, 18, 34, 59, 0, 52, 61, 15, 44, 19, 30, 49 }, + { 0, 27, 12, 43, 54, 9, 22, 53, 21, 46, 15, 55, 29, 47, 20, 33, 39, 28, 59, 35, 9, 44, 5, 24, 47, 7, 52, 17, 56, 22, 30, 42, 14, 26, 45, 18, 49, 1, 24, 34, 11, 27, 55, 32, 61, 47, 2, 56, 6, 44, 13, 47, 36, 27, 58, 22, 16, 47, 40, 4, 57, 38, 21, 45, 16, 9, 56, 26, 11, 38, 0, 22, 36, 17, 33, 57, 16, 30, 62, 15, 35, 40, 20, 45, 59, 10, 54, 8, 63, 13, 52, 27, 22, 57, 28, 12, 32, 51, 55, 22, 63, 4, 16, 54, 12, 62, 45, 19, 58, 13, 32, 40, 20, 56, 7, 57, 9, 54, 6, 29, 42, 21, 8, 55, 35, 47, 6, 41 }, + { 56, 33, 58, 32, 19, 35, 42, 6, 59, 11, 38, 5, 49, 12, 62, 7, 52, 17, 5, 25, 54, 20, 61, 31, 54, 27, 41, 11, 44, 5, 59, 12, 36, 51, 10, 61, 28, 41, 48, 9, 43, 63, 5, 40, 20, 8, 49, 26, 34, 21, 58, 1, 18, 45, 7, 39, 61, 26, 8, 50, 23, 10, 63, 5, 55, 37, 19, 49, 52, 15, 59, 47, 13, 54, 1, 25, 42, 58, 10, 48, 3, 27, 50, 1, 17, 48, 34, 41, 16, 40, 2, 45, 10, 39, 17, 61, 5, 38, 19, 9, 41, 31, 60, 38, 5, 23, 36, 8, 30, 55, 24, 63, 12, 48, 14, 51, 31, 20, 45, 25, 12, 50, 32, 2, 28, 11, 62, 14 }, + { 44, 16, 7, 48, 1, 62, 16, 50, 27, 33, 61, 25, 17, 44, 31, 14, 22, 43, 32, 48, 18, 40, 8, 36, 3, 16, 33, 62, 23, 38, 25, 53, 2, 21, 41, 6, 22, 15, 59, 29, 16, 37, 26, 15, 52, 42, 23, 15, 54, 39, 10, 30, 53, 11, 49, 24, 2, 43, 55, 17, 34, 44, 15, 31, 24, 44, 2, 32, 7, 35, 25, 5, 40, 45, 29, 51, 6, 21, 37, 52, 24, 60, 13, 31, 53, 23, 2, 28, 49, 24, 31, 60, 20, 51, 1, 34, 48, 14, 59, 33, 50, 1, 18, 33, 48, 60, 17, 51, 39, 6, 38, 2, 35, 29, 40, 23, 1, 62, 15, 53, 37, 17, 46, 57, 40, 51, 24, 22 }, + { 5, 37, 52, 24, 45, 13, 40, 3, 45, 9, 19, 42, 56, 4, 37, 46, 56, 2, 63, 11, 51, 1, 49, 13, 59, 45, 39, 1, 48, 15, 58, 9, 46, 31, 54, 35, 57, 38, 3, 46, 56, 4, 47, 57, 1, 30, 38, 63, 3, 46, 28, 63, 41, 14, 33, 62, 19, 32, 13, 28, 61, 1, 53, 42, 11, 60, 22, 62, 27, 42, 61, 31, 19, 8, 61, 12, 32, 55, 2, 18, 33, 12, 43, 36, 9, 62, 30, 55, 6, 58, 35, 7, 43, 29, 54, 23, 43, 30, 3, 25, 11, 45, 52, 28, 7, 14, 42, 1, 22, 50, 16, 53, 19, 59, 4, 46, 33, 41, 4, 35, 58, 5, 26, 13, 20, 2, 34, 54 }, + { 30, 63, 21, 10, 26, 55, 29, 59, 23, 39, 53, 1, 36, 24, 59, 27, 10, 34, 23, 38, 30, 60, 22, 42, 28, 19, 9, 57, 30, 19, 43, 33, 13, 63, 3, 19, 11, 50, 31, 20, 14, 34, 10, 35, 17, 59, 7, 31, 19, 25, 50, 5, 20, 57, 29, 6, 52, 41, 4, 46, 20, 37, 26, 17, 49, 6, 39, 18, 53, 14, 3, 49, 57, 23, 34, 48, 14, 41, 28, 38, 56, 6, 58, 25, 39, 19, 43, 15, 37, 11, 47, 18, 53, 4, 37, 9, 62, 21, 53, 40, 57, 24, 13, 40, 56, 26, 47, 31, 59, 25, 45, 27, 10, 43, 21, 61, 13, 27, 48, 9, 23, 43, 31, 62, 38, 59, 9, 47 }, + { 25, 4, 40, 60, 34, 6, 18, 36, 8, 57, 12, 30, 49, 14, 6, 54, 41, 16, 50, 6, 43, 15, 34, 4, 53, 24, 50, 35, 4, 51, 7, 55, 28, 24, 39, 44, 60, 7, 25, 62, 42, 53, 24, 61, 28, 45, 52, 12, 48, 37, 9, 35, 43, 3, 37, 48, 12, 58, 30, 52, 9, 59, 6, 57, 33, 29, 48, 4, 37, 45, 20, 34, 10, 39, 0, 60, 22, 45, 8, 63, 21, 42, 14, 49, 3, 56, 11, 46, 21, 61, 0, 42, 25, 13, 63, 17, 36, 8, 46, 16, 6, 35, 63, 0, 21, 37, 4, 57, 9, 34, 5, 61, 48, 32, 8, 37, 54, 17, 56, 30, 60, 0, 50, 16, 7, 29, 42, 17 }, + { 32, 50, 15, 48, 2, 43, 52, 25, 47, 16, 32, 63, 21, 52, 40, 19, 0, 61, 29, 58, 20, 56, 26, 46, 12, 55, 6, 22, 62, 32, 17, 40, 0, 49, 34, 8, 27, 32, 48, 0, 21, 39, 5, 44, 12, 6, 22, 40, 0, 57, 16, 60, 23, 17, 54, 22, 36, 15, 24, 39, 19, 34, 47, 23, 0, 54, 13, 51, 24, 9, 55, 16, 52, 27, 44, 20, 4, 54, 26, 49, 0, 30, 46, 16, 29, 51, 34, 4, 52, 28, 33, 15, 57, 39, 26, 49, 0, 56, 27, 31, 48, 20, 43, 29, 53, 11, 46, 19, 41, 13, 55, 18, 0, 57, 26, 51, 2, 44, 6, 38, 14, 40, 22, 45, 36, 53, 3, 57 }, + { 44, 12, 37, 28, 22, 57, 11, 38, 0, 51, 9, 41, 4, 29, 11, 47, 33, 45, 12, 26, 3, 36, 9, 63, 31, 16, 38, 44, 14, 47, 25, 61, 20, 58, 15, 47, 17, 57, 13, 36, 9, 51, 18, 29, 50, 36, 54, 20, 61, 27, 32, 13, 53, 44, 9, 27, 0, 63, 45, 2, 56, 10, 14, 43, 41, 28, 58, 11, 35, 60, 30, 41, 6, 63, 11, 51, 37, 32, 15, 10, 35, 53, 5, 61, 22, 7, 26, 59, 23, 9, 44, 48, 21, 3, 51, 32, 24, 41, 12, 61, 2, 55, 9, 15, 35, 58, 28, 15, 62, 30, 37, 23, 42, 29, 11, 17, 35, 24, 63, 20, 52, 28, 8, 55, 11, 23, 47, 19 }, + { 0, 56, 8, 53, 14, 31, 61, 20, 55, 28, 62, 18, 35, 60, 25, 57, 7, 23, 39, 54, 47, 17, 43, 0, 40, 59, 29, 2, 56, 10, 37, 5, 43, 11, 29, 52, 1, 23, 54, 41, 59, 30, 55, 1, 62, 15, 33, 4, 43, 10, 47, 39, 1, 31, 40, 60, 49, 33, 7, 55, 26, 50, 31, 61, 8, 18, 21, 32, 44, 1, 25, 47, 18, 36, 30, 23, 59, 7, 40, 59, 27, 19, 38, 32, 44, 54, 40, 17, 38, 60, 27, 6, 35, 55, 10, 14, 44, 5, 50, 17, 38, 26, 42, 50, 18, 3, 44, 52, 2, 49, 7, 52, 15, 46, 62, 39, 55, 10, 31, 48, 3, 58, 33, 18, 61, 34, 13, 59 }, + { 39, 27, 63, 20, 35, 41, 4, 45, 26, 5, 38, 13, 44, 2, 50, 17, 37, 52, 2, 13, 28, 58, 24, 51, 21, 8, 34, 48, 27, 42, 18, 51, 31, 56, 5, 36, 38, 44, 4, 17, 26, 11, 38, 23, 42, 8, 56, 39, 24, 51, 5, 56, 21, 59, 14, 6, 18, 42, 22, 35, 16, 37, 3, 25, 39, 46, 63, 5, 50, 17, 58, 8, 55, 3, 50, 12, 43, 17, 47, 2, 51, 9, 62, 12, 1, 35, 13, 50, 1, 37, 12, 51, 19, 29, 46, 59, 22, 58, 33, 45, 22, 60, 10, 32, 61, 39, 8, 33, 25, 36, 20, 60, 38, 4, 21, 5, 28, 45, 12, 18, 42, 11, 49, 1, 27, 40, 6, 30 }, + { 24, 16, 42, 1, 50, 10, 48, 17, 33, 43, 24, 48, 21, 55, 31, 42, 10, 21, 63, 35, 49, 6, 33, 13, 41, 53, 10, 20, 60, 6, 53, 26, 12, 41, 22, 60, 14, 28, 63, 33, 49, 3, 45, 16, 48, 26, 14, 46, 18, 30, 35, 26, 8, 50, 29, 51, 25, 57, 12, 47, 53, 9, 62, 20, 54, 2, 36, 15, 40, 28, 33, 13, 38, 24, 46, 1, 29, 56, 33, 20, 44, 24, 41, 26, 57, 20, 63, 8, 30, 55, 5, 41, 62, 8, 34, 2, 37, 10, 19, 6, 37, 1, 53, 23, 5, 27, 58, 22, 43, 12, 50, 26, 9, 34, 54, 32, 49, 1, 59, 37, 22, 46, 25, 36, 51, 15, 54, 46 }, + { 52, 7, 45, 33, 26, 58, 14, 60, 7, 54, 3, 58, 8, 34, 14, 5, 59, 30, 18, 44, 8, 22, 48, 62, 3, 26, 55, 38, 23, 16, 39, 1, 62, 24, 49, 9, 53, 19, 46, 7, 19, 60, 31, 58, 2, 34, 53, 7, 59, 2, 62, 42, 46, 19, 36, 11, 44, 4, 38, 28, 1, 43, 32, 51, 12, 29, 56, 22, 52, 2, 62, 49, 22, 60, 14, 35, 63, 5, 25, 57, 14, 53, 4, 46, 18, 31, 42, 22, 47, 20, 58, 31, 16, 43, 23, 54, 30, 42, 52, 57, 29, 49, 30, 13, 45, 48, 16, 55, 6, 63, 1, 44, 14, 58, 19, 47, 15, 24, 51, 34, 6, 55, 5, 63, 20, 41, 21, 9 }, + { 30, 62, 18, 55, 5, 23, 39, 29, 49, 30, 15, 36, 28, 46, 60, 25, 39, 46, 4, 32, 61, 40, 15, 30, 36, 45, 14, 2, 49, 33, 57, 45, 18, 32, 3, 45, 30, 2, 35, 52, 40, 27, 13, 21, 38, 63, 20, 28, 37, 23, 16, 10, 13, 55, 2, 62, 21, 32, 60, 17, 58, 23, 5, 40, 16, 48, 7, 45, 10, 26, 43, 19, 6, 31, 52, 21, 39, 16, 48, 9, 37, 28, 36, 55, 7, 48, 3, 59, 15, 45, 25, 1, 53, 13, 47, 7, 62, 15, 4, 25, 12, 41, 18, 60, 38, 11, 34, 19, 39, 31, 29, 56, 23, 42, 3, 27, 60, 41, 8, 16, 61, 29, 43, 9, 32, 2, 60, 34 }, + { 3, 38, 13, 37, 52, 44, 2, 19, 12, 42, 63, 19, 40, 1, 20, 50, 12, 55, 15, 56, 27, 1, 54, 11, 57, 18, 32, 63, 44, 4, 29, 13, 37, 61, 35, 16, 42, 57, 12, 22, 6, 55, 43, 10, 50, 5, 44, 11, 48, 52, 34, 58, 28, 41, 38, 30, 7, 52, 11, 49, 30, 14, 45, 27, 59, 34, 21, 38, 32, 58, 11, 36, 56, 42, 9, 41, 3, 54, 31, 42, 0, 60, 16, 11, 39, 24, 52, 33, 6, 36, 10, 40, 32, 60, 26, 20, 39, 28, 47, 34, 63, 8, 54, 3, 24, 56, 0, 51, 13, 47, 16, 40, 7, 35, 52, 11, 36, 4, 57, 30, 39, 13, 18, 50, 58, 28, 12, 48 }, + { 57, 24, 49, 21, 10, 31, 61, 36, 56, 0, 22, 53, 11, 56, 32, 7, 36, 27, 41, 9, 46, 19, 34, 42, 25, 7, 50, 9, 28, 21, 54, 8, 50, 7, 27, 59, 10, 25, 48, 62, 37, 0, 33, 58, 25, 18, 32, 61, 0, 15, 45, 5, 50, 3, 23, 55, 47, 17, 40, 6, 60, 34, 53, 8, 41, 0, 61, 13, 54, 4, 46, 28, 0, 17, 48, 27, 58, 13, 23, 61, 33, 21, 50, 30, 62, 8, 14, 29, 56, 27, 61, 49, 17, 2, 44, 11, 51, 0, 59, 17, 40, 20, 32, 47, 36, 21, 42, 28, 60, 4, 54, 10, 59, 17, 30, 62, 21, 43, 26, 48, 0, 56, 36, 25, 8, 44, 39, 17 }, + { 10, 42, 4, 59, 27, 47, 8, 23, 51, 32, 45, 6, 37, 26, 48, 43, 62, 0, 21, 53, 38, 12, 51, 5, 60, 47, 24, 37, 59, 15, 35, 47, 22, 55, 0, 50, 21, 40, 6, 29, 15, 52, 24, 8, 41, 55, 13, 29, 40, 56, 24, 31, 19, 33, 61, 15, 0, 35, 24, 42, 21, 2, 19, 57, 24, 15, 30, 50, 20, 25, 40, 16, 57, 34, 61, 8, 29, 45, 6, 49, 11, 47, 2, 44, 19, 57, 38, 50, 12, 42, 21, 4, 35, 52, 28, 56, 23, 36, 13, 45, 4, 52, 27, 14, 6, 62, 9, 45, 21, 37, 25, 46, 33, 49, 0, 44, 7, 53, 13, 19, 53, 31, 3, 47, 15, 56, 22, 51 }, + { 35, 28, 53, 32, 1, 16, 54, 40, 9, 17, 25, 58, 14, 59, 3, 22, 16, 51, 31, 5, 23, 58, 28, 17, 35, 20, 0, 42, 11, 52, 3, 31, 41, 17, 43, 13, 32, 54, 18, 60, 32, 45, 17, 49, 2, 36, 51, 22, 7, 36, 9, 63, 48, 12, 46, 26, 43, 28, 63, 13, 48, 37, 51, 33, 5, 47, 55, 9, 42, 63, 7, 51, 24, 12, 37, 19, 55, 34, 18, 38, 15, 28, 54, 34, 5, 43, 22, 0, 48, 14, 54, 24, 58, 9, 38, 5, 32, 55, 21, 30, 49, 9, 59, 43, 30, 51, 35, 26, 7, 53, 2, 22, 14, 27, 57, 18, 38, 24, 33, 45, 10, 41, 20, 60, 37, 5, 32, 0 }, + { 63, 19, 15, 40, 62, 35, 14, 28, 46, 61, 4, 49, 35, 10, 29, 54, 33, 8, 45, 62, 37, 1, 43, 55, 10, 52, 61, 30, 19, 40, 25, 62, 11, 38, 27, 58, 36, 3, 46, 8, 39, 4, 62, 28, 47, 20, 4, 54, 47, 27, 43, 1, 21, 38, 8, 58, 10, 54, 4, 56, 9, 26, 12, 39, 60, 27, 18, 37, 1, 31, 35, 5, 45, 50, 2, 43, 26, 1, 59, 23, 56, 40, 7, 26, 58, 17, 32, 63, 25, 39, 7, 31, 45, 19, 63, 15, 48, 8, 37, 61, 16, 34, 1, 56, 18, 3, 15, 58, 49, 32, 63, 41, 55, 5, 40, 22, 50, 6, 59, 2, 63, 23, 52, 11, 26, 61, 44, 23 }, + { 11, 56, 46, 6, 22, 43, 58, 3, 34, 21, 38, 30, 18, 44, 52, 13, 41, 57, 17, 28, 14, 49, 25, 7, 33, 39, 26, 6, 56, 48, 1, 20, 56, 5, 46, 9, 19, 51, 30, 25, 56, 21, 35, 14, 57, 42, 16, 33, 10, 57, 17, 59, 41, 25, 53, 37, 20, 40, 30, 18, 31, 62, 44, 22, 3, 44, 11, 48, 23, 53, 18, 60, 29, 22, 62, 15, 53, 47, 10, 41, 3, 19, 52, 36, 13, 46, 10, 35, 3, 61, 41, 16, 1, 50, 26, 42, 18, 46, 2, 25, 54, 20, 39, 23, 47, 31, 41, 12, 38, 17, 8, 19, 31, 48, 12, 61, 9, 54, 29, 35, 15, 38, 6, 43, 34, 14, 7, 47 }, + { 39, 2, 33, 26, 53, 8, 18, 50, 41, 12, 53, 1, 63, 24, 19, 39, 2, 24, 47, 10, 60, 38, 19, 63, 48, 4, 15, 45, 32, 14, 60, 36, 29, 53, 23, 63, 34, 12, 61, 1, 43, 11, 53, 30, 1, 26, 60, 45, 23, 39, 3, 29, 12, 50, 4, 16, 51, 3, 45, 36, 50, 1, 16, 54, 35, 14, 57, 30, 58, 9, 46, 14, 41, 10, 32, 38, 4, 30, 21, 51, 32, 63, 25, 1, 60, 27, 53, 18, 51, 22, 28, 55, 34, 12, 40, 3, 60, 29, 57, 41, 6, 44, 11, 53, 8, 61, 24, 57, 1, 28, 44, 59, 36, 3, 34, 25, 41, 31, 16, 44, 22, 47, 28, 58, 1, 49, 54, 29 }, + { 58, 25, 50, 13, 38, 30, 60, 24, 6, 57, 27, 42, 9, 45, 6, 61, 30, 50, 4, 34, 29, 3, 46, 13, 22, 42, 58, 28, 9, 39, 23, 44, 7, 15, 44, 2, 40, 15, 47, 41, 23, 37, 7, 59, 38, 11, 34, 6, 62, 14, 52, 35, 55, 19, 32, 61, 33, 24, 57, 6, 22, 59, 29, 7, 49, 25, 40, 3, 17, 39, 27, 52, 0, 55, 16, 57, 24, 61, 36, 6, 29, 12, 48, 39, 20, 44, 6, 40, 33, 5, 48, 10, 57, 36, 22, 51, 33, 9, 24, 12, 62, 29, 50, 35, 14, 43, 5, 33, 47, 52, 13, 23, 10, 51, 56, 16, 46, 1, 49, 4, 61, 9, 52, 18, 31, 21, 36, 17 }, + { 19, 42, 9, 48, 2, 44, 11, 37, 48, 20, 33, 16, 55, 35, 49, 15, 37, 20, 59, 16, 53, 22, 56, 31, 50, 11, 34, 54, 16, 51, 4, 49, 33, 53, 21, 28, 56, 24, 31, 9, 52, 16, 48, 24, 44, 13, 51, 20, 31, 49, 18, 6, 34, 2, 44, 14, 47, 8, 15, 43, 13, 41, 33, 52, 20, 61, 7, 51, 34, 62, 4, 20, 36, 33, 43, 8, 46, 13, 53, 17, 45, 42, 9, 31, 52, 11, 30, 56, 13, 59, 17, 44, 27, 6, 62, 11, 43, 17, 49, 38, 26, 2, 16, 27, 58, 21, 54, 18, 26, 5, 35, 61, 43, 27, 7, 39, 14, 58, 37, 55, 20, 33, 13, 40, 62, 10, 55, 5 }, + { 51, 14, 61, 29, 59, 20, 55, 31, 0, 49, 11, 60, 3, 26, 22, 56, 0, 40, 12, 43, 41, 8, 36, 0, 17, 57, 24, 2, 46, 26, 61, 18, 0, 38, 12, 59, 6, 49, 3, 57, 19, 63, 5, 33, 18, 54, 28, 56, 0, 43, 26, 46, 63, 27, 56, 22, 27, 54, 38, 28, 63, 24, 10, 45, 0, 31, 42, 21, 12, 25, 44, 49, 59, 6, 26, 50, 3, 34, 27, 59, 0, 35, 62, 16, 4, 58, 47, 0, 43, 24, 37, 2, 54, 20, 46, 31, 0, 56, 34, 5, 55, 45, 60, 37, 0, 40, 10, 38, 63, 46, 15, 20, 0, 53, 21, 62, 30, 11, 24, 27, 40, 0, 57, 26, 3, 45, 27, 35 }, +}; + +static const guint32 DM_565[128 * 128] = +{ + 3072, 5243909, 2099202, 3072, 2099202, 4195332, 3072, 1051649, 7340039, 2099202, 5243909, 6291462, 3147779, 5243909, 1051649, 4195332, 6291462, 3147779, 7340039, 3147779, 3072, 7340039, 3147779, 6291462, 4195332, 3072, 5243909, 7340039, 2099202, 4195332, 1051649, 5243909, 3147779, 7340039, 5243909, 4195332, 2099202, 5243909, 4195332, 1051649, 4195332, 3147779, 6291462, 1051649, 7340039, 3072, 5243909, 1051649, 4195332, 1051649, 7340039, 2099202, 3072, 5243909, 1051649, 4195332, 3072, 7340039, 1051649, 5243909, 3072, 6291462, 4195332, 2099202, 4195332, 7340039, 1051649, 6291462, 4195332, 7340039, 1051649, 3147779, 2099202, 1051649, 7340039, 2099202, 5243909, 6291462, 3072, 2099202, 6291462, 1051649, 2099202, 6291462, 4195332, 2099202, 2099202, 4195332, 1051649, 6291462, 2099202, 7340039, 3147779, 1051649, 4195332, 3147779, 6291462, 1051649, 2099202, 5243909, 2099202, 3147779, 3072, 2099202, 6291462, 3147779, 6291462, 2099202, 3072, 4195332, 7340039, 5243909, 3147779, 4195332, 1051649, 6291462, 2099202, 5243909, 3072, 6291462, 1051649, 5243909, 4195332, 6291462, 2099202, 5243909, 1051649, 7340039, + 3147779, 7340039, 4195332, 6291462, 5243909, 4195332, 6291462, 3147779, 5243909, 3072, 3147779, 3072, 2099202, 4195332, 7340039, 1051649, 5243909, 3072, 2099202, 6291462, 4195332, 2099202, 5243909, 1051649, 3147779, 5243909, 1051649, 4195332, 3072, 6291462, 3147779, 7340039, 1051649, 3147779, 3072, 2099202, 6291462, 1051649, 7340039, 3147779, 5243909, 3072, 4195332, 3147779, 5243909, 2099202, 5243909, 3147779, 7340039, 4195332, 1051649, 4195332, 6291462, 2099202, 7340039, 3147779, 6291462, 2099202, 4195332, 3147779, 6291462, 2099202, 3072, 6291462, 2099202, 1051649, 3147779, 5243909, 3072, 4195332, 5243909, 2099202, 6291462, 5243909, 4195332, 2099202, 3147779, 1051649, 5243909, 3147779, 4195332, 7340039, 3072, 4195332, 1051649, 5243909, 7340039, 3147779, 7340039, 1051649, 5243909, 1051649, 5243909, 3072, 7340039, 3072, 2099202, 6291462, 7340039, 1051649, 6291462, 1051649, 5243909, 7340039, 1051649, 3147779, 3072, 6291462, 5243909, 3147779, 1051649, 6291462, 2099202, 7340039, 5243909, 3072, 4195332, 7340039, 4195332, 2099202, 7340039, 3147779, 2099202, 3072, 7340039, 4195332, 3147779, 4195332, + 2099202, 1051649, 2099202, 4195332, 3072, 3147779, 1051649, 7340039, 2099202, 5243909, 7340039, 4195332, 6291462, 2099202, 3072, 5243909, 2099202, 4195332, 7340039, 3072, 6291462, 1051649, 7340039, 3072, 7340039, 2099202, 6291462, 3147779, 5243909, 2099202, 3072, 6291462, 1051649, 6291462, 5243909, 6291462, 3147779, 4195332, 3072, 6291462, 2099202, 7340039, 1051649, 6291462, 3072, 4195332, 1051649, 6291462, 2099202, 3147779, 6291462, 1051649, 3147779, 6291462, 3072, 4195332, 1051649, 5243909, 3072, 6291462, 1051649, 4195332, 7340039, 3147779, 7340039, 4195332, 6291462, 1051649, 7340039, 2099202, 3072, 7340039, 3072, 3147779, 3072, 6291462, 7340039, 4195332, 1051649, 7340039, 3072, 3147779, 5243909, 3147779, 6291462, 1051649, 3072, 5243909, 3072, 4195332, 4195332, 6291462, 3147779, 6291462, 4195332, 5243909, 7340039, 3072, 3147779, 4195332, 2099202, 7340039, 3072, 4195332, 5243909, 7340039, 4195332, 2099202, 7340039, 3072, 6291462, 3147779, 3072, 4195332, 2099202, 6291462, 3147779, 1051649, 5243909, 6291462, 1051649, 3072, 7340039, 4195332, 2099202, 6291462, 3072, 5243909, + 6291462, 6291462, 5243909, 1051649, 5243909, 7340039, 3147779, 4195332, 1051649, 4195332, 2099202, 3072, 3147779, 5243909, 3147779, 7340039, 3072, 6291462, 1051649, 4195332, 3147779, 2099202, 4195332, 4195332, 2099202, 5243909, 3072, 6291462, 1051649, 7340039, 3147779, 4195332, 2099202, 4195332, 2099202, 2099202, 3072, 5243909, 4195332, 2099202, 1051649, 5243909, 3147779, 3147779, 7340039, 2099202, 7340039, 3072, 5243909, 3072, 5243909, 7340039, 3072, 3147779, 5243909, 2099202, 7340039, 3147779, 7340039, 2099202, 4195332, 5243909, 1051649, 5243909, 3072, 4195332, 3072, 4195332, 1051649, 5243909, 6291462, 4195332, 2099202, 6291462, 5243909, 1051649, 2099202, 3072, 6291462, 2099202, 6291462, 5243909, 1051649, 7340039, 2099202, 6291462, 3147779, 6291462, 2099202, 7340039, 1051649, 3072, 7340039, 2099202, 1051649, 2099202, 4195332, 4195332, 2099202, 5243909, 3072, 6291462, 3147779, 4195332, 2099202, 3072, 6291462, 1051649, 3147779, 5243909, 4195332, 2099202, 7340039, 1051649, 5243909, 1051649, 6291462, 2099202, 3072, 4195332, 3147779, 5243909, 3147779, 3072, 6291462, 1051649, 7340039, 3072, + 2099202, 3147779, 3072, 7340039, 2099202, 1051649, 6291462, 3072, 5243909, 6291462, 1051649, 7340039, 1051649, 6291462, 1051649, 4195332, 2099202, 3147779, 5243909, 1051649, 6291462, 3147779, 5243909, 3072, 6291462, 1051649, 7340039, 1051649, 4195332, 1051649, 6291462, 1051649, 7340039, 3072, 7340039, 5243909, 7340039, 1051649, 6291462, 3147779, 7340039, 4195332, 1051649, 6291462, 3072, 5243909, 3147779, 4195332, 6291462, 2099202, 4195332, 1051649, 6291462, 4195332, 1051649, 6291462, 3072, 2099202, 1051649, 5243909, 3072, 7340039, 1051649, 2099202, 6291462, 2099202, 6291462, 3147779, 7340039, 2099202, 3147779, 1051649, 5243909, 1051649, 3147779, 7340039, 5243909, 4195332, 3147779, 4195332, 1051649, 3147779, 2099202, 4195332, 3072, 5243909, 4195332, 1051649, 6291462, 4195332, 2099202, 5243909, 3147779, 5243909, 3147779, 6291462, 3072, 5243909, 6291462, 1051649, 7340039, 3147779, 1051649, 6291462, 2099202, 5243909, 4195332, 2099202, 4195332, 3072, 6291462, 1051649, 5243909, 4195332, 3072, 7340039, 3147779, 5243909, 7340039, 2099202, 1051649, 7340039, 4195332, 5243909, 1051649, 4195332, 3147779, 4195332, + 6291462, 4195332, 7340039, 3147779, 4195332, 5243909, 2099202, 7340039, 3072, 4195332, 5243909, 3147779, 5243909, 4195332, 3072, 6291462, 6291462, 1051649, 7340039, 2099202, 5243909, 3072, 7340039, 3147779, 2099202, 5243909, 4195332, 3147779, 7340039, 5243909, 2099202, 4195332, 4195332, 3147779, 5243909, 1051649, 3147779, 2099202, 3072, 5243909, 1051649, 6291462, 3072, 4195332, 2099202, 6291462, 1051649, 2099202, 3072, 7340039, 2099202, 3147779, 6291462, 2099202, 7340039, 3147779, 5243909, 4195332, 7340039, 1051649, 6291462, 4195332, 3147779, 5243909, 2099202, 7340039, 3147779, 1051649, 5243909, 3072, 4195332, 7340039, 1051649, 7340039, 3147779, 3072, 6291462, 1051649, 7340039, 3072, 5243909, 7340039, 3072, 7340039, 3147779, 2099202, 3072, 7340039, 3147779, 1051649, 7340039, 2099202, 5243909, 3072, 7340039, 4195332, 3147779, 1051649, 3147779, 4195332, 1051649, 5243909, 6291462, 3072, 6291462, 1051649, 7340039, 3072, 7340039, 1051649, 3147779, 7340039, 2099202, 6291462, 4195332, 2099202, 4195332, 1051649, 3147779, 6291462, 5243909, 2099202, 3072, 3147779, 7340039, 2099202, 6291462, 1051649, + 3147779, 3072, 3147779, 1051649, 6291462, 3072, 4195332, 3147779, 2099202, 6291462, 2099202, 7340039, 3072, 7340039, 3147779, 2099202, 3072, 4195332, 3147779, 3072, 6291462, 4195332, 1051649, 6291462, 3147779, 6291462, 2099202, 5243909, 3072, 3147779, 7340039, 3072, 6291462, 1051649, 3147779, 3072, 6291462, 5243909, 7340039, 3147779, 4195332, 1051649, 7340039, 2099202, 5243909, 1051649, 7340039, 4195332, 5243909, 3147779, 5243909, 5243909, 3072, 4195332, 1051649, 5243909, 2099202, 3072, 5243909, 3147779, 3147779, 2099202, 7340039, 3072, 4195332, 3072, 5243909, 4195332, 3147779, 6291462, 2099202, 3147779, 6291462, 3072, 4195332, 7340039, 2099202, 4195332, 2099202, 6291462, 1051649, 5243909, 3147779, 4195332, 1051649, 6291462, 5243909, 3147779, 2099202, 5243909, 4195332, 3072, 6291462, 2099202, 1051649, 1051649, 6291462, 7340039, 3072, 7340039, 5243909, 2099202, 1051649, 3147779, 7340039, 3147779, 3147779, 5243909, 3147779, 6291462, 4195332, 2099202, 5243909, 3072, 3147779, 6291462, 3072, 7340039, 3072, 4195332, 3072, 7340039, 6291462, 5243909, 1051649, 5243909, 3072, 5243909, + 2099202, 7340039, 5243909, 3072, 7340039, 3147779, 7340039, 1051649, 6291462, 1051649, 4195332, 1051649, 3147779, 5243909, 2099202, 5243909, 7340039, 3147779, 6291462, 4195332, 1051649, 7340039, 2099202, 4195332, 3072, 5243909, 3072, 7340039, 4195332, 2099202, 5243909, 1051649, 5243909, 2099202, 7340039, 5243909, 2099202, 1051649, 4195332, 2099202, 6291462, 4195332, 2099202, 7340039, 3147779, 6291462, 3147779, 3072, 2099202, 6291462, 3072, 7340039, 2099202, 7340039, 3147779, 3072, 7340039, 4195332, 2099202, 7340039, 3072, 6291462, 3072, 5243909, 3147779, 7340039, 1051649, 6291462, 1051649, 7340039, 3072, 2099202, 4195332, 2099202, 5243909, 1051649, 5243909, 3072, 5243909, 3147779, 4195332, 2099202, 6291462, 2099202, 6291462, 5243909, 1051649, 7340039, 3072, 6291462, 1051649, 6291462, 3147779, 4195332, 7340039, 2099202, 5243909, 2099202, 4195332, 3147779, 3072, 6291462, 4195332, 4195332, 3072, 5243909, 1051649, 5243909, 1051649, 2099202, 3072, 6291462, 1051649, 4195332, 7340039, 1051649, 5243909, 2099202, 6291462, 3147779, 5243909, 2099202, 3147779, 1051649, 7340039, 2099202, 4195332, 7340039, + 6291462, 4195332, 1051649, 5243909, 3147779, 2099202, 5243909, 3072, 4195332, 7340039, 3147779, 5243909, 6291462, 3072, 7340039, 1051649, 5243909, 2099202, 3072, 7340039, 2099202, 1051649, 5243909, 1051649, 7340039, 4195332, 1051649, 3147779, 3072, 6291462, 2099202, 7340039, 4195332, 6291462, 3072, 4195332, 6291462, 3147779, 7340039, 3072, 5243909, 3072, 5243909, 3072, 5243909, 3072, 6291462, 4195332, 7340039, 1051649, 4195332, 1051649, 5243909, 1051649, 4195332, 6291462, 3147779, 6291462, 1051649, 5243909, 2099202, 4195332, 7340039, 1051649, 2099202, 6291462, 4195332, 3072, 5243909, 3147779, 5243909, 6291462, 3072, 6291462, 1051649, 7340039, 3147779, 6291462, 1051649, 7340039, 3072, 6291462, 3072, 7340039, 3072, 4195332, 2099202, 4195332, 5243909, 3147779, 3147779, 7340039, 3072, 1051649, 5243909, 4195332, 3072, 6291462, 1051649, 7340039, 2099202, 5243909, 1051649, 7340039, 2099202, 7340039, 3072, 6291462, 3147779, 7340039, 5243909, 3147779, 6291462, 2099202, 5243909, 3147779, 7340039, 4195332, 2099202, 5243909, 1051649, 4195332, 3072, 6291462, 4195332, 6291462, 2099202, 1051649, + 3072, 2099202, 5243909, 2099202, 6291462, 1051649, 4195332, 6291462, 2099202, 5243909, 3072, 2099202, 3147779, 4195332, 4195332, 2099202, 3147779, 7340039, 1051649, 4195332, 5243909, 3147779, 7340039, 5243909, 3147779, 2099202, 7340039, 6291462, 5243909, 3147779, 3072, 4195332, 3072, 3147779, 2099202, 7340039, 3072, 1051649, 5243909, 3147779, 6291462, 2099202, 3147779, 6291462, 1051649, 4195332, 2099202, 1051649, 5243909, 3147779, 2099202, 6291462, 3147779, 5243909, 6291462, 1051649, 4195332, 3072, 6291462, 3147779, 6291462, 1051649, 4195332, 3147779, 5243909, 1051649, 2099202, 3147779, 7340039, 1051649, 4195332, 6291462, 2099202, 4195332, 3147779, 3072, 5243909, 2099202, 4195332, 2099202, 3147779, 5243909, 3147779, 4195332, 2099202, 6291462, 3147779, 3072, 7340039, 1051649, 5243909, 2099202, 3147779, 6291462, 2099202, 7340039, 3147779, 4195332, 5243909, 2099202, 6291462, 3147779, 3147779, 1051649, 5243909, 2099202, 4195332, 2099202, 4195332, 3072, 4195332, 1051649, 1051649, 7340039, 3072, 2099202, 1051649, 3072, 7340039, 1051649, 6291462, 3147779, 5243909, 3147779, 1051649, 3072, 3147779, 6291462, + 5243909, 3147779, 7340039, 3072, 4195332, 7340039, 3147779, 1051649, 7340039, 1051649, 6291462, 7340039, 1051649, 6291462, 1051649, 6291462, 3072, 5243909, 3147779, 6291462, 3072, 4195332, 2099202, 3072, 6291462, 4195332, 3072, 2099202, 1051649, 7340039, 6291462, 1051649, 6291462, 6291462, 5243909, 3147779, 4195332, 7340039, 1051649, 4195332, 1051649, 7340039, 4195332, 1051649, 7340039, 3147779, 7340039, 5243909, 1051649, 6291462, 5243909, 3072, 4195332, 2099202, 3072, 2099202, 7340039, 3147779, 1051649, 5243909, 3072, 6291462, 5243909, 3072, 6291462, 4195332, 6291462, 7340039, 3072, 5243909, 2099202, 3072, 7340039, 3147779, 6291462, 4195332, 7340039, 1051649, 7340039, 3147779, 5243909, 1051649, 7340039, 3072, 5243909, 1051649, 7340039, 5243909, 3147779, 4195332, 3072, 7340039, 5243909, 1051649, 4195332, 3072, 6291462, 1051649, 7340039, 3072, 4195332, 1051649, 5243909, 6291462, 3072, 6291462, 3147779, 3072, 7340039, 6291462, 3147779, 7340039, 5243909, 3147779, 4195332, 5243909, 6291462, 3147779, 5243909, 4195332, 2099202, 7340039, 3072, 7340039, 5243909, 4195332, 7340039, 2099202, + 3072, 6291462, 1051649, 6291462, 2099202, 5243909, 3072, 5243909, 3147779, 2099202, 5243909, 4195332, 3072, 5243909, 2099202, 3147779, 7340039, 1051649, 4195332, 2099202, 5243909, 6291462, 3147779, 7340039, 1051649, 6291462, 3147779, 5243909, 4195332, 2099202, 2099202, 4195332, 3147779, 1051649, 2099202, 3072, 6291462, 2099202, 4195332, 2099202, 6291462, 3072, 3147779, 5243909, 2099202, 4195332, 3072, 3147779, 4195332, 3072, 7340039, 1051649, 7340039, 4195332, 7340039, 3147779, 5243909, 2099202, 4195332, 7340039, 3147779, 2099202, 1051649, 7340039, 2099202, 3072, 2099202, 2099202, 4195332, 1051649, 7340039, 3147779, 5243909, 1051649, 1051649, 5243909, 2099202, 4195332, 3072, 6291462, 3072, 4195332, 1051649, 6291462, 3147779, 4195332, 2099202, 3072, 6291462, 1051649, 6291462, 4195332, 3147779, 3072, 7340039, 5243909, 1051649, 4195332, 2099202, 6291462, 2099202, 7340039, 3072, 4195332, 4195332, 1051649, 7340039, 5243909, 2099202, 1051649, 5243909, 3072, 4195332, 3072, 6291462, 1051649, 2099202, 6291462, 1051649, 5243909, 3072, 4195332, 2099202, 4195332, 3072, 3147779, 1051649, 4195332, + 6291462, 4195332, 3147779, 1051649, 6291462, 1051649, 4195332, 6291462, 3072, 7340039, 3072, 2099202, 6291462, 4195332, 7340039, 1051649, 5243909, 3147779, 7340039, 1051649, 6291462, 3072, 3147779, 4195332, 2099202, 5243909, 3072, 7340039, 3072, 4195332, 7340039, 3072, 5243909, 7340039, 4195332, 5243909, 3147779, 5243909, 3072, 7340039, 2099202, 5243909, 6291462, 3072, 4195332, 7340039, 6291462, 2099202, 7340039, 2099202, 5243909, 3147779, 4195332, 3072, 2099202, 5243909, 3072, 6291462, 2099202, 3072, 5243909, 4195332, 6291462, 3147779, 4195332, 7340039, 5243909, 3147779, 6291462, 4195332, 3072, 6291462, 3147779, 5243909, 7340039, 3072, 6291462, 2099202, 5243909, 3147779, 7340039, 2099202, 6291462, 2099202, 7340039, 1051649, 4195332, 7340039, 2099202, 4195332, 2099202, 3072, 6291462, 5243909, 3147779, 2099202, 3147779, 6291462, 3072, 3147779, 5243909, 2099202, 4195332, 7340039, 2099202, 5243909, 3147779, 1051649, 6291462, 4195332, 2099202, 6291462, 3147779, 7340039, 3147779, 7340039, 4195332, 3072, 7340039, 2099202, 6291462, 7340039, 1051649, 6291462, 2099202, 7340039, 5243909, 2099202, + 2099202, 3072, 7340039, 5243909, 3147779, 7340039, 3072, 2099202, 5243909, 3147779, 4195332, 7340039, 1051649, 3147779, 3072, 6291462, 1051649, 6291462, 3072, 4195332, 2099202, 7340039, 1051649, 5243909, 1051649, 6291462, 2099202, 3147779, 6291462, 3147779, 1051649, 6291462, 2099202, 3072, 6291462, 1051649, 7340039, 1051649, 6291462, 3147779, 4195332, 3072, 3147779, 7340039, 1051649, 2099202, 1051649, 5243909, 3147779, 3072, 4195332, 1051649, 6291462, 6291462, 1051649, 7340039, 1051649, 4195332, 7340039, 4195332, 1051649, 7340039, 3072, 3147779, 2099202, 3072, 5243909, 1051649, 1051649, 5243909, 2099202, 4195332, 1051649, 2099202, 3147779, 4195332, 1051649, 6291462, 3147779, 1051649, 2099202, 5243909, 3072, 4195332, 3072, 5243909, 3147779, 1051649, 6291462, 3072, 7340039, 5243909, 2099202, 4195332, 3072, 7340039, 5243909, 1051649, 4195332, 7340039, 3072, 6291462, 3147779, 3072, 2099202, 6291462, 3072, 7340039, 4195332, 3072, 7340039, 1051649, 2099202, 1051649, 1051649, 4195332, 3147779, 5243909, 4195332, 3072, 3147779, 1051649, 5243909, 3147779, 6291462, 1051649, 3147779, 7340039, + 6291462, 4195332, 2099202, 4195332, 3072, 5243909, 6291462, 4195332, 6291462, 1051649, 3147779, 6291462, 3147779, 7340039, 4195332, 2099202, 5243909, 2099202, 4195332, 7340039, 2099202, 5243909, 3147779, 3072, 7340039, 4195332, 3147779, 5243909, 1051649, 2099202, 6291462, 4195332, 5243909, 1051649, 3147779, 4195332, 1051649, 3147779, 5243909, 3072, 5243909, 6291462, 2099202, 5243909, 3147779, 5243909, 6291462, 1051649, 7340039, 6291462, 2099202, 7340039, 3072, 3147779, 5243909, 2099202, 4195332, 3147779, 1051649, 6291462, 2099202, 5243909, 1051649, 6291462, 6291462, 4195332, 7340039, 3147779, 7340039, 3147779, 7340039, 3072, 5243909, 7340039, 4195332, 7340039, 2099202, 5243909, 3072, 7340039, 6291462, 1051649, 7340039, 4195332, 6291462, 2099202, 6291462, 3147779, 4195332, 5243909, 1051649, 3147779, 6291462, 1051649, 6291462, 4195332, 2099202, 7340039, 3147779, 1051649, 5243909, 4195332, 2099202, 6291462, 4195332, 3147779, 5243909, 1051649, 3147779, 6291462, 3147779, 4195332, 5243909, 6291462, 7340039, 3072, 6291462, 1051649, 7340039, 2099202, 6291462, 6291462, 3072, 4195332, 1051649, 5243909, 3147779, 3072, + 5243909, 1051649, 7340039, 3147779, 2099202, 3147779, 2099202, 1051649, 4195332, 3072, 5243909, 1051649, 3072, 5243909, 1051649, 5243909, 3072, 6291462, 3147779, 3072, 4195332, 1051649, 6291462, 4195332, 2099202, 1051649, 6291462, 3072, 5243909, 7340039, 1051649, 3147779, 3072, 7340039, 2099202, 5243909, 3147779, 6291462, 2099202, 7340039, 2099202, 1051649, 7340039, 3072, 6291462, 3072, 4195332, 3147779, 3072, 2099202, 4195332, 5243909, 2099202, 6291462, 3147779, 3072, 6291462, 7340039, 3147779, 4195332, 3072, 7340039, 3147779, 5243909, 3072, 2099202, 1051649, 4195332, 3072, 6291462, 1051649, 5243909, 2099202, 1051649, 3072, 3147779, 6291462, 2099202, 4195332, 4195332, 3072, 5243909, 3147779, 1051649, 1051649, 5243909, 3072, 5243909, 3072, 3147779, 7340039, 3072, 3147779, 7340039, 2099202, 1051649, 3072, 5243909, 2099202, 6291462, 3147779, 3072, 7340039, 1051649, 5243909, 3072, 3147779, 7340039, 3072, 5243909, 2099202, 7340039, 3072, 4195332, 2099202, 3147779, 5243909, 2099202, 3147779, 5243909, 1051649, 3147779, 7340039, 2099202, 6291462, 1051649, 7340039, 3147779, + 2099202, 6291462, 1051649, 5243909, 7340039, 3072, 7340039, 6291462, 2099202, 7340039, 2099202, 4195332, 7340039, 2099202, 6291462, 3147779, 4195332, 7340039, 1051649, 6291462, 7340039, 5243909, 3147779, 3072, 6291462, 3147779, 7340039, 2099202, 4195332, 3072, 4195332, 7340039, 6291462, 4195332, 5243909, 3072, 7340039, 3072, 4195332, 1051649, 5243909, 4195332, 2099202, 4195332, 3147779, 1051649, 7340039, 3147779, 5243909, 4195332, 1051649, 6291462, 3072, 4195332, 1051649, 7340039, 2099202, 3072, 5243909, 2099202, 5243909, 1051649, 4195332, 2099202, 7340039, 5243909, 3147779, 6291462, 5243909, 1051649, 4195332, 3147779, 7340039, 4195332, 6291462, 3072, 5243909, 1051649, 3147779, 6291462, 3147779, 2099202, 7340039, 5243909, 3147779, 4195332, 7340039, 2099202, 7340039, 2099202, 2099202, 6291462, 4195332, 1051649, 5243909, 7340039, 3147779, 4195332, 6291462, 3072, 4195332, 7340039, 1051649, 6291462, 2099202, 7340039, 1051649, 4195332, 6291462, 3147779, 1051649, 5243909, 1051649, 3147779, 3072, 7340039, 1051649, 6291462, 3072, 7340039, 4195332, 4195332, 2099202, 5243909, 3072, 4195332, 3072, 5243909, + 3072, 7340039, 2099202, 4195332, 1051649, 5243909, 1051649, 4195332, 3072, 3147779, 6291462, 3147779, 3072, 4195332, 1051649, 7340039, 2099202, 3072, 4195332, 3147779, 2099202, 3072, 6291462, 4195332, 5243909, 1051649, 4195332, 2099202, 7340039, 5243909, 3147779, 1051649, 2099202, 1051649, 7340039, 3147779, 2099202, 6291462, 4195332, 7340039, 3072, 7340039, 1051649, 5243909, 7340039, 5243909, 1051649, 2099202, 6291462, 3072, 7340039, 1051649, 7340039, 3147779, 5243909, 2099202, 4195332, 6291462, 1051649, 7340039, 3147779, 3147779, 6291462, 3072, 4195332, 1051649, 7340039, 3072, 2099202, 7340039, 3072, 6291462, 3072, 2099202, 5243909, 3147779, 7340039, 4195332, 7340039, 1051649, 4195332, 6291462, 2099202, 3072, 7340039, 1051649, 4195332, 3147779, 1051649, 6291462, 5243909, 1051649, 5243909, 2099202, 3147779, 6291462, 3072, 4195332, 1051649, 7340039, 2099202, 5243909, 3147779, 1051649, 5243909, 3147779, 6291462, 2099202, 1051649, 4195332, 6291462, 2099202, 4195332, 6291462, 5243909, 2099202, 4195332, 3147779, 6291462, 2099202, 3072, 5243909, 3072, 6291462, 4195332, 7340039, 3147779, 4195332, + 5243909, 3147779, 3072, 4195332, 6291462, 3147779, 4195332, 7340039, 3147779, 5243909, 1051649, 5243909, 6291462, 3147779, 6291462, 3072, 5243909, 4195332, 7340039, 1051649, 3147779, 7340039, 2099202, 5243909, 1051649, 7340039, 3072, 5243909, 3072, 2099202, 5243909, 3072, 7340039, 4195332, 1051649, 6291462, 4195332, 3072, 1051649, 3147779, 2099202, 6291462, 3147779, 2099202, 3072, 3147779, 6291462, 5243909, 3147779, 2099202, 5243909, 3147779, 3147779, 5243909, 1051649, 6291462, 4195332, 3072, 5243909, 2099202, 3072, 5243909, 1051649, 6291462, 3147779, 5243909, 2099202, 4195332, 5243909, 3147779, 5243909, 2099202, 3147779, 7340039, 1051649, 6291462, 3072, 1051649, 5243909, 3072, 7340039, 3072, 5243909, 3147779, 6291462, 3072, 6291462, 2099202, 5243909, 4195332, 3072, 3147779, 6291462, 3072, 7340039, 1051649, 5243909, 2099202, 5243909, 3147779, 5243909, 3072, 4195332, 6291462, 3072, 6291462, 3072, 4195332, 5243909, 2099202, 3072, 7340039, 5243909, 3072, 2099202, 7340039, 3072, 5243909, 1051649, 4195332, 6291462, 2099202, 7340039, 1051649, 3147779, 2099202, 6291462, 1051649, + 7340039, 3147779, 6291462, 2099202, 3072, 7340039, 2099202, 3072, 6291462, 1051649, 6291462, 2099202, 4195332, 1051649, 2099202, 6291462, 3147779, 2099202, 3072, 5243909, 5243909, 3147779, 1051649, 7340039, 2099202, 3147779, 6291462, 4195332, 3147779, 6291462, 3147779, 6291462, 2099202, 3147779, 5243909, 3072, 3147779, 7340039, 5243909, 6291462, 5243909, 3072, 4195332, 7340039, 6291462, 2099202, 4195332, 3072, 6291462, 4195332, 6291462, 1051649, 6291462, 3072, 7340039, 3072, 3147779, 7340039, 3147779, 4195332, 6291462, 3147779, 7340039, 2099202, 6291462, 3072, 4195332, 7340039, 1051649, 6291462, 3072, 7340039, 1051649, 5243909, 4195332, 2099202, 4195332, 6291462, 2099202, 6291462, 3147779, 2099202, 7340039, 4195332, 1051649, 4195332, 5243909, 3072, 7340039, 1051649, 6291462, 7340039, 2099202, 5243909, 3147779, 4195332, 2099202, 7340039, 3072, 6291462, 1051649, 3147779, 7340039, 2099202, 3147779, 5243909, 2099202, 7340039, 3147779, 6291462, 3147779, 4195332, 1051649, 7340039, 1051649, 4195332, 6291462, 3147779, 7340039, 3147779, 1051649, 5243909, 3147779, 4195332, 6291462, 1051649, 5243909, 2099202, + 1051649, 5243909, 1051649, 6291462, 3147779, 5243909, 1051649, 5243909, 3147779, 3072, 4195332, 7340039, 3072, 7340039, 5243909, 3072, 7340039, 3147779, 6291462, 2099202, 1051649, 6291462, 4195332, 4195332, 3072, 5243909, 1051649, 1051649, 7340039, 3072, 1051649, 4195332, 7340039, 1051649, 2099202, 6291462, 2099202, 1051649, 3147779, 3072, 1051649, 6291462, 2099202, 1051649, 4195332, 1051649, 5243909, 7340039, 1051649, 2099202, 3072, 7340039, 4195332, 2099202, 3147779, 4195332, 5243909, 1051649, 3072, 7340039, 1051649, 4195332, 3072, 4195332, 2099202, 7340039, 3147779, 1051649, 2099202, 6291462, 4195332, 2099202, 5243909, 3147779, 3072, 7340039, 3147779, 1051649, 3147779, 5243909, 1051649, 4195332, 3072, 6291462, 2099202, 7340039, 2099202, 4195332, 1051649, 5243909, 3147779, 3072, 4195332, 1051649, 7340039, 3072, 6291462, 4195332, 3147779, 2099202, 7340039, 6291462, 1051649, 4195332, 7340039, 2099202, 4195332, 3072, 5243909, 3072, 7340039, 1051649, 4195332, 3147779, 5243909, 2099202, 3072, 2099202, 3072, 6291462, 3147779, 7340039, 2099202, 3072, 7340039, 3147779, 3072, 6291462, + 4195332, 3072, 4195332, 1051649, 3147779, 4195332, 6291462, 2099202, 7340039, 5243909, 3147779, 1051649, 3147779, 5243909, 2099202, 4195332, 1051649, 5243909, 1051649, 4195332, 6291462, 3072, 2099202, 6291462, 2099202, 3147779, 6291462, 4195332, 2099202, 5243909, 6291462, 3147779, 3072, 5243909, 5243909, 4195332, 7340039, 4195332, 6291462, 4195332, 7340039, 3147779, 4195332, 5243909, 3147779, 7340039, 3072, 3147779, 4195332, 7340039, 2099202, 5243909, 1051649, 5243909, 7340039, 1051649, 6291462, 3147779, 5243909, 2099202, 1051649, 6291462, 5243909, 1051649, 3147779, 6291462, 3072, 5243909, 4195332, 3072, 3147779, 6291462, 1051649, 6291462, 2099202, 5243909, 3072, 7340039, 5243909, 3072, 7340039, 3147779, 5243909, 1051649, 4195332, 3072, 6291462, 3147779, 7340039, 2099202, 4195332, 6291462, 3147779, 5243909, 2099202, 4195332, 1051649, 1051649, 5243909, 4195332, 3072, 4195332, 3147779, 5243909, 3072, 6291462, 1051649, 7340039, 3147779, 2099202, 5243909, 2099202, 5243909, 6291462, 3072, 7340039, 5243909, 7340039, 4195332, 5243909, 1051649, 3072, 6291462, 4195332, 1051649, 7340039, 5243909, 2099202, + 7340039, 5243909, 4195332, 7340039, 6291462, 3072, 1051649, 4195332, 1051649, 5243909, 2099202, 6291462, 4195332, 1051649, 7340039, 3147779, 6291462, 3147779, 7340039, 3072, 3147779, 5243909, 7340039, 1051649, 5243909, 7340039, 3072, 7340039, 3147779, 1051649, 4195332, 6291462, 2099202, 7340039, 2099202, 3072, 3147779, 3072, 2099202, 5243909, 1051649, 5243909, 3072, 7340039, 3072, 3147779, 6291462, 1051649, 6291462, 1051649, 3147779, 4195332, 6291462, 3072, 2099202, 4195332, 2099202, 6291462, 3072, 5243909, 7340039, 2099202, 3147779, 7340039, 5243909, 1051649, 3147779, 6291462, 2099202, 7340039, 1051649, 3147779, 4195332, 1051649, 7340039, 1051649, 5243909, 2099202, 2099202, 5243909, 4195332, 1051649, 3147779, 7340039, 5243909, 3147779, 6291462, 3072, 3147779, 7340039, 3072, 1051649, 6291462, 3072, 7340039, 3147779, 6291462, 3147779, 7340039, 1051649, 7340039, 3072, 6291462, 1051649, 5243909, 2099202, 3147779, 5243909, 1051649, 7340039, 1051649, 6291462, 3072, 2099202, 4195332, 4195332, 1051649, 1051649, 3147779, 2099202, 5243909, 4195332, 2099202, 5243909, 3147779, 1051649, 4195332, 2099202, + 3072, 3147779, 2099202, 3072, 2099202, 6291462, 5243909, 7340039, 2099202, 3072, 7340039, 1051649, 6291462, 2099202, 4195332, 3072, 2099202, 3072, 5243909, 2099202, 6291462, 1051649, 3147779, 4195332, 3072, 2099202, 5243909, 1051649, 5243909, 7340039, 2099202, 3072, 5243909, 1051649, 4195332, 6291462, 3147779, 5243909, 7340039, 2099202, 6291462, 3147779, 2099202, 5243909, 2099202, 5243909, 4195332, 3072, 5243909, 3147779, 7340039, 3072, 2099202, 5243909, 7340039, 3072, 5243909, 1051649, 6291462, 4195332, 3072, 4195332, 5243909, 3072, 2099202, 6291462, 4195332, 3072, 5243909, 4195332, 5243909, 7340039, 3072, 6291462, 4195332, 3147779, 6291462, 4195332, 6291462, 1051649, 6291462, 2099202, 6291462, 3072, 2099202, 3147779, 1051649, 4195332, 6291462, 2099202, 5243909, 3147779, 5243909, 2099202, 4195332, 3072, 2099202, 5243909, 1051649, 4195332, 2099202, 6291462, 2099202, 4195332, 3072, 7340039, 4195332, 3072, 6291462, 4195332, 6291462, 4195332, 3147779, 7340039, 1051649, 6291462, 3147779, 6291462, 7340039, 3072, 7340039, 3147779, 6291462, 3072, 7340039, 3072, 5243909, 7340039, + 1051649, 6291462, 5243909, 5243909, 7340039, 3147779, 3072, 2099202, 4195332, 6291462, 4195332, 3147779, 5243909, 3072, 5243909, 7340039, 5243909, 6291462, 4195332, 7340039, 3147779, 3072, 5243909, 5243909, 7340039, 4195332, 2099202, 6291462, 3147779, 3072, 4195332, 7340039, 3147779, 6291462, 2099202, 1051649, 5243909, 1051649, 3072, 4195332, 3072, 6291462, 1051649, 7340039, 3147779, 1051649, 6291462, 2099202, 7340039, 1051649, 2099202, 4195332, 6291462, 1051649, 3147779, 4195332, 7340039, 3147779, 2099202, 7340039, 1051649, 7340039, 1051649, 6291462, 3147779, 7340039, 1051649, 7340039, 3147779, 1051649, 5243909, 2099202, 2099202, 4195332, 6291462, 3072, 3147779, 3072, 3147779, 3072, 3147779, 5243909, 4195332, 2099202, 6291462, 7340039, 5243909, 3072, 4195332, 1051649, 3147779, 7340039, 1051649, 6291462, 2099202, 6291462, 5243909, 3072, 6291462, 5243909, 3072, 3147779, 5243909, 7340039, 3147779, 2099202, 6291462, 2099202, 3147779, 1051649, 2099202, 3072, 7340039, 3147779, 5243909, 2099202, 3072, 4195332, 2099202, 4195332, 3147779, 1051649, 5243909, 2099202, 4195332, 6291462, 2099202, 2099202, + 6291462, 4195332, 3072, 3147779, 1051649, 4195332, 7340039, 5243909, 3147779, 3072, 7340039, 3072, 3147779, 6291462, 2099202, 1051649, 1051649, 4195332, 2099202, 1051649, 4195332, 7340039, 2099202, 1051649, 1051649, 3147779, 6291462, 3072, 5243909, 6291462, 2099202, 1051649, 4195332, 3072, 6291462, 7340039, 3147779, 6291462, 4195332, 7340039, 3147779, 2099202, 6291462, 3072, 4195332, 7340039, 3147779, 3072, 4195332, 6291462, 5243909, 3072, 7340039, 4195332, 6291462, 1051649, 2099202, 6291462, 3072, 3147779, 5243909, 3147779, 4195332, 2099202, 3072, 4195332, 2099202, 5243909, 1051649, 7340039, 3072, 4195332, 7340039, 1051649, 1051649, 7340039, 2099202, 6291462, 7340039, 4195332, 7340039, 1051649, 3072, 7340039, 1051649, 4195332, 2099202, 7340039, 5243909, 3147779, 6291462, 1051649, 4195332, 3072, 7340039, 3147779, 1051649, 4195332, 3147779, 2099202, 7340039, 5243909, 1051649, 1051649, 6291462, 4195332, 3072, 5243909, 7340039, 3147779, 5243909, 4195332, 1051649, 5243909, 3072, 6291462, 3147779, 5243909, 1051649, 6291462, 1051649, 7340039, 3147779, 5243909, 4195332, 3072, 6291462, 3147779, + 1051649, 4195332, 1051649, 7340039, 6291462, 4195332, 3072, 2099202, 6291462, 1051649, 5243909, 2099202, 5243909, 2099202, 4195332, 7340039, 3147779, 7340039, 3072, 5243909, 6291462, 3072, 4195332, 6291462, 6291462, 3072, 7340039, 4195332, 2099202, 1051649, 7340039, 3147779, 7340039, 2099202, 4195332, 3072, 5243909, 2099202, 3147779, 1051649, 5243909, 4195332, 3147779, 6291462, 2099202, 1051649, 5243909, 7340039, 3147779, 3072, 2099202, 5243909, 2099202, 3147779, 3072, 5243909, 2099202, 4195332, 5243909, 1051649, 6291462, 1051649, 6291462, 3147779, 7340039, 4195332, 6291462, 3072, 4195332, 3147779, 6291462, 2099202, 3147779, 5243909, 2099202, 4195332, 5243909, 2099202, 1051649, 4195332, 2099202, 6291462, 5243909, 3147779, 5243909, 3072, 5243909, 2099202, 1051649, 6291462, 3072, 5243909, 3147779, 5243909, 2099202, 5243909, 7340039, 2099202, 6291462, 1051649, 3147779, 3072, 7340039, 4195332, 5243909, 2099202, 7340039, 4195332, 1051649, 6291462, 3072, 6291462, 3147779, 2099202, 7340039, 2099202, 6291462, 1051649, 7340039, 3072, 4195332, 5243909, 2099202, 3072, 7340039, 3147779, 1051649, 5243909, + 7340039, 3147779, 5243909, 3147779, 1051649, 2099202, 6291462, 1051649, 7340039, 3147779, 4195332, 7340039, 3072, 6291462, 3147779, 3072, 6291462, 2099202, 4195332, 1051649, 3147779, 3147779, 5243909, 2099202, 3147779, 4195332, 1051649, 3147779, 7340039, 5243909, 1051649, 4195332, 3072, 5243909, 1051649, 4195332, 7340039, 3072, 6291462, 7340039, 3072, 7340039, 1051649, 4195332, 7340039, 2099202, 4195332, 1051649, 6291462, 3147779, 7340039, 1051649, 6291462, 6291462, 4195332, 3147779, 7340039, 3072, 7340039, 3147779, 2099202, 7340039, 4195332, 3072, 5243909, 1051649, 2099202, 5243909, 3072, 7340039, 1051649, 5243909, 3072, 6291462, 4195332, 3072, 7340039, 3147779, 5243909, 6291462, 3072, 4195332, 2099202, 1051649, 7340039, 2099202, 4195332, 7340039, 3072, 3147779, 4195332, 2099202, 7340039, 1051649, 4195332, 3072, 6291462, 3072, 7340039, 4195332, 6291462, 2099202, 4195332, 2099202, 3072, 6291462, 1051649, 5243909, 3072, 2099202, 5243909, 1051649, 7340039, 4195332, 1051649, 5243909, 3072, 4195332, 3147779, 3147779, 7340039, 3072, 4195332, 6291462, 2099202, 5243909, 7340039, 2099202, + 3072, 6291462, 3072, 4195332, 5243909, 7340039, 2099202, 5243909, 4195332, 1051649, 6291462, 1051649, 4195332, 1051649, 2099202, 5243909, 2099202, 5243909, 3147779, 7340039, 6291462, 1051649, 7340039, 3072, 6291462, 2099202, 5243909, 6291462, 3072, 3147779, 5243909, 2099202, 6291462, 3147779, 7340039, 1051649, 6291462, 2099202, 4195332, 3147779, 2099202, 5243909, 1051649, 5243909, 3072, 5243909, 4195332, 3072, 5243909, 2099202, 4195332, 3147779, 2099202, 3072, 1051649, 6291462, 3147779, 4195332, 2099202, 5243909, 3072, 5243909, 1051649, 7340039, 2099202, 6291462, 3147779, 2099202, 6291462, 3147779, 3147779, 4195332, 7340039, 1051649, 6291462, 3147779, 1051649, 6291462, 3072, 2099202, 4195332, 7340039, 3072, 6291462, 3147779, 5243909, 1051649, 4195332, 6291462, 2099202, 7340039, 4195332, 3072, 7340039, 6291462, 2099202, 4195332, 3147779, 1051649, 4195332, 3072, 3147779, 6291462, 1051649, 6291462, 3147779, 3147779, 7340039, 4195332, 5243909, 1051649, 6291462, 4195332, 3072, 5243909, 3147779, 7340039, 2099202, 6291462, 1051649, 5243909, 2099202, 6291462, 1051649, 4195332, 3072, 3147779, 4195332, + 5243909, 2099202, 7340039, 2099202, 1051649, 4195332, 3147779, 3072, 3147779, 7340039, 3072, 5243909, 3147779, 7340039, 6291462, 3072, 7340039, 4195332, 3072, 2099202, 4195332, 2099202, 4195332, 5243909, 7340039, 3072, 4195332, 2099202, 5243909, 2099202, 7340039, 3072, 3147779, 5243909, 3072, 4195332, 3147779, 5243909, 1051649, 5243909, 1051649, 3147779, 6291462, 2099202, 6291462, 3147779, 3147779, 6291462, 1051649, 7340039, 3072, 6291462, 3147779, 7340039, 5243909, 3072, 6291462, 1051649, 4195332, 1051649, 6291462, 4195332, 2099202, 3147779, 5243909, 3072, 7340039, 5243909, 1051649, 6291462, 3072, 6291462, 3072, 4195332, 2099202, 5243909, 7340039, 4195332, 2099202, 7340039, 1051649, 2099202, 5243909, 4195332, 3072, 2099202, 7340039, 3072, 5243909, 1051649, 1051649, 3147779, 5243909, 1051649, 3147779, 5243909, 1051649, 6291462, 5243909, 2099202, 5243909, 7340039, 1051649, 5243909, 4195332, 1051649, 5243909, 3072, 2099202, 7340039, 2099202, 3147779, 3072, 6291462, 3147779, 6291462, 1051649, 5243909, 3072, 6291462, 2099202, 7340039, 1051649, 3147779, 6291462, 3147779, 7340039, 2099202, + 1051649, 4195332, 3147779, 6291462, 4195332, 3072, 7340039, 5243909, 2099202, 6291462, 2099202, 5243909, 1051649, 4195332, 1051649, 5243909, 3147779, 1051649, 7340039, 6291462, 3072, 7340039, 3072, 1051649, 3147779, 3147779, 6291462, 1051649, 7340039, 4195332, 4195332, 2099202, 6291462, 1051649, 7340039, 4195332, 3072, 7340039, 2099202, 4195332, 7340039, 5243909, 3072, 4195332, 1051649, 7340039, 3072, 7340039, 4195332, 2099202, 5243909, 1051649, 4195332, 3072, 4195332, 3147779, 1051649, 7340039, 2099202, 7340039, 3147779, 3072, 6291462, 1051649, 6291462, 2099202, 4195332, 3072, 4195332, 2099202, 5243909, 2099202, 5243909, 3147779, 7340039, 3072, 3147779, 1051649, 4195332, 5243909, 3147779, 6291462, 3147779, 1051649, 7340039, 5243909, 3147779, 6291462, 3147779, 6291462, 5243909, 2099202, 6291462, 2099202, 4195332, 3072, 7340039, 3147779, 1051649, 7340039, 3072, 3147779, 4195332, 3072, 3147779, 7340039, 2099202, 6291462, 3147779, 3072, 7340039, 4195332, 3147779, 7340039, 1051649, 2099202, 4195332, 2099202, 7340039, 1051649, 4195332, 3072, 4195332, 6291462, 1051649, 5243909, 3072, 6291462, + 5243909, 1051649, 6291462, 3072, 3147779, 7340039, 1051649, 4195332, 1051649, 3147779, 6291462, 2099202, 7340039, 3072, 3147779, 6291462, 3072, 6291462, 3147779, 2099202, 3147779, 4195332, 6291462, 5243909, 3072, 7340039, 1051649, 4195332, 3072, 6291462, 1051649, 5243909, 3072, 5243909, 2099202, 3147779, 6291462, 2099202, 6291462, 3072, 2099202, 3147779, 7340039, 4195332, 1051649, 5243909, 2099202, 4195332, 3072, 6291462, 1051649, 7340039, 2099202, 5243909, 2099202, 7340039, 5243909, 3147779, 4195332, 3072, 6291462, 1051649, 4195332, 5243909, 3072, 6291462, 3147779, 7340039, 1051649, 7340039, 2099202, 7340039, 1051649, 2099202, 5243909, 1051649, 6291462, 6291462, 3072, 5243909, 3072, 7340039, 3072, 6291462, 3147779, 6291462, 1051649, 2099202, 4195332, 3072, 4195332, 7340039, 3072, 5243909, 7340039, 3147779, 3072, 5243909, 3147779, 2099202, 6291462, 4195332, 7340039, 2099202, 6291462, 3072, 5243909, 1051649, 6291462, 4195332, 2099202, 5243909, 3072, 5243909, 4195332, 7340039, 3072, 6291462, 3147779, 3147779, 7340039, 5243909, 3147779, 3072, 7340039, 1051649, 4195332, 3147779, + 3072, 7340039, 2099202, 5243909, 5243909, 2099202, 6291462, 2099202, 7340039, 4195332, 3072, 5243909, 3147779, 4195332, 6291462, 2099202, 5243909, 4195332, 1051649, 5243909, 6291462, 1051649, 2099202, 4195332, 4195332, 2099202, 6291462, 3147779, 6291462, 3147779, 2099202, 7340039, 3147779, 4195332, 1051649, 6291462, 3072, 4195332, 3147779, 5243909, 6291462, 3072, 2099202, 6291462, 3147779, 7340039, 1051649, 5243909, 3147779, 5243909, 4195332, 3147779, 7340039, 3072, 6291462, 2099202, 3072, 6291462, 2099202, 5243909, 4195332, 3147779, 7340039, 2099202, 7340039, 2099202, 5243909, 1051649, 4195332, 5243909, 3072, 3147779, 4195332, 7340039, 3072, 3147779, 4195332, 2099202, 7340039, 3147779, 1051649, 5243909, 2099202, 4195332, 1051649, 3072, 4195332, 7340039, 2099202, 7340039, 3147779, 1051649, 6291462, 3147779, 1051649, 7340039, 5243909, 2099202, 4195332, 7340039, 4195332, 3072, 2099202, 5243909, 1051649, 4195332, 7340039, 3147779, 3072, 6291462, 3147779, 1051649, 7340039, 2099202, 3072, 5243909, 4195332, 1051649, 5243909, 3072, 3147779, 2099202, 5243909, 4195332, 2099202, 6291462, 2099202, 7340039, + 5243909, 3147779, 1051649, 7340039, 3072, 4195332, 3072, 5243909, 3072, 5243909, 1051649, 7340039, 3072, 5243909, 1051649, 2099202, 7340039, 1051649, 7340039, 3147779, 3072, 5243909, 7340039, 3072, 7340039, 1051649, 5243909, 2099202, 1051649, 5243909, 1051649, 3072, 6291462, 2099202, 7340039, 3147779, 6291462, 1051649, 7340039, 1051649, 1051649, 7340039, 5243909, 3072, 2099202, 4195332, 6291462, 1051649, 6291462, 3072, 2099202, 6291462, 1051649, 4195332, 1051649, 4195332, 7340039, 1051649, 2099202, 7340039, 1051649, 5243909, 3072, 3147779, 4195332, 1051649, 3147779, 6291462, 2099202, 4195332, 3147779, 6291462, 3072, 3147779, 6291462, 5243909, 3072, 4195332, 1051649, 6291462, 4195332, 6291462, 1051649, 3147779, 5243909, 7340039, 3147779, 3072, 5243909, 1051649, 4195332, 6291462, 2099202, 4195332, 3072, 2099202, 4195332, 1051649, 6291462, 3072, 1051649, 5243909, 6291462, 3147779, 7340039, 3147779, 2099202, 6291462, 4195332, 2099202, 7340039, 3147779, 4195332, 6291462, 4195332, 2099202, 3147779, 6291462, 3072, 6291462, 4195332, 7340039, 1051649, 6291462, 3072, 5243909, 2099202, 4195332, + 3147779, 3072, 6291462, 1051649, 3147779, 5243909, 6291462, 3147779, 7340039, 3147779, 6291462, 2099202, 4195332, 2099202, 7340039, 3147779, 3072, 5243909, 3147779, 6291462, 2099202, 4195332, 1051649, 3147779, 5243909, 4195332, 3072, 6291462, 3147779, 7340039, 4195332, 6291462, 3147779, 5243909, 3072, 5243909, 1051649, 4195332, 2099202, 4195332, 5243909, 3147779, 1051649, 6291462, 6291462, 3072, 2099202, 5243909, 3147779, 7340039, 4195332, 3072, 7340039, 3147779, 2099202, 5243909, 3147779, 5243909, 6291462, 3072, 3147779, 5243909, 6291462, 1051649, 5243909, 3147779, 7340039, 3072, 6291462, 2099202, 7340039, 1051649, 5243909, 2099202, 1051649, 7340039, 2099202, 7340039, 2099202, 5243909, 3072, 3147779, 7340039, 6291462, 3072, 2099202, 5243909, 6291462, 2099202, 4195332, 5243909, 3072, 3147779, 7340039, 5243909, 6291462, 1051649, 7340039, 2099202, 5243909, 7340039, 3147779, 3072, 6291462, 3072, 5243909, 1051649, 5243909, 3072, 6291462, 1051649, 6291462, 1051649, 3072, 6291462, 1051649, 7340039, 4195332, 2099202, 5243909, 1051649, 3072, 5243909, 2099202, 6291462, 3147779, 7340039, 1051649, + 5243909, 7340039, 3147779, 4195332, 6291462, 2099202, 1051649, 4195332, 2099202, 5243909, 3072, 4195332, 6291462, 6291462, 1051649, 4195332, 6291462, 2099202, 1051649, 3072, 7340039, 3147779, 5243909, 7340039, 2099202, 2099202, 6291462, 1051649, 5243909, 3072, 3147779, 1051649, 6291462, 2099202, 2099202, 7340039, 3147779, 3072, 5243909, 6291462, 3072, 7340039, 4195332, 2099202, 4195332, 3147779, 7340039, 2099202, 6291462, 1051649, 3147779, 5243909, 1051649, 5243909, 6291462, 3072, 7340039, 3072, 4195332, 6291462, 4195332, 2099202, 2099202, 7340039, 3072, 6291462, 1051649, 4195332, 5243909, 3072, 5243909, 1051649, 4195332, 6291462, 4195332, 2099202, 3147779, 5243909, 3072, 3147779, 7340039, 2099202, 4195332, 2099202, 6291462, 4195332, 1051649, 1051649, 7340039, 3072, 6291462, 2099202, 6291462, 1051649, 2099202, 3072, 6291462, 4195332, 3147779, 1051649, 4195332, 2099202, 4195332, 2099202, 4195332, 2099202, 7340039, 1051649, 3147779, 5243909, 4195332, 2099202, 5243909, 5243909, 3147779, 5243909, 2099202, 3072, 7340039, 3147779, 6291462, 4195332, 3147779, 7340039, 1051649, 4195332, 3072, 6291462, + 2099202, 4195332, 1051649, 7340039, 3072, 6291462, 3147779, 7340039, 3072, 3147779, 7340039, 1051649, 3072, 3147779, 5243909, 3072, 4195332, 6291462, 7340039, 4195332, 5243909, 1051649, 4195332, 3072, 3147779, 7340039, 4195332, 7340039, 2099202, 7340039, 4195332, 5243909, 3072, 7340039, 4195332, 3072, 5243909, 7340039, 3147779, 2099202, 5243909, 3147779, 1051649, 6291462, 3072, 4195332, 3072, 5243909, 3072, 4195332, 6291462, 2099202, 7340039, 2099202, 1051649, 5243909, 3147779, 2099202, 5243909, 1051649, 3072, 7340039, 1051649, 4195332, 4195332, 2099202, 7340039, 3147779, 1051649, 6291462, 3147779, 7340039, 3147779, 3072, 7340039, 1051649, 6291462, 4195332, 1051649, 6291462, 1051649, 5243909, 3072, 5243909, 1051649, 3147779, 7340039, 5243909, 3147779, 4195332, 2099202, 5243909, 1051649, 7340039, 4195332, 5243909, 3147779, 3072, 5243909, 6291462, 3072, 7340039, 1051649, 6291462, 7340039, 1051649, 3147779, 7340039, 4195332, 2099202, 3072, 7340039, 3147779, 2099202, 7340039, 1051649, 5243909, 3147779, 5243909, 1051649, 2099202, 6291462, 2099202, 3072, 4195332, 3147779, 7340039, 2099202, + 1051649, 5243909, 3147779, 2099202, 5243909, 4195332, 3072, 6291462, 2099202, 5243909, 1051649, 5243909, 3147779, 7340039, 2099202, 7340039, 3147779, 1051649, 3072, 3147779, 6291462, 1051649, 2099202, 6291462, 5243909, 3072, 3147779, 3072, 5243909, 1051649, 6291462, 1051649, 4195332, 3147779, 2099202, 6291462, 1051649, 4195332, 3072, 7340039, 1051649, 2099202, 5243909, 3147779, 7340039, 1051649, 6291462, 3147779, 7340039, 1051649, 2099202, 3072, 4195332, 6291462, 3147779, 4195332, 3072, 7340039, 1051649, 3147779, 6291462, 5243909, 3147779, 6291462, 1051649, 6291462, 3072, 4195332, 7340039, 4195332, 1051649, 4195332, 6291462, 2099202, 5243909, 3147779, 3072, 4195332, 7340039, 3147779, 6291462, 4195332, 7340039, 2099202, 4195332, 6291462, 3072, 2099202, 6291462, 3072, 7340039, 3147779, 5243909, 2099202, 4195332, 1051649, 6291462, 2099202, 7340039, 2099202, 5243909, 4195332, 3147779, 5243909, 3072, 4195332, 6291462, 3072, 1051649, 5243909, 7340039, 3147779, 3072, 6291462, 3072, 4195332, 6291462, 2099202, 7340039, 4195332, 7340039, 3072, 5243909, 7340039, 1051649, 6291462, 3072, 5243909, + 4195332, 3072, 6291462, 2099202, 7340039, 1051649, 2099202, 6291462, 3147779, 1051649, 7340039, 3147779, 6291462, 1051649, 5243909, 1051649, 6291462, 5243909, 5243909, 2099202, 3072, 4195332, 7340039, 1051649, 6291462, 2099202, 6291462, 4195332, 3147779, 3072, 3147779, 5243909, 2099202, 7340039, 1051649, 3147779, 6291462, 2099202, 6291462, 3147779, 4195332, 7340039, 4195332, 1051649, 5243909, 3147779, 5243909, 1051649, 4195332, 5243909, 7340039, 3147779, 5243909, 3072, 7340039, 2099202, 6291462, 3147779, 6291462, 4195332, 3147779, 3072, 7340039, 2099202, 5243909, 3147779, 2099202, 5243909, 3072, 2099202, 6291462, 3072, 1051649, 6291462, 2099202, 7340039, 5243909, 2099202, 3072, 5243909, 1051649, 3072, 3147779, 6291462, 1051649, 3147779, 5243909, 3147779, 5243909, 3147779, 1051649, 6291462, 3072, 5243909, 3072, 7340039, 3147779, 5243909, 1051649, 3147779, 1051649, 3072, 6291462, 2099202, 3147779, 5243909, 2099202, 4195332, 6291462, 4195332, 1051649, 5243909, 6291462, 1051649, 7340039, 2099202, 3072, 4195332, 3072, 1051649, 5243909, 3147779, 1051649, 4195332, 5243909, 2099202, 3147779, 6291462, + 7340039, 4195332, 1051649, 4195332, 3072, 5243909, 4195332, 1051649, 7340039, 4195332, 4195332, 3072, 4195332, 2099202, 6291462, 3072, 3147779, 2099202, 4195332, 7340039, 4195332, 6291462, 3072, 3147779, 4195332, 3072, 5243909, 1051649, 2099202, 6291462, 7340039, 3072, 6291462, 3072, 4195332, 6291462, 3072, 5243909, 1051649, 5243909, 3072, 5243909, 2099202, 6291462, 3072, 7340039, 2099202, 7340039, 2099202, 3072, 4195332, 2099202, 6291462, 1051649, 4195332, 1051649, 5243909, 2099202, 3072, 7340039, 2099202, 5243909, 1051649, 4195332, 3072, 7340039, 1051649, 6291462, 3147779, 7340039, 2099202, 5243909, 7340039, 3147779, 3072, 4195332, 1051649, 6291462, 7340039, 3147779, 5243909, 4195332, 5243909, 1051649, 7340039, 2099202, 7340039, 3072, 4195332, 1051649, 7340039, 4195332, 2099202, 6291462, 4195332, 2099202, 3072, 7340039, 2099202, 6291462, 4195332, 7340039, 3147779, 6291462, 3072, 1051649, 7340039, 3147779, 3072, 7340039, 2099202, 1051649, 4195332, 3147779, 4195332, 6291462, 3147779, 6291462, 2099202, 6291462, 3147779, 4195332, 1051649, 7340039, 3072, 4195332, 7340039, 1051649, + 2099202, 3147779, 5243909, 6291462, 3147779, 7340039, 1051649, 6291462, 3072, 2099202, 1051649, 5243909, 7340039, 4195332, 2099202, 4195332, 7340039, 3072, 6291462, 1051649, 2099202, 3147779, 7340039, 5243909, 2099202, 7340039, 3147779, 7340039, 5243909, 1051649, 4195332, 2099202, 4195332, 5243909, 2099202, 7340039, 3147779, 4195332, 1051649, 6291462, 3147779, 3072, 7340039, 2099202, 4195332, 3072, 5243909, 1051649, 6291462, 3147779, 6291462, 1051649, 4195332, 3147779, 6291462, 7340039, 2099202, 6291462, 5243909, 1051649, 4195332, 7340039, 2099202, 6291462, 3147779, 4195332, 5243909, 2099202, 4195332, 3072, 5243909, 3147779, 3072, 4195332, 3147779, 6291462, 2099202, 4195332, 2099202, 3072, 7340039, 1051649, 2099202, 6291462, 3147779, 3072, 4195332, 1051649, 7340039, 5243909, 2099202, 1051649, 7340039, 1051649, 7340039, 3147779, 6291462, 4195332, 4195332, 3072, 6291462, 3072, 5243909, 1051649, 7340039, 4195332, 1051649, 6291462, 3147779, 2099202, 6291462, 3147779, 5243909, 3072, 5243909, 1051649, 3072, 7340039, 3147779, 6291462, 3072, 7340039, 5243909, 2099202, 6291462, 3147779, 1051649, 5243909, + 3072, 7340039, 2099202, 3072, 3147779, 2099202, 4195332, 3147779, 6291462, 5243909, 6291462, 3147779, 2099202, 3072, 7340039, 3147779, 1051649, 5243909, 3147779, 5243909, 6291462, 2099202, 1051649, 5243909, 1051649, 4195332, 1051649, 4195332, 2099202, 7340039, 3147779, 7340039, 1051649, 3147779, 5243909, 1051649, 2099202, 7340039, 3147779, 2099202, 7340039, 4195332, 1051649, 5243909, 6291462, 3147779, 4195332, 4195332, 3072, 3147779, 7340039, 2099202, 7340039, 3072, 2099202, 4195332, 1051649, 4195332, 3072, 6291462, 3147779, 3072, 3147779, 5243909, 1051649, 7340039, 3072, 3147779, 6291462, 2099202, 1051649, 5243909, 7340039, 2099202, 5243909, 3072, 6291462, 3072, 5243909, 3147779, 2099202, 7340039, 5243909, 3072, 4195332, 6291462, 3147779, 6291462, 2099202, 3072, 6291462, 4195332, 3147779, 3147779, 3072, 5243909, 1051649, 1051649, 5243909, 2099202, 3147779, 5243909, 2099202, 3147779, 5243909, 2099202, 5243909, 3072, 4195332, 5243909, 3072, 7340039, 1051649, 6291462, 2099202, 7340039, 2099202, 5243909, 1051649, 1051649, 5243909, 2099202, 1051649, 4195332, 3072, 5243909, 3147779, 6291462, + 4195332, 1051649, 6291462, 4195332, 5243909, 6291462, 3072, 5243909, 2099202, 1051649, 4195332, 3072, 6291462, 5243909, 1051649, 4195332, 7340039, 2099202, 4195332, 3072, 4195332, 3072, 7340039, 3147779, 6291462, 2099202, 6291462, 3072, 6291462, 4195332, 3072, 5243909, 6291462, 3072, 5243909, 3147779, 5243909, 3072, 6291462, 5243909, 1051649, 6291462, 3147779, 2099202, 3072, 7340039, 1051649, 3147779, 6291462, 4195332, 3072, 5243909, 3147779, 5243909, 1051649, 7340039, 3147779, 6291462, 3147779, 4195332, 1051649, 7340039, 5243909, 3072, 4195332, 1051649, 5243909, 7340039, 3072, 4195332, 6291462, 3147779, 1051649, 3147779, 7340039, 2099202, 5243909, 7340039, 1051649, 6291462, 4195332, 3072, 4195332, 1051649, 7340039, 2099202, 3072, 3147779, 5243909, 4195332, 3147779, 1051649, 6291462, 5243909, 2099202, 7340039, 3147779, 6291462, 2099202, 7340039, 4195332, 3072, 7340039, 6291462, 3072, 7340039, 2099202, 3147779, 7340039, 1051649, 6291462, 2099202, 4195332, 2099202, 5243909, 1051649, 4195332, 3147779, 7340039, 5243909, 3147779, 3147779, 6291462, 2099202, 6291462, 1051649, 7340039, 2099202, + 3147779, 7340039, 2099202, 7340039, 3072, 2099202, 4195332, 1051649, 7340039, 3072, 7340039, 5243909, 1051649, 3147779, 6291462, 3072, 4195332, 6291462, 1051649, 7340039, 2099202, 5243909, 4195332, 3147779, 3072, 6291462, 3147779, 5243909, 1051649, 2099202, 5243909, 1051649, 2099202, 6291462, 1051649, 7340039, 2099202, 4195332, 1051649, 4195332, 2099202, 3072, 5243909, 7340039, 3147779, 5243909, 2099202, 6291462, 2099202, 5243909, 2099202, 6291462, 1051649, 4195332, 5243909, 3072, 5243909, 2099202, 3072, 6291462, 2099202, 5243909, 2099202, 7340039, 3147779, 6291462, 1051649, 4195332, 5243909, 1051649, 6291462, 3072, 7340039, 4195332, 1051649, 4195332, 1051649, 3147779, 4195332, 2099202, 3147779, 7340039, 3147779, 6291462, 2099202, 5243909, 7340039, 1051649, 6291462, 3072, 7340039, 6291462, 3072, 1051649, 5243909, 3072, 4195332, 3072, 5243909, 1051649, 6291462, 3147779, 4195332, 1051649, 4195332, 1051649, 6291462, 5243909, 3072, 4195332, 3147779, 5243909, 3072, 4195332, 7340039, 3147779, 5243909, 3072, 4195332, 1051649, 7340039, 5243909, 3072, 7340039, 3147779, 5243909, 3072, 4195332, + 3072, 5243909, 1051649, 3147779, 4195332, 7340039, 3147779, 5243909, 2099202, 6291462, 3147779, 2099202, 7340039, 2099202, 2099202, 5243909, 3147779, 3072, 5243909, 2099202, 6291462, 1051649, 1051649, 6291462, 5243909, 1051649, 7340039, 3072, 4195332, 7340039, 2099202, 7340039, 3147779, 6291462, 4195332, 3072, 6291462, 2099202, 7340039, 3072, 7340039, 4195332, 2099202, 4195332, 1051649, 3147779, 6291462, 3072, 4195332, 7340039, 3072, 3147779, 7340039, 3072, 3147779, 6291462, 1051649, 7340039, 5243909, 2099202, 7340039, 3072, 4195332, 2099202, 6291462, 3072, 7340039, 2099202, 2099202, 7340039, 2099202, 3147779, 5243909, 1051649, 6291462, 5243909, 3147779, 6291462, 3072, 6291462, 5243909, 3072, 4195332, 1051649, 4195332, 3072, 4195332, 7340039, 2099202, 5243909, 2099202, 4195332, 3147779, 7340039, 3147779, 6291462, 2099202, 7340039, 4195332, 3147779, 1051649, 3072, 6291462, 2099202, 7340039, 5243909, 3147779, 1051649, 3147779, 7340039, 1051649, 7340039, 6291462, 2099202, 3072, 6291462, 1051649, 6291462, 2099202, 6291462, 3072, 2099202, 4195332, 1051649, 4195332, 7340039, 2099202, 6291462, + 6291462, 3147779, 5243909, 6291462, 1051649, 6291462, 1051649, 7340039, 4195332, 3072, 4195332, 5243909, 3072, 4195332, 6291462, 1051649, 7340039, 3147779, 7340039, 3072, 3147779, 7340039, 6291462, 1051649, 3147779, 4195332, 2099202, 5243909, 3147779, 4195332, 1051649, 4195332, 3072, 2099202, 3147779, 7340039, 1051649, 4195332, 3147779, 5243909, 2099202, 6291462, 3072, 7340039, 1051649, 7340039, 3072, 5243909, 1051649, 4195332, 1051649, 6291462, 5243909, 2099202, 7340039, 4195332, 3147779, 4195332, 1051649, 6291462, 3147779, 1051649, 6291462, 1051649, 3147779, 5243909, 2099202, 4195332, 6291462, 1051649, 4195332, 7340039, 3072, 4195332, 2099202, 3072, 7340039, 1051649, 5243909, 2099202, 1051649, 5243909, 6291462, 2099202, 7340039, 3147779, 5243909, 3072, 4195332, 3147779, 1051649, 7340039, 5243909, 3072, 4195332, 1051649, 4195332, 2099202, 3072, 6291462, 5243909, 7340039, 2099202, 4195332, 2099202, 3072, 3147779, 7340039, 5243909, 2099202, 5243909, 3147779, 1051649, 7340039, 4195332, 3147779, 2099202, 4195332, 3147779, 4195332, 2099202, 6291462, 5243909, 2099202, 6291462, 3072, 4195332, 1051649, + 1051649, 4195332, 3072, 2099202, 5243909, 3072, 3147779, 3072, 4195332, 7340039, 3147779, 1051649, 7340039, 3147779, 5243909, 2099202, 5243909, 1051649, 4195332, 5243909, 4195332, 3072, 2099202, 7340039, 5243909, 3072, 6291462, 1051649, 7340039, 3072, 6291462, 3147779, 5243909, 3147779, 5243909, 3072, 5243909, 6291462, 3072, 6291462, 1051649, 3147779, 5243909, 3147779, 6291462, 2099202, 5243909, 4195332, 7340039, 2099202, 5243909, 3147779, 1051649, 5243909, 3072, 2099202, 6291462, 3072, 7340039, 3072, 4195332, 5243909, 3147779, 5243909, 1051649, 6291462, 3072, 6291462, 3072, 5243909, 3072, 3147779, 6291462, 2099202, 7340039, 4195332, 2099202, 7340039, 4195332, 2099202, 7340039, 3147779, 1051649, 6291462, 1051649, 5243909, 1051649, 6291462, 2099202, 6291462, 4195332, 1051649, 2099202, 6291462, 2099202, 7340039, 5243909, 3147779, 5243909, 2099202, 4195332, 1051649, 5243909, 3072, 6291462, 4195332, 6291462, 3072, 2099202, 6291462, 3072, 4195332, 4195332, 1051649, 5243909, 3072, 7340039, 1051649, 7340039, 3072, 7340039, 3147779, 3072, 7340039, 1051649, 5243909, 2099202, 7340039, + 1051649, 5243909, 7340039, 2099202, 6291462, 3147779, 6291462, 5243909, 2099202, 5243909, 3072, 6291462, 3147779, 3072, 1051649, 6291462, 3072, 6291462, 3147779, 1051649, 7340039, 2099202, 4195332, 3072, 2099202, 7340039, 4195332, 3147779, 1051649, 6291462, 2099202, 7340039, 3072, 7340039, 1051649, 6291462, 3147779, 2099202, 4195332, 3147779, 6291462, 1051649, 1051649, 4195332, 1051649, 3147779, 7340039, 2099202, 3072, 6291462, 1051649, 7340039, 2099202, 7340039, 3147779, 5243909, 2099202, 5243909, 3147779, 2099202, 7340039, 3072, 4195332, 7340039, 3072, 4195332, 3147779, 4195332, 2099202, 7340039, 5243909, 1051649, 6291462, 3147779, 1051649, 5243909, 3147779, 3072, 3147779, 6291462, 3072, 6291462, 5243909, 3147779, 4195332, 3072, 7340039, 3147779, 6291462, 3072, 3147779, 6291462, 4195332, 3072, 5243909, 1051649, 3072, 7340039, 1051649, 7340039, 3072, 6291462, 3147779, 4195332, 7340039, 1051649, 2099202, 6291462, 4195332, 4195332, 2099202, 6291462, 3072, 7340039, 3147779, 6291462, 4195332, 5243909, 2099202, 4195332, 5243909, 1051649, 3147779, 4195332, 6291462, 3147779, 3147779, 5243909, + 7340039, 3147779, 3072, 4195332, 1051649, 4195332, 2099202, 1051649, 6291462, 1051649, 4195332, 2099202, 4195332, 7340039, 5243909, 4195332, 3147779, 2099202, 7340039, 3147779, 2099202, 5243909, 6291462, 3147779, 5243909, 1051649, 3072, 6291462, 5243909, 2099202, 4195332, 1051649, 5243909, 2099202, 4195332, 4195332, 1051649, 7340039, 3072, 7340039, 4195332, 5243909, 7340039, 3072, 6291462, 5243909, 1051649, 3147779, 6291462, 2099202, 4195332, 3072, 4195332, 1051649, 4195332, 3072, 7340039, 1051649, 4195332, 6291462, 1051649, 5243909, 1051649, 2099202, 4195332, 7340039, 2099202, 7340039, 3147779, 1051649, 4195332, 4195332, 3072, 5243909, 1051649, 6291462, 5243909, 6291462, 5243909, 1051649, 4195332, 2099202, 3072, 2099202, 7340039, 4195332, 2099202, 3072, 5243909, 2099202, 7340039, 1051649, 3147779, 7340039, 3147779, 6291462, 3147779, 6291462, 4195332, 3147779, 6291462, 2099202, 7340039, 1051649, 2099202, 5243909, 3147779, 1051649, 7340039, 1051649, 5243909, 2099202, 4195332, 5243909, 3072, 2099202, 3072, 2099202, 6291462, 1051649, 3072, 6291462, 7340039, 3072, 2099202, 6291462, 3072, 3147779, + 3072, 5243909, 2099202, 6291462, 7340039, 3072, 7340039, 5243909, 3147779, 6291462, 2099202, 7340039, 5243909, 1051649, 2099202, 3072, 7340039, 4195332, 3072, 6291462, 3072, 5243909, 1051649, 7340039, 3147779, 6291462, 5243909, 2099202, 3072, 5243909, 3072, 7340039, 4195332, 6291462, 3072, 7340039, 2099202, 4195332, 5243909, 2099202, 3072, 2099202, 6291462, 4195332, 2099202, 3072, 6291462, 4195332, 1051649, 5243909, 3147779, 6291462, 3147779, 7340039, 2099202, 6291462, 3147779, 5243909, 3072, 4195332, 3147779, 7340039, 3147779, 6291462, 3147779, 1051649, 6291462, 3072, 5243909, 3147779, 6291462, 2099202, 7340039, 3147779, 7340039, 3072, 3147779, 2099202, 1051649, 7340039, 3147779, 7340039, 4195332, 5243909, 1051649, 3147779, 6291462, 3147779, 4195332, 5243909, 2099202, 5243909, 3072, 6291462, 1051649, 5243909, 1051649, 2099202, 3072, 5243909, 1051649, 5243909, 3072, 3147779, 6291462, 3072, 7340039, 5243909, 3072, 6291462, 3147779, 7340039, 1051649, 6291462, 3147779, 7340039, 5243909, 6291462, 3147779, 5243909, 7340039, 2099202, 4195332, 3147779, 5243909, 1051649, 7340039, 4195332, + 2099202, 6291462, 3147779, 1051649, 3147779, 2099202, 5243909, 2099202, 3072, 7340039, 1051649, 3147779, 3072, 6291462, 4195332, 6291462, 3147779, 1051649, 5243909, 2099202, 7340039, 1051649, 4195332, 3072, 4195332, 1051649, 3147779, 7340039, 4195332, 3147779, 6291462, 2099202, 3147779, 1051649, 3147779, 5243909, 3072, 6291462, 1051649, 7340039, 3147779, 5243909, 3072, 3147779, 7340039, 5243909, 2099202, 3147779, 7340039, 3072, 5243909, 1051649, 6291462, 1051649, 5243909, 3072, 2099202, 4195332, 7340039, 1051649, 6291462, 3072, 5243909, 1051649, 5243909, 4195332, 2099202, 4195332, 1051649, 7340039, 3072, 2099202, 5243909, 3072, 2099202, 4195332, 1051649, 7340039, 6291462, 1051649, 4195332, 2099202, 1051649, 6291462, 3072, 7340039, 1051649, 7340039, 1051649, 3072, 7340039, 3147779, 4195332, 2099202, 7340039, 3147779, 7340039, 4195332, 2099202, 7340039, 3147779, 4195332, 6291462, 1051649, 5243909, 3147779, 2099202, 4195332, 3147779, 4195332, 3072, 5243909, 1051649, 3147779, 2099202, 4195332, 1051649, 3147779, 3072, 2099202, 3147779, 5243909, 1051649, 7340039, 2099202, 5243909, 1051649, 4195332, + 6291462, 3072, 7340039, 4195332, 6291462, 4195332, 3072, 7340039, 4195332, 4195332, 1051649, 6291462, 3147779, 7340039, 2099202, 1051649, 6291462, 5243909, 3147779, 4195332, 3147779, 6291462, 3147779, 6291462, 2099202, 7340039, 4195332, 3072, 7340039, 1051649, 5243909, 3072, 6291462, 7340039, 4195332, 2099202, 7340039, 3147779, 5243909, 6291462, 1051649, 2099202, 6291462, 4195332, 1051649, 3147779, 7340039, 3072, 4195332, 5243909, 2099202, 6291462, 3072, 3147779, 4195332, 7340039, 6291462, 1051649, 4195332, 2099202, 5243909, 2099202, 6291462, 3072, 7340039, 3072, 6291462, 2099202, 5243909, 4195332, 6291462, 3147779, 6291462, 4195332, 6291462, 5243909, 3072, 3147779, 4195332, 5243909, 3072, 6291462, 4195332, 5243909, 3147779, 4195332, 5243909, 2099202, 4195332, 6291462, 2099202, 5243909, 1051649, 6291462, 2099202, 3072, 5243909, 2099202, 6291462, 3147779, 1051649, 5243909, 2099202, 7340039, 1051649, 6291462, 4195332, 1051649, 6291462, 1051649, 7340039, 2099202, 7340039, 5243909, 6291462, 3072, 6291462, 7340039, 4195332, 7340039, 3072, 4195332, 1051649, 6291462, 3072, 4195332, 7340039, 2099202, + 4195332, 5243909, 1051649, 5243909, 3072, 3147779, 5243909, 1051649, 6291462, 2099202, 5243909, 2099202, 5243909, 3072, 4195332, 5243909, 2099202, 3072, 7340039, 1051649, 6291462, 3072, 5243909, 1051649, 2099202, 5243909, 1051649, 5243909, 2099202, 4195332, 3147779, 7340039, 2099202, 3072, 3147779, 5243909, 1051649, 4195332, 2099202, 3072, 4195332, 7340039, 4195332, 1051649, 5243909, 3072, 4195332, 6291462, 2099202, 7340039, 1051649, 4195332, 5243909, 7340039, 2099202, 3072, 5243909, 3147779, 6291462, 1051649, 7340039, 4195332, 3147779, 3147779, 2099202, 5243909, 3147779, 7340039, 3072, 3147779, 1051649, 5243909, 3072, 2099202, 1051649, 6291462, 2099202, 7340039, 3072, 3147779, 7340039, 3072, 3147779, 2099202, 6291462, 3072, 1051649, 7340039, 3072, 3147779, 1051649, 7340039, 3072, 5243909, 3147779, 5243909, 3072, 7340039, 3072, 4195332, 7340039, 3072, 4195332, 3147779, 4195332, 3072, 3147779, 7340039, 3072, 5243909, 3147779, 3072, 4195332, 3072, 3147779, 7340039, 2099202, 1051649, 4195332, 1051649, 6291462, 3147779, 6291462, 3147779, 2099202, 6291462, 1051649, 3147779, + 3072, 3147779, 2099202, 7340039, 2099202, 6291462, 3072, 4195332, 1051649, 7340039, 3072, 3147779, 7340039, 3147779, 7340039, 3072, 3147779, 5243909, 2099202, 4195332, 2099202, 3147779, 7340039, 4195332, 6291462, 3072, 7340039, 3147779, 3072, 6291462, 1051649, 1051649, 5243909, 4195332, 1051649, 6291462, 6291462, 3072, 7340039, 3147779, 5243909, 1051649, 3072, 7340039, 3147779, 6291462, 3147779, 1051649, 5243909, 3147779, 6291462, 2099202, 1051649, 3147779, 4195332, 6291462, 2099202, 1051649, 6291462, 3072, 3147779, 3072, 6291462, 7340039, 1051649, 6291462, 1051649, 2099202, 6291462, 1051649, 7340039, 4195332, 5243909, 7340039, 4195332, 3072, 5243909, 2099202, 6291462, 4195332, 2099202, 5243909, 7340039, 3072, 4195332, 7340039, 5243909, 3147779, 4195332, 6291462, 2099202, 4195332, 4195332, 1051649, 7340039, 2099202, 4195332, 5243909, 3147779, 1051649, 6291462, 2099202, 5243909, 3072, 6291462, 2099202, 5243909, 2099202, 4195332, 2099202, 6291462, 2099202, 6291462, 3147779, 5243909, 1051649, 4195332, 5243909, 6291462, 5243909, 3072, 4195332, 1051649, 5243909, 7340039, 3072, 5243909, 6291462, + 7340039, 5243909, 4195332, 1051649, 5243909, 3147779, 7340039, 3147779, 5243909, 3147779, 4195332, 6291462, 1051649, 4195332, 1051649, 5243909, 6291462, 1051649, 7340039, 3072, 6291462, 5243909, 3072, 2099202, 3147779, 4195332, 2099202, 6291462, 3147779, 4195332, 7340039, 5243909, 2099202, 7340039, 4195332, 2099202, 2099202, 4195332, 1051649, 6291462, 3147779, 5243909, 2099202, 5243909, 2099202, 1051649, 5243909, 7340039, 3072, 4195332, 3072, 7340039, 3147779, 6291462, 3072, 3147779, 7340039, 4195332, 5243909, 2099202, 7340039, 4195332, 1051649, 3147779, 4195332, 2099202, 4195332, 5243909, 3147779, 5243909, 2099202, 3072, 3147779, 1051649, 3147779, 7340039, 3147779, 5243909, 1051649, 5243909, 1051649, 6291462, 2099202, 5243909, 2099202, 3147779, 1051649, 5243909, 1051649, 6291462, 3072, 7340039, 3147779, 6291462, 3147779, 3072, 6291462, 2099202, 6291462, 1051649, 4195332, 5243909, 2099202, 7340039, 1051649, 7340039, 3147779, 3072, 7340039, 5243909, 1051649, 5243909, 1051649, 7340039, 2099202, 6291462, 3072, 3147779, 1051649, 2099202, 7340039, 5243909, 3072, 3147779, 1051649, 5243909, 3147779, 2099202, + 3072, 6291462, 1051649, 6291462, 4195332, 2099202, 1051649, 6291462, 3072, 6291462, 2099202, 3072, 5243909, 6291462, 2099202, 7340039, 3072, 3147779, 4195332, 5243909, 1051649, 3147779, 5243909, 7340039, 1051649, 6291462, 4195332, 3072, 7340039, 1051649, 3147779, 3072, 3147779, 1051649, 6291462, 3072, 5243909, 3147779, 5243909, 2099202, 3072, 7340039, 1051649, 6291462, 4195332, 6291462, 2099202, 1051649, 4195332, 7340039, 2099202, 5243909, 3072, 5243909, 2099202, 5243909, 3072, 6291462, 1051649, 3147779, 5243909, 2099202, 6291462, 3072, 7340039, 3147779, 7340039, 3072, 7340039, 3072, 4195332, 7340039, 6291462, 6291462, 1051649, 4195332, 3072, 2099202, 3147779, 7340039, 3072, 4195332, 1051649, 4195332, 3072, 6291462, 6291462, 3072, 7340039, 1051649, 3147779, 5243909, 2099202, 1051649, 4195332, 7340039, 1051649, 7340039, 3072, 3147779, 7340039, 3072, 6291462, 3147779, 4195332, 1051649, 5243909, 6291462, 3147779, 1051649, 7340039, 4195332, 4195332, 3072, 4195332, 3147779, 7340039, 4195332, 7340039, 3072, 3147779, 2099202, 6291462, 4195332, 7340039, 3147779, 1051649, 5243909, + 2099202, 3147779, 7340039, 2099202, 3072, 6291462, 4195332, 3147779, 5243909, 1051649, 4195332, 7340039, 2099202, 4195332, 3072, 3147779, 4195332, 7340039, 1051649, 2099202, 6291462, 2099202, 3072, 5243909, 3147779, 1051649, 6291462, 5243909, 2099202, 5243909, 6291462, 3147779, 6291462, 5243909, 3147779, 7340039, 3072, 7340039, 1051649, 6291462, 3147779, 4195332, 3147779, 7340039, 3072, 3147779, 5243909, 3147779, 6291462, 2099202, 5243909, 1051649, 4195332, 1051649, 7340039, 3147779, 1051649, 2099202, 7340039, 4195332, 3072, 7340039, 1051649, 4195332, 5243909, 3072, 5243909, 1051649, 3147779, 5243909, 2099202, 1051649, 3072, 4195332, 2099202, 5243909, 7340039, 6291462, 4195332, 3147779, 6291462, 2099202, 7340039, 3147779, 7340039, 1051649, 3147779, 4195332, 2099202, 6291462, 4195332, 3072, 5243909, 6291462, 3072, 4195332, 2099202, 4195332, 3147779, 5243909, 2099202, 4195332, 3147779, 1051649, 6291462, 5243909, 2099202, 4195332, 3072, 6291462, 3147779, 3072, 7340039, 2099202, 6291462, 1051649, 2099202, 3072, 5243909, 3147779, 7340039, 5243909, 1051649, 6291462, 2099202, 3072, 4195332, 7340039, + 6291462, 3072, 4195332, 3147779, 5243909, 1051649, 7340039, 3072, 7340039, 5243909, 3147779, 3072, 5243909, 1051649, 6291462, 5243909, 1051649, 3147779, 6291462, 5243909, 4195332, 7340039, 4195332, 2099202, 4195332, 7340039, 3072, 2099202, 4195332, 3072, 4195332, 1051649, 5243909, 3072, 2099202, 5243909, 2099202, 3147779, 4195332, 2099202, 7340039, 3072, 5243909, 2099202, 4195332, 7340039, 3072, 4195332, 1051649, 3072, 6291462, 3147779, 7340039, 4195332, 1051649, 6291462, 5243909, 4195332, 2099202, 6291462, 1051649, 4195332, 5243909, 2099202, 6291462, 1051649, 4195332, 6291462, 2099202, 4195332, 6291462, 7340039, 4195332, 3147779, 7340039, 3072, 3147779, 1051649, 3072, 6291462, 1051649, 5243909, 3072, 6291462, 2099202, 5243909, 6291462, 2099202, 5243909, 3072, 3147779, 7340039, 2099202, 4195332, 6291462, 2099202, 5243909, 1051649, 6291462, 1051649, 7340039, 5243909, 3072, 7340039, 3147779, 3072, 7340039, 1051649, 5243909, 4195332, 2099202, 5243909, 1051649, 5243909, 2099202, 5243909, 4195332, 6291462, 4195332, 1051649, 2099202, 4195332, 2099202, 3072, 5243909, 6291462, 4195332, 1051649, + 4195332, 1051649, 5243909, 1051649, 7340039, 4195332, 2099202, 3147779, 2099202, 4195332, 2099202, 7340039, 3147779, 5243909, 2099202, 7340039, 2099202, 6291462, 3072, 2099202, 3072, 3147779, 1051649, 7340039, 3072, 5243909, 3147779, 7340039, 1051649, 6291462, 2099202, 7340039, 1051649, 7340039, 4195332, 7340039, 1051649, 6291462, 3072, 5243909, 4195332, 1051649, 6291462, 3072, 3147779, 1051649, 6291462, 2099202, 7340039, 5243909, 3147779, 3072, 3147779, 6291462, 2099202, 4195332, 3072, 7340039, 3072, 3147779, 3147779, 1051649, 7340039, 3072, 3147779, 7340039, 3147779, 2099202, 6291462, 3072, 3147779, 1051649, 2099202, 5243909, 1051649, 5243909, 2099202, 4195332, 5243909, 2099202, 7340039, 3147779, 5243909, 1051649, 4195332, 3072, 3147779, 5243909, 3072, 7340039, 4195332, 1051649, 5243909, 1051649, 3147779, 7340039, 3072, 6291462, 2099202, 4195332, 3072, 3147779, 5243909, 4195332, 2099202, 5243909, 3147779, 6291462, 2099202, 1051649, 6291462, 3147779, 7340039, 3072, 6291462, 3072, 7340039, 2099202, 1051649, 5243909, 6291462, 3072, 7340039, 4195332, 3147779, 1051649, 7340039, 3147779, + 7340039, 6291462, 3147779, 7340039, 2099202, 3072, 5243909, 6291462, 3072, 6291462, 1051649, 6291462, 3072, 2099202, 4195332, 3072, 4195332, 1051649, 7340039, 4195332, 7340039, 6291462, 5243909, 1051649, 6291462, 2099202, 6291462, 1051649, 5243909, 4195332, 3072, 3147779, 6291462, 2099202, 4195332, 3072, 4195332, 4195332, 2099202, 6291462, 1051649, 4195332, 3147779, 6291462, 7340039, 4195332, 2099202, 6291462, 3072, 6291462, 1051649, 7340039, 4195332, 3072, 5243909, 7340039, 1051649, 3147779, 5243909, 6291462, 5243909, 4195332, 2099202, 6291462, 1051649, 5243909, 3072, 7340039, 1051649, 5243909, 6291462, 5243909, 6291462, 1051649, 7340039, 3147779, 6291462, 3072, 7340039, 2099202, 4195332, 1051649, 6291462, 3147779, 7340039, 5243909, 1051649, 7340039, 2099202, 5243909, 2099202, 6291462, 3072, 7340039, 4195332, 3147779, 5243909, 3147779, 1051649, 7340039, 6291462, 2099202, 7340039, 1051649, 7340039, 4195332, 1051649, 3072, 4195332, 7340039, 5243909, 3072, 3147779, 2099202, 4195332, 5243909, 1051649, 3147779, 7340039, 3072, 3147779, 6291462, 4195332, 3072, 7340039, 2099202, 5243909, 3072, + 2099202, 3072, 5243909, 1051649, 4195332, 6291462, 3147779, 1051649, 7340039, 3147779, 5243909, 3147779, 1051649, 7340039, 6291462, 3147779, 6291462, 5243909, 1051649, 4195332, 2099202, 3072, 3147779, 7340039, 4195332, 3072, 3147779, 5243909, 2099202, 7340039, 3147779, 6291462, 1051649, 5243909, 2099202, 6291462, 1051649, 7340039, 3072, 3147779, 7340039, 5243909, 3072, 5243909, 2099202, 3072, 5243909, 3147779, 4195332, 4195332, 2099202, 5243909, 2099202, 6291462, 1051649, 2099202, 4195332, 6291462, 1051649, 2099202, 3072, 7340039, 2099202, 3147779, 6291462, 2099202, 5243909, 4195332, 4195332, 1051649, 2099202, 3072, 7340039, 4195332, 3072, 6291462, 3147779, 4195332, 1051649, 5243909, 3072, 7340039, 1051649, 4195332, 3072, 3147779, 2099202, 6291462, 4195332, 1051649, 7340039, 3147779, 4195332, 2099202, 3072, 6291462, 1051649, 6291462, 3072, 4195332, 1051649, 5243909, 2099202, 4195332, 3072, 2099202, 6291462, 3147779, 6291462, 3072, 2099202, 7340039, 4195332, 6291462, 2099202, 7340039, 3147779, 5243909, 2099202, 6291462, 5243909, 1051649, 2099202, 5243909, 4195332, 2099202, 6291462, 3147779, + 7340039, 2099202, 4195332, 6291462, 2099202, 3072, 6291462, 4195332, 2099202, 5243909, 3072, 7340039, 4195332, 3147779, 1051649, 4195332, 3072, 5243909, 1051649, 3147779, 6291462, 2099202, 5243909, 1051649, 3147779, 4195332, 7340039, 3072, 4195332, 1051649, 5243909, 1051649, 4195332, 6291462, 3072, 1051649, 5243909, 3147779, 6291462, 5243909, 2099202, 1051649, 7340039, 1051649, 6291462, 3147779, 7340039, 1051649, 7340039, 1051649, 6291462, 3072, 7340039, 4195332, 3147779, 7340039, 3072, 3147779, 5243909, 7340039, 4195332, 1051649, 5243909, 3072, 4195332, 7340039, 3072, 2099202, 7340039, 3147779, 6291462, 3147779, 2099202, 3147779, 5243909, 2099202, 1051649, 7340039, 3147779, 4195332, 2099202, 5243909, 3147779, 7340039, 2099202, 6291462, 4195332, 3072, 3147779, 5243909, 3072, 5243909, 1051649, 6291462, 5243909, 2099202, 7340039, 2099202, 4195332, 7340039, 3147779, 6291462, 3072, 6291462, 3147779, 7340039, 1051649, 5243909, 2099202, 4195332, 5243909, 3147779, 1051649, 3072, 5243909, 1051649, 6291462, 3072, 4195332, 3147779, 3072, 7340039, 6291462, 3147779, 1051649, 6291462, 3072, 5243909, + 1051649, 3147779, 7340039, 3072, 5243909, 7340039, 2099202, 4195332, 1051649, 7340039, 4195332, 1051649, 6291462, 3072, 6291462, 2099202, 7340039, 3147779, 7340039, 3072, 5243909, 4195332, 1051649, 7340039, 5243909, 1051649, 6291462, 3147779, 6291462, 2099202, 4195332, 3147779, 7340039, 2099202, 7340039, 3147779, 6291462, 3072, 3147779, 2099202, 4195332, 6291462, 3147779, 4195332, 3072, 5243909, 1051649, 5243909, 3147779, 7340039, 2099202, 4195332, 3147779, 3072, 6291462, 1051649, 3147779, 5243909, 3072, 2099202, 3147779, 6291462, 2099202, 7340039, 3147779, 1051649, 4195332, 6291462, 3072, 5243909, 1051649, 7340039, 5243909, 3072, 6291462, 4195332, 5243909, 3072, 6291462, 1051649, 7340039, 2099202, 3072, 6291462, 1051649, 5243909, 2099202, 7340039, 4195332, 3147779, 6291462, 2099202, 7340039, 3072, 3147779, 4195332, 1051649, 5243909, 3072, 5243909, 3072, 3147779, 5243909, 1051649, 5243909, 4195332, 2099202, 6291462, 3072, 7340039, 1051649, 3147779, 7340039, 4195332, 3147779, 6291462, 2099202, 4195332, 1051649, 6291462, 2099202, 4195332, 1051649, 3072, 5243909, 3147779, 1051649, 5243909, + 4195332, 1051649, 4195332, 2099202, 3147779, 1051649, 7340039, 3072, 3147779, 6291462, 2099202, 5243909, 2099202, 5243909, 1051649, 5243909, 3072, 6291462, 2099202, 4195332, 2099202, 6291462, 3147779, 4195332, 3072, 6291462, 2099202, 2099202, 3072, 7340039, 3072, 6291462, 3072, 3147779, 4195332, 5243909, 1051649, 4195332, 7340039, 3072, 7340039, 3072, 2099202, 7340039, 2099202, 4195332, 6291462, 2099202, 3072, 5243909, 1051649, 1051649, 6291462, 2099202, 5243909, 4195332, 6291462, 2099202, 7340039, 4195332, 6291462, 3072, 4195332, 5243909, 3072, 6291462, 5243909, 3147779, 2099202, 6291462, 4195332, 2099202, 4195332, 3147779, 1051649, 7340039, 2099202, 4195332, 3147779, 5243909, 3072, 5243909, 6291462, 2099202, 4195332, 3072, 6291462, 1051649, 1051649, 6291462, 1051649, 4195332, 3147779, 5243909, 1051649, 7340039, 3072, 6291462, 3147779, 2099202, 6291462, 6291462, 1051649, 3147779, 7340039, 3072, 6291462, 4195332, 2099202, 5243909, 1051649, 5243909, 3072, 6291462, 2099202, 3072, 6291462, 1051649, 7340039, 5243909, 3072, 5243909, 7340039, 4195332, 7340039, 2099202, 6291462, 3147779, + 3072, 6291462, 2099202, 5243909, 6291462, 4195332, 3147779, 5243909, 6291462, 3072, 4195332, 1051649, 7340039, 3147779, 4195332, 7340039, 2099202, 3147779, 3072, 7340039, 3147779, 3072, 6291462, 2099202, 7340039, 3147779, 4195332, 7340039, 5243909, 3147779, 4195332, 1051649, 5243909, 7340039, 2099202, 3072, 5243909, 2099202, 6291462, 2099202, 3147779, 5243909, 6291462, 1051649, 5243909, 3072, 7340039, 2099202, 4195332, 7340039, 3147779, 5243909, 3147779, 7340039, 3072, 2099202, 1051649, 5243909, 3072, 4195332, 1051649, 7340039, 3147779, 6291462, 1051649, 3147779, 1051649, 7340039, 4195332, 2099202, 3072, 7340039, 3072, 5243909, 6291462, 3072, 3147779, 1051649, 7340039, 2099202, 6291462, 3147779, 1051649, 5243909, 7340039, 3147779, 4195332, 7340039, 5243909, 2099202, 7340039, 3072, 7340039, 4195332, 6291462, 3147779, 2099202, 4195332, 2099202, 7340039, 3147779, 3072, 4195332, 5243909, 1051649, 4195332, 3147779, 1051649, 7340039, 3147779, 6291462, 2099202, 4195332, 3147779, 7340039, 4195332, 3147779, 4195332, 3147779, 3147779, 7340039, 2099202, 1051649, 3147779, 3072, 4195332, 1051649, 7340039, + 5243909, 4195332, 7340039, 3072, 2099202, 1051649, 5243909, 3072, 3147779, 7340039, 5243909, 1051649, 4195332, 3072, 4195332, 1051649, 3147779, 6291462, 5243909, 1051649, 4195332, 7340039, 3072, 5243909, 1051649, 6291462, 3072, 5243909, 1051649, 2099202, 6291462, 2099202, 5243909, 1051649, 4195332, 6291462, 3147779, 7340039, 1051649, 5243909, 1051649, 5243909, 1051649, 4195332, 4195332, 3147779, 1051649, 5243909, 3072, 4195332, 3072, 6291462, 1051649, 2099202, 5243909, 6291462, 7340039, 3147779, 7340039, 2099202, 3147779, 5243909, 1051649, 2099202, 5243909, 7340039, 2099202, 4195332, 3072, 6291462, 5243909, 2099202, 6291462, 1051649, 2099202, 5243909, 6291462, 5243909, 3072, 4195332, 1051649, 4195332, 7340039, 3072, 3147779, 1051649, 5243909, 3072, 3147779, 1051649, 5243909, 3147779, 2099202, 3072, 2099202, 6291462, 5243909, 7340039, 3072, 4195332, 1051649, 7340039, 1051649, 6291462, 3147779, 7340039, 2099202, 5243909, 3072, 4195332, 3072, 7340039, 5243909, 1051649, 5243909, 2099202, 7340039, 3072, 6291462, 1051649, 3072, 6291462, 4195332, 6291462, 2099202, 7340039, 5243909, 2099202, + 1051649, 3072, 3147779, 4195332, 7340039, 6291462, 2099202, 7340039, 2099202, 1051649, 2099202, 6291462, 3147779, 7340039, 2099202, 6291462, 5243909, 1051649, 4195332, 6291462, 2099202, 3147779, 5243909, 2099202, 4195332, 1051649, 7340039, 2099202, 4195332, 5243909, 3072, 7340039, 2099202, 3147779, 7340039, 1051649, 5243909, 3147779, 1051649, 7340039, 4195332, 2099202, 3147779, 7340039, 2099202, 6291462, 3147779, 4195332, 6291462, 2099202, 5243909, 2099202, 4195332, 7340039, 3147779, 3072, 1051649, 4195332, 1051649, 6291462, 3072, 4195332, 7340039, 4195332, 3072, 6291462, 3072, 7340039, 3147779, 4195332, 1051649, 3147779, 4195332, 3147779, 7340039, 1051649, 3147779, 2099202, 7340039, 4195332, 6291462, 3072, 2099202, 4195332, 6291462, 2099202, 7340039, 2099202, 6291462, 4195332, 3072, 5243909, 6291462, 2099202, 5243909, 3072, 3147779, 1051649, 5243909, 3147779, 5243909, 2099202, 6291462, 2099202, 2099202, 3072, 6291462, 3147779, 7340039, 1051649, 5243909, 3147779, 3072, 7340039, 1051649, 6291462, 3072, 5243909, 2099202, 5243909, 4195332, 2099202, 1051649, 3147779, 5243909, 3147779, 3072, 6291462, + 3147779, 7340039, 5243909, 3072, 3147779, 1051649, 4195332, 3072, 5243909, 6291462, 4195332, 3072, 7340039, 1051649, 5243909, 3147779, 3072, 7340039, 2099202, 3072, 7340039, 1051649, 7340039, 3072, 6291462, 4195332, 3147779, 6291462, 3072, 7340039, 3147779, 5243909, 3072, 6291462, 2099202, 4195332, 3072, 6291462, 3147779, 3072, 6291462, 3072, 6291462, 3147779, 3072, 6291462, 3072, 7340039, 1051649, 3147779, 6291462, 3072, 6291462, 1051649, 5243909, 4195332, 6291462, 3147779, 5243909, 2099202, 6291462, 3147779, 3072, 6291462, 3147779, 4195332, 2099202, 5243909, 1051649, 7340039, 6291462, 1051649, 7340039, 3072, 4195332, 3147779, 7340039, 3072, 4195332, 1051649, 2099202, 7340039, 3147779, 6291462, 3072, 2099202, 4195332, 3072, 7340039, 1051649, 6291462, 3147779, 1051649, 6291462, 4195332, 7340039, 3147779, 6291462, 1051649, 7340039, 1051649, 4195332, 3072, 4195332, 7340039, 4195332, 5243909, 1051649, 4195332, 6291462, 2099202, 2099202, 6291462, 4195332, 3147779, 4195332, 2099202, 7340039, 4195332, 1051649, 7340039, 3147779, 7340039, 3072, 6291462, 1051649, 7340039, 4195332, + 1051649, 4195332, 2099202, 6291462, 3147779, 5243909, 6291462, 4195332, 3147779, 1051649, 6291462, 4195332, 2099202, 5243909, 3072, 4195332, 6291462, 2099202, 4195332, 3147779, 5243909, 1051649, 3147779, 5243909, 2099202, 3072, 5243909, 1051649, 5243909, 3147779, 1051649, 6291462, 4195332, 3072, 7340039, 2099202, 6291462, 2099202, 7340039, 4195332, 3147779, 5243909, 1051649, 6291462, 5243909, 2099202, 3147779, 1051649, 4195332, 7340039, 3147779, 4195332, 3147779, 3072, 7340039, 2099202, 3072, 7340039, 3072, 5243909, 1051649, 5243909, 2099202, 6291462, 1051649, 7340039, 3147779, 1051649, 5243909, 3072, 2099202, 5243909, 2099202, 5243909, 1051649, 5243909, 1051649, 6291462, 3147779, 6291462, 5243909, 3147779, 1051649, 5243909, 4195332, 7340039, 3147779, 5243909, 3147779, 4195332, 2099202, 7340039, 4195332, 3072, 2099202, 1051649, 5243909, 3072, 4195332, 2099202, 5243909, 6291462, 3147779, 7340039, 1051649, 3072, 6291462, 2099202, 7340039, 3072, 4195332, 6291462, 1051649, 2099202, 7340039, 3072, 5243909, 1051649, 3147779, 6291462, 3072, 3147779, 5243909, 4195332, 2099202, 5243909, 2099202, 6291462, + 7340039, 2099202, 6291462, 1051649, 1051649, 7340039, 2099202, 1051649, 7340039, 5243909, 3072, 3147779, 6291462, 2099202, 6291462, 3147779, 1051649, 5243909, 3072, 7340039, 2099202, 5243909, 6291462, 1051649, 7340039, 4195332, 3147779, 6291462, 2099202, 7340039, 2099202, 4195332, 1051649, 3147779, 5243909, 1051649, 4195332, 5243909, 3072, 2099202, 1051649, 7340039, 4195332, 3072, 4195332, 1051649, 7340039, 5243909, 3072, 5243909, 1051649, 7340039, 6291462, 2099202, 5243909, 3147779, 4195332, 2099202, 5243909, 2099202, 4195332, 7340039, 2099202, 4195332, 5243909, 3072, 5243909, 2099202, 6291462, 4195332, 3147779, 7340039, 4195332, 3072, 6291462, 2099202, 7340039, 2099202, 5243909, 1051649, 3072, 5243909, 7340039, 1051649, 6291462, 3072, 5243909, 1051649, 6291462, 3072, 5243909, 1051649, 4195332, 6291462, 7340039, 3147779, 4195332, 2099202, 7340039, 5243909, 3072, 3147779, 1051649, 5243909, 3147779, 3147779, 7340039, 1051649, 3147779, 5243909, 1051649, 3147779, 5243909, 6291462, 1051649, 5243909, 2099202, 7340039, 5243909, 2099202, 5243909, 6291462, 1051649, 2099202, 7340039, 3147779, 4195332, 3072, + 4195332, 3072, 3147779, 5243909, 5243909, 3072, 3147779, 6291462, 3072, 2099202, 7340039, 3147779, 1051649, 7340039, 1051649, 3147779, 7340039, 3147779, 6291462, 2099202, 4195332, 3072, 4195332, 4195332, 2099202, 1051649, 7340039, 3072, 4195332, 1051649, 5243909, 3072, 7340039, 6291462, 3147779, 7340039, 3072, 3147779, 4195332, 6291462, 5243909, 3147779, 1051649, 7340039, 3147779, 5243909, 3147779, 2099202, 6291462, 1051649, 5243909, 3072, 2099202, 4195332, 6291462, 3072, 6291462, 1051649, 3147779, 7340039, 3147779, 3072, 6291462, 3072, 7340039, 3147779, 2099202, 7340039, 3147779, 1051649, 7340039, 1051649, 4195332, 7340039, 3147779, 5243909, 3072, 4195332, 3072, 6291462, 3147779, 4195332, 2099202, 4195332, 1051649, 2099202, 7340039, 2099202, 4195332, 6291462, 1051649, 7340039, 2099202, 3147779, 1051649, 5243909, 7340039, 3072, 3147779, 1051649, 7340039, 2099202, 6291462, 2099202, 6291462, 5243909, 3072, 4195332, 5243909, 2099202, 7340039, 4195332, 3072, 4195332, 3147779, 6291462, 3147779, 3072, 4195332, 1051649, 7340039, 3072, 4195332, 5243909, 3072, 6291462, 1051649, 5243909, + 2099202, 7340039, 6291462, 3072, 3147779, 7340039, 5243909, 2099202, 4195332, 6291462, 1051649, 5243909, 5243909, 3072, 4195332, 5243909, 3072, 4195332, 1051649, 6291462, 3147779, 6291462, 1051649, 7340039, 3072, 5243909, 2099202, 4195332, 6291462, 1051649, 6291462, 3147779, 5243909, 2099202, 1051649, 4195332, 6291462, 1051649, 5243909, 2099202, 3072, 7340039, 2099202, 4195332, 3072, 6291462, 1051649, 7340039, 3147779, 4195332, 3147779, 7340039, 5243909, 3147779, 1051649, 5243909, 1051649, 7340039, 4195332, 3072, 6291462, 1051649, 4195332, 3147779, 1051649, 6291462, 4195332, 3072, 4195332, 6291462, 3072, 5243909, 2099202, 3072, 4195332, 1051649, 6291462, 4195332, 7340039, 2099202, 7340039, 3072, 6291462, 3147779, 6291462, 4195332, 3147779, 3072, 5243909, 2099202, 3147779, 5243909, 3072, 6291462, 4195332, 3072, 2099202, 3147779, 6291462, 4195332, 2099202, 6291462, 3072, 4195332, 3072, 4195332, 2099202, 6291462, 3072, 6291462, 3147779, 1051649, 7340039, 1051649, 6291462, 3072, 7340039, 4195332, 6291462, 3072, 3147779, 6291462, 3147779, 1051649, 7340039, 2099202, 6291462, 3147779, + 5243909, 2099202, 1051649, 6291462, 4195332, 2099202, 3072, 7340039, 1051649, 4195332, 3072, 4195332, 2099202, 7340039, 4195332, 2099202, 7340039, 2099202, 5243909, 3072, 4195332, 1051649, 5243909, 3147779, 5243909, 3147779, 6291462, 3147779, 3072, 4195332, 3147779, 6291462, 3072, 7340039, 1051649, 6291462, 2099202, 7340039, 3072, 7340039, 4195332, 1051649, 5243909, 6291462, 2099202, 4195332, 2099202, 5243909, 3072, 7340039, 1051649, 2099202, 3072, 7340039, 2099202, 4195332, 6291462, 3147779, 1051649, 5243909, 2099202, 7340039, 2099202, 6291462, 3147779, 3072, 5243909, 6291462, 1051649, 2099202, 5243909, 3147779, 6291462, 3147779, 6291462, 4195332, 2099202, 3147779, 1051649, 5243909, 1051649, 5243909, 3147779, 5243909, 3072, 1051649, 7340039, 3147779, 6291462, 3072, 7340039, 3147779, 5243909, 2099202, 7340039, 4195332, 7340039, 6291462, 1051649, 5243909, 3072, 4195332, 5243909, 3147779, 7340039, 1051649, 7340039, 2099202, 7340039, 2099202, 3072, 5243909, 2099202, 4195332, 2099202, 5243909, 1051649, 2099202, 3147779, 6291462, 2099202, 3072, 7340039, 4195332, 5243909, 3072, 3147779, 1051649, + 3072, 7340039, 4195332, 3147779, 1051649, 6291462, 3147779, 5243909, 3147779, 5243909, 7340039, 1051649, 6291462, 3147779, 1051649, 6291462, 3072, 6291462, 4195332, 7340039, 6291462, 2099202, 7340039, 2099202, 1051649, 7340039, 3072, 2099202, 5243909, 7340039, 1051649, 2099202, 4195332, 4195332, 5243909, 3072, 4195332, 2099202, 5243909, 3147779, 3147779, 6291462, 3072, 2099202, 7340039, 3147779, 6291462, 1051649, 4195332, 2099202, 5243909, 6291462, 4195332, 6291462, 3072, 7340039, 2099202, 3072, 7340039, 5243909, 1051649, 4195332, 5243909, 1051649, 7340039, 4195332, 3147779, 1051649, 6291462, 4195332, 1051649, 7340039, 3072, 5243909, 1051649, 7340039, 3072, 6291462, 3147779, 6291462, 2099202, 4195332, 1051649, 2099202, 7340039, 5243909, 4195332, 3072, 6291462, 4195332, 1051649, 6291462, 3072, 4195332, 1051649, 3147779, 3072, 2099202, 4195332, 1051649, 3147779, 7340039, 2099202, 1051649, 2099202, 5243909, 4195332, 1051649, 3147779, 4195332, 5243909, 3147779, 6291462, 3072, 7340039, 3147779, 4195332, 7340039, 3072, 5243909, 4195332, 3147779, 5243909, 1051649, 2099202, 6291462, 4195332, 7340039, + 5243909, 3147779, 1051649, 7340039, 5243909, 2099202, 4195332, 3072, 7340039, 2099202, 1051649, 6291462, 3147779, 3072, 7340039, 3147779, 2099202, 5243909, 1051649, 3147779, 2099202, 5243909, 3072, 4195332, 6291462, 2099202, 4195332, 7340039, 1051649, 3147779, 6291462, 3072, 7340039, 2099202, 1051649, 6291462, 3147779, 1051649, 6291462, 3072, 6291462, 2099202, 4195332, 5243909, 1051649, 5243909, 3072, 3147779, 6291462, 7340039, 1051649, 3147779, 2099202, 1051649, 4195332, 1051649, 4195332, 5243909, 3147779, 2099202, 6291462, 3147779, 3072, 4195332, 2099202, 5243909, 2099202, 7340039, 3072, 6291462, 2099202, 4195332, 3147779, 2099202, 5243909, 1051649, 2099202, 5243909, 3072, 7340039, 3072, 4195332, 7340039, 5243909, 3147779, 1051649, 2099202, 5243909, 1051649, 2099202, 5243909, 2099202, 7340039, 5243909, 3147779, 6291462, 5243909, 1051649, 7340039, 6291462, 5243909, 1051649, 6291462, 4195332, 7340039, 3072, 3147779, 5243909, 6291462, 3072, 7340039, 1051649, 2099202, 5243909, 3147779, 1051649, 6291462, 4195332, 1051649, 7340039, 1051649, 6291462, 2099202, 7340039, 4195332, 3072, 3147779, 2099202, + 6291462, 3072, 5243909, 2099202, 3072, 6291462, 1051649, 6291462, 2099202, 4195332, 5243909, 2099202, 4195332, 5243909, 2099202, 5243909, 3072, 7340039, 1051649, 5243909, 3072, 3147779, 7340039, 4195332, 3072, 5243909, 1051649, 5243909, 3147779, 5243909, 1051649, 4195332, 5243909, 3147779, 6291462, 3147779, 7340039, 4195332, 2099202, 5243909, 1051649, 5243909, 3147779, 3072, 6291462, 1051649, 7340039, 4195332, 3072, 4195332, 3072, 5243909, 4195332, 7340039, 3147779, 6291462, 3072, 7340039, 3072, 4195332, 1051649, 5243909, 7340039, 3147779, 6291462, 3072, 3147779, 2099202, 5243909, 1051649, 7340039, 3072, 7340039, 1051649, 4195332, 7340039, 4195332, 6291462, 3147779, 1051649, 3147779, 6291462, 2099202, 3072, 7340039, 5243909, 6291462, 3147779, 4195332, 7340039, 3072, 6291462, 1051649, 3072, 6291462, 2099202, 4195332, 5243909, 3072, 3147779, 3072, 5243909, 3147779, 3072, 4195332, 6291462, 2099202, 7340039, 1051649, 4195332, 2099202, 5243909, 6291462, 3147779, 1051649, 7340039, 3072, 2099202, 5243909, 2099202, 4195332, 3147779, 6291462, 3072, 3147779, 6291462, 5243909, 1051649, + 4195332, 3147779, 4195332, 7340039, 4195332, 2099202, 5243909, 3072, 7340039, 3147779, 6291462, 3072, 7340039, 1051649, 6291462, 3147779, 4195332, 2099202, 6291462, 4195332, 7340039, 6291462, 1051649, 2099202, 6291462, 3147779, 7340039, 2099202, 3072, 7340039, 3147779, 7340039, 3072, 4195332, 3072, 5243909, 3072, 2099202, 6291462, 3147779, 7340039, 1051649, 7340039, 4195332, 2099202, 4195332, 5243909, 2099202, 6291462, 3147779, 7340039, 1051649, 6291462, 3072, 2099202, 5243909, 2099202, 3147779, 6291462, 2099202, 7340039, 4195332, 1051649, 3072, 5243909, 7340039, 5243909, 1051649, 6291462, 4195332, 3147779, 5243909, 2099202, 6291462, 3147779, 3072, 4195332, 1051649, 5243909, 4195332, 7340039, 1051649, 6291462, 4195332, 2099202, 3147779, 3072, 7340039, 1051649, 4195332, 2099202, 3147779, 4195332, 6291462, 2099202, 1051649, 7340039, 3147779, 6291462, 2099202, 7340039, 2099202, 6291462, 3147779, 5243909, 1051649, 4195332, 3072, 5243909, 3147779, 7340039, 3072, 4195332, 3072, 5243909, 4195332, 6291462, 3147779, 7340039, 3147779, 3072, 7340039, 2099202, 4195332, 7340039, 1051649, 2099202, 7340039, + 3072, 6291462, 1051649, 1051649, 3147779, 7340039, 3147779, 5243909, 3147779, 3072, 1051649, 5243909, 3147779, 4195332, 2099202, 7340039, 3072, 6291462, 3147779, 3072, 1051649, 3147779, 5243909, 6291462, 1051649, 4195332, 3072, 6291462, 4195332, 2099202, 5243909, 1051649, 4195332, 2099202, 7340039, 1051649, 4195332, 7340039, 1051649, 4195332, 3072, 5243909, 2099202, 5243909, 6291462, 3072, 3147779, 7340039, 1051649, 2099202, 4195332, 3147779, 5243909, 2099202, 6291462, 1051649, 7340039, 4195332, 1051649, 6291462, 3072, 7340039, 3147779, 6291462, 2099202, 3147779, 3072, 4195332, 2099202, 7340039, 3072, 3147779, 5243909, 3072, 6291462, 2099202, 7340039, 2099202, 6291462, 3072, 3147779, 5243909, 2099202, 3072, 6291462, 1051649, 4195332, 6291462, 1051649, 6291462, 4195332, 7340039, 3072, 3147779, 4195332, 5243909, 3072, 3147779, 1051649, 5243909, 4195332, 7340039, 3072, 7340039, 2099202, 6291462, 3147779, 7340039, 2099202, 6291462, 1051649, 4195332, 6291462, 1051649, 7340039, 2099202, 3072, 5243909, 1051649, 5243909, 6291462, 1051649, 5243909, 1051649, 4195332, 4195332, 5243909, 2099202, + 6291462, 4195332, 2099202, 6291462, 5243909, 3072, 4195332, 1051649, 6291462, 2099202, 4195332, 7340039, 2099202, 3072, 5243909, 1051649, 3147779, 5243909, 1051649, 5243909, 7340039, 3147779, 3072, 4195332, 2099202, 6291462, 3147779, 2099202, 5243909, 3072, 6291462, 3147779, 6291462, 2099202, 5243909, 3147779, 5243909, 2099202, 6291462, 3147779, 7340039, 1051649, 6291462, 3072, 3147779, 7340039, 1051649, 4195332, 5243909, 6291462, 3072, 7340039, 3072, 5243909, 3147779, 3147779, 5243909, 3072, 5243909, 3147779, 4195332, 2099202, 4195332, 1051649, 6291462, 3147779, 4195332, 6291462, 3072, 3147779, 6291462, 1051649, 7340039, 4195332, 2099202, 5243909, 3147779, 3072, 2099202, 6291462, 4195332, 1051649, 7340039, 4195332, 5243909, 7340039, 2099202, 3147779, 3147779, 5243909, 3072, 5243909, 2099202, 7340039, 1051649, 4195332, 7340039, 4195332, 7340039, 3072, 2099202, 1051649, 5243909, 3147779, 1051649, 3072, 5243909, 1051649, 3072, 4195332, 7340039, 2099202, 3147779, 5243909, 1051649, 4195332, 6291462, 2099202, 6291462, 3072, 2099202, 6291462, 3147779, 7340039, 3072, 7340039, 3072, 3147779, + 1051649, 2099202, 7340039, 3072, 4195332, 7340039, 2099202, 7340039, 4195332, 1051649, 6291462, 3072, 3147779, 7340039, 4195332, 6291462, 3072, 7340039, 2099202, 4195332, 2099202, 5243909, 7340039, 3072, 7340039, 1051649, 6291462, 3072, 7340039, 3147779, 1051649, 5243909, 3072, 6291462, 3072, 7340039, 3072, 4195332, 1051649, 5243909, 3072, 4195332, 3147779, 7340039, 1051649, 4195332, 3147779, 6291462, 3072, 2099202, 5243909, 4195332, 2099202, 7340039, 1051649, 6291462, 1051649, 3147779, 7340039, 1051649, 6291462, 3072, 7340039, 5243909, 3072, 7340039, 1051649, 2099202, 7340039, 4195332, 5243909, 2099202, 4195332, 3072, 6291462, 1051649, 6291462, 3147779, 7340039, 4195332, 3072, 6291462, 1051649, 3147779, 3072, 2099202, 6291462, 3072, 7340039, 1051649, 7340039, 1051649, 5243909, 1051649, 6291462, 2099202, 3072, 2099202, 5243909, 3147779, 6291462, 4195332, 3072, 6291462, 4195332, 7340039, 3147779, 5243909, 6291462, 3147779, 1051649, 6291462, 3072, 7340039, 4195332, 3072, 2099202, 4195332, 3147779, 5243909, 4195332, 3072, 2099202, 5243909, 3147779, 1051649, 6291462, 5243909, + 7340039, 4195332, 1051649, 6291462, 3147779, 3072, 5243909, 1051649, 3147779, 7340039, 2099202, 5243909, 6291462, 1051649, 1051649, 4195332, 3147779, 6291462, 4195332, 3072, 6291462, 1051649, 3147779, 4195332, 5243909, 3147779, 5243909, 4195332, 3147779, 1051649, 7340039, 2099202, 7340039, 4195332, 3147779, 2099202, 6291462, 3147779, 2099202, 7340039, 3147779, 6291462, 3072, 5243909, 2099202, 5243909, 1051649, 2099202, 7340039, 5243909, 2099202, 3147779, 6291462, 2099202, 4195332, 3072, 6291462, 4195332, 2099202, 5243909, 2099202, 5243909, 2099202, 4195332, 3147779, 5243909, 1051649, 5243909, 1051649, 5243909, 3072, 6291462, 7340039, 2099202, 3147779, 7340039, 3072, 5243909, 1051649, 5243909, 3147779, 2099202, 5243909, 5243909, 7340039, 4195332, 1051649, 5243909, 4195332, 3147779, 2099202, 4195332, 6291462, 3072, 3147779, 5243909, 3147779, 6291462, 1051649, 4195332, 1051649, 7340039, 3147779, 1051649, 2099202, 4195332, 1051649, 7340039, 2099202, 1051649, 5243909, 3147779, 5243909, 2099202, 4195332, 6291462, 7340039, 3072, 7340039, 1051649, 7340039, 3147779, 5243909, 1051649, 4195332, 5243909, 2099202, 3147779, + 3072, 4195332, 5243909, 2099202, 5243909, 2099202, 4195332, 6291462, 3072, 4195332, 1051649, 3147779, 3072, 3147779, 7340039, 2099202, 6291462, 1051649, 2099202, 7340039, 4195332, 2099202, 6291462, 1051649, 7340039, 3072, 1051649, 2099202, 6291462, 4195332, 5243909, 3072, 4195332, 1051649, 4195332, 5243909, 1051649, 7340039, 5243909, 2099202, 1051649, 3147779, 6291462, 2099202, 7340039, 3072, 4195332, 7340039, 3147779, 1051649, 6291462, 1051649, 3072, 7340039, 4195332, 5243909, 2099202, 7340039, 4195332, 3072, 7340039, 3147779, 3072, 6291462, 1051649, 6291462, 4195332, 3147779, 2099202, 7340039, 2099202, 3147779, 1051649, 5243909, 4195332, 1051649, 5243909, 2099202, 7340039, 3147779, 1051649, 7340039, 3072, 3147779, 1051649, 4195332, 3072, 7340039, 3072, 6291462, 5243909, 3072, 4195332, 3147779, 6291462, 3072, 7340039, 2099202, 5243909, 3072, 5243909, 2099202, 6291462, 5243909, 6291462, 3072, 5243909, 2099202, 4195332, 6291462, 2099202, 7340039, 3072, 3147779, 6291462, 2099202, 1051649, 5243909, 3147779, 2099202, 3072, 6291462, 1051649, 7340039, 3072, 6291462, 1051649, 5243909, + 2099202, 3147779, 3072, 7340039, 1051649, 6291462, 3072, 2099202, 6291462, 5243909, 7340039, 5243909, 4195332, 6291462, 5243909, 3072, 3147779, 5243909, 3147779, 5243909, 1051649, 5243909, 3072, 6291462, 2099202, 4195332, 7340039, 3147779, 3072, 7340039, 2099202, 3147779, 6291462, 2099202, 7340039, 1051649, 3147779, 4195332, 3072, 5243909, 7340039, 4195332, 1051649, 4195332, 2099202, 6291462, 3147779, 3072, 1051649, 5243909, 3147779, 7340039, 4195332, 3147779, 2099202, 1051649, 6291462, 3072, 3147779, 6291462, 1051649, 5243909, 1051649, 7340039, 4195332, 2099202, 3072, 7340039, 3072, 4195332, 5243909, 7340039, 3147779, 3072, 7340039, 2099202, 4195332, 6291462, 3072, 6291462, 5243909, 4195332, 2099202, 6291462, 7340039, 3147779, 6291462, 2099202, 3147779, 5243909, 2099202, 6291462, 2099202, 7340039, 2099202, 4195332, 1051649, 6291462, 4195332, 7340039, 3147779, 4195332, 3072, 3147779, 2099202, 7340039, 4195332, 1051649, 7340039, 3072, 4195332, 1051649, 6291462, 5243909, 1051649, 3147779, 5243909, 3072, 6291462, 5243909, 6291462, 3147779, 4195332, 3147779, 7340039, 3147779, 4195332, 6291462, + 7340039, 5243909, 6291462, 1051649, 5243909, 3147779, 7340039, 4195332, 2099202, 2099202, 3147779, 1051649, 7340039, 1051649, 2099202, 7340039, 4195332, 1051649, 7340039, 3072, 7340039, 2099202, 5243909, 3147779, 3072, 5243909, 2099202, 4195332, 5243909, 1051649, 4195332, 6291462, 1051649, 5243909, 3072, 4195332, 6291462, 1051649, 7340039, 2099202, 3072, 5243909, 6291462, 3072, 6291462, 3147779, 4195332, 7340039, 4195332, 5243909, 3072, 1051649, 5243909, 3072, 7340039, 5243909, 3147779, 1051649, 5243909, 2099202, 4195332, 3147779, 6291462, 1051649, 3147779, 5243909, 6291462, 3147779, 6291462, 2099202, 3072, 1051649, 6291462, 4195332, 2099202, 7340039, 3072, 3147779, 1051649, 3147779, 3072, 7340039, 2099202, 4195332, 3072, 5243909, 2099202, 6291462, 1051649, 7340039, 1051649, 3147779, 7340039, 3072, 4195332, 3147779, 7340039, 2099202, 3072, 3147779, 1051649, 6291462, 4195332, 7340039, 1051649, 3147779, 3072, 6291462, 3147779, 3147779, 7340039, 3147779, 4195332, 3072, 7340039, 4195332, 7340039, 3147779, 4195332, 1051649, 2099202, 5243909, 3072, 6291462, 2099202, 3072, 5243909, 1051649, + 2099202, 3072, 3147779, 4195332, 7340039, 3072, 4195332, 1051649, 6291462, 3072, 5243909, 3072, 2099202, 5243909, 4195332, 3072, 3147779, 6291462, 2099202, 3147779, 4195332, 3147779, 7340039, 1051649, 6291462, 3147779, 6291462, 3072, 7340039, 2099202, 7340039, 3072, 6291462, 2099202, 7340039, 3147779, 3072, 5243909, 1051649, 4195332, 6291462, 1051649, 3147779, 5243909, 2099202, 3072, 5243909, 1051649, 2099202, 7340039, 3147779, 6291462, 2099202, 4195332, 6291462, 1051649, 6291462, 3147779, 5243909, 3072, 7340039, 3072, 7340039, 2099202, 4195332, 3072, 2099202, 1051649, 4195332, 5243909, 6291462, 5243909, 2099202, 3072, 6291462, 1051649, 5243909, 6291462, 4195332, 6291462, 4195332, 1051649, 5243909, 1051649, 3147779, 6291462, 3072, 5243909, 3147779, 3147779, 4195332, 6291462, 1051649, 5243909, 1051649, 5243909, 3072, 5243909, 6291462, 4195332, 7340039, 1051649, 5243909, 3072, 5243909, 6291462, 3147779, 5243909, 2099202, 6291462, 3072, 5243909, 2099202, 5243909, 2099202, 1051649, 3072, 5243909, 1051649, 7340039, 4195332, 2099202, 7340039, 1051649, 4195332, 7340039, 2099202, 6291462, + 5243909, 4195332, 7340039, 3072, 2099202, 5243909, 3147779, 6291462, 4195332, 3147779, 7340039, 4195332, 6291462, 3072, 6291462, 5243909, 6291462, 3072, 5243909, 1051649, 6291462, 3072, 2099202, 5243909, 4195332, 1051649, 2099202, 5243909, 3147779, 4195332, 1051649, 3147779, 5243909, 4195332, 1051649, 6291462, 4195332, 3147779, 7340039, 2099202, 3072, 7340039, 2099202, 7340039, 3147779, 6291462, 2099202, 4195332, 6291462, 3072, 5243909, 1051649, 6291462, 3072, 2099202, 4195332, 1051649, 7340039, 3072, 6291462, 5243909, 2099202, 4195332, 5243909, 1051649, 7340039, 5243909, 7340039, 1051649, 3147779, 3147779, 1051649, 7340039, 4195332, 3147779, 5243909, 3147779, 2099202, 1051649, 5243909, 2099202, 6291462, 3147779, 7340039, 4195332, 1051649, 4195332, 7340039, 3072, 7340039, 3072, 2099202, 6291462, 3147779, 7340039, 2099202, 4195332, 3147779, 2099202, 3072, 2099202, 5243909, 3147779, 2099202, 4195332, 1051649, 2099202, 6291462, 3072, 5243909, 2099202, 6291462, 1051649, 7340039, 3147779, 6291462, 4195332, 2099202, 7340039, 3147779, 3072, 6291462, 1051649, 5243909, 2099202, 4195332, 1051649, 3147779, + 1051649, 3072, 5243909, 3147779, 6291462, 1051649, 2099202, 1051649, 6291462, 1051649, 5243909, 2099202, 3147779, 7340039, 2099202, 1051649, 2099202, 4195332, 3147779, 7340039, 2099202, 4195332, 6291462, 1051649, 3147779, 7340039, 4195332, 6291462, 3072, 6291462, 2099202, 5243909, 3072, 3147779, 7340039, 3147779, 2099202, 6291462, 3072, 5243909, 3147779, 4195332, 5243909, 3072, 1051649, 6291462, 3072, 7340039, 2099202, 4195332, 3147779, 6291462, 2099202, 7340039, 5243909, 3147779, 5243909, 2099202, 4195332, 3147779, 1051649, 3147779, 6291462, 3072, 6291462, 3147779, 1051649, 4195332, 6291462, 3072, 4195332, 6291462, 2099202, 5243909, 1051649, 7340039, 1051649, 4195332, 7340039, 3072, 7340039, 1051649, 4195332, 2099202, 3072, 6291462, 1051649, 4195332, 2099202, 5243909, 3147779, 5243909, 1051649, 4195332, 3072, 6291462, 1051649, 7340039, 3147779, 7340039, 5243909, 3072, 6291462, 2099202, 7340039, 4195332, 7340039, 1051649, 4195332, 7340039, 1051649, 3147779, 4195332, 3072, 6291462, 1051649, 5243909, 3147779, 3072, 6291462, 5243909, 3147779, 4195332, 7340039, 3072, 6291462, 3147779, 7340039, + 7340039, 4195332, 1051649, 7340039, 3072, 4195332, 7340039, 5243909, 3147779, 3072, 5243909, 1051649, 5243909, 3072, 4195332, 7340039, 3147779, 5243909, 1051649, 4195332, 3072, 7340039, 3147779, 7340039, 3072, 6291462, 3072, 5243909, 1051649, 2099202, 7340039, 4195332, 6291462, 1051649, 5243909, 3072, 6291462, 1051649, 5243909, 1051649, 6291462, 3072, 3147779, 6291462, 4195332, 3147779, 5243909, 1051649, 5243909, 1051649, 7340039, 1051649, 4195332, 2099202, 3072, 6291462, 3072, 7340039, 2099202, 5243909, 7340039, 1051649, 2099202, 7340039, 3147779, 3072, 7340039, 3147779, 2099202, 5243909, 7340039, 1051649, 3147779, 3072, 6291462, 3072, 6291462, 3147779, 2099202, 5243909, 3147779, 3072, 5243909, 2099202, 7340039, 3147779, 5243909, 2099202, 6291462, 1051649, 7340039, 2099202, 6291462, 5243909, 2099202, 4195332, 5243909, 3072, 6291462, 1051649, 4195332, 7340039, 2099202, 6291462, 3072, 3147779, 3072, 5243909, 3147779, 2099202, 5243909, 3072, 7340039, 4195332, 2099202, 7340039, 1051649, 6291462, 4195332, 2099202, 1051649, 6291462, 3072, 2099202, 5243909, 1051649, 4195332, 2099202, + 3072, 3147779, 6291462, 2099202, 5243909, 3147779, 3072, 2099202, 4195332, 7340039, 3147779, 7340039, 2099202, 4195332, 1051649, 1051649, 6291462, 3072, 6291462, 2099202, 5243909, 2099202, 3072, 5243909, 2099202, 4195332, 2099202, 3147779, 7340039, 3147779, 5243909, 3072, 1051649, 6291462, 2099202, 7340039, 2099202, 4195332, 4195332, 7340039, 2099202, 6291462, 4195332, 1051649, 7340039, 2099202, 3072, 7340039, 3147779, 6291462, 3147779, 3072, 7340039, 4195332, 2099202, 5243909, 4195332, 4195332, 1051649, 6291462, 3072, 4195332, 5243909, 2099202, 4195332, 5243909, 2099202, 3072, 6291462, 3147779, 3072, 4195332, 7340039, 4195332, 2099202, 5243909, 4195332, 3072, 6291462, 2099202, 4195332, 6291462, 4195332, 6291462, 3072, 5243909, 1051649, 5243909, 3072, 4195332, 3147779, 3072, 1051649, 7340039, 1051649, 6291462, 1051649, 5243909, 2099202, 5243909, 3147779, 1051649, 4195332, 1051649, 5243909, 5243909, 6291462, 4195332, 3072, 6291462, 2099202, 7340039, 1051649, 3147779, 5243909, 3072, 4195332, 1051649, 7340039, 3147779, 7340039, 2099202, 5243909, 6291462, 2099202, 7340039, 3147779, 5243909, + 2099202, 6291462, 1051649, 7340039, 4195332, 1051649, 7340039, 3147779, 6291462, 1051649, 6291462, 3072, 7340039, 5243909, 6291462, 4195332, 2099202, 7340039, 3147779, 6291462, 1051649, 4195332, 5243909, 1051649, 6291462, 1051649, 7340039, 4195332, 3072, 5243909, 2099202, 6291462, 3147779, 4195332, 3072, 4195332, 3147779, 1051649, 6291462, 3072, 3147779, 4195332, 2099202, 7340039, 2099202, 5243909, 6291462, 4195332, 3072, 2099202, 5243909, 3147779, 5243909, 1051649, 7340039, 1051649, 3147779, 6291462, 3072, 4195332, 3147779, 6291462, 4195332, 3072, 6291462, 1051649, 5243909, 7340039, 4195332, 1051649, 7340039, 2099202, 5243909, 2099202, 6291462, 3147779, 2099202, 7340039, 5243909, 1051649, 7340039, 3072, 1051649, 3147779, 7340039, 2099202, 7340039, 3147779, 6291462, 2099202, 6291462, 7340039, 3147779, 5243909, 2099202, 3147779, 7340039, 3147779, 4195332, 3072, 6291462, 4195332, 3072, 7340039, 3147779, 2099202, 2099202, 1051649, 7340039, 4195332, 1051649, 3147779, 5243909, 3072, 6291462, 3147779, 7340039, 5243909, 2099202, 3072, 4195332, 5243909, 3072, 3147779, 1051649, 4195332, 3072, 6291462, + 5243909, 1051649, 4195332, 3147779, 2099202, 6291462, 5243909, 3072, 2099202, 4195332, 2099202, 4195332, 3147779, 3072, 2099202, 7340039, 4195332, 1051649, 4195332, 3072, 7340039, 3147779, 3147779, 7340039, 3072, 5243909, 3147779, 1051649, 7340039, 3072, 4195332, 5243909, 2099202, 7340039, 5243909, 1051649, 5243909, 7340039, 2099202, 3147779, 7340039, 1051649, 5243909, 3072, 4195332, 3147779, 1051649, 4195332, 7340039, 4195332, 1051649, 6291462, 2099202, 4195332, 5243909, 6291462, 1051649, 3147779, 7340039, 2099202, 5243909, 1051649, 3147779, 7340039, 2099202, 7340039, 1051649, 2099202, 4195332, 5243909, 1051649, 6291462, 3072, 5243909, 3072, 1051649, 5243909, 3072, 2099202, 3147779, 5243909, 3147779, 7340039, 5243909, 4195332, 1051649, 4195332, 1051649, 4195332, 3072, 4195332, 1051649, 4195332, 3072, 4195332, 6291462, 3072, 1051649, 7340039, 3147779, 6291462, 1051649, 6291462, 3147779, 3072, 4195332, 7340039, 3147779, 4195332, 2099202, 6291462, 2099202, 4195332, 7340039, 2099202, 4195332, 3072, 1051649, 6291462, 3147779, 6291462, 1051649, 7340039, 3147779, 6291462, 6291462, 1051649, 3147779, + 3072, 7340039, 5243909, 3072, 6291462, 1051649, 3147779, 5243909, 7340039, 3072, 6291462, 4195332, 6291462, 1051649, 5243909, 3072, 3147779, 6291462, 2099202, 5243909, 2099202, 6291462, 3072, 4195332, 3147779, 3072, 6291462, 5243909, 2099202, 6291462, 3147779, 1051649, 7340039, 3072, 3147779, 7340039, 3072, 2099202, 4195332, 6291462, 3072, 5243909, 3147779, 6291462, 5243909, 2099202, 6291462, 3072, 2099202, 7340039, 5243909, 3072, 7340039, 3072, 2099202, 3147779, 7340039, 3072, 5243909, 3147779, 3072, 6291462, 5243909, 3072, 3147779, 4195332, 3147779, 6291462, 3072, 2099202, 5243909, 3147779, 7340039, 3147779, 7340039, 6291462, 3147779, 7340039, 4195332, 7340039, 3072, 4195332, 2099202, 3072, 3147779, 6291462, 3072, 6291462, 7340039, 2099202, 7340039, 5243909, 2099202, 6291462, 1051649, 5243909, 3147779, 6291462, 2099202, 5243909, 1051649, 4195332, 2099202, 5243909, 7340039, 1051649, 6291462, 3072, 7340039, 3072, 5243909, 7340039, 3072, 3147779, 1051649, 6291462, 3147779, 5243909, 4195332, 5243909, 1051649, 4195332, 2099202, 4195332, 3072, 5243909, 3147779, 7340039, + 4195332, 3147779, 2099202, 5243909, 4195332, 7340039, 4195332, 1051649, 2099202, 5243909, 3072, 3147779, 1051649, 5243909, 3147779, 6291462, 1051649, 5243909, 4195332, 7340039, 1051649, 4195332, 1051649, 6291462, 4195332, 7340039, 2099202, 3147779, 5243909, 1051649, 3147779, 6291462, 2099202, 5243909, 1051649, 4195332, 6291462, 6291462, 1051649, 5243909, 2099202, 7340039, 1051649, 2099202, 1051649, 7340039, 1051649, 6291462, 5243909, 3072, 3147779, 4195332, 2099202, 5243909, 7340039, 3072, 4195332, 2099202, 6291462, 1051649, 7340039, 1051649, 2099202, 5243909, 7340039, 3072, 6291462, 1051649, 4195332, 7340039, 3147779, 3072, 4195332, 2099202, 4195332, 3072, 4195332, 1051649, 3147779, 1051649, 6291462, 2099202, 4195332, 6291462, 5243909, 2099202, 5243909, 3147779, 1051649, 5243909, 3072, 2099202, 7340039, 3147779, 6291462, 3072, 7340039, 4195332, 3072, 4195332, 7340039, 3072, 7340039, 1051649, 3147779, 6291462, 1051649, 5243909, 2099202, 5243909, 1051649, 3147779, 5243909, 4195332, 6291462, 2099202, 1051649, 7340039, 2099202, 3072, 7340039, 3147779, 6291462, 1051649, 7340039, 1051649, 5243909, 2099202, + 3072, 6291462, 1051649, 7340039, 2099202, 3072, 3147779, 6291462, 7340039, 2099202, 6291462, 2099202, 7340039, 3147779, 7340039, 1051649, 7340039, 3147779, 3072, 2099202, 4195332, 7340039, 5243909, 2099202, 1051649, 5243909, 1051649, 6291462, 3072, 4195332, 7340039, 3072, 6291462, 3147779, 6291462, 3072, 2099202, 3147779, 3072, 4195332, 6291462, 3072, 4195332, 6291462, 5243909, 3147779, 3072, 3147779, 4195332, 3147779, 6291462, 1051649, 6291462, 3147779, 1051649, 6291462, 3147779, 7340039, 2099202, 5243909, 4195332, 3147779, 6291462, 4195332, 1051649, 5243909, 2099202, 3147779, 6291462, 1051649, 5243909, 2099202, 6291462, 3072, 5243909, 2099202, 7340039, 6291462, 3072, 6291462, 3147779, 7340039, 1051649, 2099202, 3072, 7340039, 2099202, 3072, 6291462, 2099202, 5243909, 4195332, 3072, 4195332, 2099202, 3147779, 1051649, 2099202, 6291462, 2099202, 3147779, 5243909, 3147779, 5243909, 4195332, 3072, 5243909, 4195332, 6291462, 3147779, 6291462, 2099202, 1051649, 7340039, 3072, 4195332, 6291462, 3072, 4195332, 6291462, 3147779, 3072, 5243909, 2099202, 5243909, 4195332, 3072, 6291462, + 2099202, 5243909, 4195332, 3072, 3147779, 6291462, 4195332, 3072, 4195332, 1051649, 3147779, 5243909, 3072, 4195332, 3072, 2099202, 5243909, 2099202, 5243909, 7340039, 1051649, 3072, 3147779, 6291462, 2099202, 7340039, 4195332, 3147779, 7340039, 2099202, 1051649, 5243909, 2099202, 4195332, 1051649, 5243909, 7340039, 4195332, 7340039, 2099202, 1051649, 5243909, 3147779, 1051649, 3072, 4195332, 7340039, 2099202, 7340039, 1051649, 5243909, 3072, 7340039, 1051649, 6291462, 4195332, 3072, 4195332, 1051649, 5243909, 1051649, 7340039, 3072, 2099202, 6291462, 4195332, 7340039, 4195332, 3072, 7340039, 1051649, 6291462, 1051649, 7340039, 3147779, 5243909, 1051649, 3147779, 5243909, 2099202, 5243909, 1051649, 6291462, 4195332, 5243909, 1051649, 4195332, 6291462, 3147779, 3147779, 7340039, 1051649, 3147779, 5243909, 3147779, 7340039, 6291462, 5243909, 1051649, 7340039, 1051649, 6291462, 3072, 2099202, 6291462, 2099202, 7340039, 2099202, 3072, 1051649, 4195332, 6291462, 4195332, 2099202, 5243909, 3147779, 4195332, 7340039, 2099202, 1051649, 4195332, 6291462, 2099202, 6291462, 3072, 3147779, 7340039, 4195332, + 7340039, 1051649, 3147779, 6291462, 5243909, 1051649, 7340039, 2099202, 6291462, 5243909, 3072, 6291462, 3147779, 6291462, 4195332, 7340039, 3072, 6291462, 1051649, 3147779, 6291462, 3147779, 5243909, 3072, 4195332, 1051649, 3072, 6291462, 2099202, 5243909, 3147779, 7340039, 3072, 3147779, 6291462, 4195332, 2099202, 1051649, 3147779, 5243909, 7340039, 3147779, 7340039, 4195332, 6291462, 2099202, 3147779, 5243909, 3072, 6291462, 3147779, 2099202, 4195332, 4195332, 1051649, 5243909, 2099202, 6291462, 3147779, 7340039, 3072, 4195332, 3147779, 6291462, 3072, 2099202, 3072, 5243909, 3147779, 4195332, 2099202, 5243909, 4195332, 2099202, 4195332, 3072, 6291462, 4195332, 1051649, 7340039, 3072, 5243909, 3147779, 1051649, 7340039, 3147779, 7340039, 1051649, 5243909, 3072, 4195332, 6291462, 2099202, 7340039, 1051649, 4195332, 3072, 3147779, 5243909, 3072, 4195332, 2099202, 7340039, 4195332, 3072, 4195332, 1051649, 3147779, 7340039, 5243909, 3072, 7340039, 3072, 5243909, 1051649, 7340039, 1051649, 2099202, 5243909, 3147779, 7340039, 1051649, 4195332, 1051649, 7340039, 4195332, 1051649, 2099202, + 3072, 4195332, 1051649, 5243909, 2099202, 3072, 5243909, 3147779, 1051649, 3147779, 7340039, 2099202, 5243909, 1051649, 4195332, 2099202, 5243909, 4195332, 3072, 5243909, 2099202, 7340039, 1051649, 6291462, 4195332, 7340039, 5243909, 3147779, 4195332, 3072, 6291462, 1051649, 4195332, 7340039, 2099202, 3072, 6291462, 2099202, 7340039, 3072, 4195332, 1051649, 4195332, 3072, 2099202, 6291462, 1051649, 4195332, 5243909, 1051649, 4195332, 7340039, 3147779, 3072, 6291462, 2099202, 7340039, 4195332, 1051649, 3147779, 6291462, 2099202, 7340039, 1051649, 5243909, 3147779, 7340039, 1051649, 6291462, 1051649, 7340039, 3147779, 3072, 6291462, 1051649, 7340039, 1051649, 2099202, 5243909, 3147779, 4195332, 2099202, 6291462, 3072, 5243909, 3072, 4195332, 2099202, 7340039, 3147779, 7340039, 1051649, 5243909, 3072, 6291462, 2099202, 7340039, 4195332, 2099202, 7340039, 3147779, 5243909, 1051649, 5243909, 7340039, 3147779, 6291462, 5243909, 2099202, 4195332, 3147779, 1051649, 6291462, 2099202, 5243909, 3072, 3147779, 6291462, 3072, 6291462, 2099202, 3147779, 7340039, 4195332, 3072, 6291462, 3147779, 5243909, + 7340039, 5243909, 7340039, 3072, 3147779, 7340039, 2099202, 7340039, 4195332, 4195332, 1051649, 6291462, 3072, 7340039, 1051649, 6291462, 2099202, 7340039, 3147779, 6291462, 3072, 4195332, 3147779, 1051649, 3147779, 3072, 2099202, 7340039, 1051649, 6291462, 2099202, 4195332, 5243909, 3072, 5243909, 3147779, 6291462, 4195332, 1051649, 5243909, 2099202, 6291462, 2099202, 5243909, 7340039, 1051649, 4195332, 7340039, 2099202, 4195332, 3072, 6291462, 2099202, 7340039, 3147779, 5243909, 3072, 2099202, 6291462, 4195332, 1051649, 5243909, 3072, 4195332, 5243909, 1051649, 4195332, 6291462, 2099202, 5243909, 3072, 2099202, 7340039, 3147779, 6291462, 3147779, 4195332, 7340039, 2099202, 6291462, 1051649, 7340039, 2099202, 6291462, 3147779, 4195332, 2099202, 6291462, 1051649, 4195332, 3072, 5243909, 3147779, 4195332, 1051649, 5243909, 3147779, 3072, 6291462, 4195332, 3072, 6291462, 4195332, 2099202, 1051649, 5243909, 1051649, 3072, 7340039, 1051649, 5243909, 4195332, 3147779, 7340039, 1051649, 7340039, 2099202, 5243909, 2099202, 4195332, 3072, 5243909, 2099202, 5243909, 3147779, 2099202, 6291462, 1051649, + 3147779, 1051649, 2099202, 6291462, 4195332, 1051649, 5243909, 1051649, 3072, 6291462, 2099202, 3147779, 5243909, 1051649, 5243909, 3147779, 3072, 3147779, 1051649, 5243909, 2099202, 7340039, 2099202, 6291462, 6291462, 4195332, 5243909, 1051649, 5243909, 3147779, 7340039, 3072, 2099202, 4195332, 1051649, 7340039, 1051649, 3072, 6291462, 3147779, 5243909, 2099202, 6291462, 3072, 3147779, 5243909, 2099202, 3072, 7340039, 3147779, 6291462, 1051649, 5243909, 3147779, 3072, 7340039, 1051649, 6291462, 5243909, 3072, 7340039, 3147779, 3147779, 6291462, 2099202, 7340039, 2099202, 3072, 4195332, 3147779, 6291462, 5243909, 4195332, 1051649, 5243909, 3072, 5243909, 3072, 4195332, 3072, 4195332, 5243909, 3072, 4195332, 1051649, 7340039, 3072, 6291462, 5243909, 2099202, 7340039, 1051649, 6291462, 2099202, 7340039, 1051649, 6291462, 5243909, 1051649, 3147779, 2099202, 1051649, 7340039, 2099202, 6291462, 3147779, 7340039, 3147779, 6291462, 2099202, 4195332, 3072, 6291462, 3072, 3147779, 4195332, 3147779, 6291462, 1051649, 7340039, 5243909, 1051649, 6291462, 3072, 7340039, 5243909, 3072, 4195332, + 6291462, 3147779, 4195332, 2099202, 6291462, 2099202, 3147779, 6291462, 5243909, 2099202, 7340039, 4195332, 3147779, 7340039, 2099202, 6291462, 4195332, 7340039, 5243909, 4195332, 1051649, 5243909, 3072, 4195332, 3072, 3147779, 1051649, 7340039, 4195332, 3072, 3147779, 5243909, 7340039, 3147779, 6291462, 3147779, 5243909, 7340039, 4195332, 1051649, 7340039, 3072, 3147779, 7340039, 5243909, 3072, 6291462, 5243909, 1051649, 6291462, 2099202, 4195332, 1051649, 5243909, 2099202, 4195332, 5243909, 1051649, 3147779, 5243909, 2099202, 1051649, 7340039, 3072, 6291462, 3147779, 1051649, 5243909, 7340039, 1051649, 3147779, 3072, 2099202, 7340039, 2099202, 4195332, 3147779, 7340039, 2099202, 6291462, 1051649, 6291462, 3147779, 7340039, 4195332, 2099202, 5243909, 3147779, 3072, 5243909, 3147779, 4195332, 3072, 5243909, 2099202, 3147779, 4195332, 2099202, 1051649, 7340039, 5243909, 6291462, 3072, 5243909, 4195332, 3072, 5243909, 2099202, 3147779, 6291462, 1051649, 7340039, 2099202, 5243909, 1051649, 6291462, 3072, 7340039, 4195332, 1051649, 3147779, 7340039, 2099202, 4195332, 1051649, 3147779, 6291462, 2099202, + 5243909, 3072, 7340039, 1051649, 5243909, 3072, 6291462, 3072, 3147779, 5243909, 3072, 6291462, 3072, 4195332, 4195332, 3072, 1051649, 2099202, 4195332, 3072, 6291462, 3147779, 7340039, 2099202, 5243909, 7340039, 4195332, 2099202, 6291462, 2099202, 6291462, 2099202, 1051649, 5243909, 3072, 4195332, 3072, 3147779, 2099202, 6291462, 1051649, 5243909, 4195332, 1051649, 2099202, 7340039, 3147779, 1051649, 4195332, 3147779, 5243909, 3072, 7340039, 3147779, 6291462, 1051649, 4195332, 2099202, 7340039, 3072, 4195332, 5243909, 2099202, 4195332, 3147779, 3072, 6291462, 3147779, 2099202, 4195332, 7340039, 4195332, 6291462, 1051649, 6291462, 1051649, 5243909, 3072, 5243909, 3147779, 7340039, 3147779, 2099202, 4195332, 3072, 7340039, 2099202, 6291462, 4195332, 3072, 6291462, 1051649, 7340039, 4195332, 3072, 7340039, 3072, 3147779, 6291462, 3072, 2099202, 3147779, 4195332, 3147779, 2099202, 7340039, 4195332, 3072, 7340039, 3072, 5243909, 3147779, 7340039, 4195332, 5243909, 2099202, 4195332, 3072, 3147779, 6291462, 4195332, 3072, 3147779, 5243909, 6291462, 2099202, 7340039, 3072, + 2099202, 7340039, 3147779, 4195332, 2099202, 7340039, 4195332, 6291462, 1051649, 4195332, 1051649, 7340039, 5243909, 2099202, 6291462, 3147779, 7340039, 6291462, 1051649, 6291462, 2099202, 5243909, 1051649, 6291462, 1051649, 2099202, 6291462, 3072, 3147779, 5243909, 3072, 6291462, 1051649, 4195332, 6291462, 2099202, 5243909, 7340039, 3072, 4195332, 3147779, 1051649, 7340039, 3147779, 6291462, 1051649, 4195332, 6291462, 7340039, 3072, 3147779, 7340039, 2099202, 2099202, 3072, 5243909, 7340039, 3072, 6291462, 2099202, 7340039, 1051649, 6291462, 3072, 5243909, 7340039, 2099202, 6291462, 3072, 6291462, 3072, 2099202, 5243909, 3147779, 3072, 6291462, 2099202, 7340039, 1051649, 3147779, 3072, 5243909, 6291462, 3072, 5243909, 3147779, 1051649, 1051649, 2099202, 7340039, 4195332, 3147779, 5243909, 1051649, 6291462, 2099202, 5243909, 6291462, 4195332, 7340039, 5243909, 3072, 7340039, 1051649, 6291462, 3072, 3147779, 6291462, 2099202, 5243909, 6291462, 1051649, 3147779, 3072, 2099202, 7340039, 3147779, 6291462, 5243909, 3072, 2099202, 6291462, 7340039, 1051649, 4195332, 3072, 5243909, 3147779, + 4195332, 3072, 5243909, 1051649, 5243909, 3147779, 1051649, 4195332, 3147779, 7340039, 3147779, 2099202, 1051649, 6291462, 1051649, 5243909, 3072, 3147779, 4195332, 3147779, 7340039, 3072, 4195332, 3147779, 7340039, 5243909, 1051649, 7340039, 4195332, 1051649, 5243909, 3147779, 4195332, 7340039, 1051649, 7340039, 2099202, 5243909, 2099202, 7340039, 3147779, 6291462, 2099202, 4195332, 3072, 5243909, 2099202, 3072, 2099202, 6291462, 5243909, 1051649, 6291462, 4195332, 7340039, 2099202, 3147779, 5243909, 3147779, 4195332, 3072, 5243909, 3147779, 7340039, 2099202, 4195332, 1051649, 4195332, 5243909, 2099202, 4195332, 7340039, 1051649, 4195332, 7340039, 2099202, 4195332, 1051649, 6291462, 4195332, 7340039, 1051649, 2099202, 6291462, 1051649, 5243909, 7340039, 5243909, 6291462, 1051649, 6291462, 2099202, 3072, 3147779, 4195332, 7340039, 1051649, 3147779, 3072, 2099202, 6291462, 4195332, 1051649, 5243909, 2099202, 5243909, 4195332, 1051649, 4195332, 3147779, 1051649, 4195332, 7340039, 4195332, 6291462, 1051649, 5243909, 1051649, 2099202, 7340039, 4195332, 2099202, 3072, 5243909, 6291462, 3147779, 1051649, 7340039, + 6291462, 2099202, 3147779, 6291462, 1051649, 7340039, 3072, 7340039, 2099202, 5243909, 3072, 5243909, 7340039, 4195332, 1051649, 5243909, 2099202, 7340039, 2099202, 4195332, 1051649, 5243909, 2099202, 6291462, 3072, 3147779, 1051649, 5243909, 3147779, 7340039, 2099202, 7340039, 3072, 2099202, 3147779, 4195332, 1051649, 3147779, 4195332, 3072, 5243909, 3072, 5243909, 4195332, 7340039, 2099202, 7340039, 5243909, 3147779, 4195332, 3072, 4195332, 1051649, 5243909, 1051649, 3147779, 6291462, 1051649, 7340039, 1051649, 3147779, 6291462, 1051649, 4195332, 3072, 5243909, 1051649, 7340039, 2099202, 7340039, 1051649, 3147779, 6291462, 3147779, 3072, 3147779, 5243909, 6291462, 3147779, 3072, 2099202, 5243909, 3147779, 4195332, 7340039, 3072, 4195332, 3147779, 3072, 4195332, 2099202, 7340039, 5243909, 6291462, 2099202, 3072, 5243909, 5243909, 6291462, 3147779, 1051649, 7340039, 4195332, 3072, 7340039, 1051649, 6291462, 6291462, 3072, 7340039, 2099202, 5243909, 2099202, 3072, 6291462, 3147779, 3072, 7340039, 4195332, 1051649, 5243909, 3147779, 4195332, 2099202, 3072, 7340039, 4195332, 1051649, + 2099202, 4195332, 7340039, 3072, 4195332, 3147779, 6291462, 3147779, 3072, 4195332, 6291462, 2099202, 3072, 3147779, 7340039, 3072, 6291462, 1051649, 5243909, 3072, 7340039, 3147779, 6291462, 1051649, 4195332, 7340039, 2099202, 4195332, 3072, 6291462, 3072, 4195332, 5243909, 6291462, 3072, 4195332, 6291462, 1051649, 7340039, 6291462, 2099202, 6291462, 2099202, 3072, 1051649, 3147779, 4195332, 1051649, 6291462, 2099202, 7340039, 3147779, 6291462, 3072, 4195332, 6291462, 3072, 4195332, 2099202, 6291462, 4195332, 3072, 6291462, 3147779, 7340039, 3147779, 5243909, 3072, 5243909, 3147779, 6291462, 5243909, 3072, 7340039, 5243909, 1051649, 4195332, 3072, 2099202, 5243909, 6291462, 1051649, 7340039, 3072, 3147779, 4195332, 2099202, 5243909, 2099202, 7340039, 3147779, 3072, 4195332, 1051649, 5243909, 7340039, 3147779, 1051649, 3072, 4195332, 5243909, 2099202, 3147779, 5243909, 3147779, 4195332, 3072, 3147779, 5243909, 1051649, 6291462, 3072, 5243909, 3147779, 3147779, 4195332, 5243909, 2099202, 4195332, 7340039, 3072, 6291462, 7340039, 1051649, 5243909, 2099202, 3147779, 6291462, + 3072, 3147779, 1051649, 5243909, 6291462, 1051649, 2099202, 6291462, 2099202, 5243909, 1051649, 6291462, 3147779, 5243909, 2099202, 4195332, 4195332, 3147779, 7340039, 4195332, 1051649, 5243909, 3072, 3147779, 5243909, 3072, 6291462, 2099202, 7340039, 2099202, 3147779, 5243909, 1051649, 3147779, 5243909, 2099202, 6291462, 3072, 3147779, 4195332, 1051649, 3147779, 6291462, 4195332, 7340039, 5243909, 3072, 7340039, 3072, 5243909, 1051649, 5243909, 4195332, 3147779, 7340039, 2099202, 2099202, 5243909, 5243909, 3072, 7340039, 4195332, 2099202, 5243909, 2099202, 1051649, 7340039, 3147779, 1051649, 4195332, 3072, 2099202, 4195332, 2099202, 4195332, 7340039, 2099202, 3147779, 7340039, 1051649, 4195332, 5243909, 2099202, 5243909, 7340039, 1051649, 6291462, 1051649, 7340039, 1051649, 6291462, 3147779, 2099202, 7340039, 3147779, 1051649, 4195332, 6291462, 6291462, 2099202, 7340039, 3072, 2099202, 6291462, 1051649, 7340039, 5243909, 2099202, 7340039, 1051649, 4195332, 5243909, 2099202, 7340039, 3072, 7340039, 1051649, 6291462, 3072, 3147779, 5243909, 2099202, 1051649, 6291462, 4195332, 5243909, 3072, 5243909, + 7340039, 4195332, 7340039, 4195332, 2099202, 4195332, 5243909, 3072, 7340039, 1051649, 4195332, 3072, 6291462, 1051649, 7340039, 3072, 6291462, 2099202, 3072, 3147779, 6291462, 2099202, 7340039, 3147779, 6291462, 3147779, 5243909, 1051649, 5243909, 3072, 7340039, 1051649, 4195332, 6291462, 1051649, 7340039, 3147779, 5243909, 6291462, 1051649, 5243909, 7340039, 3072, 5243909, 2099202, 1051649, 6291462, 3147779, 4195332, 2099202, 7340039, 3072, 2099202, 5243909, 3072, 4195332, 7340039, 3147779, 1051649, 6291462, 2099202, 1051649, 7340039, 3072, 6291462, 4195332, 2099202, 6291462, 6291462, 1051649, 7340039, 5243909, 1051649, 6291462, 3072, 3147779, 5243909, 7340039, 1051649, 6291462, 3072, 3147779, 6291462, 3072, 2099202, 6291462, 4195332, 5243909, 2099202, 5243909, 3072, 5243909, 1051649, 4195332, 2099202, 7340039, 3072, 4195332, 2099202, 1051649, 5243909, 3147779, 7340039, 4195332, 3072, 2099202, 4195332, 1051649, 3147779, 6291462, 3147779, 7340039, 1051649, 6291462, 1051649, 6291462, 3147779, 2099202, 5243909, 3147779, 1051649, 6291462, 4195332, 3072, 3147779, 1051649, 7340039, 1051649, + 5243909, 2099202, 3072, 6291462, 3072, 7340039, 2099202, 6291462, 3147779, 4195332, 7340039, 3147779, 2099202, 5243909, 3147779, 1051649, 2099202, 5243909, 4195332, 6291462, 2099202, 5243909, 1051649, 4195332, 3072, 2099202, 4195332, 7340039, 2099202, 4195332, 3147779, 6291462, 3072, 2099202, 5243909, 3072, 2099202, 1051649, 7340039, 3147779, 2099202, 4195332, 3147779, 1051649, 6291462, 5243909, 2099202, 1051649, 6291462, 4195332, 1051649, 3147779, 6291462, 1051649, 6291462, 3147779, 3072, 5243909, 6291462, 2099202, 4195332, 5243909, 1051649, 3147779, 3147779, 5243909, 3072, 4195332, 3072, 4195332, 3147779, 3072, 5243909, 5243909, 3147779, 6291462, 3072, 2099202, 4195332, 6291462, 3147779, 7340039, 1051649, 3147779, 6291462, 2099202, 3072, 3147779, 6291462, 3147779, 3147779, 7340039, 2099202, 6291462, 3072, 4195332, 6291462, 1051649, 7340039, 4195332, 6291462, 3072, 2099202, 4195332, 6291462, 7340039, 2099202, 6291462, 4195332, 3072, 4195332, 3072, 4195332, 3147779, 5243909, 2099202, 3072, 7340039, 1051649, 6291462, 4195332, 2099202, 5243909, 7340039, 5243909, 6291462, 3147779, 2099202, + 3072, 4195332, 6291462, 3147779, 5243909, 1051649, 5243909, 3072, 5243909, 1051649, 2099202, 5243909, 7340039, 3072, 4195332, 5243909, 7340039, 3072, 7340039, 1051649, 6291462, 3072, 6291462, 1051649, 7340039, 5243909, 4195332, 3072, 6291462, 1051649, 7340039, 1051649, 5243909, 3147779, 6291462, 4195332, 7340039, 4195332, 3072, 5243909, 7340039, 3072, 5243909, 7340039, 3072, 3147779, 4195332, 7340039, 3072, 5243909, 3147779, 7340039, 5243909, 1051649, 4195332, 7340039, 2099202, 4195332, 1051649, 3147779, 7340039, 3072, 6291462, 5243909, 1051649, 7340039, 2099202, 7340039, 3147779, 5243909, 7340039, 3147779, 2099202, 1051649, 7340039, 1051649, 4195332, 6291462, 3072, 2099202, 4195332, 1051649, 5243909, 4195332, 1051649, 7340039, 3147779, 6291462, 3072, 7340039, 4195332, 3072, 5243909, 3147779, 6291462, 2099202, 5243909, 3147779, 3072, 3147779, 1051649, 5243909, 6291462, 3147779, 3072, 1051649, 5243909, 3072, 2099202, 6291462, 2099202, 6291462, 2099202, 7340039, 3072, 5243909, 4195332, 5243909, 3072, 4195332, 7340039, 3072, 3147779, 1051649, 2099202, 3072, 4195332, 6291462, + 3147779, 7340039, 2099202, 1051649, 3147779, 6291462, 3147779, 7340039, 2099202, 4195332, 6291462, 3072, 4195332, 3147779, 7340039, 3147779, 1051649, 4195332, 2099202, 4195332, 3147779, 7340039, 2099202, 5243909, 3147779, 2099202, 1051649, 7340039, 3147779, 2099202, 5243909, 4195332, 1051649, 7340039, 3072, 2099202, 1051649, 6291462, 3147779, 2099202, 1051649, 4195332, 1051649, 4195332, 2099202, 7340039, 3072, 3147779, 2099202, 3147779, 6291462, 3072, 2099202, 7340039, 3147779, 3072, 6291462, 5243909, 3072, 5243909, 2099202, 4195332, 3147779, 2099202, 6291462, 3072, 4195332, 2099202, 6291462, 1051649, 3072, 6291462, 7340039, 2099202, 4195332, 6291462, 1051649, 5243909, 3147779, 4195332, 7340039, 3072, 7340039, 3147779, 4195332, 2099202, 5243909, 1051649, 4195332, 1051649, 5243909, 2099202, 6291462, 3072, 4195332, 1051649, 7340039, 2099202, 6291462, 5243909, 7340039, 3147779, 1051649, 5243909, 7340039, 3147779, 5243909, 3147779, 7340039, 3147779, 5243909, 3147779, 1051649, 5243909, 2099202, 7340039, 1051649, 3147779, 6291462, 1051649, 2099202, 5243909, 3147779, 7340039, 4195332, 7340039, 1051649, 5243909, + 3147779, 3072, 5243909, 7340039, 4195332, 3072, 2099202, 4195332, 1051649, 7340039, 1051649, 3147779, 6291462, 1051649, 3072, 6291462, 5243909, 2099202, 6291462, 3072, 5243909, 1051649, 4195332, 3072, 6291462, 3147779, 6291462, 4195332, 3072, 6291462, 3072, 6291462, 3147779, 3147779, 4195332, 5243909, 7340039, 3072, 3147779, 7340039, 5243909, 6291462, 3147779, 7340039, 3147779, 5243909, 6291462, 1051649, 6291462, 4195332, 1051649, 4195332, 5243909, 3072, 4195332, 6291462, 1051649, 7340039, 3147779, 6291462, 1051649, 7340039, 3072, 7340039, 4195332, 3147779, 6291462, 3072, 4195332, 5243909, 2099202, 4195332, 1051649, 4195332, 3072, 7340039, 2099202, 5243909, 1051649, 7340039, 2099202, 5243909, 1051649, 6291462, 3072, 7340039, 1051649, 5243909, 2099202, 7340039, 3072, 5243909, 3147779, 1051649, 7340039, 2099202, 4195332, 1051649, 5243909, 2099202, 3072, 4195332, 7340039, 3072, 2099202, 4195332, 3072, 7340039, 1051649, 4195332, 3072, 7340039, 6291462, 4195332, 1051649, 4195332, 6291462, 2099202, 7340039, 3147779, 7340039, 3072, 6291462, 2099202, 3072, 3147779, 5243909, 2099202, + 4195332, 6291462, 1051649, 6291462, 3072, 5243909, 6291462, 3147779, 5243909, 2099202, 4195332, 7340039, 2099202, 6291462, 5243909, 2099202, 3072, 7340039, 3147779, 7340039, 2099202, 7340039, 3147779, 5243909, 1051649, 6291462, 3072, 2099202, 7340039, 4195332, 2099202, 5243909, 3072, 6291462, 4195332, 1051649, 3147779, 4195332, 6291462, 3072, 2099202, 4195332, 3072, 5243909, 1051649, 3072, 2099202, 5243909, 3072, 7340039, 2099202, 7340039, 2099202, 2099202, 6291462, 2099202, 4195332, 1051649, 3147779, 4195332, 2099202, 4195332, 5243909, 2099202, 3072, 6291462, 1051649, 6291462, 3147779, 1051649, 6291462, 2099202, 6291462, 3147779, 5243909, 2099202, 3072, 6291462, 3147779, 6291462, 3072, 3147779, 5243909, 2099202, 3147779, 6291462, 4195332, 3072, 6291462, 3147779, 4195332, 1051649, 7340039, 4195332, 3147779, 6291462, 3072, 7340039, 3147779, 3147779, 6291462, 2099202, 5243909, 3147779, 6291462, 1051649, 5243909, 2099202, 5243909, 1051649, 6291462, 2099202, 3072, 7340039, 3147779, 6291462, 3072, 5243909, 3072, 4195332, 1051649, 5243909, 2099202, 5243909, 4195332, 6291462, 3072, 7340039, + 5243909, 1051649, 4195332, 3147779, 2099202, 7340039, 1051649, 4195332, 3072, 6291462, 1051649, 5243909, 3072, 3147779, 1051649, 5243909, 4195332, 5243909, 1051649, 3147779, 3072, 4195332, 1051649, 7340039, 3147779, 2099202, 4195332, 5243909, 1051649, 5243909, 3147779, 7340039, 2099202, 7340039, 1051649, 5243909, 2099202, 7340039, 1051649, 4195332, 1051649, 6291462, 2099202, 3147779, 6291462, 4195332, 6291462, 2099202, 7340039, 3147779, 4195332, 1051649, 6291462, 5243909, 1051649, 3147779, 3072, 7340039, 5243909, 3072, 7340039, 1051649, 1051649, 5243909, 5243909, 3147779, 7340039, 1051649, 4195332, 7340039, 3147779, 5243909, 3072, 7340039, 1051649, 6291462, 4195332, 4195332, 1051649, 1051649, 4195332, 6291462, 3072, 7340039, 2099202, 3072, 3147779, 7340039, 2099202, 1051649, 5243909, 6291462, 2099202, 3072, 6291462, 4195332, 3147779, 5243909, 1051649, 7340039, 3072, 6291462, 1051649, 1051649, 4195332, 7340039, 3147779, 1051649, 7340039, 3147779, 4195332, 2099202, 5243909, 3147779, 1051649, 2099202, 4195332, 3147779, 7340039, 2099202, 6291462, 3147779, 1051649, 6291462, 1051649, 2099202, 5243909, 2099202, + 3072, 7340039, 1051649, 6291462, 1051649, 3147779, 7340039, 2099202, 6291462, 3147779, 7340039, 2099202, 4195332, 7340039, 3147779, 7340039, 3072, 2099202, 4195332, 6291462, 5243909, 2099202, 5243909, 3072, 5243909, 7340039, 3147779, 3072, 7340039, 1051649, 4195332, 3072, 5243909, 1051649, 3147779, 6291462, 3072, 2099202, 6291462, 5243909, 7340039, 3147779, 6291462, 3072, 7340039, 1051649, 4195332, 3072, 5243909, 1051649, 5243909, 4195332, 3072, 3147779, 5243909, 7340039, 6291462, 4195332, 3072, 6291462, 3147779, 6291462, 3147779, 7340039, 1051649, 2099202, 2099202, 4195332, 5243909, 3072, 3147779, 5243909, 2099202, 4195332, 3147779, 2099202, 7340039, 3072, 5243909, 7340039, 3147779, 2099202, 4195332, 4195332, 5243909, 6291462, 5243909, 2099202, 4195332, 7340039, 3147779, 3072, 4195332, 6291462, 1051649, 1051649, 5243909, 3072, 6291462, 2099202, 4195332, 3147779, 5243909, 6291462, 2099202, 3072, 5243909, 6291462, 3072, 6291462, 3072, 6291462, 1051649, 5243909, 7340039, 4195332, 6291462, 1051649, 3147779, 6291462, 3072, 7340039, 4195332, 2099202, 7340039, 4195332, 1051649, 7340039, + 4195332, 3147779, 7340039, 2099202, 4195332, 5243909, 3072, 5243909, 3147779, 3072, 4195332, 1051649, 5243909, 3072, 6291462, 2099202, 4195332, 6291462, 3072, 1051649, 3147779, 7340039, 3147779, 6291462, 2099202, 1051649, 4195332, 6291462, 3147779, 5243909, 2099202, 6291462, 3147779, 7340039, 3072, 4195332, 4195332, 5243909, 3072, 2099202, 3147779, 1051649, 4195332, 2099202, 5243909, 1051649, 7340039, 4195332, 3147779, 6291462, 3072, 7340039, 2099202, 7340039, 1051649, 3072, 2099202, 5243909, 2099202, 4195332, 2099202, 4195332, 3072, 3147779, 4195332, 5243909, 7340039, 3072, 6291462, 2099202, 7340039, 1051649, 6291462, 3072, 6291462, 1051649, 5243909, 2099202, 5243909, 3072, 6291462, 1051649, 7340039, 1051649, 3072, 4195332, 1051649, 6291462, 3072, 4195332, 1051649, 6291462, 2099202, 3147779, 5243909, 7340039, 2099202, 7340039, 4195332, 5243909, 2099202, 7340039, 1051649, 4195332, 7340039, 4195332, 1051649, 4195332, 3147779, 4195332, 2099202, 7340039, 4195332, 3072, 2099202, 3072, 3147779, 5243909, 1051649, 2099202, 5243909, 1051649, 6291462, 3072, 3147779, 5243909, 3072, 3147779, + 3147779, 2099202, 5243909, 3072, 6291462, 1051649, 6291462, 2099202, 4195332, 5243909, 3147779, 6291462, 2099202, 6291462, 3147779, 5243909, 1051649, 2099202, 7340039, 4195332, 6291462, 3072, 4195332, 1051649, 5243909, 6291462, 1051649, 2099202, 7340039, 3072, 6291462, 3147779, 1051649, 5243909, 2099202, 7340039, 1051649, 3147779, 7340039, 4195332, 6291462, 3072, 5243909, 2099202, 6291462, 3147779, 1051649, 5243909, 2099202, 3147779, 4195332, 3147779, 1051649, 6291462, 3147779, 6291462, 3147779, 7340039, 1051649, 5243909, 6291462, 1051649, 7340039, 2099202, 6291462, 3072, 4195332, 1051649, 5243909, 3147779, 4195332, 1051649, 4195332, 3147779, 5243909, 3072, 3147779, 7340039, 4195332, 2099202, 5243909, 3147779, 5243909, 3147779, 7340039, 2099202, 7340039, 1051649, 3147779, 6291462, 3072, 5243909, 7340039, 1051649, 4195332, 3072, 4195332, 1051649, 2099202, 3072, 4195332, 3072, 6291462, 2099202, 3072, 3147779, 7340039, 2099202, 5243909, 1051649, 6291462, 3147779, 1051649, 4195332, 6291462, 4195332, 6291462, 3072, 7340039, 4195332, 2099202, 5243909, 3147779, 4195332, 6291462, 1051649, 6291462, 5243909, + 6291462, 3072, 5243909, 4195332, 3147779, 7340039, 1051649, 7340039, 3072, 6291462, 3072, 7340039, 1051649, 4195332, 1051649, 3072, 7340039, 3147779, 2099202, 5243909, 1051649, 2099202, 6291462, 7340039, 3072, 3147779, 6291462, 4195332, 2099202, 2099202, 4195332, 3072, 7340039, 3147779, 6291462, 1051649, 6291462, 2099202, 5243909, 3072, 2099202, 7340039, 3147779, 7340039, 3072, 4195332, 6291462, 3072, 7340039, 3072, 7340039, 5243909, 5243909, 2099202, 4195332, 1051649, 5243909, 3072, 4195332, 3147779, 3072, 5243909, 4195332, 6291462, 1051649, 3147779, 7340039, 2099202, 6291462, 3072, 7340039, 6291462, 2099202, 7340039, 1051649, 4195332, 7340039, 3072, 3147779, 7340039, 1051649, 6291462, 3072, 5243909, 2099202, 3147779, 5243909, 2099202, 5243909, 2099202, 7340039, 3147779, 2099202, 5243909, 2099202, 6291462, 3147779, 5243909, 6291462, 7340039, 3147779, 6291462, 3147779, 1051649, 5243909, 6291462, 2099202, 6291462, 3072, 7340039, 3072, 5243909, 1051649, 7340039, 2099202, 5243909, 1051649, 3147779, 6291462, 4195332, 3072, 6291462, 3072, 7340039, 2099202, 5243909, 2099202, 1051649, + 3147779, 7340039, 2099202, 6291462, 3072, 2099202, 4195332, 3147779, 6291462, 3147779, 1051649, 4195332, 3147779, 5243909, 7340039, 3147779, 4195332, 5243909, 3072, 4195332, 7340039, 5243909, 1051649, 3147779, 4195332, 5243909, 1051649, 3072, 6291462, 4195332, 7340039, 5243909, 2099202, 4195332, 3072, 5243909, 3147779, 3072, 4195332, 6291462, 5243909, 3147779, 1051649, 2099202, 4195332, 7340039, 2099202, 3147779, 4195332, 2099202, 2099202, 1051649, 1051649, 6291462, 3072, 7340039, 2099202, 4195332, 7340039, 2099202, 7340039, 2099202, 3072, 5243909, 2099202, 6291462, 3072, 5243909, 1051649, 3147779, 5243909, 2099202, 3072, 3147779, 6291462, 2099202, 4195332, 2099202, 6291462, 1051649, 4195332, 3147779, 4195332, 6291462, 3072, 6291462, 3072, 7340039, 1051649, 5243909, 3147779, 3072, 6291462, 1051649, 5243909, 3072, 7340039, 1051649, 3072, 3147779, 1051649, 5243909, 2099202, 7340039, 4195332, 1051649, 4195332, 2099202, 4195332, 3147779, 3147779, 7340039, 2099202, 5243909, 3072, 3147779, 7340039, 5243909, 1051649, 2099202, 7340039, 3147779, 5243909, 1051649, 4195332, 3072, 7340039, 4195332, + 3072, 4195332, 1051649, 4195332, 6291462, 5243909, 3072, 2099202, 1051649, 5243909, 7340039, 2099202, 5243909, 3072, 2099202, 6291462, 1051649, 6291462, 1051649, 7340039, 3147779, 3072, 6291462, 1051649, 7340039, 2099202, 4195332, 7340039, 5243909, 3072, 3147779, 1051649, 4195332, 7340039, 4195332, 2099202, 5243909, 7340039, 1051649, 2099202, 3072, 6291462, 5243909, 1051649, 6291462, 3072, 5243909, 1051649, 6291462, 6291462, 4195332, 7340039, 3147779, 5243909, 4195332, 3147779, 3072, 6291462, 1051649, 6291462, 3147779, 1051649, 5243909, 3147779, 7340039, 4195332, 2099202, 4195332, 4195332, 7340039, 1051649, 4195332, 7340039, 5243909, 1051649, 5243909, 3072, 6291462, 3147779, 5243909, 3072, 7340039, 2099202, 1051649, 4195332, 3147779, 6291462, 4195332, 3072, 4195332, 1051649, 5243909, 4195332, 7340039, 3147779, 2099202, 4195332, 3147779, 5243909, 4195332, 7340039, 1051649, 6291462, 3072, 3147779, 7340039, 3072, 6291462, 1051649, 5243909, 2099202, 5243909, 3072, 4195332, 6291462, 1051649, 4195332, 3072, 7340039, 3147779, 4195332, 1051649, 2099202, 6291462, 7340039, 3147779, 1051649, 6291462, + 7340039, 3147779, 6291462, 2099202, 1051649, 3147779, 7340039, 4195332, 7340039, 3072, 2099202, 6291462, 1051649, 7340039, 4195332, 3072, 4195332, 3147779, 5243909, 1051649, 5243909, 2099202, 4195332, 5243909, 3147779, 3072, 6291462, 1051649, 3147779, 2099202, 6291462, 1051649, 6291462, 3072, 3147779, 7340039, 1051649, 3147779, 6291462, 7340039, 4195332, 3072, 4195332, 7340039, 3147779, 2099202, 4195332, 7340039, 3072, 1051649, 5243909, 3072, 6291462, 3072, 2099202, 6291462, 5243909, 2099202, 5243909, 3072, 7340039, 4195332, 6291462, 1051649, 5243909, 3072, 7340039, 1051649, 6291462, 3072, 5243909, 3147779, 3072, 2099202, 6291462, 3147779, 7340039, 1051649, 2099202, 7340039, 4195332, 2099202, 6291462, 3147779, 7340039, 1051649, 1051649, 3147779, 7340039, 3147779, 7340039, 6291462, 2099202, 3072, 5243909, 1051649, 6291462, 3072, 7340039, 2099202, 5243909, 2099202, 4195332, 5243909, 4195332, 2099202, 5243909, 3147779, 7340039, 3072, 6291462, 1051649, 7340039, 2099202, 3147779, 7340039, 2099202, 5243909, 3147779, 6291462, 3072, 7340039, 4195332, 3147779, 1051649, 5243909, 4195332, 2099202, + 1051649, 5243909, 3072, 7340039, 3147779, 5243909, 1051649, 2099202, 6291462, 4195332, 5243909, 3072, 4195332, 3147779, 6291462, 5243909, 7340039, 3072, 2099202, 6291462, 4195332, 1051649, 6291462, 3072, 7340039, 5243909, 3147779, 4195332, 7340039, 1051649, 4195332, 5243909, 2099202, 6291462, 3072, 6291462, 2099202, 5243909, 3072, 3147779, 1051649, 6291462, 3147779, 1051649, 5243909, 6291462, 1051649, 3147779, 5243909, 7340039, 3147779, 3147779, 2099202, 4195332, 7340039, 1051649, 3072, 4195332, 3147779, 5243909, 2099202, 3072, 2099202, 7340039, 3147779, 1051649, 3147779, 6291462, 2099202, 3147779, 5243909, 2099202, 7340039, 4195332, 7340039, 1051649, 3147779, 5243909, 3072, 6291462, 1051649, 5243909, 3072, 5243909, 2099202, 7340039, 4195332, 6291462, 1051649, 5243909, 2099202, 3072, 4195332, 6291462, 3147779, 7340039, 2099202, 4195332, 1051649, 5243909, 3072, 6291462, 3147779, 1051649, 3072, 7340039, 1051649, 5243909, 2099202, 4195332, 3147779, 5243909, 4195332, 6291462, 3072, 5243909, 3072, 6291462, 1051649, 2099202, 6291462, 3147779, 3072, 5243909, 1051649, 7340039, 2099202, 6291462, + 4195332, 3147779, 6291462, 4195332, 3072, 2099202, 6291462, 5243909, 1051649, 2099202, 3147779, 7340039, 1051649, 7340039, 3072, 2099202, 2099202, 6291462, 3147779, 3072, 2099202, 7340039, 3147779, 2099202, 4195332, 2099202, 3072, 5243909, 1051649, 6291462, 3072, 3147779, 5243909, 2099202, 5243909, 1051649, 4195332, 6291462, 2099202, 7340039, 4195332, 5243909, 2099202, 6291462, 3072, 4195332, 6291462, 2099202, 3072, 4195332, 1051649, 7340039, 6291462, 1051649, 5243909, 3147779, 5243909, 3147779, 7340039, 1051649, 6291462, 4195332, 6291462, 4195332, 3072, 5243909, 6291462, 1051649, 5243909, 7340039, 3072, 6291462, 3147779, 1051649, 4195332, 2099202, 6291462, 4195332, 2099202, 4195332, 1051649, 3147779, 6291462, 4195332, 3072, 5243909, 2099202, 3072, 6291462, 1051649, 6291462, 3147779, 7340039, 1051649, 4195332, 3072, 4195332, 6291462, 2099202, 3147779, 6291462, 1051649, 7340039, 5243909, 3147779, 6291462, 4195332, 3147779, 3072, 6291462, 3072, 2099202, 1051649, 3147779, 7340039, 2099202, 4195332, 3147779, 4195332, 5243909, 1051649, 5243909, 2099202, 7340039, 4195332, 3072, 4195332, 3072, + 7340039, 2099202, 1051649, 5243909, 7340039, 4195332, 1051649, 3147779, 5243909, 7340039, 3072, 6291462, 4195332, 1051649, 3147779, 6291462, 4195332, 1051649, 5243909, 7340039, 4195332, 3072, 5243909, 6291462, 1051649, 6291462, 7340039, 3147779, 2099202, 5243909, 3147779, 7340039, 1051649, 4195332, 3147779, 7340039, 4195332, 3072, 5243909, 1051649, 4195332, 3072, 7340039, 3147779, 5243909, 2099202, 3072, 6291462, 5243909, 3147779, 5243909, 3072, 2099202, 4195332, 1051649, 7340039, 1051649, 6291462, 3072, 7340039, 1051649, 3147779, 1051649, 4195332, 7340039, 3147779, 2099202, 4195332, 3072, 3147779, 4195332, 3072, 5243909, 6291462, 3072, 5243909, 3147779, 3072, 7340039, 2099202, 7340039, 5243909, 3072, 3147779, 7340039, 2099202, 4195332, 7340039, 3147779, 4195332, 3072, 3147779, 5243909, 2099202, 7340039, 1051649, 6291462, 1051649, 4195332, 7340039, 2099202, 4195332, 3072, 7340039, 2099202, 3072, 1051649, 7340039, 6291462, 4195332, 7340039, 5243909, 6291462, 3072, 5243909, 2099202, 6291462, 3072, 7340039, 3072, 7340039, 2099202, 6291462, 1051649, 3147779, 7340039, 5243909, 2099202, + 1051649, 7340039, 5243909, 3072, 2099202, 5243909, 7340039, 3072, 4195332, 2099202, 4195332, 3147779, 2099202, 5243909, 6291462, 1051649, 5243909, 7340039, 2099202, 3147779, 1051649, 6291462, 3147779, 3072, 4195332, 4195332, 3147779, 3072, 7340039, 6291462, 3072, 2099202, 7340039, 3072, 5243909, 1051649, 2099202, 6291462, 3147779, 3147779, 7340039, 2099202, 4195332, 1051649, 7340039, 5243909, 2099202, 4195332, 1051649, 7340039, 2099202, 7340039, 5243909, 3147779, 6291462, 4195332, 2099202, 5243909, 3147779, 2099202, 3147779, 7340039, 5243909, 2099202, 3072, 5243909, 1051649, 6291462, 2099202, 6291462, 2099202, 7340039, 3147779, 2099202, 7340039, 1051649, 6291462, 5243909, 1051649, 5243909, 3072, 2099202, 6291462, 4195332, 1051649, 5243909, 1051649, 4195332, 3072, 7340039, 5243909, 2099202, 3072, 6291462, 3147779, 5243909, 2099202, 5243909, 3072, 3147779, 6291462, 2099202, 4195332, 2099202, 5243909, 3147779, 5243909, 1051649, 4195332, 2099202, 1051649, 2099202, 3147779, 6291462, 1051649, 7340039, 1051649, 6291462, 3147779, 4195332, 1051649, 4195332, 3072, 5243909, 4195332, 1051649, 3072, 5243909, + 4195332, 3072, 4195332, 3147779, 6291462, 1051649, 2099202, 6291462, 5243909, 1051649, 6291462, 3072, 7340039, 3147779, 2099202, 4195332, 3072, 3147779, 5243909, 1051649, 7340039, 4195332, 2099202, 7340039, 6291462, 3072, 1051649, 5243909, 4195332, 1051649, 7340039, 4195332, 3147779, 6291462, 2099202, 7340039, 4195332, 1051649, 7340039, 3072, 5243909, 1051649, 6291462, 3147779, 3072, 3147779, 7340039, 5243909, 2099202, 4195332, 3072, 3147779, 1051649, 6291462, 3072, 2099202, 6291462, 3072, 5243909, 4195332, 6291462, 3072, 2099202, 6291462, 4195332, 1051649, 7340039, 3147779, 7340039, 1051649, 5243909, 1051649, 5243909, 1051649, 4195332, 4195332, 3072, 3147779, 2099202, 6291462, 4195332, 7340039, 3147779, 3072, 7340039, 3147779, 6291462, 2099202, 6291462, 2099202, 3147779, 6291462, 4195332, 1051649, 5243909, 3072, 7340039, 3147779, 7340039, 5243909, 3072, 5243909, 1051649, 6291462, 1051649, 7340039, 3147779, 7340039, 3072, 3147779, 5243909, 7340039, 4195332, 3072, 4195332, 3147779, 5243909, 3147779, 2099202, 5243909, 2099202, 5243909, 3147779, 7340039, 3072, 6291462, 6291462, 3147779, + 7340039, 3147779, 6291462, 1051649, 4195332, 3147779, 7340039, 3147779, 3072, 7340039, 3147779, 5243909, 1051649, 5243909, 3072, 7340039, 3147779, 6291462, 3072, 4195332, 3147779, 3072, 5243909, 1051649, 2099202, 5243909, 7340039, 3147779, 1051649, 4195332, 2099202, 5243909, 3072, 1051649, 5243909, 3072, 5243909, 1051649, 5243909, 5243909, 2099202, 4195332, 3072, 7340039, 4195332, 1051649, 4195332, 3072, 7340039, 1051649, 6291462, 4195332, 6291462, 2099202, 4195332, 7340039, 4195332, 3147779, 7340039, 3072, 2099202, 7340039, 3147779, 3072, 6291462, 3147779, 5243909, 3072, 2099202, 4195332, 3147779, 6291462, 3072, 6291462, 2099202, 7340039, 3147779, 7340039, 4195332, 3072, 3147779, 1051649, 6291462, 4195332, 2099202, 5243909, 3072, 5243909, 4195332, 3072, 6291462, 1051649, 7340039, 4195332, 2099202, 6291462, 4195332, 1051649, 3147779, 1051649, 7340039, 3147779, 6291462, 4195332, 1051649, 5243909, 3072, 4195332, 5243909, 6291462, 1051649, 2099202, 1051649, 6291462, 7340039, 2099202, 5243909, 3072, 6291462, 3072, 7340039, 1051649, 6291462, 2099202, 3147779, 2099202, 4195332, 2099202, + 2099202, 5243909, 1051649, 6291462, 3072, 5243909, 1051649, 4195332, 6291462, 2099202, 4195332, 2099202, 6291462, 4195332, 6291462, 1051649, 4195332, 2099202, 7340039, 2099202, 6291462, 2099202, 7340039, 3147779, 6291462, 1051649, 4195332, 6291462, 2099202, 6291462, 3072, 6291462, 4195332, 6291462, 2099202, 3147779, 7340039, 3147779, 3147779, 1051649, 6291462, 2099202, 6291462, 3147779, 5243909, 1051649, 6291462, 2099202, 3147779, 6291462, 2099202, 3072, 4195332, 3072, 5243909, 1051649, 5243909, 1051649, 1051649, 5243909, 1051649, 5243909, 4195332, 6291462, 2099202, 7340039, 3072, 6291462, 4195332, 7340039, 3072, 2099202, 4195332, 4195332, 5243909, 1051649, 5243909, 1051649, 6291462, 2099202, 5243909, 5243909, 1051649, 3147779, 6291462, 1051649, 3147779, 7340039, 1051649, 7340039, 2099202, 5243909, 3147779, 3072, 7340039, 1051649, 5243909, 2099202, 6291462, 4195332, 3147779, 3072, 2099202, 3147779, 7340039, 2099202, 6291462, 2099202, 3147779, 3072, 4195332, 7340039, 5243909, 3147779, 3072, 4195332, 1051649, 7340039, 4195332, 6291462, 2099202, 4195332, 1051649, 5243909, 7340039, 1051649, 6291462, 3072, + 6291462, 1051649, 7340039, 3147779, 7340039, 2099202, 6291462, 3147779, 3072, 6291462, 1051649, 7340039, 3072, 3147779, 2099202, 7340039, 3072, 5243909, 1051649, 5243909, 5243909, 1051649, 4195332, 3072, 2099202, 7340039, 3147779, 3072, 5243909, 3147779, 7340039, 2099202, 3072, 4195332, 1051649, 7340039, 3072, 6291462, 3072, 7340039, 2099202, 7340039, 3072, 4195332, 2099202, 6291462, 3147779, 7340039, 3072, 5243909, 3147779, 5243909, 7340039, 3147779, 7340039, 2099202, 3147779, 6291462, 4195332, 3147779, 7340039, 3147779, 1051649, 5243909, 3072, 3147779, 5243909, 2099202, 1051649, 3147779, 5243909, 6291462, 7340039, 3072, 3147779, 6291462, 3072, 4195332, 3147779, 7340039, 3072, 4195332, 7340039, 2099202, 3072, 7340039, 5243909, 3072, 5243909, 3147779, 4195332, 3072, 6291462, 2099202, 5243909, 3147779, 3072, 7340039, 4195332, 3072, 6291462, 5243909, 7340039, 4195332, 3072, 5243909, 1051649, 4195332, 7340039, 5243909, 1051649, 2099202, 3072, 6291462, 2099202, 7340039, 3147779, 1051649, 3147779, 3147779, 5243909, 3072, 7340039, 3147779, 3072, 5243909, 3147779, 4195332, +}; + +#else +#define DM_WIDTH 8 +#define DM_WIDTH_SHIFT 3 +#define DM_HEIGHT 8 +static const guchar DM[8][8] = +{ + { 0, 32, 8, 40, 2, 34, 10, 42 }, + { 48, 16, 56, 24, 50, 18, 58, 26 }, + { 12, 44, 4, 36, 14, 46, 6, 38 }, + { 60, 28, 52, 20, 62, 30, 54, 22 }, + { 3, 35, 11, 43, 1, 33, 9, 41 }, + { 51, 19, 59, 27, 49, 17, 57, 25 }, + { 15, 47, 7, 39, 13, 45, 5, 37 }, + { 63, 31, 55, 23, 61, 29, 53, 21 } +}; + +static const guint32 DM_565[8 * 8] = +{ + 3072, 4195332, 1051649, 5243909, 3072, 4195332, 1051649, 5243909, + 6291462, 2099202, 7340039, 3147779, 6291462, 2099202, 7340039, 3147779, + 1051649, 5243909, 3072, 4195332, 1051649, 5243909, 3072, 4195332, + 7340039, 3147779, 6291462, 2099202, 7340039, 3147779, 6291462, 2099202, + 3072, 4195332, 1051649, 5243909, 3072, 4195332, 1051649, 5243909, + 6291462, 2099202, 7340039, 3147779, 6291462, 2099202, 7340039, 3147779, + 1051649, 5243909, 3072, 4195332, 1051649, 5243909, 3072, 4195332, + 7340039, 3147779, 6291462, 2099202, 7340039, 3147779, 6291462, 2099202, +}; + +#endif + +#if 0 +static void +gdk_rgb_preprocess_dm_565 (void) +{ + int i; + guint32 dith; + + if (DM_565 == NULL) + { + DM_565 = g_new (guint32, DM_WIDTH * DM_HEIGHT); + for (i = 0; i < DM_WIDTH * DM_HEIGHT; i++) + { + dith = DM[0][i] >> 3; + DM_565[i] = (dith << 20) | dith | (((7 - dith) >> 1) << 10); +#ifdef VERBOSE + g_print ("%i %x %x\n", i, dith, DM_565[i]); +#endif + } + } +} +#else +#define gdk_rgb_preprocess_dm_565() +#endif + +static void +gdk_rgb_convert_8_d666 (GdkRgbInfo *image_info, GdkImage *image, + gint x0, gint y0, gint width, gint height, + const guchar *buf, int rowstride, + gint x_align, gint y_align, GdkRgbCmap *cmap) +{ + int x, y; + gint bpl; + guchar *obuf, *obptr; + const guchar *bptr, *bp2; + gint r, g, b; + const guchar *dmp; + gint dith; + guchar *colorcube_d = image_info->colorcube_d; + + bptr = buf; + bpl = image->bpl; + obuf = ((guchar *)image->mem) + y0 * bpl + x0; + for (y = 0; y < height; y++) + { + dmp = DM[(y_align + y) & (DM_HEIGHT - 1)]; + bp2 = bptr; + obptr = obuf; + for (x = 0; x < width; x++) + { + r = *bp2++; + g = *bp2++; + b = *bp2++; + dith = (dmp[(x_align + x) & (DM_WIDTH - 1)] << 2) | 7; + r = ((r * 5) + dith) >> 8; + g = ((g * 5) + (262 - dith)) >> 8; + b = ((b * 5) + dith) >> 8; + obptr[0] = colorcube_d[(r << 6) | (g << 3) | b]; + obptr++; + } + bptr += rowstride; + obuf += bpl; + } +} + +static void +gdk_rgb_convert_8_d (GdkRgbInfo *image_info, GdkImage *image, + gint x0, gint y0, gint width, gint height, + const guchar *buf, int rowstride, + gint x_align, gint y_align, + GdkRgbCmap *cmap) +{ + int x, y; + gint bpl; + guchar *obuf, *obptr; + const guchar *bptr, *bp2; + gint r, g, b; + const guchar *dmp; + gint dith; + gint rs, gs, bs; + guchar *colorcube_d = image_info->colorcube_d; + + bptr = buf; + bpl = image->bpl; + rs = image_info->nred_shades - 1; + gs = image_info->ngreen_shades - 1; + bs = image_info->nblue_shades - 1; + obuf = ((guchar *)image->mem) + y0 * bpl + x0; + for (y = 0; y < height; y++) + { + dmp = DM[(y_align + y) & (DM_HEIGHT - 1)]; + bp2 = bptr; + obptr = obuf; + for (x = 0; x < width; x++) + { + r = *bp2++; + g = *bp2++; + b = *bp2++; + dith = (dmp[(x_align + x) & (DM_WIDTH - 1)] << 2) | 7; + r = ((r * rs) + dith) >> 8; + g = ((g * gs) + (262 - dith)) >> 8; + b = ((b * bs) + dith) >> 8; + obptr[0] = colorcube_d[(r << 6) | (g << 3) | b]; + obptr++; + } + bptr += rowstride; + obuf += bpl; + } +} + +static void +gdk_rgb_convert_8_indexed (GdkRgbInfo *image_info, GdkImage *image, + gint x0, gint y0, gint width, gint height, + const guchar *buf, int rowstride, + gint x_align, gint y_align, GdkRgbCmap *cmap) +{ + int x, y; + gint bpl; + guchar *obuf, *obptr; + const guchar *bptr, *bp2; + guchar c; + guchar *lut; + GdkRgbCmapInfo *cmap_info = gdk_rgb_cmap_get_info (cmap, image_info); + + lut = cmap_info->lut; + bptr = buf; + bpl = image->bpl; + obuf = ((guchar *)image->mem) + y0 * bpl + x0; + for (y = 0; y < height; y++) + { + bp2 = bptr; + obptr = obuf; + for (x = 0; x < width; x++) + { + c = *bp2++; + obptr[0] = lut[c]; + obptr++; + } + bptr += rowstride; + obuf += bpl; + } +} + +static void +gdk_rgb_convert_gray8 (GdkRgbInfo *image_info, GdkImage *image, + gint x0, gint y0, gint width, gint height, + const guchar *buf, int rowstride, + gint x_align, gint y_align, GdkRgbCmap *cmap) +{ + int x, y; + gint bpl; + guchar *obuf, *obptr; + const guchar *bptr, *bp2; + gint r, g, b; + + bptr = buf; + bpl = image->bpl; + obuf = ((guchar *)image->mem) + y0 * bpl + x0; + for (y = 0; y < height; y++) + { + bp2 = bptr; + obptr = obuf; + for (x = 0; x < width; x++) + { + r = *bp2++; + g = *bp2++; + b = *bp2++; + obptr[0] = (g + ((b + r) >> 1)) >> 1; + obptr++; + } + bptr += rowstride; + obuf += bpl; + } +} + +static void +gdk_rgb_convert_gray8_gray (GdkRgbInfo *image_info, GdkImage *image, + gint x0, gint y0, gint width, gint height, + const guchar *buf, int rowstride, + gint x_align, gint y_align, GdkRgbCmap *cmap) +{ + int y; + gint bpl; + guchar *obuf; + const guchar *bptr; + + bptr = buf; + bpl = image->bpl; + obuf = ((guchar *)image->mem) + y0 * bpl + x0; + for (y = 0; y < height; y++) + { + memcpy (obuf, bptr, width); + bptr += rowstride; + obuf += bpl; + } +} + +#if G_BYTE_ORDER == G_LITTLE_ENDIAN +#define HAIRY_CONVERT_565 +#endif + +#ifdef HAIRY_CONVERT_565 +/* Render a 24-bit RGB image in buf into the GdkImage, without dithering. + This assumes native byte ordering - what should really be done is to + check whether the image byte_order is consistent with the _ENDIAN + config flag, and if not, use a different function. + + This one is even faster than the one below - its inner loop loads 3 + words (i.e. 4 24-bit pixels), does a lot of shifting and masking, + then writes 2 words. */ +static void +gdk_rgb_convert_565 (GdkRgbInfo *image_info, GdkImage *image, + gint x0, gint y0, gint width, gint height, + const guchar *buf, int rowstride, + gint x_align, gint y_align, GdkRgbCmap *cmap) +{ + int x, y; + guchar *obuf, *obptr; + gint bpl; + const guchar *bptr, *bp2; + guchar r, g, b; + + bptr = buf; + bpl = image->bpl; + obuf = ((guchar *)image->mem) + y0 * bpl + x0 * 2; + for (y = 0; y < height; y++) + { + bp2 = bptr; + obptr = obuf; + if (((guintptr)obuf | (guintptr) bp2) & 3) + { + for (x = 0; x < width; x++) + { + r = *bp2++; + g = *bp2++; + b = *bp2++; + ((guint16 *)obptr)[0] = ((r & 0xf8) << 8) | + ((g & 0xfc) << 3) | + (b >> 3); + obptr += 2; + } + } + else + { + for (x = 0; x < width - 3; x += 4) + { + guint32 r1b0g0r0; + guint32 g2r2b1g1; + guint32 b3g3r3b2; + + r1b0g0r0 = ((guint32 *)bp2)[0]; + g2r2b1g1 = ((guint32 *)bp2)[1]; + b3g3r3b2 = ((guint32 *)bp2)[2]; + ((guint32 *)obptr)[0] = + ((r1b0g0r0 & 0xf8) << 8) | + ((r1b0g0r0 & 0xfc00) >> 5) | + ((r1b0g0r0 & 0xf80000) >> 19) | + (r1b0g0r0 & 0xf8000000) | + ((g2r2b1g1 & 0xfc) << 19) | + ((g2r2b1g1 & 0xf800) << 5); + ((guint32 *)obptr)[1] = + ((g2r2b1g1 & 0xf80000) >> 8) | + ((g2r2b1g1 & 0xfc000000) >> 21) | + ((b3g3r3b2 & 0xf8) >> 3) | + ((b3g3r3b2 & 0xf800) << 16) | + ((b3g3r3b2 & 0xfc0000) << 3) | + ((b3g3r3b2 & 0xf8000000) >> 11); + bp2 += 12; + obptr += 8; + } + for (; x < width; x++) + { + r = *bp2++; + g = *bp2++; + b = *bp2++; + ((guint16 *)obptr)[0] = ((r & 0xf8) << 8) | + ((g & 0xfc) << 3) | + (b >> 3); + obptr += 2; + } + } + bptr += rowstride; + obuf += bpl; + } +} +#else +/* Render a 24-bit RGB image in buf into the GdkImage, without dithering. + This assumes native byte ordering - what should really be done is to + check whether the image byte_order is consistent with the _ENDIAN + config flag, and if not, use a different function. + + This routine is faster than the one included with Gtk 1.0 for a number + of reasons: + + 1. Shifting instead of lookup tables (less memory traffic). + + 2. Much less register pressure, especially because shifts are + in the code. + + 3. A memcpy is avoided (i.e. the transfer function). + + 4. On big-endian architectures, byte swapping is avoided. + + That said, it wouldn't be hard to make it even faster - just make an + inner loop that reads 3 words (i.e. 4 24-bit pixels), does a lot of + shifting and masking, then writes 2 words. +*/ +static void +gdk_rgb_convert_565 (GdkRgbInfo *image_info, GdkImage *image, + gint x0, gint y0, gint width, gint height, + const guchar *buf, int rowstride, + gint x_align, gint y_align, GdkRgbCmap *cmap) +{ + int x, y; + guchar *obuf; + gint bpl; + const guchar *bptr, *bp2; + guchar r, g, b; + + bptr = buf; + bpl = image->bpl; + obuf = ((guchar *)image->mem) + y0 * bpl + x0 * 2; + for (y = 0; y < height; y++) + { + bp2 = bptr; + for (x = 0; x < width; x++) + { + r = *bp2++; + g = *bp2++; + b = *bp2++; + ((unsigned short *)obuf)[x] = ((r & 0xf8) << 8) | + ((g & 0xfc) << 3) | + (b >> 3); + } + bptr += rowstride; + obuf += bpl; + } +} +#endif + +#ifdef HAIRY_CONVERT_565 +static void +gdk_rgb_convert_565_gray (GdkRgbInfo *image_info, GdkImage *image, + gint x0, gint y0, gint width, gint height, + const guchar *buf, int rowstride, + gint x_align, gint y_align, GdkRgbCmap *cmap) +{ + int x, y; + guchar *obuf, *obptr; + gint bpl; + const guchar *bptr, *bp2; + guchar g; + + bptr = buf; + bpl = image->bpl; + obuf = ((guchar *)image->mem) + y0 * bpl + x0 * 2; + for (y = 0; y < height; y++) + { + bp2 = bptr; + obptr = obuf; + if (((guintptr)obuf | (guintptr) bp2) & 3) + { + for (x = 0; x < width; x++) + { + g = *bp2++; + ((guint16 *)obptr)[0] = ((g & 0xf8) << 8) | + ((g & 0xfc) << 3) | + (g >> 3); + obptr += 2; + } + } + else + { + for (x = 0; x < width - 3; x += 4) + { + guint32 g3g2g1g0; + + g3g2g1g0 = ((guint32 *)bp2)[0]; + ((guint32 *)obptr)[0] = + ((g3g2g1g0 & 0xf8) << 8) | + ((g3g2g1g0 & 0xfc) << 3) | + ((g3g2g1g0 & 0xf8) >> 3) | + (g3g2g1g0 & 0xf800) << 16 | + ((g3g2g1g0 & 0xfc00) << 11) | + ((g3g2g1g0 & 0xf800) << 5); + ((guint32 *)obptr)[1] = + ((g3g2g1g0 & 0xf80000) >> 8) | + ((g3g2g1g0 & 0xfc0000) >> 13) | + ((g3g2g1g0 & 0xf80000) >> 19) | + (g3g2g1g0 & 0xf8000000) | + ((g3g2g1g0 & 0xfc000000) >> 5) | + ((g3g2g1g0 & 0xf8000000) >> 11); + bp2 += 4; + obptr += 8; + } + for (; x < width; x++) + { + g = *bp2++; + ((guint16 *)obptr)[0] = ((g & 0xf8) << 8) | + ((g & 0xfc) << 3) | + (g >> 3); + obptr += 2; + } + } + bptr += rowstride; + obuf += bpl; + } +} +#else +static void +gdk_rgb_convert_565_gray (GdkRgbInfo *image_info, GdkImage *image, + gint x0, gint y0, gint width, gint height, + const guchar *buf, int rowstride, + gint x_align, gint y_align, GdkRgbCmap *cmap) +{ + int x, y; + guchar *obuf; + gint bpl; + const guchar *bptr, *bp2; + guchar g; + + bptr = buf; + bpl = image->bpl; + obuf = ((guchar *)image->mem) + y0 * bpl + x0 * 2; + for (y = 0; y < height; y++) + { + bp2 = bptr; + for (x = 0; x < width; x++) + { + g = *bp2++; + ((guint16 *)obuf)[x] = ((g & 0xf8) << 8) | + ((g & 0xfc) << 3) | + (g >> 3); + } + bptr += rowstride; + obuf += bpl; + } +} +#endif + +static void +gdk_rgb_convert_565_br (GdkRgbInfo *image_info, GdkImage *image, + gint x0, gint y0, gint width, gint height, + const guchar *buf, int rowstride, + gint x_align, gint y_align, GdkRgbCmap *cmap) +{ + int x, y; + guchar *obuf; + gint bpl; + const guchar *bptr, *bp2; + guchar r, g, b; + + bptr = buf; + bpl = image->bpl; + obuf = ((guchar *)image->mem) + y0 * bpl + x0 * 2; + for (y = 0; y < height; y++) + { + bp2 = bptr; + for (x = 0; x < width; x++) + { + r = *bp2++; + g = *bp2++; + b = *bp2++; + /* final word is: + g4 g3 g2 b7 b6 b5 b4 b3 r7 r6 r5 r4 r3 g7 g6 g5 + */ + ((unsigned short *)obuf)[x] = (r & 0xf8) | + ((g & 0xe0) >> 5) | + ((g & 0x1c) << 11) | + ((b & 0xf8) << 5); + } + bptr += rowstride; + obuf += bpl; + } +} + +/* Thanks to Ray Lehtiniemi for a patch that resulted in a ~25% speedup + in this mode. */ +#ifdef HAIRY_CONVERT_565 +static void +gdk_rgb_convert_565_d (GdkRgbInfo *image_info, GdkImage *image, + gint x0, gint y0, gint width, gint height, + const guchar *buf, int rowstride, + gint x_align, gint y_align, GdkRgbCmap *cmap) +{ + /* Now this is what I'd call some highly tuned code! */ + int x, y; + guchar *obuf, *obptr; + gint bpl; + const guchar *bptr, *bp2; + + width += x_align; + height += y_align; + + bptr = buf; + bpl = image->bpl; + obuf = ((guchar *)image->mem) + y0 * bpl + x0 * 2; + for (y = y_align; y < height; y++) + { + const guint32 *dmp = DM_565 + ((y & (DM_HEIGHT - 1)) << DM_WIDTH_SHIFT); + bp2 = bptr; + obptr = obuf; + if (((guintptr)obuf | (guintptr) bp2) & 3) + { + for (x = x_align; x < width; x++) + { + gint32 rgb = *bp2++ << 20; + rgb += *bp2++ << 10; + rgb += *bp2++; + rgb += dmp[x & (DM_WIDTH - 1)]; + rgb += 0x10040100 + - ((rgb & 0x1e0001e0) >> 5) + - ((rgb & 0x00070000) >> 6); + + ((unsigned short *)obptr)[0] = + ((rgb & 0x0f800000) >> 12) | + ((rgb & 0x0003f000) >> 7) | + ((rgb & 0x000000f8) >> 3); + obptr += 2; + } + } + else + { + for (x = x_align; x < width - 3; x += 4) + { + guint32 r1b0g0r0; + guint32 g2r2b1g1; + guint32 b3g3r3b2; + guint32 rgb02, rgb13; + + r1b0g0r0 = ((guint32 *)bp2)[0]; + g2r2b1g1 = ((guint32 *)bp2)[1]; + b3g3r3b2 = ((guint32 *)bp2)[2]; + rgb02 = + ((r1b0g0r0 & 0xff) << 20) + + ((r1b0g0r0 & 0xff00) << 2) + + ((r1b0g0r0 & 0xff0000) >> 16) + + dmp[x & (DM_WIDTH - 1)]; + rgb02 += 0x10040100 + - ((rgb02 & 0x1e0001e0) >> 5) + - ((rgb02 & 0x00070000) >> 6); + rgb13 = + ((r1b0g0r0 & 0xff000000) >> 4) + + ((g2r2b1g1 & 0xff) << 10) + + ((g2r2b1g1 & 0xff00) >> 8) + + dmp[(x + 1) & (DM_WIDTH - 1)]; + rgb13 += 0x10040100 + - ((rgb13 & 0x1e0001e0) >> 5) + - ((rgb13 & 0x00070000) >> 6); + ((guint32 *)obptr)[0] = + ((rgb02 & 0x0f800000) >> 12) | + ((rgb02 & 0x0003f000) >> 7) | + ((rgb02 & 0x000000f8) >> 3) | + ((rgb13 & 0x0f800000) << 4) | + ((rgb13 & 0x0003f000) << 9) | + ((rgb13 & 0x000000f8) << 13); + rgb02 = + ((g2r2b1g1 & 0xff0000) << 4) + + ((g2r2b1g1 & 0xff000000) >> 14) + + (b3g3r3b2 & 0xff) + + dmp[(x + 2) & (DM_WIDTH - 1)]; + rgb02 += 0x10040100 + - ((rgb02 & 0x1e0001e0) >> 5) + - ((rgb02 & 0x00070000) >> 6); + rgb13 = + ((b3g3r3b2 & 0xff00) << 12) + + ((b3g3r3b2 & 0xff0000) >> 6) + + ((b3g3r3b2 & 0xff000000) >> 24) + + dmp[(x + 3) & (DM_WIDTH - 1)]; + rgb13 += 0x10040100 + - ((rgb13 & 0x1e0001e0) >> 5) + - ((rgb13 & 0x00070000) >> 6); + ((guint32 *)obptr)[1] = + ((rgb02 & 0x0f800000) >> 12) | + ((rgb02 & 0x0003f000) >> 7) | + ((rgb02 & 0x000000f8) >> 3) | + ((rgb13 & 0x0f800000) << 4) | + ((rgb13 & 0x0003f000) << 9) | + ((rgb13 & 0x000000f8) << 13); + bp2 += 12; + obptr += 8; + } + for (; x < width; x++) + { + gint32 rgb = *bp2++ << 20; + rgb += *bp2++ << 10; + rgb += *bp2++; + rgb += dmp[x & (DM_WIDTH - 1)]; + rgb += 0x10040100 + - ((rgb & 0x1e0001e0) >> 5) + - ((rgb & 0x00070000) >> 6); + + ((unsigned short *)obptr)[0] = + ((rgb & 0x0f800000) >> 12) | + ((rgb & 0x0003f000) >> 7) | + ((rgb & 0x000000f8) >> 3); + obptr += 2; + } + } + bptr += rowstride; + obuf += bpl; + } +} +#else +static void +gdk_rgb_convert_565_d (GdkRgbInfo *image_info, GdkImage *image, + gint x0, gint y0, gint width, gint height, + const guchar *buf, int rowstride, + gint x_align, gint y_align, GdkRgbCmap *cmap) +{ + int x, y; + guchar *obuf; + gint bpl; + const guchar *bptr; + + width += x_align; + height += y_align; + + bptr = buf; + bpl = image->bpl; + obuf = ((guchar *)image->mem) + y0 * bpl + (x0 - x_align) * 2; + + for (y = y_align; y < height; y++) + { + const guint32 *dmp = DM_565 + ((y & (DM_HEIGHT - 1)) << DM_WIDTH_SHIFT); + guchar *bp2 = bptr; + + for (x = x_align; x < width; x++) + { + gint32 rgb = *bp2++ << 20; + rgb += *bp2++ << 10; + rgb += *bp2++; + rgb += dmp[x & (DM_WIDTH - 1)]; + rgb += 0x10040100 + - ((rgb & 0x1e0001e0) >> 5) + - ((rgb & 0x00070000) >> 6); + + ((unsigned short *)obuf)[x] = + ((rgb & 0x0f800000) >> 12) | + ((rgb & 0x0003f000) >> 7) | + ((rgb & 0x000000f8) >> 3); + } + + bptr += rowstride; + obuf += bpl; + } +} +#endif + +static void +gdk_rgb_convert_555 (GdkRgbInfo *image_info, GdkImage *image, + gint x0, gint y0, gint width, gint height, + const guchar *buf, int rowstride, + gint x_align, gint y_align, GdkRgbCmap *cmap) +{ + int x, y; + guchar *obuf; + gint bpl; + const guchar *bptr, *bp2; + guchar r, g, b; + + bptr = buf; + bpl = image->bpl; + obuf = ((guchar *)image->mem) + y0 * bpl + x0 * 2; + for (y = 0; y < height; y++) + { + bp2 = bptr; + for (x = 0; x < width; x++) + { + r = *bp2++; + g = *bp2++; + b = *bp2++; + ((unsigned short *)obuf)[x] = ((r & 0xf8) << 7) | + ((g & 0xf8) << 2) | + (b >> 3); + } + bptr += rowstride; + obuf += bpl; + } +} + +static void +gdk_rgb_convert_555_br (GdkRgbInfo *image_info, GdkImage *image, + gint x0, gint y0, gint width, gint height, + const guchar *buf, int rowstride, + gint x_align, gint y_align, GdkRgbCmap *cmap) +{ + int x, y; + guchar *obuf; + gint bpl; + const guchar *bptr, *bp2; + guchar r, g, b; + + bptr = buf; + bpl = image->bpl; + obuf = ((guchar *)image->mem) + y0 * bpl + x0 * 2; + for (y = 0; y < height; y++) + { + bp2 = bptr; + for (x = 0; x < width; x++) + { + r = *bp2++; + g = *bp2++; + b = *bp2++; + /* final word is: + g5 g4 g3 b7 b6 b5 b4 b3 0 r7 r6 r5 r4 r3 g7 g6 + */ + ((unsigned short *)obuf)[x] = ((r & 0xf8) >> 1) | + ((g & 0xc0) >> 6) | + ((g & 0x38) << 10) | + ((b & 0xf8) << 5); + } + bptr += rowstride; + obuf += bpl; + } +} + +static void +gdk_rgb_convert_888_msb (GdkRgbInfo *image_info, GdkImage *image, + gint x0, gint y0, gint width, gint height, + const guchar *buf, int rowstride, + gint x_align, gint y_align, GdkRgbCmap *cmap) +{ + int y; + guchar *obuf; + gint bpl; + const guchar *bptr; + + bptr = buf; + bpl = image->bpl; + obuf = ((guchar *)image->mem) + y0 * bpl + x0 * 3; + for (y = 0; y < height; y++) + { + memcpy (obuf, bptr, width + width + width); + bptr += rowstride; + obuf += bpl; + } +} + +/* todo: optimize this */ +#if G_BYTE_ORDER == G_LITTLE_ENDIAN +#define HAIRY_CONVERT_888 +#endif + +#ifdef HAIRY_CONVERT_888 +static void +gdk_rgb_convert_888_lsb (GdkRgbInfo *image_info, GdkImage *image, + gint x0, gint y0, gint width, gint height, + const guchar *buf, int rowstride, + gint x_align, gint y_align, GdkRgbCmap *cmap) +{ + int x, y; + guchar *obuf, *obptr; + gint bpl; + const guchar *bptr, *bp2; + int r, g, b; + + bptr = buf; + bpl = image->bpl; + obuf = ((guchar *)image->mem) + y0 * bpl + x0 * 3; + for (y = 0; y < height; y++) + { + bp2 = bptr; + obptr = obuf; + if (((guintptr)obuf | (guintptr) bp2) & 3) + { + for (x = 0; x < width; x++) + { + r = bp2[0]; + g = bp2[1]; + b = bp2[2]; + *obptr++ = b; + *obptr++ = g; + *obptr++ = r; + bp2 += 3; + } + } + else + { + for (x = 0; x < width - 3; x += 4) + { + guint32 r1b0g0r0; + guint32 g2r2b1g1; + guint32 b3g3r3b2; + + r1b0g0r0 = ((guint32 *)bp2)[0]; + g2r2b1g1 = ((guint32 *)bp2)[1]; + b3g3r3b2 = ((guint32 *)bp2)[2]; + ((guint32 *)obptr)[0] = + (r1b0g0r0 & 0xff00) | + ((r1b0g0r0 & 0xff0000) >> 16) | + (((g2r2b1g1 & 0xff00) | (r1b0g0r0 & 0xff)) << 16); + ((guint32 *)obptr)[1] = + (g2r2b1g1 & 0xff0000ff) | + ((r1b0g0r0 & 0xff000000) >> 16) | + ((b3g3r3b2 & 0xff) << 16); + ((guint32 *)obptr)[2] = + (((g2r2b1g1 & 0xff0000) | (b3g3r3b2 & 0xff000000)) >> 16) | + ((b3g3r3b2 & 0xff00) << 16) | + ((b3g3r3b2 & 0xff0000)); + bp2 += 12; + obptr += 12; + } + for (; x < width; x++) + { + r = bp2[0]; + g = bp2[1]; + b = bp2[2]; + *obptr++ = b; + *obptr++ = g; + *obptr++ = r; + bp2 += 3; + } + } + bptr += rowstride; + obuf += bpl; + } +} +#else +static void +gdk_rgb_convert_888_lsb (GdkRgbInfo *image_info, GdkImage *image, + gint x0, gint y0, gint width, gint height, + const guchar *buf, int rowstride, + gint x_align, gint y_align, GdkRgbCmap *cmap) +{ + int x, y; + guchar *obuf; + gint bpl; + const guchar *bptr, *bp2; + int r, g, b; + + bptr = buf; + bpl = image->bpl; + obuf = ((guchar *)image->mem) + y0 * bpl + x0 * 3; + for (y = 0; y < height; y++) + { + bp2 = bptr; + for (x = 0; x < width; x++) + { + r = bp2[0]; + g = bp2[1]; + b = bp2[2]; + obuf[x * 3] = b; + obuf[x * 3 + 1] = g; + obuf[x * 3 + 2] = r; + bp2 += 3; + } + bptr += rowstride; + obuf += bpl; + } +} +#endif + +/* convert 24-bit packed to 32-bit unpacked */ +/* todo: optimize this */ +static void +gdk_rgb_convert_0888 (GdkRgbInfo *image_info, GdkImage *image, + gint x0, gint y0, gint width, gint height, + const guchar *buf, int rowstride, + gint x_align, gint y_align, GdkRgbCmap *cmap) +{ + int y, w; + guchar *obuf, *p; + gint bpl; + const guchar *bptr, *bp2; + + bptr = buf; + bpl = image->bpl; + obuf = ((guchar *)image->mem) + y0 * bpl + x0 * 4; + for (y = 0; y < height; y++) + { + bp2 = bptr; + p = obuf; + w = width; + while (w--) + { + p[0] = bp2[2]; + p[1] = bp2[1]; + p[2] = bp2[0]; + p[3] = 0xff; + bp2 += 3; + p += 4; + } + bptr += rowstride; + obuf += bpl; + } +} + +#ifdef USE_MEDIALIB25 +/* convert 24-bit packed to 32-bit unpacked */ +static void +gdk_rgb_convert_0888_medialib (GdkRgbInfo *image_info, GdkImage *image, + gint x0, gint y0, gint width, gint height, + const guchar *buf, int rowstride, + gint x_align, gint y_align, GdkRgbCmap *cmap) +{ + int y, w; + guchar *obuf, *p; + gint bpl; + const guchar *bptr, *bp2; + + bptr = buf; + bpl = image->bpl; + obuf = ((guchar *)image->mem) + y0 * bpl + x0 * 4; + + mlib_VideoColorRGBint_to_BGRAint (obuf, bptr, NULL, 0xff, + width, height, bpl, + rowstride, 0); +} +#endif + +static void +gdk_rgb_convert_0888_br (GdkRgbInfo *image_info, GdkImage *image, + gint x0, gint y0, gint width, gint height, + const guchar *buf, int rowstride, + gint x_align, gint y_align, GdkRgbCmap *cmap) +{ + int y, w; + guchar *obuf, *p; + gint bpl; + const guchar *bptr, *bp2; + + bptr = buf; + bpl = image->bpl; + obuf = ((guchar *)image->mem) + y0 * bpl + x0 * 4; + for (y = 0; y < height; y++) + { + bp2 = bptr; + p = obuf; + w = width; + while (w--) + { + p[0] = 0xff; + p[1] = bp2[0]; + p[2] = bp2[1]; + p[3] = bp2[2]; + bp2 += 3; + p += 4; + } + bptr += rowstride; + obuf += bpl; + } +} + +static void +gdk_rgb_convert_8880_br (GdkRgbInfo *image_info, GdkImage *image, + gint x0, gint y0, gint width, gint height, + const guchar *buf, int rowstride, + gint x_align, gint y_align, GdkRgbCmap *cmap) +{ + int x, y; + guchar *obuf; + gint bpl; + const guchar *bptr, *bp2; + int r, g, b; + + bptr = buf; + bpl = image->bpl; + obuf = ((guchar *)image->mem) + y0 * bpl + x0 * 4; + for (y = 0; y < height; y++) + { + bp2 = bptr; + for (x = 0; x < width; x++) + { + r = bp2[0]; + g = bp2[1]; + b = bp2[2]; + ((guint32 *)obuf)[x] = (b << 16) | (g << 8) | r; + bp2 += 3; + } + bptr += rowstride; + obuf += bpl; + } +} + +/* Generic truecolor/directcolor conversion function. Slow, but these + are oddball modes. */ +static void +gdk_rgb_convert_truecolor_lsb (GdkRgbInfo *image_info, GdkImage *image, + gint x0, gint y0, gint width, gint height, + const guchar *buf, int rowstride, + gint x_align, gint y_align, + GdkRgbCmap *cmap) +{ + int x, y; + guchar *obuf, *obptr; + gint bpl; + const guchar *bptr, *bp2; + gint r, g, b; + gint r_right, r_left; + gint g_right, g_left; + gint b_right, b_left; + gint bpp; + guint32 pixel; + guint32 alpha_mask = gdk_rgb_alpha_mask (image_info); + gint i; + + r_right = 8 - image_info->visual->red_prec; + r_left = image_info->visual->red_shift; + g_right = 8 - image_info->visual->green_prec; + g_left = image_info->visual->green_shift; + b_right = 8 - image_info->visual->blue_prec; + b_left = image_info->visual->blue_shift; + bpp = image_info->bpp; + bptr = buf; + bpl = image->bpl; + obuf = ((guchar *)image->mem) + y0 * bpl + x0 * bpp; + for (y = 0; y < height; y++) + { + obptr = obuf; + bp2 = bptr; + for (x = 0; x < width; x++) + { + r = bp2[0]; + g = bp2[1]; + b = bp2[2]; + pixel = ((r >> r_right) << r_left) | + ((g >> g_right) << g_left) | + ((b >> b_right) << b_left) | alpha_mask; + for (i = 0; i < bpp; i++) + { + *obptr++ = pixel & 0xff; + pixel >>= 8; + } + bp2 += 3; + } + bptr += rowstride; + obuf += bpl; + } +} + +static void +gdk_rgb_convert_truecolor_lsb_d (GdkRgbInfo *image_info, GdkImage *image, + gint x0, gint y0, gint width, gint height, + const guchar *buf, int rowstride, + gint x_align, gint y_align, + GdkRgbCmap *cmap) +{ + int x, y; + guchar *obuf, *obptr; + gint bpl; + const guchar *bptr, *bp2; + gint r, g, b; + gint r_right, r_left, r_prec; + gint g_right, g_left, g_prec; + gint b_right, b_left, b_prec; + gint bpp; + guint32 pixel; + guint32 alpha_mask = gdk_rgb_alpha_mask (image_info); + gint i; + gint dith; + gint r1, g1, b1; + const guchar *dmp; + + r_right = 8 - image_info->visual->red_prec; + r_left = image_info->visual->red_shift; + r_prec = image_info->visual->red_prec; + g_right = 8 - image_info->visual->green_prec; + g_left = image_info->visual->green_shift; + g_prec = image_info->visual->green_prec; + b_right = 8 - image_info->visual->blue_prec; + b_left = image_info->visual->blue_shift; + b_prec = image_info->visual->blue_prec; + bpp = image_info->bpp; + bptr = buf; + bpl = image->bpl; + obuf = ((guchar *)image->mem) + y0 * bpl + x0 * bpp; + for (y = 0; y < height; y++) + { + dmp = DM[(y_align + y) & (DM_HEIGHT - 1)]; + obptr = obuf; + bp2 = bptr; + for (x = 0; x < width; x++) + { + r = bp2[0]; + g = bp2[1]; + b = bp2[2]; + dith = dmp[(x_align + x) & (DM_WIDTH - 1)] << 2; + r1 = r + (dith >> r_prec); + g1 = g + ((252 - dith) >> g_prec); + b1 = b + (dith >> b_prec); + pixel = (((r1 - (r1 >> r_prec)) >> r_right) << r_left) | + (((g1 - (g1 >> g_prec)) >> g_right) << g_left) | + (((b1 - (b1 >> b_prec)) >> b_right) << b_left) | alpha_mask; + for (i = 0; i < bpp; i++) + { + *obptr++ = pixel & 0xff; + pixel >>= 8; + } + bp2 += 3; + } + bptr += rowstride; + obuf += bpl; + } +} + +static void +gdk_rgb_convert_truecolor_msb (GdkRgbInfo *image_info, GdkImage *image, + gint x0, gint y0, gint width, gint height, + const guchar *buf, int rowstride, + gint x_align, gint y_align, + GdkRgbCmap *cmap) +{ + int x, y; + guchar *obuf, *obptr; + gint bpl; + const guchar *bptr, *bp2; + gint r, g, b; + gint r_right, r_left; + gint g_right, g_left; + gint b_right, b_left; + gint bpp; + guint32 pixel; + guint32 alpha_mask = gdk_rgb_alpha_mask (image_info); + gint shift, shift_init; + + r_right = 8 - image_info->visual->red_prec; + r_left = image_info->visual->red_shift; + g_right = 8 - image_info->visual->green_prec; + g_left = image_info->visual->green_shift; + b_right = 8 - image_info->visual->blue_prec; + b_left = image_info->visual->blue_shift; + bpp = image_info->bpp; + bptr = buf; + bpl = image->bpl; + obuf = ((guchar *)image->mem) + y0 * bpl + x0 * bpp; + shift_init = (bpp - 1) << 3; + for (y = 0; y < height; y++) + { + obptr = obuf; + bp2 = bptr; + for (x = 0; x < width; x++) + { + r = bp2[0]; + g = bp2[1]; + b = bp2[2]; + pixel = ((r >> r_right) << r_left) | + ((g >> g_right) << g_left) | + ((b >> b_right) << b_left) | alpha_mask; + for (shift = shift_init; shift >= 0; shift -= 8) + { + *obptr++ = (pixel >> shift) & 0xff; + } + bp2 += 3; + } + bptr += rowstride; + obuf += bpl; + } +} + +static void +gdk_rgb_convert_truecolor_msb_d (GdkRgbInfo *image_info, GdkImage *image, + gint x0, gint y0, gint width, gint height, + const guchar *buf, int rowstride, + gint x_align, gint y_align, + GdkRgbCmap *cmap) +{ + int x, y; + guchar *obuf, *obptr; + gint bpl; + const guchar *bptr, *bp2; + gint r, g, b; + gint r_right, r_left, r_prec; + gint g_right, g_left, g_prec; + gint b_right, b_left, b_prec; + gint bpp; + guint32 pixel; + guint32 alpha_mask = gdk_rgb_alpha_mask (image_info); + gint shift, shift_init; + gint dith; + gint r1, g1, b1; + const guchar *dmp; + + r_right = 8 - image_info->visual->red_prec; + r_left = image_info->visual->red_shift; + r_prec = image_info->visual->red_prec; + g_right = 8 - image_info->visual->green_prec; + g_left = image_info->visual->green_shift; + g_prec = image_info->visual->green_prec; + b_right = 8 - image_info->visual->blue_prec; + b_left = image_info->visual->blue_shift; + b_prec = image_info->visual->blue_prec; + bpp = image_info->bpp; + bptr = buf; + bpl = image->bpl; + obuf = ((guchar *)image->mem) + y0 * bpl + x0 * bpp; + shift_init = (bpp - 1) << 3; + for (y = 0; y < height; y++) + { + dmp = DM[(y_align + y) & (DM_HEIGHT - 1)]; + obptr = obuf; + bp2 = bptr; + for (x = 0; x < width; x++) + { + r = bp2[0]; + g = bp2[1]; + b = bp2[2]; + dith = dmp[(x_align + x) & (DM_WIDTH - 1)] << 2; + r1 = r + (dith >> r_prec); + g1 = g + ((252 - dith) >> g_prec); + b1 = b + (dith >> b_prec); + pixel = (((r1 - (r1 >> r_prec)) >> r_right) << r_left) | + (((g1 - (g1 >> g_prec)) >> g_right) << g_left) | + (((b1 - (b1 >> b_prec)) >> b_right) << b_left) | alpha_mask; + for (shift = shift_init; shift >= 0; shift -= 8) + { + *obptr++ = (pixel >> shift) & 0xff; + } + bp2 += 3; + } + bptr += rowstride; + obuf += bpl; + } +} + +/* This actually works for depths from 3 to 7 */ +static void +gdk_rgb_convert_4 (GdkRgbInfo *image_info, GdkImage *image, + gint x0, gint y0, gint width, gint height, + const guchar *buf, int rowstride, + gint x_align, gint y_align, + GdkRgbCmap *cmap) +{ + int x, y; + gint bpl; + guchar *obuf, *obptr; + const guchar *bptr, *bp2; + gint r, g, b; + const guchar *dmp; + gint dith; + guchar *colorcube_d = image_info->colorcube_d; + + bptr = buf; + bpl = image->bpl; + obuf = ((guchar *)image->mem) + y0 * bpl + x0; + for (y = 0; y < height; y++) + { + dmp = DM[(y_align + y) & (DM_HEIGHT - 1)]; + bp2 = bptr; + obptr = obuf; + for (x = 0; x < width; x += 1) + { + r = *bp2++; + g = *bp2++; + b = *bp2++; + dith = (dmp[(x_align + x) & (DM_WIDTH - 1)] << 2) | 3; + obptr[0] = colorcube_d[(((r + dith) & 0x100) >> 2) | + (((g + 258 - dith) & 0x100) >> 5) | + (((b + dith) & 0x100) >> 8)]; + obptr++; + } + bptr += rowstride; + obuf += bpl; + } +} + +static void +gdk_rgb_convert_4_pack (GdkRgbInfo *image_info, GdkImage *image, + gint x0, gint y0, gint width, gint height, + const guchar *buf, int rowstride, + gint x_align, gint y_align, + GdkRgbCmap *cmap) +{ + int x, y, ix; + gint bpl; + guchar *obuf, *obptr; + const guchar *bptr, *bp2; + gint r, g, b; + const guchar *dmp; + gint dith; + guchar *colorcube_d = image_info->colorcube_d; + guchar pix0, pix1; + + bptr = buf; + bpl = image->bpl; + obuf = ((guchar *)image->mem) + y0 * bpl + (x0 >> 1); + for (y = 0; y < height; y++) + { + dmp = DM[(y_align + y) & (DM_HEIGHT - 1)]; + bp2 = bptr; + obptr = obuf; + + x = 0; + if (x0 & 1) + { + r = *bp2++; + g = *bp2++; + b = *bp2++; + dith = (dmp[(x_align + x + 1) & (DM_WIDTH - 1)] << 2) | 3; + ix = (((r + dith) & 0x100) >> 2) | + (((g + 258 - dith) & 0x100) >> 5) | + (((b + dith) & 0x100) >> 8); + pix1 = (colorcube_d[ix]); + *obptr = (*obptr & 0xF0) | pix1; + obptr++; + x++; + } + while (x < width) + { + r = *bp2++; + g = *bp2++; + b = *bp2++; + dith = (dmp[(x_align + x) & (DM_WIDTH - 1)] << 2) | 3; + ix = (((r + dith) & 0x100) >> 2) | + (((g + 258 - dith) & 0x100) >> 5) | + (((b + dith) & 0x100) >> 8); + pix0 = (colorcube_d[ix]); + x++; + if (x == width) + pix1 = (*obptr & 0x0F); + else + { + r = *bp2++; + g = *bp2++; + b = *bp2++; + dith = (dmp[(x_align + x + 1) & (DM_WIDTH - 1)] << 2) | 3; + ix = (((r + dith) & 0x100) >> 2) | + (((g + 258 - dith) & 0x100) >> 5) | + (((b + dith) & 0x100) >> 8); + pix1 = (colorcube_d[ix]); + x++; + } + *obptr++ = (pix0 << 4) | pix1; + } + bptr += rowstride; + obuf += bpl; + } +} + +/* This actually works for depths from 3 to 7 */ +static void +gdk_rgb_convert_gray4 (GdkRgbInfo *image_info, GdkImage *image, + gint x0, gint y0, gint width, gint height, + const guchar *buf, int rowstride, + gint x_align, gint y_align, GdkRgbCmap *cmap) +{ + int x, y; + gint bpl; + guchar *obuf, *obptr; + const guchar *bptr, *bp2; + gint r, g, b; + gint shift; + + bptr = buf; + bpl = image->bpl; + obuf = ((guchar *)image->mem) + y0 * bpl + x0; + shift = 9 - image_info->visual->depth; + for (y = 0; y < height; y++) + { + bp2 = bptr; + obptr = obuf; + for (x = 0; x < width; x++) + { + r = *bp2++; + g = *bp2++; + b = *bp2++; + obptr[0] = (g + ((b + r) >> 1)) >> shift; + obptr++; + } + bptr += rowstride; + obuf += bpl; + } +} + +static void +gdk_rgb_convert_gray4_pack (GdkRgbInfo *image_info, GdkImage *image, + gint x0, gint y0, gint width, gint height, + const guchar *buf, int rowstride, + gint x_align, gint y_align, GdkRgbCmap *cmap) +{ + int x, y; + gint bpl; + guchar *obuf, *obptr; + const guchar *bptr, *bp2; + gint r, g, b; + gint shift; + guchar pix0, pix1; + /* todo: this is hardcoded to big-endian. Make endian-agile. */ + + bptr = buf; + bpl = image->bpl; + obuf = ((guchar *)image->mem) + y0 * bpl + (x0 >> 1); + shift = 9 - image_info->visual->depth; + for (y = 0; y < height; y++) + { + bp2 = bptr; + obptr = obuf; + + x = 0; + if (x0 & 1) + { + r = *bp2++; + g = *bp2++; + b = *bp2++; + pix1 = (g + ((b + r) >> 1)) >> shift; + *obptr = (*obptr & 0xF0) | pix1; + obptr++; + x++; + } + while (x < width) + { + r = *bp2++; + g = *bp2++; + b = *bp2++; + pix0 = (g + ((b + r) >> 1)) >> shift; + x++; + if (x == width) + pix1 = (*obptr & 0x0F); + else + { + r = *bp2++; + g = *bp2++; + b = *bp2++; + pix1 = (g + ((b + r) >> 1)) >> shift; + x++; + } + *obptr++ = (pix0 << 4) | pix1; + } + bptr += rowstride; + obuf += bpl; + } +} + +/* This actually works for depths from 3 to 7 */ +static void +gdk_rgb_convert_gray4_d (GdkRgbInfo *image_info, GdkImage *image, + gint x0, gint y0, gint width, gint height, + const guchar *buf, int rowstride, + gint x_align, gint y_align, GdkRgbCmap *cmap) +{ + int x, y; + gint bpl; + guchar *obuf, *obptr; + const guchar *bptr, *bp2; + gint r, g, b; + const guchar *dmp; + gint prec, right; + gint gray; + + bptr = buf; + bpl = image->bpl; + obuf = ((guchar *)image->mem) + y0 * bpl + x0; + prec = image_info->visual->depth; + right = 8 - prec; + for (y = 0; y < height; y++) + { + bp2 = bptr; + obptr = obuf; + dmp = DM[(y_align + y) & (DM_HEIGHT - 1)]; + for (x = 0; x < width; x++) + { + r = *bp2++; + g = *bp2++; + b = *bp2++; + gray = (g + ((b + r) >> 1)) >> 1; + gray += (dmp[(x_align + x) & (DM_WIDTH - 1)] << 2) >> prec; + obptr[0] = (gray - (gray >> prec)) >> right; + obptr++; + } + bptr += rowstride; + obuf += bpl; + } +} + +static void +gdk_rgb_convert_gray4_d_pack (GdkRgbInfo *image_info, GdkImage *image, + gint x0, gint y0, gint width, gint height, + const guchar *buf, int rowstride, + gint x_align, gint y_align, GdkRgbCmap *cmap) +{ + int x, y; + gint bpl; + guchar *obuf, *obptr; + const guchar *bptr, *bp2; + gint r, g, b; + const guchar *dmp; + gint prec, right; + gint gray; + guchar pix0, pix1; + /* todo: this is hardcoded to big-endian. Make endian-agile. */ + + bptr = buf; + bpl = image->bpl; + obuf = ((guchar *)image->mem) + y0 * bpl + (x0 >> 1); + prec = image_info->visual->depth; + right = 8 - prec; + for (y = 0; y < height; y++) + { + bp2 = bptr; + obptr = obuf; + dmp = DM[(y_align + y) & (DM_HEIGHT - 1)]; + + x = 0; + if (x0 & 1) + { + r = *bp2++; + g = *bp2++; + b = *bp2++; + gray = (g + ((b + r) >> 1)) >> 1; + gray += (dmp[(x_align + x + 1) & (DM_WIDTH - 1)] << 2) >> prec; + pix1 = (gray - (gray >> prec)) >> right; + *obptr = (*obptr & 0xF0) | pix1; + obptr++; + x++; + } + while (x < width) + { + r = *bp2++; + g = *bp2++; + b = *bp2++; + gray = (g + ((b + r) >> 1)) >> 1; + gray += (dmp[(x_align + x) & (DM_WIDTH - 1)] << 2) >> prec; + pix0 = (gray - (gray >> prec)) >> right; + x++; + if (x == width) + pix1 = (*obptr & 0x0F); + else + { + r = *bp2++; + g = *bp2++; + b = *bp2++; + gray = (g + ((b + r) >> 1)) >> 1; + gray += (dmp[(x_align + x + 1) & (DM_WIDTH - 1)] << 2) >> prec; + pix1 = (gray - (gray >> prec)) >> right; + x++; + } + *obptr++ = (pix0 << 4) | pix1; + } + bptr += rowstride; + obuf += bpl; + } +} + +static void +gdk_rgb_convert_1 (GdkRgbInfo *image_info, GdkImage *image, + gint x0, gint y0, gint width, gint height, + const guchar *buf, int rowstride, + gint x_align, gint y_align, + GdkRgbCmap *cmap) +{ + int x, y; + gint bpl; + guchar *obuf, *obptr; + const guchar *bptr, *bp2; + gint r, g, b; + const guchar *dmp; + gint dith; + guchar byte; + + bptr = buf; + bpl = image->bpl; + obuf = ((guchar *)image->mem) + y0 * bpl + (x0 >> 3); + byte = 0; /* unnecessary, but it keeps gcc from complaining */ + for (y = 0; y < height; y++) + { + dmp = DM[(y_align + y) & (DM_HEIGHT - 1)]; + bp2 = bptr; + obptr = obuf; + for (x = 0; x < width; x++) + { + r = *bp2++; + g = *bp2++; + b = *bp2++; + dith = (dmp[(x_align + x) & (DM_WIDTH - 1)] << 4) | 4; + byte += byte + (r + g + g + b + dith > 1020); + if ((x & 7) == 7) + { + obptr[0] = byte; + obptr++; + } + } + if (x & 7) + obptr[0] = byte << (8 - (x & 7)); + bptr += rowstride; + obuf += bpl; + } +} + +/* Returns a pointer to the stage buffer. */ +static guchar * +gdk_rgb_ensure_stage (GdkRgbInfo *image_info) +{ + if (image_info->stage_buf == NULL) + image_info->stage_buf = g_malloc (GDK_SCRATCH_IMAGE_HEIGHT * STAGE_ROWSTRIDE); + return image_info->stage_buf; +} + +/* This is slow. Speed me up, please. */ +static void +gdk_rgb_32_to_stage (GdkRgbInfo *image_info, + const guchar *buf, gint rowstride, gint width, gint height) +{ + gint x, y; + const guchar *pi_start; + guchar *po_start; + const guchar *pi; + guchar *po; + + pi_start = buf; + po_start = gdk_rgb_ensure_stage (image_info); + for (y = 0; y < height; y++) + { + pi = pi_start; + po = po_start; + for (x = 0; x < width; x++) + { + *po++ = *pi++; + *po++ = *pi++; + *po++ = *pi++; + pi++; + } + pi_start += rowstride; + po_start += STAGE_ROWSTRIDE; + } +} + +/* Generic 32bit RGB conversion function - convert to 24bit packed, then + go from there. */ +static void +gdk_rgb_convert_32_generic (GdkRgbInfo *image_info, GdkImage *image, + gint x0, gint y0, gint width, gint height, + const guchar *buf, gint rowstride, + gint x_align, gint y_align, GdkRgbCmap *cmap) +{ + gdk_rgb_32_to_stage (image_info, buf, rowstride, width, height); + + (*image_info->conv) (image_info, image, x0, y0, width, height, + image_info->stage_buf, STAGE_ROWSTRIDE, + x_align, y_align, cmap); +} + +/* Generic 32bit RGB conversion function - convert to 24bit packed, then + go from there. */ +static void +gdk_rgb_convert_32_generic_d (GdkRgbInfo *image_info, GdkImage *image, + gint x0, gint y0, gint width, gint height, + const guchar *buf, gint rowstride, + gint x_align, gint y_align, GdkRgbCmap *cmap) +{ + gdk_rgb_32_to_stage (image_info, buf, rowstride, width, height); + + (*image_info->conv_d) (image_info, image, x0, y0, width, height, + image_info->stage_buf, STAGE_ROWSTRIDE, + x_align, y_align, cmap); +} + +/* This is slow. Speed me up, please. */ +static void +gdk_rgb_gray_to_stage (GdkRgbInfo *image_info, + const guchar *buf, gint rowstride, gint width, gint height) +{ + gint x, y; + const guchar *pi_start; + guchar *po_start; + const guchar *pi; + guchar *po; + guchar gray; + + pi_start = buf; + po_start = gdk_rgb_ensure_stage (image_info); + for (y = 0; y < height; y++) + { + pi = pi_start; + po = po_start; + for (x = 0; x < width; x++) + { + gray = *pi++; + *po++ = gray; + *po++ = gray; + *po++ = gray; + } + pi_start += rowstride; + po_start += STAGE_ROWSTRIDE; + } +} + +/* Generic gray conversion function - convert to 24bit packed, then go + from there. */ +static void +gdk_rgb_convert_gray_generic (GdkRgbInfo *image_info, GdkImage *image, + gint x0, gint y0, gint width, gint height, + const guchar *buf, gint rowstride, + gint x_align, gint y_align, GdkRgbCmap *cmap) +{ + gdk_rgb_gray_to_stage (image_info, buf, rowstride, width, height); + + (*image_info->conv) (image_info, image, x0, y0, width, height, + image_info->stage_buf, STAGE_ROWSTRIDE, + x_align, y_align, cmap); +} + +static void +gdk_rgb_convert_gray_generic_d (GdkRgbInfo *image_info, GdkImage *image, + gint x0, gint y0, gint width, gint height, + const guchar *buf, gint rowstride, + gint x_align, gint y_align, GdkRgbCmap *cmap) +{ + gdk_rgb_gray_to_stage (image_info, buf, rowstride, width, height); + + (*image_info->conv_d) (image_info, image, x0, y0, width, height, + image_info->stage_buf, STAGE_ROWSTRIDE, + x_align, y_align, cmap); +} + +/* Render grayscale using indexed method. */ +static void +gdk_rgb_convert_gray_cmap (GdkRgbInfo *image_info, GdkImage *image, + gint x0, gint y0, gint width, gint height, + const guchar *buf, gint rowstride, + gint x_align, gint y_align, GdkRgbCmap *cmap) +{ + (*image_info->conv_indexed) (image_info, image, x0, y0, width, height, + buf, rowstride, + x_align, y_align, image_info->gray_cmap); +} + +#if 0 +static void +gdk_rgb_convert_gray_cmap_d (GdkRgbInfo *image_info, GdkImage *image, + gint x0, gint y0, gint width, gint height, + const guchar *buf, gint rowstride, + gint x_align, gint y_align, GdkRgbCmap *cmap) +{ + (*image_info->conv_indexed_d) (image_info, image, x0, y0, width, height, + buf, rowstride, + x_align, y_align, image_info->gray_cmap); +} +#endif + +/* This is slow. Speed me up, please. */ +static void +gdk_rgb_indexed_to_stage (GdkRgbInfo *image_info, + const guchar *buf, gint rowstride, gint width, gint height, + GdkRgbCmap *cmap) +{ + gint x, y; + const guchar *pi_start; + guchar *po_start; + const guchar *pi; + guchar *po; + gint rgb; + + pi_start = buf; + po_start = gdk_rgb_ensure_stage (image_info); + for (y = 0; y < height; y++) + { + pi = pi_start; + po = po_start; + for (x = 0; x < width; x++) + { + rgb = cmap->colors[*pi++]; + *po++ = rgb >> 16; + *po++ = (rgb >> 8) & 0xff; + *po++ = rgb & 0xff; + } + pi_start += rowstride; + po_start += STAGE_ROWSTRIDE; + } +} + +/* Generic gray conversion function - convert to 24bit packed, then go + from there. */ +static void +gdk_rgb_convert_indexed_generic (GdkRgbInfo *image_info, GdkImage *image, + gint x0, gint y0, gint width, gint height, + const guchar *buf, gint rowstride, + gint x_align, gint y_align, GdkRgbCmap *cmap) +{ + gdk_rgb_indexed_to_stage (image_info, buf, rowstride, width, height, cmap); + + (*image_info->conv) (image_info, image, x0, y0, width, height, + image_info->stage_buf, STAGE_ROWSTRIDE, + x_align, y_align, cmap); +} + +static void +gdk_rgb_convert_indexed_generic_d (GdkRgbInfo *image_info, GdkImage *image, + gint x0, gint y0, gint width, gint height, + const guchar *buf, gint rowstride, + gint x_align, gint y_align, + GdkRgbCmap *cmap) +{ + gdk_rgb_indexed_to_stage (image_info, buf, rowstride, width, height, cmap); + + (*image_info->conv_d) (image_info, image, x0, y0, width, height, + image_info->stage_buf, STAGE_ROWSTRIDE, + x_align, y_align, cmap); +} + +/* Select a conversion function based on the visual and a + representative image. */ +static void +gdk_rgb_select_conv (GdkRgbInfo *image_info) +{ + GdkByteOrder byte_order; + gint depth, bpp, byterev; + GdkVisualType vtype; + guint32 red_mask, green_mask, blue_mask; + GdkRgbConvFunc conv, conv_d; + GdkRgbConvFunc conv_32, conv_32_d; + GdkRgbConvFunc conv_gray, conv_gray_d; + GdkRgbConvFunc conv_indexed, conv_indexed_d; + gboolean mask_rgb, mask_bgr; + GdkScreen *screen = gdk_visual_get_screen (image_info->visual); + + depth = image_info->visual->depth; + + bpp = _gdk_windowing_get_bits_for_depth (gdk_screen_get_display (screen), + image_info->visual->depth); + + byte_order = image_info->visual->byte_order; + if (gdk_rgb_verbose) + g_print ("Chose visual type=%d depth=%d, image bpp=%d, %s first\n", + image_info->visual->type, image_info->visual->depth, + bpp, byte_order == GDK_LSB_FIRST ? "lsb" : "msb"); + +#if G_BYTE_ORDER == G_BIG_ENDIAN + byterev = (byte_order == GDK_LSB_FIRST); +#else + byterev = (byte_order == GDK_MSB_FIRST); +#endif + + vtype = image_info->visual->type; + if (vtype == GDK_VISUAL_DIRECT_COLOR) + vtype = GDK_VISUAL_TRUE_COLOR; + + red_mask = image_info->visual->red_mask; + green_mask = image_info->visual->green_mask; + blue_mask = image_info->visual->blue_mask; + + mask_rgb = red_mask == 0xff0000 && green_mask == 0xff00 && blue_mask == 0xff; + mask_bgr = red_mask == 0xff && green_mask == 0xff00 && blue_mask == 0xff0000; + + conv = NULL; + conv_d = NULL; + + conv_32 = gdk_rgb_convert_32_generic; + conv_32_d = gdk_rgb_convert_32_generic_d; + + conv_gray = gdk_rgb_convert_gray_generic; + conv_gray_d = gdk_rgb_convert_gray_generic_d; + + conv_indexed = gdk_rgb_convert_indexed_generic; + conv_indexed_d = gdk_rgb_convert_indexed_generic_d; + + image_info->dith_default = FALSE; + + if (image_info->bitmap) + conv = gdk_rgb_convert_1; + else if (bpp == 16 && depth == 16 && !byterev && + red_mask == 0xf800 && green_mask == 0x7e0 && blue_mask == 0x1f) + { + conv = gdk_rgb_convert_565; + conv_d = gdk_rgb_convert_565_d; + conv_gray = gdk_rgb_convert_565_gray; + gdk_rgb_preprocess_dm_565 (); + } + else if (bpp == 16 && depth == 16 && + vtype == GDK_VISUAL_TRUE_COLOR && byterev && + red_mask == 0xf800 && green_mask == 0x7e0 && blue_mask == 0x1f) + conv = gdk_rgb_convert_565_br; + + else if (bpp == 16 && depth == 15 && + vtype == GDK_VISUAL_TRUE_COLOR && !byterev && + red_mask == 0x7c00 && green_mask == 0x3e0 && blue_mask == 0x1f) + conv = gdk_rgb_convert_555; + + else if (bpp == 16 && depth == 15 && + vtype == GDK_VISUAL_TRUE_COLOR && byterev && + red_mask == 0x7c00 && green_mask == 0x3e0 && blue_mask == 0x1f) + conv = gdk_rgb_convert_555_br; + + /* I'm not 100% sure about the 24bpp tests - but testing will show*/ + else if (bpp == 24 && depth == 24 && vtype == GDK_VISUAL_TRUE_COLOR && + ((mask_rgb && byte_order == GDK_LSB_FIRST) || + (mask_bgr && byte_order == GDK_MSB_FIRST))) + conv = gdk_rgb_convert_888_lsb; + else if (bpp == 24 && depth == 24 && vtype == GDK_VISUAL_TRUE_COLOR && + ((mask_rgb && byte_order == GDK_MSB_FIRST) || + (mask_bgr && byte_order == GDK_LSB_FIRST))) + conv = gdk_rgb_convert_888_msb; + else if (bpp == 32 && + (depth == 24 || depth == 32) && + vtype == GDK_VISUAL_TRUE_COLOR && + (mask_rgb && byte_order == GDK_MSB_FIRST)) + conv = gdk_rgb_convert_0888_br; + else if (bpp == 32 && + (depth == 24 || depth == 32) && + vtype == GDK_VISUAL_TRUE_COLOR && + (mask_rgb && byte_order == GDK_LSB_FIRST)) + { +#ifdef USE_MEDIALIB25 + if (_gdk_use_medialib ()) + conv = gdk_rgb_convert_0888_medialib; + else + conv = gdk_rgb_convert_0888; +#else + conv = gdk_rgb_convert_0888; +#endif + } + +#if G_BYTE_ORDER == G_BIG_ENDIAN + else if (bpp == 32 && depth == 24 && vtype == GDK_VISUAL_TRUE_COLOR && + (mask_bgr && byte_order == GDK_MSB_FIRST)) + conv = gdk_rgb_convert_8880_br; + else if (bpp == 32 && depth == 32 && vtype == GDK_VISUAL_TRUE_COLOR && + (mask_rgb && byte_order == GDK_LSB_FIRST)) + conv = gdk_rgb_convert_8880_br; + else if (bpp == 32 && depth == 32 && vtype == GDK_VISUAL_TRUE_COLOR && + (mask_rgb && byte_order == GDK_MSB_FIRST)) + conv = gdk_rgb_convert_8880_br; +#else + else if (bpp == 32 && depth == 24 && vtype == GDK_VISUAL_TRUE_COLOR && + (mask_bgr && byte_order == GDK_LSB_FIRST)) + conv = gdk_rgb_convert_8880_br; + else if (bpp == 32 && depth == 32 && vtype == GDK_VISUAL_TRUE_COLOR && + (mask_rgb && byte_order == GDK_LSB_FIRST)) + { +#ifdef USE_MEDIALIB25 + if (_gdk_use_medialib ()) + conv = gdk_rgb_convert_0888_medialib; + else + conv = gdk_rgb_convert_0888; +#else + conv = gdk_rgb_convert_0888; +#endif + } +#endif + else if (vtype == GDK_VISUAL_TRUE_COLOR && byte_order == GDK_LSB_FIRST) + { + conv = gdk_rgb_convert_truecolor_lsb; + conv_d = gdk_rgb_convert_truecolor_lsb_d; + } + else if (vtype == GDK_VISUAL_TRUE_COLOR && byte_order == GDK_MSB_FIRST) + { + conv = gdk_rgb_convert_truecolor_msb; + conv_d = gdk_rgb_convert_truecolor_msb_d; + } + else if (bpp == 8 && + depth <= 8 && + depth > 4 && + (vtype == GDK_VISUAL_PSEUDO_COLOR + || vtype == GDK_VISUAL_STATIC_COLOR +#ifdef ENABLE_GRAYSCALE + || vtype == GDK_VISUAL_GRAYSCALE +#endif + )) + { + /* Mainly for Win32: use these conversion functions also for the + * explicitly (on user request) restricted palette versions of + * 256-color, i.e. depths 5, 6 and 7. On X11, such depths + * probably never occur. + */ + image_info->dith_default = TRUE; + conv = gdk_rgb_convert_8; + if (vtype != GDK_VISUAL_GRAYSCALE) + { + if (image_info->nred_shades == 6 && + image_info->ngreen_shades == 6 && + image_info->nblue_shades == 6) + conv_d = gdk_rgb_convert_8_d666; + else + conv_d = gdk_rgb_convert_8_d; + } + conv_indexed = gdk_rgb_convert_8_indexed; + conv_gray = gdk_rgb_convert_gray_cmap; + } + else if (bpp == 8 && depth == 8 && (vtype == GDK_VISUAL_STATIC_GRAY +#ifdef not_ENABLE_GRAYSCALE + || vtype == GDK_VISUAL_GRAYSCALE +#endif + )) + { + conv = gdk_rgb_convert_gray8; + conv_gray = gdk_rgb_convert_gray8_gray; + } + else if (bpp == 8 && depth < 8 && depth >= 2 && + (vtype == GDK_VISUAL_STATIC_GRAY + || vtype == GDK_VISUAL_GRAYSCALE)) + { + conv = gdk_rgb_convert_gray4; + conv_d = gdk_rgb_convert_gray4_d; + } + else if (bpp == 8 && depth < 8 && depth >= 3) + { + conv = gdk_rgb_convert_4; + } + else if (bpp == 4 && depth <= 4 && depth >= 2 && + (vtype == GDK_VISUAL_STATIC_GRAY + || vtype == GDK_VISUAL_GRAYSCALE)) + { + conv = gdk_rgb_convert_gray4_pack; + conv_d = gdk_rgb_convert_gray4_d_pack; + } + else if (bpp == 4 && depth == 4 && + vtype == GDK_VISUAL_STATIC_COLOR) + conv = gdk_rgb_convert_4_pack; + + if (!conv) + g_error ("Visual type=%d depth=%d, image bpp=%d, %s first\n" + "is not supported by GdkRGB. Please submit a bug report\n" + "with the above values to bugzilla.gnome.org", + vtype, depth, bpp, + byte_order == GDK_LSB_FIRST ? "lsb" : "msb"); + + if (conv_d == NULL) + conv_d = conv; + + image_info->conv = conv; + image_info->conv_d = conv_d; + + image_info->conv_32 = conv_32; + image_info->conv_32_d = conv_32_d; + + image_info->conv_gray = conv_gray; + image_info->conv_gray_d = conv_gray_d; + + image_info->conv_indexed = conv_indexed; + image_info->conv_indexed_d = conv_indexed_d; +} + +static void +gdk_draw_rgb_image_core (GdkRgbInfo *image_info, + GdkDrawable *drawable, + GdkGC *gc, + gint x, + gint y, + gint width, + gint height, + const guchar *buf, + gint pixstride, + gint rowstride, + GdkRgbConvFunc conv, + GdkRgbCmap *cmap, + gint xdith, + gint ydith) +{ + gint y0, x0; + gint xs0, ys0; + GdkImage *image; + gint width1, height1; + const guchar *buf_ptr; + + if (image_info->bitmap) + { + if (image_info->own_gc == NULL) + image_info->own_gc = gdk_gc_new (drawable); + gc = image_info->own_gc; + } + for (y0 = 0; y0 < height; y0 += GDK_SCRATCH_IMAGE_HEIGHT) + { + height1 = MIN (height - y0, GDK_SCRATCH_IMAGE_HEIGHT); + for (x0 = 0; x0 < width; x0 += GDK_SCRATCH_IMAGE_WIDTH) + { + width1 = MIN (width - x0, GDK_SCRATCH_IMAGE_WIDTH); + buf_ptr = buf + y0 * rowstride + x0 * pixstride; + + image = _gdk_image_get_scratch (gdk_drawable_get_screen (drawable), + width1, height1, + image_info->visual->depth, &xs0, &ys0); + + conv (image_info, image, xs0, ys0, width1, height1, buf_ptr, rowstride, + x + x0 + xdith, y + y0 + ydith, cmap); + +#ifndef DONT_ACTUALLY_DRAW + gdk_draw_image (drawable, gc, + image, xs0, ys0, x + x0, y + y0, width1, height1); +#endif + } + } +} + +static GdkRgbInfo * +gdk_rgb_get_info_from_drawable (GdkDrawable *drawable) +{ + GdkColormap *cmap = gdk_drawable_get_colormap (drawable); + GdkScreen *screen = gdk_drawable_get_screen (drawable); + + if (!cmap) + { + /* This guessing is required to maintain backward compatibility, + * but would otherwise be a bad thing + */ + + gint depth = gdk_drawable_get_depth (drawable); + GdkColormap *rgb_cmap = gdk_screen_get_rgb_colormap (screen); + if (depth == gdk_colormap_get_visual (rgb_cmap)->depth) + cmap = rgb_cmap; + else + { + g_warning ("The gdk_draw_*_image require the drawable argument to\n" + "have a specified colormap. All windows have a colormap,\n" + "however, pixmaps only have colormap by default if they\n" + "were created with a non-NULL window argument. Otherwise\n" + "a colormap must be set on them with gdk_drawable_set_colormap"); + return NULL; + } + } + + return gdk_rgb_get_info_from_colormap (cmap); +} + +void +gdk_draw_rgb_image (GdkDrawable *drawable, + GdkGC *gc, + gint x, + gint y, + gint width, + gint height, + GdkRgbDither dith, + const guchar *rgb_buf, + gint rowstride) +{ + GdkRgbInfo *image_info = gdk_rgb_get_info_from_drawable (drawable); + if (!image_info) + return; + + if (dith == GDK_RGB_DITHER_NONE || (dith == GDK_RGB_DITHER_NORMAL && + !image_info->dith_default)) + gdk_draw_rgb_image_core (image_info, drawable, gc, x, y, width, height, + rgb_buf, 3, rowstride, image_info->conv, NULL, + 0, 0); + else + gdk_draw_rgb_image_core (image_info, drawable, gc, x, y, width, height, + rgb_buf, 3, rowstride, image_info->conv_d, NULL, + 0, 0); +} + +void +gdk_draw_rgb_image_dithalign (GdkDrawable *drawable, + GdkGC *gc, + gint x, + gint y, + gint width, + gint height, + GdkRgbDither dith, + const guchar *rgb_buf, + gint rowstride, + gint xdith, + gint ydith) +{ + GdkRgbInfo *image_info = gdk_rgb_get_info_from_drawable (drawable); + if (!image_info) + return; + + if (dith == GDK_RGB_DITHER_NONE || (dith == GDK_RGB_DITHER_NORMAL && + !image_info->dith_default)) + gdk_draw_rgb_image_core (image_info, drawable, gc, x, y, width, height, + rgb_buf, 3, rowstride, image_info->conv, NULL, + xdith, ydith); + else + gdk_draw_rgb_image_core (image_info, drawable, gc, x, y, width, height, + rgb_buf, 3, rowstride, image_info->conv_d, NULL, + xdith, ydith); +} + +void +gdk_draw_rgb_32_image (GdkDrawable *drawable, + GdkGC *gc, + gint x, + gint y, + gint width, + gint height, + GdkRgbDither dith, + const guchar *buf, + gint rowstride) +{ + GdkRgbInfo *image_info = gdk_rgb_get_info_from_drawable (drawable); + if (!image_info) + return; + + if (dith == GDK_RGB_DITHER_NONE || (dith == GDK_RGB_DITHER_NORMAL && + !image_info->dith_default)) + gdk_draw_rgb_image_core (image_info, drawable, gc, x, y, width, height, + buf, 4, rowstride, + image_info->conv_32, NULL, 0, 0); + else + gdk_draw_rgb_image_core (image_info, drawable, gc, x, y, width, height, + buf, 4, rowstride, + image_info->conv_32_d, NULL, 0, 0); +} + +/** + * gdk_draw_rgb_32_image_dithalign: + * @drawable: a #GdkDrawable + * @gc: a #GdkGC + * @x: X coordinate on @drawable where image should go + * @y: Y coordinate on @drawable where image should go + * @width: width of area of image to draw + * @height: height of area of image to draw + * @dith: dithering mode + * @buf: RGB image data + * @rowstride: rowstride of RGB image data + * @xdith: X dither offset + * @ydith: Y dither offset + * + * Like gdk_draw_rgb_32_image(), but allows you to specify the dither + * offsets. See gdk_draw_rgb_image_dithalign() for more details. + * + * Deprecated: 2.22: Cairo handles colors automatically. + **/ +void +gdk_draw_rgb_32_image_dithalign (GdkDrawable *drawable, + GdkGC *gc, + gint x, + gint y, + gint width, + gint height, + GdkRgbDither dith, + const guchar *buf, + gint rowstride, + gint xdith, + gint ydith) +{ + GdkRgbInfo *image_info = gdk_rgb_get_info_from_drawable (drawable); + if (!image_info) + return; + + if (dith == GDK_RGB_DITHER_NONE || (dith == GDK_RGB_DITHER_NORMAL && + !image_info->dith_default)) + gdk_draw_rgb_image_core (image_info, drawable, gc, x, y, width, height, + buf, 4, rowstride, + image_info->conv_32, NULL, xdith, ydith); + else + gdk_draw_rgb_image_core (image_info, drawable, gc, x, y, width, height, + buf, 4, rowstride, + image_info->conv_32_d, NULL, xdith, ydith); +} + +static void +gdk_rgb_make_gray_cmap (GdkRgbInfo *info) +{ + guint32 rgb[256]; + gint i; + + for (i = 0; i < 256; i++) + rgb[i] = (i << 16) | (i << 8) | i; + info->gray_cmap = gdk_rgb_cmap_new (rgb, 256); +} + +void +gdk_draw_gray_image (GdkDrawable *drawable, + GdkGC *gc, + gint x, + gint y, + gint width, + gint height, + GdkRgbDither dith, + const guchar *buf, + gint rowstride) +{ + GdkRgbInfo *image_info = gdk_rgb_get_info_from_drawable (drawable); + if (!image_info) + return; + + if (image_info->bpp == 1 && + image_info->gray_cmap == NULL && + (image_info->visual->type == GDK_VISUAL_PSEUDO_COLOR || + image_info->visual->type == GDK_VISUAL_STATIC_COLOR || + image_info->visual->type == GDK_VISUAL_GRAYSCALE)) + gdk_rgb_make_gray_cmap (image_info); + + if (dith == GDK_RGB_DITHER_NONE || (dith == GDK_RGB_DITHER_NORMAL && + !image_info->dith_default)) + gdk_draw_rgb_image_core (image_info, drawable, gc, x, y, width, height, + buf, 1, rowstride, + image_info->conv_gray, NULL, 0, 0); + else + gdk_draw_rgb_image_core (image_info, drawable, gc, x, y, width, height, + buf, 1, rowstride, + image_info->conv_gray_d, NULL, 0, 0); +} + +static GdkRgbCmapInfo * +gdk_rgb_cmap_get_info (GdkRgbCmap *cmap, + GdkRgbInfo *image_info) +{ + GSList *tmp_list; + GdkRgbCmapInfo *cmap_info; + int i, j; + guint32 rgb; + + /* We don't need a LUT for TrueColor or DirectColor visuals */ + if (image_info->bpp != 1 || + !(image_info->visual->type == GDK_VISUAL_PSEUDO_COLOR || + image_info->visual->type == GDK_VISUAL_STATIC_COLOR || + image_info->visual->type == GDK_VISUAL_GRAYSCALE)) + return NULL; + + tmp_list = cmap->info_list; + + while (tmp_list) + { + cmap_info = tmp_list->data; + if (cmap_info->image_info == image_info) + return cmap_info; + } + + cmap_info = g_new (GdkRgbCmapInfo, 1); + cmap_info->image_info = image_info; + cmap_info->cmap = cmap; + + for (i = 0; i < cmap->n_colors; i++) + { + rgb = cmap->colors[i]; + j = ((rgb & 0xf00000) >> 12) | + ((rgb & 0xf000) >> 8) | + ((rgb & 0xf0) >> 4); +#ifdef VERBOSE + g_print ("%d %x %x\n", i, j, image_info->colorcube[j]); +#endif + cmap_info->lut[i] = image_info->colorcube[j]; + } + + cmap->info_list = g_slist_prepend (cmap->info_list, cmap_info); + image_info->cmap_info_list = g_slist_prepend (image_info->cmap_info_list, cmap_info); + + return cmap_info; +} + +GdkRgbCmap * +gdk_rgb_cmap_new (guint32 *colors, gint n_colors) +{ + GdkRgbCmap *cmap; + + g_return_val_if_fail (n_colors >= 0, NULL); + g_return_val_if_fail (n_colors <= 256, NULL); + + cmap = g_new (GdkRgbCmap, 1); + + cmap->n_colors = n_colors; + memcpy (cmap->colors, colors, n_colors * sizeof(guint32)); + + cmap->info_list = NULL; + + return cmap; +} + +void +gdk_rgb_cmap_free (GdkRgbCmap *cmap) +{ + GSList *tmp_list; + + tmp_list = cmap->info_list; + while (tmp_list) + { + GdkRgbCmapInfo *cmap_info = tmp_list->data; + cmap_info->image_info->cmap_info_list = g_slist_remove (cmap_info->image_info->cmap_info_list, cmap_info); + g_free (cmap_info); + tmp_list = tmp_list->next; + } + g_slist_free (cmap->info_list); + + g_free (cmap); +} + +void +gdk_draw_indexed_image (GdkDrawable *drawable, + GdkGC *gc, + gint x, + gint y, + gint width, + gint height, + GdkRgbDither dith, + const guchar *buf, + gint rowstride, + GdkRgbCmap *cmap) +{ + GdkRgbInfo *image_info = gdk_rgb_get_info_from_drawable (drawable); + if (!image_info) + return; + + if (dith == GDK_RGB_DITHER_NONE || (dith == GDK_RGB_DITHER_NORMAL && + !image_info->dith_default)) + gdk_draw_rgb_image_core (image_info, drawable, gc, x, y, width, height, + buf, 1, rowstride, + image_info->conv_indexed, cmap, 0, 0); + else + gdk_draw_rgb_image_core (image_info, drawable, gc, x, y, width, height, + buf, 1, rowstride, + image_info->conv_indexed_d, cmap, 0, 0); +} + +gboolean +gdk_rgb_colormap_ditherable (GdkColormap *cmap) +{ + GdkRgbInfo *image_info = gdk_rgb_get_info_from_colormap (cmap); + + return (image_info->conv != image_info->conv_d); +} + +gboolean +gdk_rgb_ditherable (void) +{ + return gdk_rgb_colormap_ditherable (gdk_rgb_get_colormap ()); +} + +/** + * gdk_rgb_get_colormap: + * + * Get the preferred colormap for rendering image data. Not a + * very useful function; historically, GDK could only render RGB image + * data to one colormap and visual, but in the current version it can + * render to any colormap and visual. So there's no need to call this + * function. + * + * Return value: (transfer none): the preferred colormap + * + * Deprecated: 2.22: Use gdk_screen_get_system_colormap (gdk_screen_get_default ()) instead. + **/ +GdkColormap * +gdk_rgb_get_colormap (void) +{ + static GdkColormap *cmap = NULL; + if (!cmap) + { + GdkRgbInfo *image_info = gdk_rgb_create_info (gdk_rgb_choose_visual (gdk_screen_get_default ()), NULL); + cmap = image_info->cmap; + } + + return cmap; +} + +/** + * gdk_screen_get_rgb_colormap: + * @screen: a #GdkScreen. + * + * Gets the preferred colormap for rendering image data on @screen. + * Not a very useful function; historically, GDK could only render RGB + * image data to one colormap and visual, but in the current version + * it can render to any colormap and visual. So there's no need to + * call this function. + * + * Return value: (transfer none): the preferred colormap + * + * Since: 2.2 + * + * Deprecated: 2.22: Use gdk_screen_get_system_colormap() + **/ +GdkColormap * +gdk_screen_get_rgb_colormap (GdkScreen *screen) +{ + GdkColormap *cmap; + g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL); + cmap = g_object_get_data (G_OBJECT (screen), "rgb-colormap"); + if (!cmap) + { + GdkRgbInfo *image_info = gdk_rgb_create_info (gdk_rgb_choose_visual (screen), NULL); + cmap = image_info->cmap; + g_object_set_data (G_OBJECT (screen), "rgb-colormap", cmap); + } + + return cmap; +} + +/** + * gdk_screen_get_rgb_visual: + * @screen: a #GdkScreen + * + * Gets a "preferred visual" chosen by GdkRGB for rendering image data + * on @screen. In previous versions of + * GDK, this was the only visual GdkRGB could use for rendering. In + * current versions, it's simply the visual GdkRGB would have chosen as + * the optimal one in those previous versions. GdkRGB can now render to + * drawables with any visual. + * + * Return value: (transfer none): The #GdkVisual chosen by GdkRGB. + * + * Since: 2.2 + * + * Deprecated: 2.22: Use gdk_screen_get_system_visual() + **/ +GdkVisual * +gdk_screen_get_rgb_visual (GdkScreen *screen) +{ + g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL); + return gdk_colormap_get_visual (gdk_screen_get_rgb_colormap (screen)); +} + +/** + * gdk_rgb_get_visual: + * + * Gets a "preferred visual" chosen by GdkRGB for rendering image data + * on the default screen. In previous versions of GDK, this was the + * only visual GdkRGB could use for rendering. In current versions, + * it's simply the visual GdkRGB would have chosen as the optimal one + * in those previous versions. GdkRGB can now render to drawables with + * any visual. + * + * Return value: (transfer none): The #GdkVisual chosen by GdkRGB. + * + * Deprecated: 2.22: Use gdk_visual_get_system_visual (gdk_screen_get_default ()) instead. + **/ +GdkVisual * +gdk_rgb_get_visual (void) +{ + return gdk_screen_get_rgb_visual (gdk_screen_get_default ()); +} + +#define __GDK_RGB_C__ +#include "gdkaliasdef.c" diff --git a/libs/tk/ydk/gdkscreen.c b/libs/tk/ydk/gdkscreen.c new file mode 100644 index 0000000000..4a6e11b657 --- /dev/null +++ b/libs/tk/ydk/gdkscreen.c @@ -0,0 +1,545 @@ +/* + * gdkscreen.c + * + * Copyright 2001 Sun Microsystems Inc. + * + * Erwann Chenede + * + * 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 "gdk.h" /* For gdk_rectangle_intersect() */ +#include "gdkcolor.h" +#include "gdkwindow.h" +#include "gdkscreen.h" +#include "gdkintl.h" +#include "gdkalias.h" + +static void gdk_screen_dispose (GObject *object); +static void gdk_screen_finalize (GObject *object); +static void gdk_screen_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static void gdk_screen_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); + +enum +{ + PROP_0, + PROP_FONT_OPTIONS, + PROP_RESOLUTION +}; + +enum +{ + SIZE_CHANGED, + COMPOSITED_CHANGED, + MONITORS_CHANGED, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +G_DEFINE_TYPE (GdkScreen, gdk_screen, G_TYPE_OBJECT) + +static void +gdk_screen_class_init (GdkScreenClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->dispose = gdk_screen_dispose; + object_class->finalize = gdk_screen_finalize; + object_class->set_property = gdk_screen_set_property; + object_class->get_property = gdk_screen_get_property; + + g_object_class_install_property (object_class, + PROP_FONT_OPTIONS, + g_param_spec_pointer ("font-options", + P_("Font options"), + P_("The default font options for the screen"), + G_PARAM_READWRITE|G_PARAM_STATIC_NAME| + G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB)); + + g_object_class_install_property (object_class, + PROP_RESOLUTION, + g_param_spec_double ("resolution", + P_("Font resolution"), + P_("The resolution for fonts on the screen"), + -G_MAXDOUBLE, + G_MAXDOUBLE, + -1.0, + G_PARAM_READWRITE|G_PARAM_STATIC_NAME| + G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB)); + + /** + * GdkScreen::size-changed: + * @screen: the object on which the signal is emitted + * + * The ::size-changed signal is emitted when the pixel width or + * height of a screen changes. + * + * Since: 2.2 + */ + signals[SIZE_CHANGED] = + g_signal_new (g_intern_static_string ("size-changed"), + G_OBJECT_CLASS_TYPE (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GdkScreenClass, size_changed), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); + + /** + * GdkScreen::composited-changed: + * @screen: the object on which the signal is emitted + * + * The ::composited-changed signal is emitted when the composited + * status of the screen changes + * + * Since: 2.10 + */ + signals[COMPOSITED_CHANGED] = + g_signal_new (g_intern_static_string ("composited-changed"), + G_OBJECT_CLASS_TYPE (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GdkScreenClass, composited_changed), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); + + /** + * GdkScreen::monitors-changed: + * @screen: the object on which the signal is emitted + * + * The ::monitors-changed signal is emitted when the number, size + * or position of the monitors attached to the screen change. + * + * Only for X11 and OS X for now. A future implementation for Win32 + * may be a possibility. + * + * Since: 2.14 + */ + signals[MONITORS_CHANGED] = + g_signal_new (g_intern_static_string ("monitors-changed"), + G_OBJECT_CLASS_TYPE (klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GdkScreenClass, monitors_changed), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); +} + +static void +gdk_screen_init (GdkScreen *screen) +{ + screen->resolution = -1.; +} + +static void +gdk_screen_dispose (GObject *object) +{ + GdkScreen *screen = GDK_SCREEN (object); + gint i; + + for (i = 0; i < 32; ++i) + { + if (screen->exposure_gcs[i]) + { + g_object_unref (screen->exposure_gcs[i]); + screen->exposure_gcs[i] = NULL; + } + + if (screen->normal_gcs[i]) + { + g_object_unref (screen->normal_gcs[i]); + screen->normal_gcs[i] = NULL; + } + } + + G_OBJECT_CLASS (gdk_screen_parent_class)->dispose (object); +} + +static void +gdk_screen_finalize (GObject *object) +{ + GdkScreen *screen = GDK_SCREEN (object); + + if (screen->font_options) + cairo_font_options_destroy (screen->font_options); + + G_OBJECT_CLASS (gdk_screen_parent_class)->finalize (object); +} + +void +_gdk_screen_close (GdkScreen *screen) +{ + g_return_if_fail (GDK_IS_SCREEN (screen)); + + if (!screen->closed) + { + screen->closed = TRUE; + g_object_run_dispose (G_OBJECT (screen)); + } +} + +/* Fallback used when the monitor "at" a point or window + * doesn't exist. + */ +static gint +get_nearest_monitor (GdkScreen *screen, + gint x, + gint y) +{ + gint num_monitors, i; + gint nearest_dist = G_MAXINT; + gint nearest_monitor = 0; + + g_return_val_if_fail (GDK_IS_SCREEN (screen), -1); + + num_monitors = gdk_screen_get_n_monitors (screen); + + for (i = 0; i < num_monitors; i++) + { + GdkRectangle monitor; + gint dist_x, dist_y, dist; + + gdk_screen_get_monitor_geometry (screen, i, &monitor); + + if (x < monitor.x) + dist_x = monitor.x - x; + else if (x >= monitor.x + monitor.width) + dist_x = x - (monitor.x + monitor.width) + 1; + else + dist_x = 0; + + if (y < monitor.y) + dist_y = monitor.y - y; + else if (y >= monitor.y + monitor.height) + dist_y = y - (monitor.y + monitor.height) + 1; + else + dist_y = 0; + + dist = dist_x + dist_y; + if (dist < nearest_dist) + { + nearest_dist = dist; + nearest_monitor = i; + } + } + + return nearest_monitor; +} + +/** + * gdk_screen_get_monitor_at_point: + * @screen: a #GdkScreen. + * @x: the x coordinate in the virtual screen. + * @y: the y coordinate in the virtual screen. + * + * Returns the monitor number in which the point (@x,@y) is located. + * + * Returns: the monitor number in which the point (@x,@y) lies, or + * a monitor close to (@x,@y) if the point is not in any monitor. + * + * Since: 2.2 + **/ +gint +gdk_screen_get_monitor_at_point (GdkScreen *screen, + gint x, + gint y) +{ + gint num_monitors, i; + + g_return_val_if_fail (GDK_IS_SCREEN (screen), -1); + + num_monitors = gdk_screen_get_n_monitors (screen); + + for (i=0;i= monitor.x && + x < monitor.x + monitor.width && + y >= monitor.y && + y < (monitor.y + monitor.height)) + return i; + } + + return get_nearest_monitor (screen, x, y); +} + +/** + * gdk_screen_get_monitor_at_window: + * @screen: a #GdkScreen. + * @window: a #GdkWindow + * @returns: the monitor number in which most of @window is located, + * or if @window does not intersect any monitors, a monitor, + * close to @window. + * + * Returns the number of the monitor in which the largest area of the + * bounding rectangle of @window resides. + * + * Since: 2.2 + **/ +gint +gdk_screen_get_monitor_at_window (GdkScreen *screen, + GdkWindow *window) +{ + gint num_monitors, i, area = 0, screen_num = -1; + GdkRectangle win_rect; + + g_return_val_if_fail (GDK_IS_SCREEN (screen), -1); + + gdk_window_get_geometry (window, &win_rect.x, &win_rect.y, &win_rect.width, + &win_rect.height, NULL); + gdk_window_get_origin (window, &win_rect.x, &win_rect.y); + num_monitors = gdk_screen_get_n_monitors (screen); + + for (i=0;i area) + { + area = intersect.width * intersect.height; + screen_num = i; + } + } + if (screen_num >= 0) + return screen_num; + else + return get_nearest_monitor (screen, + win_rect.x + win_rect.width / 2, + win_rect.y + win_rect.height / 2); +} + +/** + * gdk_screen_width: + * + * Returns the width of the default screen in pixels. + * + * Return value: the width of the default screen in pixels. + **/ +gint +gdk_screen_width (void) +{ + return gdk_screen_get_width (gdk_screen_get_default ()); +} + +/** + * gdk_screen_height: + * + * Returns the height of the default screen in pixels. + * + * Return value: the height of the default screen in pixels. + **/ +gint +gdk_screen_height (void) +{ + return gdk_screen_get_height (gdk_screen_get_default ()); +} + +/** + * gdk_screen_width_mm: + * + * Returns the width of the default screen in millimeters. + * Note that on many X servers this value will not be correct. + * + * Return value: the width of the default screen in millimeters, + * though it is not always correct. + **/ +gint +gdk_screen_width_mm (void) +{ + return gdk_screen_get_width_mm (gdk_screen_get_default ()); +} + +/** + * gdk_screen_height_mm: + * + * Returns the height of the default screen in millimeters. + * Note that on many X servers this value will not be correct. + * + * Return value: the height of the default screen in millimeters, + * though it is not always correct. + **/ +gint +gdk_screen_height_mm (void) +{ + return gdk_screen_get_height_mm (gdk_screen_get_default ()); +} + +/** + * gdk_screen_set_font_options: + * @screen: a #GdkScreen + * @options: (allow-none): a #cairo_font_options_t, or %NULL to unset any + * previously set default font options. + * + * Sets the default font options for the screen. These + * options will be set on any #PangoContext's newly created + * with gdk_pango_context_get_for_screen(). Changing the + * default set of font options does not affect contexts that + * have already been created. + * + * Since: 2.10 + **/ +void +gdk_screen_set_font_options (GdkScreen *screen, + const cairo_font_options_t *options) +{ + g_return_if_fail (GDK_IS_SCREEN (screen)); + + if (screen->font_options != options) + { + if (screen->font_options) + cairo_font_options_destroy (screen->font_options); + + if (options) + screen->font_options = cairo_font_options_copy (options); + else + screen->font_options = NULL; + + g_object_notify (G_OBJECT (screen), "font-options"); + } +} + +/** + * gdk_screen_get_font_options: + * @screen: a #GdkScreen + * + * Gets any options previously set with gdk_screen_set_font_options(). + * + * Return value: the current font options, or %NULL if no default + * font options have been set. + * + * Since: 2.10 + **/ +const cairo_font_options_t * +gdk_screen_get_font_options (GdkScreen *screen) +{ + g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL); + + return screen->font_options; +} + +/** + * gdk_screen_set_resolution: + * @screen: a #GdkScreen + * @dpi: the resolution in "dots per inch". (Physical inches aren't actually + * involved; the terminology is conventional.) + + * Sets the resolution for font handling on the screen. This is a + * scale factor between points specified in a #PangoFontDescription + * and cairo units. The default value is 96, meaning that a 10 point + * font will be 13 units high. (10 * 96. / 72. = 13.3). + * + * Since: 2.10 + **/ +void +gdk_screen_set_resolution (GdkScreen *screen, + gdouble dpi) +{ + g_return_if_fail (GDK_IS_SCREEN (screen)); + + if (dpi < 0) + dpi = -1.0; + + if (screen->resolution != dpi) + { + screen->resolution = dpi; + + g_object_notify (G_OBJECT (screen), "resolution"); + } +} + +/** + * gdk_screen_get_resolution: + * @screen: a #GdkScreen + * + * Gets the resolution for font handling on the screen; see + * gdk_screen_set_resolution() for full details. + * + * Return value: the current resolution, or -1 if no resolution + * has been set. + * + * Since: 2.10 + **/ +gdouble +gdk_screen_get_resolution (GdkScreen *screen) +{ + g_return_val_if_fail (GDK_IS_SCREEN (screen), -1.0); + + return screen->resolution; +} + +static void +gdk_screen_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GdkScreen *screen = GDK_SCREEN (object); + + switch (prop_id) + { + case PROP_FONT_OPTIONS: + g_value_set_pointer (value, (gpointer) gdk_screen_get_font_options (screen)); + break; + case PROP_RESOLUTION: + g_value_set_double (value, gdk_screen_get_resolution (screen)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gdk_screen_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GdkScreen *screen = GDK_SCREEN (object); + + switch (prop_id) + { + case PROP_FONT_OPTIONS: + gdk_screen_set_font_options (screen, g_value_get_pointer (value)); + break; + case PROP_RESOLUTION: + gdk_screen_set_resolution (screen, g_value_get_double (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +#define __GDK_SCREEN_C__ +#include "gdkaliasdef.c" diff --git a/libs/tk/ydk/gdkselection.c b/libs/tk/ydk/gdkselection.c new file mode 100644 index 0000000000..fd8f705811 --- /dev/null +++ b/libs/tk/ydk/gdkselection.c @@ -0,0 +1,139 @@ +/* GDK - The GIMP Drawing Kit + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, 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 "config.h" +#include "gdkproperty.h" +#include "gdkdisplay.h" +#include "gdkselection.h" +#include "gdkalias.h" + +gboolean +gdk_selection_owner_set (GdkWindow *owner, + GdkAtom selection, + guint32 time, + gboolean send_event) +{ + return gdk_selection_owner_set_for_display (gdk_display_get_default (), + owner, selection, + time, send_event); +} + +GdkWindow* +gdk_selection_owner_get (GdkAtom selection) +{ + return gdk_selection_owner_get_for_display (gdk_display_get_default (), + selection); +} + +void +gdk_selection_send_notify (GdkNativeWindow requestor, + GdkAtom selection, + GdkAtom target, + GdkAtom property, + guint32 time) +{ + gdk_selection_send_notify_for_display (gdk_display_get_default (), + requestor, selection, + target, property, time); +} + +gint +gdk_text_property_to_text_list (GdkAtom encoding, + gint format, + const guchar *text, + gint length, + gchar ***list) +{ + return gdk_text_property_to_text_list_for_display (gdk_display_get_default (), + encoding, format, text, length, list); +} + +/** + * gdk_text_property_to_utf8_list: + * @encoding: an atom representing the encoding of the text + * @format: the format of the property + * @text: the text to convert + * @length: the length of @text, in bytes + * @list: (allow-none): location to store the list of strings or %NULL. The + * list should be freed with g_strfreev(). + * + * Convert a text property in the giving encoding to + * a list of UTF-8 strings. + * + * Return value: the number of strings in the resulting + * list. + **/ +gint +gdk_text_property_to_utf8_list (GdkAtom encoding, + gint format, + const guchar *text, + gint length, + gchar ***list) +{ + return gdk_text_property_to_utf8_list_for_display (gdk_display_get_default (), + encoding, format, text, length, list); +} + +gint +gdk_string_to_compound_text (const gchar *str, + GdkAtom *encoding, + gint *format, + guchar **ctext, + gint *length) +{ + return gdk_string_to_compound_text_for_display (gdk_display_get_default (), + str, encoding, format, + ctext, length); +} + +/** + * gdk_utf8_to_compound_text: + * @str: a UTF-8 string + * @encoding: location to store resulting encoding + * @format: location to store format of the result + * @ctext: location to store the data of the result + * @length: location to store the length of the data + * stored in @ctext + * + * Convert from UTF-8 to compound text. + * + * Return value: %TRUE if the conversion succeeded, otherwise + * false. + **/ +gboolean +gdk_utf8_to_compound_text (const gchar *str, + GdkAtom *encoding, + gint *format, + guchar **ctext, + gint *length) +{ + return gdk_utf8_to_compound_text_for_display (gdk_display_get_default (), + str, encoding, format, + ctext, length); +} + +#define __GDK_SELECTION_C__ +#include "gdkaliasdef.c" diff --git a/libs/tk/ydk/gdkvisual.c b/libs/tk/ydk/gdkvisual.c new file mode 100644 index 0000000000..0131f41021 --- /dev/null +++ b/libs/tk/ydk/gdkvisual.c @@ -0,0 +1,254 @@ +/* GDK - The GIMP Drawing Kit + * gdkvisual.c + * + * Copyright 2001 Sun Microsystems Inc. + * + * Erwann Chenede + * + * 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 "gdkvisual.h" +#include "gdkscreen.h" +#include "gdkalias.h" + +/** + * gdk_list_visuals: + * + * Lists the available visuals for the default screen. + * (See gdk_screen_list_visuals()) + * A visual describes a hardware image data format. + * For example, a visual might support 24-bit color, or 8-bit color, + * and might expect pixels to be in a certain format. + * + * Call g_list_free() on the return value when you're finished with it. + * + * Return value: (transfer container) (element-type GdkVisual): + * a list of visuals; the list must be freed, but not its contents + **/ +GList* +gdk_list_visuals (void) +{ + return gdk_screen_list_visuals (gdk_screen_get_default ()); +} + +/** + * gdk_visual_get_system: + * + * Get the system's default visual for the default GDK screen. + * This is the visual for the root window of the display. + * The return value should not be freed. + * + * Return value: (transfer none): system visual + **/ +GdkVisual* +gdk_visual_get_system (void) +{ + return gdk_screen_get_system_visual (gdk_screen_get_default()); +} + +/** + * gdk_visual_get_visual_type: + * @visual: A #GdkVisual. + * + * Returns the type of visual this is (PseudoColor, TrueColor, etc). + * + * Return value: A #GdkVisualType stating the type of @visual. + * + * Since: 2.22 + */ +GdkVisualType +gdk_visual_get_visual_type (GdkVisual *visual) +{ + g_return_val_if_fail (GDK_IS_VISUAL (visual), 0); + + return visual->type; +} + +/** + * gdk_visual_get_depth: + * @visual: A #GdkVisual. + * + * Returns the bit depth of this visual. + * + * Return value: The bit depth of this visual. + * + * Since: 2.22 + */ +gint +gdk_visual_get_depth (GdkVisual *visual) +{ + g_return_val_if_fail (GDK_IS_VISUAL (visual), 0); + + return visual->depth; +} + +/** + * gdk_visual_get_byte_order: + * @visual: A #GdkVisual. + * + * Returns the byte order of this visual. + * + * Return value: A #GdkByteOrder stating the byte order of @visual. + * + * Since: 2.22 + */ +GdkByteOrder +gdk_visual_get_byte_order (GdkVisual *visual) +{ + g_return_val_if_fail (GDK_IS_VISUAL (visual), 0); + + return visual->byte_order; +} + +/** + * gdk_visual_get_colormap_size: + * @visual: A #GdkVisual. + * + * Returns the size of a colormap for this visual. + * + * Return value: The size of a colormap that is suitable for @visual. + * + * Since: 2.22 + */ +gint +gdk_visual_get_colormap_size (GdkVisual *visual) +{ + g_return_val_if_fail (GDK_IS_VISUAL (visual), 0); + + return visual->colormap_size; +} + +/** + * gdk_visual_get_bits_per_rgb: + * @visual: a #GdkVisual + * + * Returns the number of significant bits per red, green and blue value. + * + * Return value: The number of significant bits per color value for @visual. + * + * Since: 2.22 + */ +gint +gdk_visual_get_bits_per_rgb (GdkVisual *visual) +{ + g_return_val_if_fail (GDK_IS_VISUAL (visual), 0); + + return visual->bits_per_rgb; +} + +/** + * gdk_visual_get_red_pixel_details: + * @visual: A #GdkVisual. + * @mask: (out) (allow-none): A pointer to a #guint32 to be filled in, or %NULL. + * @shift: (out) (allow-none): A pointer to a #gint to be filled in, or %NULL. + * @precision: (out) (allow-none): A pointer to a #gint to be filled in, or %NULL. + * + * Obtains values that are needed to calculate red pixel values in TrueColor + * and DirectColor. The "mask" is the significant bits within the pixel. + * The "shift" is the number of bits left we must shift a primary for it + * to be in position (according to the "mask"). Finally, "precision" refers + * to how much precision the pixel value contains for a particular primary. + * + * Since: 2.22 + */ +void +gdk_visual_get_red_pixel_details (GdkVisual *visual, + guint32 *mask, + gint *shift, + gint *precision) +{ + g_return_if_fail (GDK_IS_VISUAL (visual)); + + if (mask) + *mask = visual->red_mask; + + if (shift) + *shift = visual->red_shift; + + if (precision) + *precision = visual->red_prec; +} + +/** + * gdk_visual_get_green_pixel_details: + * @visual: a #GdkVisual + * @mask: (out) (allow-none): A pointer to a #guint32 to be filled in, or %NULL. + * @shift: (out) (allow-none): A pointer to a #gint to be filled in, or %NULL. + * @precision: (out) (allow-none): A pointer to a #gint to be filled in, or %NULL. + * + * Obtains values that are needed to calculate green pixel values in TrueColor + * and DirectColor. The "mask" is the significant bits within the pixel. + * The "shift" is the number of bits left we must shift a primary for it + * to be in position (according to the "mask"). Finally, "precision" refers + * to how much precision the pixel value contains for a particular primary. + * + * Since: 2.22 + */ +void +gdk_visual_get_green_pixel_details (GdkVisual *visual, + guint32 *mask, + gint *shift, + gint *precision) +{ + g_return_if_fail (GDK_IS_VISUAL (visual)); + + if (mask) + *mask = visual->green_mask; + + if (shift) + *shift = visual->green_shift; + + if (precision) + *precision = visual->green_prec; +} + +/** + * gdk_visual_get_blue_pixel_details: + * @visual: a #GdkVisual + * @mask: (out) (allow-none): A pointer to a #guint32 to be filled in, or %NULL. + * @shift: (out) (allow-none): A pointer to a #gint to be filled in, or %NULL. + * @precision: (out) (allow-none): A pointer to a #gint to be filled in, or %NULL. + * + * Obtains values that are needed to calculate blue pixel values in TrueColor + * and DirectColor. The "mask" is the significant bits within the pixel. + * The "shift" is the number of bits left we must shift a primary for it + * to be in position (according to the "mask"). Finally, "precision" refers + * to how much precision the pixel value contains for a particular primary. + * + * Since: 2.22 + */ +void +gdk_visual_get_blue_pixel_details (GdkVisual *visual, + guint32 *mask, + gint *shift, + gint *precision) +{ + g_return_if_fail (GDK_IS_VISUAL (visual)); + + if (mask) + *mask = visual->blue_mask; + + if (shift) + *shift = visual->blue_shift; + + if (precision) + *precision = visual->blue_prec; +} + +#define __GDK_VISUAL_C__ +#include "gdkaliasdef.c" diff --git a/libs/tk/ydk/gdkwindow.c b/libs/tk/ydk/gdkwindow.c new file mode 100644 index 0000000000..4fd12edaa0 --- /dev/null +++ b/libs/tk/ydk/gdkwindow.c @@ -0,0 +1,11413 @@ +/* GDK - The GIMP Drawing Kit + * Copyright (C) 1995-2007 Peter Mattis, Spencer Kimball, + * Josh MacDonald, Ryan Lortie + * + * 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. + */ + +/* + * 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 "config.h" +#include "gdkwindow.h" +#include "gdkwindowimpl.h" +#include "gdkinternals.h" +#include "gdk.h" /* For gdk_rectangle_union() */ +#include "gdkpixmap.h" +#include "gdkdrawable.h" +#include "gdkintl.h" +#include "gdkscreen.h" +#include "gdkmarshalers.h" +#include "gdkalias.h" + +#undef DEBUG_WINDOW_PRINTING + +#ifdef GDK_WINDOWING_X11 +#include "gdkx.h" /* For workaround */ +#endif + +#include "math.h" + +/* Historically a GdkWindow always matches a platform native window, + * be it a toplevel window or a child window. In this setup the + * GdkWindow (and other GdkDrawables) were platform independent classes, + * and the actual platform specific implementation was in a delegate + * object availible as "impl" in the window object. + * + * With the addition of client side windows and offscreen windows this + * changes a bit. The application-visible GdkWindow object behaves as + * it did before, but not all such windows now have a corresponding native + * window. Instead windows that are "client side" are emulated by the gdk + * code such that clipping, drawing, moving, events etc work as expected. + * + * For GdkWindows that have a native window the "impl" object is the + * same as before. However, for all client side windows the impl object + * is shared with its parent (i.e. all client windows descendants of one + * native window has the same impl. + * + * Additionally there is a new type of platform independent impl object, + * GdkOffscreenWindow. All windows of type GDK_WINDOW_OFFSCREEN get an impl + * of this type (while their children are generally GDK_WINDOW_CHILD virtual + * windows). Such windows work by allocating a GdkPixmap as the backing store + * for drawing operations, which is resized with the window. + * + * GdkWindows have a pointer to the "impl window" they are in, i.e. + * the topmost GdkWindow which have the same "impl" value. This is stored + * in impl_window, which is different from the window itself only for client + * side windows. + * All GdkWindows (native or not) track the position of the window in the parent + * (x, y), the size of the window (width, height), the position of the window + * with respect to the impl window (abs_x, abs_y). We also track the clip + * region of the window wrt parent windows and siblings, in window-relative + * coordinates with and without child windows included (clip_region, + * clip_region_with_children). + * + * All toplevel windows are native windows, but also child windows can be + * native (although not children of offscreens). We always listen to + * a basic set of events (see get_native_event_mask) for these windows + * so that we can emulate events for any client side children. + * + * For native windows we apply the calculated clip region as a window shape + * so that eg. client side siblings that overlap the native child properly + * draws over the native child window. + * + * In order to minimize flicker and for performance we use a couple of cacheing + * tricks. First of all, every time we do a window to window copy area, for instance + * when moving a client side window or when scrolling/moving a region in a window + * we store this in outstanding_moves instead of applying immediately. We then + * delay this move until we really need it (because something depends on being + * able to read it), or until we're handing a redraw from an expose/invalidation + * (actually we delay it past redraw, but before blitting the double buffer pixmap + * to the window). This gives us two advantages. First of all it minimizes the time + * from the window is moved to the exposes related to that move, secondly it allows + * us to be smart about how to do the copy. We combine multiple moves into one (when + * possible) and we don't actually do copies to anything that is or will be + * invalidated and exposed anyway. + * + * Secondly, we use something called a "implicit paint" during repaint handling. + * An implicit paint is similar to a regular paint for the paint stack, but it is + * not put on the stack. Instead, it is set on the impl window, and later when + * regular gdk_window_begin_paint_region() happen on a window of this impl window + * we reuse the pixmap from the implicit paint. During repaint we create and at the + * end flush an implicit paint, which means we can collect all the paints on + * multiple client side windows in the same backing store pixmap. + * + * All drawing to windows are wrapped with macros that set up the GC such that + * the offsets and clip region is right for drawing to the paint object or + * directly to the emulated window. It also automatically handles any flushing + * needed when drawing directly to a window. Adding window/paint clipping is + * done using _gdk_gc_add_drawable_clip which lets us efficiently add and then + * remove a custom clip region. + */ + +#ifndef __APPLE__ +#define USE_BACKING_STORE /* Appears to work on Win32, too, now. */ +#endif + +/* This adds a local value to the GdkVisibilityState enum */ +#define GDK_VISIBILITY_NOT_VIEWABLE 3 + +enum { + PICK_EMBEDDED_CHILD, /* only called if children are embedded */ + TO_EMBEDDER, + FROM_EMBEDDER, + LAST_SIGNAL +}; + +enum { + PROP_0, + PROP_CURSOR +}; + +typedef enum { + CLEAR_BG_NONE, + CLEAR_BG_WINCLEARED, /* Clear backgrounds except those that the window system clears */ + CLEAR_BG_ALL +} ClearBg; + +struct _GdkWindowPaint +{ + GdkRegion *region; + GdkPixmap *pixmap; + gint x_offset; + gint y_offset; + cairo_surface_t *surface; + guint uses_implicit : 1; + guint flushed : 1; + guint32 region_tag; +}; + +typedef struct { + GdkRegion *dest_region; /* The destination region */ + int dx, dy; /* The amount that the source was moved to reach dest_region */ +} GdkWindowRegionMove; + + +/* Global info */ + +static GdkGC *gdk_window_create_gc (GdkDrawable *drawable, + GdkGCValues *values, + GdkGCValuesMask mask); +static void gdk_window_draw_rectangle (GdkDrawable *drawable, + GdkGC *gc, + gboolean filled, + gint x, + gint y, + gint width, + gint height); +static void gdk_window_draw_arc (GdkDrawable *drawable, + GdkGC *gc, + gboolean filled, + gint x, + gint y, + gint width, + gint height, + gint angle1, + gint angle2); +static void gdk_window_draw_polygon (GdkDrawable *drawable, + GdkGC *gc, + gboolean filled, + GdkPoint *points, + gint npoints); +static void gdk_window_draw_text (GdkDrawable *drawable, + GdkFont *font, + GdkGC *gc, + gint x, + gint y, + const gchar *text, + gint text_length); +static void gdk_window_draw_text_wc (GdkDrawable *drawable, + GdkFont *font, + GdkGC *gc, + gint x, + gint y, + const GdkWChar *text, + gint text_length); +static void gdk_window_draw_drawable (GdkDrawable *drawable, + GdkGC *gc, + GdkPixmap *src, + gint xsrc, + gint ysrc, + gint xdest, + gint ydest, + gint width, + gint height, + GdkDrawable *original_src); +static void gdk_window_draw_points (GdkDrawable *drawable, + GdkGC *gc, + GdkPoint *points, + gint npoints); +static void gdk_window_draw_segments (GdkDrawable *drawable, + GdkGC *gc, + GdkSegment *segs, + gint nsegs); +static void gdk_window_draw_lines (GdkDrawable *drawable, + GdkGC *gc, + GdkPoint *points, + gint npoints); + +static void gdk_window_draw_glyphs (GdkDrawable *drawable, + GdkGC *gc, + PangoFont *font, + gint x, + gint y, + PangoGlyphString *glyphs); +static void gdk_window_draw_glyphs_transformed (GdkDrawable *drawable, + GdkGC *gc, + PangoMatrix *matrix, + PangoFont *font, + gint x, + gint y, + PangoGlyphString *glyphs); + +static void gdk_window_draw_image (GdkDrawable *drawable, + GdkGC *gc, + GdkImage *image, + gint xsrc, + gint ysrc, + gint xdest, + gint ydest, + gint width, + gint height); + +static void gdk_window_draw_pixbuf (GdkDrawable *drawable, + GdkGC *gc, + GdkPixbuf *pixbuf, + gint src_x, + gint src_y, + gint dest_x, + gint dest_y, + gint width, + gint height, + GdkRgbDither dither, + gint x_dither, + gint y_dither); + +static void gdk_window_draw_trapezoids (GdkDrawable *drawable, + GdkGC *gc, + GdkTrapezoid *trapezoids, + gint n_trapezoids); + +static GdkImage* gdk_window_copy_to_image (GdkDrawable *drawable, + GdkImage *image, + gint src_x, + gint src_y, + gint dest_x, + gint dest_y, + gint width, + gint height); + +static cairo_surface_t *gdk_window_ref_cairo_surface (GdkDrawable *drawable); +static cairo_surface_t *gdk_window_create_cairo_surface (GdkDrawable *drawable, + int width, + int height); +static void gdk_window_drop_cairo_surface (GdkWindowObject *private); +static void gdk_window_set_cairo_clip (GdkDrawable *drawable, + cairo_t *cr); + +static void gdk_window_real_get_size (GdkDrawable *drawable, + gint *width, + gint *height); + +static GdkVisual* gdk_window_real_get_visual (GdkDrawable *drawable); +static gint gdk_window_real_get_depth (GdkDrawable *drawable); +static GdkScreen* gdk_window_real_get_screen (GdkDrawable *drawable); +static void gdk_window_real_set_colormap (GdkDrawable *drawable, + GdkColormap *cmap); +static GdkColormap* gdk_window_real_get_colormap (GdkDrawable *drawable); + +static GdkDrawable* gdk_window_get_source_drawable (GdkDrawable *drawable); +static GdkDrawable* gdk_window_get_composite_drawable (GdkDrawable *drawable, + gint x, + gint y, + gint width, + gint height, + gint *composite_x_offset, + gint *composite_y_offset); +static GdkRegion* gdk_window_get_clip_region (GdkDrawable *drawable); +static GdkRegion* gdk_window_get_visible_region (GdkDrawable *drawable); + +static void gdk_window_free_paint_stack (GdkWindow *window); + +static void gdk_window_init (GdkWindowObject *window); +static void gdk_window_class_init (GdkWindowObjectClass *klass); +static void gdk_window_finalize (GObject *object); + +static void gdk_window_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static void gdk_window_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); + +static void gdk_window_clear_backing_region (GdkWindow *window, + GdkRegion *region); +static void gdk_window_redirect_free (GdkWindowRedirect *redirect); +static void apply_redirect_to_children (GdkWindowObject *private, + GdkWindowRedirect *redirect); +static void remove_redirect_from_children (GdkWindowObject *private, + GdkWindowRedirect *redirect); + +static void recompute_visible_regions (GdkWindowObject *private, + gboolean recalculate_siblings, + gboolean recalculate_children); +static void gdk_window_flush_outstanding_moves (GdkWindow *window); +static void gdk_window_flush_recursive (GdkWindowObject *window); +static void do_move_region_bits_on_impl (GdkWindowObject *private, + GdkRegion *region, /* In impl window coords */ + int dx, int dy); +static void gdk_window_invalidate_in_parent (GdkWindowObject *private); +static void move_native_children (GdkWindowObject *private); +static void update_cursor (GdkDisplay *display); +static void impl_window_add_update_area (GdkWindowObject *impl_window, + GdkRegion *region); +static void gdk_window_region_move_free (GdkWindowRegionMove *move); +static void gdk_window_invalidate_region_full (GdkWindow *window, + const GdkRegion *region, + gboolean invalidate_children, + ClearBg clear_bg); +static void gdk_window_invalidate_rect_full (GdkWindow *window, + const GdkRectangle *rect, + gboolean invalidate_children, + ClearBg clear_bg); + +static guint signals[LAST_SIGNAL] = { 0 }; + +static gpointer parent_class = NULL; + +static const cairo_user_data_key_t gdk_window_cairo_key; + +static guint32 +new_region_tag (void) +{ + static guint32 tag = 0; + + return ++tag; +} + +GType +gdk_window_object_get_type (void) +{ + static GType object_type = 0; + + if (!object_type) + object_type = g_type_register_static_simple (GDK_TYPE_DRAWABLE, + "GdkWindow", + sizeof (GdkWindowObjectClass), + (GClassInitFunc) gdk_window_class_init, + sizeof (GdkWindowObject), + (GInstanceInitFunc) gdk_window_init, + 0); + + return object_type; +} + +GType +_gdk_paintable_get_type (void) +{ + static GType paintable_type = 0; + + if (!paintable_type) + { + const GTypeInfo paintable_info = + { + sizeof (GdkPaintableIface), /* class_size */ + NULL, /* base_init */ + NULL, /* base_finalize */ + }; + + paintable_type = g_type_register_static (G_TYPE_INTERFACE, + g_intern_static_string ("GdkPaintable"), + &paintable_info, 0); + + g_type_interface_add_prerequisite (paintable_type, G_TYPE_OBJECT); + } + + return paintable_type; +} + +static void +gdk_window_init (GdkWindowObject *window) +{ + /* 0-initialization is good for all other fields. */ + + window->window_type = GDK_WINDOW_CHILD; + + window->state = GDK_WINDOW_STATE_WITHDRAWN; + window->width = 1; + window->height = 1; + window->toplevel_window_type = -1; + /* starts hidden */ + window->effective_visibility = GDK_VISIBILITY_NOT_VIEWABLE; + window->visibility = GDK_VISIBILITY_FULLY_OBSCURED; + /* Default to unobscured since some backends don't send visibility events */ + window->native_visibility = GDK_VISIBILITY_UNOBSCURED; +} + +/* Stop and return on the first non-NULL parent */ +static gboolean +accumulate_get_window (GSignalInvocationHint *ihint, + GValue *return_accu, + const GValue *handler_return, + gpointer data) +{ + g_value_copy (handler_return, return_accu); + /* Continue while returning NULL */ + return g_value_get_object (handler_return) == NULL; +} + +static GQuark quark_pointer_window = 0; + +static void +gdk_window_class_init (GdkWindowObjectClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass); + + parent_class = g_type_class_peek_parent (klass); + + object_class->finalize = gdk_window_finalize; + object_class->set_property = gdk_window_set_property; + object_class->get_property = gdk_window_get_property; + + drawable_class->create_gc = gdk_window_create_gc; + drawable_class->draw_rectangle = gdk_window_draw_rectangle; + drawable_class->draw_arc = gdk_window_draw_arc; + drawable_class->draw_polygon = gdk_window_draw_polygon; + drawable_class->draw_text = gdk_window_draw_text; + drawable_class->draw_text_wc = gdk_window_draw_text_wc; + drawable_class->draw_drawable_with_src = gdk_window_draw_drawable; + drawable_class->draw_points = gdk_window_draw_points; + drawable_class->draw_segments = gdk_window_draw_segments; + drawable_class->draw_lines = gdk_window_draw_lines; + drawable_class->draw_glyphs = gdk_window_draw_glyphs; + drawable_class->draw_glyphs_transformed = gdk_window_draw_glyphs_transformed; + drawable_class->draw_image = gdk_window_draw_image; + drawable_class->draw_pixbuf = gdk_window_draw_pixbuf; + drawable_class->draw_trapezoids = gdk_window_draw_trapezoids; + drawable_class->get_depth = gdk_window_real_get_depth; + drawable_class->get_screen = gdk_window_real_get_screen; + drawable_class->get_size = gdk_window_real_get_size; + drawable_class->set_colormap = gdk_window_real_set_colormap; + drawable_class->get_colormap = gdk_window_real_get_colormap; + drawable_class->get_visual = gdk_window_real_get_visual; + drawable_class->_copy_to_image = gdk_window_copy_to_image; + drawable_class->ref_cairo_surface = gdk_window_ref_cairo_surface; + drawable_class->create_cairo_surface = gdk_window_create_cairo_surface; + drawable_class->set_cairo_clip = gdk_window_set_cairo_clip; + drawable_class->get_clip_region = gdk_window_get_clip_region; + drawable_class->get_visible_region = gdk_window_get_visible_region; + drawable_class->get_composite_drawable = gdk_window_get_composite_drawable; + drawable_class->get_source_drawable = gdk_window_get_source_drawable; + + quark_pointer_window = g_quark_from_static_string ("gtk-pointer-window"); + + + /* Properties */ + + /** + * GdkWindow:cursor: + * + * The mouse pointer for a #GdkWindow. See gdk_window_set_cursor() and + * gdk_window_get_cursor() for details. + * + * Since: 2.18 + */ + g_object_class_install_property (object_class, + PROP_CURSOR, + g_param_spec_boxed ("cursor", + P_("Cursor"), + P_("Cursor"), + GDK_TYPE_CURSOR, + G_PARAM_READWRITE)); + + /** + * GdkWindow::pick-embedded-child: + * @window: the window on which the signal is emitted + * @x: x coordinate in the window + * @y: y coordinate in the window + * + * The ::pick-embedded-child signal is emitted to find an embedded + * child at the given position. + * + * Returns: (transfer none): the #GdkWindow of the embedded child at + * @x, @y, or %NULL + * + * Since: 2.18 + */ + signals[PICK_EMBEDDED_CHILD] = + g_signal_new (g_intern_static_string ("pick-embedded-child"), + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + 0, + accumulate_get_window, NULL, + _gdk_marshal_OBJECT__DOUBLE_DOUBLE, + GDK_TYPE_WINDOW, + 2, + G_TYPE_DOUBLE, + G_TYPE_DOUBLE); + + /** + * GdkWindow::to-embedder: + * @window: the offscreen window on which the signal is emitted + * @offscreen-x: x coordinate in the offscreen window + * @offscreen-y: y coordinate in the offscreen window + * @embedder-x: (out) (type double): return location for the x + * coordinate in the embedder window + * @embedder-y: (out) (type double): return location for the y + * coordinate in the embedder window + * + * The ::to-embedder signal is emitted to translate coordinates + * in an offscreen window to its embedder. + * + * See also #GtkWindow::from-embedder. + * + * Since: 2.18 + */ + signals[TO_EMBEDDER] = + g_signal_new (g_intern_static_string ("to-embedder"), + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + _gdk_marshal_VOID__DOUBLE_DOUBLE_POINTER_POINTER, + G_TYPE_NONE, + 4, + G_TYPE_DOUBLE, + G_TYPE_DOUBLE, + G_TYPE_POINTER, + G_TYPE_POINTER); + + /** + * GdkWindow::from-embedder: + * @window: the offscreen window on which the signal is emitted + * @embedder-x: x coordinate in the embedder window + * @embedder-y: y coordinate in the embedder window + * @offscreen-x: (out) (type double): return location for the x + * coordinate in the offscreen window + * @offscreen-y: (out) (type double): return location for the y + * coordinate in the offscreen window + * + * The ::from-embedder signal is emitted to translate coordinates + * in the embedder of an offscreen window to the offscreen window. + * + * See also #GtkWindow::to-embedder. + * + * Since: 2.18 + */ + signals[FROM_EMBEDDER] = + g_signal_new (g_intern_static_string ("from-embedder"), + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + _gdk_marshal_VOID__DOUBLE_DOUBLE_POINTER_POINTER, + G_TYPE_NONE, + 4, + G_TYPE_DOUBLE, + G_TYPE_DOUBLE, + G_TYPE_POINTER, + G_TYPE_POINTER); +} + +static void +gdk_window_finalize (GObject *object) +{ + GdkWindow *window = GDK_WINDOW (object); + GdkWindowObject *obj = (GdkWindowObject *) object; + + if (!GDK_WINDOW_DESTROYED (window)) + { + if (GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN) + { + g_warning ("losing last reference to undestroyed window\n"); + _gdk_window_destroy (window, FALSE); + } + else + /* We use TRUE here, to keep us from actually calling + * XDestroyWindow() on the window + */ + _gdk_window_destroy (window, TRUE); + } + + if (obj->impl) + { + g_object_unref (obj->impl); + obj->impl = NULL; + } + + if (obj->impl_window != obj) + { + g_object_unref (obj->impl_window); + obj->impl_window = NULL; + } + + if (obj->shape) + gdk_region_destroy (obj->shape); + + if (obj->input_shape) + gdk_region_destroy (obj->input_shape); + + if (obj->cursor) + gdk_cursor_unref (obj->cursor); + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +gdk_window_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GdkWindow *window = (GdkWindow *)object; + + switch (prop_id) + { + case PROP_CURSOR: + gdk_window_set_cursor (window, g_value_get_boxed (value)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gdk_window_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GdkWindow *window = (GdkWindow *) object; + + switch (prop_id) + { + case PROP_CURSOR: + g_value_set_boxed (value, gdk_window_get_cursor (window)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static gboolean +gdk_window_is_offscreen (GdkWindowObject *window) +{ + return window->window_type == GDK_WINDOW_OFFSCREEN; +} + +static GdkWindowObject * +gdk_window_get_impl_window (GdkWindowObject *window) +{ + return window->impl_window; +} + +GdkWindow * +_gdk_window_get_impl_window (GdkWindow *window) +{ + return (GdkWindow *)gdk_window_get_impl_window ((GdkWindowObject *)window); +} + +static gboolean +gdk_window_has_impl (GdkWindowObject *window) +{ + return window->impl_window == window; +} + +static gboolean +gdk_window_is_toplevel (GdkWindowObject *window) +{ + return + window->parent == NULL || + window->parent->window_type == GDK_WINDOW_ROOT; +} + +gboolean +_gdk_window_has_impl (GdkWindow *window) +{ + return gdk_window_has_impl ((GdkWindowObject *)window); +} + +static gboolean +gdk_window_has_no_impl (GdkWindowObject *window) +{ + return window->impl_window != window; +} + +static void +remove_child_area (GdkWindowObject *private, + GdkWindowObject *until, + gboolean for_input, + GdkRegion *region) +{ + GdkWindowObject *child; + GdkRegion *child_region; + GdkRectangle r; + GList *l; + GdkRegion *shape; + + for (l = private->children; l; l = l->next) + { + child = l->data; + + if (child == until) + break; + + /* If region is empty already, no need to do + anything potentially costly */ + if (gdk_region_empty (region)) + break; + + if (!GDK_WINDOW_IS_MAPPED (child) || child->input_only || child->composited) + continue; + + /* Ignore offscreen children, as they don't draw in their parent and + * don't take part in the clipping */ + if (gdk_window_is_offscreen (child)) + continue; + + r.x = child->x; + r.y = child->y; + r.width = child->width; + r.height = child->height; + + /* Bail early if child totally outside region */ + if (gdk_region_rect_in (region, &r) == GDK_OVERLAP_RECTANGLE_OUT) + continue; + + child_region = gdk_region_rectangle (&r); + + if (child->shape) + { + /* Adjust shape region to parent window coords */ + gdk_region_offset (child->shape, child->x, child->y); + gdk_region_intersect (child_region, child->shape); + gdk_region_offset (child->shape, -child->x, -child->y); + } + else if (private->window_type == GDK_WINDOW_FOREIGN) + { + shape = _gdk_windowing_window_get_shape ((GdkWindow *)child); + if (shape) + { + gdk_region_intersect (child_region, shape); + gdk_region_destroy (shape); + } + } + + if (for_input) + { + if (child->input_shape) + gdk_region_intersect (child_region, child->input_shape); + else if (private->window_type == GDK_WINDOW_FOREIGN) + { + shape = _gdk_windowing_window_get_input_shape ((GdkWindow *)child); + if (shape) + { + gdk_region_intersect (child_region, shape); + gdk_region_destroy (shape); + } + } + } + + gdk_region_subtract (region, child_region); + gdk_region_destroy (child_region); + + } +} + +static GdkVisibilityState +effective_visibility (GdkWindowObject *private) +{ + GdkVisibilityState native; + + if (!gdk_window_is_viewable ((GdkWindow *)private)) + return GDK_VISIBILITY_NOT_VIEWABLE; + + native = private->impl_window->native_visibility; + + if (native == GDK_VISIBILITY_FULLY_OBSCURED || + private->visibility == GDK_VISIBILITY_FULLY_OBSCURED) + return GDK_VISIBILITY_FULLY_OBSCURED; + else if (native == GDK_VISIBILITY_UNOBSCURED) + return private->visibility; + else /* native PARTIAL, private partial or unobscured */ + return GDK_VISIBILITY_PARTIAL; +} + +static void +gdk_window_update_visibility (GdkWindowObject *private) +{ + GdkVisibilityState new_visibility; + GdkEvent *event; + + new_visibility = effective_visibility (private); + + if (new_visibility != private->effective_visibility) + { + private->effective_visibility = new_visibility; + + if (new_visibility != GDK_VISIBILITY_NOT_VIEWABLE && + private->event_mask & GDK_VISIBILITY_NOTIFY) + { + event = _gdk_make_event ((GdkWindow *)private, GDK_VISIBILITY_NOTIFY, + NULL, FALSE); + event->visibility.state = new_visibility; + } + } +} + +static void +gdk_window_update_visibility_recursively (GdkWindowObject *private, + GdkWindowObject *only_for_impl) +{ + GdkWindowObject *child; + GList *l; + + gdk_window_update_visibility (private); + for (l = private->children; l != NULL; l = l->next) + { + child = l->data; + if ((only_for_impl == NULL) || + (only_for_impl == child->impl_window)) + gdk_window_update_visibility_recursively (child, only_for_impl); + } +} + +static gboolean +should_apply_clip_as_shape (GdkWindowObject *private) +{ + return + gdk_window_has_impl (private) && + /* Not for offscreens */ + !gdk_window_is_offscreen (private) && + /* or for toplevels */ + !gdk_window_is_toplevel (private) && + /* or for foreign windows */ + private->window_type != GDK_WINDOW_FOREIGN && + /* or for the root window */ + private->window_type != GDK_WINDOW_ROOT; +} + +static void +apply_shape (GdkWindowObject *private, + GdkRegion *region) +{ + GdkWindowImplIface *impl_iface; + + /* We trash whether we applied a shape so that + we can avoid unsetting it many times, which + could happen in e.g. apply_clip_as_shape as + windows get resized */ + impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl); + if (region) + impl_iface->shape_combine_region ((GdkWindow *)private, + region, 0, 0); + else if (private->applied_shape) + impl_iface->shape_combine_region ((GdkWindow *)private, + NULL, 0, 0); + + private->applied_shape = region != NULL; +} + +static void +apply_clip_as_shape (GdkWindowObject *private) +{ + GdkRectangle r; + + r.x = r.y = 0; + r.width = private->width; + r.height = private->height; + + /* We only apply the clip region if would differ + from the actual clip region implied by the size + of the window. This is to avoid unneccessarily + adding meaningless shapes to all native subwindows */ + if (!gdk_region_rect_equal (private->clip_region, &r)) + apply_shape (private, private->clip_region); + else + apply_shape (private, NULL); +} + +static void +recompute_visible_regions_internal (GdkWindowObject *private, + gboolean recalculate_clip, + gboolean recalculate_siblings, + gboolean recalculate_children) +{ + GdkRectangle r; + GList *l; + GdkWindowObject *child; + GdkRegion *new_clip, *old_clip_region_with_children; + gboolean clip_region_changed; + gboolean abs_pos_changed; + int old_abs_x, old_abs_y; + + old_abs_x = private->abs_x; + old_abs_y = private->abs_y; + + /* Update absolute position */ + if (gdk_window_has_impl (private)) + { + /* Native window starts here */ + private->abs_x = 0; + private->abs_y = 0; + } + else + { + private->abs_x = private->parent->abs_x + private->x; + private->abs_y = private->parent->abs_y + private->y; + } + + abs_pos_changed = + private->abs_x != old_abs_x || + private->abs_y != old_abs_y; + + /* Update clip region based on: + * parent clip + * window size + * siblings in parents above window + */ + clip_region_changed = FALSE; + if (recalculate_clip) + { + if (private->viewable) + { + /* Calculate visible region (sans children) in parent window coords */ + r.x = private->x; + r.y = private->y; + r.width = private->width; + r.height = private->height; + new_clip = gdk_region_rectangle (&r); + + if (!gdk_window_is_toplevel (private)) + { + gdk_region_intersect (new_clip, private->parent->clip_region); + + /* Remove all overlapping children from parent. + * Unless we're all native, because then we don't need to take + * siblings into account since X does that clipping for us. + * This makes things like SWT that modify the raw X stacking + * order without GDKs knowledge work. + */ + if (!_gdk_native_windows) + remove_child_area (private->parent, private, FALSE, new_clip); + } + + /* Convert from parent coords to window coords */ + gdk_region_offset (new_clip, -private->x, -private->y); + + if (private->shape) + gdk_region_intersect (new_clip, private->shape); + } + else + new_clip = gdk_region_new (); + + if (private->clip_region == NULL || + !gdk_region_equal (private->clip_region, new_clip)) + clip_region_changed = TRUE; + + if (private->clip_region) + gdk_region_destroy (private->clip_region); + private->clip_region = new_clip; + + old_clip_region_with_children = private->clip_region_with_children; + private->clip_region_with_children = gdk_region_copy (private->clip_region); + if (private->window_type != GDK_WINDOW_ROOT) + remove_child_area (private, NULL, FALSE, private->clip_region_with_children); + + if (clip_region_changed || + !gdk_region_equal (private->clip_region_with_children, old_clip_region_with_children)) + private->clip_tag = new_region_tag (); + + if (old_clip_region_with_children) + gdk_region_destroy (old_clip_region_with_children); + } + + if (clip_region_changed) + { + GdkVisibilityState visibility; + gboolean fully_visible; + + if (gdk_region_empty (private->clip_region)) + visibility = GDK_VISIBILITY_FULLY_OBSCURED; + else + { + if (private->shape) + { + fully_visible = gdk_region_equal (private->clip_region, + private->shape); + } + else + { + r.x = 0; + r.y = 0; + r.width = private->width; + r.height = private->height; + fully_visible = gdk_region_rect_equal (private->clip_region, &r); + } + + if (fully_visible) + visibility = GDK_VISIBILITY_UNOBSCURED; + else + visibility = GDK_VISIBILITY_PARTIAL; + } + + if (private->visibility != visibility) + { + private->visibility = visibility; + gdk_window_update_visibility (private); + } + } + + /* Update all children, recursively (except for root, where children are not exact). */ + if ((abs_pos_changed || clip_region_changed || recalculate_children) && + private->window_type != GDK_WINDOW_ROOT) + { + for (l = private->children; l; l = l->next) + { + child = l->data; + /* Only recalculate clip if the the clip region changed, otherwise + * there is no way the child clip region could change (its has not e.g. moved) + * Except if recalculate_children is set to force child updates + */ + recompute_visible_regions_internal (child, + recalculate_clip && (clip_region_changed || recalculate_children), + FALSE, FALSE); + } + } + + if (clip_region_changed && + should_apply_clip_as_shape (private)) + apply_clip_as_shape (private); + + if (recalculate_siblings && + !gdk_window_is_toplevel (private)) + { + /* If we moved a child window in parent or changed the stacking order, then we + * need to recompute the visible area of all the other children in the parent + */ + for (l = private->parent->children; l; l = l->next) + { + child = l->data; + + if (child != private) + recompute_visible_regions_internal (child, TRUE, FALSE, FALSE); + } + + /* We also need to recompute the _with_children clip for the parent */ + recompute_visible_regions_internal (private->parent, TRUE, FALSE, FALSE); + } + + if (private->cairo_surface) + { + int width, height; + + /* It would be nice if we had some cairo support here so we + could set the clip rect on the cairo surface */ + width = private->abs_x + private->width; + height = private->abs_y + private->height; + + _gdk_windowing_set_cairo_surface_size (private->cairo_surface, + width, height); + cairo_surface_set_device_offset (private->cairo_surface, + private->abs_x, + private->abs_y); + } +} + +/* Call this when private has changed in one or more of these ways: + * size changed + * window moved + * new window added + * stacking order of window changed + * child deleted + * + * It will recalculate abs_x/y and the clip regions + * + * Unless the window didn't change stacking order or size/pos, pass in TRUE + * for recalculate_siblings. (Mostly used internally for the recursion) + * + * If a child window was removed (and you can't use that child for + * recompute_visible_regions), pass in TRUE for recalculate_children on the parent + */ +static void +recompute_visible_regions (GdkWindowObject *private, + gboolean recalculate_siblings, + gboolean recalculate_children) +{ + recompute_visible_regions_internal (private, + TRUE, + recalculate_siblings, + recalculate_children); +} + +void +_gdk_window_update_size (GdkWindow *window) +{ + recompute_visible_regions ((GdkWindowObject *)window, TRUE, FALSE); +} + +/* Find the native window that would be just above "child" + * in the native stacking order if "child" was a native window + * (it doesn't have to be native). If there is no such native + * window inside this native parent then NULL is returned. + * If child is NULL, find lowest native window in parent. + */ +static GdkWindowObject * +find_native_sibling_above_helper (GdkWindowObject *parent, + GdkWindowObject *child) +{ + GdkWindowObject *w; + GList *l; + + if (child) + { + l = g_list_find (parent->children, child); + g_assert (l != NULL); /* Better be a child of its parent... */ + l = l->prev; /* Start looking at the one above the child */ + } + else + l = g_list_last (parent->children); + + for (; l != NULL; l = l->prev) + { + w = l->data; + + if (gdk_window_has_impl (w)) + return w; + + g_assert (parent != w); + w = find_native_sibling_above_helper (w, NULL); + if (w) + return w; + } + + return NULL; +} + + +static GdkWindowObject * +find_native_sibling_above (GdkWindowObject *parent, + GdkWindowObject *child) +{ + GdkWindowObject *w; + + w = find_native_sibling_above_helper (parent, child); + if (w) + return w; + + if (gdk_window_has_impl (parent)) + return NULL; + else + return find_native_sibling_above (parent->parent, parent); +} + +static GdkEventMask +get_native_event_mask (GdkWindowObject *private) +{ + if (_gdk_native_windows || + private->window_type == GDK_WINDOW_ROOT || + private->window_type == GDK_WINDOW_FOREIGN) + return private->event_mask; + else + { + GdkEventMask mask; + + /* Do whatever the app asks to, since the app + * may be asking for weird things for native windows, + * but don't use motion hints as that may affect non-native + * child windows that don't want it. Also, we need to + * set all the app-specified masks since they will be picked + * up by any implicit grabs (i.e. if they were not set as + * native we would not get the events we need). */ + mask = private->event_mask & ~GDK_POINTER_MOTION_HINT_MASK; + + /* We need thse for all native windows so we can + emulate events on children: */ + mask |= + GDK_EXPOSURE_MASK | + GDK_VISIBILITY_NOTIFY_MASK | + GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK; + + /* Additionally we select for pointer and button events + * for toplevels as we need to get these to emulate + * them for non-native subwindows. Even though we don't + * select on them for all native windows we will get them + * as the events are propagated out to the first window + * that select for them. + * Not selecting for button press on all windows is an + * important thing, because in X only one client can do + * so, and we don't want to unexpectedly prevent another + * client from doing it. + * + * We also need to do the same if the app selects for button presses + * because then we will get implicit grabs for this window, and the + * event mask used for that grab is based on the rest of the mask + * for the window, but we might need more events than this window + * lists due to some non-native child window. + */ + if (gdk_window_is_toplevel (private) || + mask & GDK_BUTTON_PRESS_MASK) + mask |= + GDK_POINTER_MOTION_MASK | + GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | + GDK_SCROLL_MASK; + + return mask; + } +} + +static GdkEventMask +get_native_grab_event_mask (GdkEventMask grab_mask) +{ + /* Similar to the above but for pointer events only */ + return + GDK_POINTER_MOTION_MASK | + GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | + GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | + GDK_SCROLL_MASK | + (grab_mask & + ~GDK_POINTER_MOTION_HINT_MASK); +} + +/* Puts the native window in the right order wrt the other native windows + * in the hierarchy, given the position it has in the client side data. + * This is useful if some operation changed the stacking order. + * This calls assumes the native window is now topmost in its native parent. + */ +static void +sync_native_window_stack_position (GdkWindow *window) +{ + GdkWindowObject *above; + GdkWindowObject *private; + GdkWindowImplIface *impl_iface; + GList listhead = {0}; + + private = (GdkWindowObject *) window; + impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl); + + above = find_native_sibling_above (private->parent, private); + if (above) + { + listhead.data = window; + impl_iface->restack_under ((GdkWindow *)above, + &listhead); + } +} + +/** + * gdk_window_new: + * @parent: (allow-none): a #GdkWindow, or %NULL to create the window as a child of + * the default root window for the default display. + * @attributes: attributes of the new window + * @attributes_mask: mask indicating which fields in @attributes are valid + * + * Creates a new #GdkWindow using the attributes from + * @attributes. See #GdkWindowAttr and #GdkWindowAttributesType for + * more details. Note: to use this on displays other than the default + * display, @parent must be specified. + * + * Return value: (transfer none): the new #GdkWindow + **/ +GdkWindow* +gdk_window_new (GdkWindow *parent, + GdkWindowAttr *attributes, + gint attributes_mask) +{ + GdkWindow *window; + GdkWindowObject *private; + GdkScreen *screen; + GdkVisual *visual; + int x, y; + gboolean native; + GdkEventMask event_mask; + GdkWindow *real_parent; + + g_return_val_if_fail (attributes != NULL, NULL); + + if (!parent) + { + GDK_NOTE (MULTIHEAD, + g_warning ("gdk_window_new(): no parent specified reverting to parent = default root window")); + + screen = gdk_screen_get_default (); + parent = gdk_screen_get_root_window (screen); + } + else + screen = gdk_drawable_get_screen (parent); + + g_return_val_if_fail (GDK_IS_WINDOW (parent), NULL); + + if (GDK_WINDOW_DESTROYED (parent)) + { + g_warning ("gdk_window_new(): parent is destroyed\n"); + return NULL; + } + + if (attributes->window_type == GDK_WINDOW_OFFSCREEN && + _gdk_native_windows) + { + g_warning ("Offscreen windows not supported with native-windows gdk"); + return NULL; + } + + window = g_object_new (GDK_TYPE_WINDOW, NULL); + private = (GdkWindowObject *) window; + + /* Windows with a foreign parent are treated as if they are children + * of the root window, except for actual creation. + */ + real_parent = parent; + if (GDK_WINDOW_TYPE (parent) == GDK_WINDOW_FOREIGN) + parent = gdk_screen_get_root_window (screen); + + private->parent = (GdkWindowObject *)parent; + + private->accept_focus = TRUE; + private->focus_on_map = TRUE; + + if (attributes_mask & GDK_WA_X) + x = attributes->x; + else + x = 0; + + if (attributes_mask & GDK_WA_Y) + y = attributes->y; + else + y = 0; + + private->x = x; + private->y = y; + private->width = (attributes->width > 1) ? (attributes->width) : (1); + private->height = (attributes->height > 1) ? (attributes->height) : (1); + +#ifdef GDK_WINDOWING_X11 + /* Work around a bug where Xorg refuses to map toplevel InputOnly windows + * from an untrusted client: http://bugs.freedesktop.org/show_bug.cgi?id=6988 + */ + if (attributes->wclass == GDK_INPUT_ONLY && + private->parent->window_type == GDK_WINDOW_ROOT && + !G_LIKELY (GDK_DISPLAY_X11 (GDK_WINDOW_DISPLAY (parent))->trusted_client)) + { + g_warning ("Coercing GDK_INPUT_ONLY toplevel window to GDK_INPUT_OUTPUT to work around bug in Xorg server"); + attributes->wclass = GDK_INPUT_OUTPUT; + } +#endif + + if (attributes->wclass == GDK_INPUT_ONLY) + { + /* Backwards compatiblity - we've always ignored + * attributes->window_type for input-only windows + * before + */ + if (GDK_WINDOW_TYPE (parent) == GDK_WINDOW_ROOT) + private->window_type = GDK_WINDOW_TEMP; + else + private->window_type = GDK_WINDOW_CHILD; + } + else + private->window_type = attributes->window_type; + + /* Sanity checks */ + switch (private->window_type) + { + case GDK_WINDOW_TOPLEVEL: + case GDK_WINDOW_DIALOG: + case GDK_WINDOW_TEMP: + case GDK_WINDOW_OFFSCREEN: + if (GDK_WINDOW_TYPE (parent) != GDK_WINDOW_ROOT) + g_warning (G_STRLOC "Toplevel windows must be created as children of\n" + "of a window of type GDK_WINDOW_ROOT or GDK_WINDOW_FOREIGN"); + case GDK_WINDOW_CHILD: + break; + break; + default: + g_warning (G_STRLOC "cannot make windows of type %d", private->window_type); + return NULL; + } + + if (attributes_mask & GDK_WA_VISUAL) + visual = attributes->visual; + else + visual = gdk_screen_get_system_visual (screen); + + private->event_mask = attributes->event_mask; + + if (attributes->wclass == GDK_INPUT_OUTPUT) + { + private->input_only = FALSE; + private->depth = visual->depth; + + private->bg_color.pixel = 0; /* TODO: BlackPixel (xdisplay, screen_x11->screen_num); */ + private->bg_color.red = private->bg_color.green = private->bg_color.blue = 0; + + private->bg_pixmap = NULL; + } + else + { + private->depth = 0; + private->input_only = TRUE; + } + + if (private->parent) + private->parent->children = g_list_prepend (private->parent->children, window); + + native = _gdk_native_windows; /* Default */ + if (private->parent->window_type == GDK_WINDOW_ROOT) + native = TRUE; /* Always use native windows for toplevels */ + else if (!private->input_only && + ((attributes_mask & GDK_WA_COLORMAP && + attributes->colormap != gdk_drawable_get_colormap ((GdkDrawable *)private->parent)) || + (attributes_mask & GDK_WA_VISUAL && + attributes->visual != gdk_drawable_get_visual ((GdkDrawable *)private->parent)))) + native = TRUE; /* InputOutput window with different colormap or visual than parent, needs native window */ + + if (gdk_window_is_offscreen (private)) + { + _gdk_offscreen_window_new (window, screen, visual, attributes, attributes_mask); + private->impl_window = private; + } + else if (native) + { + event_mask = get_native_event_mask (private); + + /* Create the impl */ + _gdk_window_impl_new (window, real_parent, screen, visual, event_mask, attributes, attributes_mask); + private->impl_window = private; + + /* This will put the native window topmost in the native parent, which may + * be wrong wrt other native windows in the non-native hierarchy, so restack */ + if (!_gdk_window_has_impl (real_parent)) + sync_native_window_stack_position (window); + } + else + { + private->impl_window = g_object_ref (private->parent->impl_window); + private->impl = g_object_ref (private->impl_window->impl); + } + + recompute_visible_regions (private, TRUE, FALSE); + + if (private->parent->window_type != GDK_WINDOW_ROOT) + { + /* Inherit redirection from parent */ + private->redirect = private->parent->redirect; + } + + gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ? + (attributes->cursor) : + NULL)); + + return window; +} + +static gboolean +is_parent_of (GdkWindow *parent, + GdkWindow *child) +{ + GdkWindow *w; + + w = child; + while (w != NULL) + { + if (w == parent) + return TRUE; + + w = gdk_window_get_parent (w); + } + + return FALSE; +} + +static void +change_impl (GdkWindowObject *private, + GdkWindowObject *impl_window, + GdkDrawable *new) +{ + GList *l; + GdkWindowObject *child; + GdkDrawable *old_impl; + GdkWindowObject *old_impl_window; + + old_impl = private->impl; + old_impl_window = private->impl_window; + if (private != impl_window) + private->impl_window = g_object_ref (impl_window); + else + private->impl_window = private; + private->impl = g_object_ref (new); + if (old_impl_window != private) + g_object_unref (old_impl_window); + g_object_unref (old_impl); + + for (l = private->children; l != NULL; l = l->next) + { + child = l->data; + + if (child->impl == old_impl) + change_impl (child, impl_window, new); + } +} + +static void +reparent_to_impl (GdkWindowObject *private) +{ + GList *l; + GdkWindowObject *child; + gboolean show; + GdkWindowImplIface *impl_iface; + + impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl); + + /* Enumerate in reverse order so we get the right order for the native + windows (first in childrens list is topmost, and reparent places on top) */ + for (l = g_list_last (private->children); l != NULL; l = l->prev) + { + child = l->data; + + if (child->impl == private->impl) + reparent_to_impl (child); + else + { + show = impl_iface->reparent ((GdkWindow *)child, + (GdkWindow *)private, + child->x, child->y); + if (show) + gdk_window_show_unraised ((GdkWindow *)child); + } + } +} + + +/** + * gdk_window_reparent: + * @window: a #GdkWindow + * @new_parent: new parent to move @window into + * @x: X location inside the new parent + * @y: Y location inside the new parent + * + * Reparents @window into the given @new_parent. The window being + * reparented will be unmapped as a side effect. + * + **/ +void +gdk_window_reparent (GdkWindow *window, + GdkWindow *new_parent, + gint x, + gint y) +{ + GdkWindowObject *private; + GdkWindowObject *new_parent_private; + GdkWindowObject *old_parent; + GdkScreen *screen; + gboolean show, was_mapped, applied_clip_as_shape; + gboolean do_reparent_to_impl; + GdkEventMask old_native_event_mask; + GdkWindowImplIface *impl_iface; + + g_return_if_fail (GDK_IS_WINDOW (window)); + g_return_if_fail (new_parent == NULL || GDK_IS_WINDOW (new_parent)); + g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_ROOT); + + if (GDK_WINDOW_DESTROYED (window) || + (new_parent && GDK_WINDOW_DESTROYED (new_parent))) + return; + + screen = gdk_drawable_get_screen (GDK_DRAWABLE (window)); + if (!new_parent) + new_parent = gdk_screen_get_root_window (screen); + + private = (GdkWindowObject *) window; + new_parent_private = (GdkWindowObject *)new_parent; + + /* No input-output children of input-only windows */ + if (new_parent_private->input_only && !private->input_only) + return; + + /* Don't create loops in hierarchy */ + if (is_parent_of (window, new_parent)) + return; + + /* This might be wrong in the new parent, e.g. for non-native surfaces. + To make sure we're ok, just wipe it. */ + gdk_window_drop_cairo_surface (private); + + impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl); + old_parent = private->parent; + + /* Break up redirection if inherited */ + if (private->redirect && private->redirect->redirected != private) + { + remove_redirect_from_children (private, private->redirect); + private->redirect = NULL; + } + + was_mapped = GDK_WINDOW_IS_MAPPED (window); + show = FALSE; + + /* Reparenting to toplevel. Ensure we have a native window so this can work */ + if (new_parent_private->window_type == GDK_WINDOW_ROOT || + new_parent_private->window_type == GDK_WINDOW_FOREIGN) + gdk_window_ensure_native (window); + + applied_clip_as_shape = should_apply_clip_as_shape (private); + + old_native_event_mask = 0; + do_reparent_to_impl = FALSE; + if (gdk_window_has_impl (private)) + { + old_native_event_mask = get_native_event_mask (private); + /* Native window */ + show = impl_iface->reparent (window, new_parent, x, y); + } + else + { + /* This shouldn't happen, as we created a native in this case, check anyway to see if that ever fails */ + g_assert (new_parent_private->window_type != GDK_WINDOW_ROOT && + new_parent_private->window_type != GDK_WINDOW_FOREIGN); + + show = was_mapped; + gdk_window_hide (window); + + do_reparent_to_impl = TRUE; + change_impl (private, + new_parent_private->impl_window, + new_parent_private->impl); + } + + /* From here on, we treat parents of type GDK_WINDOW_FOREIGN like + * the root window + */ + if (GDK_WINDOW_TYPE (new_parent) == GDK_WINDOW_FOREIGN) + { + new_parent = gdk_screen_get_root_window (screen); + new_parent_private = (GdkWindowObject *)new_parent; + } + + if (old_parent) + old_parent->children = g_list_remove (old_parent->children, window); + + private->parent = new_parent_private; + private->x = x; + private->y = y; + + new_parent_private->children = g_list_prepend (new_parent_private->children, window); + + /* Switch the window type as appropriate */ + + switch (GDK_WINDOW_TYPE (new_parent)) + { + case GDK_WINDOW_ROOT: + case GDK_WINDOW_FOREIGN: + if (private->toplevel_window_type != -1) + GDK_WINDOW_TYPE (window) = private->toplevel_window_type; + else if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD) + GDK_WINDOW_TYPE (window) = GDK_WINDOW_TOPLEVEL; + break; + case GDK_WINDOW_OFFSCREEN: + case GDK_WINDOW_TOPLEVEL: + case GDK_WINDOW_CHILD: + case GDK_WINDOW_DIALOG: + case GDK_WINDOW_TEMP: + if (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD && \ + GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN) + { + /* Save the original window type so we can restore it if the + * window is reparented back to be a toplevel + */ + private->toplevel_window_type = GDK_WINDOW_TYPE (window); + GDK_WINDOW_TYPE (window) = GDK_WINDOW_CHILD; + } + } + + /* We might have changed window type for a native windows, so we + need to change the event mask too. */ + if (gdk_window_has_impl (private)) + { + GdkEventMask native_event_mask = get_native_event_mask (private); + + if (native_event_mask != old_native_event_mask) + impl_iface->set_events (window, native_event_mask); + } + + /* Inherit parent redirect if we don't have our own */ + if (private->parent && private->redirect == NULL) + { + private->redirect = private->parent->redirect; + apply_redirect_to_children (private, private->redirect); + } + + _gdk_window_update_viewable (window); + + recompute_visible_regions (private, TRUE, FALSE); + if (old_parent && GDK_WINDOW_TYPE (old_parent) != GDK_WINDOW_ROOT) + recompute_visible_regions (old_parent, FALSE, TRUE); + + /* We used to apply the clip as the shape, but no more. + Reset this to the real shape */ + if (gdk_window_has_impl (private) && + applied_clip_as_shape && + !should_apply_clip_as_shape (private)) + apply_shape (private, private->shape); + + if (do_reparent_to_impl) + reparent_to_impl (private); + else + { + /* The reparent will have put the native window topmost in the native parent, + * which may be wrong wrt other native windows in the non-native hierarchy, + * so restack */ + if (!gdk_window_has_impl (new_parent_private)) + sync_native_window_stack_position (window); + } + + if (show) + gdk_window_show_unraised (window); + else + _gdk_synthesize_crossing_events_for_geometry_change (window); +} + +static gboolean +temporary_disable_extension_events (GdkWindowObject *window) +{ + GdkWindowObject *child; + GList *l; + gboolean res; + + if (window->extension_events != 0) + { + g_object_set_data (G_OBJECT (window), + "gdk-window-extension-events", + GINT_TO_POINTER (window->extension_events)); + gdk_input_set_extension_events ((GdkWindow *)window, 0, + GDK_EXTENSION_EVENTS_NONE); + } + else + res = FALSE; + + for (l = window->children; l != NULL; l = l->next) + { + child = l->data; + + if (window->impl_window == child->impl_window) + res |= temporary_disable_extension_events (child); + } + + return res; +} + +static void +reenable_extension_events (GdkWindowObject *window) +{ + GdkWindowObject *child; + GList *l; + int mask; + + mask = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), + "gdk-window-extension-events")); + + if (mask != 0) + { + /* We don't have the mode here, so we pass in cursor. + This works with the current code since mode is not + stored except as part of the mask, and cursor doesn't + change the mask. */ + gdk_input_set_extension_events ((GdkWindow *)window, mask, + GDK_EXTENSION_EVENTS_CURSOR); + g_object_set_data (G_OBJECT (window), + "gdk-window-extension-events", + NULL); + } + + for (l = window->children; l != NULL; l = l->next) + { + child = l->data; + + if (window->impl_window == child->impl_window) + reenable_extension_events (window); + } +} + +/** + * gdk_window_ensure_native: + * @window: a #GdkWindow + * + * Tries to ensure that there is a window-system native window for this + * GdkWindow. This may fail in some situations, returning %FALSE. + * + * Offscreen window and children of them can never have native windows. + * + * Some backends may not support native child windows. + * + * Returns: %TRUE if the window has a native window, %FALSE otherwise + * + * Since: 2.18 + */ +gboolean +gdk_window_ensure_native (GdkWindow *window) +{ + GdkWindowObject *private; + GdkWindowObject *impl_window; + GdkDrawable *new_impl, *old_impl; + GdkScreen *screen; + GdkVisual *visual; + GdkWindowAttr attributes; + GdkWindowObject *above; + GList listhead; + GdkWindowImplIface *impl_iface; + gboolean disabled_extension_events; + + g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE); + + if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_ROOT || + GDK_WINDOW_DESTROYED (window)) + return FALSE; + + private = (GdkWindowObject *) window; + + impl_window = gdk_window_get_impl_window (private); + + if (gdk_window_is_offscreen (impl_window)) + return FALSE; /* native in offscreens not supported */ + + if (impl_window == private) + /* Already has an impl, and its not offscreen . */ + return TRUE; + + /* Need to create a native window */ + + /* First we disable any extension events on the window or its + descendants to handle the native input window moving */ + disabled_extension_events = FALSE; + if (impl_window->input_window) + disabled_extension_events = temporary_disable_extension_events (private); + + gdk_window_drop_cairo_surface (private); + + screen = gdk_drawable_get_screen (window); + visual = gdk_drawable_get_visual (window); + + /* These fields are required in the attributes struct so we can't + ignore them by clearing a flag in the attributes mask */ + attributes.wclass = private->input_only ? GDK_INPUT_ONLY : GDK_INPUT_OUTPUT; + attributes.width = private->width; + attributes.height = private->height; + attributes.window_type = private->window_type; + + attributes.colormap = gdk_drawable_get_colormap (window); + + old_impl = private->impl; + _gdk_window_impl_new (window, (GdkWindow *)private->parent, + screen, visual, + get_native_event_mask (private), + &attributes, GDK_WA_COLORMAP); + new_impl = private->impl; + + private->impl = old_impl; + change_impl (private, private, new_impl); + + impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl); + + /* Native window creation will put the native window topmost in the + * native parent, which may be wrong wrt the position of the previous + * non-native window wrt to the other non-native children, so correct this. + */ + above = find_native_sibling_above (private->parent, private); + if (above) + { + listhead.data = window; + listhead.prev = NULL; + listhead.next = NULL; + impl_iface->restack_under ((GdkWindow *)above, &listhead); + } + + recompute_visible_regions (private, FALSE, FALSE); + + /* The shape may not have been set, as the clip region doesn't actually + change, so do it here manually */ + if (should_apply_clip_as_shape (private)) + apply_clip_as_shape (private); + + reparent_to_impl (private); + + if (!private->input_only) + { + impl_iface->set_background (window, &private->bg_color); + if (private->bg_pixmap != NULL) + impl_iface->set_back_pixmap (window, private->bg_pixmap); + } + + impl_iface->input_shape_combine_region (window, + private->input_shape, + 0, 0); + + if (gdk_window_is_viewable (window)) + impl_iface->show (window, FALSE); + + if (disabled_extension_events) + reenable_extension_events (private); + + return TRUE; +} + +/** + * _gdk_event_filter_unref: + * @window: (allow-none): A #GdkWindow, or %NULL to be the global window + * @filter: A window filter + * + * Release a reference to @filter. Note this function may + * mutate the list storage, so you need to handle this + * if iterating over a list of filters. + */ +void +_gdk_event_filter_unref (GdkWindow *window, + GdkEventFilter *filter) +{ + GList **filters; + GList *tmp_list; + + if (window == NULL) + filters = &_gdk_default_filters; + else + { + GdkWindowObject *private; + private = (GdkWindowObject *) window; + filters = &private->filters; + } + + tmp_list = *filters; + while (tmp_list) + { + GdkEventFilter *iter_filter = tmp_list->data; + GList *node; + + node = tmp_list; + tmp_list = tmp_list->next; + + if (iter_filter != filter) + continue; + + g_assert (iter_filter->ref_count > 0); + + filter->ref_count--; + if (filter->ref_count != 0) + continue; + + *filters = g_list_remove_link (*filters, node); + g_free (filter); + g_list_free_1 (node); + } +} + +static void +window_remove_filters (GdkWindow *window) +{ + GdkWindowObject *obj = (GdkWindowObject*) window; + while (obj->filters) + _gdk_event_filter_unref (window, obj->filters->data); +} + +/** + * _gdk_window_destroy_hierarchy: + * @window: a #GdkWindow + * @recursing: If TRUE, then this is being called because a parent + * was destroyed. + * @recursing_native: If TRUE, then this is being called because a native parent + * was destroyed. This generally means that the call to the + * windowing system to destroy the window can be omitted, since + * it will be destroyed as a result of the parent being destroyed. + * Unless @foreign_destroy. + * @foreign_destroy: If TRUE, the window or a parent was destroyed by some + * external agency. The window has already been destroyed and no + * windowing system calls should be made. (This may never happen + * for some windowing systems.) + * + * Internal function to destroy a window. Like gdk_window_destroy(), + * but does not drop the reference count created by gdk_window_new(). + **/ +static void +_gdk_window_destroy_hierarchy (GdkWindow *window, + gboolean recursing, + gboolean recursing_native, + gboolean foreign_destroy) +{ + GdkWindowObject *private; + GdkWindowObject *temp_private; + GdkWindowImplIface *impl_iface; + GdkWindow *temp_window; + GdkScreen *screen; + GdkDisplay *display; + GList *children; + GList *tmp; + + g_return_if_fail (GDK_IS_WINDOW (window)); + + private = (GdkWindowObject*) window; + + if (GDK_WINDOW_DESTROYED (window)) + return; + + display = gdk_drawable_get_display (GDK_DRAWABLE (window)); + screen = gdk_drawable_get_screen (GDK_DRAWABLE (window)); + temp_window = g_object_get_qdata (G_OBJECT (screen), quark_pointer_window); + if (temp_window == window) + g_object_set_qdata (G_OBJECT (screen), quark_pointer_window, NULL); + + + switch (private->window_type) + { + case GDK_WINDOW_ROOT: + if (!screen->closed) + { + g_error ("attempted to destroy root window"); + break; + } + /* else fall thru */ + case GDK_WINDOW_TOPLEVEL: + case GDK_WINDOW_CHILD: + case GDK_WINDOW_DIALOG: + case GDK_WINDOW_TEMP: + case GDK_WINDOW_FOREIGN: + case GDK_WINDOW_OFFSCREEN: + if (private->window_type == GDK_WINDOW_FOREIGN && !foreign_destroy) + { + /* Logically, it probably makes more sense to send + * a "destroy yourself" message to the foreign window + * whether or not it's in our hierarchy; but for historical + * reasons, we only send "destroy yourself" messages to + * foreign windows in our hierarchy. + */ + if (private->parent) + _gdk_windowing_window_destroy_foreign (window); + + /* Also for historical reasons, we remove any filters + * on a foreign window when it or a parent is destroyed; + * this likely causes problems if two separate portions + * of code are maintaining filter lists on a foreign window. + */ + window_remove_filters (window); + } + else + { + if (private->parent) + { + GdkWindowObject *parent_private = (GdkWindowObject *)private->parent; + + if (parent_private->children) + parent_private->children = g_list_remove (parent_private->children, window); + + if (!recursing && + GDK_WINDOW_IS_MAPPED (window)) + { + recompute_visible_regions (private, TRUE, FALSE); + gdk_window_invalidate_in_parent (private); + } + } + + gdk_window_free_paint_stack (window); + + if (private->bg_pixmap && + private->bg_pixmap != GDK_PARENT_RELATIVE_BG && + private->bg_pixmap != GDK_NO_BG) + { + g_object_unref (private->bg_pixmap); + private->bg_pixmap = NULL; + } + + if (private->background) + { + cairo_pattern_destroy (private->background); + private->background = NULL; + } + + if (private->window_type == GDK_WINDOW_FOREIGN) + g_assert (private->children == NULL); + else + { + children = tmp = private->children; + private->children = NULL; + + while (tmp) + { + temp_window = tmp->data; + tmp = tmp->next; + + temp_private = (GdkWindowObject*) temp_window; + if (temp_private) + _gdk_window_destroy_hierarchy (temp_window, + TRUE, + recursing_native || gdk_window_has_impl (private), + foreign_destroy); + } + + g_list_free (children); + } + + _gdk_window_clear_update_area (window); + + gdk_window_drop_cairo_surface (private); + + impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl); + + if (private->extension_events) + impl_iface->input_window_destroy (window); + + if (gdk_window_has_impl (private)) + impl_iface->destroy (window, recursing_native, + foreign_destroy); + else + { + /* hide to make sure we repaint and break grabs */ + gdk_window_hide (window); + } + + private->state |= GDK_WINDOW_STATE_WITHDRAWN; + private->parent = NULL; + private->destroyed = TRUE; + + window_remove_filters (window); + + gdk_drawable_set_colormap (GDK_DRAWABLE (window), NULL); + + /* If we own the redirect, free it */ + if (private->redirect && private->redirect->redirected == private) + gdk_window_redirect_free (private->redirect); + + private->redirect = NULL; + + if (display->pointer_info.toplevel_under_pointer == window) + { + g_object_unref (display->pointer_info.toplevel_under_pointer); + display->pointer_info.toplevel_under_pointer = NULL; + } + + if (private->clip_region) + { + gdk_region_destroy (private->clip_region); + private->clip_region = NULL; + } + + if (private->clip_region_with_children) + { + gdk_region_destroy (private->clip_region_with_children); + private->clip_region_with_children = NULL; + } + + if (private->outstanding_moves) + { + g_list_foreach (private->outstanding_moves, (GFunc)gdk_window_region_move_free, NULL); + g_list_free (private->outstanding_moves); + private->outstanding_moves = NULL; + } + } + break; + } +} + +/** + * _gdk_window_destroy: + * @window: a #GdkWindow + * @foreign_destroy: If TRUE, the window or a parent was destroyed by some + * external agency. The window has already been destroyed and no + * windowing system calls should be made. (This may never happen + * for some windowing systems.) + * + * Internal function to destroy a window. Like gdk_window_destroy(), + * but does not drop the reference count created by gdk_window_new(). + **/ +void +_gdk_window_destroy (GdkWindow *window, + gboolean foreign_destroy) +{ + _gdk_window_destroy_hierarchy (window, FALSE, FALSE, foreign_destroy); +} + +/** + * gdk_window_destroy: + * @window: a #GdkWindow + * + * Destroys the window system resources associated with @window and decrements @window's + * reference count. The window system resources for all children of @window are also + * destroyed, but the children's reference counts are not decremented. + * + * Note that a window will not be destroyed automatically when its reference count + * reaches zero. You must call this function yourself before that happens. + * + **/ +void +gdk_window_destroy (GdkWindow *window) +{ + _gdk_window_destroy_hierarchy (window, FALSE, FALSE, FALSE); + g_object_unref (window); +} + +/** + * gdk_window_set_user_data: + * @window: a #GdkWindow + * @user_data: user data + * + * For most purposes this function is deprecated in favor of + * g_object_set_data(). However, for historical reasons GTK+ stores + * the #GtkWidget that owns a #GdkWindow as user data on the + * #GdkWindow. So, custom widget implementations should use + * this function for that. If GTK+ receives an event for a #GdkWindow, + * and the user data for the window is non-%NULL, GTK+ will assume the + * user data is a #GtkWidget, and forward the event to that widget. + * + **/ +void +gdk_window_set_user_data (GdkWindow *window, + gpointer user_data) +{ + g_return_if_fail (GDK_IS_WINDOW (window)); + + ((GdkWindowObject*)window)->user_data = user_data; +} + +/** + * gdk_window_get_user_data: + * @window: a #GdkWindow + * @data: (out): return location for user data + * + * Retrieves the user data for @window, which is normally the widget + * that @window belongs to. See gdk_window_set_user_data(). + * + **/ +void +gdk_window_get_user_data (GdkWindow *window, + gpointer *data) +{ + g_return_if_fail (GDK_IS_WINDOW (window)); + + *data = ((GdkWindowObject*)window)->user_data; +} + +/** + * gdk_window_get_window_type: + * @window: a #GdkWindow + * + * Gets the type of the window. See #GdkWindowType. + * + * Return value: type of window + **/ +GdkWindowType +gdk_window_get_window_type (GdkWindow *window) +{ + g_return_val_if_fail (GDK_IS_WINDOW (window), (GdkWindowType) -1); + + return GDK_WINDOW_TYPE (window); +} + +/** + * gdk_window_is_destroyed: + * @window: a #GdkWindow + * + * Check to see if a window is destroyed.. + * + * Return value: %TRUE if the window is destroyed + * + * Since: 2.18 + **/ +gboolean +gdk_window_is_destroyed (GdkWindow *window) +{ + return GDK_WINDOW_DESTROYED (window); +} + +static void +to_embedder (GdkWindowObject *window, + gdouble offscreen_x, + gdouble offscreen_y, + gdouble *embedder_x, + gdouble *embedder_y) +{ + g_signal_emit (window, signals[TO_EMBEDDER], 0, + offscreen_x, offscreen_y, + embedder_x, embedder_y); +} + +static void +from_embedder (GdkWindowObject *window, + gdouble embedder_x, + gdouble embedder_y, + gdouble *offscreen_x, + gdouble *offscreen_y) +{ + g_signal_emit (window, signals[FROM_EMBEDDER], 0, + embedder_x, embedder_y, + offscreen_x, offscreen_y); +} + +/** + * gdk_window_has_native: + * @window: a #GdkWindow + * + * Checks whether the window has a native window or not. Note that + * you can use gdk_window_ensure_native() if a native window is needed. + * + * Returns: %TRUE if the %window has a native window, %FALSE otherwise. + * + * Since: 2.22 + */ +gboolean +gdk_window_has_native (GdkWindow *window) +{ + GdkWindowObject *w; + + g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE); + + w = GDK_WINDOW_OBJECT (window); + + return w->parent == NULL || w->parent->impl != w->impl; +} + +/** + * gdk_window_get_position: + * @window: a #GdkWindow + * @x: (out) (allow-none): X coordinate of window + * @y: (out) (allow-none): Y coordinate of window + * + * Obtains the position of the window as reported in the + * most-recently-processed #GdkEventConfigure. Contrast with + * gdk_window_get_geometry() which queries the X server for the + * current window position, regardless of which events have been + * received or processed. + * + * The position coordinates are relative to the window's parent window. + * + **/ +void +gdk_window_get_position (GdkWindow *window, + gint *x, + gint *y) +{ + GdkWindowObject *obj; + + g_return_if_fail (GDK_IS_WINDOW (window)); + + obj = (GdkWindowObject*) window; + + if (x) + *x = obj->x; + if (y) + *y = obj->y; +} + +/** + * gdk_window_get_parent: + * @window: a #GdkWindow + * + * Obtains the parent of @window, as known to GDK. Does not query the + * X server; thus this returns the parent as passed to gdk_window_new(), + * not the actual parent. This should never matter unless you're using + * Xlib calls mixed with GDK calls on the X11 platform. It may also + * matter for toplevel windows, because the window manager may choose + * to reparent them. + * + * Note that you should use gdk_window_get_effective_parent() when + * writing generic code that walks up a window hierarchy, because + * gdk_window_get_parent() will most likely not do what you expect if + * there are offscreen windows in the hierarchy. + * + * Return value: parent of @window + **/ +GdkWindow* +gdk_window_get_parent (GdkWindow *window) +{ + g_return_val_if_fail (GDK_IS_WINDOW (window), NULL); + + return (GdkWindow*) ((GdkWindowObject*) window)->parent; +} + +/** + * gdk_window_get_effective_parent: + * @window: a #GdkWindow + * + * Obtains the parent of @window, as known to GDK. Works like + * gdk_window_get_parent() for normal windows, but returns the + * window's embedder for offscreen windows. + * + * See also: gdk_offscreen_window_get_embedder() + * + * Return value: effective parent of @window + * + * Since: 2.22 + **/ +GdkWindow * +gdk_window_get_effective_parent (GdkWindow *window) +{ + GdkWindowObject *obj; + + g_return_val_if_fail (GDK_IS_WINDOW (window), NULL); + + obj = (GdkWindowObject *)window; + + if (gdk_window_is_offscreen (obj)) + return gdk_offscreen_window_get_embedder (window); + else + return (GdkWindow *) obj->parent; +} + +/** + * gdk_window_get_toplevel: + * @window: a #GdkWindow + * + * Gets the toplevel window that's an ancestor of @window. + * + * Any window type but %GDK_WINDOW_CHILD is considered a + * toplevel window, as is a %GDK_WINDOW_CHILD window that + * has a root window as parent. + * + * Note that you should use gdk_window_get_effective_toplevel() when + * you want to get to a window's toplevel as seen on screen, because + * gdk_window_get_toplevel() will most likely not do what you expect + * if there are offscreen windows in the hierarchy. + * + * Return value: the toplevel window containing @window + **/ +GdkWindow * +gdk_window_get_toplevel (GdkWindow *window) +{ + GdkWindowObject *obj; + + g_return_val_if_fail (GDK_IS_WINDOW (window), NULL); + + obj = (GdkWindowObject *)window; + + while (obj->window_type == GDK_WINDOW_CHILD) + { + if (gdk_window_is_toplevel (obj)) + break; + obj = obj->parent; + } + + return GDK_WINDOW (obj); +} + +/** + * gdk_window_get_effective_toplevel: + * @window: a #GdkWindow + * + * Gets the toplevel window that's an ancestor of @window. + * + * Works like gdk_window_get_toplevel(), but treats an offscreen window's + * embedder as its parent, using gdk_window_get_effective_parent(). + * + * See also: gdk_offscreen_window_get_embedder() + * + * Return value: the effective toplevel window containing @window + * + * Since: 2.22 + **/ +GdkWindow * +gdk_window_get_effective_toplevel (GdkWindow *window) +{ + GdkWindow *parent; + + g_return_val_if_fail (GDK_IS_WINDOW (window), NULL); + + while ((parent = gdk_window_get_effective_parent (window)) != NULL && + (gdk_window_get_window_type (parent) != GDK_WINDOW_ROOT)) + window = parent; + + return window; +} + +/** + * gdk_window_get_children: + * @window: a #GdkWindow + * + * Gets the list of children of @window known to GDK. + * This function only returns children created via GDK, + * so for example it's useless when used with the root window; + * it only returns windows an application created itself. + * + * The returned list must be freed, but the elements in the + * list need not be. + * + * Return value: (transfer container) (element-type GdkWindow): + * list of child windows inside @window + **/ +GList* +gdk_window_get_children (GdkWindow *window) +{ + g_return_val_if_fail (GDK_IS_WINDOW (window), NULL); + + if (GDK_WINDOW_DESTROYED (window)) + return NULL; + + return g_list_copy (GDK_WINDOW_OBJECT (window)->children); +} + +/** + * gdk_window_peek_children: + * @window: a #GdkWindow + * + * Like gdk_window_get_children(), but does not copy the list of + * children, so the list does not need to be freed. + * + * Return value: (transfer none) (element-type GdkWindow): + * a reference to the list of child windows in @window + **/ +GList * +gdk_window_peek_children (GdkWindow *window) +{ + g_return_val_if_fail (GDK_IS_WINDOW (window), NULL); + + if (GDK_WINDOW_DESTROYED (window)) + return NULL; + + return GDK_WINDOW_OBJECT (window)->children; +} + +/** + * gdk_window_add_filter: + * @window: a #GdkWindow + * @function: filter callback + * @data: data to pass to filter callback + * + * Adds an event filter to @window, allowing you to intercept events + * before they reach GDK. This is a low-level operation and makes it + * easy to break GDK and/or GTK+, so you have to know what you're + * doing. Pass %NULL for @window to get all events for all windows, + * instead of events for a specific window. + * + * See gdk_display_add_client_message_filter() if you are interested + * in X ClientMessage events. + **/ +void +gdk_window_add_filter (GdkWindow *window, + GdkFilterFunc function, + gpointer data) +{ + GdkWindowObject *private; + GList *tmp_list; + GdkEventFilter *filter; + + g_return_if_fail (window == NULL || GDK_IS_WINDOW (window)); + + private = (GdkWindowObject*) window; + if (private && GDK_WINDOW_DESTROYED (window)) + return; + + /* Filters are for the native events on the native window, so + ensure there is a native window. */ + if (window) + gdk_window_ensure_native (window); + + if (private) + tmp_list = private->filters; + else + tmp_list = _gdk_default_filters; + + while (tmp_list) + { + filter = (GdkEventFilter *)tmp_list->data; + if ((filter->function == function) && (filter->data == data)) + { + filter->ref_count++; + return; + } + tmp_list = tmp_list->next; + } + + filter = g_new (GdkEventFilter, 1); + filter->function = function; + filter->data = data; + filter->ref_count = 1; + filter->flags = 0; + + if (private) + private->filters = g_list_append (private->filters, filter); + else + _gdk_default_filters = g_list_append (_gdk_default_filters, filter); +} + +/** + * gdk_window_remove_filter: + * @window: a #GdkWindow + * @function: previously-added filter function + * @data: user data for previously-added filter function + * + * Remove a filter previously added with gdk_window_add_filter(). + * + **/ +void +gdk_window_remove_filter (GdkWindow *window, + GdkFilterFunc function, + gpointer data) +{ + GdkWindowObject *private; + GList *tmp_list; + GdkEventFilter *filter; + + g_return_if_fail (window == NULL || GDK_IS_WINDOW (window)); + + private = (GdkWindowObject*) window; + + if (private) + tmp_list = private->filters; + else + tmp_list = _gdk_default_filters; + + while (tmp_list) + { + filter = (GdkEventFilter *)tmp_list->data; + tmp_list = tmp_list->next; + + if ((filter->function == function) && (filter->data == data)) + { + filter->flags |= GDK_EVENT_FILTER_REMOVED; + _gdk_event_filter_unref (window, filter); + + return; + } + } +} + +/** + * gdk_screen_get_toplevel_windows: + * @screen: The #GdkScreen where the toplevels are located. + * + * Obtains a list of all toplevel windows known to GDK on the screen @screen. + * A toplevel window is a child of the root window (see + * gdk_get_default_root_window()). + * + * The returned list should be freed with g_list_free(), but + * its elements need not be freed. + * + * Return value: (transfer container) (element-type GdkWindow): + * list of toplevel windows, free with g_list_free() + * + * Since: 2.2 + **/ +GList * +gdk_screen_get_toplevel_windows (GdkScreen *screen) +{ + GdkWindow * root_window; + GList *new_list = NULL; + GList *tmp_list; + + g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL); + + root_window = gdk_screen_get_root_window (screen); + + tmp_list = ((GdkWindowObject *)root_window)->children; + while (tmp_list) + { + GdkWindowObject *w = tmp_list->data; + + if (w->window_type != GDK_WINDOW_FOREIGN) + new_list = g_list_prepend (new_list, w); + tmp_list = tmp_list->next; + } + + return new_list; +} + +/** + * gdk_window_get_toplevels: + * + * Obtains a list of all toplevel windows known to GDK on the default + * screen (see gdk_screen_get_toplevel_windows()). + * A toplevel window is a child of the root window (see + * gdk_get_default_root_window()). + * + * The returned list should be freed with g_list_free(), but + * its elements need not be freed. + * + * Return value: list of toplevel windows, free with g_list_free() + * + * Deprecated: 2.16: Use gdk_screen_get_toplevel_windows() instead. + */ +GList * +gdk_window_get_toplevels (void) +{ + return gdk_screen_get_toplevel_windows (gdk_screen_get_default ()); +} + +/** + * gdk_window_is_visible: + * @window: a #GdkWindow + * + * Checks whether the window has been mapped (with gdk_window_show() or + * gdk_window_show_unraised()). + * + * Return value: %TRUE if the window is mapped + **/ +gboolean +gdk_window_is_visible (GdkWindow *window) +{ + g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE); + + return GDK_WINDOW_IS_MAPPED (window); +} + +/** + * gdk_window_is_viewable: + * @window: a #GdkWindow + * + * Check if the window and all ancestors of the window are + * mapped. (This is not necessarily "viewable" in the X sense, since + * we only check as far as we have GDK window parents, not to the root + * window.) + * + * Return value: %TRUE if the window is viewable + **/ +gboolean +gdk_window_is_viewable (GdkWindow *window) +{ + GdkWindowObject *private = (GdkWindowObject *)window; + + g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE); + + if (private->destroyed) + return FALSE; + + return private->viewable; +} + +/** + * gdk_window_get_state: + * @window: a #GdkWindow + * + * Gets the bitwise OR of the currently active window state flags, + * from the #GdkWindowState enumeration. + * + * Return value: window state bitfield + **/ +GdkWindowState +gdk_window_get_state (GdkWindow *window) +{ + GdkWindowObject *private = (GdkWindowObject *)window; + + g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE); + + return private->state; +} + + +/* This creates an empty "implicit" paint region for the impl window. + * By itself this does nothing, but real paints to this window + * or children of it can use this pixmap as backing to avoid allocating + * multiple pixmaps for subwindow rendering. When doing so they + * add to the region of the implicit paint region, which will be + * pushed to the window when the implicit paint region is ended. + * Such paints should not copy anything to the window on paint end, but + * should rely on the implicit paint end. + * The implicit paint will be automatically ended if someone draws + * directly to the window or a child window. + */ +static gboolean +gdk_window_begin_implicit_paint (GdkWindow *window, GdkRectangle *rect) +{ + GdkWindowObject *private = (GdkWindowObject *)window; + GdkWindowPaint *paint; + + g_assert (gdk_window_has_impl (private)); + + if (_gdk_native_windows) + return FALSE; /* No need for implicit paints since we can't merge draws anyway */ + + if (GDK_IS_PAINTABLE (private->impl)) + return FALSE; /* Implementation does double buffering */ + + if (private->paint_stack != NULL || + private->implicit_paint != NULL) + return FALSE; /* Don't stack implicit paints */ + + if (private->outstanding_surfaces != 0) + return FALSE; /* May conflict with direct drawing to cairo surface */ + + /* Never do implicit paints for foreign windows, they don't need + * double buffer combination since they have no client side children, + * and creating pixmaps for them is risky since they could disappear + * at any time + */ + if (private->window_type == GDK_WINDOW_FOREIGN) + return FALSE; + + paint = g_new (GdkWindowPaint, 1); + paint->region = gdk_region_new (); /* Empty */ + paint->x_offset = rect->x; + paint->y_offset = rect->y; + paint->uses_implicit = FALSE; + paint->flushed = FALSE; + paint->surface = NULL; + paint->pixmap = + gdk_pixmap_new (window, + MAX (rect->width, 1), MAX (rect->height, 1), -1); + + private->implicit_paint = paint; + + return TRUE; +} + +/* Ensure that all content related to this (sub)window is pushed to the + native region. If there is an active paint then that area is not + pushed, in order to not show partially finished double buffers. */ +static void +gdk_window_flush_implicit_paint (GdkWindow *window) +{ + GdkWindowObject *private = (GdkWindowObject *)window; + GdkWindowObject *impl_window; + GdkWindowPaint *paint; + GdkRegion *region; + GdkGC *tmp_gc; + GSList *list; + + impl_window = gdk_window_get_impl_window (private); + if (impl_window->implicit_paint == NULL) + return; + + paint = impl_window->implicit_paint; + paint->flushed = TRUE; + region = gdk_region_copy (private->clip_region_with_children); + + /* Don't flush active double buffers, as that may show partially done + * rendering */ + for (list = private->paint_stack; list != NULL; list = list->next) + { + GdkWindowPaint *tmp_paint = list->data; + + gdk_region_subtract (region, tmp_paint->region); + } + + gdk_region_offset (region, private->abs_x, private->abs_y); + gdk_region_intersect (region, paint->region); + + if (!GDK_WINDOW_DESTROYED (window) && !gdk_region_empty (region)) + { + /* Remove flushed region from the implicit paint */ + gdk_region_subtract (paint->region, region); + + /* Some regions are valid, push these to window now */ + tmp_gc = _gdk_drawable_get_scratch_gc ((GdkDrawable *)window, FALSE); + _gdk_gc_set_clip_region_internal (tmp_gc, region, TRUE); + gdk_draw_drawable (private->impl, tmp_gc, paint->pixmap, + 0, 0, paint->x_offset, paint->y_offset, -1, -1); + /* Reset clip region of the cached GdkGC */ + gdk_gc_set_clip_region (tmp_gc, NULL); + } + else + gdk_region_destroy (region); +} + +/* Ends an implicit paint, paired with gdk_window_begin_implicit_paint returning TRUE */ +static void +gdk_window_end_implicit_paint (GdkWindow *window) +{ + GdkWindowObject *private = (GdkWindowObject *)window; + GdkWindowPaint *paint; + GdkGC *tmp_gc; + + g_assert (gdk_window_has_impl (private)); + + g_assert (private->implicit_paint != NULL); + + paint = private->implicit_paint; + + private->implicit_paint = NULL; + + if (!GDK_WINDOW_DESTROYED (window) && !gdk_region_empty (paint->region)) + { + /* Some regions are valid, push these to window now */ + tmp_gc = _gdk_drawable_get_scratch_gc ((GdkDrawable *)window, FALSE); + _gdk_gc_set_clip_region_internal (tmp_gc, paint->region, TRUE); + gdk_draw_drawable (private->impl, tmp_gc, paint->pixmap, + 0, 0, paint->x_offset, paint->y_offset, -1, -1); + /* Reset clip region of the cached GdkGC */ + gdk_gc_set_clip_region (tmp_gc, NULL); + } + else + gdk_region_destroy (paint->region); + + g_object_unref (paint->pixmap); + g_free (paint); +} + +/** + * gdk_window_begin_paint_rect: + * @window: a #GdkWindow + * @rectangle: rectangle you intend to draw to + * + * A convenience wrapper around gdk_window_begin_paint_region() which + * creates a rectangular region for you. See + * gdk_window_begin_paint_region() for details. + * + **/ +void +gdk_window_begin_paint_rect (GdkWindow *window, + const GdkRectangle *rectangle) +{ + GdkRegion *region; + + g_return_if_fail (GDK_IS_WINDOW (window)); + + region = gdk_region_rectangle (rectangle); + gdk_window_begin_paint_region (window, region); + gdk_region_destroy (region); +} + +/** + * gdk_window_begin_paint_region: + * @window: a #GdkWindow + * @region: region you intend to draw to + * + * Indicates that you are beginning the process of redrawing @region. + * A backing store (offscreen buffer) large enough to contain @region + * will be created. The backing store will be initialized with the + * background color or background pixmap for @window. Then, all + * drawing operations performed on @window will be diverted to the + * backing store. When you call gdk_window_end_paint(), the backing + * store will be copied to @window, making it visible onscreen. Only + * the part of @window contained in @region will be modified; that is, + * drawing operations are clipped to @region. + * + * The net result of all this is to remove flicker, because the user + * sees the finished product appear all at once when you call + * gdk_window_end_paint(). If you draw to @window directly without + * calling gdk_window_begin_paint_region(), the user may see flicker + * as individual drawing operations are performed in sequence. The + * clipping and background-initializing features of + * gdk_window_begin_paint_region() are conveniences for the + * programmer, so you can avoid doing that work yourself. + * + * When using GTK+, the widget system automatically places calls to + * gdk_window_begin_paint_region() and gdk_window_end_paint() around + * emissions of the expose_event signal. That is, if you're writing an + * expose event handler, you can assume that the exposed area in + * #GdkEventExpose has already been cleared to the window background, + * is already set as the clip region, and already has a backing store. + * Therefore in most cases, application code need not call + * gdk_window_begin_paint_region(). (You can disable the automatic + * calls around expose events on a widget-by-widget basis by calling + * gtk_widget_set_double_buffered().) + * + * If you call this function multiple times before calling the + * matching gdk_window_end_paint(), the backing stores are pushed onto + * a stack. gdk_window_end_paint() copies the topmost backing store + * onscreen, subtracts the topmost region from all other regions in + * the stack, and pops the stack. All drawing operations affect only + * the topmost backing store in the stack. One matching call to + * gdk_window_end_paint() is required for each call to + * gdk_window_begin_paint_region(). + * + **/ +void +gdk_window_begin_paint_region (GdkWindow *window, + const GdkRegion *region) +{ +#ifdef USE_BACKING_STORE + GdkWindowObject *private = (GdkWindowObject *)window; + GdkRectangle clip_box; + GdkWindowPaint *paint, *implicit_paint; + GdkWindowObject *impl_window; + GSList *list; + + g_return_if_fail (GDK_IS_WINDOW (window)); + + if (GDK_WINDOW_DESTROYED (window)) + return; + + if (GDK_IS_PAINTABLE (private->impl)) + { + GdkPaintableIface *iface = GDK_PAINTABLE_GET_IFACE (private->impl); + + if (iface->begin_paint_region) + iface->begin_paint_region ((GdkPaintable*)private->impl, window, region); + + return; + } + + impl_window = gdk_window_get_impl_window (private); + implicit_paint = impl_window->implicit_paint; + + paint = g_new (GdkWindowPaint, 1); + paint->region = gdk_region_copy (region); + paint->region_tag = new_region_tag (); + + gdk_region_intersect (paint->region, private->clip_region_with_children); + gdk_region_get_clipbox (paint->region, &clip_box); + + /* Convert to impl coords */ + gdk_region_offset (paint->region, private->abs_x, private->abs_y); + + /* Mark the region as valid on the implicit paint */ + + if (implicit_paint) + gdk_region_union (implicit_paint->region, paint->region); + + /* Convert back to normal coords */ + gdk_region_offset (paint->region, -private->abs_x, -private->abs_y); + + if (implicit_paint) + { + paint->uses_implicit = TRUE; + paint->pixmap = g_object_ref (implicit_paint->pixmap); + paint->x_offset = -private->abs_x + implicit_paint->x_offset; + paint->y_offset = -private->abs_y + implicit_paint->y_offset; + } + else + { + paint->uses_implicit = FALSE; + paint->x_offset = clip_box.x; + paint->y_offset = clip_box.y; + paint->pixmap = + gdk_pixmap_new (window, + MAX (clip_box.width, 1), MAX (clip_box.height, 1), -1); + } + + paint->surface = _gdk_drawable_ref_cairo_surface (paint->pixmap); + + if (paint->surface) + cairo_surface_set_device_offset (paint->surface, + -paint->x_offset, -paint->y_offset); + + for (list = private->paint_stack; list != NULL; list = list->next) + { + GdkWindowPaint *tmp_paint = list->data; + + gdk_region_subtract (tmp_paint->region, paint->region); + } + + private->paint_stack = g_slist_prepend (private->paint_stack, paint); + + if (!gdk_region_empty (paint->region)) + { + gdk_window_clear_backing_region (window, + paint->region); + } + +#endif /* USE_BACKING_STORE */ +} + +static void +setup_redirect_clip (GdkWindow *window, + GdkGC *gc, + int *x_offset_out, + int *y_offset_out) +{ + GdkWindowObject *private = (GdkWindowObject *)window; + GdkRegion *visible_region; + GdkRectangle dest_rect; + GdkRegion *tmpreg; + GdkWindow *toplevel; + int x_offset, y_offset; + + toplevel = GDK_WINDOW (private->redirect->redirected); + + /* Get the clip region for gc clip rect + window hierarchy in + window relative coords */ + visible_region = + _gdk_window_calculate_full_clip_region (window, toplevel, + TRUE, + &x_offset, + &y_offset); + + /* Compensate for the source pos/size */ + x_offset -= private->redirect->src_x; + y_offset -= private->redirect->src_y; + dest_rect.x = -x_offset; + dest_rect.y = -y_offset; + dest_rect.width = private->redirect->width; + dest_rect.height = private->redirect->height; + tmpreg = gdk_region_rectangle (&dest_rect); + gdk_region_intersect (visible_region, tmpreg); + gdk_region_destroy (tmpreg); + + /* Compensate for the dest pos */ + x_offset += private->redirect->dest_x; + y_offset += private->redirect->dest_y; + + gdk_gc_set_clip_region (gc, visible_region); /* This resets clip origin! */ + + /* offset clip and tiles from window coords to pixmaps coords */ + gdk_gc_offset (gc, -x_offset, -y_offset); + + gdk_region_destroy (visible_region); + + *x_offset_out = x_offset; + *y_offset_out = y_offset; +} + +/** + * gdk_window_end_paint: + * @window: a #GdkWindow + * + * Indicates that the backing store created by the most recent call to + * gdk_window_begin_paint_region() should be copied onscreen and + * deleted, leaving the next-most-recent backing store or no backing + * store at all as the active paint region. See + * gdk_window_begin_paint_region() for full details. It is an error to + * call this function without a matching + * gdk_window_begin_paint_region() first. + * + **/ +void +gdk_window_end_paint (GdkWindow *window) +{ +#ifdef USE_BACKING_STORE + GdkWindowObject *private = (GdkWindowObject *)window; + GdkWindowObject *composited; + GdkWindowPaint *paint; + GdkGC *tmp_gc; + GdkRectangle clip_box; + gint x_offset, y_offset; + GdkRegion *full_clip; + + g_return_if_fail (GDK_IS_WINDOW (window)); + + if (GDK_WINDOW_DESTROYED (window)) + return; + + if (GDK_IS_PAINTABLE (private->impl)) + { + GdkPaintableIface *iface = GDK_PAINTABLE_GET_IFACE (private->impl); + + if (iface->end_paint) + iface->end_paint ((GdkPaintable*)private->impl); + return; + } + + if (private->paint_stack == NULL) + { + g_warning (G_STRLOC": no preceding call to gdk_window_begin_paint_region(), see documentation"); + return; + } + + paint = private->paint_stack->data; + + private->paint_stack = g_slist_delete_link (private->paint_stack, + private->paint_stack); + + gdk_region_get_clipbox (paint->region, &clip_box); + + tmp_gc = _gdk_drawable_get_scratch_gc (window, FALSE); + + x_offset = -private->abs_x; + y_offset = -private->abs_y; + + if (!paint->uses_implicit) + { + gdk_window_flush_outstanding_moves (window); + + full_clip = gdk_region_copy (private->clip_region_with_children); + gdk_region_intersect (full_clip, paint->region); + _gdk_gc_set_clip_region_internal (tmp_gc, full_clip, TRUE); /* Takes ownership of full_clip */ + gdk_gc_set_clip_origin (tmp_gc, - x_offset, - y_offset); + gdk_draw_drawable (private->impl, tmp_gc, paint->pixmap, + clip_box.x - paint->x_offset, + clip_box.y - paint->y_offset, + clip_box.x - x_offset, clip_box.y - y_offset, + clip_box.width, clip_box.height); + } + + if (private->redirect) + { + int x_offset, y_offset; + + /* TODO: Should also use paint->region for clipping */ + setup_redirect_clip (window, tmp_gc, &x_offset, &y_offset); + gdk_draw_drawable (private->redirect->pixmap, tmp_gc, paint->pixmap, + clip_box.x - paint->x_offset, + clip_box.y - paint->y_offset, + clip_box.x + x_offset, + clip_box.y + y_offset, + clip_box.width, clip_box.height); + } + + /* Reset clip region of the cached GdkGC */ + gdk_gc_set_clip_region (tmp_gc, NULL); + + cairo_surface_destroy (paint->surface); + g_object_unref (paint->pixmap); + gdk_region_destroy (paint->region); + g_free (paint); + + /* find a composited window in our hierarchy to signal its + * parent to redraw, calculating the clip box as we go... + * + * stop if parent becomes NULL since then we'd have nowhere + * to draw (ie: 'composited' will always be non-NULL here). + */ + for (composited = private; + composited->parent; + composited = composited->parent) + { + int width, height; + + gdk_drawable_get_size (GDK_DRAWABLE (composited->parent), + &width, &height); + + clip_box.x += composited->x; + clip_box.y += composited->y; + clip_box.width = MIN (clip_box.width, width - clip_box.x); + clip_box.height = MIN (clip_box.height, height - clip_box.y); + + if (composited->composited) + { + gdk_window_invalidate_rect (GDK_WINDOW (composited->parent), + &clip_box, FALSE); + break; + } + } +#endif /* USE_BACKING_STORE */ +} + +static void +gdk_window_free_paint_stack (GdkWindow *window) +{ + GdkWindowObject *private = (GdkWindowObject *)window; + + if (private->paint_stack) + { + GSList *tmp_list = private->paint_stack; + + while (tmp_list) + { + GdkWindowPaint *paint = tmp_list->data; + + if (tmp_list == private->paint_stack) + g_object_unref (paint->pixmap); + + gdk_region_destroy (paint->region); + g_free (paint); + + tmp_list = tmp_list->next; + } + + g_slist_free (private->paint_stack); + private->paint_stack = NULL; + } +} + +static void +do_move_region_bits_on_impl (GdkWindowObject *impl_window, + GdkRegion *dest_region, /* In impl window coords */ + int dx, int dy) +{ + GdkGC *tmp_gc; + GdkRectangle copy_rect; + GdkWindowObject *private; + GdkWindowImplIface *impl_iface; + + /* We need to get data from subwindows here, because we might have + * shaped a native window over the moving region (with bg none, + * so the pixels are still there). In fact we might need to get data + * from overlapping native window that are not children of this window, + * so we copy from the toplevel with INCLUDE_INFERIORS. + */ + private = impl_window; + while (!gdk_window_is_toplevel (private) && + !private->composited && + gdk_drawable_get_visual ((GdkDrawable *) private) == gdk_drawable_get_visual ((GdkDrawable *) private->parent)) + { + dx -= private->parent->abs_x + private->x; + dy -= private->parent->abs_y + private->y; + private = gdk_window_get_impl_window (private->parent); + } + tmp_gc = _gdk_drawable_get_subwindow_scratch_gc ((GdkWindow *)private); + + gdk_region_get_clipbox (dest_region, ©_rect); + gdk_gc_set_clip_region (tmp_gc, dest_region); + + /* The region area is moved and we queue translations for all expose events + to the source area that were sent prior to the copy */ + gdk_region_offset (dest_region, -dx, -dy); /* Move to source region */ + impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl); + + impl_iface->queue_translation ((GdkWindow *)impl_window, + tmp_gc, + dest_region, dx, dy); + + gdk_draw_drawable (impl_window->impl, + tmp_gc, + private->impl, + copy_rect.x-dx, copy_rect.y-dy, + copy_rect.x, copy_rect.y, + copy_rect.width, copy_rect.height); + gdk_gc_set_clip_region (tmp_gc, NULL); +} + +static GdkWindowRegionMove * +gdk_window_region_move_new (GdkRegion *region, + int dx, int dy) +{ + GdkWindowRegionMove *move; + + move = g_slice_new (GdkWindowRegionMove); + move->dest_region = gdk_region_copy (region); + move->dx = dx; + move->dy = dy; + + return move; +} + +static void +gdk_window_region_move_free (GdkWindowRegionMove *move) +{ + gdk_region_destroy (move->dest_region); + g_slice_free (GdkWindowRegionMove, move); +} + +static void +append_move_region (GdkWindowObject *impl_window, + GdkRegion *new_dest_region, + int dx, int dy) +{ + GdkWindowRegionMove *move, *old_move; + GdkRegion *new_total_region, *old_total_region; + GdkRegion *source_overlaps_destination; + GdkRegion *non_overwritten; + gboolean added_move; + GList *l, *prev; + + if (gdk_region_empty (new_dest_region)) + return; + + /* In principle this could just append the move to the list of outstanding + moves that will be replayed before drawing anything when we're handling + exposes. However, we'd like to do a bit better since its commonly the case + that we get multiple copies where A is copied to B and then B is copied + to C, and we'd like to express this as a simple copy A to C operation. */ + + /* We approach this by taking the new move and pushing it ahead of moves + starting at the end of the list and stopping when its not safe to do so. + It's not safe to push past a move if either the source of the new move + is in the destination of the old move, or if the destination of the new + move is in the source of the new move, or if the destination of the new + move overlaps the destination of the old move. We simplify this by + just comparing the total regions (src + dest) */ + new_total_region = gdk_region_copy (new_dest_region); + gdk_region_offset (new_total_region, -dx, -dy); + gdk_region_union (new_total_region, new_dest_region); + + added_move = FALSE; + for (l = g_list_last (impl_window->outstanding_moves); l != NULL; l = prev) + { + prev = l->prev; + old_move = l->data; + + old_total_region = gdk_region_copy (old_move->dest_region); + gdk_region_offset (old_total_region, -old_move->dx, -old_move->dy); + gdk_region_union (old_total_region, old_move->dest_region); + + gdk_region_intersect (old_total_region, new_total_region); + /* If these regions intersect then its not safe to push the + new region before the old one */ + if (!gdk_region_empty (old_total_region)) + { + /* The area where the new moves source overlaps the old ones + destination */ + source_overlaps_destination = gdk_region_copy (new_dest_region); + gdk_region_offset (source_overlaps_destination, -dx, -dy); + gdk_region_intersect (source_overlaps_destination, old_move->dest_region); + gdk_region_offset (source_overlaps_destination, dx, dy); + + /* We can do all sort of optimizations here, but to do things safely it becomes + quite complicated. However, a very common case is that you copy something first, + then copy all that or a subset of it to a new location (i.e. if you scroll twice + in the same direction). We'd like to detect this case and optimize it to one + copy. */ + if (gdk_region_equal (source_overlaps_destination, new_dest_region)) + { + /* This means we might be able to replace the old move and the new one + with the new one read from the old ones source, and a second copy of + the non-overwritten parts of the old move. However, such a split + is only valid if the source in the old move isn't overwritten + by the destination of the new one */ + + /* the new destination of old move if split is ok: */ + non_overwritten = gdk_region_copy (old_move->dest_region); + gdk_region_subtract (non_overwritten, new_dest_region); + /* move to source region */ + gdk_region_offset (non_overwritten, -old_move->dx, -old_move->dy); + + gdk_region_intersect (non_overwritten, new_dest_region); + if (gdk_region_empty (non_overwritten)) + { + added_move = TRUE; + move = gdk_window_region_move_new (new_dest_region, + dx + old_move->dx, + dy + old_move->dy); + + impl_window->outstanding_moves = + g_list_insert_before (impl_window->outstanding_moves, + l, move); + gdk_region_subtract (old_move->dest_region, new_dest_region); + } + gdk_region_destroy (non_overwritten); + } + + gdk_region_destroy (source_overlaps_destination); + gdk_region_destroy (old_total_region); + break; + } + gdk_region_destroy (old_total_region); + } + + gdk_region_destroy (new_total_region); + + if (!added_move) + { + move = gdk_window_region_move_new (new_dest_region, dx, dy); + + if (l == NULL) + impl_window->outstanding_moves = + g_list_prepend (impl_window->outstanding_moves, + move); + else + impl_window->outstanding_moves = + g_list_insert_before (impl_window->outstanding_moves, + l->next, move); + } +} + +/* Moves bits and update area by dx/dy in impl window. + Takes ownership of region to avoid copy (because we may change it) */ +static void +move_region_on_impl (GdkWindowObject *impl_window, + GdkRegion *region, /* In impl window coords */ + int dx, int dy) +{ + if ((dx == 0 && dy == 0) || + gdk_region_empty (region)) + { + gdk_region_destroy (region); + return; + } + + g_assert (impl_window == gdk_window_get_impl_window (impl_window)); + + /* Move any old invalid regions in the copy source area by dx/dy */ + if (impl_window->update_area) + { + GdkRegion *update_area; + + update_area = gdk_region_copy (region); + + /* Convert from target to source */ + gdk_region_offset (update_area, -dx, -dy); + gdk_region_intersect (update_area, impl_window->update_area); + /* We only copy the area, so keep the old update area invalid. + It would be safe to remove it too, as code that uses + move_region_on_impl generally also invalidate the source + area. However, it would just use waste cycles. */ + + /* Convert back */ + gdk_region_offset (update_area, dx, dy); + gdk_region_union (impl_window->update_area, update_area); + + /* This area of the destination is now invalid, + so no need to copy to it. */ + gdk_region_subtract (region, update_area); + + gdk_region_destroy (update_area); + } + + /* If we're currently exposing this window, don't copy to this + destination, as it will be overdrawn when the expose is done, + instead invalidate it and repaint later. */ + if (impl_window->implicit_paint) + { + GdkWindowPaint *implicit_paint = impl_window->implicit_paint; + GdkRegion *exposing; + + exposing = gdk_region_copy (implicit_paint->region); + gdk_region_intersect (exposing, region); + gdk_region_subtract (region, exposing); + + impl_window_add_update_area (impl_window, exposing); + gdk_region_destroy (exposing); + } + + if (impl_window->outstanding_surfaces == 0) /* Enable flicker free handling of moves. */ + append_move_region (impl_window, region, dx, dy); + else + do_move_region_bits_on_impl (impl_window, + region, dx, dy); + + gdk_region_destroy (region); +} + +/* Flushes all outstanding changes to the window, call this + * before drawing directly to the window (i.e. outside a begin/end_paint pair). + */ +static void +gdk_window_flush_outstanding_moves (GdkWindow *window) +{ + GdkWindowObject *private; + GdkWindowObject *impl_window; + GdkWindowRegionMove *move; + + private = (GdkWindowObject *) window; + + impl_window = gdk_window_get_impl_window (private); + + while (impl_window->outstanding_moves) + { + move = impl_window->outstanding_moves->data; + impl_window->outstanding_moves = g_list_delete_link (impl_window->outstanding_moves, + impl_window->outstanding_moves); + + do_move_region_bits_on_impl (impl_window, + move->dest_region, move->dx, move->dy); + + gdk_window_region_move_free (move); + } +} + +/** + * gdk_window_flush: + * @window: a #GdkWindow + * + * Flush all outstanding cached operations on a window, leaving the + * window in a state which reflects all that has been drawn before. + * + * Gdk uses multiple kinds of caching to get better performance and + * nicer drawing. For instance, during exposes all paints to a window + * using double buffered rendering are keep on a pixmap until the last + * window has been exposed. It also delays window moves/scrolls until + * as long as possible until next update to avoid tearing when moving + * windows. + * + * Normally this should be completely invisible to applications, as + * we automatically flush the windows when required, but this might + * be needed if you for instance mix direct native drawing with + * gdk drawing. For Gtk widgets that don't use double buffering this + * will be called automatically before sending the expose event. + * + * Since: 2.18 + **/ +void +gdk_window_flush (GdkWindow *window) +{ + gdk_window_flush_outstanding_moves (window); + gdk_window_flush_implicit_paint (window); +} + +/* If we're about to move/resize or otherwise change the + * hierarchy of a client side window in an impl and we're + * called from an expose event handler then we need to + * flush any already painted parts of the implicit paint + * that are not part of the current paint, as these may + * be used when scrolling or may overdraw the changes + * caused by the hierarchy change. + */ +static void +gdk_window_flush_if_exposing (GdkWindow *window) +{ + GdkWindowObject *private; + GdkWindowObject *impl_window; + + private = (GdkWindowObject *) window; + impl_window = gdk_window_get_impl_window (private); + + /* If we're in an implicit paint (i.e. in an expose handler, flush + all the already finished exposes to get things to an uptodate state. */ + if (impl_window->implicit_paint) + gdk_window_flush (window); +} + + +static void +gdk_window_flush_recursive_helper (GdkWindowObject *window, + GdkWindow *impl) +{ + GdkWindowObject *child; + GList *l; + + for (l = window->children; l != NULL; l = l->next) + { + child = l->data; + + if (child->impl == impl) + /* Same impl, ignore */ + gdk_window_flush_recursive_helper (child, impl); + else + gdk_window_flush_recursive (child); + } +} + +static void +gdk_window_flush_recursive (GdkWindowObject *window) +{ + gdk_window_flush ((GdkWindow *)window); + gdk_window_flush_recursive_helper (window, window->impl); +} + +static void +gdk_window_get_offsets (GdkWindow *window, + gint *x_offset, + gint *y_offset) +{ + GdkWindowObject *private = (GdkWindowObject *)window; + + if (private->paint_stack) + { + GdkWindowPaint *paint = private->paint_stack->data; + *x_offset = paint->x_offset; + *y_offset = paint->y_offset; + } + else + { + *x_offset = -private->abs_x; + *y_offset = -private->abs_y; + } +} + +/** + * gdk_window_get_internal_paint_info: + * @window: a #GdkWindow + * @real_drawable: (out): location to store the drawable to which drawing should be + * done. + * @x_offset: (out): location to store the X offset between coordinates in @window, + * and the underlying window system primitive coordinates for + * *@real_drawable. + * @y_offset: (out): location to store the Y offset between coordinates in @window, + * and the underlying window system primitive coordinates for + * *@real_drawable. + * + * If you bypass the GDK layer and use windowing system primitives to + * draw directly onto a #GdkWindow, then you need to deal with two + * details: there may be an offset between GDK coordinates and windowing + * system coordinates, and GDK may have redirected drawing to a offscreen + * pixmap as the result of a gdk_window_begin_paint_region() calls. + * This function allows retrieving the information you need to compensate + * for these effects. + * + * This function exposes details of the GDK implementation, and is thus + * likely to change in future releases of GDK. + **/ +void +gdk_window_get_internal_paint_info (GdkWindow *window, + GdkDrawable **real_drawable, + gint *x_offset, + gint *y_offset) +{ + gint x_off, y_off; + + GdkWindowObject *private; + + g_return_if_fail (GDK_IS_WINDOW (window)); + + private = (GdkWindowObject *)window; + + if (real_drawable) + { + if (private->paint_stack) + { + GdkWindowPaint *paint = private->paint_stack->data; + *real_drawable = paint->pixmap; + } + else + { + /* This means you're probably gonna be doing some weird shit + directly to the window, so we flush all outstanding stuff */ + gdk_window_flush (window); + *real_drawable = window; + } + } + + gdk_window_get_offsets (window, &x_off, &y_off); + + if (x_offset) + *x_offset = x_off; + if (y_offset) + *y_offset = y_off; +} + +static GdkDrawable * +start_draw_helper (GdkDrawable *drawable, + GdkGC *gc, + gint *x_offset_out, + gint *y_offset_out) +{ + GdkWindowObject *private = (GdkWindowObject *)drawable; + gint x_offset, y_offset; + GdkDrawable *impl; + gint old_clip_x = gc->clip_x_origin; + gint old_clip_y = gc->clip_y_origin; + GdkRegion *clip; + guint32 clip_region_tag; + GdkWindowPaint *paint; + + paint = NULL; + if (private->paint_stack) + paint = private->paint_stack->data; + + if (paint) + { + x_offset = paint->x_offset; + y_offset = paint->y_offset; + } + else + { + x_offset = -private->abs_x; + y_offset = -private->abs_y; + } + + if (x_offset != 0 || y_offset != 0) + { + gdk_gc_set_clip_origin (gc, + old_clip_x - x_offset, + old_clip_y - y_offset); + gdk_gc_set_ts_origin (gc, + gc->ts_x_origin - x_offset, + gc->ts_y_origin - y_offset); + } + + *x_offset_out = x_offset; + *y_offset_out = y_offset; + + /* Add client side window clip region to gc */ + clip = NULL; + if (paint) + { + /* Only need clipping if using implicit paint, otherwise + the pixmap is clipped when copying to the window in end_paint */ + if (paint->uses_implicit) + { + /* This includes the window clip */ + clip = paint->region; + } + clip_region_tag = paint->region_tag; + + /* After having set up the drawable clip rect on a GC we need to make sure + * that we draw to th the impl, otherwise the pixmap code will reset the + * drawable clip. */ + impl = ((GdkPixmapObject *)(paint->pixmap))->impl; + } + else + { + /* Drawing directly to the window, flush anything outstanding to + guarantee ordering. */ + gdk_window_flush ((GdkWindow *)drawable); + + /* Don't clip when drawing to root or all native */ + if (!_gdk_native_windows && private->window_type != GDK_WINDOW_ROOT) + { + if (_gdk_gc_get_subwindow (gc) == GDK_CLIP_BY_CHILDREN) + clip = private->clip_region_with_children; + else + clip = private->clip_region; + } + clip_region_tag = private->clip_tag; + impl = private->impl; + } + + if (clip) + _gdk_gc_add_drawable_clip (gc, + clip_region_tag, clip, + /* If there was a clip origin set appart from the + * window offset, need to take that into + * consideration */ + -old_clip_x, -old_clip_y); + + return impl; +} + +#define BEGIN_DRAW \ + { \ + GdkDrawable *impl; \ + gint x_offset, y_offset; \ + gint old_clip_x = gc->clip_x_origin; \ + gint old_clip_y = gc->clip_y_origin; \ + gint old_ts_x = gc->ts_x_origin; \ + gint old_ts_y = gc->ts_y_origin; \ + impl = start_draw_helper (drawable, gc, \ + &x_offset, &y_offset); + +#define END_DRAW \ + if (x_offset != 0 || y_offset != 0) \ + { \ + gdk_gc_set_clip_origin (gc, old_clip_x, old_clip_y); \ + gdk_gc_set_ts_origin (gc, old_ts_x, old_ts_y); \ + } \ + } + +#define BEGIN_DRAW_MACRO \ + { + +#define END_DRAW_MACRO \ + } + +typedef struct +{ + GdkDrawable *drawable; + GdkGC *gc; + + gint x_offset; + gint y_offset; + + gint clip_x; + gint clip_y; + gint ts_x; + gint ts_y; +} DirectDrawInfo; + +GdkDrawable * +_gdk_drawable_begin_direct_draw (GdkDrawable *drawable, + GdkGC *gc, + gpointer *priv_data, + gint *x_offset_out, + gint *y_offset_out) +{ + GdkDrawable *out_impl = NULL; + + g_return_val_if_fail (priv_data != NULL, NULL); + + *priv_data = NULL; + + if (GDK_IS_PIXMAP (drawable)) + { + /* We bypass the GdkPixmap functions, so do this ourself */ + _gdk_gc_remove_drawable_clip (gc); + + out_impl = drawable; + + *x_offset_out = 0; + *y_offset_out = 0; + } + else + { + DirectDrawInfo *priv; + + if (GDK_WINDOW_DESTROYED (drawable)) + return NULL; + + BEGIN_DRAW; + + if (impl == NULL) + return NULL; + + out_impl = impl; + + *x_offset_out = x_offset; + *y_offset_out = y_offset; + + priv = g_new (DirectDrawInfo, 1); + + priv->drawable = impl; + priv->gc = gc; + + priv->x_offset = x_offset; + priv->y_offset = y_offset; + priv->clip_x = old_clip_x; + priv->clip_y = old_clip_y; + priv->ts_x = old_ts_x; + priv->ts_y = old_ts_y; + + *priv_data = (gpointer) priv; + + END_DRAW_MACRO; + } + + return out_impl; +} + +void +_gdk_drawable_end_direct_draw (gpointer priv_data) +{ + DirectDrawInfo *priv; + GdkGC *gc; + + /* Its a GdkPixmap or the call to _gdk_drawable_begin_direct_draw failed. */ + if (priv_data == NULL) + return; + + priv = priv_data; + gc = priv->gc; + + /* This is only for GdkWindows - if GdkPixmaps need any handling here in + * the future, then we should keep track of what type of drawable it is in + * DirectDrawInfo. */ + BEGIN_DRAW_MACRO; + + { + gint x_offset = priv->x_offset; + gint y_offset = priv->y_offset; + gint old_clip_x = priv->clip_x; + gint old_clip_y = priv->clip_y; + gint old_ts_x = priv->ts_x; + gint old_ts_y = priv->ts_y; + + END_DRAW; + } + + g_free (priv_data); +} + +static GdkGC * +gdk_window_create_gc (GdkDrawable *drawable, + GdkGCValues *values, + GdkGCValuesMask mask) +{ + g_return_val_if_fail (GDK_IS_WINDOW (drawable), NULL); + + if (GDK_WINDOW_DESTROYED (drawable)) + return NULL; + + return gdk_gc_new_with_values (((GdkWindowObject *) drawable)->impl, + values, mask); +} + +static void +gdk_window_draw_rectangle (GdkDrawable *drawable, + GdkGC *gc, + gboolean filled, + gint x, + gint y, + gint width, + gint height) +{ + if (GDK_WINDOW_DESTROYED (drawable)) + return; + + BEGIN_DRAW; + gdk_draw_rectangle (impl, gc, filled, + x - x_offset, y - y_offset, width, height); + END_DRAW; +} + +static void +gdk_window_draw_arc (GdkDrawable *drawable, + GdkGC *gc, + gboolean filled, + gint x, + gint y, + gint width, + gint height, + gint angle1, + gint angle2) +{ + if (GDK_WINDOW_DESTROYED (drawable)) + return; + + BEGIN_DRAW; + gdk_draw_arc (impl, gc, filled, + x - x_offset, y - y_offset, + width, height, angle1, angle2); + END_DRAW; +} + +static void +gdk_window_draw_polygon (GdkDrawable *drawable, + GdkGC *gc, + gboolean filled, + GdkPoint *points, + gint npoints) +{ + GdkPoint *new_points; + + if (GDK_WINDOW_DESTROYED (drawable)) + return; + + BEGIN_DRAW; + + if (x_offset != 0 || y_offset != 0) + { + int i; + + new_points = g_new (GdkPoint, npoints); + for (i=0; iimpl)->get_source_drawable) + return GDK_DRAWABLE_GET_CLASS (private->impl)->get_source_drawable (private->impl); + + return drawable; +} + +static GdkDrawable * +gdk_window_get_composite_drawable (GdkDrawable *drawable, + gint x, + gint y, + gint width, + gint height, + gint *composite_x_offset, + gint *composite_y_offset) +{ + GdkWindowObject *private = (GdkWindowObject *)drawable; + GSList *list; + GdkPixmap *tmp_pixmap; + GdkRectangle rect; + GdkGC *tmp_gc; + gboolean overlap_buffer; + GdkDrawable *source; + GdkWindowObject *impl_window; + GdkWindowPaint *implicit_paint; + + *composite_x_offset = -private->abs_x; + *composite_y_offset = -private->abs_y; + + if ((GDK_IS_WINDOW (drawable) && GDK_WINDOW_DESTROYED (drawable))) + return g_object_ref (_gdk_drawable_get_source_drawable (drawable)); + + /* See if any buffered part is overlapping the part we want + * to get + */ + rect.x = x; + rect.y = y; + rect.width = width; + rect.height = height; + + overlap_buffer = FALSE; + + for (list = private->paint_stack; list != NULL; list = list->next) + { + GdkWindowPaint *paint = list->data; + GdkOverlapType overlap; + + overlap = gdk_region_rect_in (paint->region, &rect); + + if (overlap == GDK_OVERLAP_RECTANGLE_IN) + { + *composite_x_offset = paint->x_offset; + *composite_y_offset = paint->y_offset; + + return g_object_ref (paint->pixmap); + } + else if (overlap == GDK_OVERLAP_RECTANGLE_PART) + { + overlap_buffer = TRUE; + break; + } + } + + impl_window = gdk_window_get_impl_window (private); + implicit_paint = impl_window->implicit_paint; + if (implicit_paint) + { + GdkOverlapType overlap; + + rect.x += private->abs_x; + rect.y += private->abs_y; + + overlap = gdk_region_rect_in (implicit_paint->region, &rect); + if (overlap == GDK_OVERLAP_RECTANGLE_IN) + { + *composite_x_offset = -private->abs_x + implicit_paint->x_offset; + *composite_y_offset = -private->abs_y + implicit_paint->y_offset; + + return g_object_ref (implicit_paint->pixmap); + } + else if (overlap == GDK_OVERLAP_RECTANGLE_PART) + overlap_buffer = TRUE; + } + + if (!overlap_buffer) + return g_object_ref (_gdk_drawable_get_source_drawable (drawable)); + + tmp_pixmap = gdk_pixmap_new (drawable, width, height, -1); + tmp_gc = _gdk_drawable_get_scratch_gc (tmp_pixmap, FALSE); + + source = _gdk_drawable_get_source_drawable (drawable); + + /* Copy the current window contents */ + gdk_draw_drawable (tmp_pixmap, + tmp_gc, + GDK_WINDOW_OBJECT (source)->impl, + x - *composite_x_offset, + y - *composite_y_offset, + 0, 0, + width, height); + + /* paint the backing stores */ + if (implicit_paint) + { + GdkWindowPaint *paint = list->data; + + gdk_gc_set_clip_region (tmp_gc, paint->region); + gdk_gc_set_clip_origin (tmp_gc, -x - paint->x_offset, -y - paint->y_offset); + + gdk_draw_drawable (tmp_pixmap, tmp_gc, paint->pixmap, + x - paint->x_offset, + y - paint->y_offset, + 0, 0, width, height); + } + + for (list = private->paint_stack; list != NULL; list = list->next) + { + GdkWindowPaint *paint = list->data; + + if (paint->uses_implicit) + continue; /* We already copied this above */ + + gdk_gc_set_clip_region (tmp_gc, paint->region); + gdk_gc_set_clip_origin (tmp_gc, -x, -y); + + gdk_draw_drawable (tmp_pixmap, tmp_gc, paint->pixmap, + x - paint->x_offset, + y - paint->y_offset, + 0, 0, width, height); + } + + /* Reset clip region of the cached GdkGC */ + gdk_gc_set_clip_region (tmp_gc, NULL); + + /* Set these to location of tmp_pixmap within the window */ + *composite_x_offset = x; + *composite_y_offset = y; + + return tmp_pixmap; +} + +static GdkRegion* +gdk_window_get_clip_region (GdkDrawable *drawable) +{ + GdkWindowObject *private = (GdkWindowObject *)drawable; + GdkRegion *result; + + result = gdk_region_copy (private->clip_region); + + if (private->paint_stack) + { + GdkRegion *paint_region = gdk_region_new (); + GSList *tmp_list = private->paint_stack; + + while (tmp_list) + { + GdkWindowPaint *paint = tmp_list->data; + + gdk_region_union (paint_region, paint->region); + + tmp_list = tmp_list->next; + } + + gdk_region_intersect (result, paint_region); + gdk_region_destroy (paint_region); + } + + return result; +} + +static GdkRegion* +gdk_window_get_visible_region (GdkDrawable *drawable) +{ + GdkWindowObject *private = (GdkWindowObject*) drawable; + + return gdk_region_copy (private->clip_region); +} + +static void +gdk_window_draw_drawable (GdkDrawable *drawable, + GdkGC *gc, + GdkPixmap *src, + gint xsrc, + gint ysrc, + gint xdest, + gint ydest, + gint width, + gint height, + GdkDrawable *original_src) +{ + GdkWindowObject *private = (GdkWindowObject *)drawable; + + if (GDK_WINDOW_DESTROYED (drawable)) + return; + + BEGIN_DRAW; + + /* Call the method directly to avoid getting the composite drawable again */ + GDK_DRAWABLE_GET_CLASS (impl)->draw_drawable_with_src (impl, gc, + src, + xsrc, ysrc, + xdest - x_offset, + ydest - y_offset, + width, height, + original_src); + + if (!private->paint_stack) + { + /* We might have drawn from an obscured part of a client + side window, if so we need to send graphics exposures */ + if (_gdk_gc_get_exposures (gc) && + GDK_IS_WINDOW (original_src)) + { + GdkRegion *exposure_region; + GdkRegion *clip; + GdkRectangle r; + + r.x = xdest; + r.y = ydest; + r.width = width; + r.height = height; + exposure_region = gdk_region_rectangle (&r); + + if (_gdk_gc_get_subwindow (gc) == GDK_CLIP_BY_CHILDREN) + clip = private->clip_region_with_children; + else + clip = private->clip_region; + gdk_region_intersect (exposure_region, clip); + + _gdk_gc_remove_drawable_clip (gc); + clip = _gdk_gc_get_clip_region (gc); + if (clip) + { + gdk_region_offset (exposure_region, + old_clip_x, + old_clip_y); + gdk_region_intersect (exposure_region, clip); + gdk_region_offset (exposure_region, + -old_clip_x, + -old_clip_y); + } + + /* Note: We don't clip by the clip mask if set, so this + may invalidate to much */ + + /* Remove the area that is correctly copied from the src. + * Note that xsrc/ysrc has been corrected for abs_x/y offsets already, + * which need to be undone */ + clip = gdk_drawable_get_visible_region (original_src); + gdk_region_offset (clip, + xdest - (xsrc - GDK_WINDOW_OBJECT (original_src)->abs_x), + ydest - (ysrc - GDK_WINDOW_OBJECT (original_src)->abs_y)); + gdk_region_subtract (exposure_region, clip); + gdk_region_destroy (clip); + + gdk_window_invalidate_region_full (GDK_WINDOW (private), + exposure_region, + _gdk_gc_get_subwindow (gc) == GDK_INCLUDE_INFERIORS, + CLEAR_BG_ALL); + + gdk_region_destroy (exposure_region); + } + } + + END_DRAW; +} + +static void +gdk_window_draw_points (GdkDrawable *drawable, + GdkGC *gc, + GdkPoint *points, + gint npoints) +{ + GdkPoint *new_points; + + if (GDK_WINDOW_DESTROYED (drawable)) + return; + + BEGIN_DRAW; + + if (x_offset != 0 || y_offset != 0) + { + gint i; + + new_points = g_new (GdkPoint, npoints); + for (i=0; ibg_pixmap == GDK_PARENT_RELATIVE_BG && private->parent) + { + GdkWindowPaint tmp_paint; + + tmp_paint = *paint; + tmp_paint.x_offset += private->x; + tmp_paint.y_offset += private->y; + + x_offset_cairo += private->x; + y_offset_cairo += private->y; + + setup_backing_rect_method (method, GDK_WINDOW (private->parent), &tmp_paint, x_offset_cairo, y_offset_cairo); + } + else if (private->bg_pixmap && + private->bg_pixmap != GDK_PARENT_RELATIVE_BG && + private->bg_pixmap != GDK_NO_BG) + { +/* This is a workaround for https://bugs.freedesktop.org/show_bug.cgi?id=4320. + * In it, using a pixmap as a repeating pattern in Cairo, and painting it to a + * pixmap destination surface, can be very slow (on the order of seconds for a + * whole-screen copy). The workaround is to use pretty much the same code that + * we used in GTK+ 2.6 (pre-Cairo), which clears the double-buffer pixmap with + * a tiled GC XFillRectangle(). + */ + +/* Actually computing this flag is left as an exercise for the reader */ +#if defined (G_OS_UNIX) +# define GDK_CAIRO_REPEAT_IS_FAST 0 +#else +# define GDK_CAIRO_REPEAT_IS_FAST 1 +#endif + +#if GDK_CAIRO_REPEAT_IS_FAST + cairo_surface_t *surface = _gdk_drawable_ref_cairo_surface (private->bg_pixmap); + cairo_pattern_t *pattern = cairo_pattern_create_for_surface (surface); + cairo_surface_destroy (surface); + + if (x_offset_cairo != 0 || y_offset_cairo != 0) + { + cairo_matrix_t matrix; + cairo_matrix_init_translate (&matrix, x_offset_cairo, y_offset_cairo); + cairo_pattern_set_matrix (pattern, &matrix); + } + + cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT); + + method->cr = cairo_create (paint->surface); + method->gc = NULL; + + cairo_set_source (method->cr, pattern); + cairo_pattern_destroy (pattern); +#else + guint gc_mask; + GdkGCValues gc_values; + + gc_values.fill = GDK_TILED; + gc_values.tile = private->bg_pixmap; + gc_values.ts_x_origin = -x_offset_cairo; + gc_values.ts_y_origin = -y_offset_cairo; + + gc_mask = GDK_GC_FILL | GDK_GC_TILE | GDK_GC_TS_X_ORIGIN | GDK_GC_TS_Y_ORIGIN; + + method->gc = gdk_gc_new_with_values (paint->pixmap, &gc_values, gc_mask); +#endif + } + else + { + method->cr = cairo_create (paint->surface); + + gdk_cairo_set_source_color (method->cr, &private->bg_color); + } +} + +static void +gdk_window_clear_backing_region (GdkWindow *window, + GdkRegion *region) +{ + GdkWindowObject *private = (GdkWindowObject *)window; + GdkWindowPaint *paint = private->paint_stack->data; + BackingRectMethod method; + GdkRegion *clip; + GdkRectangle clipbox; +#if 0 + GTimer *timer; + double elapsed; +#endif + + if (GDK_WINDOW_DESTROYED (window)) + return; + +#if 0 + timer = g_timer_new (); +#endif + + method.cr = NULL; + method.gc = NULL; + setup_backing_rect_method (&method, window, paint, 0, 0); + + clip = gdk_region_copy (paint->region); + gdk_region_intersect (clip, region); + gdk_region_get_clipbox (clip, &clipbox); + + + if (method.cr) + { + g_assert (method.gc == NULL); + + gdk_cairo_region (method.cr, clip); + cairo_fill (method.cr); + + cairo_destroy (method.cr); +#if 0 + elapsed = g_timer_elapsed (timer, NULL); + g_print ("Draw the background with Cairo: %fs\n", elapsed); +#endif + } + else + { + g_assert (method.gc != NULL); + + gdk_gc_set_clip_region (method.gc, clip); + gdk_draw_rectangle (window, method.gc, TRUE, + clipbox.x, clipbox.y, + clipbox.width, clipbox.height); + g_object_unref (method.gc); + +#if 0 + elapsed = g_timer_elapsed (timer, NULL); + g_print ("Draw the background with GDK: %fs\n", elapsed); +#endif + } + + gdk_region_destroy (clip); + +#if 0 + g_timer_destroy (timer); +#endif +} + +static void +gdk_window_clear_backing_region_redirect (GdkWindow *window, + GdkRegion *region) +{ + GdkWindowObject *private = (GdkWindowObject *)window; + GdkWindowRedirect *redirect = private->redirect; + GdkRegion *clip_region; + GdkRectangle clipbox; + gint x_offset, y_offset; + BackingRectMethod method; + GdkWindowPaint paint; + + if (GDK_WINDOW_DESTROYED (window)) + return; + + clip_region = _gdk_window_calculate_full_clip_region (window, + GDK_WINDOW (redirect->redirected), + TRUE, + &x_offset, &y_offset); + gdk_region_intersect (clip_region, region); + + /* offset is from redirected window origin to window origin, convert to + the offset from the redirected pixmap origin to the window origin */ + x_offset += redirect->dest_x - redirect->src_x; + y_offset += redirect->dest_y - redirect->src_y; + + /* Convert region to pixmap coords */ + gdk_region_offset (clip_region, x_offset, y_offset); + + paint.x_offset = 0; + paint.y_offset = 0; + paint.pixmap = redirect->pixmap; + paint.surface = _gdk_drawable_ref_cairo_surface (redirect->pixmap); + + method.cr = NULL; + method.gc = NULL; + setup_backing_rect_method (&method, window, &paint, -x_offset, -y_offset); + + if (method.cr) + { + g_assert (method.gc == NULL); + + gdk_cairo_region (method.cr, clip_region); + cairo_fill (method.cr); + + cairo_destroy (method.cr); + } + else + { + g_assert (method.gc != NULL); + + gdk_region_get_clipbox (clip_region, &clipbox); + gdk_gc_set_clip_region (method.gc, clip_region); + gdk_draw_rectangle (redirect->pixmap, method.gc, TRUE, + clipbox.x, clipbox.y, + clipbox.width, clipbox.height); + g_object_unref (method.gc); + + } + + gdk_region_destroy (clip_region); + cairo_surface_destroy (paint.surface); +} + +static void +gdk_window_clear_backing_region_direct (GdkWindow *window, + GdkRegion *region) +{ + GdkWindowObject *private = (GdkWindowObject *)window; + BackingRectMethod method; + GdkWindowPaint paint; + GdkRegion *clip; + GdkRectangle clipbox; + + if (GDK_WINDOW_DESTROYED (window)) + return; + + paint.x_offset = 0; + paint.y_offset = 0; + paint.pixmap = window; + paint.surface = _gdk_drawable_ref_cairo_surface (window); + + method.cr = NULL; + method.gc = NULL; + setup_backing_rect_method (&method, window, &paint, 0, 0); + + clip = gdk_region_copy (private->clip_region_with_children); + gdk_region_intersect (clip, region); + gdk_region_get_clipbox (clip, &clipbox); + + if (method.cr) + { + g_assert (method.gc == NULL); + + gdk_cairo_region (method.cr, clip); + cairo_fill (method.cr); + + cairo_destroy (method.cr); + } + else + { + g_assert (method.gc != NULL); + + gdk_gc_set_clip_region (method.gc, clip); + gdk_draw_rectangle (window, method.gc, TRUE, + clipbox.x, clipbox.y, + clipbox.width, clipbox.height); + g_object_unref (method.gc); + + } + + gdk_region_destroy (clip); + cairo_surface_destroy (paint.surface); +} + + +/** + * gdk_window_clear: + * @window: a #GdkWindow + * + * Clears an entire @window to the background color or background pixmap. + **/ +void +gdk_window_clear (GdkWindow *window) +{ + gint width, height; + + g_return_if_fail (GDK_IS_WINDOW (window)); + + gdk_drawable_get_size (GDK_DRAWABLE (window), &width, &height); + + gdk_window_clear_area (window, 0, 0, + width, height); +} + +/* TRUE if the window clears to the same pixels as a native + window clear. This means you can use the native window + clearing operation, and additionally it means any clearing + done by the native window system for you will already be right */ +static gboolean +clears_as_native (GdkWindowObject *private) +{ + GdkWindowObject *next; + + next = private; + do + { + private = next; + if (gdk_window_has_impl (private)) + return TRUE; + next = private->parent; + } + while (private->bg_pixmap == GDK_PARENT_RELATIVE_BG && + next && next->window_type != GDK_WINDOW_ROOT); + return FALSE; +} + +static void +gdk_window_clear_region_internal (GdkWindow *window, + GdkRegion *region, + gboolean send_expose) +{ + GdkWindowObject *private = (GdkWindowObject *)window; + GdkWindowImplIface *impl_iface; + + if (private->paint_stack) + gdk_window_clear_backing_region (window, region); + else + { + if (private->redirect) + gdk_window_clear_backing_region_redirect (window, region); + + impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl); + + if (impl_iface->clear_region && clears_as_native (private)) + { + GdkRegion *copy; + copy = gdk_region_copy (region); + gdk_region_intersect (copy, + private->clip_region_with_children); + + + /* Drawing directly to the window, flush anything outstanding to + guarantee ordering. */ + gdk_window_flush (window); + impl_iface->clear_region (window, copy, send_expose); + + gdk_region_destroy (copy); + } + else + { + gdk_window_clear_backing_region_direct (window, region); + if (send_expose) + gdk_window_invalidate_region (window, region, FALSE); + } + } +} + +static void +gdk_window_clear_area_internal (GdkWindow *window, + gint x, + gint y, + gint width, + gint height, + gboolean send_expose) +{ + GdkRectangle rect; + GdkRegion *region; + + g_return_if_fail (GDK_IS_WINDOW (window)); + + if (GDK_WINDOW_DESTROYED (window)) + return; + + /* Terminate early to avoid weird interpretation of + zero width/height by XClearArea */ + if (width == 0 || height == 0) + return; + + rect.x = x; + rect.y = y; + rect.width = width; + rect.height = height; + + region = gdk_region_rectangle (&rect); + gdk_window_clear_region_internal (window, + region, + send_expose); + gdk_region_destroy (region); + +} + +/** + * gdk_window_clear_area: + * @window: a #GdkWindow + * @x: x coordinate of rectangle to clear + * @y: y coordinate of rectangle to clear + * @width: width of rectangle to clear + * @height: height of rectangle to clear + * + * Clears an area of @window to the background color or background pixmap. + * + **/ +void +gdk_window_clear_area (GdkWindow *window, + gint x, + gint y, + gint width, + gint height) +{ + gdk_window_clear_area_internal (window, + x, y, + width, height, + FALSE); +} + +/** + * gdk_window_clear_area_e: + * @window: a #GdkWindow + * @x: x coordinate of rectangle to clear + * @y: y coordinate of rectangle to clear + * @width: width of rectangle to clear + * @height: height of rectangle to clear + * + * Like gdk_window_clear_area(), but also generates an expose event for + * the cleared area. + * + * This function has a stupid name because it dates back to the mists + * time, pre-GDK-1.0. + * + **/ +void +gdk_window_clear_area_e (GdkWindow *window, + gint x, + gint y, + gint width, + gint height) +{ + gdk_window_clear_area_internal (window, + x, y, + width, height, + TRUE); +} + +static void +gdk_window_draw_image (GdkDrawable *drawable, + GdkGC *gc, + GdkImage *image, + gint xsrc, + gint ysrc, + gint xdest, + gint ydest, + gint width, + gint height) +{ + if (GDK_WINDOW_DESTROYED (drawable)) + return; + + BEGIN_DRAW; + gdk_draw_image (impl, gc, image, xsrc, ysrc, + xdest - x_offset, ydest - y_offset, + width, height); + END_DRAW; +} + +static void +gdk_window_draw_pixbuf (GdkDrawable *drawable, + GdkGC *gc, + GdkPixbuf *pixbuf, + gint src_x, + gint src_y, + gint dest_x, + gint dest_y, + gint width, + gint height, + GdkRgbDither dither, + gint x_dither, + gint y_dither) +{ + GdkWindowObject *private = (GdkWindowObject *)drawable; + GdkDrawableClass *klass; + + if (GDK_WINDOW_DESTROYED (drawable)) + return; + + /* If no gc => no user clipping, but we need clipping + for window emulation, so use a scratch gc */ + if (!gc) + gc = _gdk_drawable_get_scratch_gc (drawable, FALSE); + + BEGIN_DRAW; + + klass = GDK_DRAWABLE_GET_CLASS (impl); + + if (private->paint_stack) + klass->draw_pixbuf (impl, gc, pixbuf, src_x, src_y, + dest_x - x_offset, dest_y - y_offset, + width, height, + dither, x_dither - x_offset, y_dither - y_offset); + else + klass->draw_pixbuf (impl, gc, pixbuf, src_x, src_y, + dest_x - x_offset, dest_y - y_offset, + width, height, + dither, x_dither, y_dither); + END_DRAW; +} + +static void +gdk_window_draw_trapezoids (GdkDrawable *drawable, + GdkGC *gc, + GdkTrapezoid *trapezoids, + gint n_trapezoids) +{ + GdkTrapezoid *new_trapezoids = NULL; + + if (GDK_WINDOW_DESTROYED (drawable)) + return; + + BEGIN_DRAW; + + if (x_offset != 0 || y_offset != 0) + { + gint i; + + new_trapezoids = g_new (GdkTrapezoid, n_trapezoids); + for (i=0; i < n_trapezoids; i++) + { + new_trapezoids[i].y1 = trapezoids[i].y1 - y_offset; + new_trapezoids[i].x11 = trapezoids[i].x11 - x_offset; + new_trapezoids[i].x21 = trapezoids[i].x21 - x_offset; + new_trapezoids[i].y2 = trapezoids[i].y2 - y_offset; + new_trapezoids[i].x12 = trapezoids[i].x12 - x_offset; + new_trapezoids[i].x22 = trapezoids[i].x22 - x_offset; + } + + trapezoids = new_trapezoids; + } + + gdk_draw_trapezoids (impl, gc, trapezoids, n_trapezoids); + + g_free (new_trapezoids); + + END_DRAW; +} + +static void +gdk_window_real_get_size (GdkDrawable *drawable, + gint *width, + gint *height) +{ + GdkWindowObject *private = (GdkWindowObject *)drawable; + + if (width) + *width = private->width; + if (height) + *height = private->height; +} + +static GdkVisual* +gdk_window_real_get_visual (GdkDrawable *drawable) +{ + GdkColormap *colormap; + + g_return_val_if_fail (GDK_IS_WINDOW (drawable), NULL); + + colormap = gdk_drawable_get_colormap (drawable); + return colormap ? gdk_colormap_get_visual (colormap) : NULL; +} + +static gint +gdk_window_real_get_depth (GdkDrawable *drawable) +{ + g_return_val_if_fail (GDK_IS_WINDOW (drawable), 0); + + return ((GdkWindowObject *)GDK_WINDOW (drawable))->depth; +} + +static GdkScreen* +gdk_window_real_get_screen (GdkDrawable *drawable) +{ + return gdk_drawable_get_screen (GDK_WINDOW_OBJECT (drawable)->impl); +} + +static void +gdk_window_real_set_colormap (GdkDrawable *drawable, + GdkColormap *cmap) +{ + GdkWindowObject *private; + + g_return_if_fail (GDK_IS_WINDOW (drawable)); + + if (GDK_WINDOW_DESTROYED (drawable)) + return; + + private = (GdkWindowObject *)drawable; + + /* different colormap than parent, requires native window */ + if (!private->input_only && + cmap != gdk_drawable_get_colormap ((GdkDrawable *)(private->parent))) + gdk_window_ensure_native ((GdkWindow *)drawable); + + gdk_drawable_set_colormap (private->impl, cmap); +} + +static GdkColormap* +gdk_window_real_get_colormap (GdkDrawable *drawable) +{ + g_return_val_if_fail (GDK_IS_WINDOW (drawable), NULL); + + if (GDK_WINDOW_DESTROYED (drawable)) + return NULL; + + return gdk_drawable_get_colormap (((GdkWindowObject*)drawable)->impl); +} + +static GdkImage* +gdk_window_copy_to_image (GdkDrawable *drawable, + GdkImage *image, + gint src_x, + gint src_y, + gint dest_x, + gint dest_y, + gint width, + gint height) +{ + GdkWindowObject *private = (GdkWindowObject *) drawable; + gint x_offset, y_offset; + + g_return_val_if_fail (GDK_IS_WINDOW (drawable), NULL); + + if (GDK_WINDOW_DESTROYED (drawable)) + return NULL; + + /* If we're here, a composite image was not necessary, so + * we can ignore the paint stack. + */ + + /* TODO: Is this right? */ + x_offset = 0; + y_offset = 0; + + return gdk_drawable_copy_to_image (private->impl, + image, + src_x - x_offset, + src_y - y_offset, + dest_x, dest_y, + width, height); +} + +static void +gdk_window_drop_cairo_surface (GdkWindowObject *private) +{ + if (private->cairo_surface) + { + cairo_surface_finish (private->cairo_surface); + cairo_surface_set_user_data (private->cairo_surface, &gdk_window_cairo_key, + NULL, NULL); + } +} + +static void +gdk_window_cairo_surface_destroy (void *data) +{ + GdkWindowObject *private = (GdkWindowObject*) data; + + private->cairo_surface = NULL; + private->impl_window->outstanding_surfaces--; +} + +static cairo_surface_t * +gdk_window_create_cairo_surface (GdkDrawable *drawable, + int width, + int height) +{ + return _gdk_windowing_create_cairo_surface (GDK_WINDOW_OBJECT(drawable)->impl, + width, height); +} + + +static cairo_surface_t * +gdk_window_ref_cairo_surface (GdkDrawable *drawable) +{ + GdkWindowObject *private = (GdkWindowObject*) drawable; + cairo_surface_t *surface; + + if (private->paint_stack) + { + GdkWindowPaint *paint = private->paint_stack->data; + + surface = paint->surface; + cairo_surface_reference (surface); + } + else + { + + /* This will be drawing directly to the window, so flush implicit paint */ + gdk_window_flush ((GdkWindow *)drawable); + + if (!private->cairo_surface) + { + int width, height; + GdkDrawable *source; + + gdk_drawable_get_size ((GdkWindow *) private->impl_window, + &width, &height); + + source = _gdk_drawable_get_source_drawable (drawable); + + private->cairo_surface = _gdk_drawable_create_cairo_surface (source, width, height); + + if (private->cairo_surface) + { + private->impl_window->outstanding_surfaces++; + + cairo_surface_set_device_offset (private->cairo_surface, + private->abs_x, + private->abs_y); + + cairo_surface_set_user_data (private->cairo_surface, &gdk_window_cairo_key, + drawable, gdk_window_cairo_surface_destroy); + } + } + else + cairo_surface_reference (private->cairo_surface); + + surface = private->cairo_surface; + } + + return surface; +} + +static void +gdk_window_set_cairo_clip (GdkDrawable *drawable, + cairo_t *cr) +{ + GdkWindowObject *private = (GdkWindowObject*) drawable; + + if (!private->paint_stack) + { + cairo_reset_clip (cr); + + cairo_save (cr); + cairo_identity_matrix (cr); + + cairo_new_path (cr); + gdk_cairo_region (cr, private->clip_region_with_children); + + cairo_restore (cr); + cairo_clip (cr); + } + else + { + GdkWindowPaint *paint = private->paint_stack->data; + + /* Only needs to clip to region if piggybacking + on an implicit paint pixmap */ + cairo_reset_clip (cr); + if (paint->uses_implicit) + { + cairo_save (cr); + cairo_identity_matrix (cr); + + cairo_new_path (cr); + gdk_cairo_region (cr, paint->region); + cairo_restore (cr); + + cairo_clip (cr); + } + } +} + +/* Code for dirty-region queueing + */ +static GSList *update_windows = NULL; +static guint update_idle = 0; +static gboolean debug_updates = FALSE; + +static inline gboolean +gdk_window_is_ancestor (GdkWindow *window, + GdkWindow *ancestor) +{ + while (window) + { + GdkWindow *parent = (GdkWindow*) ((GdkWindowObject*) window)->parent; + + if (parent == ancestor) + return TRUE; + + window = parent; + } + + return FALSE; +} + +static void +gdk_window_add_update_window (GdkWindow *window) +{ + GSList *tmp; + GSList *prev = NULL; + gboolean has_ancestor_in_list = FALSE; + + /* Check whether "window" is already in "update_windows" list. + * It could be added during execution of gtk_widget_destroy() when + * setting focus widget to NULL and redrawing old focus widget. + * See bug 711552. + */ + tmp = g_slist_find (update_windows, window); + if (tmp != NULL) + return; + + for (tmp = update_windows; tmp; tmp = tmp->next) + { + GdkWindowObject *parent = GDK_WINDOW_OBJECT (window)->parent; + + /* check if tmp is an ancestor of "window"; if it is, set a + * flag indicating that all following windows are either + * children of "window" or from a differen hierarchy + */ + if (!has_ancestor_in_list && gdk_window_is_ancestor (window, tmp->data)) + has_ancestor_in_list = TRUE; + + /* insert in reverse stacking order when adding around siblings, + * so processing updates properly paints over lower stacked windows + */ + if (parent == GDK_WINDOW_OBJECT (tmp->data)->parent) + { + gint index = g_list_index (parent->children, window); + for (; tmp && parent == GDK_WINDOW_OBJECT (tmp->data)->parent; tmp = tmp->next) + { + gint sibling_index = g_list_index (parent->children, tmp->data); + if (index > sibling_index) + break; + prev = tmp; + } + /* here, tmp got advanced past all lower stacked siblings */ + tmp = g_slist_prepend (tmp, g_object_ref (window)); + if (prev) + prev->next = tmp; + else + update_windows = tmp; + return; + } + + /* if "window" has an ancestor in the list and tmp is one of + * "window's" children, insert "window" before tmp + */ + if (has_ancestor_in_list && gdk_window_is_ancestor (tmp->data, window)) + { + tmp = g_slist_prepend (tmp, g_object_ref (window)); + + if (prev) + prev->next = tmp; + else + update_windows = tmp; + return; + } + + /* if we're at the end of the list and had an ancestor it it, + * append to the list + */ + if (! tmp->next && has_ancestor_in_list) + { + tmp = g_slist_append (tmp, g_object_ref (window)); + return; + } + + prev = tmp; + } + + /* if all above checks failed ("window" is from a different + * hierarchy than what is already in the list) or the list is + * empty, prepend + */ + update_windows = g_slist_prepend (update_windows, g_object_ref (window)); +} + +static void +gdk_window_remove_update_window (GdkWindow *window) +{ + GSList *link; + + link = g_slist_find (update_windows, window); + if (link != NULL) + { + update_windows = g_slist_delete_link (update_windows, link); + g_object_unref (window); + } +} + +static gboolean +gdk_window_update_idle (gpointer data) +{ + gdk_window_process_all_updates (); + + return FALSE; +} + +static gboolean +gdk_window_is_toplevel_frozen (GdkWindow *window) +{ + GdkWindowObject *toplevel; + + toplevel = (GdkWindowObject *)gdk_window_get_toplevel (window); + + return toplevel->update_and_descendants_freeze_count > 0; +} + +static void +gdk_window_schedule_update (GdkWindow *window) +{ + if (window && + (GDK_WINDOW_OBJECT (window)->update_freeze_count || + gdk_window_is_toplevel_frozen (window))) + return; + + if (!update_idle) + update_idle = + gdk_threads_add_idle_full (GDK_PRIORITY_REDRAW, + gdk_window_update_idle, + NULL, NULL); +} + +void +_gdk_window_process_updates_recurse (GdkWindow *window, + GdkRegion *expose_region) +{ + GdkWindowObject *private = (GdkWindowObject *)window; + GdkWindowObject *child; + GdkRegion *child_region; + GdkRectangle r; + GList *l, *children; + + if (gdk_region_empty (expose_region)) + return; + + /* Make this reentrancy safe for expose handlers freeing windows */ + children = g_list_copy (private->children); + g_list_foreach (children, (GFunc)g_object_ref, NULL); + + /* Iterate over children, starting at topmost */ + for (l = children; l != NULL; l = l->next) + { + child = l->data; + + if (child->destroyed || !GDK_WINDOW_IS_MAPPED (child) || child->input_only || child->composited) + continue; + + /* Ignore offscreen children, as they don't draw in their parent and + * don't take part in the clipping */ + if (gdk_window_is_offscreen (child)) + continue; + + r.x = child->x; + r.y = child->y; + r.width = child->width; + r.height = child->height; + + child_region = gdk_region_rectangle (&r); + if (child->shape) + { + /* Adjust shape region to parent window coords */ + gdk_region_offset (child->shape, child->x, child->y); + gdk_region_intersect (child_region, child->shape); + gdk_region_offset (child->shape, -child->x, -child->y); + } + + if (child->impl == private->impl) + { + /* Client side child, expose */ + gdk_region_intersect (child_region, expose_region); + gdk_region_subtract (expose_region, child_region); + gdk_region_offset (child_region, -child->x, -child->y); + _gdk_window_process_updates_recurse ((GdkWindow *)child, child_region); + } + else + { + /* Native child, just remove area from expose region */ + gdk_region_subtract (expose_region, child_region); + } + gdk_region_destroy (child_region); + } + + g_list_foreach (children, (GFunc)g_object_unref, NULL); + g_list_free (children); + + if (!gdk_region_empty (expose_region) && + !private->destroyed) + { + if (private->event_mask & GDK_EXPOSURE_MASK) + { + GdkEvent event; + +#ifdef __APPLE__ + /* we no longer double-buffer on macOS/quartz, but double-buffering has seeped + into GTK sufficiently that several widgets rely on the background paint that + gdk_window_begin_paint_region() would do. So here we sort-of-explicitly paint + the window directly to provide the same starting point for the window drawing + that will take place as the expose is processed. + */ + gdk_window_clear_region_internal (window, expose_region, FALSE); +#endif + event.expose.type = GDK_EXPOSE; + event.expose.window = g_object_ref (window); + event.expose.send_event = FALSE; + event.expose.count = 0; + event.expose.region = expose_region; + gdk_region_get_clipbox (expose_region, &event.expose.area); + + (*_gdk_event_func) (&event, _gdk_event_data); + + g_object_unref (window); + } + else if (private->bg_pixmap != GDK_NO_BG && + private->window_type != GDK_WINDOW_FOREIGN) + { + /* No exposure mask set, so nothing will be drawn, the + * app relies on the background being what it specified + * for the window. So, we need to clear this manually. + * + * For foreign windows if expose is not set that generally + * means some other client paints them, so don't clear + * there. + * + * We use begin/end_paint around the clear so that we can + * piggyback on the implicit paint */ + + gdk_window_begin_paint_region (window, expose_region); + gdk_window_clear_region_internal (window, expose_region, FALSE); + gdk_window_end_paint (window); + } + } +} + +/* Process and remove any invalid area on the native window by creating + * expose events for the window and all non-native descendants. + * Also processes any outstanding moves on the window before doing + * any drawing. Note that its possible to have outstanding moves without + * any invalid area as we use the update idle mechanism to coalesce + * multiple moves as well as multiple invalidations. + */ +static void +gdk_window_process_updates_internal (GdkWindow *window) +{ + GdkWindowObject *private = (GdkWindowObject *)window; + GdkWindowImplIface *impl_iface; + gboolean save_region = FALSE; + GdkRectangle clip_box; + int iteration; + + /* Ensure the window lives while updating it */ + g_object_ref (window); + + /* If an update got queued during update processing, we can get a + * window in the update queue that has an empty update_area. + * just ignore it. + * + * We run this multiple times if needed because on win32 the + * first run can cause new (synchronous) updates from + * gdk_window_flush_outstanding_moves(). However, we + * limit it to two iterations to avoid any potential loops. + */ + iteration = 0; + while (private->update_area && + iteration++ < 2) + { + GdkRegion *update_area = private->update_area; + private->update_area = NULL; + + if (_gdk_event_func && gdk_window_is_viewable (window)) + { + GdkRegion *expose_region; + gboolean end_implicit; + + /* Clip to part visible in toplevel */ + gdk_region_intersect (update_area, private->clip_region); + + if (debug_updates) + { + /* Make sure we see the red invalid area before redrawing. */ + gdk_display_sync (gdk_drawable_get_display (window)); + g_usleep (70000); + } + + /* At this point we will be completely redrawing all of update_area. + * If we have any outstanding moves that end up moving stuff inside + * this area we don't actually need to move that as that part would + * be overdrawn by the expose anyway. So, in order to copy less data + * we remove these areas from the outstanding moves. + */ + if (private->outstanding_moves) + { + GdkWindowRegionMove *move; + GdkRegion *remove; + GList *l, *prev; + + remove = gdk_region_copy (update_area); + /* We iterate backwards, starting from the state that would be + if we had applied all the moves. */ + for (l = g_list_last (private->outstanding_moves); l != NULL; l = prev) + { + prev = l->prev; + move = l->data; + + /* Don't need this area */ + gdk_region_subtract (move->dest_region, remove); + + /* However if any of the destination we do need has a source + in the updated region we do need that as a destination for + the earlier moves */ + gdk_region_offset (move->dest_region, -move->dx, -move->dy); + gdk_region_subtract (remove, move->dest_region); + + if (gdk_region_empty (move->dest_region)) + { + gdk_window_region_move_free (move); + private->outstanding_moves = + g_list_delete_link (private->outstanding_moves, l); + } + else /* move back */ + gdk_region_offset (move->dest_region, move->dx, move->dy); + } + gdk_region_destroy (remove); + } + + /* By now we a set of window moves that should be applied, and then + * an update region that should be repainted. A trivial implementation + * would just do that in order, however in order to get nicer drawing + * we do some tricks: + * + * First of all, each subwindow expose may be double buffered by + * itself (depending on widget setting) via + * gdk_window_begin/end_paint(). But we also do an "implicit" paint, + * creating a single pixmap the size of the invalid area on the + * native window which all the individual normal paints will draw + * into. This way in the normal case there will be only one pixmap + * allocated and only once pixmap draw done for all the windows + * in this native window. + * There are a couple of reasons this may fail, for instance, some + * backends (like quartz) do its own double buffering, so we disable + * gdk double buffering there. Secondly, some subwindow could be + * non-double buffered and draw directly to the window outside a + * begin/end_paint pair. That will be lead to a gdk_window_flush + * which immediately executes all outstanding moves and paints+removes + * the implicit paint (further paints will allocate their own pixmap). + * + * Secondly, in the case of implicit double buffering we expose all + * the child windows into the implicit pixmap before we execute + * the outstanding moves. This way we minimize the time between + * doing the moves and rendering the new update area, thus minimizing + * flashing. Of course, if any subwindow is non-double buffered we + * well flush earlier than that. + * + * Thirdly, after having done the outstanding moves we queue an + * "antiexpose" on the area that will be drawn by the expose, which + * means that any invalid region on the native window side before + * the first expose drawing operation will be discarded, as it + * has by then been overdrawn with valid data. This means we can + * avoid doing the unnecessary repaint any outstanding expose events. + */ + + gdk_region_get_clipbox (update_area, &clip_box); + end_implicit = gdk_window_begin_implicit_paint (window, &clip_box); + expose_region = gdk_region_copy (update_area); + if (!end_implicit) + { + /* Rendering is not double buffered by gdk, do outstanding + * moves and queue antiexposure immediately. No need to do + * any tricks */ + gdk_window_flush_outstanding_moves (window); + impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl); + save_region = impl_iface->queue_antiexpose (window, update_area); + } + + /* Render the invalid areas to the implicit paint, by sending exposes. + * May flush if non-double buffered widget draw. */ + _gdk_windowing_window_process_updates_recurse (window, expose_region); + + if (end_implicit) + { + /* Do moves right before exposes are rendered to the window */ + gdk_window_flush_outstanding_moves (window); + + /* By this time we know that any outstanding expose for this + * area is invalid and we can avoid it, so queue an antiexpose. + * However, it may be that due to an non-double buffered expose + * we have already started drawing to the window, so it would + * be to late to anti-expose now. Since this is merely an + * optimization we just avoid doing it at all in that case. + */ + if (private->implicit_paint != NULL && + !private->implicit_paint->flushed) + { + impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl); + save_region = impl_iface->queue_antiexpose (window, update_area); + } + + gdk_window_end_implicit_paint (window); + } + gdk_region_destroy (expose_region); + } + if (!save_region) + gdk_region_destroy (update_area); + } + + if (private->outstanding_moves) + { + /* Flush any outstanding moves, may happen if we moved a window but got + no actual invalid area */ + gdk_window_flush_outstanding_moves (window); + } + + g_object_unref (window); +} + +static void +flush_all_displays (void) +{ + GSList *displays = gdk_display_manager_list_displays (gdk_display_manager_get ()); + GSList *tmp_list; + + for (tmp_list = displays; tmp_list; tmp_list = tmp_list->next) + gdk_display_flush (tmp_list->data); + + g_slist_free (displays); +} + +/* Currently it is not possible to override + * gdk_window_process_all_updates in the same manner as + * gdk_window_process_updates and gdk_window_invalidate_maybe_recurse + * by implementing the GdkPaintable interface. If in the future a + * backend would need this, the right solution would be to add a + * method to GdkDisplay that can be optionally + * NULL. gdk_window_process_all_updates can then walk the list of open + * displays and call the mehod. + */ + +/** + * gdk_window_process_all_updates: + * + * Calls gdk_window_process_updates() for all windows (see #GdkWindow) + * in the application. + * + **/ +void +gdk_window_process_all_updates (void) +{ + GSList *old_update_windows = update_windows; + GSList *tmp_list = update_windows; + static gboolean in_process_all_updates = FALSE; + static gboolean got_recursive_update = FALSE; + + if (in_process_all_updates) + { + /* We can't do this now since that would recurse, so + delay it until after the recursion is done. */ + got_recursive_update = TRUE; + update_idle = 0; + return; + } + + in_process_all_updates = TRUE; + got_recursive_update = FALSE; + + if (update_idle) + g_source_remove (update_idle); + + update_windows = NULL; + update_idle = 0; + + _gdk_windowing_before_process_all_updates (); + + while (tmp_list) + { + GdkWindowObject *private = (GdkWindowObject *)tmp_list->data; + + if (!GDK_WINDOW_DESTROYED (tmp_list->data)) + { + if (private->update_freeze_count || + gdk_window_is_toplevel_frozen (tmp_list->data)) + gdk_window_add_update_window ((GdkWindow *) private); + else + gdk_window_process_updates_internal (tmp_list->data); + } + + g_object_unref (tmp_list->data); + tmp_list = tmp_list->next; + } + + g_slist_free (old_update_windows); + + flush_all_displays (); + + _gdk_windowing_after_process_all_updates (); + + in_process_all_updates = FALSE; + + /* If we ignored a recursive call, schedule a + redraw now so that it eventually happens, + otherwise we could miss an update if nothing + else schedules an update. */ + if (got_recursive_update && !update_idle) + update_idle = + gdk_threads_add_idle_full (GDK_PRIORITY_REDRAW, + gdk_window_update_idle, + NULL, NULL); +} + +/** + * gdk_window_process_updates: + * @window: a #GdkWindow + * @update_children: whether to also process updates for child windows + * + * Sends one or more expose events to @window. The areas in each + * expose event will cover the entire update area for the window (see + * gdk_window_invalidate_region() for details). Normally GDK calls + * gdk_window_process_all_updates() on your behalf, so there's no + * need to call this function unless you want to force expose events + * to be delivered immediately and synchronously (vs. the usual + * case, where GDK delivers them in an idle handler). Occasionally + * this is useful to produce nicer scrolling behavior, for example. + * + **/ +void +gdk_window_process_updates (GdkWindow *window, + gboolean update_children) +{ + GdkWindowObject *private = (GdkWindowObject *)window; + GdkWindowObject *impl_window; + + g_return_if_fail (GDK_IS_WINDOW (window)); + + if (GDK_WINDOW_DESTROYED (window)) + return; + + /* Make sure the window lives during the expose callouts */ + g_object_ref (window); + + impl_window = gdk_window_get_impl_window (private); + if ((impl_window->update_area || + impl_window->outstanding_moves) && + !impl_window->update_freeze_count && + !gdk_window_is_toplevel_frozen (window) && + + /* Don't recurse into process_updates_internal, we'll + * do the update later when idle instead. */ + impl_window->implicit_paint == NULL) + { + gdk_window_process_updates_internal ((GdkWindow *)impl_window); + gdk_window_remove_update_window ((GdkWindow *)impl_window); + } + + if (update_children) + { + /* process updates in reverse stacking order so composition or + * painting over achieves the desired effect for offscreen windows + */ + GList *node, *children; + + children = g_list_copy (private->children); + g_list_foreach (children, (GFunc)g_object_ref, NULL); + + for (node = g_list_last (children); node; node = node->prev) + { + gdk_window_process_updates (node->data, TRUE); + g_object_unref (node->data); + } + + g_list_free (children); + } + + g_object_unref (window); +} + +static void +gdk_window_invalidate_rect_full (GdkWindow *window, + const GdkRectangle *rect, + gboolean invalidate_children, + ClearBg clear_bg) +{ + GdkRectangle window_rect; + GdkRegion *region; + GdkWindowObject *private = (GdkWindowObject *)window; + + g_return_if_fail (GDK_IS_WINDOW (window)); + + if (GDK_WINDOW_DESTROYED (window)) + return; + + if (private->input_only || !private->viewable) + return; + + if (!rect) + { + window_rect.x = 0; + window_rect.y = 0; + gdk_drawable_get_size (GDK_DRAWABLE (window), + &window_rect.width, + &window_rect.height); + rect = &window_rect; + } + + region = gdk_region_rectangle (rect); + gdk_window_invalidate_region_full (window, region, invalidate_children, clear_bg); + gdk_region_destroy (region); +} + +/** + * gdk_window_invalidate_rect: + * @window: a #GdkWindow + * @rect: (allow-none): rectangle to invalidate or %NULL to invalidate the whole + * window + * @invalidate_children: whether to also invalidate child windows + * + * A convenience wrapper around gdk_window_invalidate_region() which + * invalidates a rectangular region. See + * gdk_window_invalidate_region() for details. + **/ +void +gdk_window_invalidate_rect (GdkWindow *window, + const GdkRectangle *rect, + gboolean invalidate_children) +{ + gdk_window_invalidate_rect_full (window, rect, invalidate_children, CLEAR_BG_NONE); +} + +static void +draw_ugly_color (GdkWindow *window, + const GdkRegion *region) +{ + /* Draw ugly color all over the newly-invalid region */ + GdkColor ugly_color = { 0, 50000, 10000, 10000 }; + GdkGC *ugly_gc; + GdkRectangle clipbox; + + ugly_gc = gdk_gc_new (window); + gdk_gc_set_rgb_fg_color (ugly_gc, &ugly_color); + gdk_gc_set_clip_region (ugly_gc, region); + + gdk_region_get_clipbox (region, &clipbox); + + gdk_draw_rectangle (window, + ugly_gc, + TRUE, + clipbox.x, clipbox.y, + clipbox.width, clipbox.height); + + g_object_unref (ugly_gc); +} + +static void +impl_window_add_update_area (GdkWindowObject *impl_window, + GdkRegion *region) +{ + if (impl_window->update_area) + gdk_region_union (impl_window->update_area, region); + else + { + gdk_window_add_update_window ((GdkWindow *)impl_window); + impl_window->update_area = gdk_region_copy (region); + gdk_window_schedule_update ((GdkWindow *)impl_window); + } +} + +/* clear_bg controls if the region will be cleared to + * the background color/pixmap if the exposure mask is not + * set for the window, whereas this might not otherwise be + * done (unless necessary to emulate background settings). + * Set this to CLEAR_BG_WINCLEARED or CLEAR_BG_ALL if you + * need to clear the background, such as when exposing the area beneath a + * hidden or moved window, but not when an app requests repaint or when the + * windowing system exposes a newly visible area (because then the windowing + * system has already cleared the area). + */ +static void +gdk_window_invalidate_maybe_recurse_full (GdkWindow *window, + const GdkRegion *region, + ClearBg clear_bg, + gboolean (*child_func) (GdkWindow *, + gpointer), + gpointer user_data) +{ + GdkWindowObject *private = (GdkWindowObject *)window; + GdkWindowObject *impl_window; + GdkRegion *visible_region; + GList *tmp_list; + + g_return_if_fail (GDK_IS_WINDOW (window)); + + if (GDK_WINDOW_DESTROYED (window)) + return; + + if (private->input_only || + !private->viewable || + gdk_region_empty (region) || + private->window_type == GDK_WINDOW_ROOT) + return; + + visible_region = gdk_drawable_get_visible_region (window); + gdk_region_intersect (visible_region, region); + + tmp_list = private->children; + while (tmp_list) + { + GdkWindowObject *child = tmp_list->data; + + if (!child->input_only) + { + GdkRegion *child_region; + GdkRectangle child_rect; + + child_rect.x = child->x; + child_rect.y = child->y; + child_rect.width = child->width; + child_rect.height = child->height; + child_region = gdk_region_rectangle (&child_rect); + + /* remove child area from the invalid area of the parent */ + if (GDK_WINDOW_IS_MAPPED (child) && !child->shaped && + !child->composited && + !gdk_window_is_offscreen (child)) + gdk_region_subtract (visible_region, child_region); + + if (child_func && (*child_func) ((GdkWindow *)child, user_data)) + { + GdkRegion *tmp = gdk_region_copy (region); + + gdk_region_offset (tmp, - child_rect.x, - child_rect.y); + gdk_region_offset (child_region, - child_rect.x, - child_rect.y); + gdk_region_intersect (child_region, tmp); + + gdk_window_invalidate_maybe_recurse_full ((GdkWindow *)child, + child_region, clear_bg, child_func, user_data); + + gdk_region_destroy (tmp); + } + + gdk_region_destroy (child_region); + } + + tmp_list = tmp_list->next; + } + + impl_window = gdk_window_get_impl_window (private); + + if (!gdk_region_empty (visible_region) || + /* Even if we're not exposing anything, make sure we process + idles for windows with outstanding moves */ + (impl_window->outstanding_moves != NULL && + impl_window->update_area == NULL)) + { + if (debug_updates) + draw_ugly_color (window, region); + + /* Convert to impl coords */ + gdk_region_offset (visible_region, private->abs_x, private->abs_y); + + /* Only invalidate area if app requested expose events or if + we need to clear the area (by request or to emulate background + clearing for non-native windows or native windows with no support + for window backgrounds */ + if (private->event_mask & GDK_EXPOSURE_MASK || + clear_bg == CLEAR_BG_ALL || + (clear_bg == CLEAR_BG_WINCLEARED && + (!clears_as_native (private) || + !GDK_WINDOW_IMPL_GET_IFACE (private->impl)->supports_native_bg))) + impl_window_add_update_area (impl_window, visible_region); + } + + gdk_region_destroy (visible_region); +} + +/** + * gdk_window_invalidate_maybe_recurse: + * @window: a #GdkWindow + * @region: a #GdkRegion + * @child_func: function to use to decide if to recurse to a child, + * %NULL means never recurse. + * @user_data: data passed to @child_func + * + * Adds @region to the update area for @window. The update area is the + * region that needs to be redrawn, or "dirty region." The call + * gdk_window_process_updates() sends one or more expose events to the + * window, which together cover the entire update area. An + * application would normally redraw the contents of @window in + * response to those expose events. + * + * GDK will call gdk_window_process_all_updates() on your behalf + * whenever your program returns to the main loop and becomes idle, so + * normally there's no need to do that manually, you just need to + * invalidate regions that you know should be redrawn. + * + * The @child_func parameter controls whether the region of + * each child window that intersects @region will also be invalidated. + * Only children for which @child_func returns TRUE will have the area + * invalidated. + **/ +void +gdk_window_invalidate_maybe_recurse (GdkWindow *window, + const GdkRegion *region, + gboolean (*child_func) (GdkWindow *, + gpointer), + gpointer user_data) +{ + gdk_window_invalidate_maybe_recurse_full (window, region, CLEAR_BG_NONE, + child_func, user_data); +} + +static gboolean +true_predicate (GdkWindow *window, + gpointer user_data) +{ + return TRUE; +} + +static void +gdk_window_invalidate_region_full (GdkWindow *window, + const GdkRegion *region, + gboolean invalidate_children, + ClearBg clear_bg) +{ + gdk_window_invalidate_maybe_recurse_full (window, region, clear_bg, + invalidate_children ? + true_predicate : (gboolean (*) (GdkWindow *, gpointer))NULL, + NULL); +} + +/** + * gdk_window_invalidate_region: + * @window: a #GdkWindow + * @region: a #GdkRegion + * @invalidate_children: %TRUE to also invalidate child windows + * + * Adds @region to the update area for @window. The update area is the + * region that needs to be redrawn, or "dirty region." The call + * gdk_window_process_updates() sends one or more expose events to the + * window, which together cover the entire update area. An + * application would normally redraw the contents of @window in + * response to those expose events. + * + * GDK will call gdk_window_process_all_updates() on your behalf + * whenever your program returns to the main loop and becomes idle, so + * normally there's no need to do that manually, you just need to + * invalidate regions that you know should be redrawn. + * + * The @invalidate_children parameter controls whether the region of + * each child window that intersects @region will also be invalidated. + * If %FALSE, then the update area for child windows will remain + * unaffected. See gdk_window_invalidate_maybe_recurse if you need + * fine grained control over which children are invalidated. + **/ +void +gdk_window_invalidate_region (GdkWindow *window, + const GdkRegion *region, + gboolean invalidate_children) +{ + gdk_window_invalidate_maybe_recurse (window, region, + invalidate_children ? + true_predicate : (gboolean (*) (GdkWindow *, gpointer))NULL, + NULL); +} + +/** + * _gdk_window_invalidate_for_expose: + * @window: a #GdkWindow + * @region: a #GdkRegion + * + * Adds @region to the update area for @window. The update area is the + * region that needs to be redrawn, or "dirty region." The call + * gdk_window_process_updates() sends one or more expose events to the + * window, which together cover the entire update area. An + * application would normally redraw the contents of @window in + * response to those expose events. + * + * GDK will call gdk_window_process_all_updates() on your behalf + * whenever your program returns to the main loop and becomes idle, so + * normally there's no need to do that manually, you just need to + * invalidate regions that you know should be redrawn. + * + * This version of invalidation is used when you recieve expose events + * from the native window system. It exposes the native window, plus + * any non-native child windows (but not native child windows, as those would + * have gotten their own expose events). + **/ +void +_gdk_window_invalidate_for_expose (GdkWindow *window, + GdkRegion *region) +{ + GdkWindowObject *private = (GdkWindowObject *) window; + GdkWindowRegionMove *move; + GdkRegion *move_region; + GList *l; + + /* Any invalidations comming from the windowing system will + be in areas that may be moved by outstanding moves, + so we need to modify the expose region correspondingly, + otherwise we would expose in the wrong place, as the + outstanding moves will be copied before we draw the + exposes. */ + for (l = private->outstanding_moves; l != NULL; l = l->next) + { + move = l->data; + + /* covert to move source region */ + move_region = gdk_region_copy (move->dest_region); + gdk_region_offset (move_region, -move->dx, -move->dy); + + /* Move area of region that intersects with move source + by dx, dy of the move*/ + gdk_region_intersect (move_region, region); + gdk_region_subtract (region, move_region); + gdk_region_offset (move_region, move->dx, move->dy); + gdk_region_union (region, move_region); + + gdk_region_destroy (move_region); + } + + gdk_window_invalidate_maybe_recurse_full (window, region, CLEAR_BG_WINCLEARED, + (gboolean (*) (GdkWindow *, gpointer))gdk_window_has_no_impl, + NULL); +} + + +/** + * gdk_window_get_update_area: + * @window: a #GdkWindow + * + * Transfers ownership of the update area from @window to the caller + * of the function. That is, after calling this function, @window will + * no longer have an invalid/dirty region; the update area is removed + * from @window and handed to you. If a window has no update area, + * gdk_window_get_update_area() returns %NULL. You are responsible for + * calling gdk_region_destroy() on the returned region if it's non-%NULL. + * + * Return value: the update area for @window + **/ +GdkRegion * +gdk_window_get_update_area (GdkWindow *window) +{ + GdkWindowObject *private = (GdkWindowObject *)window; + GdkWindowObject *impl_window; + GdkRegion *tmp_region; + + g_return_val_if_fail (GDK_IS_WINDOW (window), NULL); + + impl_window = gdk_window_get_impl_window (private); + + if (impl_window->update_area) + { + tmp_region = gdk_region_copy (private->clip_region_with_children); + /* Convert to impl coords */ + gdk_region_offset (tmp_region, private->abs_x, private->abs_y); + gdk_region_intersect (tmp_region, impl_window->update_area); + + if (gdk_region_empty (tmp_region)) + { + gdk_region_destroy (tmp_region); + return NULL; + } + else + { + gdk_region_subtract (impl_window->update_area, tmp_region); + + if (gdk_region_empty (impl_window->update_area) && + impl_window->outstanding_moves == NULL) + { + gdk_region_destroy (impl_window->update_area); + impl_window->update_area = NULL; + + gdk_window_remove_update_window ((GdkWindow *)impl_window); + } + + /* Convert from impl coords */ + gdk_region_offset (tmp_region, -private->abs_x, -private->abs_y); + return tmp_region; + + } + } + else + return NULL; +} + +/** + * _gdk_window_clear_update_area: + * @window: a #GdkWindow. + * + * Internal function to clear the update area for a window. This + * is called when the window is hidden or destroyed. + **/ +void +_gdk_window_clear_update_area (GdkWindow *window) +{ + GdkWindowObject *private = (GdkWindowObject *)window; + + g_return_if_fail (GDK_IS_WINDOW (window)); + + if (private->update_area) + { + gdk_window_remove_update_window (window); + + gdk_region_destroy (private->update_area); + private->update_area = NULL; + } +} + +/** + * gdk_window_freeze_updates: + * @window: a #GdkWindow + * + * Temporarily freezes a window such that it won't receive expose + * events. The window will begin receiving expose events again when + * gdk_window_thaw_updates() is called. If gdk_window_freeze_updates() + * has been called more than once, gdk_window_thaw_updates() must be called + * an equal number of times to begin processing exposes. + **/ +void +gdk_window_freeze_updates (GdkWindow *window) +{ + GdkWindowObject *private = (GdkWindowObject *)window; + GdkWindowObject *impl_window; + + g_return_if_fail (GDK_IS_WINDOW (window)); + + impl_window = gdk_window_get_impl_window (private); + impl_window->update_freeze_count++; +} + +/** + * gdk_window_thaw_updates: + * @window: a #GdkWindow + * + * Thaws a window frozen with gdk_window_freeze_updates(). + **/ +void +gdk_window_thaw_updates (GdkWindow *window) +{ + GdkWindowObject *private = (GdkWindowObject *)window; + GdkWindowObject *impl_window; + + g_return_if_fail (GDK_IS_WINDOW (window)); + + impl_window = gdk_window_get_impl_window (private); + + g_return_if_fail (impl_window->update_freeze_count > 0); + + if (--impl_window->update_freeze_count == 0) + gdk_window_schedule_update (GDK_WINDOW (impl_window)); +} + +/** + * gdk_window_freeze_toplevel_updates_libgtk_only: + * @window: a #GdkWindow + * + * Temporarily freezes a window and all its descendants such that it won't + * receive expose events. The window will begin receiving expose events + * again when gdk_window_thaw_toplevel_updates_libgtk_only() is called. If + * gdk_window_freeze_toplevel_updates_libgtk_only() + * has been called more than once, + * gdk_window_thaw_toplevel_updates_libgtk_only() must be called + * an equal number of times to begin processing exposes. + * + * This function is not part of the GDK public API and is only + * for use by GTK+. + **/ +void +gdk_window_freeze_toplevel_updates_libgtk_only (GdkWindow *window) +{ + GdkWindowObject *private = (GdkWindowObject *)window; + + g_return_if_fail (GDK_IS_WINDOW (window)); + g_return_if_fail (private->window_type != GDK_WINDOW_CHILD); + + private->update_and_descendants_freeze_count++; +} + +/** + * gdk_window_thaw_toplevel_updates_libgtk_only: + * @window: a #GdkWindow + * + * Thaws a window frozen with + * gdk_window_freeze_toplevel_updates_libgtk_only(). + * + * This function is not part of the GDK public API and is only + * for use by GTK+. + **/ +void +gdk_window_thaw_toplevel_updates_libgtk_only (GdkWindow *window) +{ + GdkWindowObject *private = (GdkWindowObject *)window; + + g_return_if_fail (GDK_IS_WINDOW (window)); + g_return_if_fail (private->window_type != GDK_WINDOW_CHILD); + g_return_if_fail (private->update_and_descendants_freeze_count > 0); + + private->update_and_descendants_freeze_count--; + + gdk_window_schedule_update (window); +} + +/** + * gdk_window_set_debug_updates: + * @setting: %TRUE to turn on update debugging + * + * With update debugging enabled, calls to + * gdk_window_invalidate_region() clear the invalidated region of the + * screen to a noticeable color, and GDK pauses for a short time + * before sending exposes to windows during + * gdk_window_process_updates(). The net effect is that you can see + * the invalid region for each window and watch redraws as they + * occur. This allows you to diagnose inefficiencies in your application. + * + * In essence, because the GDK rendering model prevents all flicker, + * if you are redrawing the same region 400 times you may never + * notice, aside from noticing a speed problem. Enabling update + * debugging causes GTK to flicker slowly and noticeably, so you can + * see exactly what's being redrawn when, in what order. + * + * The --gtk-debug=updates command line option passed to GTK+ programs + * enables this debug option at application startup time. That's + * usually more useful than calling gdk_window_set_debug_updates() + * yourself, though you might want to use this function to enable + * updates sometime after application startup time. + * + **/ +void +gdk_window_set_debug_updates (gboolean setting) +{ + debug_updates = setting; +} + +/** + * gdk_window_constrain_size: + * @geometry: a #GdkGeometry structure + * @flags: a mask indicating what portions of @geometry are set + * @width: desired width of window + * @height: desired height of the window + * @new_width: (out): location to store resulting width + * @new_height: (out): location to store resulting height + * + * Constrains a desired width and height according to a + * set of geometry hints (such as minimum and maximum size). + */ +void +gdk_window_constrain_size (GdkGeometry *geometry, + guint flags, + gint width, + gint height, + gint *new_width, + gint *new_height) +{ + /* This routine is partially borrowed from fvwm. + * + * Copyright 1993, Robert Nation + * You may use this code for any purpose, as long as the original + * copyright remains in the source code and all documentation + * + * which in turn borrows parts of the algorithm from uwm + */ + gint min_width = 0; + gint min_height = 0; + gint base_width = 0; + gint base_height = 0; + gint xinc = 1; + gint yinc = 1; + gint max_width = G_MAXINT; + gint max_height = G_MAXINT; + +#define FLOOR(value, base) ( ((gint) ((value) / (base))) * (base) ) + + if ((flags & GDK_HINT_BASE_SIZE) && (flags & GDK_HINT_MIN_SIZE)) + { + base_width = geometry->base_width; + base_height = geometry->base_height; + min_width = geometry->min_width; + min_height = geometry->min_height; + } + else if (flags & GDK_HINT_BASE_SIZE) + { + base_width = geometry->base_width; + base_height = geometry->base_height; + min_width = geometry->base_width; + min_height = geometry->base_height; + } + else if (flags & GDK_HINT_MIN_SIZE) + { + base_width = geometry->min_width; + base_height = geometry->min_height; + min_width = geometry->min_width; + min_height = geometry->min_height; + } + + if (flags & GDK_HINT_MAX_SIZE) + { + max_width = geometry->max_width ; + max_height = geometry->max_height; + } + + if (flags & GDK_HINT_RESIZE_INC) + { + xinc = MAX (xinc, geometry->width_inc); + yinc = MAX (yinc, geometry->height_inc); + } + + /* clamp width and height to min and max values + */ + width = CLAMP (width, min_width, max_width); + height = CLAMP (height, min_height, max_height); + + /* shrink to base + N * inc + */ + width = base_width + FLOOR (width - base_width, xinc); + height = base_height + FLOOR (height - base_height, yinc); + + /* constrain aspect ratio, according to: + * + * width + * min_aspect <= -------- <= max_aspect + * height + */ + + if (flags & GDK_HINT_ASPECT && + geometry->min_aspect > 0 && + geometry->max_aspect > 0) + { + gint delta; + + if (geometry->min_aspect * height > width) + { + delta = FLOOR (height - width / geometry->min_aspect, yinc); + if (height - delta >= min_height) + height -= delta; + else + { + delta = FLOOR (height * geometry->min_aspect - width, xinc); + if (width + delta <= max_width) + width += delta; + } + } + + if (geometry->max_aspect * height < width) + { + delta = FLOOR (width - height * geometry->max_aspect, xinc); + if (width - delta >= min_width) + width -= delta; + else + { + delta = FLOOR (width / geometry->max_aspect - height, yinc); + if (height + delta <= max_height) + height += delta; + } + } + } + +#undef FLOOR + + *new_width = width; + *new_height = height; +} + +/** + * gdk_window_get_pointer: + * @window: a #GdkWindow + * @x: (out) (allow-none): return location for X coordinate of pointer or %NULL to not + * return the X coordinate + * @y: (out) (allow-none): return location for Y coordinate of pointer or %NULL to not + * return the Y coordinate + * @mask: (out) (allow-none): return location for modifier mask or %NULL to not return the + * modifier mask + * + * Obtains the current pointer position and modifier state. + * The position is given in coordinates relative to the upper left + * corner of @window. + * + * Return value: (transfer none): the window containing the pointer (as with + * gdk_window_at_pointer()), or %NULL if the window containing the + * pointer isn't known to GDK + **/ +GdkWindow* +gdk_window_get_pointer (GdkWindow *window, + gint *x, + gint *y, + GdkModifierType *mask) +{ + GdkDisplay *display; + gint tmp_x, tmp_y; + GdkModifierType tmp_mask; + GdkWindow *child; + + g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL); + + if (window) + { + display = gdk_drawable_get_display (window); + } + else + { + GdkScreen *screen = gdk_screen_get_default (); + + display = gdk_screen_get_display (screen); + window = gdk_screen_get_root_window (screen); + + GDK_NOTE (MULTIHEAD, + g_message ("Passing NULL for window to gdk_window_get_pointer()\n" + "is not multihead safe")); + } + + child = display->pointer_hooks->window_get_pointer (display, window, &tmp_x, &tmp_y, &tmp_mask); + + if (x) + *x = tmp_x; + if (y) + *y = tmp_y; + if (mask) + *mask = tmp_mask; + + _gdk_display_enable_motion_hints (display); + + return child; +} + +/** + * gdk_window_at_pointer: + * @win_x: (out) (allow-none): return location for origin of the window under the pointer + * @win_y: (out) (allow-none): return location for origin of the window under the pointer + * + * Obtains the window underneath the mouse pointer, returning the + * location of that window in @win_x, @win_y. Returns %NULL if the + * window under the mouse pointer is not known to GDK (if the window + * belongs to another application and a #GdkWindow hasn't been created + * for it with gdk_window_foreign_new()) + * + * NOTE: For multihead-aware widgets or applications use + * gdk_display_get_window_at_pointer() instead. + * + * Return value: (transfer none): window under the mouse pointer + **/ +GdkWindow* +gdk_window_at_pointer (gint *win_x, + gint *win_y) +{ + return gdk_display_get_window_at_pointer (gdk_display_get_default (), win_x, win_y); +} + +/** + * gdk_get_default_root_window: + * + * Obtains the root window (parent all other windows are inside) + * for the default display and screen. + * + * Return value: the default root window + **/ +GdkWindow * +gdk_get_default_root_window (void) +{ + return gdk_screen_get_root_window (gdk_screen_get_default ()); +} + +/** + * gdk_window_foreign_new: + * @anid: a native window handle. + * + * Wraps a native window for the default display in a #GdkWindow. + * This may fail if the window has been destroyed. + * + * For example in the X backend, a native window handle is an Xlib + * XID. + * + * Return value: the newly-created #GdkWindow wrapper for the + * native window or %NULL if the window has been destroyed. + **/ +GdkWindow * +gdk_window_foreign_new (GdkNativeWindow anid) +{ + return gdk_window_foreign_new_for_display (gdk_display_get_default (), anid); +} + +static void +get_all_native_children (GdkWindowObject *private, + GList **native) +{ + GdkWindowObject *child; + GList *l; + + for (l = private->children; l != NULL; l = l->next) + { + child = l->data; + + if (gdk_window_has_impl (child)) + *native = g_list_prepend (*native, child); + else + get_all_native_children (child, native); + } +} + + +static inline void +gdk_window_raise_internal (GdkWindow *window) +{ + GdkWindowObject *private = (GdkWindowObject *)window; + GdkWindowObject *parent = private->parent; + GdkWindowObject *above; + GList *native_children; + GList *l, listhead; + GdkWindowImplIface *impl_iface; + + if (parent) + { + parent->children = g_list_remove (parent->children, window); + parent->children = g_list_prepend (parent->children, window); + } + + impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl); + /* Just do native raise for toplevels */ + if (gdk_window_is_toplevel (private) || + /* The restack_under codepath should work correctly even if the parent + is native, but it relies on the order of ->children to be correct, + and some apps like SWT reorder the x windows without gdks knowledge, + so we use raise directly in order to make these behave as before + when using native windows */ + (gdk_window_has_impl (private) && gdk_window_has_impl (parent))) + { + impl_iface->raise (window); + } + else if (gdk_window_has_impl (private)) + { + above = find_native_sibling_above (parent, private); + if (above) + { + listhead.data = window; + listhead.next = NULL; + listhead.prev = NULL; + impl_iface->restack_under ((GdkWindow *)above, + &listhead); + } + else + impl_iface->raise (window); + } + else + { + native_children = NULL; + get_all_native_children (private, &native_children); + if (native_children != NULL) + { + above = find_native_sibling_above (parent, private); + + if (above) + impl_iface->restack_under ((GdkWindow *)above, + native_children); + else + { + /* Right order, since native_children is bottom-topmost first */ + for (l = native_children; l != NULL; l = l->next) + impl_iface->raise (l->data); + } + + g_list_free (native_children); + } + + } +} + +/* Returns TRUE If the native window was mapped or unmapped */ +static gboolean +set_viewable (GdkWindowObject *w, + gboolean val) +{ + GdkWindowObject *child; + GdkWindowImplIface *impl_iface; + GList *l; + + if (w->viewable == val) + return FALSE; + + w->viewable = val; + + if (val) + recompute_visible_regions (w, FALSE, FALSE); + + for (l = w->children; l != NULL; l = l->next) + { + child = l->data; + + if (GDK_WINDOW_IS_MAPPED (child) && + child->window_type != GDK_WINDOW_FOREIGN) + set_viewable (child, val); + } + + if (!_gdk_native_windows && + gdk_window_has_impl (w) && + w->window_type != GDK_WINDOW_FOREIGN && + !gdk_window_is_toplevel (w)) + { + /* For most native windows we show/hide them not when they are + * mapped/unmapped, because that may not produce the correct results. + * For instance, if a native window have a non-native parent which is + * hidden, but its native parent is viewable then showing the window + * would make it viewable to X but its not viewable wrt the non-native + * hierarchy. In order to handle this we track the gdk side viewability + * and only map really viewable windows. + * + * There are two exceptions though: + * + * For foreign windows we don't want ever change the mapped state + * except when explicitly done via gdk_window_show/hide, as this may + * cause problems for client owning the foreign window when its window + * is suddenly mapped or unmapped. + * + * For toplevel windows embedded in a foreign window (e.g. a plug) + * we sometimes synthesize a map of a window, but the native + * window is really shown by the embedder, so we don't want to + * do the show ourselves. We can't really tell this case from the normal + * toplevel show as such toplevels are seen by gdk as parents of the + * root window, so we make an exception for all toplevels. + * + * Also, when in GDK_NATIVE_WINDOW mode we never need to play games + * like this, so we just always show/hide directly. + */ + + impl_iface = GDK_WINDOW_IMPL_GET_IFACE (w->impl); + if (val) + impl_iface->show ((GdkWindow *)w, FALSE); + else + impl_iface->hide ((GdkWindow *)w); + + return TRUE; + } + + return FALSE; +} + +/* Returns TRUE If the native window was mapped or unmapped */ +gboolean +_gdk_window_update_viewable (GdkWindow *window) +{ + GdkWindowObject *priv = (GdkWindowObject *)window; + gboolean viewable; + + if (priv->window_type == GDK_WINDOW_FOREIGN || + priv->window_type == GDK_WINDOW_ROOT) + viewable = TRUE; + else if (gdk_window_is_toplevel (priv) || + priv->parent->viewable) + viewable = GDK_WINDOW_IS_MAPPED (priv); + else + viewable = FALSE; + + return set_viewable (priv, viewable); +} + +static void +gdk_window_show_internal (GdkWindow *window, gboolean raise) +{ + GdkWindowObject *private; + GdkWindowImplIface *impl_iface; + gboolean was_mapped, was_viewable; + gboolean did_show; + + g_return_if_fail (GDK_IS_WINDOW (window)); + + private = (GdkWindowObject *) window; + if (private->destroyed) + return; + + was_mapped = GDK_WINDOW_IS_MAPPED (window); + was_viewable = private->viewable; + + if (raise) + /* Keep children in (reverse) stacking order */ + gdk_window_raise_internal (window); + + if (gdk_window_has_impl (private)) + { + if (!was_mapped) + gdk_synthesize_window_state (window, + GDK_WINDOW_STATE_WITHDRAWN, + 0); + } + else + { + private->state = 0; + } + + did_show = _gdk_window_update_viewable (window); + + /* If it was already viewable the backend show op won't be called, call it + again to ensure things happen right if the mapped tracking was not right + for e.g. a foreign window. + Dunno if this is strictly needed but its what happened pre-csw. + Also show if not done by gdk_window_update_viewable. */ + if (gdk_window_has_impl (private) && (was_viewable || !did_show)) + { + impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl); + impl_iface->show ((GdkWindow *)private, + !did_show ? was_mapped : TRUE); + } + + if (!was_mapped && !gdk_window_has_impl (private)) + { + if (private->event_mask & GDK_STRUCTURE_MASK) + _gdk_make_event (GDK_WINDOW (private), GDK_MAP, NULL, FALSE); + + if (private->parent && private->parent->event_mask & GDK_SUBSTRUCTURE_MASK) + _gdk_make_event (GDK_WINDOW (private), GDK_MAP, NULL, FALSE); + } + + if (!was_mapped || raise) + { + recompute_visible_regions (private, TRUE, FALSE); + + /* If any decendants became visible we need to send visibility notify */ + gdk_window_update_visibility_recursively (private, NULL); + + if (gdk_window_is_viewable (window)) + { + _gdk_synthesize_crossing_events_for_geometry_change (window); + gdk_window_invalidate_rect_full (window, NULL, TRUE, CLEAR_BG_ALL); + } + } +} + +/** + * gdk_window_show_unraised: + * @window: a #GdkWindow + * + * Shows a #GdkWindow onscreen, but does not modify its stacking + * order. In contrast, gdk_window_show() will raise the window + * to the top of the window stack. + * + * On the X11 platform, in Xlib terms, this function calls + * XMapWindow() (it also updates some internal GDK state, which means + * that you can't really use XMapWindow() directly on a GDK window). + */ +void +gdk_window_show_unraised (GdkWindow *window) +{ + gdk_window_show_internal (window, FALSE); +} + +/** + * gdk_window_raise: + * @window: a #GdkWindow + * + * Raises @window to the top of the Z-order (stacking order), so that + * other windows with the same parent window appear below @window. + * This is true whether or not the windows are visible. + * + * If @window is a toplevel, the window manager may choose to deny the + * request to move the window in the Z-order, gdk_window_raise() only + * requests the restack, does not guarantee it. + */ +void +gdk_window_raise (GdkWindow *window) +{ + GdkWindowObject *private; + GdkRegion *old_region, *new_region; + + g_return_if_fail (GDK_IS_WINDOW (window)); + + private = (GdkWindowObject *) window; + if (private->destroyed) + return; + + gdk_window_flush_if_exposing (window); + + old_region = NULL; + if (gdk_window_is_viewable (window) && + !private->input_only) + old_region = gdk_region_copy (private->clip_region); + + /* Keep children in (reverse) stacking order */ + gdk_window_raise_internal (window); + + recompute_visible_regions (private, TRUE, FALSE); + + if (old_region) + { + new_region = gdk_region_copy (private->clip_region); + + gdk_region_subtract (new_region, old_region); + gdk_window_invalidate_region_full (window, new_region, TRUE, CLEAR_BG_ALL); + + gdk_region_destroy (old_region); + gdk_region_destroy (new_region); + } +} + +static void +gdk_window_lower_internal (GdkWindow *window) +{ + GdkWindowObject *private = (GdkWindowObject *)window; + GdkWindowObject *parent = private->parent; + GdkWindowImplIface *impl_iface; + GdkWindowObject *above; + GList *native_children; + GList *l, listhead; + + if (parent) + { + parent->children = g_list_remove (parent->children, window); + parent->children = g_list_append (parent->children, window); + } + + impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl); + /* Just do native lower for toplevels */ + if (gdk_window_is_toplevel (private) || + /* The restack_under codepath should work correctly even if the parent + is native, but it relies on the order of ->children to be correct, + and some apps like SWT reorder the x windows without gdks knowledge, + so we use lower directly in order to make these behave as before + when using native windows */ + (gdk_window_has_impl (private) && gdk_window_has_impl (parent))) + { + impl_iface->lower (window); + } + else if (gdk_window_has_impl (private)) + { + above = find_native_sibling_above (parent, private); + if (above) + { + listhead.data = window; + listhead.next = NULL; + listhead.prev = NULL; + impl_iface->restack_under ((GdkWindow *)above, &listhead); + } + else + impl_iface->raise (window); + } + else + { + native_children = NULL; + get_all_native_children (private, &native_children); + if (native_children != NULL) + { + above = find_native_sibling_above (parent, private); + + if (above) + impl_iface->restack_under ((GdkWindow *)above, + native_children); + else + { + /* Right order, since native_children is bottom-topmost first */ + for (l = native_children; l != NULL; l = l->next) + impl_iface->raise (l->data); + } + + g_list_free (native_children); + } + + } +} + +static void +gdk_window_invalidate_in_parent (GdkWindowObject *private) +{ + GdkRectangle r, child; + + if (gdk_window_is_toplevel (private)) + return; + + /* get the visible rectangle of the parent */ + r.x = r.y = 0; + r.width = private->parent->width; + r.height = private->parent->height; + + child.x = private->x; + child.y = private->y; + child.width = private->width; + child.height = private->height; + gdk_rectangle_intersect (&r, &child, &r); + + gdk_window_invalidate_rect_full (GDK_WINDOW (private->parent), &r, TRUE, CLEAR_BG_ALL); +} + + +/** + * gdk_window_lower: + * @window: a #GdkWindow + * + * Lowers @window to the bottom of the Z-order (stacking order), so that + * other windows with the same parent window appear above @window. + * This is true whether or not the other windows are visible. + * + * If @window is a toplevel, the window manager may choose to deny the + * request to move the window in the Z-order, gdk_window_lower() only + * requests the restack, does not guarantee it. + * + * Note that gdk_window_show() raises the window again, so don't call this + * function before gdk_window_show(). (Try gdk_window_show_unraised().) + */ +void +gdk_window_lower (GdkWindow *window) +{ + GdkWindowObject *private; + + g_return_if_fail (GDK_IS_WINDOW (window)); + + private = (GdkWindowObject *) window; + if (private->destroyed) + return; + + gdk_window_flush_if_exposing (window); + + /* Keep children in (reverse) stacking order */ + gdk_window_lower_internal (window); + + recompute_visible_regions (private, TRUE, FALSE); + + _gdk_synthesize_crossing_events_for_geometry_change (window); + gdk_window_invalidate_in_parent (private); +} + +/** + * gdk_window_restack: + * @window: a #GdkWindow + * @sibling: (allow-none): a #GdkWindow that is a sibling of @window, or %NULL + * @above: a boolean + * + * Changes the position of @window in the Z-order (stacking order), so that + * it is above @sibling (if @above is %TRUE) or below @sibling (if @above is + * %FALSE). + * + * If @sibling is %NULL, then this either raises (if @above is %TRUE) or + * lowers the window. + * + * If @window is a toplevel, the window manager may choose to deny the + * request to move the window in the Z-order, gdk_window_restack() only + * requests the restack, does not guarantee it. + * + * Since: 2.18 + */ +void +gdk_window_restack (GdkWindow *window, + GdkWindow *sibling, + gboolean above) +{ + GdkWindowObject *private; + GdkWindowImplIface *impl_iface; + GdkWindowObject *parent; + GdkWindowObject *above_native; + GList *sibling_link; + GList *native_children; + GList *l, listhead; + + g_return_if_fail (GDK_IS_WINDOW (window)); + g_return_if_fail (sibling == NULL || GDK_IS_WINDOW (sibling)); + + private = (GdkWindowObject *) window; + if (private->destroyed) + return; + + if (sibling == NULL) + { + if (above) + gdk_window_raise (window); + else + gdk_window_lower (window); + return; + } + + gdk_window_flush_if_exposing (window); + + if (gdk_window_is_toplevel (private)) + { + g_return_if_fail (gdk_window_is_toplevel (GDK_WINDOW_OBJECT (sibling))); + impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl); + impl_iface->restack_toplevel (window, sibling, above); + return; + } + + parent = private->parent; + if (parent) + { + sibling_link = g_list_find (parent->children, sibling); + g_return_if_fail (sibling_link != NULL); + if (sibling_link == NULL) + return; + + parent->children = g_list_remove (parent->children, window); + if (above) + parent->children = g_list_insert_before (parent->children, + sibling_link, + window); + else + parent->children = g_list_insert_before (parent->children, + sibling_link->next, + window); + + impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl); + if (gdk_window_has_impl (private)) + { + above_native = find_native_sibling_above (parent, private); + if (above_native) + { + listhead.data = window; + listhead.next = NULL; + listhead.prev = NULL; + impl_iface->restack_under ((GdkWindow *)above_native, &listhead); + } + else + impl_iface->raise (window); + } + else + { + native_children = NULL; + get_all_native_children (private, &native_children); + if (native_children != NULL) + { + above_native = find_native_sibling_above (parent, private); + if (above_native) + impl_iface->restack_under ((GdkWindow *)above_native, + native_children); + else + { + /* Right order, since native_children is bottom-topmost first */ + for (l = native_children; l != NULL; l = l->next) + impl_iface->raise (l->data); + } + + g_list_free (native_children); + } + } + } + + recompute_visible_regions (private, TRUE, FALSE); + + _gdk_synthesize_crossing_events_for_geometry_change (window); + gdk_window_invalidate_in_parent (private); +} + + +/** + * gdk_window_show: + * @window: a #GdkWindow + * + * Like gdk_window_show_unraised(), but also raises the window to the + * top of the window stack (moves the window to the front of the + * Z-order). + * + * This function maps a window so it's visible onscreen. Its opposite + * is gdk_window_hide(). + * + * When implementing a #GtkWidget, you should call this function on the widget's + * #GdkWindow as part of the "map" method. + */ +void +gdk_window_show (GdkWindow *window) +{ + gdk_window_show_internal (window, TRUE); +} + +/** + * gdk_window_hide: + * @window: a #GdkWindow + * + * For toplevel windows, withdraws them, so they will no longer be + * known to the window manager; for all windows, unmaps them, so + * they won't be displayed. Normally done automatically as + * part of gtk_widget_hide(). + */ +void +gdk_window_hide (GdkWindow *window) +{ + GdkWindowObject *private; + GdkWindowImplIface *impl_iface; + gboolean was_mapped, did_hide; + + g_return_if_fail (GDK_IS_WINDOW (window)); + + private = (GdkWindowObject *) window; + if (private->destroyed) + return; + + was_mapped = GDK_WINDOW_IS_MAPPED (private); + + if (gdk_window_has_impl (private)) + { + + if (GDK_WINDOW_IS_MAPPED (window)) + gdk_synthesize_window_state (window, + 0, + GDK_WINDOW_STATE_WITHDRAWN); + } + else if (was_mapped) + { + GdkDisplay *display; + + /* May need to break grabs on children */ + display = gdk_drawable_get_display (window); + + if (_gdk_display_end_pointer_grab (display, + _gdk_windowing_window_get_next_serial (display), + window, + TRUE)) + gdk_display_pointer_ungrab (display, GDK_CURRENT_TIME); + + if (display->keyboard_grab.window != NULL) + { + if (is_parent_of (window, display->keyboard_grab.window)) + { + /* Call this ourselves, even though gdk_display_keyboard_ungrab + does so too, since we want to pass implicit == TRUE so the + broken grab event is generated */ + _gdk_display_unset_has_keyboard_grab (display, + TRUE); + gdk_display_keyboard_ungrab (display, GDK_CURRENT_TIME); + } + } + + private->state = GDK_WINDOW_STATE_WITHDRAWN; + } + + did_hide = _gdk_window_update_viewable (window); + + /* Hide foreign window as those are not handled by update_viewable. */ + if (gdk_window_has_impl (private) && (!did_hide)) + { + impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl); + impl_iface->hide (window); + } + + recompute_visible_regions (private, TRUE, FALSE); + + /* all decendants became non-visible, we need to send visibility notify */ + gdk_window_update_visibility_recursively (private, NULL); + + if (was_mapped && !gdk_window_has_impl (private)) + { + if (private->event_mask & GDK_STRUCTURE_MASK) + _gdk_make_event (GDK_WINDOW (private), GDK_UNMAP, NULL, FALSE); + + if (private->parent && private->parent->event_mask & GDK_SUBSTRUCTURE_MASK) + _gdk_make_event (GDK_WINDOW (private), GDK_UNMAP, NULL, FALSE); + + _gdk_synthesize_crossing_events_for_geometry_change (GDK_WINDOW (private->parent)); + } + + /* Invalidate the rect */ + if (was_mapped) + gdk_window_invalidate_in_parent (private); +} + +/** + * gdk_window_withdraw: + * @window: a toplevel #GdkWindow + * + * Withdraws a window (unmaps it and asks the window manager to forget about it). + * This function is not really useful as gdk_window_hide() automatically + * withdraws toplevel windows before hiding them. + **/ +void +gdk_window_withdraw (GdkWindow *window) +{ + GdkWindowObject *private; + GdkWindowImplIface *impl_iface; + gboolean was_mapped; + + g_return_if_fail (GDK_IS_WINDOW (window)); + + private = (GdkWindowObject *) window; + if (private->destroyed) + return; + + was_mapped = GDK_WINDOW_IS_MAPPED (private); + + if (gdk_window_has_impl (private)) + { + impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl); + impl_iface->withdraw (window); + + if (was_mapped) + { + if (private->event_mask & GDK_STRUCTURE_MASK) + _gdk_make_event (GDK_WINDOW (private), GDK_UNMAP, NULL, FALSE); + + if (private->parent && private->parent->event_mask & GDK_SUBSTRUCTURE_MASK) + _gdk_make_event (GDK_WINDOW (private), GDK_UNMAP, NULL, FALSE); + + _gdk_synthesize_crossing_events_for_geometry_change (GDK_WINDOW (private->parent)); + } + + recompute_visible_regions (private, TRUE, FALSE); + } +} + +/** + * gdk_window_set_events: + * @window: a #GdkWindow + * @event_mask: event mask for @window + * + * The event mask for a window determines which events will be reported + * for that window. For example, an event mask including #GDK_BUTTON_PRESS_MASK + * means the window should report button press events. The event mask + * is the bitwise OR of values from the #GdkEventMask enumeration. + **/ +void +gdk_window_set_events (GdkWindow *window, + GdkEventMask event_mask) +{ + GdkWindowObject *private; + GdkWindowImplIface *impl_iface; + GdkDisplay *display; + + g_return_if_fail (GDK_IS_WINDOW (window)); + + private = (GdkWindowObject *) window; + if (private->destroyed) + return; + + /* If motion hint is disabled, enable motion events again */ + display = gdk_drawable_get_display (window); + if ((private->event_mask & GDK_POINTER_MOTION_HINT_MASK) && + !(event_mask & GDK_POINTER_MOTION_HINT_MASK)) + _gdk_display_enable_motion_hints (display); + + private->event_mask = event_mask; + + if (gdk_window_has_impl (private)) + { + impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl); + impl_iface->set_events (window, + get_native_event_mask (private)); + } + +} + +/** + * gdk_window_get_events: + * @window: a #GdkWindow + * + * Gets the event mask for @window. See gdk_window_set_events(). + * + * Return value: event mask for @window + **/ +GdkEventMask +gdk_window_get_events (GdkWindow *window) +{ + GdkWindowObject *private; + + g_return_val_if_fail (GDK_IS_WINDOW (window), 0); + + private = (GdkWindowObject *) window; + if (private->destroyed) + return 0; + + return private->event_mask; +} + +static void +gdk_window_move_resize_toplevel (GdkWindow *window, + gboolean with_move, + gint x, + gint y, + gint width, + gint height) +{ + GdkWindowObject *private; + GdkRegion *old_region, *new_region; + GdkWindowImplIface *impl_iface; + gboolean expose; + int old_x, old_y, old_abs_x, old_abs_y; + int dx, dy; + gboolean is_resize; + + private = (GdkWindowObject *) window; + + expose = FALSE; + old_region = NULL; + + old_x = private->x; + old_y = private->y; + + is_resize = (width != -1) || (height != -1); + + if (gdk_window_is_viewable (window) && + !private->input_only) + { + expose = TRUE; + old_region = gdk_region_copy (private->clip_region); + } + + impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl); + impl_iface->move_resize (window, with_move, x, y, width, height); + + dx = private->x - old_x; + dy = private->y - old_y; + + old_abs_x = private->abs_x; + old_abs_y = private->abs_y; + + /* Avoid recomputing for pure toplevel moves, for performance reasons */ + if (is_resize) + recompute_visible_regions (private, TRUE, FALSE); + + if (expose) + { + new_region = gdk_region_copy (private->clip_region); + + /* This is the newly exposed area (due to any resize), + * X will expose it, but lets do that without the + * roundtrip + */ + gdk_region_subtract (new_region, old_region); + gdk_window_invalidate_region_full (window, new_region, TRUE, CLEAR_BG_WINCLEARED); + + gdk_region_destroy (old_region); + gdk_region_destroy (new_region); + } + + _gdk_synthesize_crossing_events_for_geometry_change (window); +} + + +static void +move_native_children (GdkWindowObject *private) +{ + GList *l; + GdkWindowObject *child; + GdkWindowImplIface *impl_iface; + + for (l = private->children; l; l = l->next) + { + child = l->data; + + if (child->impl != private->impl) + { + impl_iface = GDK_WINDOW_IMPL_GET_IFACE (child->impl); + impl_iface->move_resize ((GdkWindow *)child, TRUE, + child->x, child->y, + child->width, child->height); + } + else + move_native_children (child); + } +} + +static gboolean +collect_native_child_region_helper (GdkWindowObject *window, + GdkWindow *impl, + GdkRegion **region, + int x_offset, + int y_offset) +{ + GdkWindowObject *child; + GdkRegion *tmp; + GList *l; + + for (l = window->children; l != NULL; l = l->next) + { + child = l->data; + + if (!GDK_WINDOW_IS_MAPPED (child) || child->input_only) + continue; + + if (child->impl != impl) + { + tmp = gdk_region_copy (child->clip_region); + gdk_region_offset (tmp, + x_offset + child->x, + y_offset + child->y); + if (*region == NULL) + *region = tmp; + else + { + gdk_region_union (*region, tmp); + gdk_region_destroy (tmp); + } + } + else + collect_native_child_region_helper (child, impl, region, + x_offset + child->x, + y_offset + child->y); + } + + return FALSE; +} + +static GdkRegion * +collect_native_child_region (GdkWindowObject *window, + gboolean include_this) +{ + GdkRegion *region; + + if (include_this && gdk_window_has_impl (window) && window->viewable) + return gdk_region_copy (window->clip_region); + + region = NULL; + + collect_native_child_region_helper (window, window->impl, ®ion, 0, 0); + + return region; +} + + +static void +gdk_window_move_resize_internal (GdkWindow *window, + gboolean with_move, + gint x, + gint y, + gint width, + gint height) +{ + GdkWindowObject *private; + GdkRegion *old_region, *new_region, *copy_area; + GdkRegion *old_native_child_region, *new_native_child_region; + GdkWindowObject *impl_window; + GdkWindowImplIface *impl_iface; + gboolean expose; + int old_x, old_y, old_abs_x, old_abs_y; + int dx, dy; + + g_return_if_fail (GDK_IS_WINDOW (window)); + + private = (GdkWindowObject *) window; + if (private->destroyed) + return; + + if (gdk_window_is_toplevel (private)) + { + gdk_window_move_resize_toplevel (window, with_move, x, y, width, height); + return; + } + + /* Bail early if no change */ + if (private->width == width && + private->height == height && + (!with_move || + (private->x == x && + private->y == y))) + return; + + gdk_window_flush_if_exposing (window); + + /* Handle child windows */ + + expose = FALSE; + old_region = NULL; + + impl_window = gdk_window_get_impl_window (private); + + old_x = private->x; + old_y = private->y; + + old_native_child_region = NULL; + if (gdk_window_is_viewable (window) && + !private->input_only) + { + expose = TRUE; + + old_region = gdk_region_copy (private->clip_region); + /* Adjust region to parent window coords */ + gdk_region_offset (old_region, private->x, private->y); + + old_native_child_region = collect_native_child_region (private, TRUE); + if (old_native_child_region) + { + /* Adjust region to parent window coords */ + gdk_region_offset (old_native_child_region, private->x, private->y); + + /* Any native window move will immediately copy stuff to the destination, which may overwrite a + * source or destination for a delayed GdkWindowRegionMove. So, we need + * to flush those here for the parent window and all overlapped subwindows + * of it. And we need to do this before setting the new clips as those will be + * affecting this. + */ + gdk_window_flush_recursive (private->parent); + } + } + + /* Set the new position and size */ + if (with_move) + { + private->x = x; + private->y = y; + } + if (!(width < 0 && height < 0)) + { + if (width < 1) + width = 1; + private->width = width; + if (height < 1) + height = 1; + private->height = height; + } + + dx = private->x - old_x; + dy = private->y - old_y; + + old_abs_x = private->abs_x; + old_abs_y = private->abs_y; + + recompute_visible_regions (private, TRUE, FALSE); + + new_native_child_region = NULL; + if (old_native_child_region) + { + new_native_child_region = collect_native_child_region (private, TRUE); + /* Adjust region to parent window coords */ + gdk_region_offset (new_native_child_region, private->x, private->y); + } + + if (gdk_window_has_impl (private)) + { + impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl); + + /* Do the actual move after recomputing things, as this will have set the shape to + the now correct one, thus avoiding copying regions that should not be copied. */ + impl_iface->move_resize (window, TRUE, + private->x, private->y, + private->width, private->height); + } + else if (old_abs_x != private->abs_x || + old_abs_y != private->abs_y) + move_native_children (private); + + if (expose) + { + new_region = gdk_region_copy (private->clip_region); + /* Adjust region to parent window coords */ + gdk_region_offset (new_region, private->x, private->y); + + /* copy_area: + * Part of the data at the new location can be copied from the + * old location, this area is the intersection of the old region + * moved as the copy will move it and then intersected with + * the new region. + * + * new_region: + * Everything in the old and new regions that is not copied must be + * invalidated (including children) as this is newly exposed + */ + copy_area = gdk_region_copy (new_region); + + gdk_region_union (new_region, old_region); + + if (old_native_child_region) + { + /* Don't copy from inside native children, as this is copied by + * the native window move. + */ + gdk_region_subtract (old_region, old_native_child_region); + } + gdk_region_offset (old_region, dx, dy); + + gdk_region_intersect (copy_area, old_region); + + if (new_native_child_region) + { + /* Don't copy any bits that would cause a read from the moved + native windows, as we can't read that data */ + gdk_region_offset (new_native_child_region, dx, dy); + gdk_region_subtract (copy_area, new_native_child_region); + gdk_region_offset (new_native_child_region, -dx, -dy); + } + + gdk_region_subtract (new_region, copy_area); + + /* Convert old region to impl coords */ + gdk_region_offset (old_region, -dx + private->abs_x - private->x, -dy + private->abs_y - private->y); + + /* convert from parent coords to impl */ + gdk_region_offset (copy_area, private->abs_x - private->x, private->abs_y - private->y); + + move_region_on_impl (impl_window, copy_area, dx, dy); /* takes ownership of copy_area */ + + /* Invalidate affected part in the parent window + * (no higher window should be affected) + * We also invalidate any children in that area, which could include + * this window if it still overlaps that area. + */ + if (old_native_child_region) + { + /* No need to expose the region that the native window move copies */ + gdk_region_offset (old_native_child_region, dx, dy); + gdk_region_intersect (old_native_child_region, new_native_child_region); + gdk_region_subtract (new_region, old_native_child_region); + } + gdk_window_invalidate_region_full (GDK_WINDOW (private->parent), new_region, TRUE, CLEAR_BG_ALL); + + gdk_region_destroy (old_region); + gdk_region_destroy (new_region); + } + + if (old_native_child_region) + { + gdk_region_destroy (old_native_child_region); + gdk_region_destroy (new_native_child_region); + } + + _gdk_synthesize_crossing_events_for_geometry_change (window); +} + + + +/** + * gdk_window_move: + * @window: a #GdkWindow + * @x: X coordinate relative to window's parent + * @y: Y coordinate relative to window's parent + * + * Repositions a window relative to its parent window. + * For toplevel windows, window managers may ignore or modify the move; + * you should probably use gtk_window_move() on a #GtkWindow widget + * anyway, instead of using GDK functions. For child windows, + * the move will reliably succeed. + * + * If you're also planning to resize the window, use gdk_window_move_resize() + * to both move and resize simultaneously, for a nicer visual effect. + **/ +void +gdk_window_move (GdkWindow *window, + gint x, + gint y) +{ + gdk_window_move_resize_internal (window, TRUE, x, y, -1, -1); +} + +/** + * gdk_window_resize: + * @window: a #GdkWindow + * @width: new width of the window + * @height: new height of the window + * + * Resizes @window; for toplevel windows, asks the window manager to resize + * the window. The window manager may not allow the resize. When using GTK+, + * use gtk_window_resize() instead of this low-level GDK function. + * + * Windows may not be resized below 1x1. + * + * If you're also planning to move the window, use gdk_window_move_resize() + * to both move and resize simultaneously, for a nicer visual effect. + **/ +void +gdk_window_resize (GdkWindow *window, + gint width, + gint height) +{ + gdk_window_move_resize_internal (window, FALSE, 0, 0, width, height); +} + + +/** + * gdk_window_move_resize: + * @window: a #GdkWindow + * @x: new X position relative to window's parent + * @y: new Y position relative to window's parent + * @width: new width + * @height: new height + * + * Equivalent to calling gdk_window_move() and gdk_window_resize(), + * except that both operations are performed at once, avoiding strange + * visual effects. (i.e. the user may be able to see the window first + * move, then resize, if you don't use gdk_window_move_resize().) + **/ +void +gdk_window_move_resize (GdkWindow *window, + gint x, + gint y, + gint width, + gint height) +{ + gdk_window_move_resize_internal (window, TRUE, x, y, width, height); +} + + +/** + * gdk_window_scroll: + * @window: a #GdkWindow + * @dx: Amount to scroll in the X direction + * @dy: Amount to scroll in the Y direction + * + * Scroll the contents of @window, both pixels and children, by the + * given amount. @window itself does not move. Portions of the window + * that the scroll operation brings in from offscreen areas are + * invalidated. The invalidated region may be bigger than what would + * strictly be necessary. + * + * For X11, a minimum area will be invalidated if the window has no + * subwindows, or if the edges of the window's parent do not extend + * beyond the edges of the window. In other cases, a multi-step process + * is used to scroll the window which may produce temporary visual + * artifacts and unnecessary invalidations. + **/ +void +gdk_window_scroll (GdkWindow *window, + gint dx, + gint dy) +{ + GdkWindowObject *private = (GdkWindowObject *) window; + GdkWindowObject *impl_window; + GdkRegion *copy_area, *noncopy_area; + GdkRegion *old_native_child_region, *new_native_child_region; + GList *tmp_list; + + g_return_if_fail (GDK_IS_WINDOW (window)); + + if (dx == 0 && dy == 0) + return; + + if (private->destroyed) + return; + + gdk_window_flush_if_exposing (window); + + old_native_child_region = collect_native_child_region (private, FALSE); + if (old_native_child_region) + { + /* Any native window move will immediately copy stuff to the destination, which may overwrite a + * source or destination for a delayed GdkWindowRegionMove. So, we need + * to flush those here for the window and all overlapped subwindows + * of it. And we need to do this before setting the new clips as those will be + * affecting this. + */ + gdk_window_flush_recursive (private); + } + + + /* First move all child windows, without causing invalidation */ + + tmp_list = private->children; + while (tmp_list) + { + GdkWindow *child = GDK_WINDOW (tmp_list->data); + GdkWindowObject *child_obj = GDK_WINDOW_OBJECT (child); + + /* Just update the positions, the bits will move with the copy */ + child_obj->x += dx; + child_obj->y += dy; + + tmp_list = tmp_list->next; + } + + recompute_visible_regions (private, FALSE, TRUE); + + new_native_child_region = NULL; + if (old_native_child_region) + new_native_child_region = collect_native_child_region (private, FALSE); + + move_native_children (private); + + /* Then copy the actual bits of the window w/ child windows */ + + impl_window = gdk_window_get_impl_window (private); + + /* Calculate the area that can be gotten by copying the old area */ + copy_area = gdk_region_copy (private->clip_region); + if (old_native_child_region) + { + /* Don't copy from inside native children, as this is copied by + * the native window move. + */ + gdk_region_subtract (copy_area, old_native_child_region); + + /* Don't copy any bits that would cause a read from the moved + native windows, as we can't read that data */ + gdk_region_subtract (copy_area, new_native_child_region); + } + gdk_region_offset (copy_area, dx, dy); + gdk_region_intersect (copy_area, private->clip_region); + + /* And the rest need to be invalidated */ + noncopy_area = gdk_region_copy (private->clip_region); + gdk_region_subtract (noncopy_area, copy_area); + + /* convert from window coords to impl */ + gdk_region_offset (copy_area, private->abs_x, private->abs_y); + + move_region_on_impl (impl_window, copy_area, dx, dy); /* takes ownership of copy_area */ + + /* Invalidate not copied regions */ + if (old_native_child_region) + { + /* No need to expose the region that the native window move copies */ + gdk_region_offset (old_native_child_region, dx, dy); + gdk_region_intersect (old_native_child_region, new_native_child_region); + gdk_region_subtract (noncopy_area, old_native_child_region); + } + gdk_window_invalidate_region_full (window, noncopy_area, TRUE, CLEAR_BG_ALL); + + gdk_region_destroy (noncopy_area); + + if (old_native_child_region) + { + gdk_region_destroy (old_native_child_region); + gdk_region_destroy (new_native_child_region); + } + + _gdk_synthesize_crossing_events_for_geometry_change (window); +} + +/** + * gdk_window_move_region: + * @window: a #GdkWindow + * @region: The #GdkRegion to move + * @dx: Amount to move in the X direction + * @dy: Amount to move in the Y direction + * + * Move the part of @window indicated by @region by @dy pixels in the Y + * direction and @dx pixels in the X direction. The portions of @region + * that not covered by the new position of @region are invalidated. + * + * Child windows are not moved. + * + * Since: 2.8 + */ +void +gdk_window_move_region (GdkWindow *window, + const GdkRegion *region, + gint dx, + gint dy) +{ + GdkWindowObject *private = (GdkWindowObject *) window; + GdkWindowObject *impl_window; + GdkRegion *nocopy_area; + GdkRegion *copy_area; + + g_return_if_fail (GDK_IS_WINDOW (window)); + g_return_if_fail (region != NULL); + + if (dx == 0 && dy == 0) + return; + + if (private->destroyed) + return; + + impl_window = gdk_window_get_impl_window (private); + + /* compute source regions */ + copy_area = gdk_region_copy (region); + gdk_region_intersect (copy_area, private->clip_region_with_children); + + /* compute destination regions */ + gdk_region_offset (copy_area, dx, dy); + gdk_region_intersect (copy_area, private->clip_region_with_children); + + /* Invalidate parts of the region (source and dest) not covered + by the copy */ + nocopy_area = gdk_region_copy (region); + gdk_region_offset (nocopy_area, dx, dy); + gdk_region_union (nocopy_area, region); + gdk_region_subtract (nocopy_area, copy_area); + + /* convert from window coords to impl */ + gdk_region_offset (copy_area, private->abs_x, private->abs_y); + move_region_on_impl (impl_window, copy_area, dx, dy); /* Takes ownership of copy_area */ + + gdk_window_invalidate_region_full (window, nocopy_area, FALSE, CLEAR_BG_ALL); + gdk_region_destroy (nocopy_area); +} + +/** + * gdk_window_set_background: + * @window: a #GdkWindow + * @color: an allocated #GdkColor + * + * Sets the background color of @window. (However, when using GTK+, + * set the background of a widget with gtk_widget_modify_bg() - if + * you're an application - or gtk_style_set_background() - if you're + * implementing a custom widget.) + * + * The @color must be allocated; gdk_rgb_find_color() is the best way + * to allocate a color. + * + * See also gdk_window_set_back_pixmap(). + */ +void +gdk_window_set_background (GdkWindow *window, + const GdkColor *color) +{ + GdkWindowObject *private; + GdkColormap *colormap = gdk_drawable_get_colormap (window); + GdkWindowImplIface *impl_iface; + + g_return_if_fail (GDK_IS_WINDOW (window)); + + private = (GdkWindowObject *) window; + + private->bg_color = *color; + gdk_colormap_query_color (colormap, private->bg_color.pixel, &private->bg_color); + + if (private->bg_pixmap && + private->bg_pixmap != GDK_PARENT_RELATIVE_BG && + private->bg_pixmap != GDK_NO_BG) + g_object_unref (private->bg_pixmap); + + private->bg_pixmap = NULL; + + if (private->background) + { + cairo_pattern_destroy (private->background); + private->background = NULL; + } + + if (!GDK_WINDOW_DESTROYED (window) && + gdk_window_has_impl (private) && + !private->input_only) + { + impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl); + impl_iface->set_background (window, &private->bg_color); + } +} + +/** + * gdk_window_set_back_pixmap: + * @window: a #GdkWindow + * @pixmap: (allow-none): a #GdkPixmap, or %NULL + * @parent_relative: whether the tiling origin is at the origin of + * @window's parent + * + * Sets the background pixmap of @window. May also be used to set a + * background of "None" on @window, by setting a background pixmap + * of %NULL. + * + * A background pixmap will be tiled, positioning the first tile at + * the origin of @window, or if @parent_relative is %TRUE, the tiling + * will be done based on the origin of the parent window (useful to + * align tiles in a parent with tiles in a child). + * + * A background pixmap of %NULL means that the window will have no + * background. A window with no background will never have its + * background filled by the windowing system, instead the window will + * contain whatever pixels were already in the corresponding area of + * the display. + * + * The windowing system will normally fill a window with its background + * when the window is obscured then exposed, and when you call + * gdk_window_clear(). + */ +void +gdk_window_set_back_pixmap (GdkWindow *window, + GdkPixmap *pixmap, + gboolean parent_relative) +{ + GdkWindowObject *private; + GdkWindowImplIface *impl_iface; + + g_return_if_fail (GDK_IS_WINDOW (window)); + g_return_if_fail (pixmap == NULL || !parent_relative); + g_return_if_fail (pixmap == NULL || gdk_drawable_get_depth (window) == gdk_drawable_get_depth (pixmap)); + + private = (GdkWindowObject *) window; + + if (pixmap && !gdk_drawable_get_colormap (pixmap)) + { + g_warning ("gdk_window_set_back_pixmap(): pixmap must have a colormap"); + return; + } + + if (private->bg_pixmap && + private->bg_pixmap != GDK_PARENT_RELATIVE_BG && + private->bg_pixmap != GDK_NO_BG) + g_object_unref (private->bg_pixmap); + + if (private->background) + { + cairo_pattern_destroy (private->background); + private->background = NULL; + } + + if (parent_relative) + private->bg_pixmap = GDK_PARENT_RELATIVE_BG; + else if (pixmap) + private->bg_pixmap = g_object_ref (pixmap); + else + private->bg_pixmap = GDK_NO_BG; + + if (!GDK_WINDOW_DESTROYED (window) && + gdk_window_has_impl (private) && + !private->input_only) + { + impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl); + impl_iface->set_back_pixmap (window, private->bg_pixmap); + } +} + +/** + * gdk_window_get_background_pattern: + * @window: a window + * + * Gets the pattern used to clear the background on @window. If @window + * does not have its own background and reuses the parent's, %NULL is + * returned and you'll have to query it yourself. + * + * Returns: (transfer none): The pattern to use for the background or + * %NULL to use the parent's background. + * + * Since: 2.22 + **/ +cairo_pattern_t * +gdk_window_get_background_pattern (GdkWindow *window) +{ + GdkWindowObject *private = (GdkWindowObject *) window; + + g_return_val_if_fail (GDK_IS_WINDOW (window), NULL); + + if (private->background == NULL) + { + if (private->bg_pixmap == GDK_PARENT_RELATIVE_BG) + private->background = NULL; + else if (private->bg_pixmap != GDK_NO_BG && + private->bg_pixmap != NULL) + { + static cairo_user_data_key_t key; + cairo_surface_t *surface; + + surface = _gdk_drawable_ref_cairo_surface (private->bg_pixmap); + private->background = cairo_pattern_create_for_surface (surface); + cairo_surface_destroy (surface); + + cairo_pattern_set_extend (private->background, CAIRO_EXTEND_REPEAT); + cairo_pattern_set_user_data (private->background, + &key, + g_object_ref (private->bg_pixmap), + g_object_unref); + } + else + private->background = + cairo_pattern_create_rgb (private->bg_color.red / 65535., + private->bg_color.green / 65535., + private->bg_color.blue / 65535.); + } + + return private->background; +} + +/** + * gdk_window_get_cursor: + * @window: a #GdkWindow + * + * Retrieves a #GdkCursor pointer for the cursor currently set on the + * specified #GdkWindow, or %NULL. If the return value is %NULL then + * there is no custom cursor set on the specified window, and it is + * using the cursor for its parent window. + * + * Return value: (transfer none): a #GdkCursor, or %NULL. The returned + * object is owned by the #GdkWindow and should not be unreferenced + * directly. Use gdk_window_set_cursor() to unset the cursor of the + * window + * + * Since: 2.18 + */ +GdkCursor * +gdk_window_get_cursor (GdkWindow *window) +{ + GdkWindowObject *private; + + g_return_val_if_fail (GDK_IS_WINDOW (window), NULL); + + private = (GdkWindowObject *) window; + + return private->cursor; +} + +/** + * gdk_window_set_cursor: + * @window: a #GdkWindow + * @cursor: (allow-none): a cursor + * + * Sets the mouse pointer for a #GdkWindow. Use gdk_cursor_new_for_display() + * or gdk_cursor_new_from_pixmap() to create the cursor. To make the cursor + * invisible, use %GDK_BLANK_CURSOR. Passing %NULL for the @cursor argument + * to gdk_window_set_cursor() means that @window will use the cursor of its + * parent window. Most windows should use this default. + */ +void +gdk_window_set_cursor (GdkWindow *window, + GdkCursor *cursor) +{ + GdkWindowObject *private; + GdkWindowImplIface *impl_iface; + GdkDisplay *display; + + g_return_if_fail (GDK_IS_WINDOW (window)); + + private = (GdkWindowObject *) window; + display = gdk_drawable_get_display (window); + + if (private->cursor) + { + gdk_cursor_unref (private->cursor); + private->cursor = NULL; + } + + if (!GDK_WINDOW_DESTROYED (window)) + { + if (cursor) + private->cursor = gdk_cursor_ref (cursor); + + if (_gdk_native_windows || + private->window_type == GDK_WINDOW_ROOT || + private->window_type == GDK_WINDOW_FOREIGN) + { + impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl); + impl_iface->set_cursor (window, cursor); + } + else if (_gdk_window_event_parent_of (window, display->pointer_info.window_under_pointer)) + update_cursor (display); + + g_object_notify (G_OBJECT (window), "cursor"); + } +} + +/** + * gdk_window_get_geometry: + * @window: a #GdkWindow + * @x: return location for X coordinate of window (relative to its parent) + * @y: return location for Y coordinate of window (relative to its parent) + * @width: return location for width of window + * @height: return location for height of window + * @depth: return location for bit depth of window + * + * Any of the return location arguments to this function may be %NULL, + * if you aren't interested in getting the value of that field. + * + * The X and Y coordinates returned are relative to the parent window + * of @window, which for toplevels usually means relative to the + * window decorations (titlebar, etc.) rather than relative to the + * root window (screen-size background window). + * + * On the X11 platform, the geometry is obtained from the X server, + * so reflects the latest position of @window; this may be out-of-sync + * with the position of @window delivered in the most-recently-processed + * #GdkEventConfigure. gdk_window_get_position() in contrast gets the + * position from the most recent configure event. + * + * + * If @window is not a toplevel, it is much better + * to call gdk_window_get_position() and gdk_drawable_get_size() instead, + * because it avoids the roundtrip to the X server and because + * gdk_drawable_get_size() supports the full 32-bit coordinate space, + * whereas gdk_window_get_geometry() is restricted to the 16-bit + * coordinates of X11. + * + **/ +void +gdk_window_get_geometry (GdkWindow *window, + gint *x, + gint *y, + gint *width, + gint *height, + gint *depth) +{ + GdkWindowObject *private, *parent; + GdkWindowImplIface *impl_iface; + + if (!window) + { + GDK_NOTE (MULTIHEAD, + g_message ("gdk_window_get_geometry(): Window needs " + "to be non-NULL to be multi head safe")); + window = gdk_screen_get_root_window ((gdk_screen_get_default ())); + } + + g_return_if_fail (GDK_IS_WINDOW (window)); + + private = (GdkWindowObject *) window; + + if (!GDK_WINDOW_DESTROYED (window)) + { + if (gdk_window_has_impl (private)) + { + impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl); + impl_iface->get_geometry (window, x, y, + width, height, + depth); + /* This reports the position wrt to the native parent, we need to convert + it to be relative to the client side parent */ + parent = private->parent; + if (parent && !gdk_window_has_impl (parent)) + { + if (x) + *x -= parent->abs_x; + if (y) + *y -= parent->abs_y; + } + } + else + { + if (x) + *x = private->x; + if (y) + *y = private->y; + if (width) + *width = private->width; + if (height) + *height = private->height; + if (depth) + *depth = private->depth; + } + } +} + +/** + * gdk_window_get_origin: + * @window: a #GdkWindow + * @x: return location for X coordinate + * @y: return location for Y coordinate + * + * Obtains the position of a window in root window coordinates. + * (Compare with gdk_window_get_position() and + * gdk_window_get_geometry() which return the position of a window + * relative to its parent window.) + * + * Return value: not meaningful, ignore + */ +gint +gdk_window_get_origin (GdkWindow *window, + gint *x, + gint *y) +{ + GdkWindowObject *private; + GdkWindowImplIface *impl_iface; + + g_return_val_if_fail (GDK_IS_WINDOW (window), 0); + + if (GDK_WINDOW_DESTROYED (window)) + { + if (x) + *x = 0; + if (y) + *y = 0; + return 0; + } + + private = (GdkWindowObject *) window; + + impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl); + impl_iface->get_root_coords (window, + private->abs_x, + private->abs_y, + x, y); + + return TRUE; +} + +/** + * gdk_window_get_root_coords: + * @window: a #GdkWindow + * @x: X coordinate in window + * @y: Y coordinate in window + * @root_x: (out): return location for X coordinate + * @root_y: (out): return location for Y coordinate + * + * Obtains the position of a window position in root + * window coordinates. This is similar to + * gdk_window_get_origin() but allows you go pass + * in any position in the window, not just the origin. + * + * Since: 2.18 + */ +void +gdk_window_get_root_coords (GdkWindow *window, + gint x, + gint y, + gint *root_x, + gint *root_y) +{ + GdkWindowObject *private; + GdkWindowImplIface *impl_iface; + + g_return_if_fail (GDK_IS_WINDOW (window)); + + private = (GdkWindowObject *) window; + + if (GDK_WINDOW_DESTROYED (window)) + { + if (x) + *root_x = x; + if (y) + *root_y = y; + return; + } + + impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl); + impl_iface->get_root_coords (window, + x + private->abs_x, + y + private->abs_y, + root_x, root_y); +} + +/** + * gdk_window_coords_to_parent: + * @window: a child window + * @x: X coordinate in child's coordinate system + * @y: Y coordinate in child's coordinate system + * @parent_x: (out) (allow-none): return location for X coordinate + * in parent's coordinate system, or %NULL + * @parent_y: (out) (allow-none): return location for Y coordinate + * in parent's coordinate system, or %NULL + * + * Transforms window coordinates from a child window to its parent + * window, where the parent window is the normal parent as returned by + * gdk_window_get_parent() for normal windows, and the window's + * embedder as returned by gdk_offscreen_window_get_embedder() for + * offscreen windows. + * + * For normal windows, calling this function is equivalent to adding + * the return values of gdk_window_get_position() to the child coordinates. + * For offscreen windows however (which can be arbitrarily transformed), + * this function calls the GdkWindow::to-embedder: signal to translate + * the coordinates. + * + * You should always use this function when writing generic code that + * walks up a window hierarchy. + * + * See also: gdk_window_coords_from_parent() + * + * Since: 2.22 + **/ +void +gdk_window_coords_to_parent (GdkWindow *window, + gdouble x, + gdouble y, + gdouble *parent_x, + gdouble *parent_y) +{ + GdkWindowObject *obj; + + g_return_if_fail (GDK_IS_WINDOW (window)); + + obj = (GdkWindowObject *) window; + + if (gdk_window_is_offscreen (obj)) + { + gdouble px, py; + + to_embedder (obj, x, y, &px, &py); + + if (parent_x) + *parent_x = px; + + if (parent_y) + *parent_y = py; + } + else + { + if (parent_x) + *parent_x = x + obj->x; + + if (parent_y) + *parent_y = y + obj->y; + } +} + +/** + * gdk_window_coords_from_parent: + * @window: a child window + * @parent_x: X coordinate in parent's coordinate system + * @parent_y: Y coordinate in parent's coordinate system + * @x: (out) (allow-none): return location for X coordinate in child's coordinate system + * @y: (out) (allow-none): return location for Y coordinate in child's coordinate system + * + * Transforms window coordinates from a parent window to a child + * window, where the parent window is the normal parent as returned by + * gdk_window_get_parent() for normal windows, and the window's + * embedder as returned by gdk_offscreen_window_get_embedder() for + * offscreen windows. + * + * For normal windows, calling this function is equivalent to subtracting + * the return values of gdk_window_get_position() from the parent coordinates. + * For offscreen windows however (which can be arbitrarily transformed), + * this function calls the GdkWindow::from-embedder: signal to translate + * the coordinates. + * + * You should always use this function when writing generic code that + * walks down a window hierarchy. + * + * See also: gdk_window_coords_to_parent() + * + * Since: 2.22 + **/ +void +gdk_window_coords_from_parent (GdkWindow *window, + gdouble parent_x, + gdouble parent_y, + gdouble *x, + gdouble *y) +{ + GdkWindowObject *obj; + + g_return_if_fail (GDK_IS_WINDOW (window)); + + obj = (GdkWindowObject *) window; + + if (gdk_window_is_offscreen (obj)) + { + gdouble cx, cy; + + from_embedder (obj, parent_x, parent_y, &cx, &cy); + + if (x) + *x = cx; + + if (y) + *y = cy; + } + else + { + if (x) + *x = parent_x - obj->x; + + if (y) + *y = parent_y - obj->y; + } +} + +/** + * gdk_window_get_deskrelative_origin: + * @window: a toplevel #GdkWindow + * @x: return location for X coordinate + * @y: return location for Y coordinate + * + * This gets the origin of a #GdkWindow relative to + * an Enlightenment-window-manager desktop. As long as you don't + * assume that the user's desktop/workspace covers the entire + * root window (i.e. you don't assume that the desktop begins + * at root window coordinate 0,0) this function is not necessary. + * It's deprecated for that reason. + * + * Return value: not meaningful + **/ +gboolean +gdk_window_get_deskrelative_origin (GdkWindow *window, + gint *x, + gint *y) +{ + GdkWindowObject *private; + GdkWindowImplIface *impl_iface; + gboolean return_val = FALSE; + gint tx = 0; + gint ty = 0; + + g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE); + + private = (GdkWindowObject *) window; + + if (!GDK_WINDOW_DESTROYED (window)) + { + impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl); + return_val = impl_iface->get_deskrelative_origin (window, &tx, &ty); + + if (x) + *x = tx + private->abs_x; + if (y) + *y = ty + private->abs_y; + } + + return return_val; +} + +/** + * gdk_window_shape_combine_mask: + * @window: a #GdkWindow + * @mask: shape mask + * @x: X position of shape mask with respect to @window + * @y: Y position of shape mask with respect to @window + * + * Applies a shape mask to @window. Pixels in @window corresponding to + * set bits in the @mask will be visible; pixels in @window + * corresponding to unset bits in the @mask will be transparent. This + * gives a non-rectangular window. + * + * If @mask is %NULL, the shape mask will be unset, and the @x/@y + * parameters are not used. + * + * On the X11 platform, this uses an X server extension which is + * widely available on most common platforms, but not available on + * very old X servers, and occasionally the implementation will be + * buggy. On servers without the shape extension, this function + * will do nothing. + * + * This function works on both toplevel and child windows. + */ +void +gdk_window_shape_combine_mask (GdkWindow *window, + GdkBitmap *mask, + gint x, + gint y) +{ + GdkWindowObject *private; + GdkRegion *region; + + g_return_if_fail (GDK_IS_WINDOW (window)); + + private = (GdkWindowObject *) window; + + if (mask) + region = _gdk_windowing_get_shape_for_mask (mask); + else + region = NULL; + + gdk_window_shape_combine_region (window, + region, + x, y); + + if (region) + gdk_region_destroy (region); +} + +/** + * gdk_window_shape_combine_region: + * @window: a #GdkWindow + * @shape_region: region of window to be non-transparent + * @offset_x: X position of @shape_region in @window coordinates + * @offset_y: Y position of @shape_region in @window coordinates + * + * Makes pixels in @window outside @shape_region be transparent, + * so that the window may be nonrectangular. See also + * gdk_window_shape_combine_mask() to use a bitmap as the mask. + * + * If @shape_region is %NULL, the shape will be unset, so the whole + * window will be opaque again. @offset_x and @offset_y are ignored + * if @shape_region is %NULL. + * + * On the X11 platform, this uses an X server extension which is + * widely available on most common platforms, but not available on + * very old X servers, and occasionally the implementation will be + * buggy. On servers without the shape extension, this function + * will do nothing. + * + * This function works on both toplevel and child windows. + */ +void +gdk_window_shape_combine_region (GdkWindow *window, + const GdkRegion *shape_region, + gint offset_x, + gint offset_y) +{ + GdkWindowObject *private; + GdkRegion *old_region, *new_region, *diff; + + g_return_if_fail (GDK_IS_WINDOW (window)); + + private = (GdkWindowObject *) window; + + if (GDK_WINDOW_DESTROYED (window)) + return; + + if (!private->shaped && shape_region == NULL) + return; + + private->shaped = (shape_region != NULL); + + if (private->shape) + gdk_region_destroy (private->shape); + + old_region = NULL; + if (GDK_WINDOW_IS_MAPPED (window)) + old_region = gdk_region_copy (private->clip_region); + + if (shape_region) + { + private->shape = gdk_region_copy (shape_region); + gdk_region_offset (private->shape, offset_x, offset_y); + } + else + private->shape = NULL; + + recompute_visible_regions (private, TRUE, FALSE); + + if (gdk_window_has_impl (private) && + !should_apply_clip_as_shape (private)) + apply_shape (private, private->shape); + + if (old_region) + { + new_region = gdk_region_copy (private->clip_region); + + /* New area in the window, needs invalidation */ + diff = gdk_region_copy (new_region); + gdk_region_subtract (diff, old_region); + + gdk_window_invalidate_region_full (window, diff, TRUE, CLEAR_BG_ALL); + + gdk_region_destroy (diff); + + if (!gdk_window_is_toplevel (private)) + { + /* New area in the non-root parent window, needs invalidation */ + diff = gdk_region_copy (old_region); + gdk_region_subtract (diff, new_region); + + /* Adjust region to parent window coords */ + gdk_region_offset (diff, private->x, private->y); + + gdk_window_invalidate_region_full (GDK_WINDOW (private->parent), diff, TRUE, CLEAR_BG_ALL); + + gdk_region_destroy (diff); + } + + gdk_region_destroy (new_region); + gdk_region_destroy (old_region); + } +} + +static void +do_child_shapes (GdkWindow *window, + gboolean merge) +{ + GdkWindowObject *private; + GdkRectangle r; + GdkRegion *region; + + private = (GdkWindowObject *) window; + + r.x = 0; + r.y = 0; + r.width = private->width; + r.height = private->height; + + region = gdk_region_rectangle (&r); + remove_child_area (private, NULL, FALSE, region); + + if (merge && private->shape) + gdk_region_subtract (region, private->shape); + + gdk_window_shape_combine_region (window, region, 0, 0); + + gdk_region_destroy (region); +} + +/** + * gdk_window_set_child_shapes: + * @window: a #GdkWindow + * + * Sets the shape mask of @window to the union of shape masks + * for all children of @window, ignoring the shape mask of @window + * itself. Contrast with gdk_window_merge_child_shapes() which includes + * the shape mask of @window in the masks to be merged. + **/ +void +gdk_window_set_child_shapes (GdkWindow *window) +{ + g_return_if_fail (GDK_IS_WINDOW (window)); + + do_child_shapes (window, FALSE); +} + +/** + * gdk_window_merge_child_shapes: + * @window: a #GdkWindow + * + * Merges the shape masks for any child windows into the + * shape mask for @window. i.e. the union of all masks + * for @window and its children will become the new mask + * for @window. See gdk_window_shape_combine_mask(). + * + * This function is distinct from gdk_window_set_child_shapes() + * because it includes @window's shape mask in the set of shapes to + * be merged. + */ +void +gdk_window_merge_child_shapes (GdkWindow *window) +{ + g_return_if_fail (GDK_IS_WINDOW (window)); + + do_child_shapes (window, TRUE); +} + +/** + * gdk_window_input_shape_combine_mask: + * @window: a #GdkWindow + * @mask: (allow-none): shape mask, or %NULL + * @x: X position of shape mask with respect to @window + * @y: Y position of shape mask with respect to @window + * + * Like gdk_window_shape_combine_mask(), but the shape applies + * only to event handling. Mouse events which happen while + * the pointer position corresponds to an unset bit in the + * mask will be passed on the window below @window. + * + * An input shape is typically used with RGBA windows. + * The alpha channel of the window defines which pixels are + * invisible and allows for nicely antialiased borders, + * and the input shape controls where the window is + * "clickable". + * + * On the X11 platform, this requires version 1.1 of the + * shape extension. + * + * On the Win32 platform, this functionality is not present and the + * function does nothing. + * + * Since: 2.10 + */ +void +gdk_window_input_shape_combine_mask (GdkWindow *window, + GdkBitmap *mask, + gint x, + gint y) +{ + GdkWindowObject *private; + GdkRegion *region; + + g_return_if_fail (GDK_IS_WINDOW (window)); + + private = (GdkWindowObject *) window; + + if (mask) + region = _gdk_windowing_get_shape_for_mask (mask); + else + region = NULL; + + gdk_window_input_shape_combine_region (window, + region, + x, y); + + if (region != NULL) + gdk_region_destroy (region); +} + +/** + * gdk_window_input_shape_combine_region: + * @window: a #GdkWindow + * @shape_region: region of window to be non-transparent + * @offset_x: X position of @shape_region in @window coordinates + * @offset_y: Y position of @shape_region in @window coordinates + * + * Like gdk_window_shape_combine_region(), but the shape applies + * only to event handling. Mouse events which happen while + * the pointer position corresponds to an unset bit in the + * mask will be passed on the window below @window. + * + * An input shape is typically used with RGBA windows. + * The alpha channel of the window defines which pixels are + * invisible and allows for nicely antialiased borders, + * and the input shape controls where the window is + * "clickable". + * + * On the X11 platform, this requires version 1.1 of the + * shape extension. + * + * On the Win32 platform, this functionality is not present and the + * function does nothing. + * + * Since: 2.10 + */ +void +gdk_window_input_shape_combine_region (GdkWindow *window, + const GdkRegion *shape_region, + gint offset_x, + gint offset_y) +{ + GdkWindowObject *private; + GdkWindowImplIface *impl_iface; + + g_return_if_fail (GDK_IS_WINDOW (window)); + + private = (GdkWindowObject *) window; + + if (GDK_WINDOW_DESTROYED (window)) + return; + + if (private->input_shape) + gdk_region_destroy (private->input_shape); + + if (shape_region) + { + private->input_shape = gdk_region_copy (shape_region); + gdk_region_offset (private->input_shape, offset_x, offset_y); + } + else + private->input_shape = NULL; + + if (gdk_window_has_impl (private)) + { + impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl); + impl_iface->input_shape_combine_region (window, private->input_shape, 0, 0); + } + + /* Pointer may have e.g. moved outside window due to the input mask change */ + _gdk_synthesize_crossing_events_for_geometry_change (window); +} + +static void +do_child_input_shapes (GdkWindow *window, + gboolean merge) +{ + GdkWindowObject *private; + GdkRectangle r; + GdkRegion *region; + + private = (GdkWindowObject *) window; + + r.x = 0; + r.y = 0; + r.width = private->width; + r.height = private->height; + + region = gdk_region_rectangle (&r); + remove_child_area (private, NULL, TRUE, region); + + if (merge && private->shape) + gdk_region_subtract (region, private->shape); + if (merge && private->input_shape) + gdk_region_subtract (region, private->input_shape); + + gdk_window_input_shape_combine_region (window, region, 0, 0); +} + + +/** + * gdk_window_set_child_input_shapes: + * @window: a #GdkWindow + * + * Sets the input shape mask of @window to the union of input shape masks + * for all children of @window, ignoring the input shape mask of @window + * itself. Contrast with gdk_window_merge_child_input_shapes() which includes + * the input shape mask of @window in the masks to be merged. + * + * Since: 2.10 + **/ +void +gdk_window_set_child_input_shapes (GdkWindow *window) +{ + g_return_if_fail (GDK_IS_WINDOW (window)); + + do_child_input_shapes (window, FALSE); +} + +/** + * gdk_window_merge_child_input_shapes: + * @window: a #GdkWindow + * + * Merges the input shape masks for any child windows into the + * input shape mask for @window. i.e. the union of all input masks + * for @window and its children will become the new input mask + * for @window. See gdk_window_input_shape_combine_mask(). + * + * This function is distinct from gdk_window_set_child_input_shapes() + * because it includes @window's input shape mask in the set of + * shapes to be merged. + * + * Since: 2.10 + **/ +void +gdk_window_merge_child_input_shapes (GdkWindow *window) +{ + g_return_if_fail (GDK_IS_WINDOW (window)); + + do_child_input_shapes (window, TRUE); +} + + +/** + * gdk_window_set_static_gravities: + * @window: a #GdkWindow + * @use_static: %TRUE to turn on static gravity + * + * Set the bit gravity of the given window to static, and flag it so + * all children get static subwindow gravity. This is used if you are + * implementing scary features that involve deep knowledge of the + * windowing system. Don't worry about it unless you have to. + * + * Return value: %TRUE if the server supports static gravity + */ +gboolean +gdk_window_set_static_gravities (GdkWindow *window, + gboolean use_static) +{ + GdkWindowObject *private; + GdkWindowImplIface *impl_iface; + + g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE); + + private = (GdkWindowObject *) window; + + if (gdk_window_has_impl (private)) + { + impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl); + return impl_iface->set_static_gravities (window, use_static); + } + + return FALSE; +} + +/** + * gdk_window_get_composited: + * @window: a #GdkWindow + * + * Determines whether @window is composited. + * + * See gdk_window_set_composited(). + * + * Returns: %TRUE if the window is composited. + * + * Since: 2.22 + **/ +gboolean +gdk_window_get_composited (GdkWindow *window) +{ + GdkWindowObject *private; + + g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE); + + private = (GdkWindowObject *)window; + + return private->composited; +} + +/** + * gdk_window_set_composited: + * @window: a #GdkWindow + * @composited: %TRUE to set the window as composited + * + * Sets a #GdkWindow as composited, or unsets it. Composited + * windows do not automatically have their contents drawn to + * the screen. Drawing is redirected to an offscreen buffer + * and an expose event is emitted on the parent of the composited + * window. It is the responsibility of the parent's expose handler + * to manually merge the off-screen content onto the screen in + * whatever way it sees fit. See + * for an example. + * + * It only makes sense for child windows to be composited; see + * gdk_window_set_opacity() if you need translucent toplevel + * windows. + * + * An additional effect of this call is that the area of this + * window is no longer clipped from regions marked for + * invalidation on its parent. Draws done on the parent + * window are also no longer clipped by the child. + * + * This call is only supported on some systems (currently, + * only X11 with new enough Xcomposite and Xdamage extensions). + * You must call gdk_display_supports_composite() to check if + * setting a window as composited is supported before + * attempting to do so. + * + * Since: 2.12 + */ +void +gdk_window_set_composited (GdkWindow *window, + gboolean composited) +{ + GdkWindowObject *private = (GdkWindowObject *)window; + GdkDisplay *display; + + g_return_if_fail (GDK_IS_WINDOW (window)); + + composited = composited != FALSE; + + if (private->composited == composited) + return; + + if (composited) + gdk_window_ensure_native (window); + + display = gdk_drawable_get_display (GDK_DRAWABLE (window)); + + if (!gdk_display_supports_composite (display) && composited) + { + g_warning ("gdk_window_set_composited called but " + "compositing is not supported"); + return; + } + + _gdk_windowing_window_set_composited (window, composited); + + recompute_visible_regions (private, TRUE, FALSE); + + if (GDK_WINDOW_IS_MAPPED (window)) + gdk_window_invalidate_in_parent (private); + + private->composited = composited; +} + + +static void +remove_redirect_from_children (GdkWindowObject *private, + GdkWindowRedirect *redirect) +{ + GList *l; + GdkWindowObject *child; + + for (l = private->children; l != NULL; l = l->next) + { + child = l->data; + + /* Don't redirect this child if it already has another redirect */ + if (child->redirect == redirect) + { + child->redirect = NULL; + remove_redirect_from_children (child, redirect); + } + } +} + +/** + * gdk_window_remove_redirection: + * @window: a #GdkWindow + * + * Removes any active redirection started by + * gdk_window_redirect_to_drawable(). + * + * Since: 2.14 + **/ +void +gdk_window_remove_redirection (GdkWindow *window) +{ + GdkWindowObject *private; + + g_return_if_fail (GDK_IS_WINDOW (window)); + + private = (GdkWindowObject *) window; + + if (private->redirect && + private->redirect->redirected == private) + { + remove_redirect_from_children (private, private->redirect); + gdk_window_redirect_free (private->redirect); + private->redirect = NULL; + } +} + +/** + * gdk_window_get_modal_hint: + * @window: A toplevel #GdkWindow. + * + * Determines whether or not the window manager is hinted that @window + * has modal behaviour. + * + * Return value: whether or not the window has the modal hint set. + * + * Since: 2.22 + */ +gboolean +gdk_window_get_modal_hint (GdkWindow *window) +{ + GdkWindowObject *private; + + g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE); + + private = (GdkWindowObject*) window; + + return private->modal_hint; +} + +/** + * gdk_window_get_accept_focus: + * @window: a toplevel #GdkWindow. + * + * Determines whether or not the desktop environment shuld be hinted that + * the window does not want to receive input focus. + * + * Return value: whether or not the window should receive input focus. + * + * Since: 2.22 + */ +gboolean +gdk_window_get_accept_focus (GdkWindow *window) +{ + GdkWindowObject *private; + + g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE); + + private = (GdkWindowObject *)window; + + return private->accept_focus; +} + +/** + * gdk_window_get_focus_on_map: + * @window: a toplevel #GdkWindow. + * + * Determines whether or not the desktop environment should be hinted that the + * window does not want to receive input focus when it is mapped. + * + * Return value: whether or not the window wants to receive input focus when + * it is mapped. + * + * Since: 2.22 + */ +gboolean +gdk_window_get_focus_on_map (GdkWindow *window) +{ + GdkWindowObject *private; + + g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE); + + private = (GdkWindowObject *)window; + + return private->focus_on_map; +} + +/** + * gdk_window_is_input_only: + * @window: a toplevel #GdkWindow + * + * Determines whether or not the window is an input only window. + * + * Return value: %TRUE if @window is input only + * + * Since: 2.22 + */ +gboolean +gdk_window_is_input_only (GdkWindow *window) +{ + GdkWindowObject *private; + + g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE); + + private = (GdkWindowObject *)window; + + return private->input_only; +} + +/** + * gdk_window_is_shaped: + * @window: a toplevel #GdkWindow + * + * Determines whether or not the window is shaped. + * + * Return value: %TRUE if @window is shaped + * + * Since: 2.22 + */ +gboolean +gdk_window_is_shaped (GdkWindow *window) +{ + GdkWindowObject *private; + + g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE); + + private = (GdkWindowObject *)window; + + return private->shaped; +} + +static void +apply_redirect_to_children (GdkWindowObject *private, + GdkWindowRedirect *redirect) +{ + GList *l; + GdkWindowObject *child; + + for (l = private->children; l != NULL; l = l->next) + { + child = l->data; + + /* Don't redirect this child if it already has another redirect */ + if (!child->redirect) + { + child->redirect = redirect; + apply_redirect_to_children (child, redirect); + } + } +} + +/** + * gdk_window_redirect_to_drawable: + * @window: a #GdkWindow + * @drawable: a #GdkDrawable + * @src_x: x position in @window + * @src_y: y position in @window + * @dest_x: x position in @drawable + * @dest_y: y position in @drawable + * @width: width of redirection, or -1 to use the width of @window + * @height: height of redirection or -1 to use the height of @window + * + * Redirects drawing into @window so that drawing to the + * window in the rectangle specified by @src_x, @src_y, + * @width and @height is also drawn into @drawable at + * @dest_x, @dest_y. + * + * Only drawing between gdk_window_begin_paint_region() or + * gdk_window_begin_paint_rect() and gdk_window_end_paint() is + * redirected. + * + * Redirection is active until gdk_window_remove_redirection() + * is called. + * + * Since: 2.14 + **/ +void +gdk_window_redirect_to_drawable (GdkWindow *window, + GdkDrawable *drawable, + gint src_x, + gint src_y, + gint dest_x, + gint dest_y, + gint width, + gint height) +{ + GdkWindowObject *private; + + g_return_if_fail (GDK_IS_WINDOW (window)); + g_return_if_fail (GDK_IS_DRAWABLE (drawable)); + g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_ROOT); + + private = (GdkWindowObject *) window; + + if (private->redirect) + gdk_window_remove_redirection (window); + + if (width == -1 || height == -1) + { + gint w, h; + gdk_drawable_get_size (GDK_DRAWABLE (window), &w, &h); + if (width == -1) + width = w; + if (height == -1) + height = h; + } + + private->redirect = g_new0 (GdkWindowRedirect, 1); + private->redirect->redirected = private; + private->redirect->pixmap = g_object_ref (drawable); + private->redirect->src_x = src_x; + private->redirect->src_y = src_y; + private->redirect->dest_x = dest_x; + private->redirect->dest_y = dest_y; + private->redirect->width = width; + private->redirect->height = height; + + apply_redirect_to_children (private, private->redirect); +} + +static void +window_get_size_rectangle (GdkWindow *window, + GdkRectangle *rect) +{ + GdkWindowObject *private = (GdkWindowObject *) window; + + rect->x = rect->y = 0; + rect->width = private->width; + rect->height = private->height; +} + +/* Calculates the real clipping region for a window, in window coordinates, + * taking into account other windows, gc clip region and gc clip mask. + */ +GdkRegion * +_gdk_window_calculate_full_clip_region (GdkWindow *window, + GdkWindow *base_window, + gboolean do_children, + gint *base_x_offset, + gint *base_y_offset) +{ + GdkWindowObject *private = GDK_WINDOW_OBJECT (window); + GdkRectangle visible_rect; + GdkRegion *real_clip_region, *tmpreg; + gint x_offset, y_offset; + GdkWindowObject *parentwin, *lastwin; + + if (base_x_offset) + *base_x_offset = 0; + if (base_y_offset) + *base_y_offset = 0; + + if (!private->viewable || private->input_only) + return gdk_region_new (); + + window_get_size_rectangle (window, &visible_rect); + + /* real_clip_region is in window coordinates */ + real_clip_region = gdk_region_rectangle (&visible_rect); + + x_offset = y_offset = 0; + + lastwin = private; + if (do_children) + parentwin = lastwin; + else + parentwin = lastwin->parent; + + /* Remove the areas of all overlapping windows above parentwin in the hiearachy */ + for (; parentwin != NULL && + (parentwin == private || lastwin != (GdkWindowObject*) base_window); + lastwin = parentwin, parentwin = lastwin->parent) + { + GList *cur; + GdkRectangle real_clip_rect; + + if (parentwin != private) + { + x_offset += GDK_WINDOW_OBJECT (lastwin)->x; + y_offset += GDK_WINDOW_OBJECT (lastwin)->y; + } + + /* children is ordered in reverse stack order */ + for (cur = parentwin->children; + cur && cur->data != lastwin; + cur = cur->next) + { + GdkWindow *child = cur->data; + GdkWindowObject *child_private = (GdkWindowObject *)child; + + if (!GDK_WINDOW_IS_MAPPED (child) || child_private->input_only) + continue; + + /* Ignore offscreen children, as they don't draw in their parent and + * don't take part in the clipping */ + if (gdk_window_is_offscreen (child_private)) + continue; + + window_get_size_rectangle (child, &visible_rect); + + /* Convert rect to "window" coords */ + visible_rect.x += child_private->x - x_offset; + visible_rect.y += child_private->y - y_offset; + + /* This shortcut is really necessary for performance when there are a lot of windows */ + gdk_region_get_clipbox (real_clip_region, &real_clip_rect); + if (visible_rect.x >= real_clip_rect.x + real_clip_rect.width || + visible_rect.x + visible_rect.width <= real_clip_rect.x || + visible_rect.y >= real_clip_rect.y + real_clip_rect.height || + visible_rect.y + visible_rect.height <= real_clip_rect.y) + continue; + + tmpreg = gdk_region_rectangle (&visible_rect); + gdk_region_subtract (real_clip_region, tmpreg); + gdk_region_destroy (tmpreg); + } + + /* Clip to the parent */ + window_get_size_rectangle ((GdkWindow *)parentwin, &visible_rect); + /* Convert rect to "window" coords */ + visible_rect.x += - x_offset; + visible_rect.y += - y_offset; + + tmpreg = gdk_region_rectangle (&visible_rect); + gdk_region_intersect (real_clip_region, tmpreg); + gdk_region_destroy (tmpreg); + } + + if (base_x_offset) + *base_x_offset = x_offset; + if (base_y_offset) + *base_y_offset = y_offset; + + return real_clip_region; +} + +void +_gdk_window_add_damage (GdkWindow *toplevel, + GdkRegion *damaged_region) +{ + GdkDisplay *display; + GdkEvent event = { 0, }; + event.expose.type = GDK_DAMAGE; + event.expose.window = toplevel; + event.expose.send_event = FALSE; + event.expose.region = damaged_region; + gdk_region_get_clipbox (event.expose.region, &event.expose.area); + display = gdk_drawable_get_display (event.expose.window); + _gdk_event_queue_append (display, gdk_event_copy (&event)); +} + +static void +gdk_window_redirect_free (GdkWindowRedirect *redirect) +{ + g_object_unref (redirect->pixmap); + g_free (redirect); +} + +/* Gets the toplevel for a window as used for events, + i.e. including offscreen parents */ +static GdkWindowObject * +get_event_parent (GdkWindowObject *window) +{ + if (gdk_window_is_offscreen (window)) + return (GdkWindowObject *)gdk_offscreen_window_get_embedder ((GdkWindow *)window); + else + return window->parent; +} + +/* Gets the toplevel for a window as used for events, + i.e. including offscreen parents going up to the native + toplevel */ +static GdkWindow * +get_event_toplevel (GdkWindow *w) +{ + GdkWindowObject *private = GDK_WINDOW_OBJECT (w); + GdkWindowObject *parent; + + while ((parent = get_event_parent (private)) != NULL && + (parent->window_type != GDK_WINDOW_ROOT)) + private = parent; + + return GDK_WINDOW (private); +} + +gboolean +_gdk_window_event_parent_of (GdkWindow *parent, + GdkWindow *child) +{ + GdkWindow *w; + + w = child; + while (w != NULL) + { + if (w == parent) + return TRUE; + + w = (GdkWindow *)get_event_parent ((GdkWindowObject *)w); + } + + return FALSE; +} + +static void +update_cursor (GdkDisplay *display) +{ + GdkWindowObject *cursor_window, *parent, *toplevel; + GdkWindow *pointer_window; + GdkWindowImplIface *impl_iface; + GdkPointerGrabInfo *grab; + + pointer_window = display->pointer_info.window_under_pointer; + + /* We ignore the serials here and just pick the last grab + we've sent, as that would shortly be used anyway. */ + grab = _gdk_display_get_last_pointer_grab (display); + if (/* have grab */ + grab != NULL && + /* the pointer is not in a descendant of the grab window */ + !_gdk_window_event_parent_of (grab->window, pointer_window)) + /* use the cursor from the grab window */ + cursor_window = (GdkWindowObject *)grab->window; + else + /* otherwise use the cursor from the pointer window */ + cursor_window = (GdkWindowObject *)pointer_window; + + /* Find the first window with the cursor actually set, as + the cursor is inherited from the parent */ + while (cursor_window->cursor == NULL && + (parent = get_event_parent (cursor_window)) != NULL && + parent->window_type != GDK_WINDOW_ROOT) + cursor_window = parent; + + /* Set all cursors on toplevel, otherwise its tricky to keep track of + * which native window has what cursor set. */ + toplevel = (GdkWindowObject *)get_event_toplevel (pointer_window); + impl_iface = GDK_WINDOW_IMPL_GET_IFACE (toplevel->impl); + impl_iface->set_cursor ((GdkWindow *)toplevel, cursor_window->cursor); +} + +static gboolean +point_in_window (GdkWindowObject *window, + gdouble x, + gdouble y) +{ + return + x >= 0 && x < window->width && + y >= 0 && y < window->height && + (window->shape == NULL || + gdk_region_point_in (window->shape, + x, y)) && + (window->input_shape == NULL || + gdk_region_point_in (window->input_shape, + x, y)); +} + +static GdkWindow * +convert_native_coords_to_toplevel (GdkWindow *window, + gdouble child_x, + gdouble child_y, + gdouble *toplevel_x, + gdouble *toplevel_y) +{ + GdkWindowObject *private = (GdkWindowObject *)window; + gdouble x, y; + + x = child_x; + y = child_y; + + while (!gdk_window_is_toplevel (private)) + { + x += private->x; + y += private->y; + private = private->parent; + } + + *toplevel_x = x; + *toplevel_y = y; + + return (GdkWindow *)private; +} + +static void +convert_toplevel_coords_to_window (GdkWindow *window, + gdouble toplevel_x, + gdouble toplevel_y, + gdouble *window_x, + gdouble *window_y) +{ + GdkWindowObject *private; + GdkWindowObject *parent; + gdouble x, y; + GList *children, *l; + + private = GDK_WINDOW_OBJECT (window); + + x = toplevel_x; + y = toplevel_y; + + children = NULL; + while ((parent = get_event_parent (private)) != NULL && + (parent->window_type != GDK_WINDOW_ROOT)) + { + children = g_list_prepend (children, private); + private = parent; + } + + for (l = children; l != NULL; l = l->next) + gdk_window_coords_from_parent (l->data, x, y, &x, &y); + + g_list_free (children); + + *window_x = x; + *window_y = y; +} + +static GdkWindowObject * +pick_embedded_child (GdkWindowObject *window, + gdouble x, + gdouble y) +{ + GdkWindowObject *res; + + res = NULL; + g_signal_emit (window, + signals[PICK_EMBEDDED_CHILD], 0, + x, y, &res); + + return res; +} + +GdkWindow * +_gdk_window_find_child_at (GdkWindow *window, + int x, + int y) +{ + GdkWindowObject *private, *sub; + double child_x, child_y; + GList *l; + + private = (GdkWindowObject *)window; + + if (point_in_window (private, x, y)) + { + /* Children is ordered in reverse stack order, i.e. first is topmost */ + for (l = private->children; l != NULL; l = l->next) + { + sub = l->data; + + if (!GDK_WINDOW_IS_MAPPED (sub)) + continue; + + gdk_window_coords_from_parent ((GdkWindow *)sub, + x, y, + &child_x, &child_y); + if (point_in_window (sub, child_x, child_y)) + return (GdkWindow *)sub; + } + + if (private->num_offscreen_children > 0) + { + sub = pick_embedded_child (private, + x, y); + if (sub) + return (GdkWindow *)sub; + } + } + + return NULL; +} + +GdkWindow * +_gdk_window_find_descendant_at (GdkWindow *toplevel, + gdouble x, + gdouble y, + gdouble *found_x, + gdouble *found_y) +{ + GdkWindowObject *private, *sub; + gdouble child_x, child_y; + GList *l; + gboolean found; + + private = (GdkWindowObject *)toplevel; + + if (point_in_window (private, x, y)) + { + do + { + found = FALSE; + /* Children is ordered in reverse stack order, i.e. first is topmost */ + for (l = private->children; l != NULL; l = l->next) + { + sub = l->data; + + if (!GDK_WINDOW_IS_MAPPED (sub)) + continue; + + gdk_window_coords_from_parent ((GdkWindow *)sub, + x, y, + &child_x, &child_y); + if (point_in_window (sub, child_x, child_y)) + { + x = child_x; + y = child_y; + private = sub; + found = TRUE; + break; + } + } + if (!found && + private->num_offscreen_children > 0) + { + sub = pick_embedded_child (private, + x, y); + if (sub) + { + found = TRUE; + private = sub; + from_embedder (sub, x, y, &x, &y); + } + } + } + while (found); + } + else + { + /* Not in window at all */ + private = NULL; + } + + if (found_x) + *found_x = x; + if (found_y) + *found_y = y; + + return (GdkWindow *)private; +} + +/** + * gdk_window_beep: + * @window: a toplevel #GdkWindow + * + * Emits a short beep associated to @window in the appropriate + * display, if supported. Otherwise, emits a short beep on + * the display just as gdk_display_beep(). + * + * Since: 2.12 + **/ +void +gdk_window_beep (GdkWindow *window) +{ + GdkDisplay *display; + GdkWindow *toplevel; + + g_return_if_fail (GDK_IS_WINDOW (window)); + + if (GDK_WINDOW_DESTROYED (window)) + return; + + toplevel = get_event_toplevel (window); + display = gdk_drawable_get_display (GDK_DRAWABLE (window)); + + if (toplevel && !gdk_window_is_offscreen ((GdkWindowObject *)toplevel)) + _gdk_windowing_window_beep (toplevel); + else + gdk_display_beep (display); +} + +static const guint type_masks[] = { + GDK_SUBSTRUCTURE_MASK, /* GDK_DELETE = 0 */ + GDK_STRUCTURE_MASK, /* GDK_DESTROY = 1 */ + GDK_EXPOSURE_MASK, /* GDK_EXPOSE = 2 */ + GDK_POINTER_MOTION_MASK, /* GDK_MOTION_NOTIFY = 3 */ + GDK_BUTTON_PRESS_MASK, /* GDK_BUTTON_PRESS = 4 */ + GDK_BUTTON_PRESS_MASK, /* GDK_2BUTTON_PRESS = 5 */ + GDK_BUTTON_PRESS_MASK, /* GDK_3BUTTON_PRESS = 6 */ + GDK_BUTTON_RELEASE_MASK, /* GDK_BUTTON_RELEASE = 7 */ + GDK_KEY_PRESS_MASK, /* GDK_KEY_PRESS = 8 */ + GDK_KEY_RELEASE_MASK, /* GDK_KEY_RELEASE = 9 */ + GDK_ENTER_NOTIFY_MASK, /* GDK_ENTER_NOTIFY = 10 */ + GDK_LEAVE_NOTIFY_MASK, /* GDK_LEAVE_NOTIFY = 11 */ + GDK_FOCUS_CHANGE_MASK, /* GDK_FOCUS_CHANGE = 12 */ + GDK_STRUCTURE_MASK, /* GDK_CONFIGURE = 13 */ + GDK_VISIBILITY_NOTIFY_MASK, /* GDK_MAP = 14 */ + GDK_VISIBILITY_NOTIFY_MASK, /* GDK_UNMAP = 15 */ + GDK_PROPERTY_CHANGE_MASK, /* GDK_PROPERTY_NOTIFY = 16 */ + GDK_PROPERTY_CHANGE_MASK, /* GDK_SELECTION_CLEAR = 17 */ + GDK_PROPERTY_CHANGE_MASK, /* GDK_SELECTION_REQUEST = 18 */ + GDK_PROPERTY_CHANGE_MASK, /* GDK_SELECTION_NOTIFY = 19 */ + GDK_PROXIMITY_IN_MASK, /* GDK_PROXIMITY_IN = 20 */ + GDK_PROXIMITY_OUT_MASK, /* GDK_PROXIMITY_OUT = 21 */ + GDK_ALL_EVENTS_MASK, /* GDK_DRAG_ENTER = 22 */ + GDK_ALL_EVENTS_MASK, /* GDK_DRAG_LEAVE = 23 */ + GDK_ALL_EVENTS_MASK, /* GDK_DRAG_MOTION = 24 */ + GDK_ALL_EVENTS_MASK, /* GDK_DRAG_STATUS = 25 */ + GDK_ALL_EVENTS_MASK, /* GDK_DROP_START = 26 */ + GDK_ALL_EVENTS_MASK, /* GDK_DROP_FINISHED = 27 */ + GDK_ALL_EVENTS_MASK, /* GDK_CLIENT_EVENT = 28 */ + GDK_VISIBILITY_NOTIFY_MASK, /* GDK_VISIBILITY_NOTIFY = 29 */ + GDK_EXPOSURE_MASK, /* GDK_NO_EXPOSE = 30 */ + GDK_SCROLL_MASK | GDK_BUTTON_PRESS_MASK,/* GDK_SCROLL= 31 */ + 0, /* GDK_WINDOW_STATE = 32 */ + 0, /* GDK_SETTING = 33 */ + 0, /* GDK_OWNER_CHANGE = 34 */ + 0, /* GDK_GRAB_BROKEN = 35 */ + 0, /* GDK_DAMAGE = 36 */ +}; +G_STATIC_ASSERT (G_N_ELEMENTS (type_masks) == GDK_EVENT_LAST); + +/* send motion events if the right buttons are down */ +static guint +update_evmask_for_button_motion (guint evmask, + GdkModifierType mask) +{ + if (evmask & GDK_BUTTON_MOTION_MASK && + mask & (GDK_BUTTON1_MASK | + GDK_BUTTON2_MASK | + GDK_BUTTON3_MASK | + GDK_BUTTON4_MASK | + GDK_BUTTON5_MASK)) + evmask |= GDK_POINTER_MOTION_MASK; + + if ((evmask & GDK_BUTTON1_MOTION_MASK && mask & GDK_BUTTON1_MASK) || + (evmask & GDK_BUTTON2_MOTION_MASK && mask & GDK_BUTTON2_MASK) || + (evmask & GDK_BUTTON3_MOTION_MASK && mask & GDK_BUTTON3_MASK)) + evmask |= GDK_POINTER_MOTION_MASK; + + return evmask; +} + +static gboolean +is_button_type (GdkEventType type) +{ + return type == GDK_BUTTON_PRESS || + type == GDK_2BUTTON_PRESS || + type == GDK_3BUTTON_PRESS || + type == GDK_BUTTON_RELEASE || + type == GDK_SCROLL; +} + +static gboolean +is_motion_type (GdkEventType type) +{ + return type == GDK_MOTION_NOTIFY || + type == GDK_ENTER_NOTIFY || + type == GDK_LEAVE_NOTIFY; +} + +static GdkWindowObject * +find_common_ancestor (GdkWindowObject *win1, + GdkWindowObject *win2) +{ + GdkWindowObject *tmp; + GList *path1 = NULL, *path2 = NULL; + GList *list1, *list2; + + tmp = win1; + while (tmp != NULL && tmp->window_type != GDK_WINDOW_ROOT) + { + path1 = g_list_prepend (path1, tmp); + tmp = get_event_parent (tmp); + } + + tmp = win2; + while (tmp != NULL && tmp->window_type != GDK_WINDOW_ROOT) + { + path2 = g_list_prepend (path2, tmp); + tmp = get_event_parent (tmp); + } + + list1 = path1; + list2 = path2; + tmp = NULL; + while (list1 && list2 && (list1->data == list2->data)) + { + tmp = (GdkWindowObject *)list1->data; + list1 = g_list_next (list1); + list2 = g_list_next (list2); + } + g_list_free (path1); + g_list_free (path2); + + return tmp; +} + +GdkEvent * +_gdk_make_event (GdkWindow *window, + GdkEventType type, + GdkEvent *event_in_queue, + gboolean before_event) +{ + GdkEvent *event = gdk_event_new (type); + guint32 the_time; + GdkModifierType the_state; + + the_time = gdk_event_get_time (event_in_queue); + gdk_event_get_state (event_in_queue, &the_state); + + event->any.window = g_object_ref (window); + event->any.send_event = FALSE; + if (event_in_queue && event_in_queue->any.send_event) + event->any.send_event = TRUE; + + switch (type) + { + case GDK_MOTION_NOTIFY: + event->motion.time = the_time; + event->motion.axes = NULL; + event->motion.state = the_state; + break; + + case GDK_BUTTON_PRESS: + case GDK_2BUTTON_PRESS: + case GDK_3BUTTON_PRESS: + case GDK_BUTTON_RELEASE: + event->button.time = the_time; + event->button.axes = NULL; + event->button.state = the_state; + break; + + case GDK_SCROLL: + event->scroll.time = the_time; + event->scroll.state = the_state; + break; + + case GDK_KEY_PRESS: + case GDK_KEY_RELEASE: + event->key.time = the_time; + event->key.state = the_state; + break; + + case GDK_ENTER_NOTIFY: + case GDK_LEAVE_NOTIFY: + event->crossing.time = the_time; + event->crossing.state = the_state; + break; + + case GDK_PROPERTY_NOTIFY: + event->property.time = the_time; + event->property.state = the_state; + break; + + case GDK_SELECTION_CLEAR: + case GDK_SELECTION_REQUEST: + case GDK_SELECTION_NOTIFY: + event->selection.time = the_time; + break; + + case GDK_PROXIMITY_IN: + case GDK_PROXIMITY_OUT: + event->proximity.time = the_time; + break; + + case GDK_DRAG_ENTER: + case GDK_DRAG_LEAVE: + case GDK_DRAG_MOTION: + case GDK_DRAG_STATUS: + case GDK_DROP_START: + case GDK_DROP_FINISHED: + event->dnd.time = the_time; + break; + + case GDK_FOCUS_CHANGE: + case GDK_CONFIGURE: + case GDK_MAP: + case GDK_UNMAP: + case GDK_CLIENT_EVENT: + case GDK_VISIBILITY_NOTIFY: + case GDK_NO_EXPOSE: + case GDK_DELETE: + case GDK_DESTROY: + case GDK_EXPOSE: + default: + break; + } + + if (event_in_queue) + { + if (before_event) + _gdk_event_queue_insert_before (gdk_drawable_get_display (window), event_in_queue, event); + else + _gdk_event_queue_insert_after (gdk_drawable_get_display (window), event_in_queue, event); + } + else + _gdk_event_queue_append (gdk_drawable_get_display (window), event); + + return event; +} + +static void +send_crossing_event (GdkDisplay *display, + GdkWindowObject *toplevel, + GdkWindowObject *window, + GdkEventType type, + GdkCrossingMode mode, + GdkNotifyType notify_type, + GdkWindow *subwindow, + gint toplevel_x, + gint toplevel_y, + GdkModifierType mask, + guint32 time_, + GdkEvent *event_in_queue, + gulong serial) +{ + GdkEvent *event; + guint32 window_event_mask, type_event_mask; + GdkPointerGrabInfo *grab; + GdkWindowImplIface *impl_iface; + + grab = _gdk_display_has_pointer_grab (display, serial); + + if (grab != NULL && + !grab->owner_events) + { + /* !owner_event => only report events wrt grab window, ignore rest */ + if ((GdkWindow *)window != grab->window) + return; + window_event_mask = grab->event_mask; + } + else + window_event_mask = window->event_mask; + + if (type == GDK_LEAVE_NOTIFY) + type_event_mask = GDK_LEAVE_NOTIFY_MASK; + else + type_event_mask = GDK_ENTER_NOTIFY_MASK; + + if (window->extension_events != 0) + { + impl_iface = GDK_WINDOW_IMPL_GET_IFACE (window->impl); + impl_iface->input_window_crossing ((GdkWindow *)window, + type == GDK_ENTER_NOTIFY); + } + + if (window_event_mask & type_event_mask) + { + event = _gdk_make_event ((GdkWindow *)window, type, event_in_queue, TRUE); + event->crossing.time = time_; + event->crossing.subwindow = subwindow; + if (subwindow) + g_object_ref (subwindow); + convert_toplevel_coords_to_window ((GdkWindow *)window, + toplevel_x, toplevel_y, + &event->crossing.x, &event->crossing.y); + event->crossing.x_root = toplevel_x + toplevel->x; + event->crossing.y_root = toplevel_y + toplevel->y; + event->crossing.mode = mode; + event->crossing.detail = notify_type; + event->crossing.focus = FALSE; + event->crossing.state = mask; + } +} + + +/* The coordinates are in the toplevel window that src/dest are in. + * src and dest are always (if != NULL) in the same toplevel, as + * we get a leave-notify and set the window_under_pointer to null + * before crossing to another toplevel. + */ +void +_gdk_synthesize_crossing_events (GdkDisplay *display, + GdkWindow *src, + GdkWindow *dest, + GdkCrossingMode mode, + gint toplevel_x, + gint toplevel_y, + GdkModifierType mask, + guint32 time_, + GdkEvent *event_in_queue, + gulong serial, + gboolean non_linear) +{ + GdkWindowObject *c; + GdkWindowObject *win, *last, *next; + GList *path, *list; + GdkWindowObject *a; + GdkWindowObject *b; + GdkWindowObject *toplevel; + GdkNotifyType notify_type; + + /* TODO: Don't send events to toplevel, as we get those from the windowing system */ + + a = (GdkWindowObject *)src; + b = (GdkWindowObject *)dest; + if (a == b) + return; /* No crossings generated between src and dest */ + + c = find_common_ancestor (a, b); + + non_linear |= (c != a) && (c != b); + + if (a) /* There might not be a source (i.e. if no previous pointer_in_window) */ + { + toplevel = (GdkWindowObject *)gdk_window_get_toplevel ((GdkWindow *)a); + + /* Traverse up from a to (excluding) c sending leave events */ + if (non_linear) + notify_type = GDK_NOTIFY_NONLINEAR; + else if (c == a) + notify_type = GDK_NOTIFY_INFERIOR; + else + notify_type = GDK_NOTIFY_ANCESTOR; + send_crossing_event (display, toplevel, + a, GDK_LEAVE_NOTIFY, + mode, + notify_type, + NULL, + toplevel_x, toplevel_y, + mask, time_, + event_in_queue, + serial); + + if (c != a) + { + if (non_linear) + notify_type = GDK_NOTIFY_NONLINEAR_VIRTUAL; + else + notify_type = GDK_NOTIFY_VIRTUAL; + + last = a; + win = get_event_parent (a); + while (win != c && win->window_type != GDK_WINDOW_ROOT) + { + send_crossing_event (display, toplevel, + win, GDK_LEAVE_NOTIFY, + mode, + notify_type, + (GdkWindow *)last, + toplevel_x, toplevel_y, + mask, time_, + event_in_queue, + serial); + + last = win; + win = get_event_parent (win); + } + } + } + + if (b) /* Might not be a dest, e.g. if we're moving out of the window */ + { + toplevel = (GdkWindowObject *)gdk_window_get_toplevel ((GdkWindow *)b); + + /* Traverse down from c to b */ + if (c != b) + { + path = NULL; + win = get_event_parent (b); + while (win != c && win->window_type != GDK_WINDOW_ROOT) + { + path = g_list_prepend (path, win); + win = get_event_parent (win); + } + + if (non_linear) + notify_type = GDK_NOTIFY_NONLINEAR_VIRTUAL; + else + notify_type = GDK_NOTIFY_VIRTUAL; + + list = path; + while (list) + { + win = (GdkWindowObject *)list->data; + list = g_list_next (list); + if (list) + next = (GdkWindowObject *)list->data; + else + next = b; + + send_crossing_event (display, toplevel, + win, GDK_ENTER_NOTIFY, + mode, + notify_type, + (GdkWindow *)next, + toplevel_x, toplevel_y, + mask, time_, + event_in_queue, + serial); + } + g_list_free (path); + } + + + if (non_linear) + notify_type = GDK_NOTIFY_NONLINEAR; + else if (c == a) + notify_type = GDK_NOTIFY_ANCESTOR; + else + notify_type = GDK_NOTIFY_INFERIOR; + + send_crossing_event (display, toplevel, + b, GDK_ENTER_NOTIFY, + mode, + notify_type, + NULL, + toplevel_x, toplevel_y, + mask, time_, + event_in_queue, + serial); + } +} + +/* Returns the window inside the event window with the pointer in it + * at the specified coordinates, or NULL if its not in any child of + * the toplevel. It also takes into account !owner_events grabs. + */ +static GdkWindow * +get_pointer_window (GdkDisplay *display, + GdkWindow *event_window, + gdouble toplevel_x, + gdouble toplevel_y, + gulong serial) +{ + GdkWindow *pointer_window; + GdkPointerGrabInfo *grab; + + if (event_window == display->pointer_info.toplevel_under_pointer) + pointer_window = + _gdk_window_find_descendant_at (event_window, + toplevel_x, toplevel_y, + NULL, NULL); + else + pointer_window = NULL; + + grab = _gdk_display_has_pointer_grab (display, serial); + if (grab != NULL && + !grab->owner_events && + pointer_window != grab->window) + pointer_window = NULL; + + return pointer_window; +} + +void +_gdk_display_set_window_under_pointer (GdkDisplay *display, + GdkWindow *window) +{ + /* We don't track this if all native, and it can cause issues + with the update_cursor call below */ + if (_gdk_native_windows) + return; + + if (display->pointer_info.window_under_pointer) + g_object_unref (display->pointer_info.window_under_pointer); + display->pointer_info.window_under_pointer = window; + if (window) + g_object_ref (window); + + if (window) + update_cursor (display); + + _gdk_display_enable_motion_hints (display); +} + +/* + *-------------------------------------------------------------- + * gdk_pointer_grab + * + * Grabs the pointer to a specific window + * + * Arguments: + * "window" is the window which will receive the grab + * "owner_events" specifies whether events will be reported as is, + * or relative to "window" + * "event_mask" masks only interesting events + * "confine_to" limits the cursor movement to the specified window + * "cursor" changes the cursor for the duration of the grab + * "time" specifies the time + * + * Results: + * + * Side effects: + * requires a corresponding call to gdk_pointer_ungrab + * + *-------------------------------------------------------------- + */ +GdkGrabStatus +gdk_pointer_grab (GdkWindow * window, + gboolean owner_events, + GdkEventMask event_mask, + GdkWindow * confine_to, + GdkCursor * cursor, + guint32 time) +{ + GdkWindow *native; + GdkDisplay *display; + GdkGrabStatus res; + gulong serial; + + g_return_val_if_fail (window != NULL, 0); + g_return_val_if_fail (GDK_IS_WINDOW (window), 0); + g_return_val_if_fail (confine_to == NULL || GDK_IS_WINDOW (confine_to), 0); + + /* We need a native window for confine to to work, ensure we have one */ + if (confine_to) + { + if (!gdk_window_ensure_native (confine_to)) + { + g_warning ("Can't confine to grabbed window, not native"); + confine_to = NULL; + } + } + + /* Non-viewable client side window => fail */ + if (!_gdk_window_has_impl (window) && + !gdk_window_is_viewable (window)) + return GDK_GRAB_NOT_VIEWABLE; + + if (_gdk_native_windows) + native = window; + else + native = gdk_window_get_toplevel (window); + while (gdk_window_is_offscreen ((GdkWindowObject *)native)) + { + native = gdk_offscreen_window_get_embedder (native); + + if (native == NULL || + (!_gdk_window_has_impl (native) && + !gdk_window_is_viewable (native))) + return GDK_GRAB_NOT_VIEWABLE; + + native = gdk_window_get_toplevel (native); + } + + display = gdk_drawable_get_display (window); + + serial = _gdk_windowing_window_get_next_serial (display); + + res = _gdk_windowing_pointer_grab (window, + native, + owner_events, + get_native_grab_event_mask (event_mask), + confine_to, + cursor, + time); + + if (res == GDK_GRAB_SUCCESS) + _gdk_display_add_pointer_grab (display, + window, + native, + owner_events, + event_mask, + serial, + time, + FALSE); + + return res; +} + +/** + * gdk_window_geometry_changed: + * @window: an embedded offscreen #GdkWindow + * + * This function informs GDK that the geometry of an embedded + * offscreen window has changed. This is necessary for GDK to keep + * track of which offscreen window the pointer is in. + * + * Since: 2.18 + */ +void +gdk_window_geometry_changed (GdkWindow *window) +{ + _gdk_synthesize_crossing_events_for_geometry_change (window); +} + +static gboolean +do_synthesize_crossing_event (gpointer data) +{ + GdkDisplay *display; + GdkWindow *changed_toplevel; + GdkWindowObject *changed_toplevel_priv; + GdkWindow *new_window_under_pointer; + gulong serial; + + changed_toplevel = data; + changed_toplevel_priv = (GdkWindowObject *)changed_toplevel; + + changed_toplevel_priv->synthesize_crossing_event_queued = FALSE; + + if (GDK_WINDOW_DESTROYED (changed_toplevel)) + return FALSE; + + display = gdk_drawable_get_display (changed_toplevel); + serial = _gdk_windowing_window_get_next_serial (display); + + if (changed_toplevel == display->pointer_info.toplevel_under_pointer) + { + new_window_under_pointer = + get_pointer_window (display, changed_toplevel, + display->pointer_info.toplevel_x, + display->pointer_info.toplevel_y, + serial); + if (new_window_under_pointer != + display->pointer_info.window_under_pointer) + { + _gdk_synthesize_crossing_events (display, + display->pointer_info.window_under_pointer, + new_window_under_pointer, + GDK_CROSSING_NORMAL, + display->pointer_info.toplevel_x, + display->pointer_info.toplevel_y, + display->pointer_info.state, + GDK_CURRENT_TIME, + NULL, + serial, + FALSE); + _gdk_display_set_window_under_pointer (display, new_window_under_pointer); + } + } + + return FALSE; +} + +void +_gdk_synthesize_crossing_events_for_geometry_change (GdkWindow *changed_window) +{ + GdkDisplay *display; + GdkWindow *toplevel; + GdkWindowObject *toplevel_priv; + + if (_gdk_native_windows) + return; /* We use the native crossing events if all native */ + + display = gdk_drawable_get_display (changed_window); + + toplevel = get_event_toplevel (changed_window); + toplevel_priv = (GdkWindowObject *)toplevel; + + if (toplevel == display->pointer_info.toplevel_under_pointer && + !toplevel_priv->synthesize_crossing_event_queued) + { + toplevel_priv->synthesize_crossing_event_queued = TRUE; + gdk_threads_add_idle_full (GDK_PRIORITY_EVENTS - 1, + do_synthesize_crossing_event, + g_object_ref (toplevel), + g_object_unref); + } +} + +/* Don't use for crossing events */ +static GdkWindow * +get_event_window (GdkDisplay *display, + GdkWindow *pointer_window, + GdkEventType type, + GdkModifierType mask, + guint *evmask_out, + gulong serial) +{ + guint evmask; + GdkWindow *grab_window; + GdkWindowObject *w; + GdkPointerGrabInfo *grab; + + grab = _gdk_display_has_pointer_grab (display, serial); + + if (grab != NULL && !grab->owner_events) + { + evmask = grab->event_mask; + evmask = update_evmask_for_button_motion (evmask, mask); + + grab_window = grab->window; + + if (evmask & type_masks[type]) + { + if (evmask_out) + *evmask_out = evmask; + return grab_window; + } + else + return NULL; + } + + w = (GdkWindowObject *)pointer_window; + while (w != NULL) + { + evmask = w->event_mask; + evmask = update_evmask_for_button_motion (evmask, mask); + + if (evmask & type_masks[type]) + { + if (evmask_out) + *evmask_out = evmask; + return (GdkWindow *)w; + } + + w = get_event_parent (w); + } + + if (grab != NULL && + grab->owner_events) + { + evmask = grab->event_mask; + evmask = update_evmask_for_button_motion (evmask, mask); + + if (evmask & type_masks[type]) + { + if (evmask_out) + *evmask_out = evmask; + return grab->window; + } + else + return NULL; + } + + return NULL; +} + +static gboolean +proxy_pointer_event (GdkDisplay *display, + GdkEvent *source_event, + gulong serial) +{ + GdkWindow *toplevel_window, *event_window; + GdkWindow *pointer_window; + GdkEvent *event; + guint state; + gdouble toplevel_x, toplevel_y; + guint32 time_; + gboolean non_linear; + + event_window = source_event->any.window; + gdk_event_get_coords (source_event, &toplevel_x, &toplevel_y); + gdk_event_get_state (source_event, &state); + time_ = gdk_event_get_time (source_event); + toplevel_window = convert_native_coords_to_toplevel (event_window, + toplevel_x, toplevel_y, + &toplevel_x, &toplevel_y); + + non_linear = FALSE; + if ((source_event->type == GDK_LEAVE_NOTIFY || + source_event->type == GDK_ENTER_NOTIFY) && + (source_event->crossing.detail == GDK_NOTIFY_NONLINEAR || + source_event->crossing.detail == GDK_NOTIFY_NONLINEAR_VIRTUAL)) + non_linear = TRUE; + + /* If we get crossing events with subwindow unexpectedly being NULL + that means there is a native subwindow that gdk doesn't know about. + We track these and forward them, with the correct virtual window + events inbetween. + This is important to get right, as metacity uses gdk for the frame + windows, but gdk doesn't know about the client windows reparented + into the frame. */ + if (((source_event->type == GDK_LEAVE_NOTIFY && + source_event->crossing.detail == GDK_NOTIFY_INFERIOR) || + (source_event->type == GDK_ENTER_NOTIFY && + (source_event->crossing.detail == GDK_NOTIFY_VIRTUAL || + source_event->crossing.detail == GDK_NOTIFY_NONLINEAR_VIRTUAL))) && + source_event->crossing.subwindow == NULL) + { + /* Left for an unknown (to gdk) subwindow */ + + /* Send leave events from window under pointer to event window + that will get the subwindow == NULL window */ + _gdk_synthesize_crossing_events (display, + display->pointer_info.window_under_pointer, + event_window, + source_event->crossing.mode, + toplevel_x, toplevel_y, + state, time_, + source_event, + serial, + non_linear); + + /* Send subwindow == NULL event */ + send_crossing_event (display, + (GdkWindowObject *)toplevel_window, + (GdkWindowObject *)event_window, + source_event->type, + source_event->crossing.mode, + source_event->crossing.detail, + NULL, + toplevel_x, toplevel_y, + state, time_, + source_event, + serial); + + _gdk_display_set_window_under_pointer (display, NULL); + return TRUE; + } + + pointer_window = get_pointer_window (display, toplevel_window, + toplevel_x, toplevel_y, serial); + + if (((source_event->type == GDK_ENTER_NOTIFY && + source_event->crossing.detail == GDK_NOTIFY_INFERIOR) || + (source_event->type == GDK_LEAVE_NOTIFY && + (source_event->crossing.detail == GDK_NOTIFY_VIRTUAL || + source_event->crossing.detail == GDK_NOTIFY_NONLINEAR_VIRTUAL))) && + source_event->crossing.subwindow == NULL) + { + /* Entered from an unknown (to gdk) subwindow */ + + /* Send subwindow == NULL event */ + send_crossing_event (display, + (GdkWindowObject *)toplevel_window, + (GdkWindowObject *)event_window, + source_event->type, + source_event->crossing.mode, + source_event->crossing.detail, + NULL, + toplevel_x, toplevel_y, + state, time_, + source_event, + serial); + + /* Send enter events from event window to pointer_window */ + _gdk_synthesize_crossing_events (display, + event_window, + pointer_window, + source_event->crossing.mode, + toplevel_x, toplevel_y, + state, time_, + source_event, + serial, non_linear); + _gdk_display_set_window_under_pointer (display, pointer_window); + return TRUE; + } + + if (display->pointer_info.window_under_pointer != pointer_window) + { + /* Either a toplevel crossing notify that ended up inside a child window, + or a motion notify that got into another child window */ + + /* Different than last time, send crossing events */ + _gdk_synthesize_crossing_events (display, + display->pointer_info.window_under_pointer, + pointer_window, + GDK_CROSSING_NORMAL, + toplevel_x, toplevel_y, + state, time_, + source_event, + serial, non_linear); + _gdk_display_set_window_under_pointer (display, pointer_window); + } + else if (source_event->type == GDK_MOTION_NOTIFY) + { + GdkWindow *event_win; + guint evmask; + gboolean is_hint; + + event_win = get_event_window (display, + pointer_window, + source_event->type, + state, + &evmask, + serial); + + is_hint = FALSE; + + if (event_win && + (evmask & GDK_POINTER_MOTION_HINT_MASK)) + { + if (display->pointer_info.motion_hint_serial != 0 && + serial < display->pointer_info.motion_hint_serial) + event_win = NULL; /* Ignore event */ + else + { + is_hint = TRUE; + display->pointer_info.motion_hint_serial = G_MAXULONG; + } + } + + if (event_win && !display->ignore_core_events) + { + event = _gdk_make_event (event_win, GDK_MOTION_NOTIFY, source_event, FALSE); + event->motion.time = time_; + convert_toplevel_coords_to_window (event_win, + toplevel_x, toplevel_y, + &event->motion.x, &event->motion.y); + event->motion.x_root = source_event->motion.x_root; + event->motion.y_root = source_event->motion.y_root;; + event->motion.state = state; + event->motion.is_hint = is_hint; + event->motion.device = NULL; + event->motion.device = source_event->motion.device; + } + } + + /* unlink all move events from queue. + We handle our own, including our emulated masks. */ + return TRUE; +} + +#define GDK_ANY_BUTTON_MASK (GDK_BUTTON1_MASK | \ + GDK_BUTTON2_MASK | \ + GDK_BUTTON3_MASK | \ + GDK_BUTTON4_MASK | \ + GDK_BUTTON5_MASK) + +static gboolean +proxy_button_event (GdkEvent *source_event, + gulong serial) +{ + GdkWindow *toplevel_window, *event_window; + GdkWindow *event_win; + GdkWindow *pointer_window; + GdkWindowObject *parent; + GdkEvent *event; + guint state; + guint32 time_; + GdkEventType type; + gdouble toplevel_x, toplevel_y; + GdkDisplay *display; + GdkWindowObject *w; + + type = source_event->any.type; + event_window = source_event->any.window; + gdk_event_get_coords (source_event, &toplevel_x, &toplevel_y); + gdk_event_get_state (source_event, &state); + time_ = gdk_event_get_time (source_event); + display = gdk_drawable_get_display (source_event->any.window); + toplevel_window = convert_native_coords_to_toplevel (event_window, + toplevel_x, toplevel_y, + &toplevel_x, &toplevel_y); + + if (type == GDK_BUTTON_PRESS && + !source_event->any.send_event && + _gdk_display_has_pointer_grab (display, serial) == NULL) + { + pointer_window = + _gdk_window_find_descendant_at (toplevel_window, + toplevel_x, toplevel_y, + NULL, NULL); + + /* Find the event window, that gets the grab */ + w = (GdkWindowObject *)pointer_window; + while (w != NULL && + (parent = get_event_parent (w)) != NULL && + parent->window_type != GDK_WINDOW_ROOT) + { + if (w->event_mask & GDK_BUTTON_PRESS_MASK) + break; + w = parent; + } + pointer_window = (GdkWindow *)w; + + _gdk_display_add_pointer_grab (display, + pointer_window, + event_window, + FALSE, + gdk_window_get_events (pointer_window), + serial, + time_, + TRUE); + _gdk_display_pointer_grab_update (display, serial); + } + + pointer_window = get_pointer_window (display, toplevel_window, + toplevel_x, toplevel_y, + serial); + + event_win = get_event_window (display, + pointer_window, + type, state, + NULL, serial); + + if (event_win == NULL || display->ignore_core_events) + return TRUE; + + event = _gdk_make_event (event_win, type, source_event, FALSE); + + switch (type) + { + case GDK_BUTTON_PRESS: + case GDK_BUTTON_RELEASE: + event->button.button = source_event->button.button; + convert_toplevel_coords_to_window (event_win, + toplevel_x, toplevel_y, + &event->button.x, &event->button.y); + event->button.x_root = source_event->button.x_root; + event->button.y_root = source_event->button.y_root; + event->button.state = state; + event->button.device = source_event->button.device; + + if (type == GDK_BUTTON_PRESS) + _gdk_event_button_generate (display, event); + return TRUE; + + case GDK_SCROLL: + event->scroll.direction = source_event->scroll.direction; + convert_toplevel_coords_to_window (event_win, + toplevel_x, toplevel_y, + &event->scroll.x, &event->scroll.y); + event->scroll.x_root = source_event->scroll.x_root; + event->scroll.y_root = source_event->scroll.y_root; + event->scroll.state = state; + event->scroll.device = source_event->scroll.device; + event->scroll.has_deltas = source_event->scroll.has_deltas; + event->scroll.delta_x = source_event->scroll.delta_x; + event->scroll.delta_y = source_event->scroll.delta_y; + return TRUE; + + default: + return FALSE; + } + + return TRUE; /* Always unlink original, we want to obey the emulated event mask */ +} + +#ifdef DEBUG_WINDOW_PRINTING +static void +gdk_window_print (GdkWindowObject *window, + int indent) +{ + GdkRectangle r; + const char *window_types[] = { + "root", + "toplevel", + "child", + "dialog", + "temp", + "foreign", + "offscreen" + }; + + g_print ("%*s%p: [%s] %d,%d %dx%d", indent, "", window, + window->user_data ? g_type_name_from_instance (window->user_data) : "no widget", + window->x, window->y, + window->width, window->height + ); + + if (gdk_window_has_impl (window)) + { +#ifdef GDK_WINDOWING_X11 + g_print (" impl(0x%lx)", gdk_x11_drawable_get_xid (GDK_DRAWABLE (window))); +#endif + } + + if (window->window_type != GDK_WINDOW_CHILD) + g_print (" %s", window_types[window->window_type]); + + if (window->input_only) + g_print (" input-only"); + + if (window->shaped) + g_print (" shaped"); + + if (!gdk_window_is_visible ((GdkWindow *)window)) + g_print (" hidden"); + + g_print (" abs[%d,%d]", + window->abs_x, window->abs_y); + + gdk_region_get_clipbox (window->clip_region, &r); + if (gdk_region_empty (window->clip_region)) + g_print (" clipbox[empty]"); + else + g_print (" clipbox[%d,%d %dx%d]", r.x, r.y, r.width, r.height); + + g_print ("\n"); +} + + +static void +gdk_window_print_tree (GdkWindow *window, + int indent, + gboolean include_input_only) +{ + GdkWindowObject *private; + GList *l; + + private = (GdkWindowObject *)window; + + if (private->input_only && !include_input_only) + return; + + gdk_window_print (private, indent); + + for (l = private->children; l != NULL; l = l->next) + gdk_window_print_tree (l->data, indent + 4, include_input_only); +} + +#endif /* DEBUG_WINDOW_PRINTING */ + +static gboolean +is_input_event (GdkDisplay *display, + GdkEvent *event) +{ + GdkDevice *core_pointer; + + core_pointer = gdk_display_get_core_pointer (display); + if ((event->type == GDK_MOTION_NOTIFY && + event->motion.device != core_pointer) || + ((event->type == GDK_BUTTON_PRESS || + event->type == GDK_BUTTON_RELEASE) && + event->button.device != core_pointer)) + return TRUE; + return FALSE; +} + +void +_gdk_windowing_got_event (GdkDisplay *display, + GList *event_link, + GdkEvent *event, + gulong serial) +{ + GdkWindow *event_window; + GdkWindowObject *event_private; + gdouble x, y; + gboolean unlink_event; + guint old_state, old_button; + GdkPointerGrabInfo *button_release_grab; + gboolean is_toplevel; + + if (gdk_event_get_time (event) != GDK_CURRENT_TIME) + display->last_event_time = gdk_event_get_time (event); + + _gdk_display_pointer_grab_update (display, + serial); + + event_window = event->any.window; + if (!event_window) + return; + + event_private = GDK_WINDOW_OBJECT (event_window); + +#ifdef DEBUG_WINDOW_PRINTING + if (event->type == GDK_KEY_PRESS && + (event->key.keyval == 0xa7 || + event->key.keyval == 0xbd)) + { + gdk_window_print_tree (event_window, 0, + event->key.keyval == 0xbd); + } +#endif + + if (_gdk_native_windows) + { + if (event->type == GDK_BUTTON_PRESS && + !event->any.send_event && + _gdk_display_has_pointer_grab (display, serial) == NULL) + { + _gdk_display_add_pointer_grab (display, + event_window, + event_window, + FALSE, + gdk_window_get_events (event_window), + serial, + gdk_event_get_time (event), + TRUE); + _gdk_display_pointer_grab_update (display, + serial); + } + if (event->type == GDK_BUTTON_RELEASE && + !event->any.send_event) + { + button_release_grab = + _gdk_display_has_pointer_grab (display, serial); + if (button_release_grab && + button_release_grab->implicit && + (event->button.state & GDK_ANY_BUTTON_MASK & ~(GDK_BUTTON1_MASK << (event->button.button - 1))) == 0) + { + button_release_grab->serial_end = serial; + button_release_grab->implicit_ungrab = FALSE; + _gdk_display_pointer_grab_update (display, serial); + } + } + + if (event->type == GDK_BUTTON_PRESS) + _gdk_event_button_generate (display, event); + + return; + } + + if (event->type == GDK_VISIBILITY_NOTIFY) + { + event_private->native_visibility = event->visibility.state; + gdk_window_update_visibility_recursively (event_private, + event_private); + return; + } + + if (is_input_event (display, event)) + return; + + if (!(is_button_type (event->type) || + is_motion_type (event->type)) || + event_private->window_type == GDK_WINDOW_ROOT) + return; + + is_toplevel = gdk_window_is_toplevel (event_private); + + if ((event->type == GDK_ENTER_NOTIFY || + event->type == GDK_LEAVE_NOTIFY) && + (event->crossing.mode == GDK_CROSSING_GRAB || + event->crossing.mode == GDK_CROSSING_UNGRAB) && + (_gdk_display_has_pointer_grab (display, serial) || + event->crossing.detail == GDK_NOTIFY_INFERIOR)) + { + /* We synthesize all crossing events due to grabs ourselves, + * so we ignore the native ones caused by our native pointer_grab + * calls. Otherwise we would proxy these crossing event and cause + * multiple copies of crossing events for grabs. + * + * We do want to handle grabs from other clients though, as for + * instance alt-tab in metacity causes grabs like these and + * we want to handle those. Thus the has_pointer_grab check. + * + * Implicit grabs on child windows create some grabbing events + * that are sent before the button press. This means we can't + * detect these with the has_pointer_grab check (as the implicit + * grab is only noticed when we get button press event), so we + * detect these events by checking for INFERIOR enter or leave + * events. These should never be a problem to filter out. + */ + + /* We ended up in this window after some (perhaps other clients) + grab, so update the toplevel_under_window state */ + if (is_toplevel && + event->type == GDK_ENTER_NOTIFY && + event->crossing.mode == GDK_CROSSING_UNGRAB) + { + if (display->pointer_info.toplevel_under_pointer) + g_object_unref (display->pointer_info.toplevel_under_pointer); + display->pointer_info.toplevel_under_pointer = g_object_ref (event_window); + } + + unlink_event = TRUE; + goto out; + } + + /* Track toplevel_under_pointer */ + if (is_toplevel) + { + if (event->type == GDK_ENTER_NOTIFY && + event->crossing.detail != GDK_NOTIFY_INFERIOR) + { + if (display->pointer_info.toplevel_under_pointer) + g_object_unref (display->pointer_info.toplevel_under_pointer); + display->pointer_info.toplevel_under_pointer = g_object_ref (event_window); + } + else if (event->type == GDK_LEAVE_NOTIFY && + event->crossing.detail != GDK_NOTIFY_INFERIOR && + display->pointer_info.toplevel_under_pointer == event_window) + { + if (display->pointer_info.toplevel_under_pointer) + g_object_unref (display->pointer_info.toplevel_under_pointer); + display->pointer_info.toplevel_under_pointer = NULL; + } + } + + /* Store last pointer window and position/state */ + old_state = display->pointer_info.state; + old_button = display->pointer_info.button; + + gdk_event_get_coords (event, &x, &y); + convert_native_coords_to_toplevel (event_window, x, y, &x, &y); + display->pointer_info.toplevel_x = x; + display->pointer_info.toplevel_y = y; + gdk_event_get_state (event, &display->pointer_info.state); + if (event->type == GDK_BUTTON_PRESS || + event->type == GDK_BUTTON_RELEASE) + display->pointer_info.button = event->button.button; + + if (display->pointer_info.state != old_state || + display->pointer_info.button != old_button) + _gdk_display_enable_motion_hints (display); + + unlink_event = FALSE; + if (is_motion_type (event->type)) + unlink_event = proxy_pointer_event (display, + event, + serial); + else if (is_button_type (event->type)) + unlink_event = proxy_button_event (event, + serial); + + if (event->type == GDK_BUTTON_RELEASE && + !event->any.send_event) + { + button_release_grab = + _gdk_display_has_pointer_grab (display, serial); + if (button_release_grab && + button_release_grab->implicit && + (event->button.state & GDK_ANY_BUTTON_MASK & ~(GDK_BUTTON1_MASK << (event->button.button - 1))) == 0) + { + button_release_grab->serial_end = serial; + button_release_grab->implicit_ungrab = FALSE; + _gdk_display_pointer_grab_update (display, serial); + } + } + + out: + if (unlink_event) + { + _gdk_event_queue_remove_link (display, event_link); + g_list_free_1 (event_link); + gdk_event_free (event); + } +} + + +static GdkWindow * +get_extension_event_window (GdkDisplay *display, + GdkWindow *pointer_window, + GdkEventType type, + GdkModifierType mask, + gulong serial) +{ + guint evmask; + GdkWindow *grab_window; + GdkWindowObject *w; + GdkPointerGrabInfo *grab; + + grab = _gdk_display_has_pointer_grab (display, serial); + + if (grab != NULL && !grab->owner_events) + { + evmask = grab->event_mask; + evmask = update_evmask_for_button_motion (evmask, mask); + + grab_window = grab->window; + + if (evmask & type_masks[type]) + return grab_window; + else + return NULL; + } + + w = (GdkWindowObject *)pointer_window; + while (w != NULL) + { + evmask = w->extension_events; + evmask = update_evmask_for_button_motion (evmask, mask); + + if (evmask & type_masks[type]) + return (GdkWindow *)w; + + w = get_event_parent (w); + } + + if (grab != NULL && + grab->owner_events) + { + evmask = grab->event_mask; + evmask = update_evmask_for_button_motion (evmask, mask); + + if (evmask & type_masks[type]) + return grab->window; + else + return NULL; + } + + return NULL; +} + + +GdkWindow * +_gdk_window_get_input_window_for_event (GdkWindow *native_window, + GdkEventType event_type, + GdkModifierType mask, + int x, int y, + gulong serial) +{ + GdkDisplay *display; + GdkWindow *toplevel_window; + GdkWindow *pointer_window; + GdkWindow *event_win; + gdouble toplevel_x, toplevel_y; + + toplevel_x = x; + toplevel_y = y; + + display = gdk_drawable_get_display (native_window); + toplevel_window = convert_native_coords_to_toplevel (native_window, + toplevel_x, toplevel_y, + &toplevel_x, &toplevel_y); + pointer_window = get_pointer_window (display, toplevel_window, + toplevel_x, toplevel_y, serial); + event_win = get_extension_event_window (display, + pointer_window, + event_type, + mask, + serial); + + return event_win; +} + +/** + * gdk_window_create_similar_surface: + * @window: window to make new surface similar to + * @content: the content for the new surface + * @width: width of the new surface + * @height: height of the new surface + * + * Create a new surface that is as compatible as possible with the + * given @window. For example the new surface will have the same + * fallback resolution and font options as @window. Generally, the new + * surface will also use the same backend as @window, unless that is + * not possible for some reason. The type of the returned surface may + * be examined with cairo_surface_get_type(). + * + * Initially the surface contents are all 0 (transparent if contents + * have transparency, black otherwise.) + * + * Returns: a pointer to the newly allocated surface. The caller + * owns the surface and should call cairo_surface_destroy() when done + * with it. + * + * This function always returns a valid pointer, but it will return a + * pointer to a "nil" surface if @other is already in an error state + * or any other error occurs. + * + * Since: 2.22 + **/ +cairo_surface_t * +gdk_window_create_similar_surface (GdkWindow * window, + cairo_content_t content, + int width, + int height) +{ + cairo_surface_t *window_surface, *surface; + + g_return_val_if_fail (GDK_IS_WINDOW (window), NULL); + + window_surface = _gdk_drawable_ref_cairo_surface (window); + + surface = cairo_surface_create_similar (window_surface, + content, + width, height); + + cairo_surface_destroy (window_surface); + + return surface; +} + +/** + * gdk_window_get_screen: + * @window: a #GdkWindow + * + * Gets the #GdkScreen associated with a #GdkWindow. + * + * Return value: the #GdkScreen associated with @window + * + * Since: 2.24 + */ +GdkScreen* +gdk_window_get_screen (GdkWindow *window) +{ + g_return_val_if_fail (GDK_IS_WINDOW (window), NULL); + + return gdk_drawable_get_screen (GDK_DRAWABLE (window)); +} + +/** + * gdk_window_get_display: + * @window: a #GdkWindow + * + * Gets the #GdkDisplay associated with a #GdkWindow. + * + * Return value: the #GdkDisplay associated with @window + * + * Since: 2.24 + */ +GdkDisplay * +gdk_window_get_display (GdkWindow *window) +{ + g_return_val_if_fail (GDK_IS_WINDOW (window), NULL); + + return gdk_drawable_get_display (GDK_DRAWABLE (window)); +} + +/** + * gdk_window_get_visual: + * @window: a #GdkWindow + * + * Gets the #GdkVisual describing the pixel format of @window. + * + * Return value: a #GdkVisual + * + * Since: 2.24 + */ +GdkVisual* +gdk_window_get_visual (GdkWindow *window) +{ + g_return_val_if_fail (GDK_IS_WINDOW (window), NULL); + + return gdk_drawable_get_visual (GDK_DRAWABLE (window)); +} + +/** + * gdk_window_get_width: + * @window: a #GdkWindow + * + * Returns the width of the given @window. + * + * On the X11 platform the returned size is the size reported in the + * most-recently-processed configure event, rather than the current + * size on the X server. + * + * Returns: The width of @window + * + * Since: 2.24 + */ +int +gdk_window_get_width (GdkWindow *window) +{ + gint width, height; + + g_return_val_if_fail (GDK_IS_WINDOW (window), 0); + + gdk_drawable_get_size (GDK_DRAWABLE (window), &width, &height); + + return width; +} + +/** + * gdk_window_get_height: + * @window: a #GdkWindow + * + * Returns the height of the given @window. + * + * On the X11 platform the returned size is the size reported in the + * most-recently-processed configure event, rather than the current + * size on the X server. + * + * Returns: The height of @window + * + * Since: 2.24 + */ +int +gdk_window_get_height (GdkWindow *window) +{ + gint width, height; + + g_return_val_if_fail (GDK_IS_WINDOW (window), 0); + + gdk_drawable_get_size (GDK_DRAWABLE (window), &width, &height); + + return height; +} + + +#define __GDK_WINDOW_C__ +#include "gdkaliasdef.c" diff --git a/libs/tk/ydk/gdkwindowimpl.c b/libs/tk/ydk/gdkwindowimpl.c new file mode 100644 index 0000000000..4aef21bbab --- /dev/null +++ b/libs/tk/ydk/gdkwindowimpl.c @@ -0,0 +1,52 @@ +/* GDK - The GIMP Drawing Kit + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, 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 "config.h" +#include "gdkwindowimpl.h" +#include "gdkinternals.h" + +#include "gdkalias.h" + +GType +gdk_window_impl_get_type (void) +{ + static GType gtype = 0; + + if (G_UNLIKELY (!gtype)) + { + gtype = g_type_register_static_simple (G_TYPE_INTERFACE, + "GdkWindowImpl", + sizeof (GdkWindowImplIface), + NULL, 0, NULL, 0); + g_type_interface_add_prerequisite (gtype, G_TYPE_OBJECT); + } + + return gtype; +} + +#define __GDK_WINDOW_IMPL_C__ +#include "gdkaliasdef.c" + diff --git a/libs/tk/ydk/quartz/GdkQuartzView.c b/libs/tk/ydk/quartz/GdkQuartzView.c new file mode 100644 index 0000000000..bf7b5d3a04 --- /dev/null +++ b/libs/tk/ydk/quartz/GdkQuartzView.c @@ -0,0 +1,767 @@ +/* GdkQuartzView.m + * + * Copyright (C) 2005-2007 Imendio AB + * + * 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. + */ + +#import "GdkQuartzView.h" +#include "gdkregion.h" +#include "gdkregion-generic.h" +#include "gdkwindow-quartz.h" +#include "gdkprivate-quartz.h" +#include "gdkquartz.h" + +@implementation GdkQuartzView + +-(id)initWithFrame: (NSRect)frameRect +{ + if ((self = [super initWithFrame: frameRect])) + { + markedRange = NSMakeRange (NSNotFound, 0); + selectedRange = NSMakeRange (NSNotFound, 0); + } + + return self; +} + +-(BOOL)acceptsFirstResponder +{ + GDK_NOTE (EVENTS, g_print ("acceptsFirstResponder\n")); + return YES; +} + +-(BOOL)becomeFirstResponder +{ + GDK_NOTE (EVENTS, g_print ("becomeFirstResponder\n")); + return YES; +} + +-(BOOL)resignFirstResponder +{ + GDK_NOTE (EVENTS, g_print ("resignFirstResponder\n")); + return YES; +} + +-(void) keyDown: (NSEvent *) theEvent +{ + GDK_NOTE (EVENTS, g_print ("keyDown\n")); + [self interpretKeyEvents: [NSArray arrayWithObject: theEvent]]; +} + +-(void)flagsChanged: (NSEvent *) theEvent +{ +} + +-(NSUInteger)characterIndexForPoint: (NSPoint)aPoint +{ + GDK_NOTE (EVENTS, g_print ("characterIndexForPoint\n")); + return 0; +} + +-(NSRect)firstRectForCharacterRange: (NSRange)aRange actualRange: (NSRangePointer)actualRange +{ + GDK_NOTE (EVENTS, g_print ("firstRectForCharacterRange\n")); + gint ns_x, ns_y; + GdkRectangle *rect; + + rect = g_object_get_data (G_OBJECT (gdk_window), GIC_CURSOR_RECT); + if (rect) + { + _gdk_quartz_window_gdk_xy_to_xy (rect->x, rect->y + rect->height, + &ns_x, &ns_y); + + return NSMakeRect (ns_x, ns_y, rect->width, rect->height); + } + else + { + return NSMakeRect (0, 0, 0, 0); + } +} + +-(NSArray *)validAttributesForMarkedText +{ + GDK_NOTE (EVENTS, g_print ("validAttributesForMarkedText\n")); + return [NSArray arrayWithObjects: NSUnderlineStyleAttributeName, nil]; +} + +-(NSAttributedString *)attributedSubstringForProposedRange: (NSRange)aRange actualRange: (NSRangePointer)actualRange +{ + GDK_NOTE (EVENTS, g_print ("attributedSubstringForProposedRange\n")); + return nil; +} + +-(BOOL)hasMarkedText +{ + GDK_NOTE (EVENTS, g_print ("hasMarkedText\n")); + return markedRange.location != NSNotFound && markedRange.length != 0; +} + +-(NSRange)markedRange +{ + GDK_NOTE (EVENTS, g_print ("markedRange\n")); + return markedRange; +} + +-(NSRange)selectedRange +{ + GDK_NOTE (EVENTS, g_print ("selectedRange\n")); + return selectedRange; +} + +-(void)unmarkText +{ + GDK_NOTE (EVENTS, g_print ("unmarkText\n")); + gchar *prev_str; + markedRange = selectedRange = NSMakeRange (NSNotFound, 0); + + prev_str = g_object_get_data (G_OBJECT (gdk_window), TIC_MARKED_TEXT); + if (prev_str) + g_free (prev_str); + g_object_set_data (G_OBJECT (gdk_window), TIC_MARKED_TEXT, NULL); +} + +-(void)setMarkedText: (id)aString selectedRange: (NSRange)newSelection replacementRange: (NSRange)replacementRange +{ + GDK_NOTE (EVENTS, g_print ("setMarkedText\n")); + const char *str; + gchar *prev_str; + + if (replacementRange.location == NSNotFound) + { + markedRange = NSMakeRange (newSelection.location, [aString length]); + selectedRange = NSMakeRange (newSelection.location, newSelection.length); + } + else { + markedRange = NSMakeRange (replacementRange.location, [aString length]); + selectedRange = NSMakeRange (replacementRange.location + newSelection.location, newSelection.length); + } + + if ([aString isKindOfClass: [NSAttributedString class]]) + { + str = [[aString string] UTF8String]; + } + else { + str = [aString UTF8String]; + } + + prev_str = g_object_get_data (G_OBJECT (gdk_window), TIC_MARKED_TEXT); + if (prev_str) + g_free (prev_str); + g_object_set_data (G_OBJECT (gdk_window), TIC_MARKED_TEXT, g_strdup (str)); + g_object_set_data (G_OBJECT (gdk_window), TIC_SELECTED_POS, + GUINT_TO_POINTER (selectedRange.location)); + g_object_set_data (G_OBJECT (gdk_window), TIC_SELECTED_LEN, + GUINT_TO_POINTER (selectedRange.length)); + + GDK_NOTE (EVENTS, g_print ("setMarkedText: set %s (%p, nsview %p): %s\n", + TIC_MARKED_TEXT, gdk_window, self, + str ? str : "(empty)")); + + /* handle text input changes by mouse events */ + if (!GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (gdk_window), + TIC_IN_KEY_DOWN))) + { + _gdk_quartz_synthesize_null_key_event(gdk_window); + } +} + +-(void)doCommandBySelector: (SEL)aSelector +{ + GDK_NOTE (EVENTS, g_print ("doCommandBySelector\n")); + if ([self respondsToSelector: aSelector]) + [self performSelector: aSelector]; +} + +/* This gets called on OS X 10.6 and upwards from interpretKeyEvents */ +-(void)insertText: (id)aString replacementRange: (NSRange)replacementRange +{ + [self insertText:aString]; +} + +/* This gets called on OS X 10.5 from interpretKeyEvents, although 10.5 + * is supposed to support NSTextInputClient */ +-(void)insertText: (id)aString +{ + GDK_NOTE (EVENTS, g_print ("insertText\n")); + const char *str; + NSString *string; + gchar *prev_str; + + if ([self hasMarkedText]) + [self unmarkText]; + + if ([aString isKindOfClass: [NSAttributedString class]]) + string = [aString string]; + else + string = aString; + + NSCharacterSet *ctrlChars = [NSCharacterSet controlCharacterSet]; + NSCharacterSet *wsnlChars = [NSCharacterSet whitespaceAndNewlineCharacterSet]; + if ([string rangeOfCharacterFromSet:ctrlChars].length && + [string rangeOfCharacterFromSet:wsnlChars].length == 0) + { + /* discard invalid text input with Chinese input methods */ + str = ""; + [self unmarkText]; + NSInputManager *currentInputManager = [NSInputManager currentInputManager]; + [currentInputManager markedTextAbandoned:self]; + } + else + { + str = [string UTF8String]; + } + + prev_str = g_object_get_data (G_OBJECT (gdk_window), TIC_INSERT_TEXT); + if (prev_str) + g_free (prev_str); + g_object_set_data (G_OBJECT (gdk_window), TIC_INSERT_TEXT, g_strdup (str)); + GDK_NOTE (EVENTS, g_print ("insertText: set %s (%p, nsview %p): %s\n", + TIC_INSERT_TEXT, gdk_window, self, + str ? str : "(empty)")); + + g_object_set_data (G_OBJECT (gdk_window), GIC_FILTER_KEY, + GUINT_TO_POINTER (GIC_FILTER_FILTERED)); + + /* handle text input changes by mouse events */ + if (!GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (gdk_window), + TIC_IN_KEY_DOWN))) + { + _gdk_quartz_synthesize_null_key_event(gdk_window); + } +} + +-(void)deleteBackward: (id)sender +{ + GDK_NOTE (EVENTS, g_print ("deleteBackward\n")); + g_object_set_data (G_OBJECT (gdk_window), GIC_FILTER_KEY, + GUINT_TO_POINTER (GIC_FILTER_PASSTHRU)); +} + +-(void)deleteForward: (id)sender +{ + GDK_NOTE (EVENTS, g_print ("deleteForward\n")); + g_object_set_data (G_OBJECT (gdk_window), GIC_FILTER_KEY, + GUINT_TO_POINTER (GIC_FILTER_PASSTHRU)); +} + +-(void)deleteToBeginningOfLine: (id)sender +{ + GDK_NOTE (EVENTS, g_print ("deleteToBeginningOfLine\n")); + g_object_set_data (G_OBJECT (gdk_window), GIC_FILTER_KEY, + GUINT_TO_POINTER (GIC_FILTER_PASSTHRU)); +} + +-(void)deleteToEndOfLine: (id)sender +{ + GDK_NOTE (EVENTS, g_print ("deleteToEndOfLine\n")); + g_object_set_data (G_OBJECT (gdk_window), GIC_FILTER_KEY, + GUINT_TO_POINTER (GIC_FILTER_PASSTHRU)); +} + +-(void)deleteWordBackward: (id)sender +{ + GDK_NOTE (EVENTS, g_print ("deleteWordBackward\n")); + g_object_set_data (G_OBJECT (gdk_window), GIC_FILTER_KEY, + GUINT_TO_POINTER (GIC_FILTER_PASSTHRU)); +} + +-(void)deleteWordForward: (id)sender +{ + GDK_NOTE (EVENTS, g_print ("deleteWordForward\n")); + g_object_set_data (G_OBJECT (gdk_window), GIC_FILTER_KEY, + GUINT_TO_POINTER (GIC_FILTER_PASSTHRU)); +} + +-(void)insertBacktab: (id)sender +{ + GDK_NOTE (EVENTS, g_print ("insertBacktab\n")); + g_object_set_data (G_OBJECT (gdk_window), GIC_FILTER_KEY, + GUINT_TO_POINTER (GIC_FILTER_PASSTHRU)); +} + +-(void)insertNewline: (id)sender +{ + GDK_NOTE (EVENTS, g_print ("insertNewline\n")); + g_object_set_data (G_OBJECT (gdk_window), GIC_FILTER_KEY, GUINT_TO_POINTER (GIC_FILTER_PASSTHRU)); +} + +-(void)insertTab: (id)sender +{ + GDK_NOTE (EVENTS, g_print ("insertTab\n")); + g_object_set_data (G_OBJECT (gdk_window), GIC_FILTER_KEY, + GUINT_TO_POINTER (GIC_FILTER_PASSTHRU)); +} + +-(void)moveBackward: (id)sender +{ + GDK_NOTE (EVENTS, g_print ("moveBackward\n")); + g_object_set_data (G_OBJECT (gdk_window), GIC_FILTER_KEY, + GUINT_TO_POINTER (GIC_FILTER_PASSTHRU)); +} + +-(void)moveBackwardAndModifySelection: (id)sender +{ + GDK_NOTE (EVENTS, g_print ("moveBackwardAndModifySelection\n")); + g_object_set_data (G_OBJECT (gdk_window), GIC_FILTER_KEY, + GUINT_TO_POINTER (GIC_FILTER_PASSTHRU)); +} + +-(void)moveDown: (id)sender +{ + GDK_NOTE (EVENTS, g_print ("moveDown\n")); + g_object_set_data (G_OBJECT (gdk_window), GIC_FILTER_KEY, + GUINT_TO_POINTER (GIC_FILTER_PASSTHRU)); +} + +-(void)moveDownAndModifySelection: (id)sender +{ + GDK_NOTE (EVENTS, g_print ("moveDownAndModifySelection\n")); + g_object_set_data (G_OBJECT (gdk_window), GIC_FILTER_KEY, + GUINT_TO_POINTER (GIC_FILTER_PASSTHRU)); +} + +-(void)moveForward: (id)sender +{ + GDK_NOTE (EVENTS, g_print ("moveForward\n")); + g_object_set_data (G_OBJECT (gdk_window), GIC_FILTER_KEY, + GUINT_TO_POINTER (GIC_FILTER_PASSTHRU)); +} + +-(void)moveForwardAndModifySelection: (id)sender +{ + GDK_NOTE (EVENTS, g_print ("moveForwardAndModifySelection\n")); + g_object_set_data (G_OBJECT (gdk_window), GIC_FILTER_KEY, + GUINT_TO_POINTER (GIC_FILTER_PASSTHRU)); +} + +-(void)moveLeft: (id)sender +{ + GDK_NOTE (EVENTS, g_print ("moveLeft\n")); + g_object_set_data (G_OBJECT (gdk_window), GIC_FILTER_KEY, + GUINT_TO_POINTER (GIC_FILTER_PASSTHRU)); +} + +-(void)moveLeftAndModifySelection: (id)sender +{ + GDK_NOTE (EVENTS, g_print ("moveLeftAndModifySelection\n")); + g_object_set_data (G_OBJECT (gdk_window), GIC_FILTER_KEY, + GUINT_TO_POINTER (GIC_FILTER_PASSTHRU)); +} + +-(void)moveRight: (id)sender +{ + GDK_NOTE (EVENTS, g_print ("moveRight\n")); + g_object_set_data (G_OBJECT (gdk_window), GIC_FILTER_KEY, + GUINT_TO_POINTER (GIC_FILTER_PASSTHRU)); +} + +-(void)moveRightAndModifySelection: (id)sender +{ + GDK_NOTE (EVENTS, g_print ("moveRightAndModifySelection\n")); + g_object_set_data (G_OBJECT (gdk_window), GIC_FILTER_KEY, + GUINT_TO_POINTER (GIC_FILTER_PASSTHRU)); +} + +-(void)moveToBeginningOfDocument: (id)sender +{ + GDK_NOTE (EVENTS, g_print ("moveToBeginningOfDocument\n")); + g_object_set_data (G_OBJECT (gdk_window), GIC_FILTER_KEY, + GUINT_TO_POINTER (GIC_FILTER_PASSTHRU)); +} + +-(void)moveToBeginningOfDocumentAndModifySelection: (id)sender +{ + GDK_NOTE (EVENTS, g_print ("moveToBeginningOfDocumentAndModifySelection\n")); + g_object_set_data (G_OBJECT (gdk_window), GIC_FILTER_KEY, + GUINT_TO_POINTER (GIC_FILTER_PASSTHRU)); +} + +-(void)moveToBeginningOfLine: (id)sender +{ + GDK_NOTE (EVENTS, g_print ("moveToBeginningOfLine\n")); + g_object_set_data (G_OBJECT (gdk_window), GIC_FILTER_KEY, + GUINT_TO_POINTER (GIC_FILTER_PASSTHRU)); +} + +-(void)moveToBeginningOfLineAndModifySelection: (id)sender +{ + GDK_NOTE (EVENTS, g_print ("moveToBeginningOfLineAndModifySelection\n")); + g_object_set_data (G_OBJECT (gdk_window), GIC_FILTER_KEY, + GUINT_TO_POINTER (GIC_FILTER_PASSTHRU)); +} + +-(void)moveToEndOfDocument: (id)sender +{ + GDK_NOTE (EVENTS, g_print ("moveToEndOfDocument\n")); + g_object_set_data (G_OBJECT (gdk_window), GIC_FILTER_KEY, + GUINT_TO_POINTER (GIC_FILTER_PASSTHRU)); +} + +-(void)moveToEndOfDocumentAndModifySelection: (id)sender +{ + GDK_NOTE (EVENTS, g_print ("moveToEndOfDocumentAndModifySelection\n")); + g_object_set_data (G_OBJECT (gdk_window), GIC_FILTER_KEY, + GUINT_TO_POINTER (GIC_FILTER_PASSTHRU)); +} + +-(void)moveToEndOfLine: (id)sender +{ + GDK_NOTE (EVENTS, g_print ("moveToEndOfLine\n")); + g_object_set_data (G_OBJECT (gdk_window), GIC_FILTER_KEY, + GUINT_TO_POINTER (GIC_FILTER_PASSTHRU)); +} + +-(void)moveToEndOfLineAndModifySelection: (id)sender +{ + GDK_NOTE (EVENTS, g_print ("moveToEndOfLineAndModifySelection\n")); + g_object_set_data (G_OBJECT (gdk_window), GIC_FILTER_KEY, + GUINT_TO_POINTER (GIC_FILTER_PASSTHRU)); +} + +-(void)moveUp: (id)sender +{ + GDK_NOTE (EVENTS, g_print ("moveUp\n")); + g_object_set_data (G_OBJECT (gdk_window), GIC_FILTER_KEY, + GUINT_TO_POINTER (GIC_FILTER_PASSTHRU)); +} + +-(void)moveUpAndModifySelection: (id)sender +{ + GDK_NOTE (EVENTS, g_print ("moveUpAndModifySelection\n")); + g_object_set_data (G_OBJECT (gdk_window), GIC_FILTER_KEY, + GUINT_TO_POINTER (GIC_FILTER_PASSTHRU)); +} + +-(void)moveWordBackward: (id)sender +{ + GDK_NOTE (EVENTS, g_print ("moveWordBackward\n")); + g_object_set_data (G_OBJECT (gdk_window), GIC_FILTER_KEY, + GUINT_TO_POINTER (GIC_FILTER_PASSTHRU)); +} + +-(void)moveWordBackwardAndModifySelection: (id)sender +{ + GDK_NOTE (EVENTS, g_print ("moveWordBackwardAndModifySelection\n")); + g_object_set_data (G_OBJECT (gdk_window), GIC_FILTER_KEY, + GUINT_TO_POINTER (GIC_FILTER_PASSTHRU)); +} + +-(void)moveWordForward: (id)sender +{ + GDK_NOTE (EVENTS, g_print ("moveWordForward\n")); + g_object_set_data (G_OBJECT (gdk_window), GIC_FILTER_KEY, + GUINT_TO_POINTER (GIC_FILTER_PASSTHRU)); +} + +-(void)moveWordForwardAndModifySelection: (id)sender +{ + GDK_NOTE (EVENTS, g_print ("moveWordForwardAndModifySelection\n")); + g_object_set_data (G_OBJECT (gdk_window), GIC_FILTER_KEY, + GUINT_TO_POINTER (GIC_FILTER_PASSTHRU)); +} + +-(void)moveWordLeft: (id)sender +{ + GDK_NOTE (EVENTS, g_print ("moveWordLeft\n")); + g_object_set_data (G_OBJECT (gdk_window), GIC_FILTER_KEY, + GUINT_TO_POINTER (GIC_FILTER_PASSTHRU)); +} + +-(void)moveWordLeftAndModifySelection: (id)sender +{ + GDK_NOTE (EVENTS, g_print ("moveWordLeftAndModifySelection\n")); + g_object_set_data (G_OBJECT (gdk_window), GIC_FILTER_KEY, + GUINT_TO_POINTER (GIC_FILTER_PASSTHRU)); +} + +-(void)moveWordRight: (id)sender +{ + GDK_NOTE (EVENTS, g_print ("moveWordRight\n")); + g_object_set_data (G_OBJECT (gdk_window), GIC_FILTER_KEY, + GUINT_TO_POINTER (GIC_FILTER_PASSTHRU)); +} + +-(void)moveWordRightAndModifySelection: (id)sender +{ + GDK_NOTE (EVENTS, g_print ("moveWordRightAndModifySelection\n")); + g_object_set_data (G_OBJECT (gdk_window), GIC_FILTER_KEY, + GUINT_TO_POINTER (GIC_FILTER_PASSTHRU)); +} + +-(void)pageDown: (id)sender +{ + GDK_NOTE (EVENTS, g_print ("pageDown\n")); + g_object_set_data (G_OBJECT (gdk_window), GIC_FILTER_KEY, + GUINT_TO_POINTER (GIC_FILTER_PASSTHRU)); +} + +-(void)pageDownAndModifySelection: (id)sender +{ + GDK_NOTE (EVENTS, g_print ("pageDownAndModifySelection\n")); + g_object_set_data (G_OBJECT (gdk_window), GIC_FILTER_KEY, + GUINT_TO_POINTER (GIC_FILTER_PASSTHRU)); +} + +-(void)pageUp: (id)sender +{ + GDK_NOTE (EVENTS, g_print ("pageUp\n")); + g_object_set_data (G_OBJECT (gdk_window), GIC_FILTER_KEY, + GUINT_TO_POINTER (GIC_FILTER_PASSTHRU)); +} + +-(void)pageUpAndModifySelection: (id)sender +{ + GDK_NOTE (EVENTS, g_print ("pageUpAndModifySelection\n")); + g_object_set_data (G_OBJECT (gdk_window), GIC_FILTER_KEY, + GUINT_TO_POINTER (GIC_FILTER_PASSTHRU)); +} + +-(void)selectAll: (id)sender +{ + GDK_NOTE (EVENTS, g_print ("selectAll\n")); + g_object_set_data (G_OBJECT (gdk_window), GIC_FILTER_KEY, + GUINT_TO_POINTER (GIC_FILTER_PASSTHRU)); +} + +-(void)selectLine: (id)sender +{ + GDK_NOTE (EVENTS, g_print ("selectLine\n")); + g_object_set_data (G_OBJECT (gdk_window), GIC_FILTER_KEY, + GUINT_TO_POINTER (GIC_FILTER_PASSTHRU)); +} + +-(void)selectWord: (id)sender +{ + GDK_NOTE (EVENTS, g_print ("selectWord\n")); + g_object_set_data (G_OBJECT (gdk_window), GIC_FILTER_KEY, + GUINT_TO_POINTER (GIC_FILTER_PASSTHRU)); +} + +-(void)noop: (id)sender +{ + GDK_NOTE (EVENTS, g_print ("noop\n")); +} + +/* --------------------------------------------------------------- */ + +-(void)dealloc +{ + if (trackingRect) + { + [self removeTrackingRect: trackingRect]; +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 10500 + [(NSTrackingArea*)trackingRect release]; +#endif + trackingRect = 0; + } + + [super dealloc]; +} + +-(void)setGdkWindow: (GdkWindow *)window +{ + gdk_window = window; +} + +-(GdkWindow *)gdkWindow +{ + return gdk_window; +} + +-(NSTrackingRectTag)trackingRect +{ + return trackingRect; +} + +-(BOOL)isFlipped +{ + return YES; +} + +-(BOOL)isOpaque +{ + if (GDK_WINDOW_DESTROYED (gdk_window)) + return YES; + + /* A view is opaque if its GdkWindow doesn't have the RGBA colormap */ + return gdk_drawable_get_colormap (gdk_window) != + gdk_screen_get_rgba_colormap (_gdk_screen); +} + +-(void)drawRect: (NSRect)rect +{ + GdkRectangle gdk_rect; + GdkWindowObject *private = GDK_WINDOW_OBJECT (gdk_window); + GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl); + const NSRect *drawn_rects; + NSInteger count; + int i; + GdkRegion *region; + + if (GDK_WINDOW_DESTROYED (gdk_window)) + return; + + if (! (private->event_mask & GDK_EXPOSURE_MASK)) + return; + + if (NSEqualRects (rect, NSZeroRect)) + return; + + if (!GDK_WINDOW_IS_MAPPED (gdk_window) && ((gdk_quartz_osx_version() >= GDK_OSX_LEOPARD) && [self wantsLayer])) + { + /* If the window is not yet mapped, clip_region_with_children + * will be empty causing the usual code below to draw nothing. + * To not see garbage on the screen, we draw an aesthetic color + * here. The garbage would be visible if any widget enabled + * the NSView's CALayer in order to add sublayers for custom + * native rendering. + */ + [NSGraphicsContext saveGraphicsState]; + + if (impl->background_color_set) + [[NSColor colorWithDeviceRed:impl->background_color.red / 65535.0 + green:impl->background_color.green / 65535.0 + blue:impl->background_color.blue / 65535.0 + alpha:1.0] + setFill]; + else + [[NSColor windowBackgroundColor] setFill]; + [NSBezierPath fillRect: rect]; + + [NSGraphicsContext restoreGraphicsState]; + + return; + } + + /* Clear our own bookkeeping of regions that need display */ + if (impl->needs_display_region) + { + gdk_region_destroy (impl->needs_display_region); + impl->needs_display_region = NULL; + } + + [self getRectsBeingDrawn: &drawn_rects count: &count]; + region = gdk_region_new (); + + for (i = 0; i < count; i++) + { + gdk_rect.x = drawn_rects[i].origin.x; + gdk_rect.y = drawn_rects[i].origin.y; + gdk_rect.width = drawn_rects[i].size.width; + gdk_rect.height = drawn_rects[i].size.height; + + gdk_region_union_with_rect (region, &gdk_rect); + } + + impl->in_paint_rect_count++; + /* this essentially generates an expose event */ + _gdk_window_process_updates_recurse (gdk_window, region); + impl->in_paint_rect_count--; + + gdk_region_destroy (region); + + if (needsInvalidateShadow) + { + [[self window] invalidateShadow]; + needsInvalidateShadow = NO; + } +} + +-(void)setNeedsInvalidateShadow: (BOOL)invalidate +{ + needsInvalidateShadow = invalidate; +} + +/* For information on setting up tracking rects properly, see here: + * http://developer.apple.com/documentation/Cocoa/Conceptual/EventOverview/EventOverview.pdf + */ +-(void)updateTrackingRect +{ + GdkWindowObject *private = GDK_WINDOW_OBJECT (gdk_window); + GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl); + NSRect rect; + +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 10500 + NSTrackingArea *trackingArea; +#endif + + if (!impl || !impl->toplevel) + return; + + if (trackingRect) + { + [self removeTrackingRect: trackingRect]; +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 10500 + [(NSTrackingArea*)trackingRect release]; +#endif + trackingRect = 0; + } + + if (!impl->toplevel) + return; + + /* Note, if we want to set assumeInside we can use: + * NSPointInRect ([[self window] convertScreenToBase:[NSEvent mouseLocation]], rect) + */ + + rect = [self bounds]; + +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 10500 + trackingArea = [[NSTrackingArea alloc] initWithRect: rect + options: NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved | NSTrackingCursorUpdate | NSTrackingActiveInActiveApp | NSTrackingInVisibleRect | NSTrackingEnabledDuringMouseDrag + owner: self + userInfo: nil]; + [self addTrackingArea: trackingArea]; + trackingRect = (NSInteger)[trackingArea retain]; +#else + trackingRect = [self addTrackingRect: rect + owner: self + userData: nil + assumeInside: NO]; +#endif +} + +-(void)viewDidMoveToWindow +{ + if (![self window]) /* We are destroyed already */ + return; + + [self updateTrackingRect]; +} + +-(void)viewWillMoveToWindow: (NSWindow *)newWindow +{ + if (newWindow == nil && trackingRect) + { + [self removeTrackingRect: trackingRect]; +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 10500 + [(NSTrackingArea*)trackingRect release]; +#endif + + trackingRect = 0; + } +} + +-(void)setFrame: (NSRect)frame +{ + [super setFrame: frame]; + + if ([self window]) + [self updateTrackingRect]; +} + +@end diff --git a/libs/tk/ydk/quartz/GdkQuartzWindow.c b/libs/tk/ydk/quartz/GdkQuartzWindow.c new file mode 100644 index 0000000000..a4e6e1b067 --- /dev/null +++ b/libs/tk/ydk/quartz/GdkQuartzWindow.c @@ -0,0 +1,667 @@ +/* GdkQuartzWindow.m + * + * Copyright (C) 2005-2007 Imendio AB + * + * 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. + */ + +#import "GdkQuartzWindow.h" +#include "gdkwindow-quartz.h" +#include "gdkprivate-quartz.h" + +@implementation GdkQuartzWindow + +- (void)windowWillClose:(NSNotification*)notification +{ + // Clears the delegate when window is going to be closed; since EL + // Capitan it is possible that the methods of delegate would get + // called after the window has been closed. + [self setDelegate:nil]; +} + +-(BOOL)windowShouldClose:(id)sender +{ + GdkWindow *window = [[self contentView] gdkWindow]; + GdkEvent *event; + + event = gdk_event_new (GDK_DELETE); + + event->any.window = g_object_ref (window); + event->any.send_event = FALSE; + + _gdk_event_queue_append (gdk_display_get_default (), event); + + return NO; +} + +-(void)windowWillMiniaturize:(NSNotification *)aNotification +{ + GdkWindow *window = [[self contentView] gdkWindow]; + + _gdk_quartz_window_detach_from_parent (window); +} + +-(void)windowDidMiniaturize:(NSNotification *)aNotification +{ + GdkWindow *window = [[self contentView] gdkWindow]; + + gdk_synthesize_window_state (window, 0, + GDK_WINDOW_STATE_ICONIFIED); +} + +-(void)windowDidDeminiaturize:(NSNotification *)aNotification +{ + GdkWindow *window = [[self contentView] gdkWindow]; + + _gdk_quartz_window_attach_to_parent (window); + + gdk_synthesize_window_state (window, GDK_WINDOW_STATE_ICONIFIED, 0); +} + +-(void)windowDidBecomeKey:(NSNotification *)aNotification +{ + GdkWindow *window = [[self contentView] gdkWindow]; + + _gdk_quartz_events_update_focus_window (window, TRUE); +} + +-(void)windowDidResignKey:(NSNotification *)aNotification +{ + GdkWindow *window = [[self contentView] gdkWindow]; + + _gdk_quartz_events_update_focus_window (window, FALSE); +} + +-(void)windowDidBecomeMain:(NSNotification *)aNotification +{ + GdkWindow *window = [[self contentView] gdkWindow]; + + if (![self isVisible]) + { + /* Note: This is a hack needed because for unknown reasons, hidden + * windows get shown when clicking the dock icon when the application + * is not already active. + */ + [self orderOut:nil]; + return; + } + + _gdk_quartz_window_did_become_main (window); +} + +-(void)windowDidResignMain:(NSNotification *)aNotification +{ + GdkWindow *window; + + window = [[self contentView] gdkWindow]; + _gdk_quartz_window_did_resign_main (window); +} + +/* Used in combination with NSLeftMouseUp in sendEvent to keep track + * of when the window is being moved with the mouse. + */ +-(void)windowWillMove:(NSNotification *)aNotification +{ + inMove = YES; +} + +-(void)sendEvent:(NSEvent *)event +{ + switch ([event type]) + { + case NSLeftMouseUp: + { + double time = ((double)[event timestamp]) * 1000.0; + + _gdk_quartz_events_break_all_grabs (time); + inManualMove = NO; + inManualResize = NO; + inMove = NO; + break; + } + + case NSLeftMouseDragged: + if ([self trackManualMove] || [self trackManualResize]) + return; + break; + + default: + break; + } + + [super sendEvent:event]; +} + +-(BOOL)isInMove +{ + return inMove; +} + +-(void)checkSendEnterNotify +{ + GdkWindow *window = [[self contentView] gdkWindow]; + GdkWindowObject *private = (GdkWindowObject *)window; + GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl); + + /* When a new window has been created, and the mouse + * is in the window area, we will not receive an NSMouseEntered + * event. Therefore, we synthesize an enter notify event manually. + */ + if (!initialPositionKnown) + { + initialPositionKnown = YES; + + if (NSPointInRect ([NSEvent mouseLocation], [self frame])) + { + NSEvent *event; + + event = [NSEvent enterExitEventWithType: NSMouseEntered + location: [self mouseLocationOutsideOfEventStream] + modifierFlags: 0 + timestamp: [[NSApp currentEvent] timestamp] + windowNumber: [impl->toplevel windowNumber] + context: NULL + eventNumber: 0 + trackingNumber: [impl->view trackingRect] + userData: nil]; + + [NSApp postEvent:event atStart:NO]; + } + } +} + +/* Always update both the position and size. Certain resize operations + * (e.g. going fullscreen) also move the origin of the window. Move + * notifications sometimes also indicate a different window size (for + * example if the window size requested in the configure request was not + * fully granted). + */ +-(void)handleDidMoveResize +{ + NSRect content_rect = [self contentRectForFrameRect:[self frame]]; + GdkWindow *window = [[self contentView] gdkWindow]; + GdkWindowObject *private = (GdkWindowObject *)window; + GdkEvent *event; + + private->width = content_rect.size.width; + private->height = content_rect.size.height; + + _gdk_quartz_window_update_position (window); + + [[self contentView] setFrame:NSMakeRect (0, 0, private->width, private->height)]; + + _gdk_window_update_size (window); + + /* Synthesize a configure event */ + event = gdk_event_new (GDK_CONFIGURE); + event->configure.window = g_object_ref (window); + event->configure.x = private->x; + event->configure.y = private->y; + event->configure.width = private->width; + event->configure.height = private->height; + + _gdk_event_queue_append (gdk_display_get_default (), event); + + [self checkSendEnterNotify]; +} + +-(void)windowDidMove:(NSNotification *)aNotification +{ + [self handleDidMoveResize]; +} + +-(void)windowDidResize:(NSNotification *)aNotification +{ + [self handleDidMoveResize]; +} + +-(id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)styleMask backing:(NSBackingStoreType)backingType defer:(BOOL)flag screen:(NSScreen *)screen +{ + self = [super initWithContentRect:contentRect + styleMask:styleMask + backing:backingType + defer:flag + screen:screen]; + + [self setAcceptsMouseMovedEvents:YES]; + [self setDelegate:self]; + [self setReleasedWhenClosed:YES]; + + NSColorSpace *dcs = [NSColorSpace genericRGBColorSpace]; + [self setColorSpace:dcs]; + + return self; +} + +-(BOOL)canBecomeMainWindow +{ + GdkWindow *window = [[self contentView] gdkWindow]; + GdkWindowObject *private = (GdkWindowObject *)window; + GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl); + + switch (impl->type_hint) + { + case GDK_WINDOW_TYPE_HINT_NORMAL: + case GDK_WINDOW_TYPE_HINT_DIALOG: + return YES; + + case GDK_WINDOW_TYPE_HINT_MENU: + case GDK_WINDOW_TYPE_HINT_TOOLBAR: + case GDK_WINDOW_TYPE_HINT_SPLASHSCREEN: + case GDK_WINDOW_TYPE_HINT_UTILITY: + case GDK_WINDOW_TYPE_HINT_DOCK: + case GDK_WINDOW_TYPE_HINT_DESKTOP: + case GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU: + case GDK_WINDOW_TYPE_HINT_POPUP_MENU: + case GDK_WINDOW_TYPE_HINT_TOOLTIP: + case GDK_WINDOW_TYPE_HINT_NOTIFICATION: + case GDK_WINDOW_TYPE_HINT_COMBO: + case GDK_WINDOW_TYPE_HINT_DND: + return NO; + } + + return YES; +} + +-(BOOL)canBecomeKeyWindow +{ + GdkWindow *window = [[self contentView] gdkWindow]; + GdkWindowObject *private = (GdkWindowObject *)window; + GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl); + + if (!private->accept_focus) + return NO; + + /* Popup windows should not be able to get focused in the window + * manager sense, it's only handled through grabs. + */ + if (private->window_type == GDK_WINDOW_TEMP) + return NO; + + switch (impl->type_hint) + { + case GDK_WINDOW_TYPE_HINT_NORMAL: + case GDK_WINDOW_TYPE_HINT_DIALOG: + case GDK_WINDOW_TYPE_HINT_MENU: + case GDK_WINDOW_TYPE_HINT_TOOLBAR: + case GDK_WINDOW_TYPE_HINT_UTILITY: + case GDK_WINDOW_TYPE_HINT_DOCK: + case GDK_WINDOW_TYPE_HINT_DESKTOP: + case GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU: + case GDK_WINDOW_TYPE_HINT_POPUP_MENU: + case GDK_WINDOW_TYPE_HINT_COMBO: + return YES; + + case GDK_WINDOW_TYPE_HINT_SPLASHSCREEN: + case GDK_WINDOW_TYPE_HINT_TOOLTIP: + case GDK_WINDOW_TYPE_HINT_NOTIFICATION: + case GDK_WINDOW_TYPE_HINT_DND: + return NO; + } + + return YES; +} + +- (void)showAndMakeKey:(BOOL)makeKey +{ + GdkWindow *window = [[self contentView] gdkWindow]; + GdkWindowObject *private = (GdkWindowObject *)window; + GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl); + + inShowOrHide = YES; + + if (makeKey) + [impl->toplevel makeKeyAndOrderFront:impl->toplevel]; + else + [impl->toplevel orderFront:nil]; + + inShowOrHide = NO; + + [self checkSendEnterNotify]; +} + +- (void)hide +{ + GdkWindow *window = [[self contentView] gdkWindow]; + GdkWindowObject *private = (GdkWindowObject *)window; + GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl); + + inShowOrHide = YES; + [impl->toplevel orderOut:nil]; + inShowOrHide = NO; + + initialPositionKnown = NO; +} + +- (BOOL)trackManualMove +{ + NSPoint currentLocation; + NSPoint newOrigin; + NSRect screenFrame = [[NSScreen mainScreen] visibleFrame]; + NSRect windowFrame = [self frame]; + + if (!inManualMove) + return NO; + + currentLocation = [self convertBaseToScreen:[self mouseLocationOutsideOfEventStream]]; + newOrigin.x = currentLocation.x - initialMoveLocation.x; + newOrigin.y = currentLocation.y - initialMoveLocation.y; + + /* Clamp vertical position to below the menu bar. */ + if (newOrigin.y + windowFrame.size.height > screenFrame.origin.y + screenFrame.size.height) + newOrigin.y = screenFrame.origin.y + screenFrame.size.height - windowFrame.size.height; + + [self setFrameOrigin:newOrigin]; + + return YES; +} + +-(void)beginManualMove +{ + NSRect frame = [self frame]; + + if (inMove || inManualMove || inManualResize) + return; + + inManualMove = YES; + + initialMoveLocation = [self convertBaseToScreen:[self mouseLocationOutsideOfEventStream]]; + initialMoveLocation.x -= frame.origin.x; + initialMoveLocation.y -= frame.origin.y; +} + +- (BOOL)trackManualResize +{ + NSPoint currentLocation; + NSRect newFrame; + float dx, dy; + NSSize min_size; + + if (!inManualResize || inTrackManualResize) + return NO; + + inTrackManualResize = YES; + + currentLocation = [self convertBaseToScreen:[self mouseLocationOutsideOfEventStream]]; + currentLocation.x -= initialResizeFrame.origin.x; + currentLocation.y -= initialResizeFrame.origin.y; + + dx = currentLocation.x - initialResizeLocation.x; + dy = -(currentLocation.y - initialResizeLocation.y); + + newFrame = initialResizeFrame; + newFrame.size.width = initialResizeFrame.size.width + dx; + newFrame.size.height = initialResizeFrame.size.height + dy; + + min_size = [self contentMinSize]; + if (newFrame.size.width < min_size.width) + newFrame.size.width = min_size.width; + if (newFrame.size.height < min_size.height) + newFrame.size.height = min_size.height; + + /* We could also apply aspect ratio: + newFrame.size.height = newFrame.size.width / [self aspectRatio].width * [self aspectRatio].height; + */ + + dy = newFrame.size.height - initialResizeFrame.size.height; + + newFrame.origin.x = initialResizeFrame.origin.x; + newFrame.origin.y = initialResizeFrame.origin.y - dy; + + [self setFrame:newFrame display:YES]; + + /* Let the resizing be handled by GTK+. */ + if (g_main_context_pending (NULL)) + g_main_context_iteration (NULL, FALSE); + + inTrackManualResize = NO; + + return YES; +} + +-(BOOL)isInManualResize +{ + return inManualResize; +} + +-(void)beginManualResize +{ + if (inMove || inManualMove || inManualResize) + return; + + inManualResize = YES; + + initialResizeFrame = [self frame]; + initialResizeLocation = [self convertBaseToScreen:[self mouseLocationOutsideOfEventStream]]; + initialResizeLocation.x -= initialResizeFrame.origin.x; + initialResizeLocation.y -= initialResizeFrame.origin.y; +} + + + +static GdkDragContext *current_context = NULL; + +static GdkDragAction +drag_operation_to_drag_action (NSDragOperation operation) +{ + GdkDragAction result = 0; + + /* GDK and Quartz drag operations do not map 1:1. + * This mapping represents about the best that we + * can come up. + * + * Note that NSDragOperationPrivate and GDK_ACTION_PRIVATE + * have almost opposite meanings: the GDK one means that the + * destination is solely responsible for the action; the Quartz + * one means that the source and destination will agree + * privately on the action. NSOperationGeneric is close in meaning + * to GDK_ACTION_PRIVATE but there is a problem: it will be + * sent for any ordinary drag, and likely not understood + * by any intra-widget drag (since the source & dest are the + * same). + */ + + if (operation & NSDragOperationGeneric) + result |= GDK_ACTION_MOVE; + if (operation & NSDragOperationCopy) + result |= GDK_ACTION_COPY; + if (operation & NSDragOperationMove) + result |= GDK_ACTION_MOVE; + if (operation & NSDragOperationLink) + result |= GDK_ACTION_LINK; + + return result; +} + +static NSDragOperation +drag_action_to_drag_operation (GdkDragAction action) +{ + NSDragOperation result = 0; + + if (action & GDK_ACTION_COPY) + result |= NSDragOperationCopy; + if (action & GDK_ACTION_LINK) + result |= NSDragOperationLink; + if (action & GDK_ACTION_MOVE) + result |= NSDragOperationMove; + + return result; +} + +static void +update_context_from_dragging_info (id sender) +{ + g_assert (current_context != NULL); + + GDK_DRAG_CONTEXT_PRIVATE (current_context)->dragging_info = sender; + current_context->suggested_action = drag_operation_to_drag_action ([sender draggingSourceOperationMask]); + current_context->actions = current_context->suggested_action; +} + +- (NSDragOperation)draggingEntered:(id )sender +{ + GdkEvent event; + + if (current_context) + g_object_unref (current_context); + + current_context = gdk_drag_context_new (); + update_context_from_dragging_info (sender); + + event.dnd.type = GDK_DRAG_ENTER; + event.dnd.window = g_object_ref ([[self contentView] gdkWindow]); + event.dnd.send_event = FALSE; + event.dnd.context = current_context; + event.dnd.time = GDK_CURRENT_TIME; + + (*_gdk_event_func) (&event, _gdk_event_data); + + return NSDragOperationNone; +} + +- (void)draggingEnded:(id )sender +{ + /* leave a note for the source about what action was taken */ + if (_gdk_quartz_drag_source_context && current_context) + _gdk_quartz_drag_source_context->action = current_context->action; + + if (current_context) + g_object_unref (current_context); + current_context = NULL; +} + +- (void)draggingExited:(id )sender +{ + GdkEvent event; + + event.dnd.type = GDK_DRAG_LEAVE; + event.dnd.window = g_object_ref ([[self contentView] gdkWindow]); + event.dnd.send_event = FALSE; + event.dnd.context = current_context; + event.dnd.time = GDK_CURRENT_TIME; + + (*_gdk_event_func) (&event, _gdk_event_data); + + g_object_unref (current_context); + current_context = NULL; +} + +- (NSDragOperation)draggingUpdated:(id )sender +{ + NSPoint point = [sender draggingLocation]; + NSPoint screen_point = [self convertBaseToScreen:point]; + GdkEvent event; + int gx, gy; + + update_context_from_dragging_info (sender); + _gdk_quartz_window_nspoint_to_gdk_xy (screen_point, &gx, &gy); + + event.dnd.type = GDK_DRAG_MOTION; + event.dnd.window = g_object_ref ([[self contentView] gdkWindow]); + event.dnd.send_event = FALSE; + event.dnd.context = current_context; + event.dnd.time = GDK_CURRENT_TIME; + event.dnd.x_root = gx; + event.dnd.y_root = gy; + + (*_gdk_event_func) (&event, _gdk_event_data); + + g_object_unref (event.dnd.window); + + return drag_action_to_drag_operation (current_context->action); +} + +- (BOOL)performDragOperation:(id )sender +{ + NSPoint point = [sender draggingLocation]; + NSPoint screen_point = [self convertBaseToScreen:point]; + GdkEvent event; + int gy, gx; + + update_context_from_dragging_info (sender); + _gdk_quartz_window_nspoint_to_gdk_xy (screen_point, &gx, &gy); + + event.dnd.type = GDK_DROP_START; + event.dnd.window = g_object_ref ([[self contentView] gdkWindow]); + event.dnd.send_event = FALSE; + event.dnd.context = current_context; + event.dnd.time = GDK_CURRENT_TIME; + event.dnd.x_root = gx; + event.dnd.y_root = gy; + + (*_gdk_event_func) (&event, _gdk_event_data); + + g_object_unref (event.dnd.window); + + g_object_unref (current_context); + current_context = NULL; + + return YES; +} + +- (BOOL)wantsPeriodicDraggingUpdates +{ + return NO; +} + +- (void)draggedImage:(NSImage *)anImage endedAt:(NSPoint)aPoint operation:(NSDragOperation)operation +{ + GdkEvent event; + GdkScreen *screen; + + g_assert (_gdk_quartz_drag_source_context != NULL); + + event.dnd.type = GDK_DROP_FINISHED; + event.dnd.window = g_object_ref ([[self contentView] gdkWindow]); + event.dnd.send_event = FALSE; + event.dnd.context = _gdk_quartz_drag_source_context; + + screen = gdk_window_get_screen (event.dnd.window); + + if (screen) + { + GList* windows, *list; + gint gx, gy; + + event.dnd.context->dest_window = NULL; + + windows = gdk_screen_get_toplevel_windows (screen); + _gdk_quartz_window_nspoint_to_gdk_xy (aPoint, &gx, &gy); + + for (list = windows; list; list = list->next) + { + GdkWindow* win = (GdkWindow*) list->data; + gint wx, wy; + gint ww, wh; + + gdk_window_get_root_origin (win, &wx, &wy); + ww = gdk_window_get_width (win); + wh = gdk_window_get_height (win); + + if (gx > wx && gy > wy && gx <= wx + ww && gy <= wy + wh) + event.dnd.context->dest_window = win; + } + } + + (*_gdk_event_func) (&event, _gdk_event_data); + + g_object_unref (event.dnd.window); + + g_object_unref (_gdk_quartz_drag_source_context); + _gdk_quartz_drag_source_context = NULL; +} + +@end diff --git a/libs/tk/ydk/quartz/gdkapplaunchcontext-quartz.c b/libs/tk/ydk/quartz/gdkapplaunchcontext-quartz.c new file mode 100644 index 0000000000..ce0b9c2828 --- /dev/null +++ b/libs/tk/ydk/quartz/gdkapplaunchcontext-quartz.c @@ -0,0 +1,42 @@ +/* gdkapplaunchcontext-quartz.c - Gtk+ implementation for GAppLaunchContext + + Copyright (C) 2007 Red Hat, Inc. + + The Gnome 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 Gnome 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 Gnome 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: Matthias Clasen +*/ + +#include "config.h" + +#include "gdkapplaunchcontext.h" + + +char * +_gdk_windowing_get_startup_notify_id (GAppLaunchContext *context, + GAppInfo *info, + GList *files) +{ + return NULL; +} + +void +_gdk_windowing_launch_failed (GAppLaunchContext *context, + const char *startup_notify_id) +{ +} + + diff --git a/libs/tk/ydk/quartz/gdkcolor-quartz.c b/libs/tk/ydk/quartz/gdkcolor-quartz.c new file mode 100644 index 0000000000..2ef04279a0 --- /dev/null +++ b/libs/tk/ydk/quartz/gdkcolor-quartz.c @@ -0,0 +1,258 @@ +/* gdkcolor-quartz.c + * + * Copyright (C) 2005 Imendio AB + * + * 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. + */ + +#include "config.h" + +#include "gdkcolor.h" +#include "gdkprivate-quartz.h" + +GType +gdk_colormap_get_type (void) +{ + static GType object_type = 0; + + if (!object_type) + { + const GTypeInfo object_info = + { + sizeof (GdkColormapClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) NULL, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (GdkColormap), + 0, /* n_preallocs */ + (GInstanceInitFunc) NULL, + }; + + object_type = g_type_register_static (G_TYPE_OBJECT, + "GdkColormap", + &object_info, + 0); + } + + return object_type; +} + +GdkColormap * +gdk_colormap_new (GdkVisual *visual, + gint private_cmap) +{ + g_return_val_if_fail (visual != NULL, NULL); + + /* FIXME: Implement */ + return NULL; +} + +GdkColormap * +gdk_screen_get_system_colormap (GdkScreen *screen) +{ + static GdkColormap *colormap = NULL; + + g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL); + + if (!colormap) + { + colormap = g_object_new (GDK_TYPE_COLORMAP, NULL); + + colormap->visual = gdk_visual_get_system (); + colormap->size = colormap->visual->colormap_size; + } + + return colormap; +} + + +GdkColormap * +gdk_screen_get_rgba_colormap (GdkScreen *screen) +{ + static GdkColormap *colormap = NULL; + + g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL); + + if (!colormap) + { + colormap = g_object_new (GDK_TYPE_COLORMAP, NULL); + + colormap->visual = gdk_screen_get_rgba_visual (screen); + colormap->size = colormap->visual->colormap_size; + } + + return colormap; +} + +gint +gdk_colormap_get_system_size (void) +{ + /* FIXME: Implement */ + return 0; +} + +void +gdk_colormap_change (GdkColormap *colormap, + gint ncolors) +{ + /* FIXME: Implement */ +} + +gboolean +gdk_colors_alloc (GdkColormap *colormap, + gboolean contiguous, + gulong *planes, + gint nplanes, + gulong *pixels, + gint npixels) +{ + return TRUE; +} + +void +gdk_colors_free (GdkColormap *colormap, + gulong *pixels, + gint npixels, + gulong planes) +{ +} + +void +gdk_colormap_free_colors (GdkColormap *colormap, + const GdkColor *colors, + gint n_colors) +{ + /* This function shouldn't do anything since colors are never allocated. */ +} + +gint +gdk_colormap_alloc_colors (GdkColormap *colormap, + GdkColor *colors, + gint ncolors, + gboolean writeable, + gboolean best_match, + gboolean *success) +{ + int i; + int alpha; + + g_return_val_if_fail (GDK_IS_COLORMAP (colormap), ncolors); + g_return_val_if_fail (colors != NULL, ncolors); + g_return_val_if_fail (success != NULL, ncolors); + + if (gdk_colormap_get_visual (colormap)->depth == 32) + alpha = 0xff; + else + alpha = 0; + + for (i = 0; i < ncolors; i++) + { + colors[i].pixel = alpha << 24 | + ((colors[i].red >> 8) & 0xff) << 16 | + ((colors[i].green >> 8) & 0xff) << 8 | + ((colors[i].blue >> 8) & 0xff); + } + + *success = TRUE; + + return 0; +} + +void +gdk_colormap_query_color (GdkColormap *colormap, + gulong pixel, + GdkColor *result) +{ + result->red = pixel >> 16 & 0xff; + result->red += result->red << 8; + + result->green = pixel >> 8 & 0xff; + result->green += result->green << 8; + + result->blue = pixel & 0xff; + result->blue += result->blue << 8; +} + +GdkScreen* +gdk_colormap_get_screen (GdkColormap *cmap) +{ + g_return_val_if_fail (cmap != NULL, NULL); + + return gdk_screen_get_default (); +} + +CGColorRef +_gdk_quartz_colormap_get_cgcolor_from_pixel (GdkDrawable *drawable, + guint32 pixel) +{ + CGFloat components[4] = { 0.0f, }; + CGColorRef color; + CGColorSpaceRef colorspace; + const GdkVisual *visual; + GdkColormap *colormap; + + colormap = gdk_drawable_get_colormap (drawable); + if (colormap) + visual = gdk_colormap_get_visual (colormap); + else + visual = gdk_visual_get_best_with_depth (gdk_drawable_get_depth (drawable)); + + switch (visual->type) + { + case GDK_VISUAL_STATIC_GRAY: + case GDK_VISUAL_GRAYSCALE: + components[0] = (pixel & 0xff) / 255.0f; + + if (visual->depth == 1) + components[0] = components[0] == 0.0f ? 0.0f : 1.0f; + components[1] = 1.0f; + + colorspace = CGColorSpaceCreateWithName (kCGColorSpaceGenericGray); + color = CGColorCreate (colorspace, components); + CGColorSpaceRelease (colorspace); + break; + + default: + components[0] = (pixel >> 16 & 0xff) / 255.0; + components[1] = (pixel >> 8 & 0xff) / 255.0; + components[2] = (pixel & 0xff) / 255.0; + + if (visual->depth == 32) + components[3] = (pixel >> 24 & 0xff) / 255.0; + else + components[3] = 1.0; + + colorspace = CGColorSpaceCreateDeviceRGB (); + color = CGColorCreate (colorspace, components); + CGColorSpaceRelease (colorspace); + break; + } + + return color; +} + +gboolean +gdk_color_change (GdkColormap *colormap, + GdkColor *color) +{ + if (color->pixel < 0 || color->pixel >= colormap->size) + return FALSE; + + return TRUE; +} + diff --git a/libs/tk/ydk/quartz/gdkcursor-quartz.c b/libs/tk/ydk/quartz/gdkcursor-quartz.c new file mode 100644 index 0000000000..dcd4220031 --- /dev/null +++ b/libs/tk/ydk/quartz/gdkcursor-quartz.c @@ -0,0 +1,498 @@ +/* gdkcursor-quartz.c + * + * Copyright (C) 2005-2007 Imendio AB + * + * 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. + */ + +#include "config.h" + +#include "gdkdisplay.h" +#include "gdkcursor.h" +#include "gdkprivate-quartz.h" + +#include "xcursors.h" + +static GdkCursor *cached_xcursors[G_N_ELEMENTS (xcursors)]; + +static GdkCursor * +gdk_quartz_cursor_new_from_nscursor (NSCursor *nscursor, + GdkCursorType cursor_type) +{ + GdkCursorPrivate *private; + GdkCursor *cursor; + + private = g_new (GdkCursorPrivate, 1); + private->nscursor = nscursor; + + cursor = (GdkCursor *)private; + cursor->type = cursor_type; + cursor->ref_count = 1; + + return cursor; +} + +static GdkCursor * +create_blank_cursor (void) +{ + NSCursor *nscursor; + NSImage *nsimage; + NSSize size = { 1.0, 1.0 }; + + nsimage = [[NSImage alloc] initWithSize:size]; + nscursor = [[NSCursor alloc] initWithImage:nsimage + hotSpot:NSMakePoint(0.0, 0.0)]; + [nsimage release]; + + return gdk_quartz_cursor_new_from_nscursor (nscursor, GDK_BLANK_CURSOR); +} + +static gboolean +get_bit (const guchar *data, + gint width, + gint height, + gint x, + gint y) +{ + gint bytes_per_line; + const guchar *src; + + if (x < 0 || y < 0 || x >= width || y >= height) + return FALSE; + + bytes_per_line = (width + 7) / 8; + + src = &data[y * bytes_per_line]; + return ((src[x / 8] >> x % 8) & 1); +} + +static GdkCursor * +create_builtin_cursor (GdkCursorType cursor_type) +{ + GdkCursor *cursor; + NSBitmapImageRep *bitmap_rep; + NSInteger mask_width, mask_height; + gint src_width, src_height; + gint dst_stride; + const guchar *mask_start, *src_start; + gint dx, dy; + gint x, y; + NSPoint hotspot; + NSImage *image; + NSCursor *nscursor; + + if (cursor_type >= G_N_ELEMENTS (xcursors) || cursor_type < 0) + return NULL; + + cursor = cached_xcursors[cursor_type]; + if (cursor) + return cursor; + + GDK_QUARTZ_ALLOC_POOL; + + src_width = xcursors[cursor_type].width; + src_height = xcursors[cursor_type].height; + mask_width = xcursors[cursor_type+1].width; + mask_height = xcursors[cursor_type+1].height; + + bitmap_rep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL + pixelsWide:mask_width pixelsHigh:mask_height + bitsPerSample:8 samplesPerPixel:4 + hasAlpha:YES isPlanar:NO colorSpaceName:NSDeviceRGBColorSpace + bytesPerRow:0 bitsPerPixel:0]; + + dst_stride = [bitmap_rep bytesPerRow]; + + src_start = xcursors[cursor_type].bits; + mask_start = xcursors[cursor_type+1].bits; + + dx = xcursors[cursor_type+1].hotx - xcursors[cursor_type].hotx; + dy = xcursors[cursor_type+1].hoty - xcursors[cursor_type].hoty; + + for (y = 0; y < mask_height; y++) + { + guchar *dst = [bitmap_rep bitmapData] + y * dst_stride; + + for (x = 0; x < mask_width; x++) + { + if (get_bit (mask_start, mask_width, mask_height, x, y)) + { + if (get_bit (src_start, src_width, src_height, x - dx, y - dy)) + { + *dst++ = 0; + *dst++ = 0; + *dst++ = 0; + } + else + { + *dst++ = 0xff; + *dst++ = 0xff; + *dst++ = 0xff; + } + + *dst++ = 0xff; + } + else + { + *dst++ = 0; + *dst++ = 0; + *dst++ = 0; + *dst++ = 0; + } + } + } + + image = [[NSImage alloc] init]; + [image addRepresentation:bitmap_rep]; + [bitmap_rep release]; + + hotspot = NSMakePoint (xcursors[cursor_type+1].hotx, + xcursors[cursor_type+1].hoty); + + nscursor = [[NSCursor alloc] initWithImage:image hotSpot:hotspot]; + [image release]; + + cursor = gdk_quartz_cursor_new_from_nscursor (nscursor, GDK_CURSOR_IS_PIXMAP); + + cached_xcursors[cursor_type] = gdk_cursor_ref (cursor); + + GDK_QUARTZ_RELEASE_POOL; + + return cursor; +} + +GdkCursor* +gdk_cursor_new_for_display (GdkDisplay *display, + GdkCursorType cursor_type) +{ + NSCursor *nscursor; + + g_return_val_if_fail (display == gdk_display_get_default (), NULL); + + switch (cursor_type) + { + case GDK_XTERM: + nscursor = [NSCursor IBeamCursor]; + break; + case GDK_SB_H_DOUBLE_ARROW: + nscursor = [NSCursor resizeLeftRightCursor]; + break; + case GDK_SB_V_DOUBLE_ARROW: + nscursor = [NSCursor resizeUpDownCursor]; + break; + case GDK_SB_UP_ARROW: + case GDK_BASED_ARROW_UP: + case GDK_BOTTOM_TEE: + case GDK_TOP_SIDE: + nscursor = [NSCursor resizeUpCursor]; + break; + case GDK_SB_DOWN_ARROW: + case GDK_BASED_ARROW_DOWN: + case GDK_TOP_TEE: + case GDK_BOTTOM_SIDE: + nscursor = [NSCursor resizeDownCursor]; + break; + case GDK_SB_LEFT_ARROW: + case GDK_RIGHT_TEE: + case GDK_LEFT_SIDE: + nscursor = [NSCursor resizeLeftCursor]; + break; + case GDK_SB_RIGHT_ARROW: + case GDK_LEFT_TEE: + case GDK_RIGHT_SIDE: + nscursor = [NSCursor resizeRightCursor]; + break; + case GDK_TCROSS: + case GDK_CROSS: + case GDK_CROSSHAIR: + case GDK_DIAMOND_CROSS: + nscursor = [NSCursor crosshairCursor]; + break; + case GDK_HAND1: + case GDK_HAND2: + nscursor = [NSCursor pointingHandCursor]; + break; + case GDK_CURSOR_IS_PIXMAP: + return NULL; + case GDK_BLANK_CURSOR: + return create_blank_cursor (); + default: + return gdk_cursor_ref (create_builtin_cursor (cursor_type)); + } + + [nscursor retain]; + return gdk_quartz_cursor_new_from_nscursor (nscursor, cursor_type); +} + +GdkCursor* +gdk_cursor_new_from_pixmap (GdkPixmap *source, + GdkPixmap *mask, + const GdkColor *fg, + const GdkColor *bg, + gint x, + gint y) +{ + NSBitmapImageRep *bitmap_rep; + NSImage *image; + NSCursor *nscursor; + GdkCursor *cursor; + int width, height; + gint tmp_x, tmp_y; + guchar *dst_data, *mask_data, *src_data; + guchar *mask_start, *src_start; + int dst_stride; + + g_return_val_if_fail (GDK_IS_PIXMAP (source), NULL); + g_return_val_if_fail (GDK_IS_PIXMAP (mask), NULL); + g_return_val_if_fail (fg != NULL, NULL); + g_return_val_if_fail (bg != NULL, NULL); + + GDK_QUARTZ_ALLOC_POOL; + + gdk_drawable_get_size (source, &width, &height); + + bitmap_rep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL + pixelsWide:(NSInteger)width pixelsHigh:(NSInteger)height + bitsPerSample:8 samplesPerPixel:4 + hasAlpha:YES isPlanar:NO colorSpaceName:NSDeviceRGBColorSpace + bytesPerRow:0 bitsPerPixel:0]; + + dst_stride = [bitmap_rep bytesPerRow]; + mask_start = GDK_PIXMAP_IMPL_QUARTZ (GDK_PIXMAP_OBJECT (mask)->impl)->data; + src_start = GDK_PIXMAP_IMPL_QUARTZ (GDK_PIXMAP_OBJECT (source)->impl)->data; + + for (tmp_y = 0; tmp_y < height; tmp_y++) + { + dst_data = [bitmap_rep bitmapData] + tmp_y * dst_stride; + mask_data = mask_start + tmp_y * width; + src_data = src_start + tmp_y * width; + + for (tmp_x = 0; tmp_x < width; tmp_x++) + { + if (*mask_data++) + { + const GdkColor *color; + + if (*src_data++) + color = fg; + else + color = bg; + + *dst_data++ = (color->red >> 8) & 0xff; + *dst_data++ = (color->green >> 8) & 0xff; + *dst_data++ = (color->blue >> 8) & 0xff; + *dst_data++ = 0xff; + + } + else + { + *dst_data++ = 0x00; + *dst_data++ = 0x00; + *dst_data++ = 0x00; + *dst_data++ = 0x00; + + src_data++; + } + } + } + image = [[NSImage alloc] init]; + [image addRepresentation:bitmap_rep]; + [bitmap_rep release]; + + nscursor = [[NSCursor alloc] initWithImage:image hotSpot:NSMakePoint(x, y)]; + [image release]; + + cursor = gdk_quartz_cursor_new_from_nscursor (nscursor, GDK_CURSOR_IS_PIXMAP); + + GDK_QUARTZ_RELEASE_POOL; + + return cursor; +} + +static NSImage * +_gdk_quartz_pixbuf_to_ns_image (GdkPixbuf *pixbuf) +{ + NSBitmapImageRep *bitmap_rep; + NSImage *image; + gboolean has_alpha; + + has_alpha = gdk_pixbuf_get_has_alpha (pixbuf); + + /* Create a bitmap image rep */ + bitmap_rep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL + pixelsWide:gdk_pixbuf_get_width (pixbuf) + pixelsHigh:gdk_pixbuf_get_height (pixbuf) + bitsPerSample:8 samplesPerPixel:has_alpha ? 4 : 3 + hasAlpha:has_alpha isPlanar:NO colorSpaceName:NSDeviceRGBColorSpace + bytesPerRow:0 bitsPerPixel:0]; + + { + /* Add pixel data to bitmap rep */ + guchar *src, *dst; + int src_stride, dst_stride; + int x, y; + + src_stride = gdk_pixbuf_get_rowstride (pixbuf); + dst_stride = [bitmap_rep bytesPerRow]; + + for (y = 0; y < gdk_pixbuf_get_height (pixbuf); y++) + { + src = gdk_pixbuf_get_pixels (pixbuf) + y * src_stride; + dst = [bitmap_rep bitmapData] + y * dst_stride; + + for (x = 0; x < gdk_pixbuf_get_width (pixbuf); x++) + { + if (has_alpha) + { + guchar red, green, blue, alpha; + + red = *src++; + green = *src++; + blue = *src++; + alpha = *src++; + + *dst++ = (red * alpha) / 255; + *dst++ = (green * alpha) / 255; + *dst++ = (blue * alpha) / 255; + *dst++ = alpha; + } + else + { + *dst++ = *src++; + *dst++ = *src++; + *dst++ = *src++; + } + } + } + } + + image = [[NSImage alloc] init]; + [image addRepresentation:bitmap_rep]; + [bitmap_rep release]; + [image autorelease]; + + return image; +} + +GdkCursor * +gdk_cursor_new_from_pixbuf (GdkDisplay *display, + GdkPixbuf *pixbuf, + gint x, + gint y) +{ + NSImage *image; + NSCursor *nscursor; + GdkCursor *cursor; + gboolean has_alpha; + + g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL); + g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), NULL); + g_return_val_if_fail (0 <= x && x < gdk_pixbuf_get_width (pixbuf), NULL); + g_return_val_if_fail (0 <= y && y < gdk_pixbuf_get_height (pixbuf), NULL); + + GDK_QUARTZ_ALLOC_POOL; + + has_alpha = gdk_pixbuf_get_has_alpha (pixbuf); + + image = _gdk_quartz_pixbuf_to_ns_image (pixbuf); + nscursor = [[NSCursor alloc] initWithImage:image hotSpot:NSMakePoint(x, y)]; + + cursor = gdk_quartz_cursor_new_from_nscursor (nscursor, GDK_CURSOR_IS_PIXMAP); + + GDK_QUARTZ_RELEASE_POOL; + + return cursor; +} + +GdkCursor* +gdk_cursor_new_from_name (GdkDisplay *display, + const gchar *name) +{ + /* FIXME: Implement */ + return NULL; +} + +void +_gdk_cursor_destroy (GdkCursor *cursor) +{ + GdkCursorPrivate *private; + + g_return_if_fail (cursor != NULL); + g_return_if_fail (cursor->ref_count == 0); + + private = (GdkCursorPrivate *)cursor; + [private->nscursor release]; + + g_free (private); +} + +gboolean +gdk_display_supports_cursor_alpha (GdkDisplay *display) +{ + g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE); + + return TRUE; +} + +gboolean +gdk_display_supports_cursor_color (GdkDisplay *display) +{ + g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE); + + return TRUE; +} + +guint +gdk_display_get_default_cursor_size (GdkDisplay *display) +{ + g_return_val_if_fail (GDK_IS_DISPLAY (display), 0); + + /* Mac OS X doesn't have the notion of a default size */ + return 32; +} + +void +gdk_display_get_maximal_cursor_size (GdkDisplay *display, + guint *width, + guint *height) +{ + g_return_if_fail (GDK_IS_DISPLAY (display)); + + /* Cursor sizes in Mac OS X can be arbitrarily large */ + *width = 65536; + *height = 65536; +} + +GdkDisplay * +gdk_cursor_get_display (GdkCursor *cursor) +{ + g_return_val_if_fail (cursor != NULL, NULL); + + return gdk_display_get_default (); +} + +GdkPixbuf * +gdk_cursor_get_image (GdkCursor *cursor) +{ + /* FIXME: Implement */ + return NULL; +} + +NSImage * +gdk_quartz_pixbuf_to_ns_image_libgtk_only (GdkPixbuf *pixbuf) +{ + return _gdk_quartz_pixbuf_to_ns_image (pixbuf); +} diff --git a/libs/tk/ydk/quartz/gdkdisplay-quartz.c b/libs/tk/ydk/quartz/gdkdisplay-quartz.c new file mode 100644 index 0000000000..6884d008ca --- /dev/null +++ b/libs/tk/ydk/quartz/gdkdisplay-quartz.c @@ -0,0 +1,182 @@ +/* gdkdisplay-quartz.c + * + * Copyright (C) 2005 Imendio AB + * + * 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. + */ + +#include "config.h" + +#include "gdk.h" +#include "gdkprivate-quartz.h" +#include "gdkscreen-quartz.h" + +GdkWindow * +gdk_display_get_default_group (GdkDisplay *display) +{ + g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL); + + /* FIXME: Implement */ + + return NULL; +} + +void +_gdk_windowing_set_default_display (GdkDisplay *display) +{ + g_assert (display == NULL || _gdk_display == display); +} + +GdkDisplay * +gdk_display_open (const gchar *display_name) +{ + if (_gdk_display != NULL) + return NULL; + + /* Initialize application */ + [NSApplication sharedApplication]; + + _gdk_display = g_object_new (GDK_TYPE_DISPLAY, NULL); + + _gdk_visual_init (); + + _gdk_screen = _gdk_screen_quartz_new (); + + _gdk_windowing_window_init (); + + _gdk_events_init (); + _gdk_input_init (); + +#if 0 + /* FIXME: Remove the #if 0 when we have these functions */ + _gdk_dnd_init (); +#endif + + g_signal_emit_by_name (gdk_display_manager_get (), + "display_opened", _gdk_display); + + return _gdk_display; +} + +const gchar * +gdk_display_get_name (GdkDisplay *display) +{ + static gchar *display_name = NULL; + + if (!display_name) + { + GDK_QUARTZ_ALLOC_POOL; + display_name = g_strdup ([[[NSHost currentHost] name] UTF8String]); + GDK_QUARTZ_RELEASE_POOL; + } + + return display_name; +} + +int +gdk_display_get_n_screens (GdkDisplay *display) +{ + g_return_val_if_fail (GDK_IS_DISPLAY (display), 0); + + return 1; +} + +GdkScreen * +gdk_display_get_screen (GdkDisplay *display, + gint screen_num) +{ + g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL); + g_return_val_if_fail (screen_num == 0, NULL); + + return _gdk_screen; +} + +GdkScreen * +gdk_display_get_default_screen (GdkDisplay *display) +{ + return _gdk_screen; +} + +void +gdk_display_beep (GdkDisplay *display) +{ + g_return_if_fail (GDK_IS_DISPLAY (display)); + + NSBeep(); +} + +gboolean +gdk_display_supports_selection_notification (GdkDisplay *display) +{ + g_return_val_if_fail (GDK_IS_DISPLAY (display), FALSE); + + /* FIXME: Implement */ + return FALSE; +} + +gboolean +gdk_display_request_selection_notification (GdkDisplay *display, + GdkAtom selection) + +{ + /* FIXME: Implement */ + return FALSE; +} + +gboolean +gdk_display_supports_clipboard_persistence (GdkDisplay *display) +{ + /* FIXME: Implement */ + return FALSE; +} + +gboolean +gdk_display_supports_shapes (GdkDisplay *display) +{ + /* FIXME: Implement */ + return FALSE; +} + +gboolean +gdk_display_supports_input_shapes (GdkDisplay *display) +{ + /* FIXME: Implement */ + return FALSE; +} + +void +gdk_display_store_clipboard (GdkDisplay *display, + GdkWindow *clipboard_window, + guint32 time_, + const GdkAtom *targets, + gint n_targets) +{ + /* FIXME: Implement */ +} + + +gboolean +gdk_display_supports_composite (GdkDisplay *display) +{ + /* FIXME: Implement */ + return FALSE; +} + +gulong +_gdk_windowing_window_get_next_serial (GdkDisplay *display) +{ + return 0; +} diff --git a/libs/tk/ydk/quartz/gdkdnd-quartz.c b/libs/tk/ydk/quartz/gdkdnd-quartz.c new file mode 100644 index 0000000000..ec89ad2149 --- /dev/null +++ b/libs/tk/ydk/quartz/gdkdnd-quartz.c @@ -0,0 +1,224 @@ +/* gdkdnd-quartz.c + * + * Copyright (C) 2005 Imendio AB + * + * 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. + */ + +#include "gdkdnd.h" +#include "gdkprivate-quartz.h" + +static gpointer parent_class = NULL; + +static void +gdk_drag_context_finalize (GObject *object) +{ + GdkDragContext *context = GDK_DRAG_CONTEXT (object); + GdkDragContextPrivate *private = GDK_DRAG_CONTEXT_PRIVATE (context); + + g_free (private); + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +gdk_drag_context_init (GdkDragContext *dragcontext) +{ + GdkDragContextPrivate *priv = g_new0 (GdkDragContextPrivate, 1); + + dragcontext->windowing_data = priv; +} + +static void +gdk_drag_context_class_init (GdkDragContextClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + parent_class = g_type_class_peek_parent (klass); + + object_class->finalize = gdk_drag_context_finalize; +} + +GType +gdk_drag_context_get_type (void) +{ + static GType object_type = 0; + + if (!object_type) + { + const GTypeInfo object_info = + { + sizeof (GdkDragContextClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) gdk_drag_context_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (GdkDragContext), + 0, /* n_preallocs */ + (GInstanceInitFunc) gdk_drag_context_init, + }; + + object_type = g_type_register_static (G_TYPE_OBJECT, + "GdkDragContext", + &object_info, + 0); + } + + return object_type; +} + +GdkDragContext * +gdk_drag_context_new (void) +{ + return (GdkDragContext *)g_object_new (gdk_drag_context_get_type (), NULL); +} + +void +gdk_drag_context_ref (GdkDragContext *context) +{ + g_object_ref (context); +} + +void +gdk_drag_context_unref (GdkDragContext *context) +{ + g_object_unref (context); +} + +GdkDragContext *_gdk_quartz_drag_source_context = NULL; + +GdkDragContext * +gdk_quartz_drag_source_context () +{ + return _gdk_quartz_drag_source_context; +} + +GdkDragContext * +gdk_drag_begin (GdkWindow *window, + GList *targets) +{ + g_assert (_gdk_quartz_drag_source_context == NULL); + + /* Create fake context */ + _gdk_quartz_drag_source_context = gdk_drag_context_new (); + _gdk_quartz_drag_source_context->is_source = TRUE; + + return _gdk_quartz_drag_source_context; +} + +gboolean +gdk_drag_motion (GdkDragContext *context, + GdkWindow *dest_window, + GdkDragProtocol protocol, + gint x_root, + gint y_root, + GdkDragAction suggested_action, + GdkDragAction possible_actions, + guint32 time) +{ + /* FIXME: Implement */ + return FALSE; +} + +GdkNativeWindow +gdk_drag_get_protocol_for_display (GdkDisplay *display, + GdkNativeWindow xid, + GdkDragProtocol *protocol) +{ + /* FIXME: Implement */ + return 0; +} + +void +gdk_drag_find_window_for_screen (GdkDragContext *context, + GdkWindow *drag_window, + GdkScreen *screen, + gint x_root, + gint y_root, + GdkWindow **dest_window, + GdkDragProtocol *protocol) +{ + /* FIXME: Implement */ +} + +void +gdk_drag_drop (GdkDragContext *context, + guint32 time) +{ + /* FIXME: Implement */ +} + +void +gdk_drag_abort (GdkDragContext *context, + guint32 time) +{ + g_return_if_fail (context != NULL); + + /* FIXME: Implement */ +} + +void +gdk_drag_status (GdkDragContext *context, + GdkDragAction action, + guint32 time) +{ + context->action = action; +} + +void +gdk_drop_reply (GdkDragContext *context, + gboolean ok, + guint32 time) +{ + g_return_if_fail (context != NULL); + + /* FIXME: Implement */ +} + +void +gdk_drop_finish (GdkDragContext *context, + gboolean success, + guint32 time) +{ + /* FIXME: Implement */ +} + +void +gdk_window_register_dnd (GdkWindow *window) +{ + /* FIXME: Implement */ +} + +GdkAtom +gdk_drag_get_selection (GdkDragContext *context) +{ + /* FIXME: Implement */ + return GDK_NONE; +} + +gboolean +gdk_drag_drop_succeeded (GdkDragContext *context) +{ + /* FIXME: Implement */ + return FALSE; +} + +id +gdk_quartz_drag_context_get_dragging_info_libgtk_only (GdkDragContext *context) +{ + return GDK_DRAG_CONTEXT_PRIVATE (context)->dragging_info; +} diff --git a/libs/tk/ydk/quartz/gdkdrawable-quartz.c b/libs/tk/ydk/quartz/gdkdrawable-quartz.c new file mode 100644 index 0000000000..bbc53379de --- /dev/null +++ b/libs/tk/ydk/quartz/gdkdrawable-quartz.c @@ -0,0 +1,874 @@ +/* gdkdrawable-quartz.c + * + * Copyright (C) 2005-2007 Imendio AB + * + * 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. + */ + +#include "config.h" +#include +#include +#include "gdkprivate-quartz.h" + +static gpointer parent_class; + +static cairo_user_data_key_t gdk_quartz_cairo_key; + +typedef struct { + GdkDrawable *drawable; + CGContextRef cg_context; +} GdkQuartzCairoSurfaceData; + +void +_gdk_windowing_set_cairo_surface_size (cairo_surface_t *surface, + int width, + int height) +{ + /* This is not supported with quartz surfaces. */ +} + +static void +gdk_quartz_cairo_surface_destroy (void *data) +{ + GdkQuartzCairoSurfaceData *surface_data = data; + GdkDrawableImplQuartz *impl = GDK_DRAWABLE_IMPL_QUARTZ (surface_data->drawable); + + impl->cairo_surface = NULL; + + gdk_quartz_drawable_release_context (surface_data->drawable, + surface_data->cg_context); + + g_free (surface_data); +} + +cairo_surface_t * +_gdk_windowing_create_cairo_surface (GdkDrawable *drawable, + int width, + int height) +{ + CGContextRef cg_context; + GdkQuartzCairoSurfaceData *surface_data; + cairo_surface_t *surface; + + cg_context = gdk_quartz_drawable_get_context (drawable, TRUE); + + surface_data = g_new (GdkQuartzCairoSurfaceData, 1); + surface_data->drawable = drawable; + surface_data->cg_context = cg_context; + + if (cg_context) + surface = cairo_quartz_surface_create_for_cg_context (cg_context, + width, height); + else + surface = cairo_quartz_surface_create(CAIRO_FORMAT_ARGB32, width, height); + + cairo_surface_set_user_data (surface, &gdk_quartz_cairo_key, + surface_data, + gdk_quartz_cairo_surface_destroy); + + return surface; +} + +static cairo_surface_t * +gdk_quartz_ref_cairo_surface (GdkDrawable *drawable) +{ + GdkDrawableImplQuartz *impl = GDK_DRAWABLE_IMPL_QUARTZ (drawable); + + if (GDK_IS_WINDOW_IMPL_QUARTZ (drawable) && + GDK_WINDOW_DESTROYED (impl->wrapper)) + return NULL; + + if (!impl->cairo_surface) + { + int width, height; + + gdk_drawable_get_size (drawable, &width, &height); + impl->cairo_surface = _gdk_windowing_create_cairo_surface (drawable, + width, height); + } + else + cairo_surface_reference (impl->cairo_surface); + + return impl->cairo_surface; +} + +static void +gdk_quartz_set_colormap (GdkDrawable *drawable, + GdkColormap *colormap) +{ + GdkDrawableImplQuartz *impl = GDK_DRAWABLE_IMPL_QUARTZ (drawable); + + if (impl->colormap == colormap) + return; + + if (impl->colormap) + g_object_unref (impl->colormap); + impl->colormap = colormap; + if (impl->colormap) + g_object_ref (impl->colormap); +} + +static GdkColormap* +gdk_quartz_get_colormap (GdkDrawable *drawable) +{ + return GDK_DRAWABLE_IMPL_QUARTZ (drawable)->colormap; +} + +static GdkScreen* +gdk_quartz_get_screen (GdkDrawable *drawable) +{ + return _gdk_screen; +} + +static GdkVisual* +gdk_quartz_get_visual (GdkDrawable *drawable) +{ + return gdk_drawable_get_visual (GDK_DRAWABLE_IMPL_QUARTZ (drawable)->wrapper); +} + +static int +gdk_quartz_get_depth (GdkDrawable *drawable) +{ + /* This is a bit bogus but I'm not sure the other way is better */ + + return gdk_drawable_get_depth (GDK_DRAWABLE_IMPL_QUARTZ (drawable)->wrapper); +} + +static void +gdk_quartz_draw_rectangle (GdkDrawable *drawable, + GdkGC *gc, + gboolean filled, + gint x, + gint y, + gint width, + gint height) +{ + CGContextRef context = gdk_quartz_drawable_get_context (drawable, FALSE); + + if (!context) + return; + + if(!_gdk_quartz_gc_update_cg_context (gc, + drawable, + context, + filled ? + GDK_QUARTZ_CONTEXT_FILL : + GDK_QUARTZ_CONTEXT_STROKE)) + { + gdk_quartz_drawable_release_context (drawable, context); + return; + } + if (filled) + { + CGRect rect = CGRectMake (x, y, width, height); + + CGContextFillRect (context, rect); + } + else + { + CGRect rect = CGRectMake (x + 0.5, y + 0.5, width, height); + + CGContextStrokeRect (context, rect); + } + + gdk_quartz_drawable_release_context (drawable, context); +} + +static void +gdk_quartz_draw_arc (GdkDrawable *drawable, + GdkGC *gc, + gboolean filled, + gint x, + gint y, + gint width, + gint height, + gint angle1, + gint angle2) +{ + CGContextRef context = gdk_quartz_drawable_get_context (drawable, FALSE); + float start_angle, end_angle; + gboolean clockwise = FALSE; + + if (!context) + return; + + if (!_gdk_quartz_gc_update_cg_context (gc, drawable, context, + filled ? + GDK_QUARTZ_CONTEXT_FILL : + GDK_QUARTZ_CONTEXT_STROKE)) + { + gdk_quartz_drawable_release_context (drawable, context); + return; + } + start_angle = angle1 * 2.0 * G_PI / 360.0 / 64.0; + end_angle = start_angle + angle2 * 2.0 * G_PI / 360.0 / 64.0; + + /* angle2 is relative to angle1 and can be negative, which switches + * the drawing direction + */ + if (angle2 < 0) + clockwise = TRUE; + + /* below, flip the coordinate system back to its original y-diretion + * so the angles passed to CGContextAddArc() are interpreted as + * expected + * + * FIXME: the implementation below works only for perfect circles + * (width == height). Any other aspect ratio either scales the + * line width unevenly or scales away the path entirely for very + * small line widths (esp. for line_width == 0, which is a hair + * line on X11 but must be approximated with the thinnest possible + * line on quartz). + */ + + if (filled) + { + CGContextTranslateCTM (context, + x + width / 2.0, + y + height / 2.0); + CGContextScaleCTM (context, 1.0, - (double)height / (double)width); + + CGContextMoveToPoint (context, 0, 0); + CGContextAddArc (context, 0, 0, width / 2.0, + start_angle, end_angle, + clockwise); + CGContextClosePath (context); + CGContextFillPath (context); + } + else + { + CGContextTranslateCTM (context, + x + width / 2.0 + 0.5, + y + height / 2.0 + 0.5); + CGContextScaleCTM (context, 1.0, - (double)height / (double)width); + + CGContextAddArc (context, 0, 0, width / 2.0, + start_angle, end_angle, + clockwise); + CGContextStrokePath (context); + } + + gdk_quartz_drawable_release_context (drawable, context); +} + +static void +gdk_quartz_draw_polygon (GdkDrawable *drawable, + GdkGC *gc, + gboolean filled, + GdkPoint *points, + gint npoints) +{ + CGContextRef context = gdk_quartz_drawable_get_context (drawable, FALSE); + int i; + + if (!context) + return; + + if (!_gdk_quartz_gc_update_cg_context (gc, drawable, context, + filled ? + GDK_QUARTZ_CONTEXT_FILL : + GDK_QUARTZ_CONTEXT_STROKE)) + { + gdk_quartz_drawable_release_context (drawable, context); + return; + } + if (filled) + { + CGContextMoveToPoint (context, points[0].x, points[0].y); + for (i = 1; i < npoints; i++) + CGContextAddLineToPoint (context, points[i].x, points[i].y); + + CGContextClosePath (context); + CGContextFillPath (context); + } + else + { + CGContextMoveToPoint (context, points[0].x + 0.5, points[0].y + 0.5); + for (i = 1; i < npoints; i++) + CGContextAddLineToPoint (context, points[i].x + 0.5, points[i].y + 0.5); + + CGContextClosePath (context); + CGContextStrokePath (context); + } + + gdk_quartz_drawable_release_context (drawable, context); +} + +static void +gdk_quartz_draw_text (GdkDrawable *drawable, + GdkFont *font, + GdkGC *gc, + gint x, + gint y, + const gchar *text, + gint text_length) +{ + /* FIXME: Implement */ +} + +static void +gdk_quartz_draw_text_wc (GdkDrawable *drawable, + GdkFont *font, + GdkGC *gc, + gint x, + gint y, + const GdkWChar *text, + gint text_length) +{ + /* FIXME: Implement */ +} + +static void +gdk_quartz_draw_drawable (GdkDrawable *drawable, + GdkGC *gc, + GdkPixmap *src, + gint xsrc, + gint ysrc, + gint xdest, + gint ydest, + gint width, + gint height, + GdkDrawable *original_src) +{ + int src_depth = gdk_drawable_get_depth (src); + int dest_depth = gdk_drawable_get_depth (drawable); + GdkDrawableImplQuartz *src_impl; + + if (GDK_IS_WINDOW_IMPL_QUARTZ (src)) + { + GdkWindowImplQuartz *window_impl; + + window_impl = GDK_WINDOW_IMPL_QUARTZ (src); + + /* We do support moving areas on the same drawable, if it can be done + * by using a scroll. FIXME: We need to check that the params support + * this hack, and make sure it's done properly with any offsets etc? + */ + if (drawable == (GdkDrawable *)window_impl) + { + NSRect rect = NSMakeRect (xsrc, ysrc, width, height); + NSSize offset = NSMakeSize (xdest - xsrc, ydest - ysrc); + GdkRectangle tmp_rect; + GdkRegion *orig_region, *offset_region, *need_display_region; + GdkWindow *window = GDK_DRAWABLE_IMPL_QUARTZ (drawable)->wrapper; + + /* Origin region */ + tmp_rect.x = xsrc; + tmp_rect.y = ysrc; + tmp_rect.width = width; + tmp_rect.height = height; + orig_region = gdk_region_rectangle (&tmp_rect); + + /* Destination region (or the offset region) */ + offset_region = gdk_region_copy (orig_region); + gdk_region_offset (offset_region, offset.width, offset.height); + + need_display_region = gdk_region_copy (orig_region); + + if (window_impl->in_paint_rect_count == 0) + { + GdkRegion *bottom_border_region; + + /* If we are not in drawRect:, we can use scrollRect:. + * We apply scrollRect on the rectangle to be moved and + * subtract this area from the rectangle that needs display. + * + * Note: any area in this moved region that already needed + * display will be handled by GDK (queue translation). + * + * Queuing the redraw below is important, otherwise the + * results from scrollRect will not take effect! + */ + [window_impl->view scrollRect:rect by:offset]; + + gdk_region_subtract (need_display_region, offset_region); + + /* Here we take special care with the bottom window border, + * which extents 4 pixels and typically draws rounded corners. + */ + tmp_rect.x = 0; + tmp_rect.y = gdk_window_get_height (window) - 4; + tmp_rect.width = gdk_window_get_width (window); + tmp_rect.height = 4; + + if (gdk_region_rect_in (offset_region, &tmp_rect) != + GDK_OVERLAP_RECTANGLE_OUT) + { + /* We are copying pixels to the bottom border, we need + * to submit this area for redisplay to get the rounded + * corners drawn. + */ + gdk_region_union_with_rect (need_display_region, + &tmp_rect); + } + + /* Compute whether the bottom border is moved elsewhere. + * Because this part will have rounded corners, we have + * to fill the contents of where the rounded corners used + * to be. We post this area for redisplay. + */ + bottom_border_region = gdk_region_rectangle (&tmp_rect); + gdk_region_intersect (bottom_border_region, + orig_region); + + gdk_region_offset (bottom_border_region, + offset.width, offset.height); + + gdk_region_union (need_display_region, bottom_border_region); + + gdk_region_destroy (bottom_border_region); + } + else + { + /* If we cannot handle things with a scroll, we must redisplay + * the union of the source area and the destination area. + */ + gdk_region_union (need_display_region, offset_region); + } + + _gdk_quartz_window_set_needs_display_in_region (window, + need_display_region); + + gdk_region_destroy (orig_region); + gdk_region_destroy (offset_region); + gdk_region_destroy (need_display_region); + } + else + g_warning ("Drawing with window source != dest is not supported"); + + return; + } + else if (GDK_IS_DRAWABLE_IMPL_QUARTZ (src)) + src_impl = GDK_DRAWABLE_IMPL_QUARTZ (src); + else if (GDK_IS_PIXMAP (src)) + src_impl = GDK_DRAWABLE_IMPL_QUARTZ (GDK_PIXMAP_OBJECT (src)->impl); + else + { + g_warning ("Unsupported source %s", G_OBJECT_TYPE_NAME (src)); + return; + } + + /* Handle drawable and pixmap sources. */ + if (src_depth == 1) + { + /* FIXME: src depth 1 is not supported yet */ + g_warning ("Source with depth 1 unsupported"); + } + else if (dest_depth != 0 && src_depth == dest_depth) + { + GdkPixmapImplQuartz *pixmap_impl = GDK_PIXMAP_IMPL_QUARTZ (src_impl); + CGContextRef context = gdk_quartz_drawable_get_context (drawable, FALSE); + CGImageRef image; + + if (!context) + return; + + if (!_gdk_quartz_gc_update_cg_context (gc, drawable, context, + GDK_QUARTZ_CONTEXT_STROKE)) + { + gdk_quartz_drawable_release_context (drawable, context); + return; + } + CGContextClipToRect (context, CGRectMake (xdest, ydest, width, height)); + CGContextTranslateCTM (context, xdest - xsrc, ydest - ysrc + + pixmap_impl->height); + CGContextScaleCTM (context, 1.0, -1.0); + + image = _gdk_pixmap_get_cgimage (src); + CGContextDrawImage (context, + CGRectMake (0, 0, pixmap_impl->width, pixmap_impl->height), + image); + CGImageRelease (image); + + gdk_quartz_drawable_release_context (drawable, context); + } + else + g_warning ("Attempt to draw a drawable with depth %d to a drawable with depth %d", + src_depth, dest_depth); +} + +static void +gdk_quartz_draw_points (GdkDrawable *drawable, + GdkGC *gc, + GdkPoint *points, + gint npoints) +{ + CGContextRef context = gdk_quartz_drawable_get_context (drawable, FALSE); + int i; + + if (!context) + return; + + if (!_gdk_quartz_gc_update_cg_context (gc, drawable, context, + GDK_QUARTZ_CONTEXT_STROKE | + GDK_QUARTZ_CONTEXT_FILL)) + { + gdk_quartz_drawable_release_context (drawable, context); + return; + } + /* Just draw 1x1 rectangles */ + for (i = 0; i < npoints; i++) + { + CGRect rect = CGRectMake (points[i].x, points[i].y, 1, 1); + CGContextFillRect (context, rect); + } + + gdk_quartz_drawable_release_context (drawable, context); +} + +static inline void +gdk_quartz_fix_cap_not_last_line (GdkGCQuartz *private, + gint x1, + gint y1, + gint x2, + gint y2, + gint *xfix, + gint *yfix) +{ + *xfix = 0; + *yfix = 0; + + if (private->cap_style == GDK_CAP_NOT_LAST && private->line_width == 0) + { + /* fix only vertical and horizontal lines for now */ + + if (y1 == y2 && x1 != x2) + { + *xfix = (x1 < x2) ? -1 : 1; + } + else if (x1 == x2 && y1 != y2) + { + *yfix = (y1 < y2) ? -1 : 1; + } + } +} + +static void +gdk_quartz_draw_segments (GdkDrawable *drawable, + GdkGC *gc, + GdkSegment *segs, + gint nsegs) +{ + CGContextRef context = gdk_quartz_drawable_get_context (drawable, FALSE); + GdkGCQuartz *private; + int i; + + if (!context) + return; + + private = GDK_GC_QUARTZ (gc); + + if (!_gdk_quartz_gc_update_cg_context (gc, drawable, context, + GDK_QUARTZ_CONTEXT_STROKE)) + { + gdk_quartz_drawable_release_context (drawable, context); + return; + } + for (i = 0; i < nsegs; i++) + { + gint xfix, yfix; + + gdk_quartz_fix_cap_not_last_line (private, + segs[i].x1, segs[i].y1, + segs[i].x2, segs[i].y2, + &xfix, &yfix); + + CGContextMoveToPoint (context, segs[i].x1 + 0.5, segs[i].y1 + 0.5); + CGContextAddLineToPoint (context, segs[i].x2 + 0.5 + xfix, segs[i].y2 + 0.5 + yfix); + } + + CGContextStrokePath (context); + + gdk_quartz_drawable_release_context (drawable, context); +} + +static void +gdk_quartz_draw_lines (GdkDrawable *drawable, + GdkGC *gc, + GdkPoint *points, + gint npoints) +{ + CGContextRef context = gdk_quartz_drawable_get_context (drawable, FALSE); + GdkGCQuartz *private; + gint xfix, yfix; + gint i; + + if (!context) + return; + + private = GDK_GC_QUARTZ (gc); + + if (!_gdk_quartz_gc_update_cg_context (gc, drawable, context, + GDK_QUARTZ_CONTEXT_STROKE)) + { + gdk_quartz_drawable_release_context (drawable, context); + return; + } + CGContextMoveToPoint (context, points[0].x + 0.5, points[0].y + 0.5); + + for (i = 1; i < npoints - 1; i++) + CGContextAddLineToPoint (context, points[i].x + 0.5, points[i].y + 0.5); + + gdk_quartz_fix_cap_not_last_line (private, + points[npoints - 2].x, points[npoints - 2].y, + points[npoints - 1].x, points[npoints - 1].y, + &xfix, &yfix); + + CGContextAddLineToPoint (context, + points[npoints - 1].x + 0.5 + xfix, + points[npoints - 1].y + 0.5 + yfix); + + CGContextStrokePath (context); + + gdk_quartz_drawable_release_context (drawable, context); +} + +static void +gdk_quartz_draw_pixbuf (GdkDrawable *drawable, + GdkGC *gc, + GdkPixbuf *pixbuf, + gint src_x, + gint src_y, + gint dest_x, + gint dest_y, + gint width, + gint height, + GdkRgbDither dither, + gint x_dither, + gint y_dither) +{ + CGContextRef context = gdk_quartz_drawable_get_context (drawable, FALSE); + CGColorSpaceRef colorspace; + CGDataProviderRef data_provider; + CGImageRef image; + void *data; + int rowstride, pixbuf_width, pixbuf_height; + gboolean has_alpha; + + if (!context) + return; + + pixbuf_width = gdk_pixbuf_get_width (pixbuf); + pixbuf_height = gdk_pixbuf_get_height (pixbuf); + rowstride = gdk_pixbuf_get_rowstride (pixbuf); + has_alpha = gdk_pixbuf_get_has_alpha (pixbuf); + + data = gdk_pixbuf_get_pixels (pixbuf); + + colorspace = CGColorSpaceCreateDeviceRGB (); + data_provider = CGDataProviderCreateWithData (NULL, data, pixbuf_height * rowstride, NULL); + + image = CGImageCreate (pixbuf_width, pixbuf_height, 8, + has_alpha ? 32 : 24, rowstride, + colorspace, + has_alpha ? kCGImageAlphaLast : 0, + data_provider, NULL, FALSE, + kCGRenderingIntentDefault); + + CGDataProviderRelease (data_provider); + CGColorSpaceRelease (colorspace); + + if (!_gdk_quartz_gc_update_cg_context (gc, drawable, context, + GDK_QUARTZ_CONTEXT_STROKE)) + { + gdk_quartz_drawable_release_context (drawable, context); + return; + } + CGContextClipToRect (context, CGRectMake (dest_x, dest_y, width, height)); + CGContextTranslateCTM (context, dest_x - src_x, dest_y - src_y + pixbuf_height); + CGContextScaleCTM (context, 1, -1); + + CGContextDrawImage (context, CGRectMake (0, 0, pixbuf_width, pixbuf_height), image); + CGImageRelease (image); + + gdk_quartz_drawable_release_context (drawable, context); +} + +static void +gdk_quartz_draw_image (GdkDrawable *drawable, + GdkGC *gc, + GdkImage *image, + gint xsrc, + gint ysrc, + gint xdest, + gint ydest, + gint width, + gint height) +{ + CGContextRef context = gdk_quartz_drawable_get_context (drawable, FALSE); + CGColorSpaceRef colorspace; + CGDataProviderRef data_provider; + CGImageRef cgimage; + + if (!context) + return; + + colorspace = CGColorSpaceCreateDeviceRGB (); + data_provider = CGDataProviderCreateWithData (NULL, image->mem, image->height * image->bpl, NULL); + + /* FIXME: Make sure that this function draws 32-bit images correctly, + * also check endianness wrt kCGImageAlphaNoneSkipFirst */ + cgimage = CGImageCreate (image->width, image->height, 8, + 32, image->bpl, + colorspace, + kCGImageAlphaNoneSkipFirst, + data_provider, NULL, FALSE, kCGRenderingIntentDefault); + + CGDataProviderRelease (data_provider); + CGColorSpaceRelease (colorspace); + + if (!_gdk_quartz_gc_update_cg_context (gc, drawable, context, + GDK_QUARTZ_CONTEXT_STROKE)) + { + gdk_quartz_drawable_release_context (drawable, context); + return; + } + + CGContextClipToRect (context, CGRectMake (xdest, ydest, width, height)); + CGContextTranslateCTM (context, xdest - xsrc, ydest - ysrc + image->height); + CGContextScaleCTM (context, 1, -1); + + CGContextDrawImage (context, CGRectMake (0, 0, image->width, image->height), cgimage); + CGImageRelease (cgimage); + + gdk_quartz_drawable_release_context (drawable, context); +} + +static void +gdk_drawable_impl_quartz_finalize (GObject *object) +{ + GdkDrawableImplQuartz *impl = GDK_DRAWABLE_IMPL_QUARTZ (object); + + if (impl->colormap) + g_object_unref (impl->colormap); + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +gdk_drawable_impl_quartz_class_init (GdkDrawableImplQuartzClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass); + + parent_class = g_type_class_peek_parent (klass); + + object_class->finalize = gdk_drawable_impl_quartz_finalize; + + drawable_class->create_gc = _gdk_quartz_gc_new; + drawable_class->draw_rectangle = gdk_quartz_draw_rectangle; + drawable_class->draw_arc = gdk_quartz_draw_arc; + drawable_class->draw_polygon = gdk_quartz_draw_polygon; + drawable_class->draw_text = gdk_quartz_draw_text; + drawable_class->draw_text_wc = gdk_quartz_draw_text_wc; + drawable_class->draw_drawable_with_src = gdk_quartz_draw_drawable; + drawable_class->draw_points = gdk_quartz_draw_points; + drawable_class->draw_segments = gdk_quartz_draw_segments; + drawable_class->draw_lines = gdk_quartz_draw_lines; + drawable_class->draw_image = gdk_quartz_draw_image; + drawable_class->draw_pixbuf = gdk_quartz_draw_pixbuf; + + drawable_class->ref_cairo_surface = gdk_quartz_ref_cairo_surface; + + drawable_class->set_colormap = gdk_quartz_set_colormap; + drawable_class->get_colormap = gdk_quartz_get_colormap; + + drawable_class->get_depth = gdk_quartz_get_depth; + drawable_class->get_screen = gdk_quartz_get_screen; + drawable_class->get_visual = gdk_quartz_get_visual; + + drawable_class->_copy_to_image = _gdk_quartz_image_copy_to_image; +} + +GType +gdk_drawable_impl_quartz_get_type (void) +{ + static GType object_type = 0; + + if (!object_type) + { + const GTypeInfo object_info = + { + sizeof (GdkDrawableImplQuartzClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) gdk_drawable_impl_quartz_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (GdkDrawableImplQuartz), + 0, /* n_preallocs */ + (GInstanceInitFunc) NULL, + }; + + object_type = g_type_register_static (GDK_TYPE_DRAWABLE, + "GdkDrawableImplQuartz", + &object_info, 0); + } + + return object_type; +} + +CGContextRef +gdk_quartz_drawable_get_context (GdkDrawable *drawable, + gboolean antialias) +{ + if (!GDK_DRAWABLE_IMPL_QUARTZ_GET_CLASS (drawable)->get_context) + { + g_warning ("%s doesn't implement GdkDrawableImplQuartzClass::get_context()", + G_OBJECT_TYPE_NAME (drawable)); + return NULL; + } + + return GDK_DRAWABLE_IMPL_QUARTZ_GET_CLASS (drawable)->get_context (drawable, antialias); +} + +void +gdk_quartz_drawable_release_context (GdkDrawable *drawable, + CGContextRef cg_context) +{ + if (!cg_context) + return; + + if (GDK_IS_WINDOW_IMPL_QUARTZ (drawable)) + { + GdkWindowImplQuartz *window_impl = GDK_WINDOW_IMPL_QUARTZ (drawable); + + CGContextRestoreGState (cg_context); + CGContextSetAllowsAntialiasing (cg_context, TRUE); + + /* See comment in gdk_quartz_drawable_get_context(). */ + if (window_impl->in_paint_rect_count == 0) + { + [window_impl->view unlockFocus]; + } + } + else if (GDK_IS_PIXMAP_IMPL_QUARTZ (drawable)) + CGContextRelease (cg_context); +} + +void +_gdk_quartz_drawable_finish (GdkDrawable *drawable) +{ + GdkDrawableImplQuartz *impl = GDK_DRAWABLE_IMPL_QUARTZ (drawable); + + if (impl->cairo_surface) + { + cairo_surface_finish (impl->cairo_surface); + cairo_surface_set_user_data (impl->cairo_surface, &gdk_quartz_cairo_key, + NULL, NULL); + impl->cairo_surface = NULL; + } +} diff --git a/libs/tk/ydk/quartz/gdkeventloop-quartz.c b/libs/tk/ydk/quartz/gdkeventloop-quartz.c new file mode 100644 index 0000000000..39c1f90335 --- /dev/null +++ b/libs/tk/ydk/quartz/gdkeventloop-quartz.c @@ -0,0 +1,1049 @@ +#include "config.h" + +#include +#include +#include +#include +#include + +#include "gdkprivate-quartz.h" + +/* + * This file implementations integration between the GLib main loop and + * the native system of the Core Foundation run loop and Cocoa event + * handling. There are basically two different cases that we need to + * handle: either the GLib main loop is in control (the application + * has called gtk_main(), or is otherwise iterating the main loop), or + * CFRunLoop is in control (we are in a modal operation such as window + * resizing or drag-and-drop.) + * + * When the GLib main loop is in control we integrate in native event + * handling in two ways: first we add a GSource that handles checking + * whether there are native events available, translating native events + * to GDK events, and dispatching GDK events. Second we replace the + * "poll function" of the GLib main loop with our own version that knows + * how to wait for both the file descriptors and timeouts that GLib is + * interested in and also for incoming native events. + * + * When CFRunLoop is in control, we integrate in GLib main loop handling + * by adding a "run loop observer" that gives us notification at various + * points in the run loop cycle. We map these points onto the corresponding + * stages of the GLib main loop (prepare, check, dispatch), and make the + * appropriate calls into GLib. + * + * Both cases share a single problem: the OS X API's don't allow us to + * wait simultaneously for file descriptors and for events. So when we + * need to do a blocking wait that includes file descriptor activity, we + * push the actual work of calling select() to a helper thread (the + * "select thread") and wait for native events in the main thread. + * + * The main known limitation of this code is that if a callback is triggered + * via the OS X run loop while we are "polling" (in either case described + * above), iteration of the GLib main loop is not possible from within + * that callback. If the programmer tries to do so explicitly, then they + * will get a warning from GLib "main loop already active in another thread". + */ + +/******* State for run loop iteration *******/ + +/* Count of number of times we've gotten an "Entry" notification for + * our run loop observer. + */ +static int current_loop_level = 0; + +/* Run loop level at which we acquired ownership of the GLib main + * loop. See note in run_loop_entry(). -1 means that we don't have + * ownership + */ +static int acquired_loop_level = -1; + +/* Between run_loop_before_waiting() and run_loop_after_waiting(); + * whether we we need to call select_thread_collect_poll() + */ +static gboolean run_loop_polling_async = FALSE; + +/* Between run_loop_before_waiting() and run_loop_after_waiting(); + * max_prioritiy to pass to g_main_loop_check() + */ +static gint run_loop_max_priority; + +/* Timer that we've added to wake up the run loop when a GLib timeout + */ +static CFRunLoopTimerRef run_loop_timer = NULL; + +/* These are the file descriptors that are we are polling out of + * the run loop. (We keep the array around and reuse it to avoid + * constant allocations.) + */ +#define RUN_LOOP_POLLFDS_INITIAL_SIZE 16 +static GPollFD *run_loop_pollfds; +static guint run_loop_pollfds_size; /* Allocated size of the array */ +static guint run_loop_n_pollfds; /* Number of file descriptors in the array */ + +/******* Other global variables *******/ + +/* Since we count on replacing the GLib main loop poll function as our + * method of integrating Cocoa event handling into the GLib main loop + * we need to make sure that the poll function is always called even + * when there are no file descriptors that need to be polled. To do + * this, we add a dummy GPollFD to our event source with a file + * descriptor of '-1'. Then any time that GLib is polling the event + * source, it will call our poll function. + */ +static GPollFD event_poll_fd; + +/* Current NSEvents that we've gotten from Cocoa but haven't yet converted + * to GdkEvents. We wait until our dispatch() function to do the conversion + * since the conversion can conceivably cause signals to be emmitted + * or other things that shouldn't happen inside a poll function. + */ +static GQueue *current_events; + +/* The default poll function for GLib; we replace this with our own + * Cocoa-aware version and then call the old version to do actual + * file descriptor polling. There's no actual need to chain to the + * old one; we could reimplement the same functionality from scratch, + * but since the default implementation does the right thing, why + * bother. + */ +static GPollFunc old_poll_func; + +/* Reference to the run loop of the main thread. (There is a unique + * CFRunLoop per thread.) + */ +static CFRunLoopRef main_thread_run_loop; + +/* Normally the Cocoa main loop maintains an NSAutoReleasePool and frees + * it on every iteration. Since we are replacing the main loop we have + * to provide this functionality ourself. We free and replace the + * auto-release pool in our sources prepare() function. + */ +static NSAutoreleasePool *autorelease_pool; + +/* Flag when we've called nextEventMatchingMask ourself; this triggers + * a run loop iteration, so we need to detect that and avoid triggering + * our "run the GLib main looop while the run loop is active machinery. + */ +static gint getting_events = 0; + +/************************************************************ + ********* Select Thread ********* + ************************************************************/ + +/* The states in our state machine, see comments in select_thread_func() + * for descriptiions of each state + */ +typedef enum { + BEFORE_START, + WAITING, + POLLING_QUEUED, + POLLING_RESTART, + POLLING_DESCRIPTORS, +} SelectThreadState; + +#ifdef G_ENABLE_DEBUG +static const char *const state_names[] = { + "BEFORE_START", + "WAITING", + "POLLING_QUEUED", + "POLLING_RESTART", + "POLLING_DESCRIPTORS" +}; +#endif + +static SelectThreadState select_thread_state = BEFORE_START; + +static pthread_t select_thread; +static pthread_mutex_t select_thread_mutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t select_thread_cond = PTHREAD_COND_INITIALIZER; + +#define SELECT_THREAD_LOCK() pthread_mutex_lock (&select_thread_mutex) +#define SELECT_THREAD_UNLOCK() pthread_mutex_unlock (&select_thread_mutex) +#define SELECT_THREAD_SIGNAL() pthread_cond_signal (&select_thread_cond) +#define SELECT_THREAD_WAIT() pthread_cond_wait (&select_thread_cond, &select_thread_mutex) + +/* These are the file descriptors that the select thread is currently + * polling. + */ +static GPollFD *current_pollfds; +static guint current_n_pollfds; + +/* These are the file descriptors that the select thread should pick + * up and start polling when it has a chance. + */ +static GPollFD *next_pollfds; +static guint next_n_pollfds; + +/* Pipe used to wake up the select thread */ +static gint select_thread_wakeup_pipe[2]; + +/* Run loop source used to wake up the main thread */ +static CFRunLoopSourceRef select_main_thread_source; + +static void +select_thread_set_state (SelectThreadState new_state) +{ + gboolean old_state; + + if (select_thread_state == new_state) + return; + + GDK_NOTE (EVENTLOOP, g_print ("EventLoop: Select thread state: %s => %s\n", state_names[select_thread_state], state_names[new_state])); + + old_state = select_thread_state; + select_thread_state = new_state; + if (old_state == WAITING && new_state != WAITING) + SELECT_THREAD_SIGNAL (); +} + +static void +signal_main_thread (void) +{ + GDK_NOTE (EVENTLOOP, g_print ("EventLoop: Waking up main thread\n")); + + /* If we are in nextEventMatchingMask, then we need to make sure an + * event gets queued, otherwise it's enough to simply wake up the + * main thread run loop + */ + if (!run_loop_polling_async) + CFRunLoopSourceSignal (select_main_thread_source); + + /* Don't check for CFRunLoopIsWaiting() here because it causes a + * race condition (the loop could go into waiting state right after + * we checked). + */ + CFRunLoopWakeUp (main_thread_run_loop); +} + +static void * +select_thread_func (void *arg) +{ + char c; + + SELECT_THREAD_LOCK (); + + while (TRUE) + { + switch (select_thread_state) + { + case BEFORE_START: + /* The select thread has not been started yet + */ + g_assert_not_reached (); + + case WAITING: + /* Waiting for a set of file descriptors to be submitted by the main thread + * + * => POLLING_QUEUED: main thread thread submits a set of file descriptors + */ + SELECT_THREAD_WAIT (); + break; + + case POLLING_QUEUED: + /* Waiting for a set of file descriptors to be submitted by the main thread + * + * => POLLING_DESCRIPTORS: select thread picks up the file descriptors to begin polling + */ + if (current_pollfds) + g_free (current_pollfds); + + current_pollfds = next_pollfds; + current_n_pollfds = next_n_pollfds; + + next_pollfds = NULL; + next_n_pollfds = 0; + + select_thread_set_state (POLLING_DESCRIPTORS); + break; + + case POLLING_RESTART: + /* Select thread is currently polling a set of file descriptors, main thread has + * began a new iteration with the same set of file descriptors. We don't want to + * wake the select thread up and wait for it to restart immediately, but to avoid + * a race (described below in select_thread_start_polling()) we need to recheck after + * polling completes. + * + * => POLLING_DESCRIPTORS: select completes, main thread rechecks by polling again + * => POLLING_QUEUED: main thread submits a new set of file descriptors to be polled + */ + select_thread_set_state (POLLING_DESCRIPTORS); + break; + + case POLLING_DESCRIPTORS: + /* In the process of polling the file descriptors + * + * => WAITING: polling completes when a file descriptor becomes active + * => POLLING_QUEUED: main thread submits a new set of file descriptors to be polled + * => POLLING_RESTART: main thread begins a new iteration with the same set file descriptors + */ + SELECT_THREAD_UNLOCK (); + old_poll_func (current_pollfds, current_n_pollfds, -1); + SELECT_THREAD_LOCK (); + + read (select_thread_wakeup_pipe[0], &c, 1); + + if (select_thread_state == POLLING_DESCRIPTORS) + { + signal_main_thread (); + select_thread_set_state (WAITING); + } + break; + } + } +} + +static void +got_fd_activity (void *info) +{ + NSEvent *event; + + /* Post a message so we'll break out of the message loop */ + event = [NSEvent otherEventWithType: NSApplicationDefined + location: NSZeroPoint + modifierFlags: 0 + timestamp: 0 + windowNumber: 0 + context: nil + subtype: GDK_QUARTZ_EVENT_SUBTYPE_EVENTLOOP + data1: 0 + data2: 0]; + + [NSApp postEvent:event atStart:YES]; +} + +static void +select_thread_start (void) +{ + g_return_if_fail (select_thread_state == BEFORE_START); + + pipe (select_thread_wakeup_pipe); + fcntl (select_thread_wakeup_pipe[0], F_SETFL, O_NONBLOCK); + + CFRunLoopSourceContext source_context = {0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, got_fd_activity }; + select_main_thread_source = CFRunLoopSourceCreate (NULL, 0, &source_context); + + CFRunLoopAddSource (main_thread_run_loop, select_main_thread_source, kCFRunLoopCommonModes); + + select_thread_state = WAITING; + + while (TRUE) + { + if (pthread_create (&select_thread, NULL, select_thread_func, NULL) == 0) + break; + + g_warning ("Failed to create select thread, sleeping and trying again"); + sleep (1); + } +} + +#ifdef G_ENABLE_DEBUG +static void +dump_poll_result (GPollFD *ufds, + guint nfds) +{ + gint i; + + for (i = 0; i < nfds; i++) + { + if (ufds[i].fd >= 0 && ufds[i].revents) + { + g_print (" %d:", ufds[i].fd); + if (ufds[i].revents & G_IO_IN) + g_print (" in"); + if (ufds[i].revents & G_IO_OUT) + g_print (" out"); + if (ufds[i].revents & G_IO_PRI) + g_print (" pri"); + g_print ("\n"); + } + } +} +#endif + +gboolean +pollfds_equal (GPollFD *old_pollfds, + guint old_n_pollfds, + GPollFD *new_pollfds, + guint new_n_pollfds) +{ + gint i; + + if (old_n_pollfds != new_n_pollfds) + return FALSE; + + for (i = 0; i < old_n_pollfds; i++) + { + if (old_pollfds[i].fd != new_pollfds[i].fd || + old_pollfds[i].events != new_pollfds[i].events) + return FALSE; + } + + return TRUE; +} + +/* Begins a polling operation with the specified GPollFD array; the + * timeout is used only to tell if the polling operation is blocking + * or non-blocking. + * + * Return value: + * -1: No file descriptors ready, began asynchronous poll + * 0: No file descriptors ready, asynchronous poll not needed + * > 0: Number of file descriptors ready + */ +static gint +select_thread_start_poll (GPollFD *ufds, + guint nfds, gint timeout) +{ + gint n_ready; + gboolean have_new_pollfds = FALSE; + gint poll_fd_index = -1; + gint i; + + for (i = 0; i < nfds; i++) + if (ufds[i].fd == -1) + { + poll_fd_index = i; + break; + } + + if (nfds == 0 || + (nfds == 1 && poll_fd_index >= 0)) + { + GDK_NOTE (EVENTLOOP, g_print ("EventLoop: Nothing to poll\n")); + return 0; + } + + /* If we went immediately to an async poll, then we might decide to + * dispatch idle functions when higher priority file descriptor sources + * are ready to be dispatched. So we always need to first check + * check synchronously with a timeout of zero, and only when no + * sources are immediately ready, go to the asynchronous poll. + * + * Of course, if the timeout passed in is 0, then the synchronous + * check is sufficient and we never need to do the asynchronous poll. + */ + n_ready = old_poll_func (ufds, nfds, 0); + if (n_ready > 0 || timeout == 0) + { +#ifdef G_ENABLE_DEBUG + if ((_gdk_debug_flags & GDK_DEBUG_EVENTLOOP) && n_ready > 0) + { + g_print ("EventLoop: Found ready file descriptors before waiting\n"); + dump_poll_result (ufds, nfds); + } +#endif + + return n_ready; + } + + SELECT_THREAD_LOCK (); + + if (select_thread_state == BEFORE_START) + { + select_thread_start (); + } + + if (select_thread_state == POLLING_QUEUED) + { + /* If the select thread hasn't picked up the set of file descriptors yet + * then we can simply replace an old stale set with a new set. + */ + if (!pollfds_equal (ufds, nfds, next_pollfds, next_n_pollfds - 1)) + { + g_free (next_pollfds); + next_pollfds = NULL; + next_n_pollfds = 0; + + have_new_pollfds = TRUE; + } + } + else if (select_thread_state == POLLING_RESTART || select_thread_state == POLLING_DESCRIPTORS) + { + /* If we are already in the process of polling the right set of file descriptors, + * there's no need for us to immediately force the select thread to stop polling + * and then restart again. And avoiding doing so increases the efficiency considerably + * in the common case where we have a set of basically inactive file descriptors that + * stay unchanged present as we process many events. + * + * However, we have to be careful that we don't hit the following race condition + * Select Thread Main Thread + * ----------------- --------------- + * Polling Completes + * Reads data or otherwise changes file descriptor state + * Checks if polling is current + * Does nothing (*) + * Releases lock + * Acquires lock + * Marks polling as complete + * Wakes main thread + * Receives old stale file descriptor state + * + * To avoid this, when the new set of poll descriptors is the same as the current + * one, we transition to the POLLING_RESTART stage at the point marked (*). When + * the select thread wakes up from the poll because a file descriptor is active, if + * the state is POLLING_RESTART it immediately begins polling same the file descriptor + * set again. This normally will just return the same set of active file descriptors + * as the first time, but in sequence described above will properly update the + * file descriptor state. + * + * Special case: this RESTART logic is not needed if the only FD is the internal GLib + * "wakeup pipe" that is presented when threads are initialized. + * + * P.S.: The harm in the above sequence is mostly that sources can be signalled + * as ready when they are no longer ready. This may prompt a blocking read + * from a file descriptor that hangs. + */ + if (!pollfds_equal (ufds, nfds, current_pollfds, current_n_pollfds - 1)) + have_new_pollfds = TRUE; + else + { + if (!((nfds == 1 && poll_fd_index < 0 && g_thread_supported ()) || + (nfds == 2 && poll_fd_index >= 0 && g_thread_supported ()))) + select_thread_set_state (POLLING_RESTART); + } + } + else + have_new_pollfds = TRUE; + + if (have_new_pollfds) + { + GDK_NOTE (EVENTLOOP, g_print ("EventLoop: Submitting a new set of file descriptor to the select thread\n")); + + g_assert (next_pollfds == NULL); + + next_n_pollfds = nfds + 1; + next_pollfds = g_new (GPollFD, nfds + 1); + memcpy (next_pollfds, ufds, nfds * sizeof (GPollFD)); + + next_pollfds[nfds].fd = select_thread_wakeup_pipe[0]; + next_pollfds[nfds].events = G_IO_IN; + + if (select_thread_state != POLLING_QUEUED && select_thread_state != WAITING) + { + if (select_thread_wakeup_pipe[1]) + { + char c = 'A'; + write (select_thread_wakeup_pipe[1], &c, 1); + } + } + + select_thread_set_state (POLLING_QUEUED); + } + + SELECT_THREAD_UNLOCK (); + + return -1; +} + +/* End an asynchronous polling operation started with + * select_thread_collect_poll(). This must be called if and only if + * select_thread_start_poll() return -1. The GPollFD array passed + * in must be identical to the one passed to select_thread_start_poll(). + * + * The results of the poll are written into the GPollFD array passed in. + * + * Return Value: number of file descriptors ready + */ +static int +select_thread_collect_poll (GPollFD *ufds, guint nfds) +{ + gint i; + gint n_ready = 0; + + SELECT_THREAD_LOCK (); + + if (select_thread_state == WAITING) /* The poll completed */ + { + for (i = 0; i < nfds; i++) + { + if (ufds[i].fd == -1) + continue; + + g_assert (ufds[i].fd == current_pollfds[i].fd); + g_assert (ufds[i].events == current_pollfds[i].events); + + if (current_pollfds[i].revents) + { + ufds[i].revents = current_pollfds[i].revents; + n_ready++; + } + } + +#ifdef G_ENABLE_DEBUG + if (_gdk_debug_flags & GDK_DEBUG_EVENTLOOP) + { + g_print ("EventLoop: Found ready file descriptors after waiting\n"); + dump_poll_result (ufds, nfds); + } +#endif + } + + SELECT_THREAD_UNLOCK (); + + return n_ready; +} + +/************************************************************ + ********* Main Loop Source ********* + ************************************************************/ + +gboolean +_gdk_quartz_event_loop_check_pending (void) +{ + return current_events && current_events->head; +} + +NSEvent* +_gdk_quartz_event_loop_get_pending (void) +{ + NSEvent *event = NULL; + + if (current_events) + event = g_queue_pop_tail (current_events); + + return event; +} + +void +_gdk_quartz_event_loop_release_event (NSEvent *event) +{ + [event release]; +} + +static gboolean +gdk_event_prepare (GSource *source, + gint *timeout) +{ + gboolean retval; + + GDK_THREADS_ENTER (); + + /* The prepare stage is the stage before the main loop starts polling + * and dispatching events. The autorelease poll is drained here for + * the preceding main loop iteration or, in case of the first iteration, + * for the operations carried out between event loop initialization and + * this first iteration. + * + * The autorelease poll must only be drained when the following conditions + * apply: + * - We are at the base CFRunLoop level (indicated by current_loop_level), + * - We are at the base g_main_loop level (indicated by + * g_main_depth()) + * - We are at the base poll_func level (indicated by getting events). + * + * Messing with the autorelease pool at any level of nesting can cause access + * to deallocated memory because autorelease_pool is static and releasing a + * pool will cause all pools allocated inside of it to be released as well. + */ + if (current_loop_level == 0 && g_main_depth() == 0 && getting_events == 0) + { + if (autorelease_pool) + [autorelease_pool drain]; + + autorelease_pool = [[NSAutoreleasePool alloc] init]; + } + + *timeout = -1; + + retval = (_gdk_event_queue_find_first (_gdk_display) != NULL || + _gdk_quartz_event_loop_check_pending ()); + + GDK_THREADS_LEAVE (); + + return retval; +} + +static gboolean +gdk_event_check (GSource *source) +{ + gboolean retval; + + GDK_THREADS_ENTER (); + + retval = (_gdk_event_queue_find_first (_gdk_display) != NULL || + _gdk_quartz_event_loop_check_pending ()); + + GDK_THREADS_LEAVE (); + + return retval; +} + +static gboolean +gdk_event_dispatch (GSource *source, + GSourceFunc callback, + gpointer user_data) +{ + GdkEvent *event; + + GDK_THREADS_ENTER (); + + _gdk_events_queue (_gdk_display); + + event = _gdk_event_unqueue (_gdk_display); + + if (event) + { + if (_gdk_event_func) + (*_gdk_event_func) (event, _gdk_event_data); + + gdk_event_free (event); + } + + GDK_THREADS_LEAVE (); + + return TRUE; +} + +static GSourceFuncs event_funcs = { + gdk_event_prepare, + gdk_event_check, + gdk_event_dispatch, + NULL +}; + +/************************************************************ + ********* Our Poll Function ********* + ************************************************************/ + +static gint +poll_func (GPollFD *ufds, + guint nfds, + gint timeout_) +{ + NSEvent *event; + NSDate *limit_date; + gint n_ready; + + static GPollFD *last_ufds; + + last_ufds = ufds; + + n_ready = select_thread_start_poll (ufds, nfds, timeout_); + if (n_ready > 0) + timeout_ = 0; + + if (timeout_ == -1) + limit_date = [NSDate distantFuture]; + else if (timeout_ == 0) + limit_date = [NSDate distantPast]; + else + limit_date = [NSDate dateWithTimeIntervalSinceNow:timeout_/1000.0]; + + getting_events++; + event = [NSApp nextEventMatchingMask: NSAnyEventMask + untilDate: limit_date + inMode: NSDefaultRunLoopMode + dequeue: YES]; + getting_events--; + + /* We check if last_ufds did not change since the time this function was + * called. It is possible that a recursive main loop (and thus recursive + * invocation of this poll function) is triggered while in + * nextEventMatchingMask:. If during that time new fds are added, + * the cached fds array might be replaced in g_main_context_iterate(). + * So, we should avoid accessing the old fd array (still pointed at by + * ufds) here in that case, since it might have been freed. We avoid this + * by not calling the collect stage. + */ + if (last_ufds == ufds && n_ready < 0) + n_ready = select_thread_collect_poll (ufds, nfds); + + if (event && + [event type] == NSApplicationDefined && + [event subtype] == GDK_QUARTZ_EVENT_SUBTYPE_EVENTLOOP) + { + /* Just used to wake us up; if an event and a FD arrived at the same + * time; could have come from a previous iteration in some cases, + * but the spurious wake up is harmless if a little inefficient. + */ + event = NULL; + } + + if (event) + { + if (!current_events) + current_events = g_queue_new (); + g_queue_push_head (current_events, [event retain]); + } + + return n_ready; +} + +/************************************************************ + ********* Running the main loop out of CFRunLoop ********* + ************************************************************/ + +/* Wrapper around g_main_context_query() that handles reallocating + * run_loop_pollfds up to the proper size + */ +static gint +query_main_context (GMainContext *context, + int max_priority, + int *timeout) +{ + gint nfds; + + if (!run_loop_pollfds) + { + run_loop_pollfds_size = RUN_LOOP_POLLFDS_INITIAL_SIZE; + run_loop_pollfds = g_new (GPollFD, run_loop_pollfds_size); + } + + while ((nfds = g_main_context_query (context, max_priority, timeout, + run_loop_pollfds, + run_loop_pollfds_size)) > run_loop_pollfds_size) + { + g_free (run_loop_pollfds); + run_loop_pollfds_size = nfds; + run_loop_pollfds = g_new (GPollFD, nfds); + } + + return nfds; +} + +static void +run_loop_entry (void) +{ + if (acquired_loop_level == -1) + { + if (g_main_context_acquire (NULL)) + { + GDK_NOTE (EVENTLOOP, g_print ("EventLoop: Beginning tracking run loop activity\n")); + acquired_loop_level = current_loop_level; + } + else + { + /* If we fail to acquire the main context, that means someone is iterating + * the main context in a different thread; we simply wait until this loop + * exits and then try again at next entry. In general, iterating the loop + * from a different thread is rare: it is only possible when GDK threading + * is initialized and is not frequently used even then. So, we hope that + * having GLib main loop iteration blocked in the combination of that and + * a native modal operation is a minimal problem. We could imagine using a + * thread that does g_main_context_wait() and then wakes us back up, but + * the gain doesn't seem worth the complexity. + */ + GDK_NOTE (EVENTLOOP, g_print ("EventLoop: Can't acquire main loop; skipping tracking run loop activity\n")); + } + } +} + +static void +run_loop_before_timers (void) +{ +} + +static void +run_loop_before_sources (void) +{ + GMainContext *context = g_main_context_default (); + gint max_priority; + gint nfds; + + /* Before we let the CFRunLoop process sources, we want to check if there + * are any pending GLib main loop sources more urgent than + * G_PRIORITY_DEFAULT that need to be dispatched. (We consider all activity + * from the CFRunLoop to have a priority of G_PRIORITY_DEFAULT.) If no + * sources are processed by the CFRunLoop, then processing will continue + * on to the BeforeWaiting stage where we check for lower priority sources. + */ + + g_main_context_prepare (context, &max_priority); + max_priority = MIN (max_priority, G_PRIORITY_DEFAULT); + + /* We ignore the timeout that query_main_context () returns since we'll + * always query again before waiting. + */ + nfds = query_main_context (context, max_priority, NULL); + + if (nfds) + old_poll_func (run_loop_pollfds, nfds, 0); + + if (g_main_context_check (context, max_priority, run_loop_pollfds, nfds)) + { + GDK_NOTE (EVENTLOOP, g_print ("EventLoop: Dispatching high priority sources\n")); + g_main_context_dispatch (context); + } +} + +static void +dummy_timer_callback (CFRunLoopTimerRef timer, + void *info) +{ + /* Nothing; won't normally even be called */ +} + +static void +run_loop_before_waiting (void) +{ + GMainContext *context = g_main_context_default (); + gint timeout; + gint n_ready; + + /* At this point, the CFRunLoop is ready to wait. We start a GMain loop + * iteration by calling the check() and query() stages. We start a + * poll, and if it doesn't complete immediately we let the run loop + * go ahead and sleep. Before doing that, if there was a timeout from + * GLib, we set up a CFRunLoopTimer to wake us up. + */ + + g_main_context_prepare (context, &run_loop_max_priority); + + run_loop_n_pollfds = query_main_context (context, run_loop_max_priority, &timeout); + + n_ready = select_thread_start_poll (run_loop_pollfds, run_loop_n_pollfds, timeout); + + if (n_ready > 0 || timeout == 0) + { + /* We have stuff to do, no sleeping allowed! */ + CFRunLoopWakeUp (main_thread_run_loop); + } + else if (timeout > 0) + { + /* We need to get the run loop to break out of it's wait when our timeout + * expires. We do this by adding a dummy timer that we'll remove immediately + * after the wait wakes up. + */ + GDK_NOTE (EVENTLOOP, g_print ("EventLoop: Adding timer to wake us up in %d milliseconds\n", timeout)); + + run_loop_timer = CFRunLoopTimerCreate (NULL, /* allocator */ + CFAbsoluteTimeGetCurrent () + timeout / 1000., + 0, /* interval (0=does not repeat) */ + 0, /* flags */ + 0, /* order (priority) */ + dummy_timer_callback, + NULL); + + CFRunLoopAddTimer (main_thread_run_loop, run_loop_timer, kCFRunLoopCommonModes); + } + + run_loop_polling_async = n_ready < 0; +} + +static void +run_loop_after_waiting (void) +{ + GMainContext *context = g_main_context_default (); + + /* After sleeping, we finish of the GMain loop iteratin started in before_waiting() + * by doing the check() and dispatch() stages. + */ + + if (run_loop_timer) + { + CFRunLoopRemoveTimer (main_thread_run_loop, run_loop_timer, kCFRunLoopCommonModes); + CFRelease (run_loop_timer); + run_loop_timer = NULL; + } + + if (run_loop_polling_async) + { + select_thread_collect_poll (run_loop_pollfds, run_loop_n_pollfds); + run_loop_polling_async = FALSE; + } + + if (g_main_context_check (context, run_loop_max_priority, run_loop_pollfds, run_loop_n_pollfds)) + { + GDK_NOTE (EVENTLOOP, g_print ("EventLoop: Dispatching after waiting\n")); + g_main_context_dispatch (context); + } +} + +static void +run_loop_exit (void) +{ + /* + 1 because we decrement current_loop_level separately in observer_callback() */ + if ((current_loop_level + 1) == acquired_loop_level) + { + g_main_context_release (NULL); + acquired_loop_level = -1; + GDK_NOTE (EVENTLOOP, g_print ("EventLoop: Ended tracking run loop activity\n")); + } +} + +static void +run_loop_observer_callback (CFRunLoopObserverRef observer, + CFRunLoopActivity activity, + void *info) +{ + switch (activity) + { + case kCFRunLoopEntry: + current_loop_level++; + break; + case kCFRunLoopExit: + g_return_if_fail (current_loop_level > 0); + current_loop_level--; + break; + default: + break; + } + + if (getting_events > 0) /* Activity we triggered */ + return; + + switch (activity) + { + case kCFRunLoopEntry: + run_loop_entry (); + break; + case kCFRunLoopBeforeTimers: + run_loop_before_timers (); + break; + case kCFRunLoopBeforeSources: + run_loop_before_sources (); + break; + case kCFRunLoopBeforeWaiting: + run_loop_before_waiting (); + break; + case kCFRunLoopAfterWaiting: + run_loop_after_waiting (); + break; + case kCFRunLoopExit: + run_loop_exit (); + break; + default: + break; + } +} + +/************************************************************/ + +void +_gdk_quartz_event_loop_init (void) +{ + GSource *source; + CFRunLoopObserverRef observer; + + /* Hook into the GLib main loop */ + + event_poll_fd.events = G_IO_IN; + event_poll_fd.fd = -1; + + source = g_source_new (&event_funcs, sizeof (GSource)); + g_source_set_name (source, "GDK Quartz event source"); + g_source_add_poll (source, &event_poll_fd); + g_source_set_priority (source, GDK_PRIORITY_EVENTS); + g_source_set_can_recurse (source, TRUE); + g_source_attach (source, NULL); + + old_poll_func = g_main_context_get_poll_func (NULL); + g_main_context_set_poll_func (NULL, poll_func); + + /* Hook into the the CFRunLoop for the main thread */ + + main_thread_run_loop = CFRunLoopGetCurrent (); + + observer = CFRunLoopObserverCreate (NULL, /* default allocator */ + kCFRunLoopAllActivities, + true, /* repeats: not one-shot */ + 0, /* order (priority) */ + run_loop_observer_callback, + NULL); + + CFRunLoopAddObserver (main_thread_run_loop, observer, kCFRunLoopCommonModes); + + /* Initialize our autorelease pool */ + + autorelease_pool = [[NSAutoreleasePool alloc] init]; +} diff --git a/libs/tk/ydk/quartz/gdkevents-quartz.c b/libs/tk/ydk/quartz/gdkevents-quartz.c new file mode 100644 index 0000000000..f879987efe --- /dev/null +++ b/libs/tk/ydk/quartz/gdkevents-quartz.c @@ -0,0 +1,1893 @@ +/* gdkevents-quartz.c + * + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * Copyright (C) 1998-2002 Tor Lillqvist + * Copyright (C) 2005-2008 Imendio AB + * + * 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. + */ + +#include "config.h" +#include +#include +#include +#include + +#import +#include + +#include "gdkscreen.h" +#include "gdkkeysyms.h" +#include "gdkprivate-quartz.h" +#include "gdkinputprivate.h" + +#define GRIP_WIDTH 15 +#define GRIP_HEIGHT 15 +#define GDK_LION_RESIZE 5 + +#define WINDOW_IS_TOPLEVEL(window) \ + (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD && \ + GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN && \ + GDK_WINDOW_TYPE (window) != GDK_WINDOW_OFFSCREEN) + +/* This is the NSView not owned by GDK where a mouse down event occurs */ +static NSView *foreign_mouse_down_view; + +/* This is the window corresponding to the key window */ +static GdkWindow *current_keyboard_window; + +/* This is the event mask from the last event */ +static GdkEventMask current_event_mask; + +static void append_event (GdkEvent *event, + gboolean windowing); + +static GdkWindow *find_toplevel_under_pointer (GdkDisplay *display, + NSPoint screen_point, + gint *x, + gint *y); + + +NSEvent * +gdk_quartz_event_get_nsevent (GdkEvent *event) +{ + /* FIXME: If the event here is unallocated, we crash. */ + return ((GdkEventPrivate *) event)->windowing_data; +} + +static void +gdk_quartz_ns_notification_callback (CFNotificationCenterRef center, + void *observer, + CFStringRef name, + const void *object, + CFDictionaryRef userInfo) +{ + GdkEvent new_event; + + new_event.type = GDK_SETTING; + new_event.setting.window = gdk_screen_get_root_window (_gdk_screen); + new_event.setting.send_event = FALSE; + new_event.setting.action = GDK_SETTING_ACTION_CHANGED; + new_event.setting.name = NULL; + + /* Translate name */ + if (CFStringCompare (name, + CFSTR("AppleNoRedisplayAppearancePreferenceChanged"), + 0) == kCFCompareEqualTo) + new_event.setting.name = "gtk-primary-button-warps-slider"; + + if (!new_event.setting.name) + return; + + gdk_event_put (&new_event); +} + +static void +gdk_quartz_events_init_notifications (void) +{ + static gboolean notifications_initialized = FALSE; + + if (notifications_initialized) + return; + notifications_initialized = TRUE; + + /* Initialize any handlers for notifications we want to push to GTK + * through GdkEventSettings. + */ + + /* This is an undocumented *distributed* notification to listen for changes + * in scrollbar jump behavior. It is used by LibreOffice and WebKit as well. + */ + CFNotificationCenterAddObserver (CFNotificationCenterGetDistributedCenter (), + NULL, + &gdk_quartz_ns_notification_callback, + CFSTR ("AppleNoRedisplayAppearancePreferenceChanged"), + NULL, + CFNotificationSuspensionBehaviorDeliverImmediately); +} + +void +_gdk_events_init (void) +{ + _gdk_quartz_event_loop_init (); + gdk_quartz_events_init_notifications (); + + current_keyboard_window = g_object_ref (_gdk_root); +} + +gboolean +gdk_events_pending (void) +{ + return (_gdk_event_queue_find_first (_gdk_display) || + (_gdk_quartz_event_loop_check_pending ())); +} + +GdkEvent* +gdk_event_get_graphics_expose (GdkWindow *window) +{ + /* FIXME: Implement */ + return NULL; +} + +GdkGrabStatus +gdk_keyboard_grab (GdkWindow *window, + gint owner_events, + guint32 time) +{ + GdkDisplay *display; + GdkWindow *toplevel; + + g_return_val_if_fail (window != NULL, 0); + g_return_val_if_fail (GDK_IS_WINDOW (window), 0); + + display = gdk_drawable_get_display (window); + toplevel = gdk_window_get_effective_toplevel (window); + + _gdk_display_set_has_keyboard_grab (display, + window, + toplevel, + owner_events, + 0, + time); + + return GDK_GRAB_SUCCESS; +} + +void +gdk_display_keyboard_ungrab (GdkDisplay *display, + guint32 time) +{ + _gdk_display_unset_has_keyboard_grab (display, FALSE); +} + +void +gdk_display_pointer_ungrab (GdkDisplay *display, + guint32 time) +{ + GdkPointerGrabInfo *grab; + + grab = _gdk_display_get_last_pointer_grab (display); + if (grab) + grab->serial_end = 0; + + _gdk_display_pointer_grab_update (display, 0); +} + +GdkGrabStatus +_gdk_windowing_pointer_grab (GdkWindow *window, + GdkWindow *native, + gboolean owner_events, + GdkEventMask event_mask, + GdkWindow *confine_to, + GdkCursor *cursor, + guint32 time) +{ + g_return_val_if_fail (GDK_IS_WINDOW (window), 0); + g_return_val_if_fail (confine_to == NULL || GDK_IS_WINDOW (confine_to), 0); + + _gdk_display_add_pointer_grab (_gdk_display, + window, + native, + owner_events, + event_mask, + 0, + time, + FALSE); + + return GDK_GRAB_SUCCESS; +} + +void +_gdk_quartz_events_break_all_grabs (guint32 time) +{ + GdkPointerGrabInfo *grab; + + if (_gdk_display->keyboard_grab.window) + _gdk_display_unset_has_keyboard_grab (_gdk_display, FALSE); + + grab = _gdk_display_get_last_pointer_grab (_gdk_display); + if (grab) + { + grab->serial_end = 0; + grab->implicit_ungrab = TRUE; + } + + _gdk_display_pointer_grab_update (_gdk_display, 0); +} + +static void +fixup_event (GdkEvent *event) +{ + if (event->any.window) + g_object_ref (event->any.window); + if (((event->any.type == GDK_ENTER_NOTIFY) || + (event->any.type == GDK_LEAVE_NOTIFY)) && + (event->crossing.subwindow != NULL)) + g_object_ref (event->crossing.subwindow); + event->any.send_event = FALSE; +} + +static void +append_event (GdkEvent *event, + gboolean windowing) +{ + GList *node; + + fixup_event (event); + node = _gdk_event_queue_append (_gdk_display, event); + + if (windowing) + _gdk_windowing_got_event (_gdk_display, node, event, 0); +} + +static gint +gdk_event_apply_filters (NSEvent *nsevent, + GdkEvent *event, + GList **filters) +{ + GList *tmp_list; + GdkFilterReturn result; + + tmp_list = *filters; + + while (tmp_list) + { + GdkEventFilter *filter = (GdkEventFilter*) tmp_list->data; + GList *node; + + if ((filter->flags & GDK_EVENT_FILTER_REMOVED) != 0) + { + tmp_list = tmp_list->next; + continue; + } + + filter->ref_count++; + result = filter->function (nsevent, event, filter->data); + + /* get the next node after running the function since the + function may add or remove a next node */ + node = tmp_list; + tmp_list = tmp_list->next; + + filter->ref_count--; + if (filter->ref_count == 0) + { + *filters = g_list_remove_link (*filters, node); + g_list_free_1 (node); + g_free (filter); + } + + if (result != GDK_FILTER_CONTINUE) + return result; + } + + return GDK_FILTER_CONTINUE; +} + +static guint32 +get_time_from_ns_event (NSEvent *event) +{ + double time = [event timestamp]; + + /* cast via double->uint64 conversion to make sure that it is + * wrapped on 32-bit machines when it overflows + */ + return (guint32) (guint64) (time * 1000.0); +} + +static int +get_mouse_button_from_ns_event (NSEvent *event) +{ + NSInteger button; + + button = [event buttonNumber]; + + switch (button) + { + case 0: + return 1; + case 1: + return 3; + case 2: + return 2; + default: + return button + 1; + } +} + +static GdkModifierType +get_mouse_button_modifiers_from_ns_buttons (NSUInteger nsbuttons) +{ + GdkModifierType modifiers = 0; + + if (nsbuttons & (1 << 0)) + modifiers |= GDK_BUTTON1_MASK; + if (nsbuttons & (1 << 1)) + modifiers |= GDK_BUTTON3_MASK; + if (nsbuttons & (1 << 2)) + modifiers |= GDK_BUTTON2_MASK; + if (nsbuttons & (1 << 3)) + modifiers |= GDK_BUTTON4_MASK; + if (nsbuttons & (1 << 4)) + modifiers |= GDK_BUTTON5_MASK; + + return modifiers; +} + +static GdkModifierType +get_mouse_button_modifiers_from_ns_event (NSEvent *event) +{ + int button; + GdkModifierType state = 0; + + /* This maps buttons 1 to 5 to GDK_BUTTON[1-5]_MASK */ + button = get_mouse_button_from_ns_event (event); + if (button >= 1 && button <= 5) + state = (1 << (button + 7)); + + return state; +} + +static GdkModifierType +get_keyboard_modifiers_from_ns_flags (NSUInteger nsflags) +{ + GdkModifierType modifiers = 0; + + if (nsflags & NSAlphaShiftKeyMask) + modifiers |= GDK_LOCK_MASK; + if (nsflags & NSShiftKeyMask) + modifiers |= GDK_SHIFT_MASK; + if (nsflags & NSControlKeyMask) + modifiers |= GDK_CONTROL_MASK; + if (nsflags & NSAlternateKeyMask) + modifiers |= GDK_MOD1_MASK; + if (nsflags & NSCommandKeyMask) + modifiers |= GDK_MOD2_MASK; + + return modifiers; +} + +static GdkModifierType +get_keyboard_modifiers_from_ns_event (NSEvent *nsevent) +{ + return get_keyboard_modifiers_from_ns_flags ([nsevent modifierFlags]); +} + +/* Return an event mask from an NSEvent */ +static GdkEventMask +get_event_mask_from_ns_event (NSEvent *nsevent) +{ + switch ([nsevent type]) + { + case NSLeftMouseDown: + case NSRightMouseDown: + case NSOtherMouseDown: + return GDK_BUTTON_PRESS_MASK; + case NSLeftMouseUp: + case NSRightMouseUp: + case NSOtherMouseUp: + return GDK_BUTTON_RELEASE_MASK; + case NSMouseMoved: + return GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK; + case NSScrollWheel: + /* Since applications that want button press events can get + * scroll events on X11 (since scroll wheel events are really + * button press events there), we need to use GDK_BUTTON_PRESS_MASK too. + */ + return GDK_SCROLL_MASK | GDK_BUTTON_PRESS_MASK; + case NSLeftMouseDragged: + return (GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | + GDK_BUTTON_MOTION_MASK | GDK_BUTTON1_MOTION_MASK | + GDK_BUTTON1_MASK); + case NSRightMouseDragged: + return (GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | + GDK_BUTTON_MOTION_MASK | GDK_BUTTON3_MOTION_MASK | + GDK_BUTTON3_MASK); + case NSOtherMouseDragged: + { + GdkEventMask mask; + + mask = (GDK_POINTER_MOTION_MASK | + GDK_POINTER_MOTION_HINT_MASK | + GDK_BUTTON_MOTION_MASK); + + if (get_mouse_button_from_ns_event (nsevent) == 2) + mask |= (GDK_BUTTON2_MOTION_MASK | GDK_BUTTON2_MOTION_MASK | + GDK_BUTTON2_MASK); + + return mask; + } + case NSKeyDown: + case NSKeyUp: + case NSFlagsChanged: + { + switch (_gdk_quartz_keys_event_type (nsevent)) + { + case GDK_KEY_PRESS: + return GDK_KEY_PRESS_MASK; + case GDK_KEY_RELEASE: + return GDK_KEY_RELEASE_MASK; + case GDK_NOTHING: + return 0; + default: + g_assert_not_reached (); + } + } + break; + + case NSMouseEntered: + return GDK_ENTER_NOTIFY_MASK; + + case NSMouseExited: + return GDK_LEAVE_NOTIFY_MASK; + + default: + g_assert_not_reached (); + } + + return 0; +} + +static void +get_window_point_from_screen_point (GdkWindow *window, + NSPoint screen_point, + gint *x, + gint *y) +{ + NSPoint point; + NSWindow *nswindow; + GdkWindowObject *private; + + private = (GdkWindowObject *)window; + nswindow = ((GdkWindowImplQuartz *)private->impl)->toplevel; + + point = [nswindow convertScreenToBase:screen_point]; + + *x = point.x; + *y = private->height - point.y; +} + +static gboolean +is_mouse_button_press_event (NSEventType type) +{ + switch (type) + { + case NSLeftMouseDown: + case NSRightMouseDown: + case NSOtherMouseDown: + return TRUE; + } + + return FALSE; +} + +static GdkWindow * +get_toplevel_from_ns_event (NSEvent *nsevent, + NSPoint *screen_point, + gint *x, + gint *y) +{ + GdkWindow *toplevel = NULL; + + if ([nsevent window]) + { + GdkQuartzView *view; + GdkWindowObject *private; + NSPoint point, view_point; + NSRect view_frame; + + view = (GdkQuartzView *)[[nsevent window] contentView]; + + toplevel = [view gdkWindow]; + private = GDK_WINDOW_OBJECT (toplevel); + + point = [nsevent locationInWindow]; + view_point = [view convertPoint:point fromView:nil]; + view_frame = [view frame]; + + /* NSEvents come in with a window set, but with window coordinates + * out of window bounds. For e.g. moved events this is fine, we use + * this information to properly handle enter/leave notify and motion + * events. For mouse button press/release, we want to avoid forwarding + * these events however, because the window they relate to is not the + * window set in the event. This situation appears to occur when button + * presses come in just before (or just after?) a window is resized and + * also when a button press occurs on the OS X window titlebar. + * + * By setting toplevel to NULL, we do another attempt to get the right + * toplevel window below. + */ + if (is_mouse_button_press_event ([nsevent type]) && + (view_point.x < view_frame.origin.x || + view_point.x >= view_frame.origin.x + view_frame.size.width || + view_point.y < view_frame.origin.y || + view_point.y >= view_frame.origin.y + view_frame.size.height)) + { + toplevel = NULL; + + /* This is a hack for button presses to break all grabs. E.g. if + * a menu is open and one clicks on the title bar (or anywhere + * out of window bounds), we really want to pop down the menu (by + * breaking the grabs) before OS X handles the action of the title + * bar button. + * + * Because we cannot ingest this event into GDK, we have to do it + * here, not very nice. + */ + _gdk_quartz_events_break_all_grabs (get_time_from_ns_event (nsevent)); + } + else + { + *screen_point = [[nsevent window] convertBaseToScreen:point]; + + *x = point.x; + *y = private->height - point.y; + } + } + + if (!toplevel) + { + /* Fallback used when no NSWindow set. This happens e.g. when + * we allow motion events without a window set in gdk_event_translate() + * that occur immediately after the main menu bar was clicked/used. + * This fallback will not return coordinates contained in a window's + * titlebar. + */ + *screen_point = [NSEvent mouseLocation]; + toplevel = find_toplevel_under_pointer (_gdk_display, + *screen_point, + x, y); + } + + return toplevel; +} + +static GdkEvent * +create_focus_event (GdkWindow *window, + gboolean in) +{ + GdkEvent *event; + + event = gdk_event_new (GDK_FOCUS_CHANGE); + event->focus_change.window = window; + event->focus_change.in = in; + + return event; +} + + +static void +generate_motion_event (GdkWindow *window) +{ + NSPoint screen_point; + GdkEvent *event; + gint x, y, x_root, y_root; + + event = gdk_event_new (GDK_MOTION_NOTIFY); + event->any.window = NULL; + event->any.send_event = TRUE; + + screen_point = [NSEvent mouseLocation]; + + _gdk_quartz_window_nspoint_to_gdk_xy (screen_point, &x_root, &y_root); + get_window_point_from_screen_point (window, screen_point, &x, &y); + + event->any.type = GDK_MOTION_NOTIFY; + event->motion.window = window; + event->motion.time = get_time_from_ns_event ([NSApp currentEvent]); + event->motion.x = x; + event->motion.y = y; + event->motion.x_root = x_root; + event->motion.y_root = y_root; + /* FIXME event->axes */ + event->motion.state = _gdk_quartz_events_get_current_keyboard_modifiers () | + _gdk_quartz_events_get_current_mouse_modifiers (); + event->motion.is_hint = FALSE; + event->motion.device = _gdk_display->core_pointer; + + append_event (event, TRUE); +} + +/* Note: Used to both set a new focus window and to unset the old one. */ +void +_gdk_quartz_events_update_focus_window (GdkWindow *window, + gboolean got_focus) +{ + GdkEvent *event; + + if (got_focus && window == current_keyboard_window) + return; + + /* FIXME: Don't do this when grabbed? Or make GdkQuartzWindow + * disallow it in the first place instead? + */ + + if (!got_focus && window == current_keyboard_window) + { + event = create_focus_event (current_keyboard_window, FALSE); + append_event (event, FALSE); + g_object_unref (current_keyboard_window); + current_keyboard_window = NULL; + } + + if (got_focus) + { + if (current_keyboard_window) + { + event = create_focus_event (current_keyboard_window, FALSE); + append_event (event, FALSE); + g_object_unref (current_keyboard_window); + current_keyboard_window = NULL; + } + + event = create_focus_event (window, TRUE); + append_event (event, FALSE); + current_keyboard_window = g_object_ref (window); + + /* We just became the active window. Unlike X11, Mac OS X does + * not send us motion events while the window does not have focus + * ("is not key"). We send a dummy motion notify event now, so that + * everything in the window is set to correct state. + */ + generate_motion_event (window); + } +} + +void +_gdk_quartz_events_send_map_event (GdkWindow *window) +{ + GdkWindowObject *private = (GdkWindowObject *)window; + GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl); + + if (!impl->toplevel) + return; + + if (private->event_mask & GDK_STRUCTURE_MASK) + { + GdkEvent event; + + event.any.type = GDK_MAP; + event.any.window = window; + + gdk_event_put (&event); + } +} + +static GdkWindow * +find_toplevel_under_pointer (GdkDisplay *display, + NSPoint screen_point, + gint *x, + gint *y) +{ + GdkWindow *toplevel; + + toplevel = display->pointer_info.toplevel_under_pointer; + if (toplevel && WINDOW_IS_TOPLEVEL (toplevel)) + get_window_point_from_screen_point (toplevel, screen_point, x, y); + + if (toplevel) + { + /* If the coordinates are out of window bounds, this toplevel is not + * under the pointer and we thus return NULL. This can occur when + * toplevel under pointer has not yet been updated due to a very recent + * window resize. Alternatively, we should no longer be relying on + * the toplevel_under_pointer value which is maintained in gdkwindow.c. + */ + GdkWindowObject *private = GDK_WINDOW_OBJECT (toplevel); + if (*x < 0 || *y < 0 || *x >= private->width || *y >= private->height) + return NULL; + } + + return toplevel; +} + +/* This function finds the correct window to send an event to, taking + * into account grabs, event propagation, and event masks. + */ +static GdkWindow * +find_window_for_ns_event (NSEvent *nsevent, + gint *x, + gint *y, + gint *x_root, + gint *y_root) +{ + GdkQuartzView *view; + GdkWindow *toplevel; + NSPoint screen_point; + NSEventType event_type; + + event_type = [nsevent type]; + + if (foreign_mouse_down_view) { + switch (event_type) { + case NSLeftMouseUp: + case NSRightMouseUp: + case NSOtherMouseUp: + /* mouse up happened, foreign view needs to handle it + but we will also assume that it does (e.g. ends + a drag and whatever goes with it) and so we reset + foreign_mouse_down_view. + */ + foreign_mouse_down_view = 0; + return NULL; + + default: + /* foreign view needs to handle this */ + return NULL; + } + } + + view = (GdkQuartzView *)[[nsevent window] contentView]; + + toplevel = get_toplevel_from_ns_event (nsevent, &screen_point, x, y); + if (!toplevel) + return NULL; + + _gdk_quartz_window_nspoint_to_gdk_xy (screen_point, x_root, y_root); + + + switch (event_type) + { + case NSLeftMouseDown: + case NSRightMouseDown: + case NSOtherMouseDown: + case NSLeftMouseUp: + case NSRightMouseUp: + case NSOtherMouseUp: + case NSMouseMoved: + case NSScrollWheel: + case NSLeftMouseDragged: + case NSRightMouseDragged: + case NSOtherMouseDragged: + { + GdkDisplay *display; + GdkPointerGrabInfo *grab; + + display = gdk_drawable_get_display (toplevel); + + /* From the docs for XGrabPointer: + * + * If owner_events is True and if a generated pointer event + * would normally be reported to this client, it is reported + * as usual. Otherwise, the event is reported with respect to + * the grab_window and is reported only if selected by + * event_mask. For either value of owner_events, unreported + * events are discarded. + */ + grab = _gdk_display_get_last_pointer_grab (display); + if (WINDOW_IS_TOPLEVEL (toplevel) && grab) + { + /* Implicit grabs do not go through XGrabPointer and thus the + * event mask should not be checked. + */ + if (!grab->implicit + && (grab->event_mask & get_event_mask_from_ns_event (nsevent)) == 0) + return NULL; + + if (grab->owner_events) + { + /* For owner events, we need to use the toplevel under the + * pointer, not the window from the NSEvent, since that is + * reported with respect to the key window, which could be + * wrong. + */ + GdkWindow *toplevel_under_pointer; + gint x_tmp, y_tmp; + + toplevel_under_pointer = find_toplevel_under_pointer (display, + screen_point, + &x_tmp, &y_tmp); + if (toplevel_under_pointer) + { + toplevel = toplevel_under_pointer; + *x = x_tmp; + *y = y_tmp; + } + + return toplevel; + } + else + { + /* Finally check the grab window. */ + GdkWindow *grab_toplevel; + + grab_toplevel = gdk_window_get_effective_toplevel (grab->window); + get_window_point_from_screen_point (grab_toplevel, + screen_point, x, y); + + return grab_toplevel; + } + + return NULL; + } + else + { + /* The non-grabbed case. */ + GdkWindow *toplevel_under_pointer; + gint x_tmp, y_tmp; + + /* Ignore all events but mouse moved that might be on the title + * bar (above the content view). The reason is that otherwise + * gdk gets confused about getting e.g. button presses with no + * window (the title bar is not known to it). + */ + if (event_type != NSMouseMoved) + if (*y < 0) + return NULL; + + /* As for owner events, we need to use the toplevel under the + * pointer, not the window from the NSEvent. + */ + toplevel_under_pointer = find_toplevel_under_pointer (display, + screen_point, + &x_tmp, &y_tmp); + if (toplevel_under_pointer + && WINDOW_IS_TOPLEVEL (toplevel_under_pointer)) + { + GdkWindowObject *toplevel_private; + GdkWindowImplQuartz *toplevel_impl; + + toplevel = toplevel_under_pointer; + + toplevel_private = (GdkWindowObject *)toplevel; + toplevel_impl = (GdkWindowImplQuartz *)toplevel_private->impl; + + { + unsigned int subviews = [[toplevel_impl->view subviews] count]; + unsigned int si; + + for (si = 0; si < subviews; ++si) { + NSView* sv = [[toplevel_impl->view subviews] objectAtIndex:si]; + if ([sv tag] == ARDOUR_CANVAS_NSVIEW_TAG) + { + continue; + } + NSRect r = [sv frame]; + if (r.origin.x <= *x && r.origin.x + r.size.width >= *x && + r.origin.y <= *y && r.origin.y + r.size.height >= *y) { + /* event is within subview, forward back to Cocoa */ + + switch (event_type) + { + case NSLeftMouseDown: + case NSRightMouseDown: + case NSOtherMouseDown: + foreign_mouse_down_view = sv; + break; + default: + break; + } + + return NULL; + } + } + } + + *x = x_tmp; + *y = y_tmp; + } + return toplevel; + } + } + break; + + case NSMouseEntered: + case NSMouseExited: + /* Only handle our own entered/exited events, not the ones for the + * titlebar buttons. + */ + if ([view trackingRect] == nsevent.trackingNumber) + return toplevel; + + /* MacOS 13 isn't sending the trackingArea events so we have to + * rely on the cursorRect events that we discarded in earlier + * macOS versions. These trigger 4 pixels out from the window's + * frame so we obtain that rect and adjust it for hit testing. + */ + if (!nsevent.trackingArea && gdk_quartz_osx_version() >= GDK_OSX_VENTURA) + { + static const int border_width = 4; + NSRect frame = nsevent.window.frame; + gboolean inside, at_edge; + + frame.origin.x -= border_width; + frame.origin.y -= border_width; + frame.size.width += 2 * border_width; + frame.size.height += 2 * border_width; + inside = + screen_point.x >= frame.origin.x && + screen_point.x <= frame.origin.x + frame.size.width && + screen_point.y >= frame.origin.y && + screen_point.y <= frame.origin.y + frame.size.height; + at_edge = + screen_point.x >= frame.origin.x - 1 && + screen_point.x <= frame.origin.x + frame.size.width + 1 && + screen_point.y >= frame.origin.y - 1 && + screen_point.y <= frame.origin.y + frame.size.height + 1; + + if ((event_type == NSMouseEntered && inside) || + at_edge) + return toplevel; + else + return NULL; + } + + return NULL; + + case NSKeyDown: + case NSKeyUp: + case NSFlagsChanged: + if (_gdk_display->keyboard_grab.window && !_gdk_display->keyboard_grab.owner_events) + return gdk_window_get_effective_toplevel (_gdk_display->keyboard_grab.window); + + return toplevel; + + default: + /* Ignore everything else. */ + break; + } + + return NULL; +} + +static void +fill_crossing_event (GdkWindow *toplevel, + GdkEvent *event, + NSEvent *nsevent, + gint x, + gint y, + gint x_root, + gint y_root, + GdkEventType event_type, + GdkCrossingMode mode, + GdkNotifyType detail) +{ + event->any.type = event_type; + event->crossing.window = toplevel; + event->crossing.subwindow = NULL; + event->crossing.time = get_time_from_ns_event (nsevent); + event->crossing.x = x; + event->crossing.y = y; + event->crossing.x_root = x_root; + event->crossing.y_root = y_root; + event->crossing.mode = mode; + event->crossing.detail = detail; + event->crossing.state = get_keyboard_modifiers_from_ns_event (nsevent) | + _gdk_quartz_events_get_current_mouse_modifiers (); + + /* FIXME: Focus and button state? */ +} + +static void +fill_button_event (GdkWindow *window, + GdkEvent *event, + NSEvent *nsevent, + gint x, + gint y, + gint x_root, + gint y_root) +{ + GdkEventType type; + gint state; + + state = get_keyboard_modifiers_from_ns_event (nsevent) | + _gdk_quartz_events_get_current_mouse_modifiers (); + + switch ([nsevent type]) + { + case NSLeftMouseDown: + case NSRightMouseDown: + case NSOtherMouseDown: + type = GDK_BUTTON_PRESS; + state &= ~get_mouse_button_modifiers_from_ns_event (nsevent); + break; + + case NSLeftMouseUp: + case NSRightMouseUp: + case NSOtherMouseUp: + type = GDK_BUTTON_RELEASE; + state |= get_mouse_button_modifiers_from_ns_event (nsevent); + break; + + default: + g_assert_not_reached (); + } + + event->any.type = type; + event->button.window = window; + event->button.time = get_time_from_ns_event (nsevent); + event->button.x = x; + event->button.y = y; + event->button.x_root = x_root; + event->button.y_root = y_root; + /* FIXME event->axes */ + event->button.state = state; + event->button.button = get_mouse_button_from_ns_event (nsevent); + event->button.device = _gdk_display->core_pointer; +} + +static void +fill_motion_event (GdkWindow *window, + GdkEvent *event, + NSEvent *nsevent, + gint x, + gint y, + gint x_root, + gint y_root) +{ + GdkModifierType state; + + state = get_keyboard_modifiers_from_ns_event (nsevent); + + switch ([nsevent type]) + { + case NSLeftMouseDragged: + case NSRightMouseDragged: + case NSOtherMouseDragged: + state |= get_mouse_button_modifiers_from_ns_event (nsevent); + break; + + case NSMouseMoved: + default: + break; + } + + event->any.type = GDK_MOTION_NOTIFY; + event->motion.window = window; + event->motion.time = get_time_from_ns_event (nsevent); + event->motion.x = x; + event->motion.y = y; + event->motion.x_root = x_root; + event->motion.y_root = y_root; + /* FIXME event->axes */ + event->motion.state = get_keyboard_modifiers_from_ns_event (nsevent) | + _gdk_quartz_events_get_current_mouse_modifiers (); + event->motion.is_hint = FALSE; + event->motion.device = _gdk_display->core_pointer; +} + +static void +fill_scroll_event (GdkWindow *window, + GdkEvent *event, + NSEvent *nsevent, + gint x, + gint y, + gint x_root, + gint y_root, + gboolean has_deltas, + gdouble delta_x, + gdouble delta_y, + GdkScrollDirection direction) +{ + GdkWindowObject *private; + + private = GDK_WINDOW_OBJECT (window); + + event->any.type = GDK_SCROLL; + event->scroll.window = window; + event->scroll.time = get_time_from_ns_event (nsevent); + event->scroll.x = x; + event->scroll.y = y; + event->scroll.x_root = x_root; + event->scroll.y_root = y_root; + event->scroll.state = get_keyboard_modifiers_from_ns_event (nsevent); + event->scroll.direction = direction; + event->scroll.device = _gdk_display->core_pointer; + event->scroll.has_deltas = has_deltas; + event->scroll.delta_x = delta_x; + event->scroll.delta_y = delta_y; +} + +static void +fill_key_event (GdkWindow *window, + GdkEvent *event, + NSEvent *nsevent, + GdkEventType type) +{ + GdkEventPrivate *priv; + gchar buf[7]; + gunichar c = 0; + + priv = (GdkEventPrivate *) event; + priv->windowing_data = [nsevent retain]; + + event->any.type = type; + event->key.window = window; + event->key.time = get_time_from_ns_event (nsevent); + event->key.state = get_keyboard_modifiers_from_ns_event (nsevent); + event->key.hardware_keycode = [nsevent keyCode]; + event->key.group = ([nsevent modifierFlags] & NSAlternateKeyMask) ? 1 : 0; + event->key.keyval = GDK_VoidSymbol; + + gdk_keymap_translate_keyboard_state (NULL, + event->key.hardware_keycode, + event->key.state, + event->key.group, + &event->key.keyval, + NULL, NULL, NULL); + + event->key.is_modifier = _gdk_quartz_keys_is_modifier (event->key.hardware_keycode); + + /* If the key press is a modifier, the state should include the mask + * for that modifier but only for releases, not presses. This + * matches the X11 backend behavior. + */ + if (event->key.is_modifier) + { + int mask = 0; + + switch (event->key.keyval) + { + case GDK_Meta_R: + case GDK_Meta_L: + mask = GDK_MOD2_MASK; + break; + case GDK_Shift_R: + case GDK_Shift_L: + mask = GDK_SHIFT_MASK; + break; + case GDK_Caps_Lock: + mask = GDK_LOCK_MASK; + break; + case GDK_Alt_R: + case GDK_Alt_L: + mask = GDK_MOD1_MASK; + break; + case GDK_Control_R: + case GDK_Control_L: + mask = GDK_CONTROL_MASK; + break; + default: + mask = 0; + } + + if (type == GDK_KEY_PRESS) + event->key.state &= ~mask; + else if (type == GDK_KEY_RELEASE) + event->key.state |= mask; + } + + event->key.state |= _gdk_quartz_events_get_current_mouse_modifiers (); + event->key.string = NULL; + + /* Fill in ->string since apps depend on it, taken from the x11 backend. */ + if (event->key.keyval != GDK_VoidSymbol) + c = gdk_keyval_to_unicode (event->key.keyval); + + if (c) + { + gsize bytes_written; + gint len; + + len = g_unichar_to_utf8 (c, buf); + buf[len] = '\0'; + + event->key.string = g_locale_from_utf8 (buf, len, + NULL, &bytes_written, + NULL); + if (event->key.string) + event->key.length = bytes_written; + } + else if (event->key.keyval == GDK_Escape) + { + event->key.length = 1; + event->key.string = g_strdup ("\033"); + } + else if (event->key.keyval == GDK_Return || + event->key.keyval == GDK_KP_Enter) + { + event->key.length = 1; + event->key.string = g_strdup ("\r"); + } + + if (!event->key.string) + { + event->key.length = 0; + event->key.string = g_strdup (""); + } + + GDK_NOTE(EVENTS, + g_message ("key %s:\t\twindow: %p key: %12s %d", + type == GDK_KEY_PRESS ? "press" : "release", + event->key.window, + event->key.keyval ? gdk_keyval_name (event->key.keyval) : "(none)", + event->key.keyval)); +} + +static gboolean +synthesize_crossing_event (GdkWindow *window, + GdkEvent *event, + NSEvent *nsevent, + gint x, + gint y, + gint x_root, + gint y_root) +{ + GdkWindowObject *private; + + private = GDK_WINDOW_OBJECT (window); + + switch ([nsevent type]) + { + case NSMouseEntered: + /* Enter events are considered always to be from another toplevel + * window, this shouldn't negatively affect any app or gtk code, + * and is the only way to make GtkMenu work. EEK EEK EEK. + */ + if (!(private->event_mask & GDK_ENTER_NOTIFY_MASK)) + return FALSE; + + fill_crossing_event (window, event, nsevent, + x, y, + x_root, y_root, + GDK_ENTER_NOTIFY, + GDK_CROSSING_NORMAL, + GDK_NOTIFY_NONLINEAR); + return TRUE; + + case NSMouseExited: + /* See above */ + if (!(private->event_mask & GDK_LEAVE_NOTIFY_MASK)) + return FALSE; + + fill_crossing_event (window, event, nsevent, + x, y, + x_root, y_root, + GDK_LEAVE_NOTIFY, + GDK_CROSSING_NORMAL, + GDK_NOTIFY_NONLINEAR); + return TRUE; + + default: + break; + } + + return FALSE; +} + +void +_gdk_quartz_synthesize_null_key_event (GdkWindow *window) +{ + GdkEvent *event; + + event = gdk_event_new (GDK_KEY_PRESS); + event->any.type = GDK_KEY_PRESS; + event->key.window = window; + event->key.state = 0; + event->key.hardware_keycode = 0; + event->key.group = 0; + event->key.keyval = GDK_VoidSymbol; + append_event(event, FALSE); +} + +GdkEventMask +_gdk_quartz_events_get_current_event_mask (void) +{ + return current_event_mask; +} + +GdkModifierType +_gdk_quartz_events_get_current_keyboard_modifiers (void) +{ + if (gdk_quartz_osx_version () >= GDK_OSX_SNOW_LEOPARD) + { + return get_keyboard_modifiers_from_ns_flags ([NSClassFromString(@"NSEvent") modifierFlags]); + } + else + { + guint carbon_modifiers = GetCurrentKeyModifiers (); + GdkModifierType modifiers = 0; + + if (carbon_modifiers & alphaLock) + modifiers |= GDK_LOCK_MASK; + if (carbon_modifiers & shiftKey) + modifiers |= GDK_SHIFT_MASK; + if (carbon_modifiers & controlKey) + modifiers |= GDK_CONTROL_MASK; + if (carbon_modifiers & optionKey) + modifiers |= GDK_MOD1_MASK; + if (carbon_modifiers & cmdKey) + modifiers |= GDK_MOD2_MASK; + + return modifiers; + } +} + +GdkModifierType +_gdk_quartz_events_get_current_mouse_modifiers (void) +{ + if (gdk_quartz_osx_version () >= GDK_OSX_SNOW_LEOPARD) + { + return get_mouse_button_modifiers_from_ns_buttons ([NSClassFromString(@"NSEvent") pressedMouseButtons]); + } + else + { + return get_mouse_button_modifiers_from_ns_buttons (GetCurrentButtonState ()); + } +} + +/* Detect window resizing */ + +static gboolean +test_resize (NSEvent *event, GdkWindow *toplevel, gint x, gint y) +{ + GdkWindowObject *toplevel_private; + GdkWindowImplQuartz *toplevel_impl; + gboolean lion; + + /* Resizing from the resize indicator only begins if an NSLeftMouseButton + * event is received in the resizing area. + */ + toplevel_private = (GdkWindowObject *)toplevel; + toplevel_impl = (GdkWindowImplQuartz *)toplevel_private->impl; + if ([event type] == NSLeftMouseDown && + [toplevel_impl->toplevel showsResizeIndicator]) + { + NSRect frame; + + /* If the resize indicator is visible and the event + * is in the lower right 15x15 corner, we leave these + * events to Cocoa as to be handled as resize events. + * Applications may have widgets in this area. These + * will most likely be larger than 15x15 and for + * scroll bars there are also other means to move + * the scroll bar. Since the resize indicator is + * the only way of resizing windows on Mac OS, it + * is too important to not make functional. + */ + frame = [toplevel_impl->view bounds]; + if (x > frame.size.width - GRIP_WIDTH && + x < frame.size.width && + y > frame.size.height - GRIP_HEIGHT && + y < frame.size.height) + return TRUE; + } + + /* If we're on Lion and within 5 pixels of an edge, + * then assume that the user wants to resize, and + * return NULL to let Quartz get on with it. We check + * the selector isRestorable to see if we're on 10.7. + * This extra check is in case the user starts + * dragging before GDK recognizes the grab. + * + * We perform this check for a button press of all buttons, because we + * do receive, for instance, a right mouse down event for a GDK window + * for x-coordinate range [-3, 0], but we do not want to forward this + * into GDK. Forwarding such events into GDK will confuse the pointer + * window finding code, because there are no GdkWindows present in + * the range [-3, 0]. + */ + lion = gdk_quartz_osx_version () >= GDK_OSX_LION; + if (lion && + ([event type] == NSLeftMouseDown || + [event type] == NSRightMouseDown || + [event type] == NSOtherMouseDown)) + { + if (x < GDK_LION_RESIZE || + x > toplevel_private->width - GDK_LION_RESIZE || + y > toplevel_private->height - GDK_LION_RESIZE) + return TRUE; + } + + return FALSE; +} + +static gboolean +gdk_event_translate (GdkEvent *event, + NSEvent *nsevent) +{ + NSEventType event_type; + NSWindow *nswindow; + GdkWindow *window; + int x, y; + int x_root, y_root; + gboolean return_val; + GdkEvent *input_event; + + /* There is no support for real desktop wide grabs, so we break + * grabs when the application loses focus (gets deactivated). + */ + event_type = [nsevent type]; + if (event_type == NSAppKitDefined) + { + if ([nsevent subtype] == NSApplicationDeactivatedEventType) + _gdk_quartz_events_break_all_grabs (get_time_from_ns_event (nsevent)); + + /* This could potentially be used to break grabs when clicking + * on the title. The subtype 20 is undocumented so it's probably + * not a good idea: else if (subtype == 20) break_all_grabs (); + */ + + /* Leave all AppKit events to AppKit. */ + return FALSE; + } + + if (_gdk_default_filters) + { + /* Apply global filters */ + GdkFilterReturn result; + + result = gdk_event_apply_filters (nsevent, event, &_gdk_default_filters); + if (result != GDK_FILTER_CONTINUE) + { + return_val = (result == GDK_FILTER_TRANSLATE) ? TRUE : FALSE; + goto done; + } + } + + nswindow = [nsevent window]; + + /* Ignore events for windows not created by GDK. */ + if (nswindow && ![[nswindow contentView] isKindOfClass:[GdkQuartzView class]]) + return FALSE; + + /* Ignore events for ones with no windows */ + if (!nswindow) + { + GdkWindow *toplevel = NULL; + + if (event_type == NSMouseMoved) + { + /* Motion events received after clicking the menu bar do not have the + * window field set. Instead of giving up on the event immediately, + * we first check whether this event is within our window bounds. + */ + NSPoint screen_point = [NSEvent mouseLocation]; + gint x_tmp, y_tmp; + + toplevel = find_toplevel_under_pointer (_gdk_display, + screen_point, + &x_tmp, &y_tmp); + } + + if (!toplevel) + return FALSE; + } + + /* Ignore events and break grabs while the window is being + * dragged. This is a workaround for the window getting events for + * the window title. + */ + if ([(GdkQuartzWindow *)nswindow isInMove]) + { + _gdk_quartz_events_break_all_grabs (get_time_from_ns_event (nsevent)); + return FALSE; + } + + /* Also when in a manual resize, we ignore events so that these are + * pushed to GdkQuartzWindow's sendEvent handler. + */ + if ([(GdkQuartzWindow *)nswindow isInManualResize]) + return FALSE; + + /* Find the right GDK window to send the event to, taking grabs and + * event masks into consideration. + */ + window = find_window_for_ns_event (nsevent, &x, &y, &x_root, &y_root); + if (!window) + return FALSE; + + /* Quartz handles resizing on its own, so we want to stay out of the way. */ + if (test_resize (nsevent, window, x, y)) + return FALSE; + + /* Apply any window filters. */ + if (GDK_IS_WINDOW (window)) + { + GdkWindowObject *filter_private = (GdkWindowObject *) window; + GdkFilterReturn result; + + if (filter_private->filters) + { + g_object_ref (window); + + result = gdk_event_apply_filters (nsevent, event, &filter_private->filters); + + g_object_unref (window); + + if (result != GDK_FILTER_CONTINUE) + { + return_val = (result == GDK_FILTER_TRANSLATE) ? TRUE : FALSE; + goto done; + } + } + } + + /* If the app is not active leave the event to AppKit so the window gets + * focused correctly and don't do click-through (so we behave like most + * native apps). If the app is active, we focus the window and then handle + * the event, also to match native apps. + */ + if ((event_type == NSRightMouseDown || + event_type == NSOtherMouseDown || + event_type == NSLeftMouseDown)) + { + GdkWindowObject *private = (GdkWindowObject *)window; + GdkWindowImplQuartz *impl = GDK_WINDOW_IMPL_QUARTZ (private->impl); + + if (![NSApp isActive]) + { + [NSApp activateIgnoringOtherApps:YES]; + return FALSE; + } + else if (![impl->toplevel isKeyWindow]) + { + GdkPointerGrabInfo *grab; + + grab = _gdk_display_get_last_pointer_grab (_gdk_display); + if (!grab) + [impl->toplevel makeKeyWindow]; + } + } + + current_event_mask = get_event_mask_from_ns_event (nsevent); + + return_val = TRUE; + + switch (event_type) + { + case NSLeftMouseDown: + case NSRightMouseDown: + case NSOtherMouseDown: + case NSLeftMouseUp: + case NSRightMouseUp: + case NSOtherMouseUp: + fill_button_event (window, event, nsevent, x, y, x_root, y_root); + + input_event = gdk_event_new (GDK_NOTHING); + if (_gdk_input_fill_quartz_input_event (event, nsevent, input_event)) + append_event (input_event, TRUE); + else + gdk_event_free (input_event); + break; + + case NSLeftMouseDragged: + case NSRightMouseDragged: + case NSOtherMouseDragged: + case NSMouseMoved: + fill_motion_event (window, event, nsevent, x, y, x_root, y_root); + + input_event = gdk_event_new (GDK_NOTHING); + if (_gdk_input_fill_quartz_input_event (event, nsevent, input_event)) + append_event (input_event, TRUE); + else + gdk_event_free (input_event); + break; + + case NSScrollWheel: + { + GdkScrollDirection direction; + float dx; + float dy; + +#if GTK_OSX_MIN >= 7 + if (gdk_quartz_osx_version() >= GDK_OSX_LION && + [nsevent hasPreciseScrollingDeltas]) + { + dx = [nsevent scrollingDeltaX]; + dy = [nsevent scrollingDeltaY]; + + if (fabs (dy) > fabs (dx)) + { + if (dy < 0.0) + direction = GDK_SCROLL_DOWN; + else + direction = GDK_SCROLL_UP; + } + else + { + if (dx < 0.0) + direction = GDK_SCROLL_RIGHT; + else + direction = GDK_SCROLL_LEFT; + } + + fill_scroll_event (window, event, nsevent, x, y, x_root, y_root, + TRUE, -dx, -dy, direction); + } + else + { +#endif /* earlier than Lion */ + dx = [nsevent deltaX]; + dy = [nsevent deltaY]; + + if (dy != 0.0) + { + if (dy < 0.0) + direction = GDK_SCROLL_DOWN; + else + direction = GDK_SCROLL_UP; + + fill_scroll_event (window, event, nsevent, x, y, x_root, y_root, + FALSE, 0.0, fabs (dy), direction); + } + else if (dx != 0.0) + { + if (dx < 0.0) + direction = GDK_SCROLL_RIGHT; + else + direction = GDK_SCROLL_LEFT; + + fill_scroll_event (window, event, nsevent, x, y, x_root, y_root, + FALSE, fabs (dx), 0.0, direction); + } +#if GTK_OSX_MIN >= 7 + } +#endif + } + break; + + case NSMouseExited: + if (WINDOW_IS_TOPLEVEL (window)) + [[NSCursor arrowCursor] set]; + /* fall through */ + case NSMouseEntered: + return_val = synthesize_crossing_event (window, event, nsevent, x, y, x_root, y_root); + break; + + case NSKeyDown: + case NSKeyUp: + case NSFlagsChanged: + { + GdkEventType type; + + type = _gdk_quartz_keys_event_type (nsevent); + if (type == GDK_NOTHING) + return_val = FALSE; + else + fill_key_event (window, event, nsevent, type); + } + break; + + case NSTabletProximity: + _gdk_input_quartz_tablet_proximity ([nsevent pointingDeviceType]); + return_val = FALSE; + break; + + default: + /* Ignore everything elsee. */ + return_val = FALSE; + break; + } + + done: + if (return_val) + { + if (event->any.window) + g_object_ref (event->any.window); + if (((event->any.type == GDK_ENTER_NOTIFY) || + (event->any.type == GDK_LEAVE_NOTIFY)) && + (event->crossing.subwindow != NULL)) + g_object_ref (event->crossing.subwindow); + } + else + { + /* Mark this event as having no resources to be freed */ + event->any.window = NULL; + event->any.type = GDK_NOTHING; + } + + return return_val; +} + +void +_gdk_events_queue (GdkDisplay *display) +{ + NSEvent *nsevent; + + nsevent = _gdk_quartz_event_loop_get_pending (); + if (nsevent) + { + GdkEvent *event; + GList *node; + + event = gdk_event_new (GDK_NOTHING); + + event->any.window = NULL; + event->any.send_event = FALSE; + + ((GdkEventPrivate *)event)->flags |= GDK_EVENT_PENDING; + + node = _gdk_event_queue_append (display, event); + + if (gdk_event_translate (event, nsevent)) + { + ((GdkEventPrivate *)event)->flags &= ~GDK_EVENT_PENDING; + _gdk_windowing_got_event (display, node, event, 0); + } + else + { + _gdk_event_queue_remove_link (display, node); + g_list_free_1 (node); + gdk_event_free (event); + + GDK_THREADS_LEAVE (); + [NSApp sendEvent:nsevent]; + GDK_THREADS_ENTER (); + } + + _gdk_quartz_event_loop_release_event (nsevent); + } +} + +void +gdk_flush (void) +{ + /* Not supported. */ +} + +void +gdk_display_add_client_message_filter (GdkDisplay *display, + GdkAtom message_type, + GdkFilterFunc func, + gpointer data) +{ + /* Not supported. */ +} + +void +gdk_add_client_message_filter (GdkAtom message_type, + GdkFilterFunc func, + gpointer data) +{ + /* Not supported. */ +} + +void +gdk_display_sync (GdkDisplay *display) +{ + /* Not supported. */ +} + +void +gdk_display_flush (GdkDisplay *display) +{ + /* Not supported. */ +} + +gboolean +gdk_event_send_client_message_for_display (GdkDisplay *display, + GdkEvent *event, + GdkNativeWindow winid) +{ + /* Not supported. */ + return FALSE; +} + +void +gdk_screen_broadcast_client_message (GdkScreen *screen, + GdkEvent *event) +{ + /* Not supported. */ +} + +gboolean +gdk_screen_get_setting (GdkScreen *screen, + const gchar *name, + GValue *value) +{ + if (strcmp (name, "gtk-double-click-time") == 0) + { + NSUserDefaults *defaults; + float t; + + GDK_QUARTZ_ALLOC_POOL; + + defaults = [NSUserDefaults standardUserDefaults]; + + t = [defaults floatForKey:@"com.apple.mouse.doubleClickThreshold"]; + if (t == 0.0) + { + /* No user setting, use the default in OS X. */ + t = 0.5; + } + + GDK_QUARTZ_RELEASE_POOL; + + g_value_set_int (value, t * 1000); + + return TRUE; + } + else if (strcmp (name, "gtk-font-name") == 0) + { + NSString *name; + char *str; + + GDK_QUARTZ_ALLOC_POOL; + + name = [[NSFont systemFontOfSize:0] familyName]; + + /* Let's try to use the "views" font size (12pt) by default. This is + * used for lists/text/other "content" which is the largest parts of + * apps, using the "regular control" size (13pt) looks a bit out of + * place. We might have to tweak this. + */ + + /* The size has to be hardcoded as there doesn't seem to be a way to + * get the views font size programmatically. + */ + str = g_strdup_printf ("%s 12", [name UTF8String]); + g_value_set_string (value, str); + g_free (str); + + GDK_QUARTZ_RELEASE_POOL; + + return TRUE; + } + else if (strcmp (name, "gtk-primary-button-warps-slider") == 0) + { + GDK_QUARTZ_ALLOC_POOL; + + BOOL setting = [[NSUserDefaults standardUserDefaults] boolForKey:@"AppleScrollerPagingBehavior"]; + + /* If the Apple property is YES, it means "warp" */ + g_value_set_boolean (value, setting == YES); + + GDK_QUARTZ_RELEASE_POOL; + + return TRUE; + } + + /* FIXME: Add more settings */ + + return FALSE; +} + +void +_gdk_windowing_event_data_copy (const GdkEvent *src, + GdkEvent *dst) +{ + GdkEventPrivate *priv_src = (GdkEventPrivate *) src; + GdkEventPrivate *priv_dst = (GdkEventPrivate *) dst; + + if (priv_src->windowing_data) + { + priv_dst->windowing_data = priv_src->windowing_data; + [(NSEvent *)priv_dst->windowing_data retain]; + } +} + +void +_gdk_windowing_event_data_free (GdkEvent *event) +{ + GdkEventPrivate *priv = (GdkEventPrivate *) event; + + if (priv->windowing_data) + { + [(NSEvent *)priv->windowing_data release]; + priv->windowing_data = NULL; + } +} diff --git a/libs/tk/ydk/quartz/gdkfont-quartz.c b/libs/tk/ydk/quartz/gdkfont-quartz.c new file mode 100644 index 0000000000..2857cd5d2d --- /dev/null +++ b/libs/tk/ydk/quartz/gdkfont-quartz.c @@ -0,0 +1,134 @@ +/* gdkwindow-quartz.c + * + * Copyright (C) 2005 Imendio AB + * + * 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. + */ + + +#include "config.h" + +#include "gdkfont.h" + +GdkFont* +gdk_font_load_for_display (GdkDisplay *display, + const gchar *font_name) +{ + /* FIXME: Implement */ + return NULL; +} + +GdkFont* +gdk_font_from_description_for_display (GdkDisplay *display, + PangoFontDescription *desc) +{ + /* FIXME: Implement */ + return NULL; +} + +GdkFont * +gdk_fontset_load_for_display (GdkDisplay *display, + const gchar *fontset_name) +{ + return NULL; +} + +GdkFont* +gdk_fontset_load (const gchar *fontset_name) +{ + return NULL; +} + +gint +gdk_text_width (GdkFont *font, + const gchar *text, + gint text_length) +{ + /* FIXME: Implement */ + return -1; +} + +void +gdk_text_extents (GdkFont *font, + const gchar *text, + gint text_length, + gint *lbearing, + gint *rbearing, + gint *width, + gint *ascent, + gint *descent) +{ + /* FIXME: Implement */ +} + +gint +gdk_text_width_wc (GdkFont *font, + const GdkWChar *text, + gint text_length) +{ + /* FIXME: Implement */ + return 0; +} + + +void +gdk_text_extents_wc (GdkFont *font, + const GdkWChar *text, + gint text_length, + gint *lbearing, + gint *rbearing, + gint *width, + gint *ascent, + gint *descent) +{ + /* FIXME: Implement */ +} + +void +_gdk_font_destroy (GdkFont *font) +{ + /* FIXME: Implement */ +} + +gint +_gdk_font_strlen (GdkFont *font, + const gchar *str) +{ + /* FIXME: Implement */ + return -1; +} + +gint +gdk_font_id (const GdkFont *font) +{ + /* FIXME: Implement */ + return 0; +} + +gboolean +gdk_font_equal (const GdkFont *fonta, + const GdkFont *fontb) +{ + /* FIXME: Implement */ + return FALSE; +} + +GdkDisplay* +gdk_font_get_display (GdkFont* font) +{ + /* FIXME: Implement */ + return NULL; +} diff --git a/libs/tk/ydk/quartz/gdkgc-quartz.c b/libs/tk/ydk/quartz/gdkgc-quartz.c new file mode 100644 index 0000000000..bf2ffedd67 --- /dev/null +++ b/libs/tk/ydk/quartz/gdkgc-quartz.c @@ -0,0 +1,738 @@ +/* gdkgc-quartz.c + * + * Copyright (C) 2005 Imendio AB + * + * 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. + */ + +#include "config.h" + +#include "gdkgc.h" +#include "gdkprivate-quartz.h" + +static gpointer parent_class = NULL; + +static void +gdk_quartz_gc_get_values (GdkGC *gc, + GdkGCValues *values) +{ + GdkGCQuartz *private; + + private = GDK_GC_QUARTZ (gc); + + values->foreground.pixel = _gdk_gc_get_fg_pixel (gc); + values->background.pixel = _gdk_gc_get_bg_pixel (gc); + + values->font = private->font; + + values->function = private->function; + + values->fill = _gdk_gc_get_fill (gc); + values->tile = _gdk_gc_get_tile (gc); + values->stipple = _gdk_gc_get_stipple (gc); + + /* The X11 backend always returns a NULL clip_mask. */ + values->clip_mask = NULL; + + values->ts_x_origin = gc->ts_x_origin; + values->ts_y_origin = gc->ts_y_origin; + values->clip_x_origin = gc->clip_x_origin; + values->clip_y_origin = gc->clip_y_origin; + + values->graphics_exposures = private->graphics_exposures; + + values->line_width = private->line_width; + values->line_style = private->line_style; + values->cap_style = private->cap_style; + values->join_style = private->join_style; +} + + +static void +data_provider_release (void *info, const void *data, size_t size) +{ + g_free (info); +} + +static CGImageRef +create_clip_mask (GdkPixmap *source_pixmap) +{ + int width, height, bytes_per_row, bits_per_pixel; + void *data; + CGImageRef source; + CGImageRef clip_mask; + CGContextRef cg_context; + CGDataProviderRef data_provider; + + /* We need to flip the clip mask here, because this cannot be done during + * the drawing process when this mask will be used to do clipping. We + * quickly create a new CGImage, set up a CGContext, draw the source + * image while flipping, and done. If this appears too slow in the + * future, we would look into doing this by hand on the actual raw + * data. + */ + source = _gdk_pixmap_get_cgimage (source_pixmap); + + width = CGImageGetWidth (source); + height = CGImageGetHeight (source); + bytes_per_row = CGImageGetBytesPerRow (source); + bits_per_pixel = CGImageGetBitsPerPixel (source); + + data = g_malloc (height * bytes_per_row); + data_provider = CGDataProviderCreateWithData (data, data, + height * bytes_per_row, + data_provider_release); + + clip_mask = CGImageCreate (width, height, 8, + bits_per_pixel, + bytes_per_row, + CGImageGetColorSpace (source), + CGImageGetAlphaInfo (source), + data_provider, NULL, FALSE, + kCGRenderingIntentDefault); + CGDataProviderRelease (data_provider); + + cg_context = CGBitmapContextCreate (data, + width, height, + CGImageGetBitsPerComponent (source), + bytes_per_row, + CGImageGetColorSpace (source), + CGImageGetBitmapInfo (source)); + + if (cg_context) + { + CGContextTranslateCTM (cg_context, 0, height); + CGContextScaleCTM (cg_context, 1.0, -1.0); + + CGContextDrawImage (cg_context, + CGRectMake (0, 0, width, height), source); + + CGContextRelease (cg_context); + } + + return clip_mask; +} + +static void +gdk_quartz_gc_set_values (GdkGC *gc, + GdkGCValues *values, + GdkGCValuesMask mask) +{ + GdkGCQuartz *private = GDK_GC_QUARTZ (gc); + + if (mask & GDK_GC_FONT) + { + /* FIXME: implement font */ + } + + if (mask & GDK_GC_FUNCTION) + private->function = values->function; + + if (mask & GDK_GC_SUBWINDOW) + private->subwindow_mode = values->subwindow_mode; + + if (mask & GDK_GC_EXPOSURES) + private->graphics_exposures = values->graphics_exposures; + + if (mask & GDK_GC_CLIP_MASK) + { + private->have_clip_region = FALSE; + private->have_clip_mask = values->clip_mask != NULL; + if (private->clip_mask) + CGImageRelease (private->clip_mask); + + if (values->clip_mask) + private->clip_mask = create_clip_mask (values->clip_mask); + else + private->clip_mask = NULL; + } + + if (mask & GDK_GC_LINE_WIDTH) + private->line_width = values->line_width; + + if (mask & GDK_GC_LINE_STYLE) + private->line_style = values->line_style; + + if (mask & GDK_GC_CAP_STYLE) + private->cap_style = values->cap_style; + + if (mask & GDK_GC_JOIN_STYLE) + private->join_style = values->join_style; +} + +static void +gdk_quartz_gc_set_dashes (GdkGC *gc, + gint dash_offset, + gint8 dash_list[], + gint n) +{ + GdkGCQuartz *private = GDK_GC_QUARTZ (gc); + gint i; + + private->dash_count = n; + g_free (private->dash_lengths); + private->dash_lengths = g_new (CGFloat, n); + for (i = 0; i < n; i++) + private->dash_lengths[i] = (CGFloat) dash_list[i]; + private->dash_phase = (CGFloat) dash_offset; +} + +static void +gdk_gc_quartz_finalize (GObject *object) +{ + GdkGCQuartz *private = GDK_GC_QUARTZ (object); + + if (private->clip_mask) + CGImageRelease (private->clip_mask); + + if (private->ts_pattern) + CGPatternRelease (private->ts_pattern); + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +gdk_gc_quartz_class_init (GdkGCQuartzClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GdkGCClass *gc_class = GDK_GC_CLASS (klass); + + parent_class = g_type_class_peek_parent (klass); + + object_class->finalize = gdk_gc_quartz_finalize; + + gc_class->get_values = gdk_quartz_gc_get_values; + gc_class->set_values = gdk_quartz_gc_set_values; + gc_class->set_dashes = gdk_quartz_gc_set_dashes; +} + +static void +gdk_gc_quartz_init (GdkGCQuartz *gc_quartz) +{ + gc_quartz->function = GDK_COPY; + gc_quartz->subwindow_mode = GDK_CLIP_BY_CHILDREN; + gc_quartz->graphics_exposures = TRUE; + gc_quartz->line_width = 0; + gc_quartz->line_style = GDK_LINE_SOLID; + gc_quartz->cap_style = GDK_CAP_BUTT; + gc_quartz->join_style = GDK_JOIN_MITER; +} + +GType +_gdk_gc_quartz_get_type (void) +{ + static GType object_type = 0; + + if (!object_type) + { + const GTypeInfo object_info = + { + sizeof (GdkGCQuartzClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) gdk_gc_quartz_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (GdkGCQuartz), + 0, /* n_preallocs */ + (GInstanceInitFunc) gdk_gc_quartz_init, + }; + + object_type = g_type_register_static (GDK_TYPE_GC, + "GdkGCQuartz", + &object_info, 0); + } + + return object_type; +} + +GdkGC * +_gdk_quartz_gc_new (GdkDrawable *drawable, + GdkGCValues *values, + GdkGCValuesMask values_mask) +{ + GdkGC *gc; + + gc = g_object_new (GDK_TYPE_GC_QUARTZ, NULL); + + _gdk_gc_init (gc, drawable, values, values_mask); + + gdk_quartz_gc_set_values (gc, values, values_mask); + + return gc; +} + +void +_gdk_windowing_gc_set_clip_region (GdkGC *gc, + const GdkRegion *region, + gboolean reset_origin) +{ + GdkGCQuartz *private = GDK_GC_QUARTZ (gc); + + if ((private->have_clip_region && ! region) || private->have_clip_mask) + { + if (private->clip_mask) + { + CGImageRelease (private->clip_mask); + private->clip_mask = NULL; + } + private->have_clip_mask = FALSE; + } + + if (region == NULL || gdk_region_empty (region)) + private->have_clip_region = FALSE; + else + private->have_clip_region = TRUE; + + if (reset_origin) + { + gc->clip_x_origin = 0; + gc->clip_y_origin = 0; + } +} + +void +_gdk_windowing_gc_copy (GdkGC *dst_gc, + GdkGC *src_gc) +{ + GdkGCQuartz *dst_quartz_gc = GDK_GC_QUARTZ (dst_gc); + GdkGCQuartz *src_quartz_gc = GDK_GC_QUARTZ (src_gc); + + if (dst_quartz_gc->font) + gdk_font_unref (dst_quartz_gc->font); + dst_quartz_gc->font = src_quartz_gc->font; + if (dst_quartz_gc->font) + gdk_font_ref (dst_quartz_gc->font); + + dst_quartz_gc->function = src_quartz_gc->function; + dst_quartz_gc->subwindow_mode = src_quartz_gc->subwindow_mode; + dst_quartz_gc->graphics_exposures = src_quartz_gc->graphics_exposures; + + dst_quartz_gc->have_clip_region = src_quartz_gc->have_clip_region; + dst_quartz_gc->have_clip_mask = src_quartz_gc->have_clip_mask; + + if (dst_quartz_gc->clip_mask) + { + CGImageRelease (dst_quartz_gc->clip_mask); + dst_quartz_gc->clip_mask = NULL; + } + + if (src_quartz_gc->clip_mask) + dst_quartz_gc->clip_mask = _gdk_pixmap_get_cgimage (GDK_PIXMAP (src_quartz_gc->clip_mask)); + + dst_quartz_gc->line_width = src_quartz_gc->line_width; + dst_quartz_gc->line_style = src_quartz_gc->line_style; + dst_quartz_gc->cap_style = src_quartz_gc->cap_style; + dst_quartz_gc->join_style = src_quartz_gc->join_style; + + g_free (dst_quartz_gc->dash_lengths); + dst_quartz_gc->dash_lengths = g_memdup (src_quartz_gc->dash_lengths, + sizeof (CGFloat) * src_quartz_gc->dash_count); + dst_quartz_gc->dash_count = src_quartz_gc->dash_count; + dst_quartz_gc->dash_phase = src_quartz_gc->dash_phase; +} + +GdkScreen * +gdk_gc_get_screen (GdkGC *gc) +{ + return _gdk_screen; +} + +struct PatternCallbackInfo +{ + GdkGCQuartz *private_gc; + GdkDrawable *drawable; +}; + +static void +pattern_callback_info_release (void *info) +{ + g_free (info); +} + +static void +gdk_quartz_draw_tiled_pattern (void *info, + CGContextRef context) +{ + struct PatternCallbackInfo *pinfo = info; + GdkGC *gc = GDK_GC (pinfo->private_gc); + CGImageRef pattern_image; + size_t width, height; + + if (!context) + return; + + pattern_image = _gdk_pixmap_get_cgimage (GDK_PIXMAP (_gdk_gc_get_tile (gc))); + + width = CGImageGetWidth (pattern_image); + height = CGImageGetHeight (pattern_image); + + CGContextDrawImage (context, + CGRectMake (0, 0, width, height), + pattern_image); + CGImageRelease (pattern_image); +} + +static void +gdk_quartz_draw_stippled_pattern (void *info, + CGContextRef context) +{ + struct PatternCallbackInfo *pinfo = info; + GdkGC *gc = GDK_GC (pinfo->private_gc); + CGImageRef pattern_image; + CGRect rect; + CGColorRef color; + + if (!context) + return; + + pattern_image = _gdk_pixmap_get_cgimage (GDK_PIXMAP (_gdk_gc_get_stipple (gc))); + rect = CGRectMake (0, 0, + CGImageGetWidth (pattern_image), + CGImageGetHeight (pattern_image)); + + CGContextClipToMask (context, rect, pattern_image); + color = _gdk_quartz_colormap_get_cgcolor_from_pixel (pinfo->drawable, + _gdk_gc_get_fg_pixel (gc)); + CGContextSetFillColorWithColor (context, color); + CGColorRelease (color); + + CGContextFillRect (context, rect); + + CGImageRelease (pattern_image); +} + +static void +gdk_quartz_draw_opaque_stippled_pattern (void *info, + CGContextRef context) +{ + struct PatternCallbackInfo *pinfo = info; + GdkGC *gc = GDK_GC (pinfo->private_gc); + CGImageRef pattern_image; + CGRect rect; + CGColorRef color; + + if (!context) + return; + + pattern_image = _gdk_pixmap_get_cgimage (GDK_PIXMAP (_gdk_gc_get_stipple (gc))); + rect = CGRectMake (0, 0, + CGImageGetWidth (pattern_image), + CGImageGetHeight (pattern_image)); + + color = _gdk_quartz_colormap_get_cgcolor_from_pixel (pinfo->drawable, + _gdk_gc_get_bg_pixel (gc)); + CGContextSetFillColorWithColor (context, color); + CGColorRelease (color); + + CGContextFillRect (context, rect); + + CGContextClipToMask (context, rect, pattern_image); + color = _gdk_quartz_colormap_get_cgcolor_from_pixel (pinfo->drawable, + _gdk_gc_get_fg_pixel (gc)); + CGContextSetFillColorWithColor (context, color); + CGColorRelease (color); + + CGContextFillRect (context, rect); + + CGImageRelease (pattern_image); +} + +gboolean +_gdk_quartz_gc_update_cg_context (GdkGC *gc, + GdkDrawable *drawable, + CGContextRef context, + GdkQuartzContextValuesMask mask) +{ + GdkGCQuartz *private; + guint32 fg_pixel; + guint32 bg_pixel; + + g_return_val_if_fail (gc == NULL || GDK_IS_GC (gc), FALSE); + + if (!gc || !context) + return FALSE; + + private = GDK_GC_QUARTZ (gc); + + if (private->have_clip_region) + { + CGRect rect; + CGRect *cg_rects; + GdkRectangle *rects; + gint n_rects, i; + + gdk_region_get_rectangles (_gdk_gc_get_clip_region (gc), + &rects, &n_rects); + + if (!n_rects) + return FALSE; + + if (n_rects == 1) + cg_rects = ▭ + else + cg_rects = g_new (CGRect, n_rects); + + for (i = 0; i < n_rects; i++) + { + cg_rects[i].origin.x = rects[i].x + gc->clip_x_origin; + cg_rects[i].origin.y = rects[i].y + gc->clip_y_origin; + cg_rects[i].size.width = rects[i].width; + cg_rects[i].size.height = rects[i].height; + } + + CGContextClipToRects (context, cg_rects, n_rects); + + g_free (rects); + if (cg_rects != &rect) + g_free (cg_rects); + } + else if (private->have_clip_mask && private->clip_mask) + { + /* Note: This is 10.4 only. For lower versions, we need to transform the + * mask into a region. + */ + CGContextClipToMask (context, + CGRectMake (gc->clip_x_origin, gc->clip_y_origin, + CGImageGetWidth (private->clip_mask), + CGImageGetHeight (private->clip_mask)), + private->clip_mask); + } + + fg_pixel = _gdk_gc_get_fg_pixel (gc); + bg_pixel = _gdk_gc_get_bg_pixel (gc); + + { + CGBlendMode blend_mode = kCGBlendModeNormal; + + switch (private->function) + { + case GDK_COPY: + blend_mode = kCGBlendModeNormal; + break; + + case GDK_INVERT: + case GDK_XOR: + blend_mode = kCGBlendModeExclusion; + fg_pixel = 0xffffffff; + bg_pixel = 0xffffffff; + break; + + case GDK_CLEAR: + case GDK_AND: + case GDK_AND_REVERSE: + case GDK_AND_INVERT: + case GDK_NOOP: + case GDK_OR: + case GDK_EQUIV: + case GDK_OR_REVERSE: + case GDK_COPY_INVERT: + case GDK_OR_INVERT: + case GDK_NAND: + case GDK_NOR: + case GDK_SET: + blend_mode = kCGBlendModeNormal; /* FIXME */ + break; + } + + CGContextSetBlendMode (context, blend_mode); + } + + /* FIXME: implement subwindow mode */ + + /* FIXME: implement graphics exposures */ + + if (mask & GDK_QUARTZ_CONTEXT_STROKE) + { + CGLineCap line_cap = kCGLineCapButt; + CGLineJoin line_join = kCGLineJoinMiter; + CGColorRef color; + + color = _gdk_quartz_colormap_get_cgcolor_from_pixel (drawable, + fg_pixel); + CGContextSetStrokeColorWithColor (context, color); + CGColorRelease (color); + + CGContextSetLineWidth (context, MAX (1.0, private->line_width)); + + switch (private->line_style) + { + case GDK_LINE_SOLID: + CGContextSetLineDash (context, 0.0, NULL, 0); + break; + + case GDK_LINE_DOUBLE_DASH: + /* FIXME: Implement; for now, fall back to GDK_LINE_ON_OFF_DASH */ + + case GDK_LINE_ON_OFF_DASH: + CGContextSetLineDash (context, private->dash_phase, + private->dash_lengths, private->dash_count); + break; + } + + switch (private->cap_style) + { + case GDK_CAP_NOT_LAST: + /* FIXME: Implement; for now, fall back to GDK_CAP_BUTT */ + case GDK_CAP_BUTT: + line_cap = kCGLineCapButt; + break; + case GDK_CAP_ROUND: + line_cap = kCGLineCapRound; + break; + case GDK_CAP_PROJECTING: + line_cap = kCGLineCapSquare; + break; + } + + CGContextSetLineCap (context, line_cap); + + switch (private->join_style) + { + case GDK_JOIN_MITER: + line_join = kCGLineJoinMiter; + break; + case GDK_JOIN_ROUND: + line_join = kCGLineJoinRound; + break; + case GDK_JOIN_BEVEL: + line_join = kCGLineJoinBevel; + break; + } + + CGContextSetLineJoin (context, line_join); + } + + if (mask & GDK_QUARTZ_CONTEXT_FILL) + { + GdkFill fill = _gdk_gc_get_fill (gc); + CGColorSpaceRef baseSpace; + CGColorSpaceRef patternSpace; + CGFloat alpha = 1.0; + + if (fill == GDK_SOLID) + { + CGColorRef color; + + color = _gdk_quartz_colormap_get_cgcolor_from_pixel (drawable, + fg_pixel); + CGContextSetFillColorWithColor (context, color); + CGColorRelease (color); + } + else + { + struct PatternCallbackInfo *info; + + if (!private->ts_pattern) + { + gfloat width, height; + gboolean is_colored = FALSE; + CGPatternCallbacks callbacks = { 0, NULL, NULL }; + CGPoint phase; + GdkPixmapImplQuartz *pix_impl = NULL; + + info = g_new (struct PatternCallbackInfo, 1); + private->ts_pattern_info = info; + + /* Won't ref to avoid circular dependencies */ + info->drawable = drawable; + info->private_gc = private; + + callbacks.releaseInfo = pattern_callback_info_release; + + switch (fill) + { + case GDK_TILED: + pix_impl = GDK_PIXMAP_IMPL_QUARTZ (GDK_PIXMAP_OBJECT (_gdk_gc_get_tile (gc))->impl); + width = pix_impl->width; + height = pix_impl->height; + is_colored = TRUE; + callbacks.drawPattern = gdk_quartz_draw_tiled_pattern; + break; + case GDK_STIPPLED: + pix_impl = GDK_PIXMAP_IMPL_QUARTZ (GDK_PIXMAP_OBJECT (_gdk_gc_get_stipple (gc))->impl); + width = pix_impl->width; + height = pix_impl->height; + is_colored = FALSE; + callbacks.drawPattern = gdk_quartz_draw_stippled_pattern; + break; + case GDK_OPAQUE_STIPPLED: + pix_impl = GDK_PIXMAP_IMPL_QUARTZ (GDK_PIXMAP_OBJECT (_gdk_gc_get_stipple (gc))->impl); + width = pix_impl->width; + height = pix_impl->height; + is_colored = TRUE; + callbacks.drawPattern = gdk_quartz_draw_opaque_stippled_pattern; + break; + default: + break; + } + + phase = CGPointApplyAffineTransform (CGPointMake (gc->ts_x_origin, gc->ts_y_origin), CGContextGetCTM (context)); + CGContextSetPatternPhase (context, CGSizeMake (phase.x, phase.y)); + + private->ts_pattern = CGPatternCreate (info, + CGRectMake (0, 0, width, height), + CGAffineTransformIdentity, + width, height, + kCGPatternTilingConstantSpacing, + is_colored, + &callbacks); + } + else + info = (struct PatternCallbackInfo *)private->ts_pattern_info; + + /* Update drawable in the pattern callback info. Again, we + * won't ref to avoid circular dependencies. + */ + info->drawable = drawable; + + baseSpace = (fill == GDK_STIPPLED) ? CGColorSpaceCreateDeviceRGB () : NULL; + patternSpace = CGColorSpaceCreatePattern (baseSpace); + + CGContextSetFillColorSpace (context, patternSpace); + CGColorSpaceRelease (patternSpace); + CGColorSpaceRelease (baseSpace); + + if (fill == GDK_STIPPLED) + { + CGColorRef color; + const CGFloat *components; + + color = _gdk_quartz_colormap_get_cgcolor_from_pixel (drawable, + fg_pixel); + components = CGColorGetComponents (color); + + CGContextSetFillPattern (context, private->ts_pattern, + components); + CGColorRelease (color); + } + else + CGContextSetFillPattern (context, private->ts_pattern, &alpha); + } + } + + if (mask & GDK_QUARTZ_CONTEXT_TEXT) + { + /* FIXME: implement text */ + } + + if (GDK_IS_WINDOW_IMPL_QUARTZ (drawable)) + private->is_window = TRUE; + else + private->is_window = FALSE; + + return TRUE; +} diff --git a/libs/tk/ydk/quartz/gdkgeometry-quartz.c b/libs/tk/ydk/quartz/gdkgeometry-quartz.c new file mode 100644 index 0000000000..06a31f10cc --- /dev/null +++ b/libs/tk/ydk/quartz/gdkgeometry-quartz.c @@ -0,0 +1,65 @@ +/* gdkgeometry-quartz.c + * + * Copyright (C) 2005 Imendio AB + * + * 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. + */ + +#include "config.h" + +#include "gdkprivate-quartz.h" + +void +_gdk_quartz_window_queue_translation (GdkWindow *window, + GdkGC *gc, + GdkRegion *area, + gint dx, + gint dy) +{ + GdkWindowObject *private = (GdkWindowObject *)window; + GdkWindowImplQuartz *impl = (GdkWindowImplQuartz *)private->impl; + + int i, n_rects; + GdkRegion *intersection; + GdkRectangle *rects; + + /* We will intersect the known region that needs display with the given + * area. This intersection will be translated by dx, dy. For the end + * result, we will also set that it needs display. + */ + + if (!impl->needs_display_region) + return; + + intersection = gdk_region_copy (impl->needs_display_region); + gdk_region_intersect (intersection, area); + gdk_region_offset (intersection, dx, dy); + + gdk_region_get_rectangles (intersection, &rects, &n_rects); + + for (i = 0; i < n_rects; i++) + _gdk_quartz_window_set_needs_display_in_rect (window, &rects[i]); + + g_free (rects); + gdk_region_destroy (intersection); +} + +gboolean +_gdk_quartz_window_queue_antiexpose (GdkWindow *window, + GdkRegion *area) +{ + return FALSE; +} diff --git a/libs/tk/ydk/quartz/gdkglobals-quartz.c b/libs/tk/ydk/quartz/gdkglobals-quartz.c new file mode 100644 index 0000000000..764eb10880 --- /dev/null +++ b/libs/tk/ydk/quartz/gdkglobals-quartz.c @@ -0,0 +1,55 @@ +/* gdkglobals-quartz.c + * + * Copyright (C) 2005 Imendio AB + * + * 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. + */ + +#include "config.h" +#include "gdktypes.h" +#include "gdkprivate.h" +#include "gdkquartz.h" + +GdkDisplay *_gdk_display = NULL; +GdkScreen *_gdk_screen = NULL; +GdkWindow *_gdk_root = NULL; + +GdkOSXVersion +gdk_quartz_osx_version (void) +{ + static gint32 vkey = GDK_OSX_UNSUPPORTED; + + if (vkey == GDK_OSX_UNSUPPORTED) + { +#if MAC_OS_X_VERSION_MIN_REQUIRED < 101000 + OSErr err = Gestalt (gestaltSystemVersionMinor, (SInt32*)&vkey); + + g_return_val_if_fail (err == noErr, GDK_OSX_UNSUPPORTED); +#else + NSOperatingSystemVersion version; + + version = [[NSProcessInfo processInfo] operatingSystemVersion]; + vkey = version.majorVersion == 10 ? version.minorVersion : version.majorVersion + 5; +#endif + } + + if (vkey < GDK_OSX_MIN) + return GDK_OSX_UNSUPPORTED; + else if (vkey > GDK_OSX_CURRENT) + return GDK_OSX_NEW; + else + return vkey; +} diff --git a/libs/tk/ydk/quartz/gdkim-quartz.c b/libs/tk/ydk/quartz/gdkim-quartz.c new file mode 100644 index 0000000000..c602ecc2be --- /dev/null +++ b/libs/tk/ydk/quartz/gdkim-quartz.c @@ -0,0 +1,73 @@ +/* GDK - The GIMP Drawing Kit + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, 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 "config.h" + +#include + +#include "gdki18n.h" +#include "gdkinternals.h" +#include "gdkprivate-quartz.h" + +gchar* +gdk_set_locale (void) +{ + if (!setlocale (LC_ALL,"")) + g_warning ("locale not supported by C library"); + + return setlocale (LC_ALL, NULL); +} + +gchar * +gdk_wcstombs (const GdkWChar *src) +{ + gchar *mbstr; + + gint length = 0; + gint i; + + while (src[length] != 0) + length++; + + mbstr = g_new (gchar, length + 1); + + for (i = 0; i < length + 1; i++) + mbstr[i] = src[i]; + + return mbstr; +} + +gint +gdk_mbstowcs (GdkWChar *dest, const gchar *src, gint dest_max) +{ + gint i; + + for (i = 0; i < dest_max && src[i]; i++) + dest[i] = src[i]; + + return i; +} + diff --git a/libs/tk/ydk/quartz/gdkimage-quartz.c b/libs/tk/ydk/quartz/gdkimage-quartz.c new file mode 100644 index 0000000000..b70e49b7a9 --- /dev/null +++ b/libs/tk/ydk/quartz/gdkimage-quartz.c @@ -0,0 +1,390 @@ +/* gdkimage-quartz.c + * + * Copyright (C) 2005 Imendio AB + * + * 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. + */ + +#include "config.h" + +#include "gdk.h" +#include "gdkimage.h" +#include "gdkprivate-quartz.h" + +static GObjectClass *parent_class; + +GdkImage * +_gdk_quartz_image_copy_to_image (GdkDrawable *drawable, + GdkImage *image, + gint src_x, + gint src_y, + gint dest_x, + gint dest_y, + gint width, + gint height) +{ + GdkScreen *screen; + + g_return_val_if_fail (GDK_IS_DRAWABLE_IMPL_QUARTZ (drawable), NULL); + g_return_val_if_fail (image != NULL || (dest_x == 0 && dest_y == 0), NULL); + + screen = gdk_drawable_get_screen (drawable); + if (!image) + image = _gdk_image_new_for_depth (screen, GDK_IMAGE_FASTEST, NULL, + width, height, + gdk_drawable_get_depth (drawable)); + + if (GDK_IS_PIXMAP_IMPL_QUARTZ (drawable)) + { + GdkPixmapImplQuartz *pix_impl; + gint bytes_per_row; + guchar *data; + int x, y; + + pix_impl = GDK_PIXMAP_IMPL_QUARTZ (drawable); + data = (guchar *)(pix_impl->data); + + if (src_x + width > pix_impl->width || src_y + height > pix_impl->height) + { + g_warning ("Out of bounds copy-area for pixmap -> image conversion\n"); + return image; + } + + switch (gdk_drawable_get_depth (drawable)) + { + case 24: + bytes_per_row = pix_impl->width * 4; + for (y = 0; y < height; y++) + { + guchar *src = data + ((y + src_y) * bytes_per_row) + (src_x * 4); + + for (x = 0; x < width; x++) + { + gint32 pixel; + + /* RGB24, 4 bytes per pixel, skip first. */ + pixel = src[0] << 16 | src[1] << 8 | src[2]; + src += 4; + + gdk_image_put_pixel (image, dest_x + x, dest_y + y, pixel); + } + } + break; + + case 32: + bytes_per_row = pix_impl->width * 4; + for (y = 0; y < height; y++) + { + guchar *src = data + ((y + src_y) * bytes_per_row) + (src_x * 4); + + for (x = 0; x < width; x++) + { + gint32 pixel; + + /* ARGB32, 4 bytes per pixel. */ + pixel = src[0] << 24 | src[1] << 16 | src[2] << 8 | src[3]; + src += 4; + + gdk_image_put_pixel (image, dest_x + x, dest_y + y, pixel); + } + } + break; + + case 1: /* TODO: optimize */ + bytes_per_row = pix_impl->width; + for (y = 0; y < height; y++) + { + guchar *src = data + ((y + src_y) * bytes_per_row) + src_x; + + for (x = 0; x < width; x++) + { + gint32 pixel; + + /* 8 bits */ + pixel = src[0]; + src++; + + gdk_image_put_pixel (image, dest_x + x, dest_y + y, pixel); + } + } + break; + + default: + g_warning ("Unsupported bit depth %d\n", gdk_drawable_get_depth (drawable)); + return image; + } + } + else if (GDK_IS_WINDOW_IMPL_QUARTZ (drawable)) + { + GdkQuartzView *view; + NSBitmapImageRep *rep; + guchar *data; + int x, y; + NSSize size; + NSBitmapFormat format; + gboolean has_alpha; + gint bpp; + gint r_byte = 0; + gint g_byte = 1; + gint b_byte = 2; + gint a_byte = 3; + gboolean le_image_data = FALSE; + + if (GDK_WINDOW_IMPL_QUARTZ (drawable) == GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (_gdk_root)->impl)) + { +#if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4 + return image; +#else + /* Special case for the root window. */ + CGRect rect = CGRectMake (src_x, src_y, width, height); + CGImageRef root_image_ref = CGWindowListCreateImage (rect, + kCGWindowListOptionOnScreenOnly, + kCGNullWindowID, + kCGWindowImageDefault); + + /* HACK: the NSBitmapImageRep does not copy and convert + * CGImageRef's data so it matches what NSBitmapImageRep can + * express in its API (which is RGBA and ARGB, premultiplied + * and unpremultiplied), it only references the CGImageRef. + * Therefore we need to do the host byte swapping ourselves. + */ + if (CGImageGetBitmapInfo (root_image_ref) & kCGBitmapByteOrder32Little) + { + r_byte = 3; + g_byte = 2; + b_byte = 1; + a_byte = 0; + + le_image_data = TRUE; + } + + rep = [[NSBitmapImageRep alloc] initWithCGImage: root_image_ref]; + CGImageRelease (root_image_ref); +#endif + } + else + { + NSRect rect = NSMakeRect (src_x, src_y, width, height); + view = GDK_WINDOW_IMPL_QUARTZ (drawable)->view; + + /* We return the image even if we can't copy to it. */ + if (![view lockFocusIfCanDraw]) + return image; + + rep = [[NSBitmapImageRep alloc] initWithFocusedViewRect: rect]; + [view unlockFocus]; + } + + data = [rep bitmapData]; + size = [rep size]; + format = [rep bitmapFormat]; + has_alpha = [rep hasAlpha]; + bpp = [rep bitsPerPixel] / 8; + + /* MORE HACK: AlphaFirst seems set for le_image_data, which is + * technically correct, but really apple, are you kidding, it's + * in fact ABGR, not ARGB as promised in NSBitmapImageRep's API. + */ + if (!le_image_data && (format & NSAlphaFirstBitmapFormat)) + { + r_byte = 1; + g_byte = 2; + b_byte = 3; + a_byte = 0; + } + + for (y = 0; y < size.height; y++) + { + guchar *src = data + y * [rep bytesPerRow]; + + for (x = 0; x < size.width; x++) + { + guchar r = src[r_byte]; + guchar g = src[g_byte]; + guchar b = src[b_byte]; + gint32 pixel; + + if (has_alpha) + { + guchar alpha = src[a_byte]; + + /* unpremultiply if alpha > 0 */ + if (! (format & NSAlphaNonpremultipliedBitmapFormat) && alpha) + { + r = r * 255 / alpha; + g = g * 255 / alpha; + b = b * 255 / alpha; + } + + if (image->byte_order == GDK_MSB_FIRST) + pixel = alpha | b << 8 | g << 16 | r << 24; + else + pixel = alpha << 24 | b << 16 | g << 8 | r; + } + else + { + if (image->byte_order == GDK_MSB_FIRST) + pixel = b | g << 8 | r << 16; + else + pixel = b << 16 | g << 8 | r; + } + + src += bpp; + + gdk_image_put_pixel (image, dest_x + x, dest_y + y, pixel); + } + } + + [rep release]; + } + + return image; +} + +static void +gdk_image_finalize (GObject *object) +{ + GdkImage *image = GDK_IMAGE (object); + + g_free (image->mem); + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +gdk_image_class_init (GdkImageClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + parent_class = g_type_class_peek_parent (klass); + + object_class->finalize = gdk_image_finalize; +} + +GType +gdk_image_get_type (void) +{ + static GType object_type = 0; + + if (!object_type) + { + const GTypeInfo object_info = + { + sizeof (GdkImageClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) gdk_image_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (GdkImage), + 0, /* n_preallocs */ + (GInstanceInitFunc) NULL, + }; + + object_type = g_type_register_static (G_TYPE_OBJECT, + "GdkImage", + &object_info, + 0); + } + + return object_type; +} + +GdkImage * +gdk_image_new_bitmap (GdkVisual *visual, gpointer data, gint width, gint height) +{ + /* We don't implement this function because it's broken, deprecated and + * tricky to implement. */ + g_warning ("This function is unimplemented"); + + return NULL; +} + +GdkImage* +_gdk_image_new_for_depth (GdkScreen *screen, + GdkImageType type, + GdkVisual *visual, + gint width, + gint height, + gint depth) +{ + GdkImage *image; + + if (visual) + depth = visual->depth; + + g_assert (depth == 24 || depth == 32); + + image = g_object_new (gdk_image_get_type (), NULL); + image->type = type; + image->visual = visual; + image->width = width; + image->height = height; + image->depth = depth; + + image->byte_order = (G_BYTE_ORDER == G_LITTLE_ENDIAN) ? GDK_LSB_FIRST : GDK_MSB_FIRST; + + /* We only support images with bpp 4 */ + image->bpp = 4; + image->bpl = image->width * image->bpp; + image->bits_per_pixel = image->bpp * 8; + + image->mem = g_malloc (image->bpl * image->height); + memset (image->mem, 0x00, image->bpl * image->height); + + return image; +} + +guint32 +gdk_image_get_pixel (GdkImage *image, + gint x, + gint y) +{ + guchar *ptr; + + g_return_val_if_fail (image != NULL, 0); + g_return_val_if_fail (x >= 0 && x < image->width, 0); + g_return_val_if_fail (y >= 0 && y < image->height, 0); + + ptr = image->mem + y * image->bpl + x * image->bpp; + + return *(guint32 *)ptr; +} + +void +gdk_image_put_pixel (GdkImage *image, + gint x, + gint y, + guint32 pixel) +{ + guchar *ptr; + + ptr = image->mem + y * image->bpl + x * image->bpp; + + *(guint32 *)ptr = pixel; +} + +gint +_gdk_windowing_get_bits_for_depth (GdkDisplay *display, + gint depth) +{ + if (depth == 24 || depth == 32) + return 32; + else + g_assert_not_reached (); + + return 0; +} diff --git a/libs/tk/ydk/quartz/gdkinput.c b/libs/tk/ydk/quartz/gdkinput.c new file mode 100644 index 0000000000..6f5f8ea201 --- /dev/null +++ b/libs/tk/ydk/quartz/gdkinput.c @@ -0,0 +1,755 @@ +/* GDK - The GIMP Drawing Kit + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, 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 "config.h" +#include + +#import +#include + +#include "gdkprivate-quartz.h" +#include "gdkscreen-quartz.h" +#include "gdkinput.h" +#include "gdkprivate.h" +#include "gdkinputprivate.h" + + +#define N_CORE_POINTER_AXES 2 +#define N_INPUT_DEVICE_AXES 5 + + +static GdkDeviceAxis gdk_input_core_axes[] = { + { GDK_AXIS_X, 0, 0 }, + { GDK_AXIS_Y, 0, 0 } +}; + +static GdkDeviceAxis gdk_quartz_pen_axes[] = { + { GDK_AXIS_X, 0, 0 }, + { GDK_AXIS_Y, 0, 0 }, + { GDK_AXIS_PRESSURE, 0, 1 }, + { GDK_AXIS_XTILT, -1, 1 }, + { GDK_AXIS_YTILT, -1, 1 } +}; + +static GdkDeviceAxis gdk_quartz_cursor_axes[] = { + { GDK_AXIS_X, 0, 0 }, + { GDK_AXIS_Y, 0, 0 }, + { GDK_AXIS_PRESSURE, 0, 1 }, + { GDK_AXIS_XTILT, -1, 1 }, + { GDK_AXIS_YTILT, -1, 1 } +}; + +static GdkDeviceAxis gdk_quartz_eraser_axes[] = { + { GDK_AXIS_X, 0, 0 }, + { GDK_AXIS_Y, 0, 0 }, + { GDK_AXIS_PRESSURE, 0, 1 }, + { GDK_AXIS_XTILT, -1, 1 }, + { GDK_AXIS_YTILT, -1, 1 } +}; + + +/* Global variables */ +static GList *_gdk_input_windows = NULL; +static GList *_gdk_input_devices = NULL; +static GdkDevice *_gdk_core_pointer = NULL; +static GdkDevice *_gdk_quartz_pen = NULL; +static GdkDevice *_gdk_quartz_cursor = NULL; +static GdkDevice *_gdk_quartz_eraser = NULL; +static GdkDevice *active_device = NULL; + +static void +gdk_device_finalize (GObject *object) +{ + g_error ("A GdkDevice object was finalized. This should not happen"); +} + +static void +gdk_device_class_init (GObjectClass *class) +{ + class->finalize = gdk_device_finalize; +} + +GType +gdk_device_get_type (void) +{ + static GType object_type = 0; + + if (!object_type) + { + const GTypeInfo object_info = + { + sizeof (GdkDeviceClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) gdk_device_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (GdkDevicePrivate), + 0, /* n_preallocs */ + (GInstanceInitFunc) NULL, + }; + + object_type = g_type_register_static (G_TYPE_OBJECT, + "GdkDevice", + &object_info, 0); + } + + return object_type; +} + +GList * +gdk_devices_list (void) +{ + return _gdk_input_devices; +} + +GList * +gdk_display_list_devices (GdkDisplay *dpy) +{ + return _gdk_input_devices; +} + +const gchar * +gdk_device_get_name (GdkDevice *device) +{ + g_return_val_if_fail (GDK_IS_DEVICE (device), NULL); + + return device->name; +} + +GdkInputSource +gdk_device_get_source (GdkDevice *device) +{ + g_return_val_if_fail (GDK_IS_DEVICE (device), 0); + + return device->source; +} + +GdkInputMode +gdk_device_get_mode (GdkDevice *device) +{ + g_return_val_if_fail (GDK_IS_DEVICE (device), 0); + + return device->mode; +} + +gboolean +gdk_device_get_has_cursor (GdkDevice *device) +{ + g_return_val_if_fail (GDK_IS_DEVICE (device), FALSE); + + return device->has_cursor; +} + +void +gdk_device_set_source (GdkDevice *device, + GdkInputSource source) +{ + device->source = source; +} + +void +gdk_device_get_key (GdkDevice *device, + guint index, + guint *keyval, + GdkModifierType *modifiers) +{ + g_return_if_fail (GDK_IS_DEVICE (device)); + g_return_if_fail (index < device->num_keys); + + if (!device->keys[index].keyval && + !device->keys[index].modifiers) + return; + + if (keyval) + *keyval = device->keys[index].keyval; + + if (modifiers) + *modifiers = device->keys[index].modifiers; +} + +void +gdk_device_set_key (GdkDevice *device, + guint index, + guint keyval, + GdkModifierType modifiers) +{ + g_return_if_fail (device != NULL); + g_return_if_fail (index < device->num_keys); + + device->keys[index].keyval = keyval; + device->keys[index].modifiers = modifiers; +} + +GdkAxisUse +gdk_device_get_axis_use (GdkDevice *device, + guint index) +{ + g_return_val_if_fail (GDK_IS_DEVICE (device), GDK_AXIS_IGNORE); + g_return_val_if_fail (index < device->num_axes, GDK_AXIS_IGNORE); + + return device->axes[index].use; +} + +gint +gdk_device_get_n_keys (GdkDevice *device) +{ + g_return_val_if_fail (GDK_IS_DEVICE (device), 0); + + return device->num_keys; +} + +gint +gdk_device_get_n_axes (GdkDevice *device) +{ + g_return_val_if_fail (GDK_IS_DEVICE (device), 0); + + return device->num_axes; +} + +void +gdk_device_set_axis_use (GdkDevice *device, + guint index, + GdkAxisUse use) +{ +#if 0 + /* Remapping axes is unsupported for now */ + g_return_if_fail (device != NULL); + g_return_if_fail (index < device->num_axes); + + device->axes[index].use = use; + + switch (use) + { + case GDK_AXIS_X: + case GDK_AXIS_Y: + device->axes[index].min = 0.; + device->axes[index].max = 0.; + break; + case GDK_AXIS_XTILT: + case GDK_AXIS_YTILT: + device->axes[index].min = -1.; + device->axes[index].max = 1; + break; + default: + device->axes[index].min = 0.; + device->axes[index].max = 1; + break; + } +#endif +} + +/** + * gdk_input_set_device_state: + * @device: The devices to set + * @mask: The new button mask + * @axes: The new axes values + * + * Set the state of a device's inputs for later + * retrieval by gdk_device_get_state. + */ +static void +gdk_input_set_device_state (GdkDevice *device, + GdkModifierType mask, + gdouble *axes) +{ + GdkDevicePrivate *priv; + gint i; + + if (device != _gdk_core_pointer) + { + priv = (GdkDevicePrivate *)device; + priv->last_state = mask; + + for (i = 0; i < device->num_axes; ++i) + priv->last_axes_state[i] = axes[i]; + } +} + +void +gdk_device_get_state (GdkDevice *device, + GdkWindow *window, + gdouble *axes, + GdkModifierType *mask) +{ + GdkDevicePrivate *priv; + gint i; + + if (device == _gdk_core_pointer) + { + gint x_int, y_int; + + gdk_window_get_pointer (window, &x_int, &y_int, mask); + + if (axes) + { + axes[0] = x_int; + axes[1] = y_int; + } + } + else + { + priv = (GdkDevicePrivate *)device; + + if (mask) + *mask = priv->last_state; + + if (axes) + for (i = 0; i < device->num_axes; ++i) + axes[i] = priv->last_axes_state[i]; + } +} + +void +gdk_device_free_history (GdkTimeCoord **events, + gint n_events) +{ + gint i; + + for (i = 0; i < n_events; i++) + g_free (events[i]); + + g_free (events); +} + +gboolean +gdk_device_get_history (GdkDevice *device, + GdkWindow *window, + guint32 start, + guint32 stop, + GdkTimeCoord ***events, + gint *n_events) +{ + g_return_val_if_fail (window != NULL, FALSE); + g_return_val_if_fail (GDK_WINDOW_IS_QUARTZ (window), FALSE); + g_return_val_if_fail (events != NULL, FALSE); + g_return_val_if_fail (n_events != NULL, FALSE); + + *n_events = 0; + *events = NULL; + return FALSE; +} + +gboolean +gdk_device_set_mode (GdkDevice *device, + GdkInputMode mode) +{ + /* FIXME: Window mode isn't supported yet */ + if (device != _gdk_core_pointer && + (mode == GDK_MODE_DISABLED || mode == GDK_MODE_SCREEN)) + { + device->mode = mode; + return TRUE; + } + + return FALSE; +} + +gint +_gdk_input_enable_window (GdkWindow *window, GdkDevicePrivate *gdkdev) +{ + return TRUE; +} + +gint +_gdk_input_disable_window (GdkWindow *window, GdkDevicePrivate *gdkdev) +{ + return TRUE; +} + + +GdkInputWindow * +_gdk_input_window_find(GdkWindow *window) +{ + GList *tmp_list; + + for (tmp_list=_gdk_input_windows; tmp_list; tmp_list=tmp_list->next) + if (((GdkInputWindow *)(tmp_list->data))->window == window) + return (GdkInputWindow *)(tmp_list->data); + + return NULL; /* Not found */ +} + +/* FIXME: this routine currently needs to be called between creation + and the corresponding configure event (because it doesn't get the + root_relative_geometry). This should work with + gtk_window_set_extension_events, but will likely fail in other + cases */ + +void +gdk_input_set_extension_events (GdkWindow *window, gint mask, + GdkExtensionMode mode) +{ + GdkWindowObject *window_private; + GList *tmp_list; + GdkInputWindow *iw; + + g_return_if_fail (window != NULL); + g_return_if_fail (GDK_WINDOW_IS_QUARTZ (window)); + + window_private = (GdkWindowObject*) window; + + if (mode == GDK_EXTENSION_EVENTS_NONE) + mask = 0; + + if (mask != 0) + { + iw = g_new(GdkInputWindow,1); + + iw->window = window; + iw->mode = mode; + + iw->obscuring = NULL; + iw->num_obscuring = 0; + iw->grabbed = FALSE; + + _gdk_input_windows = g_list_append (_gdk_input_windows,iw); + window_private->extension_events = mask; + + /* Add enter window events to the event mask */ + /* FIXME, this is not needed for XINPUT_NONE */ + gdk_window_set_events (window, + gdk_window_get_events (window) | + GDK_ENTER_NOTIFY_MASK); + } + else + { + iw = _gdk_input_window_find (window); + if (iw) + { + _gdk_input_windows = g_list_remove (_gdk_input_windows,iw); + g_free (iw); + } + + window_private->extension_events = 0; + } + + for (tmp_list = _gdk_input_devices; tmp_list; tmp_list = tmp_list->next) + { + GdkDevicePrivate *gdkdev = (GdkDevicePrivate *)(tmp_list->data); + + if (gdkdev != (GdkDevicePrivate *)_gdk_core_pointer) + { + if (mask != 0 && gdkdev->info.mode != GDK_MODE_DISABLED + && (gdkdev->info.has_cursor || mode == GDK_EXTENSION_EVENTS_ALL)) + _gdk_input_enable_window (window,gdkdev); + else + _gdk_input_disable_window (window,gdkdev); + } + } +} + +void +_gdk_input_window_destroy (GdkWindow *window) +{ + GdkInputWindow *input_window; + + input_window = _gdk_input_window_find (window); + g_return_if_fail (input_window != NULL); + + _gdk_input_windows = g_list_remove (_gdk_input_windows,input_window); + g_free (input_window); +} + +void +_gdk_input_init (void) +{ + GdkDevicePrivate *priv; + + _gdk_core_pointer = g_object_new (GDK_TYPE_DEVICE, NULL); + _gdk_core_pointer->name = "Core Pointer"; + _gdk_core_pointer->source = GDK_SOURCE_MOUSE; + _gdk_core_pointer->mode = GDK_MODE_SCREEN; + _gdk_core_pointer->has_cursor = TRUE; + _gdk_core_pointer->num_axes = N_CORE_POINTER_AXES; + _gdk_core_pointer->axes = gdk_input_core_axes; + _gdk_core_pointer->num_keys = 0; + _gdk_core_pointer->keys = NULL; + + _gdk_display->core_pointer = _gdk_core_pointer; + _gdk_input_devices = g_list_append (NULL, _gdk_core_pointer); + + _gdk_quartz_pen = g_object_new (GDK_TYPE_DEVICE, NULL); + _gdk_quartz_pen->name = "Quartz Pen"; + _gdk_quartz_pen->source = GDK_SOURCE_PEN; + _gdk_quartz_pen->mode = GDK_MODE_SCREEN; + _gdk_quartz_pen->has_cursor = TRUE; + _gdk_quartz_pen->num_axes = N_INPUT_DEVICE_AXES; + _gdk_quartz_pen->axes = gdk_quartz_pen_axes; + _gdk_quartz_pen->num_keys = 0; + _gdk_quartz_pen->keys = NULL; + + priv = (GdkDevicePrivate *)_gdk_quartz_pen; + priv->last_axes_state = g_malloc_n (_gdk_quartz_pen->num_axes, sizeof (gdouble)); + + _gdk_input_devices = g_list_append (_gdk_input_devices, _gdk_quartz_pen); + + _gdk_quartz_cursor = g_object_new (GDK_TYPE_DEVICE, NULL); + _gdk_quartz_cursor->name = "Quartz Cursor"; + _gdk_quartz_cursor->source = GDK_SOURCE_CURSOR; + _gdk_quartz_cursor->mode = GDK_MODE_SCREEN; + _gdk_quartz_cursor->has_cursor = TRUE; + _gdk_quartz_cursor->num_axes = N_INPUT_DEVICE_AXES; + _gdk_quartz_cursor->axes = gdk_quartz_cursor_axes; + _gdk_quartz_cursor->num_keys = 0; + _gdk_quartz_cursor->keys = NULL; + + priv = (GdkDevicePrivate *)_gdk_quartz_cursor; + priv->last_axes_state = g_malloc_n (_gdk_quartz_cursor->num_axes, sizeof (gdouble)); + + _gdk_input_devices = g_list_append (_gdk_input_devices, _gdk_quartz_cursor); + + _gdk_quartz_eraser = g_object_new (GDK_TYPE_DEVICE, NULL); + _gdk_quartz_eraser->name = "Quartz Eraser"; + _gdk_quartz_eraser->source = GDK_SOURCE_ERASER; + _gdk_quartz_eraser->mode = GDK_MODE_SCREEN; + _gdk_quartz_eraser->has_cursor = TRUE; + _gdk_quartz_eraser->num_axes = N_INPUT_DEVICE_AXES; + _gdk_quartz_eraser->axes = gdk_quartz_eraser_axes; + _gdk_quartz_eraser->num_keys = 0; + _gdk_quartz_eraser->keys = NULL; + + priv = (GdkDevicePrivate *)_gdk_quartz_eraser; + priv->last_axes_state = g_malloc_n (_gdk_quartz_eraser->num_axes, sizeof (gdouble)); + + _gdk_input_devices = g_list_append (_gdk_input_devices, _gdk_quartz_eraser); + + active_device = _gdk_core_pointer; +} + +void +_gdk_input_exit (void) +{ + GList *tmp_list; + GdkDevicePrivate *gdkdev; + + for (tmp_list = _gdk_input_devices; tmp_list; tmp_list = tmp_list->next) + { + gdkdev = (GdkDevicePrivate *)(tmp_list->data); + if (gdkdev != (GdkDevicePrivate *)_gdk_core_pointer) + { + gdk_device_set_mode ((GdkDevice *)gdkdev, GDK_MODE_DISABLED); + + g_free (gdkdev->info.name); + g_free (gdkdev->info.axes); + g_free (gdkdev->info.keys); + g_free (gdkdev->last_axes_state); + g_free (gdkdev); + } + } + + g_list_free (_gdk_input_devices); + + for (tmp_list = _gdk_input_windows; tmp_list; tmp_list = tmp_list->next) + { + g_free (tmp_list->data); + } + g_list_free (_gdk_input_windows); +} + +gboolean +gdk_device_get_axis (GdkDevice *device, gdouble *axes, GdkAxisUse use, gdouble *value) +{ + gint i; + + g_return_val_if_fail (device != NULL, FALSE); + + if (axes == NULL) + return FALSE; + + for (i = 0; i < device->num_axes; i++) + if (device->axes[i].use == use) + { + if (value) + *value = axes[i]; + return TRUE; + } + + return FALSE; +} + +void +_gdk_input_window_crossing (GdkWindow *window, + gboolean enter) +{ +} + +/** + * _gdk_input_quartz_tablet_proximity: + * @deviceType: The result of [nsevent pointingDeviceType] + * + * Update the current active device based on a proximity event. + */ +void +_gdk_input_quartz_tablet_proximity (NSPointingDeviceType deviceType) +{ + if (deviceType == NSPenPointingDevice) + active_device = _gdk_quartz_pen; + else if (deviceType == NSCursorPointingDevice) + active_device = _gdk_quartz_cursor; + else if (deviceType == NSEraserPointingDevice) + active_device = _gdk_quartz_eraser; + else + active_device = _gdk_core_pointer; +} + +/** + * _gdk_input_fill_quartz_input_event: + * @event: The GDK mouse event. + * @nsevent: The NSEvent that generated the mouse event. + * @input_event: (out): Return location for the input event. + * + * Handle extended input for the passed event, the GdkEvent object + * passed in should be a filled mouse button or motion event. + * + * Return value: %TRUE if an extended input event was generated. + */ +gboolean +_gdk_input_fill_quartz_input_event (GdkEvent *event, + NSEvent *nsevent, + GdkEvent *input_event) +{ + gdouble *axes; + gint x, y; + gint x_target, y_target; + gdouble x_root, y_root; + gint state; + GdkInputWindow *iw; + GdkWindow *target_window; + GdkScreenQuartz *screen_quartz; + + if ([nsevent subtype] == NSTabletProximityEventSubtype) + { + _gdk_input_quartz_tablet_proximity ([nsevent pointingDeviceType]); + } + else if (([nsevent subtype] != NSTabletPointEventSubtype) || + (active_device == _gdk_core_pointer) || + (active_device->mode == GDK_MODE_DISABLED)) + { + _gdk_display->ignore_core_events = FALSE; + return FALSE; + } + + switch (event->any.type) + { + case GDK_MOTION_NOTIFY: + x = event->motion.x; + y = event->motion.y; + state = event->motion.state; + break; + case GDK_BUTTON_PRESS: + case GDK_BUTTON_RELEASE: + x = event->button.x; + y = event->button.y; + state = event->button.state; + break; + default: + /* Not an input related event */ + return FALSE; + break; + } + + /* Input events won't be propagated through windows that aren't listening + * for input events, so _gdk_window_get_input_window_for_event finds the + * window to directly send the event to. + */ + target_window = _gdk_window_get_input_window_for_event (event->any.window, + event->any.type, + 0, x, y, 0); + + iw = _gdk_input_window_find (target_window); + + if (!iw) + { + /* Return if the target window doesn't have extended events enabled or + * hasn't asked for this type of event. + */ + _gdk_display->ignore_core_events = FALSE; + return FALSE; + } + + /* The cursor is inside an extended events window, block propagation of the + * core motion / button events + */ + _gdk_display->ignore_core_events = TRUE; + + axes = g_malloc_n (N_INPUT_DEVICE_AXES, sizeof (gdouble)); + + gdk_window_get_origin (target_window, &x_target, &y_target); + + /* Equation for root x & y taken from _gdk_quartz_window_xy_to_gdk_xy + * recalculated here to get doubles instead of ints. + */ + screen_quartz = GDK_SCREEN_QUARTZ (_gdk_screen); + x_root = [NSEvent mouseLocation].x - screen_quartz->min_x; + y_root = screen_quartz->height - [NSEvent mouseLocation].y + screen_quartz->min_y; + + axes[0] = x_root - x_target; + axes[1] = y_root - y_target; + axes[2] = [nsevent pressure]; + axes[3] = [nsevent tilt].x; + axes[4] = [nsevent tilt].y; + + gdk_input_set_device_state (active_device, state, axes); + + input_event->any.window = target_window; + input_event->any.type = event->any.type; + input_event->any.send_event = event->any.send_event; + + switch (event->any.type) + { + case GDK_MOTION_NOTIFY: + input_event->motion.device = active_device; + input_event->motion.x = axes[0]; + input_event->motion.y = axes[1]; + input_event->motion.axes = axes; + input_event->motion.x_root = x_root; + input_event->motion.y_root = y_root; + + input_event->motion.time = event->motion.time; + input_event->motion.state = event->motion.state; + input_event->motion.is_hint = event->motion.is_hint; + break; + case GDK_BUTTON_PRESS: + case GDK_BUTTON_RELEASE: + input_event->button.device = active_device; + input_event->button.x = axes[0]; + input_event->button.y = axes[1]; + input_event->button.axes = axes; + input_event->button.x_root = x_root; + input_event->button.y_root = y_root; + + input_event->button.time = event->button.time; + input_event->button.state = event->button.state; + input_event->button.button = event->button.button; + break; + default: + return FALSE; + break; + } + + return TRUE; +} diff --git a/libs/tk/ydk/quartz/gdkkeys-quartz.c b/libs/tk/ydk/quartz/gdkkeys-quartz.c new file mode 100644 index 0000000000..aed5ccdd5f --- /dev/null +++ b/libs/tk/ydk/quartz/gdkkeys-quartz.c @@ -0,0 +1,820 @@ +/* gdkkeys-quartz.c + * + * Copyright (C) 2000 Red Hat, Inc. + * Copyright (C) 2005 Imendio AB + * + * 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. + */ +/* Some parts of this code come from quartzKeyboard.c, + * from the Apple X11 Server. + * + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation files + * (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT + * HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name(s) of the above + * copyright holders shall not be used in advertising or otherwise to + * promote the sale, use or other dealings in this Software without + * prior written authorization. + */ + +#include "config.h" + +#include +#include +#include "gdk.h" +#include "gdkkeysyms.h" + +#define NUM_KEYCODES 128 +#define KEYVALS_PER_KEYCODE 4 + +static GdkKeymap *default_keymap = NULL; + +/* This is a table of all keyvals. Each keycode gets KEYVALS_PER_KEYCODE entries. + * TThere is 1 keyval per modifier (Nothing, Shift, Alt, Shift+Alt); + */ +static guint *keyval_array = NULL; + +static inline UniChar +macroman2ucs (unsigned char c) +{ + /* Precalculated table mapping MacRoman-128 to Unicode. Generated + by creating single element CFStringRefs then extracting the + first character. */ + + static const unsigned short table[128] = { + 0xc4, 0xc5, 0xc7, 0xc9, 0xd1, 0xd6, 0xdc, 0xe1, + 0xe0, 0xe2, 0xe4, 0xe3, 0xe5, 0xe7, 0xe9, 0xe8, + 0xea, 0xeb, 0xed, 0xec, 0xee, 0xef, 0xf1, 0xf3, + 0xf2, 0xf4, 0xf6, 0xf5, 0xfa, 0xf9, 0xfb, 0xfc, + 0x2020, 0xb0, 0xa2, 0xa3, 0xa7, 0x2022, 0xb6, 0xdf, + 0xae, 0xa9, 0x2122, 0xb4, 0xa8, 0x2260, 0xc6, 0xd8, + 0x221e, 0xb1, 0x2264, 0x2265, 0xa5, 0xb5, 0x2202, 0x2211, + 0x220f, 0x3c0, 0x222b, 0xaa, 0xba, 0x3a9, 0xe6, 0xf8, + 0xbf, 0xa1, 0xac, 0x221a, 0x192, 0x2248, 0x2206, 0xab, + 0xbb, 0x2026, 0xa0, 0xc0, 0xc3, 0xd5, 0x152, 0x153, + 0x2013, 0x2014, 0x201c, 0x201d, 0x2018, 0x2019, 0xf7, 0x25ca, + 0xff, 0x178, 0x2044, 0x20ac, 0x2039, 0x203a, 0xfb01, 0xfb02, + 0x2021, 0xb7, 0x201a, 0x201e, 0x2030, 0xc2, 0xca, 0xc1, + 0xcb, 0xc8, 0xcd, 0xce, 0xcf, 0xcc, 0xd3, 0xd4, + 0xf8ff, 0xd2, 0xda, 0xdb, 0xd9, 0x131, 0x2c6, 0x2dc, + 0xaf, 0x2d8, 0x2d9, 0x2da, 0xb8, 0x2dd, 0x2db, 0x2c7 + }; + + if (c < 128) + return c; + else + return table[c - 128]; +} + +const static struct { + guint keycode; + guint keyval; + unsigned int modmask; /* So we can tell when a mod key is pressed/released */ +} modifier_keys[] = { + { 54, GDK_Meta_R, NSCommandKeyMask }, + { 55, GDK_Meta_L, NSCommandKeyMask }, + { 56, GDK_Shift_L, NSShiftKeyMask }, + { 57, GDK_Caps_Lock, NSAlphaShiftKeyMask }, + { 58, GDK_Alt_L, NSAlternateKeyMask }, + { 59, GDK_Control_L, NSControlKeyMask }, + { 60, GDK_Shift_R, NSShiftKeyMask }, + { 61, GDK_Alt_R, NSAlternateKeyMask }, + { 62, GDK_Control_R, NSControlKeyMask } +}; + +const static struct { + guint keycode; + guint keyval; +} function_keys[] = { + { 122, GDK_F1 }, + { 120, GDK_F2 }, + { 99, GDK_F3 }, + { 118, GDK_F4 }, + { 96, GDK_F5 }, + { 97, GDK_F6 }, + { 98, GDK_F7 }, + { 100, GDK_F8 }, + { 101, GDK_F9 }, + { 109, GDK_F10 }, + { 103, GDK_F11 }, + { 111, GDK_F12 }, + { 105, GDK_F13 }, + { 107, GDK_F14 }, + { 113, GDK_F15 }, + { 106, GDK_F16 } +}; + +const static struct { + guint keycode; + guint normal_keyval, keypad_keyval; +} known_numeric_keys[] = { + { 65, GDK_period, GDK_KP_Decimal }, + { 67, GDK_asterisk, GDK_KP_Multiply }, + { 69, GDK_plus, GDK_KP_Add }, + { 75, GDK_slash, GDK_KP_Divide }, + { 76, GDK_Return, GDK_KP_Enter }, + { 78, GDK_minus, GDK_KP_Subtract }, + { 81, GDK_equal, GDK_KP_Equal }, + { 82, GDK_0, GDK_KP_0 }, + { 83, GDK_1, GDK_KP_1 }, + { 84, GDK_2, GDK_KP_2 }, + { 85, GDK_3, GDK_KP_3 }, + { 86, GDK_4, GDK_KP_4 }, + { 87, GDK_5, GDK_KP_5 }, + { 88, GDK_6, GDK_KP_6 }, + { 89, GDK_7, GDK_KP_7 }, + { 91, GDK_8, GDK_KP_8 }, + { 92, GDK_9, GDK_KP_9 } +}; + +/* These values aren't covered by gdk_unicode_to_keyval */ +const static struct { + gunichar ucs_value; + guint keyval; +} special_ucs_table [] = { + { 0x0001, GDK_Home }, + { 0x0003, GDK_Return }, + { 0x0004, GDK_End }, + { 0x0008, GDK_BackSpace }, + { 0x0009, GDK_Tab }, + { 0x000b, GDK_Page_Up }, + { 0x000c, GDK_Page_Down }, + { 0x000d, GDK_Return }, + { 0x001b, GDK_Escape }, + { 0x001c, GDK_Left }, + { 0x001d, GDK_Right }, + { 0x001e, GDK_Up }, + { 0x001f, GDK_Down }, + { 0x007f, GDK_Delete }, + { 0xf027, GDK_dead_acute }, + { 0xf060, GDK_dead_grave }, + { 0xf300, GDK_dead_grave }, + { 0xf0b4, GDK_dead_acute }, + { 0xf301, GDK_dead_acute }, + { 0xf385, GDK_dead_acute }, + { 0xf05e, GDK_dead_circumflex }, + { 0xf2c6, GDK_dead_circumflex }, + { 0xf302, GDK_dead_circumflex }, + { 0xf07e, GDK_dead_tilde }, + { 0xf2dc, GDK_dead_tilde }, + { 0xf303, GDK_dead_tilde }, + { 0xf342, GDK_dead_perispomeni }, + { 0xf0af, GDK_dead_macron }, + { 0xf304, GDK_dead_macron }, + { 0xf2d8, GDK_dead_breve }, + { 0xf306, GDK_dead_breve }, + { 0xf2d9, GDK_dead_abovedot }, + { 0xf307, GDK_dead_abovedot }, + { 0xf0a8, GDK_dead_diaeresis }, + { 0xf308, GDK_dead_diaeresis }, + { 0xf2da, GDK_dead_abovering }, + { 0xf30A, GDK_dead_abovering }, + { 0xf022, GDK_dead_doubleacute }, + { 0xf2dd, GDK_dead_doubleacute }, + { 0xf30B, GDK_dead_doubleacute }, + { 0xf2c7, GDK_dead_caron }, + { 0xf30C, GDK_dead_caron }, + { 0xf0be, GDK_dead_cedilla }, + { 0xf327, GDK_dead_cedilla }, + { 0xf2db, GDK_dead_ogonek }, + { 0xf328, GDK_dead_ogonek }, + { 0xfe5d, GDK_dead_iota }, + { 0xf323, GDK_dead_belowdot }, + { 0xf309, GDK_dead_hook }, + { 0xf31B, GDK_dead_horn }, + { 0xf02d, GDK_dead_stroke }, + { 0xf335, GDK_dead_stroke }, + { 0xf336, GDK_dead_stroke }, + { 0xf313, GDK_dead_abovecomma }, + /* { 0xf313, GDK_dead_psili }, */ + { 0xf314, GDK_dead_abovereversedcomma }, + /* { 0xf314, GDK_dead_dasia }, */ + { 0xf30F, GDK_dead_doublegrave }, + { 0xf325, GDK_dead_belowring }, + { 0xf2cd, GDK_dead_belowmacron }, + { 0xf331, GDK_dead_belowmacron }, + { 0xf32D, GDK_dead_belowcircumflex }, + { 0xf330, GDK_dead_belowtilde }, + { 0xf32E, GDK_dead_belowbreve }, + { 0xf324, GDK_dead_belowdiaeresis }, + { 0xf311, GDK_dead_invertedbreve }, + { 0xf02c, GDK_dead_belowcomma }, + { 0xf326, GDK_dead_belowcomma } +}; + +static void +update_keymap (void) +{ + const void *chr_data = NULL; + guint *p; + int i; + + /* Note: we could check only if building against the 10.5 SDK instead, but + * that would make non-xml layouts not work in 32-bit which would be a quite + * bad regression. This way, old unsupported layouts will just not work in + * 64-bit. + */ +#ifdef __LP64__ + TISInputSourceRef new_layout = TISCopyCurrentKeyboardLayoutInputSource (); + CFDataRef layout_data_ref; + +#else + KeyboardLayoutRef new_layout; + KeyboardLayoutKind layout_kind; + + KLGetCurrentKeyboardLayout (&new_layout); +#endif + + g_free (keyval_array); + keyval_array = g_new0 (guint, NUM_KEYCODES * KEYVALS_PER_KEYCODE); + +#ifdef __LP64__ + layout_data_ref = (CFDataRef) TISGetInputSourceProperty + (new_layout, kTISPropertyUnicodeKeyLayoutData); + + if (layout_data_ref) + chr_data = CFDataGetBytePtr (layout_data_ref); + + if (chr_data == NULL) + { + g_error ("cannot get keyboard layout data"); + return; + } +#else + /* Get the layout kind */ + KLGetKeyboardLayoutProperty (new_layout, kKLKind, (const void **)&layout_kind); + + /* 8-bit-only keyabord layout */ + if (layout_kind == kKLKCHRKind) + { + /* Get chr data */ + KLGetKeyboardLayoutProperty (new_layout, kKLKCHRData, (const void **)&chr_data); + + for (i = 0; i < NUM_KEYCODES; i++) + { + int j; + UInt32 modifiers[] = {0, shiftKey, optionKey, shiftKey | optionKey}; + + p = keyval_array + i * KEYVALS_PER_KEYCODE; + + for (j = 0; j < KEYVALS_PER_KEYCODE; j++) + { + UInt32 c, state = 0; + UInt16 key_code; + UniChar uc; + + key_code = modifiers[j] | i; + c = KeyTranslate (chr_data, key_code, &state); + + if (state != 0) + { + UInt32 state2 = 0; + c = KeyTranslate (chr_data, key_code | 128, &state2); + } + + if (c != 0 && c != 0x10) + { + int k; + gboolean found = FALSE; + + /* FIXME: some keyboard layouts (e.g. Russian) use a + * different 8-bit character set. We should check + * for this. Not a serious problem, because most + * (all?) of these layouts also have a uchr version. + */ + uc = macroman2ucs (c); + + for (k = 0; k < G_N_ELEMENTS (special_ucs_table); k++) + { + if (special_ucs_table[k].ucs_value == uc) + { + p[j] = special_ucs_table[k].keyval; + found = TRUE; + break; + } + } + + /* Special-case shift-tab since GTK+ expects + * GDK_ISO_Left_Tab for that. + */ + if (found && p[j] == GDK_Tab && modifiers[j] == shiftKey) + p[j] = GDK_ISO_Left_Tab; + + if (!found) + p[j] = gdk_unicode_to_keyval (uc); + } + } + + if (p[3] == p[2]) + p[3] = 0; + if (p[2] == p[1]) + p[2] = 0; + if (p[1] == p[0]) + p[1] = 0; + if (p[0] == p[2] && + p[1] == p[3]) + p[2] = p[3] = 0; + } + } + /* unicode keyboard layout */ + else if (layout_kind == kKLKCHRuchrKind || layout_kind == kKLuchrKind) + { + /* Get chr data */ + KLGetKeyboardLayoutProperty (new_layout, kKLuchrData, (const void **)&chr_data); +#endif + + for (i = 0; i < NUM_KEYCODES; i++) + { + int j; + UInt32 modifiers[] = {0, shiftKey, optionKey, shiftKey | optionKey}; + UniChar chars[4]; + UniCharCount nChars; + + p = keyval_array + i * KEYVALS_PER_KEYCODE; + + for (j = 0; j < KEYVALS_PER_KEYCODE; j++) + { + UInt32 state = 0; + OSStatus err; + UInt16 key_code; + UniChar uc; + + key_code = modifiers[j] | i; + err = UCKeyTranslate (chr_data, i, kUCKeyActionDisplay, + (modifiers[j] >> 8) & 0xFF, + LMGetKbdType(), + 0, + &state, 4, &nChars, chars); + + /* FIXME: Theoretically, we can get multiple UTF-16 + * values; we should convert them to proper unicode and + * figure out whether there are really keyboard layouts + * that give us more than one character for one + * keypress. + */ + if (err == noErr && nChars == 1) + { + int k; + gboolean found = FALSE; + + /* A few