Localize stripped down gtk2

This is intended mainly for GNU/Linux distros who will remove
GTK2 support in the near future.
This commit is contained in:
Robin Gareus
2023-12-13 06:45:00 +01:00
parent 2a928dae19
commit ad51c7c2ba
1528 changed files with 915658 additions and 57 deletions

2
.gitignore vendored
View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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':

View File

@@ -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'

View File

@@ -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']

View File

@@ -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')

View File

@@ -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')

View File

@@ -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'

View File

@@ -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'

View File

@@ -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'

View File

@@ -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'

View File

@@ -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'

View File

@@ -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'

View File

@@ -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'

View File

@@ -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'

View File

@@ -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'

View File

@@ -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'

View File

@@ -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'

View File

@@ -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'

View File

@@ -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'

View File

@@ -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'

View File

@@ -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'

View File

@@ -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'

View File

@@ -0,0 +1,439 @@
/*
Copyright 2011-2017 David Robillard <http://drobilla.net>
Copyright 2014 Robin Gareus <robin@gareus.org>
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 <gtk/gtk.h>
#include <gdk/gdkquartz.h>
#include <string.h>
#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"

78
libs/tk/suil/dylib.h Normal file
View File

@@ -0,0 +1,78 @@
/*
Copyright 2020 David Robillard <http://drobilla.net>
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 <windows.h>
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 <dlfcn.h>
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

98
libs/tk/suil/host.c Normal file
View File

@@ -0,0 +1,98 @@
/*
Copyright 2011-2017 David Robillard <http://drobilla.net>
Copyright 2017 Stefan Westerfeld <stefan@space.twc.de>
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 <stdlib.h>
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
}

409
libs/tk/suil/instance.c Normal file
View File

@@ -0,0 +1,409 @@
/*
Copyright 2007-2017 David Robillard <http://drobilla.net>
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 <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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;
}

299
libs/tk/suil/suil/suil.h Normal file
View File

@@ -0,0 +1,299 @@
/*
Copyright 2011-2017 David Robillard <http://drobilla.net>
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 <stdbool.h>
#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 <http://drobilla.net/software/suil> 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 */

View File

@@ -0,0 +1,2 @@
#pragma once
#define SUIL_VERSION "0.10.8"

View File

@@ -0,0 +1,175 @@
/*
Copyright 2007-2017 David Robillard <http://drobilla.net>
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 <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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

View File

@@ -0,0 +1,258 @@
/*
Copyright 2011-2015 David Robillard <http://drobilla.net>
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 <gtk/gtk.h>
#include <gdk/gdkwin32.h>
#ifndef WM_MOUSEWHEEL
# define WM_MOUSEWHEEL 0x020A
#endif
#ifndef WM_MOUSEHWHEEL
# define WM_MOUSEHWHEEL 0x020E
#endif
#include <string.h>
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"

83
libs/tk/suil/wscript Normal file
View File

@@ -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')

589
libs/tk/suil/x11_in_gtk2.c Normal file
View File

@@ -0,0 +1,589 @@
/*
Copyright 2011-2020 David Robillard <http://drobilla.net>
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 <X11/X.h>
#include <X11/Xatom.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <gdk/gdk.h>
#include <gdk/gdkx.h>
#include <glib-object.h>
#include <glib.h>
#include <gobject/gclosure.h>
#include <gtk/gtk.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
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;
}

View File

@@ -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 <strings.h> header file. */
#define HAVE_STRINGS_H 1
/* Define to 1 if you have the <string.h> 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 <unistd.h> 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 */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,125 @@
/* GdkPixbuf library - Image creation from in-memory buffers
*
* Copyright (C) 1999 The Free Software Foundation
*
* Author: Federico Mena-Quintero <federico@gimp.org>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include "gdk-pixbuf.h"
#include "gdk-pixbuf-private.h"
#include <stdlib.h>
#include <string.h>
/**
* 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);
}

View File

@@ -0,0 +1,97 @@
/* Generated data (by glib-mkenums) */
#include <gdk-pixbuf/gdk-pixbuf.h>
/* 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 */

File diff suppressed because it is too large Load Diff

View File

@@ -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 <crichton@gimp.org>
* Miguel de Icaza <miguel@gnu.org>
* Federico Mena-Quintero <federico@gimp.org>
* Jonathan Blandford <jrb@redhat.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <string.h>
#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;
}

View File

@@ -0,0 +1,133 @@
#include <glib-object.h>
#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) */

View File

@@ -0,0 +1,563 @@
/* GdkPixbuf library - Scaling and compositing functions
*
* Copyright (C) 1999 The Free Software Foundation
*
* Author: Owen Taylor <otaylor@redhat.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <math.h>
#include <string.h>
#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: <link linkend="gdk-GdkRGB">GdkRGB</link>.
*
* 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;
}

View File

@@ -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 <mclasen@redhat.com>
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#include <glib.h>
#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;
}

View File

@@ -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 <cinamod@hotmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*
* Based on code originally by:
* Jonathan Blandford <jrb@redhat.com>
* Havoc Pennington <hp@redhat.com>
*/
#include "config.h"
#include <glib.h>
#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;
}

View File

@@ -0,0 +1,392 @@
/* GdkPixbuf library - Utilities and miscellaneous convenience functions
*
* Copyright (C) 1999 The Free Software Foundation
*
* Authors: Federico Mena-Quintero <federico@gimp.org>
* Cody Russell <bratsche@gnome.org>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <string.h>
#include <libintl.h>
#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);
}

File diff suppressed because it is too large Load Diff

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include "gdk-pixbuf-private.h"
#include "gdk-pixdata.h"
#include <string.h>
/**
* 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 #GdkPixbuf<!-- -->s, 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);
}

View File

@@ -0,0 +1,190 @@
/* GdkPixdata loader
*
* Copyright (c) 2012 Alexander Larsson <alexl@redhat.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#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;
}

1122
libs/tk/ydk-pixbuf/io-png.c Normal file

File diff suppressed because it is too large Load Diff

504
libs/tk/ydk-pixbuf/io-xbm.c Normal file
View File

@@ -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 <crichton@gimp.org>
* Federico Mena-Quintero <federico@gimp.org>
* Jonathan Blandford <jrb@redhat.com>
* John Harper <jsh@eazel.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
/* Following code adapted from io-tiff.c, which was ``(almost) blatantly
ripped from Imlib'' */
#include "config.h"
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <stdio.h>
#include <errno.h>
#include "gdk-pixbuf-private.h"
#include <glib/gstdio.h>
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";
}

820
libs/tk/ydk-pixbuf/io-xpm.c Normal file
View File

@@ -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 <crichton@gimp.org>
* Federico Mena-Quintero <federico@gimp.org>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <glib.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h> /* for unlink */
#endif
#include <errno.h>
#include "gdk-pixbuf-private.h"
#include <glib/gstdio.h>
/* 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";
}

View File

@@ -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)

View File

@@ -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 <otaylor@redhat.com>
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.

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
.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

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
.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

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
.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

View File

@@ -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}

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
#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

File diff suppressed because it is too large Load Diff

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
#ifndef PIXOPS_H
#define PIXOPS_H
#include <glib.h>
/* 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

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
.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

Binary file not shown.

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <glib.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#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;
}

View File

@@ -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'

View File

@@ -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 <crichton@gimp.org>
* Miguel de Icaza <miguel@gnu.org>
* Federico Mena-Quintero <federico@gimp.org>
* Havoc Pennington <hp@redhat.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#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 <gdk-pixbuf/gdk-pixbuf.h> can be included directly."
#endif
#include <glib-object.h>
#include <gdk-pixbuf/gdk-pixbuf-core.h>
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 */

View File

@@ -0,0 +1,473 @@
/* GdkPixbuf library - GdkPixbuf data structure
*
* Copyright (C) 2003 The Free Software Foundation
*
* Authors: Mark Crichton <crichton@gimp.org>
* Miguel de Icaza <miguel@gnu.org>
* Federico Mena-Quintero <federico@gimp.org>
* Havoc Pennington <hp@redhat.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#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 <gdk-pixbuf/gdk-pixbuf.h> can be included directly."
#endif
#include <glib.h>
#include <glib-object.h>
#include <gio/gio.h>
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.
*
* |[<!-- language="C" -->
* 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 */

View File

@@ -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 <gdk-pixbuf/gdk-pixbuf.h> can be included directly."
#endif
#ifndef __GDK_PIXBUF_ENUM_TYPES_H__
#define __GDK_PIXBUF_ENUM_TYPES_H__
#include <glib-object.h>
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 */

View File

@@ -0,0 +1,120 @@
#if defined(GDK_PIXBUF_DISABLE_SINGLE_INCLUDES) && !defined (GDK_PIXBUF_H_INSIDE) && !defined (GDK_PIXBUF_COMPILATION)
#error "Only <gdk-pixbuf/gdk-pixbuf.h> can be included directly."
#endif
#ifndef GDK_PIXBUF_FEATURES_H
#define GDK_PIXBUF_FEATURES_H 1
#include <glib.h>
/**
* 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 */

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
#ifndef __GDKPIXBUFINTL_H__
#define __GDKPIXBUFINTL_H__
#include <glib.h>
#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

View File

@@ -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 <crichton@gimp.org>
* Miguel de Icaza <miguel@gnu.org>
* Federico Mena-Quintero <federico@gimp.org>
* Jonathan Blandford <jrb@redhat.com>
* Michael Fulbright <drmike@redhat.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#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 <gdk-pixbuf/gdk-pixbuf.h> can be included directly."
#endif
#include <stdio.h>
#include <glib.h>
#include <gmodule.h>
#include <gdk-pixbuf/gdk-pixbuf-core.h>
#include <gdk-pixbuf/gdk-pixbuf-animation.h>
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
* "<link linkend="GdkPixbufLoader-area-prepared">area_prepared</link>"
* 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
* "<link linkend="GdkPixbufLoader-area-updated">area_updated</link>"
* 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.
*
*
* <informalexample><programlisting>
* GdkPixbufModulePattern *signature[] = {
* { "abcdx", " !x z", 100 },
* { "bla", NULL, 90 },
* { NULL, NULL, 0 }
* };
* </programlisting>
* The example matches e.g. "auud\0" with relevance 100, and "blau" with
* relevance 90.</informalexample>
*
* 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 <function>fill_vtable</function>, 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 <function>gdk_pixbuf_format_*</function> 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 */

View File

@@ -0,0 +1,108 @@
/* GdkPixbuf library - Progressive loader object
*
* Copyright (C) 1999 The Free Software Foundation
*
* Authors: Mark Crichton <crichton@gimp.org>
* Miguel de Icaza <miguel@gnu.org>
* Federico Mena-Quintero <federico@gimp.org>
* Jonathan Blandford <jrb@redhat.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#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 <gdk-pixbuf/gdk-pixbuf.h> can be included directly."
#endif
#include <glib.h>
#include <glib-object.h>
#include <gdk-pixbuf/gdk-pixbuf-core.h>
#include <gdk-pixbuf/gdk-pixbuf-animation.h>
#include <gdk-pixbuf/gdk-pixbuf-io.h>
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

View File

@@ -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 <glib-object.h>
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 */

View File

@@ -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 <crichton@gimp.org>
* Miguel de Icaza <miguel@gnu.org>
* Federico Mena-Quintero <federico@gimp.org>
* Havoc Pennington <hp@redhat.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef GDK_PIXBUF_PRIVATE_H
#define GDK_PIXBUF_PRIVATE_H
#include <stdio.h>
#include <glib-object.h>
#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 */

View File

@@ -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 <mclasen@redhat.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef GDK_PIXBUF_SCALED_ANIM_H
#define GDK_PIXBUF_SCALED_ANIM_H
#include <gdk-pixbuf/gdk-pixbuf-animation.h>
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 */

View File

@@ -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 <cinamod@hotmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#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 <gdk-pixbuf/gdk-pixbuf.h> can be included directly."
#endif
#include <gdk-pixbuf/gdk-pixbuf-animation.h>
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 */

View File

@@ -0,0 +1,158 @@
/* GdkPixbuf library - transformations
*
* Copyright (C) 2003 The Free Software Foundation
*
* Authors: Mark Crichton <crichton@gimp.org>
* Miguel de Icaza <miguel@gnu.org>
* Federico Mena-Quintero <federico@gimp.org>
* Havoc Pennington <hp@redhat.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#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 <gdk-pixbuf/gdk-pixbuf.h> can be included directly."
#endif
#include <glib.h>
#include <gdk-pixbuf/gdk-pixbuf-core.h>
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.
*
* <note>
* Cubic filtering is missing from the list; hyperbolic
* interpolation is just as fast and results in higher quality.
* </note>
*/
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 */

View File

@@ -0,0 +1,43 @@
/* GdkPixbuf library - Main header file
*
* Copyright (C) 1999 The Free Software Foundation
*
* Authors: Mark Crichton <crichton@gimp.org>
* Miguel de Icaza <miguel@gnu.org>
* Federico Mena-Quintero <federico@gimp.org>
* Havoc Pennington <hp@redhat.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef GDK_PIXBUF_H
#define GDK_PIXBUF_H
#define GDK_PIXBUF_H_INSIDE
#include <glib.h>
#include <gdk-pixbuf/gdk-pixbuf-features.h>
#include <glib-object.h>
#include <gdk-pixbuf/gdk-pixbuf-core.h>
#include <gdk-pixbuf/gdk-pixbuf-transform.h>
#include <gdk-pixbuf/gdk-pixbuf-animation.h>
#include <gdk-pixbuf/gdk-pixbuf-simple-anim.h>
#include <gdk-pixbuf/gdk-pixbuf-io.h>
#include <gdk-pixbuf/gdk-pixbuf-loader.h>
#include <gdk-pixbuf/gdk-pixbuf-enum-types.h>
#undef GDK_PIXBUF_H_INSIDE
#endif /* GDK_PIXBUF_H */

View File

@@ -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 <http://www.gnu.org/licenses/>.
*/
#ifndef __GDK_PIXDATA_H__
#define __GDK_PIXDATA_H__
#include <gdk-pixbuf/gdk-pixbuf.h>
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 <function>*_ROWSTRIDE</function>,
* <function>*_WIDTH</function>, <function>*_HEIGHT</function>,
* <function>*_BYTES_PER_PIXEL</function> and
* <function>*_RLE_PIXEL_DATA</function> or <function>*_PIXEL_DATA</function>
* 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 <function>*_RUN_LENGTH_DECODE(image_buf, rle_data, size, bpp)</function>
* 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__ */

File diff suppressed because it is too large Load Diff

153
libs/tk/ydk/config.h Normal file
View File

@@ -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 <ftw.h> 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 <strings.h> header file. */
#define HAVE_STRINGS_H 1
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the <sys/param.h> 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 <unistd.h> 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 <X11/extensions/XIproto.h> 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 <sys/types.h> doesn't define. */
#define gid_t int
/* Define to `int' if <sys/types.h> doesn't define. */
#define uid_t int
#endif

838
libs/tk/ydk/gdk.c Normal file
View File

@@ -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 <string.h>
#include <stdlib.h>
#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)
* {
* /&ast; gdk_threads_enter(); would be needed for g_idle_add() &ast;/
*
* SomeWidget *self = data;
* /&ast; do stuff with self &ast;/
*
* self->idle_id = 0;
*
* /&ast; gdk_threads_leave(); would be needed for g_idle_add() &ast;/
* return FALSE;
* }
*
* static void
* some_widget_do_stuff_later (SomeWidget *self)
* {
* self->idle_id = gdk_threads_add_idle (idle_callback, self)
* /&ast; using g_idle_add() here would require thread protection in the callback &ast;/
* }
*
* 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;
*
* /&ast; do stuff with self &ast;/
*
* 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"

2918
libs/tk/ydk/gdkaliasdef.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -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 <alexl@redhat.com>
*/
#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
* <ulink url="http://www.freedesktop.org/Standards/wm-spec">Extended
* Window Manager Hints</ulink>.
*
* 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"

353
libs/tk/ydk/gdkcairo.c Normal file
View File

@@ -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><para>
* Note that due to double-buffering, Cairo contexts created
* in a GTK+ expose event handler cannot be cached and reused
* between different expose events.
* </para></note>
*
* 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"

398
libs/tk/ydk/gdkcolor.c Normal file
View File

@@ -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 <time.h>
#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
* <structfield>pixel</structfield> 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
* <structfield>pixel</structfield> 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
* <structfield>red</structfield>, <structfield>green</structfield>,
* and <structfield>blue</structfield> fields of a #GdkColor
* structure. The color is <emphasis>not</emphasis> 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
* <filename>rgb.txt</filename> file), or it can be a hex value in the
* form '&num;rgb' '&num;rrggbb' '&num;rrrgggbbb' or
* '&num;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 '&num;fff' '&num;ffffff' '&num;fffffffff' and
* '&num;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
* <literal>&num;rrrrggggbbbb</literal>, where <literal>r</literal>,
* <literal>g</literal> and <literal>b</literal> 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"

119
libs/tk/ydk/gdkcursor.c Normal file
View File

@@ -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"

1307
libs/tk/ydk/gdkdisplay.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -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
* <literal>gdk_display_manager_get_default_display (gdk_display_manager_get ())</literal>.
*
* 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"

212
libs/tk/ydk/gdkdnd.c Normal file
View File

@@ -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 <gdkdnd.h>
#include <gdkdrawable.h>
#include <gdkdisplay.h>
#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"

1979
libs/tk/ydk/gdkdraw.c Normal file

File diff suppressed because it is too large Load Diff

962
libs/tk/ydk/gdkenumtypes.c Normal file
View File

@@ -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 */

1412
libs/tk/ydk/gdkevents.c Normal file

File diff suppressed because it is too large Load Diff

359
libs/tk/ydk/gdkfont.c Normal file
View File

@@ -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"

1599
libs/tk/ydk/gdkgc.c Normal file

File diff suppressed because it is too large Load Diff

48
libs/tk/ydk/gdkglobals.c Normal file
View File

@@ -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 <stdio.h>
#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;

659
libs/tk/ydk/gdkimage.c Normal file
View File

@@ -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 <stdlib.h>
#include <sys/types.h>
#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"

133
libs/tk/ydk/gdkkeynames.c Normal file
View File

@@ -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 <glib/gprintf.h>
#include <stdlib.h>
#include <string.h>
#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
* <filename>&lt;gdk/gdkkeysyms.h&gt;</filename> 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
* <filename>&lt;gdk/gdkkeysyms.h&gt;</filename> 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"

316
libs/tk/ydk/gdkkeys.c Normal file
View File

@@ -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"

1713
libs/tk/ydk/gdkkeyuni.c Normal file

File diff suppressed because it is too large Load Diff

208
libs/tk/ydk/gdkmarshalers.c Normal file
View File

@@ -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 <glib-object.h>
#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);
}

Some files were not shown because too many files have changed in this diff Show More