diff --git a/.gitignore b/.gitignore
index 1521e83e..bb211efd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,6 +9,7 @@
._*
*.rl
*.log
+*.lib
.byebug_history
Makefile
VERSION.txt
@@ -28,12 +29,14 @@ notes
/win7
/mavericks
/xmavericks
-snowleopard
-xsnow
/msys2
+/xmsys2
/pi2
+/qtifw
*.app
req/binject
req/bloopsaphone
req/json
/qtifw
+*.orig
+cshoes
diff --git a/CHANGELOG b/CHANGELOG
index 3d4655c7..0af04d36 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -3,16 +3,73 @@
from the internet. He went walkabout! We changed some icons and backgrounds
to relect that whimsical theme.
- Walkabout (3.3) will be less compatible with the unmaintained 3.1 and with 4.0 (jRuby)
+ Walkabout (3.3+) will be less compatible with the unmaintained 3.1 and with 4.0 (jRuby)
We have interesting ideas of we what we do with Shoes that may be difficult
to immplememt in Shoes 4.
+
+-------------- Shoes 3.3.4 ---------------------------------
+
+=== New with 3.3.4
+ * Uses Ruby 2.3.4 (2.3.3 on Windows) and Rubygems 2.6.12+
+ https://github.com/Shoes3/shoes3/issues/361 and
+ https://github.com/Shoes3/shoes3/issues/270
+ * New widget! - systray sends tiny status messages to the
+ host OS desktop.
+ https://github.com/Shoes3/shoes3/issues/363
+ * New platform - freebsd 11.1 (64). Can build, run, install and package for.
+ https://github.com/Shoes3/shoes3/issues/365
+ * Dead platform - 32 bit i686 (Linux intel) target is no longer supported
+ * libcurl.dll/dylib/so and new gems are included with Shoes. require 'typhoeus'
+ to use it. When net/http and open_uri is too confusing, arcane and limiting.
+ On Windows it's not faster (or slower) - just better in other ways.
+ see https://github.com/typhoeus/typhoeus
+ * Method app.resize can progromaticly expand the window.
+ see https://github.com/Shoes3/shoes3/issues/370
+=== Fixed with 3.3.4
+ * When Shoes is installed on a system with existing rvm/rbenv it
+ might use the wrong set of gems.
+ * Fixed some SSL issues for download and image (Windows).
+ Ruby/Windows (net/http) ssl problems remain unfixed.
+ * Improved Windows downloading speed - still sub-par but better than
+ before.
+
+=== Developer issues with 3.3.4
+ * rake does a better job of dealing with changes in lib/shoes/*.rb, static/manual-en.txt
+ and changes in samples/*/*.rb. You can change these without a full rebuild.
+ https://github.com/Shoes3/shoes3/issues/362
+ * new freebsd target (loose and tight shoes)
+
-------------- Shoes 3.3.3 ---------------------------------
+
=== New with 3.3.3
- * can specify your own title for ask_open_file andfriends
+ * Ruby 2.2.7 and RubyGems 2.6.10 (Windows is Ruby 2.2.6)
+ * can specify your own title for ask_open_file and similar file dialogs
https://github.com/Shoes3/shoes3/issues/282
- * new target 'msys2' for windows builds - very experimental
- * Shoes uses a new text search engine - 'picky' which added these gems into
+ * new manual search engine - see below.
+ * tooltips for native widgets (not all widgets for all platforms)
+ review the Manual for how to use.
+ https://github.com/Shoes3/shoes3/issues/340
+ * new widget - Switch - kind of like checkbox but different.
+ Read the manual and run the examples within.
+ * new widget Spinner
+ Read the manual and run the examples within.
+ * related side project, exe-shoes updated. Has a gui to guide you in
+ configuring your Shoes is hidden, Windows 10 happy, app installer.
+ see https://github.com/Shoes3/exe-shoes
+ * Shoes includes the ffi-1.9.18 native gem which many gems prefer over
+ Ruby's 'fiddle' - both are included. Less need for users to deal with
+ compiling problems.
+ https://github.com/Shoes3/shoes3/issues/352
+ * new samples added
+ https://github.com/Shoes3/shoes3/issues/317
+ * background can take a `scroll: true' so it scrolls as many expect.
+
+=== developer issues with 3.3.3
+ * new target 'msys2' for windows builds. Work in progress.
+ prebuilt dependcies for msys2 has newer Gtk 3.14.15
+ NOT ready for prime time.
+ * Shoes manual has a new text search engine - 'picky' which added these gems into
shoes:
activesupport
concurrent-ruby
@@ -24,21 +81,46 @@
tzinfo
url_escape
yajl-ruby
- Which means you can use them in your scripts if you like to push the
- envelope.
+ see https://github.com/Shoes3/shoes3/issues/320
+ * Chipmunk and Sqlite are now real gems, maintained by others. Shoes
+ no longer has exts nor the pseudo gems: ftsearch, chipmunk, sqlite3, hpricot.
+ Newer sqlite3 & chipmunk gems are included as real gems.
+ ** Major restucturing of C source code.
+ Less monolithic, more files but smaller files.
+ https://github.com/Shoes3/shoes3/issues/333
+ * rake files cleaned up and much faster if you are developing at the C level.
+ https://github.com/Shoes3/shoes3/issues/334
+ * cleanup - remove unused code and old comments. Ongoing, of course.
+ https://github.com/Shoes3/shoes3/issues/251
+ * samples and files are renamed to better fit a 'cleanup'
=== Fixed with 3.3.3
- * redirects of http to https - common now a days WIP
+ * OSX retina display should work. Finder->Show Info displays accurate info
+ https://github.com/Shoes3/shoes3/issues/310
+ * Restored Windows Theme (for Windows) - slows initialization slightly.
+ https://github.com/Shoes3/shoes3/issues/345
+ * redirects of http to https - common now a days.
https://github.com/Shoes3/shoes3/issues/304
* allow some Shoes built in dialogs like ask, confirm, ...
to be used before Shoes.app is called.
https://github.com/Shoes3/shoes3/issues/303
- * gifs working on Windows again?
+ * gifs are working on Windows again
https://github.com/Shoes3/shoes3/issues/306
+ * improve the manual
+ https://github.com/Shoes3/shoes3/issues/317
+ * plots/charts draw more reliably.
+ issue: https://github.com/Shoes3/shoes3/issues/315
+ * background doesn't scroll as expected
+ issues: https://github.com/Shoes3/shoes3/issues/2
+ https://github.com/Shoes3/shoes3/issues/38
+ https://github.com/Shoes3/shoes3/issues/355
+ new feaure.
+ * moved samples/classbook.* to samples/good/_why-stories.*
+ * Manual disply of samples (Furthermore->Sample) now
+ explicitly ordered from simple to good to expert.
+ * fix samples/simple/sqlites3.rb to work better on windows
+ and use UTF-8
-=== developer issues
- * clean up github - remove many
-
-------------- Shoes 3.3.2 ----------------------------------
=== New with 3.3.2
diff --git a/README.md b/README.md
index f2dcf1b2..09143a34 100644
--- a/README.md
+++ b/README.md
@@ -31,7 +31,7 @@ compatible with Shoes 4.
* Video widgets work again. Dependent on all kinds of thing Shoes can't
control.
-Shoes 3.3.2 - Not released yet, but [beta's exist](http://walkabout.mvmanila.com/public/shoes/)
+Shoes 3.3.4 - Not released yet, but [beta's exist](http://walkabout.mvmanila.com/public/shoes/)
Remember, no one is happy if the Shoes don't fit so [report your bug.](https://github.com/Shoes3/shoes3/issues)
diff --git a/Rakefile b/Rakefile
index b823647f..9de4dba0 100644
--- a/Rakefile
+++ b/Rakefile
@@ -1,7 +1,6 @@
require 'rubygems'
require 'rake'
require 'rake/clean'
-# require_relative 'platform/skel'
require 'fileutils'
require 'find'
require 'yaml'
@@ -17,11 +16,11 @@ APP['MINOR'] = APP['minor'].to_s
APP['TINY'] = APP['tiny'].to_s
APP['NAME'] = APP['release']
APP['DATE'] = Time.now.to_s
-APP['PLATFORM'] = RbConfig::CONFIG['arch'] # not correct in cross compile
+APP['PLATFORM'] = RbConfig::CONFIG['arch'] # not correct for cross compile
case APP['revision']
when 'git'
- GIT = ENV['GIT'] || "git"
- APP['REVISION'] = (`#{GIT} rev-list HEAD`.split.length).to_s
+ gitp = ENV['GIT'] || "git"
+ APP['REVISION'] = (`#{gitp} rev-list HEAD`.split.length).to_s
when 'file'
File.open('VERSION.txt', 'r') do |f|
ln = f.read
@@ -42,57 +41,84 @@ APPNAME = APP['name'] # OSX needs this
SONAME = 'shoes'
APPARGS = APP['run']
+# TODO: Shadow these until replaced with APP[] in env/setup/tasks files
RUBY_SO = RbConfig::CONFIG['RUBY_SO_NAME']
+APP['RUBY_SO'] = RbConfig::CONFIG['RUBY_SO_NAME']
RUBY_V = RbConfig::CONFIG['ruby_version']
+APP['RUBY_V'] = RbConfig::CONFIG['ruby_version']
SHOES_RUBY_ARCH = RbConfig::CONFIG['arch']
+APP['SHOES_RUBY_ARCH'] = RbConfig::CONFIG['arch']
# default exts, gems & locations to build and include - replace with custom.yaml
-APP['GEMLOC'] = File.expand_path('req')
-APP['EXTLOC'] = File.expand_path('req')
-APP['EXTLIST'] = ['chipmunk']
-APP['GEMLIST'] = ['sqlite3']
-
-if File.exists? "crosscompile"
+APP['GEMLOC'] = ""
+APP['EXTLOC'] = ""
+APP['EXTLIST'] = []
+APP['GEMLIST'] = []
+APP['Bld_Tmp'] = 'tmp'
+APP['Bld_Pre'] = ENV['NFS_ALTP'] if ENV['NFS_ALTP']
+
+if File.exists? "build_target"
CROSS = true
- File.open('crosscompile','r') do |f|
+ File.open('build_target','r') do |f|
str = f.readline
TGT_ARCH = str.split('=')[1].strip
- if ENV['NFS_ALTP']
- TGT_DIR = ENV['NFS_ALTP']+TGT_ARCH
- mkdir_p "#{TGT_DIR}"
+ # is the build output directory outside the shoes3 dir
+ if APP['Bld_Pre']
+ TGT_DIR = APP['Bld_Pre']+TGT_ARCH
else
TGT_DIR = TGT_ARCH
end
+ mkdir_p "#{TGT_DIR}"
+ BLD_ARGS = {}
+ # This allows short circuiting the need to load setup and env (and pkg-config overhead)
+ # Exprimental - no visible performance gain. see make/linux/minlin/env.rb
+ if File.exists? "#{TGT_DIR}/build.yaml"
+ $stderr.puts "loading building args"
+ thsh = YAML.load_file("#{TGT_DIR}/build.yaml")
+ thsh.each {|k,v| BLD_ARGS[k] = v}
+ HAVE_BLD = true
+ else
+ HAVE_BLD = false
+ end
end
else
CROSS = false
- # is the build directory outside the project dir like
- # Cecil's weird NFS setup for his mac
- if ENV['NFS_ALTP']
- TGT_DIR = ENV['NFS_ALTP']+'dist'
- mkdir_p "#{TGT_DIR}"
- else
- TGT_DIR = 'dist'
+ if ARGV.length == 0 # bare rake w/o a setup called earlier
+ plt = case RUBY_PLATFORM
+ when /darwin/ then 'osx'
+ when /mingw/ then 'win32'
+ when /linux/ then 'linux'
+ when /freebsd/ then 'bsd'
+ end
+ $stderr.puts "Please Select a #{plt}:setup: target from the"
+ $stderr.puts " list shown by 'rake -T'"
end
+ TGT_DIR = 'unknown'
end
+
BIN = "*.{bundle,jar,o,so,obj,pdb,pch,res,lib,def,exp,exe,ilk}"
#CLEAN.include ["{bin,shoes}/#{BIN}", "req/**/#{BIN}", "#{TGT_DIR}", "*.app"]
-CLEAN.include ["req/**/#{BIN}", "#{TGT_DIR}", "*.app"]
+#CLEAN.include ["req/**/#{BIN}", "#{TGT_DIR}", "*.app"]
+CLEAN.include ["#{TGT_DIR}/libshoes.dll", "#{TGT_DIR}/*shoes.exe",
+ "#{TGT_DIR}/libshoes.so","#{TGT_DIR}/shoes", "#{TGT_DIR}/shoes-bin",
+ "#{TGT_DIR}/*.app", "#{TGT_DIR}/#{APP['Bld_tmp']}/**/*.o"]
+CLOBBER.include ["#{TGT_DIR}/.DS_Store", "#{TGT_DIR}", "build_target", "cshoes", "shoes/**/*.o"]
-# for Host building for Host:
+# for Host building for target
case RUBY_PLATFORM
when /mingw/
if CROSS
require File.expand_path("make/win32/#{TGT_ARCH}/env")
require File.expand_path("make/win32/#{TGT_ARCH}/tasks")
require File.expand_path("make/win32/#{TGT_ARCH}/stubs")
+ require File.expand_path("make/win32/#{TGT_ARCH}/setup")
require File.expand_path("make/gems")
+ require File.expand_path('make/subsys')
else
- require File.expand_path('make/win32/loose/env.rb')
- require File.expand_path('make/win32/loose/tasks.rb')
- puts "PLEASE SELECT a build environment from the win32 options "
- puts" shown from a a `rake -T` "
+ # just enough to do a rake w/o target
+ require File.expand_path('make/win32/none/env.rb')
+ require File.expand_path('make/win32/none/tasks.rb')
end
Builder = MakeMinGW
NAMESPACE = :win32
@@ -103,52 +129,113 @@ when /darwin/
require File.expand_path("make/darwin/#{TGT_ARCH}/env")
require File.expand_path("make/darwin/#{TGT_ARCH}/tasks")
require File.expand_path("make/darwin/#{TGT_ARCH}/stubs")
+ require File.expand_path("make/darwin/#{TGT_ARCH}/setup")
require File.expand_path("make/gems")
+ require File.expand_path("make/subsys")
else
- # build Loose Shoes on OSX for OSX
- puts "OSX: please select a target - see rake -T"
- puts "This Shoes may not be portable to other OSX systems"
- require File.expand_path('make/darwin/loose/env')
- require File.expand_path('make/darwin/loose/tasks')
+ # just enough to do a rake w/o target
+ require File.expand_path('make/darwin/none/env')
+ require File.expand_path('make/darwin/none/tasks')
end
Builder = MakeDarwin
NAMESPACE = :osx
+when /bsd/
+ #$stderr.puts "running BSD"
+ if CROSS
+ case TGT_ARCH
+ when /freebsd/
+ require File.expand_path('make/bsd/freebsd/env')
+ require File.expand_path('make/bsd/freebsd/tasks')
+ require File.expand_path('make/bsd/freebsd/setup')
+ require File.expand_path("make/gems")
+ require File.expand_path('make/subsys')
+ when /minbsd/
+ require File.expand_path('make/bsd/minbsd/env')
+ require File.expand_path('make/bsd/minbsd/tasks')
+ require File.expand_path('make/bsd/minbsd/setup')
+ require File.expand_path('make/subsys')
+ else
+ require File.expand_path('make/bsd/none/env')
+ require File.expand_path('make/bsd/none/tasks')
+ end
+ else
+ require File.expand_path('make/bsd/none/env')
+ require File.expand_path('make/bsd/none/tasks')
+ $stderr.puts "Please pick a bsd:setup: target - see rake -T"
+ end
+ Builder = MakeBSD
+ NAMESPACE = :bsd
+
when /linux/
if CROSS
- # This will be a Tight Shoes setup
case TGT_ARCH
when /x86_64-linux/
require File.expand_path('make/linux/x86_64-linux/env')
require File.expand_path('make/linux/x86_64-linux/tasks')
+ require File.expand_path('make/linux/x86_64-linux/setup')
require File.expand_path("make/gems")
+ require File.expand_path('make/subsys')
when /i686-linux/
require File.expand_path('make/linux/i686-linux/env')
require File.expand_path('make/linux/i686-linux/tasks')
+ require File.expand_path('make/linux/i686-linux/setup')
require File.expand_path("make/gems")
+ require File.expand_path('make/subsys')
when /pi2/
require File.expand_path('make/linux/pi2/env')
require File.expand_path('make/linux/pi2/tasks')
+ require File.expand_path('make/linux/pi2/setup')
require File.expand_path("make/gems")
+ require File.expand_path('make/subsys')
when /xarmv6hf/
require File.expand_path('make/linux/xarm6hf/env')
require File.expand_path('make/linux/xarm6hf/tasks')
require File.expand_path('make/gems')
- when /xwin7/
+ when /xwin7/
require File.expand_path('make/linux/xwin7/env')
require File.expand_path('make/linux/xwin7/tasks')
require File.expand_path('make/linux/xwin7/stubs')
+ require File.expand_path('make/linux/xwin7/setup')
require File.expand_path('make/linux/xwin7/packdeps')
require File.expand_path('make/gems')
+ require File.expand_path('make/subsys')
+ when /xmsys2/
+ require File.expand_path('make/linux/xmsys2/env')
+ require File.expand_path('make/linux/xmsys2/tasks')
+ require File.expand_path('make/linux/xmsys2/stubs')
+ require File.expand_path('make/linux/xmsys2/packdeps')
+ require File.expand_path('make/linux/xmsys2/setup')
+ require File.expand_path('make/gems')
+ require File.expand_path('make/subsys')
+ when /minlin/
+ # This is Loose Shoes setup now known as minlin
+ if CROSS && HAVE_BLD # shortcut
+ puts "skipping #{TGT_ARCH} env.rb, setup.rb"
+ require File.expand_path('make/linux/minlin/tasks')
+ require File.expand_path('make/subsys')
+ DLEXT = BLD_ARGS['DLEXT']
+ CC = BLD_ARGS['CC']
+ SOLOCS = BLD_ARGS['SOLOCS']
+ LINUX_CFLAGS = BLD_ARGS['LINUX_CFLAGS']
+ LINUX_LDFLAGS = BLD_ARGS['LINUX_LDFLAGS']
+ LINUX_LIBS = BLD_ARGS['LINUX_LIBS']
+ else
+ #puts "Require All minlin:"
+ require File.expand_path('make/linux/minlin/env')
+ require File.expand_path('make/linux/minlin/tasks')
+ require File.expand_path('make/linux/minlin/setup')
+ require File.expand_path('make/subsys')
+ end
else
- puts "Unknown builder for #{TGT_ARCH}, removing setting"
- rm_rf "crosscompile" if File.exists? "crosscompile"
+ $stderr.puts "Unknown builder for #{TGT_ARCH}, removing setting"
+ rm_rf "build_target" if File.exists? "build_target"
end
else
- # This is Loose Shoes setup
- #TGT_DIR = "dist"
- require File.expand_path('make/linux/loose/env')
- require File.expand_path('make/linux/loose/tasks')
+ # just enough to do a rake w/o target - will fail with a decent enough
+ # error message
+ require File.expand_path('make/linux/none/env')
+ require File.expand_path('make/linux/none/tasks')
end
Builder = MakeLinux
NAMESPACE = :linux
@@ -165,10 +252,12 @@ task :default => [:build]
desc "Package Shoes for distribution"
task :package => [:version, :installer]
-task :build_os => [:build_skel, "#{TGT_DIR}/#{NAME}"]
+task :build_os => ["#{TGT_DIR}/#{NAME}"]
task "shoes/version.h" do |t|
File.open(t.name, 'w') do |f|
+ f << "#ifndef SHOES_VERSION_H\n"
+ f << "#define SHOES_VERSION_H\n\n"
f << "// compatatibily pre 3.2.22\n"
f << "#define SHOES_RELEASE_ID #{APP['MAJOR']}\n"
f << "#define SHOES_REVISION #{APP['REVISION']}\n"
@@ -184,15 +273,18 @@ task "shoes/version.h" do |t|
f << "#define SHOES_VERSION_REVISION #{APP['REVISION']}\n"
f << "#define SHOES_VERSION_DATE \"#{APP['DATE']}\"\n"
f << "#define SHOES_VERSION_PLATFORM \"#{APP['PLATFORM']}\"\n"
- if CROSS
- f << '#define SHOES_STYLE "TIGHT_SHOES"'
+ if CROSS && (!TGT_DIR[/minlin/] && !TGT_DIR[/minbsd/])
+ f << "#define SHOES_STYLE \"TIGHT_SHOES\"\n\n"
else
- f << '#define SHOES_STYLE "LOOSE_SHOES"'
+ f << "#define SHOES_STYLE \"LOOSE_SHOES\"\n\n"
end
+ f << "extern VALUE cTypes;\n"
+ f << "\nvoid shoes_version_init();\n\n"
+ f << "#endif\n"
end
end
-# FIXME: Left for historical reasons (aka OSX)
+# TODO: Left for historical reasons (aka OSX)
task "#{TGT_DIR}/VERSION.txt" do |t|
File.open(t.name, 'w') do |f|
f << %{shoes #{RELEASE_NAME.downcase} (0.r#{REVISION}) [#{SHOES_RUBY_ARCH} Ruby#{RUBY_V}]}
@@ -201,6 +293,25 @@ task "#{TGT_DIR}/VERSION.txt" do |t|
end
end
+#TODO: should the following be a task or file?
+file "shoes/types/types.h" do |t|
+ puts "Processing #{t.name}..."
+
+ rm_rf "shoes/types/types.h" if File.exists? "shoes/types/types.h"
+
+ headers = Dir["shoes/types/*.h"] - ["shoes/types/types.h"]
+ content = headers.collect { |file|
+ File.read(file).scan(/shoes_[[:alnum:]_]+_init\(\);/)
+ }.flatten
+
+ File.open(t.name, 'w') do |f|
+ headers.sort.each { |header|
+ f << "#include \"#{header}\"\n"
+ }
+ f << "\n#define SHOES_TYPES_INIT \\\n#{content.sort.collect { |n| "\t#{n}" }.join(" \\\n") }\n"
+ end
+end
+
def create_version_file file_path
File.open(file_path, 'w') do |f|
f << "shoes #{APP['NAME'].downcase} #{APP['VERSION']} r(#{APP['REVISION']}) #{APP['PLATFORM']} #{APP['DATE']}"
@@ -208,7 +319,7 @@ def create_version_file file_path
end
end
-# FIXME: called from osx(s) copy_files_to_dist in task.rb
+# TODO: called from osx(s) copy_files_to_dist in task.rb
def osx_version_txt t
create_version_file t
end
@@ -218,41 +329,6 @@ task :version do
create_version_file 'VERSION.txt'
end
-# shoes is small, if any include changes, go ahead and build from scratch.
-SRC.zip(OBJ).each do |c, o|
- file o => [c] + Dir["shoes/*.h"]
-end
-
-# ------
-# skel
-
-def skel_replace(line)
- line.gsub! /\s+%DEFAULTS%/ do
- if APPARGS
- args = APPARGS.split(/\s+/)
- %{
- char *default_argv[] = {argv[0], #{args.inspect[1..-2]}};
- argv = default_argv;
- argc = #{args.length + 1};
- }
- end
- end
- line
-end
-
-# preprocess .skel
-task :build_skel do |t|
- Dir["bin/*.skel"].each do |src|
- name = src.gsub(/\.skel$/, '.c')
- File.open(src) do |skel|
- File.open(name, 'w') do |c|
- skel.each_line do |line|
- c << skel_replace(line)
- end
- end
- end
- end
-end
# --------------------------
# tasks depending on Builder = MakeLinux|MakeDarwin|MakeMinGW
@@ -260,27 +336,55 @@ end
desc "Build using your OS setup"
task :build => ["#{NAMESPACE}:build"]
-task :pre_build do
- Builder.pre_build
-end
-# first refactor ; build calls platform namespaced build;
-# for now, each of those calls the old build method.
-task :old_build => [:pre_build, :build_os] do
- Builder.common_build
- Builder.copy_files_to_dist
- Builder.copy_deps_to_dist
+# ------ new build --------
+rtp = "#{TGT_DIR}/#{APP['Bld_Tmp']}"
+file "#{rtp}/zzsetup.done" do
+ Builder.static_setup SOLOCS
+ Builder.copy_gems #used to be common_build, located in make/gems.rb
Builder.setup_system_resources
+ touch "#{rtp}/zzsetup.done"
+ $stderr.puts "Build Products in #{rtp}"
+end
+
+#These tasks create object files:
+SubDirs = ["#{rtp}/zzbase.done", "#{rtp}/http/zzdownload.done",
+ "#{rtp}/plot/zzplot.done", "#{rtp}/console/zzconsole.done",
+ "#{rtp}/types/zzwidgets.done", "#{rtp}/native/zznative.done"]
+
+# Windows doesn't use console - don't try to build it. Delete from dependcies
+case TGT_DIR
+ when /win7/, /xwin7/, /msys2/, /xmsys2/
+ SubDirs.delete("#{rtp}/console/zzconsole.done")
+end
+
+# These tasks copy updated Shoes lib/*/*.rb files and samples and the manual
+StaticDirs = ["#{rtp}/copyonly/zzmanual.done", "#{rtp}/copyonly/zzshoesrb.done",
+ "#{rtp}/copyonly/zzshoesrblib.done", "#{rtp}/copyonly/zzsimple.done",
+ "#{rtp}/copyonly/zzgood.done", "#{rtp}/copyonly/zzexpert.done"]
+
+file "#{TGT_DIR}/libshoes.#{DLEXT}" => ["#{rtp}/zzsetup.done", "shoes/types/types.h",
+ "shoes/version.h"] + SubDirs + StaticDirs do
+ # need to compile version.c -> .o (and create the verion.h for every build)
+ sh "#{CC} -o #{rtp}/version.o -I. -c #{LINUX_CFLAGS} shoes/version.c"
+ Builder.new_so "#{TGT_DIR}/libshoes.#{DLEXT}"
+end
+
+# rake build (or just rake) will get here.
+task :new_build => "#{TGT_DIR}/libshoes.#{DLEXT}" do
+ # We can link shoes now - this will be done via a Builder call
+ # because it's platform specific.
+ Builder.new_link "#{TGT_DIR}/shoes"
end
-desc "Install Shoes in your ~/.shoes Directory"
+desc "Not Recommended! Install min Shoes in your ~/.shoes Directory"
task :install do
- if CROSS
- puts "Sorry. You can't do an install of your source built Shoes"
- puts "when crosscompiling is setup."
+ if ! (TGT_DIR[/minlin/] || TGT_DIR[/minbsd/])
+ puts "Sorry. You can't do an install of your source built Tight Shoes"
+ puts " Install the 'rake package' distro just like a user does."
else
- create_version_file 'VERSION.txt'
- Builder.copy_files_to_dist
+ create_version_file "#{TGT_DIR}/VERSION.txt"
+ #Builder.copy_files_to_dist
Builder.make_userinstall
end
end
@@ -288,11 +392,8 @@ end
directory "#{TGT_DIR}" # was 'dist'
-task "#{TGT_DIR}/#{NAME}" => ["#{TGT_DIR}/lib#{SONAME}.#{DLEXT}", "bin/main.o"] + ADD_DLL + ["#{NAMESPACE}:make_app"]
-
-task "#{TGT_DIR}/lib#{SONAME}.#{DLEXT}" => ['shoes/version.h', "#{TGT_DIR}"] + OBJ + ["#{NAMESPACE}:make_so"]
-
def cc(t)
+ $stderr.puts "compiling #{t}"
sh "#{CC} -I. -c -o #{t.name} #{LINUX_CFLAGS} #{t.source}"
end
@@ -306,168 +407,132 @@ end
task :installer => ["#{NAMESPACE}:installer"]
-def rewrite before, after, reg = /\#\{(\w+)\}/, reg2 = '\1'
- File.open(after, 'w') do |a|
- File.open(before) do |b|
- b.each do |line|
- a << line.gsub(reg) do
- if reg2.include? '\1'
- reg2.gsub(%r!\\1!, Object.const_get($1))
- else
- reg2
- end
- end
- end
- end
- end
-end
-
-def copy_files glob, dir
- FileList[glob].each { |f| cp_r f, dir }
-end
-
namespace :osx do
namespace :setup do
- desc "Setup to build Shoes for 10.10+"
- task :yosemite do
- sh "echo 'TGT_ARCH=yosemite' >crosscompile"
- end
+ #desc "Setup to build Shoes for 10.10+"
+ #task :yosemite do
+ # sh "echo 'TGT_ARCH=yosemite' >build_target"
+ #end
desc "Setup to build Shoes for 10.9+ from 10.10+"
task :xmavericks do
- sh "echo 'TGT_ARCH=xmavericks' >crosscompile"
+ sh "echo 'TGT_ARCH=xmavericks' >build_target"
end
- desc "Setup to build Shoes for 10.9+ from 10.9"
- task :mavericks do
- sh "echo 'TGT_ARCH=mavericks' >crosscompile"
- end
+ #desc "Setup to build Shoes for 10.9+ from 10.9"
+ #task :mavericks do
+ # sh "echo 'TGT_ARCH=mavericks' >build_target"
+ #end
#desc "Setup to build for 10.6+ from 10.6"
#task :snow do
- # sh "echo 'TGT_ARCH=snow' >crosscompile"
+ # sh "echo 'TGT_ARCH=snow' >build_target"
#end
#desc "Downshift Build 10.6 from 10.9"
#task "xsnow" do
- # sh "echo 'TGT_ARCH=xsnow' >crosscompile"
+ # sh "echo 'TGT_ARCH=xsnow' >build_target"
#end
- desc "restore build my current system"
- task :clean do
- rm_rf "crosscompile"
- end
end
- task :build => [:old_build]
-
- task :make_app do
- Builder.make_app "#{TGT_DIR}/#{NAME}"
- end
-
- task :make_so do
- Builder.make_so "#{TGT_DIR}/lib#{SONAME}.#{DLEXT}"
- end
+ task :build => [:new_build]
task :installer do
Builder.make_installer
end
-
end
-
namespace :win32 do
namespace :setup do
desc "Winodws build with devkit"
task :win7 do
- sh "echo TGT_ARCH=win7 >crosscompile"
+ sh "echo TGT_ARCH=win7 >build_target"
end
desc "Windows build with msys2"
task :msys2 do
- sh "echo TGT_ARCH=msys2 >crosscompile"
- end
-
- desc "remove win32 setup"
- task :clean do
- puts "restored to Loose Shoes build"
- rm_rf "crosscompile" if File.exists? "crosscompile"
- end
-
+ sh "echo TGT_ARCH=msys2 >build_target"
+ end
end
- task :build => [:old_build]
+ task :build => ["build_target", :new_build]
- task :make_app do
- Builder.make_app "#{TGT_DIR}/#{NAME}"
+ task :installer do
+ Builder.make_installer
end
+end
+
+namespace :bsd do
- task :make_so do
- Builder.make_so "#{TGT_DIR}/lib#{SONAME}.#{DLEXT}"
+ namespace :setup do
+ desc "freebsd 11.1 x86_64"
+ task :freebsd do
+ sh "echo 'TGT_ARCH=freebsd' >build_target"
+ end
+
+ desc "freebsd minimal"
+ task :minbsd do
+ sh "echo 'TGT_ARCH=minbsd' >build_target"
+ end
end
+ task :build => ["build_target", :new_build]
task :installer do
Builder.make_installer
- end
+ end
end
# get here when rake decides it's running on a linux system
namespace :linux do
namespace :setup do
- desc "Cross compile to arm6hf - advanced users"
+ desc "build non-portable linux"
+ task :minlin do
+ sh "echo 'TGT_ARCH=minlin' >build_target"
+ end
+
+ #desc "Cross compile to arm6hf - advanced users"
task :xarm6hf do
- sh "echo 'TGT_ARCH=xarmv6hf' >crosscompile"
+ sh "echo 'TGT_ARCH=xarmv6hf' >build_target"
end
- desc "Native pi2 build"
+ desc "Native arm build - pi 2+"
task :pi2 do
- sh "echo 'TGT_ARCH=pi2' >crosscompile"
+ sh "echo 'TGT_ARCH=pi2' >build_target"
+ end
+
+ #desc "Cross compile for msys2 deps (mingw)"
+ task :xmsys2 do
+ puts "Cross compile newer deps (mingw)"
+ sh "echo 'TGT_ARCH=xmsys2' >build_target"
end
- desc "Cross compile to MingW32 (Gtk, 32)"
+ desc "Cross compile with MingW32"
task :xwin7 do
puts "Cross compile for Windows MingW32"
- sh "echo 'TGT_ARCH=xwin7' >crosscompile"
+ sh "echo 'TGT_ARCH=xwin7' >build_target"
end
desc "chroot build for i686 (32bit linux)"
task :i686_linux do
puts "Cross complile for i686-linux"
- sh "echo 'TGT_ARCH=i686-linux' >crosscompile"
+ sh "echo 'TGT_ARCH=i686-linux' >build_target"
end
desc "chroot build for x86_64 (64bit linux)"
task :x86_64_linux do
puts "Cross complile for x86_64-linux"
- sh "echo 'TGT_ARCH=x86_64-linux' >crosscompile"
+ sh "echo 'TGT_ARCH=x86_64-linux' >build_target"
end
- desc "Remove linux compile setup"
- task :clean do
- puts "restored to native build"
- rm_rf "crosscompile" if File.exists? "crosscompile"
- end
- end
-
- task :build => [:old_build]
-
- task :make_app do
- Builder.make_app "#{TGT_DIR}/#{NAME}"
- end
-
- task :make_so do
- Builder.make_so "#{TGT_DIR}/lib#{SONAME}.#{DLEXT}"
end
+
+ task :build => [:new_build]
task :installer do
Builder.make_installer
end
end
-
-# Note the following works: Not pretty but it works
-#task "#{TGT_DIR}/libshoes.so" do
-# Builder.make_so "#{TGT_DIR}/lib#{SONAME}.#{DLEXT}"
-#end
diff --git a/Tests/curl/bare.rb b/Tests/curl/bare.rb
new file mode 100644
index 00000000..235379be
--- /dev/null
+++ b/Tests/curl/bare.rb
@@ -0,0 +1,34 @@
+Shoes.app do
+ background "#eee"
+ @list = stack do
+ para "Enter a URL to download:", :margin => [10, 8, 10, 0]
+ flow :margin => 10 do
+ @url = edit_line :width => -120
+ #@url.text ='http://walkabout.mvmanila.com/public/share/test-csv.tgz'
+ @url.text ='http://walkabout.mvmanila.com/public/share/Ytm-2.exe'
+ st_time = 0
+ end_time = 0
+ totalsz = 0
+ button "Download", :width => 120 do
+ st_time = Time.now
+ @list.append do
+ stack do
+ background "#eee".."#ccd"
+ stack :margin => 10 do
+ dld = nil
+ para @url.text, " [", link("cancel") { dld.abort }, "]", :margin => 0
+ d = inscription "Beginning transfer.", :margin => 0
+ dld = download @url.text, :save => File.basename(@url.text),
+ :finish => proc { |dl|
+ end_time = Time.now
+ secs = (end_time.to_i - st_time.to_i)
+ kb = dl.length < 1024 ? 1: dl.length / 1024
+ d.text = "Download completed KB/s: #{kb/secs} secs: #{secs}"
+ }
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/Tests/curl/downloader.rb b/Tests/curl/downloader.rb
new file mode 100644
index 00000000..350347c4
--- /dev/null
+++ b/Tests/curl/downloader.rb
@@ -0,0 +1,40 @@
+Shoes.app do
+ background "#eee"
+ @list = stack do
+ para "Enter a URL to download:", :margin => [10, 8, 10, 0]
+ flow :margin => 10 do
+ @url = edit_line :width => -120
+ @url.text ='http://walkabout.mvmanila.com/public/share/Ytm-2.exe'
+ st_time = 0
+ end_time = 0
+ totalsz = 0
+ button "Download", :width => 120 do
+ st_time = Time.now
+ @list.append do
+ stack do
+ background "#eee".."#ccd"
+ stack :margin => 10 do
+ dld = nil
+ para @url.text, " [", link("cancel") { @dld.abort }, "]", :margin => 0
+ d = inscription "Beginning transfer.", :margin => 0
+ p = progress :width => 1.0, :height => 14
+ @dld = download @url.text, :save => File.basename(@url.text),
+ :pause => 0.02,
+ :progress => proc { |dl|
+ d.text = "Transferred #{dl.transferred} of #{dl.length} bytes (#{dl.percent.to_s[0..6]}%)"
+ p.fraction = dl.percent
+ },
+ :finish => proc { |dl|
+ end_time = Time.now
+ secs = (end_time.to_i - st_time.to_i)
+ kb = dl.length < 1024 ? 1: dl.length / 1024
+ d.text = "Download completed KB/s: #{kb/secs} seconds:#{secs}"
+ }
+ para "Should appear after button press"
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/Tests/curl/m1.rb b/Tests/curl/m1.rb
new file mode 100644
index 00000000..63b947c1
--- /dev/null
+++ b/Tests/curl/m1.rb
@@ -0,0 +1,11 @@
+ Shoes.app do
+ stack do
+ title "Searching Google", :size => 16
+ @status = para "One moment..."
+
+ # Search Google for 'shoes' and print the HTTP headers
+ download "http://www.google.com/search?q=shoes" do |goog|
+ @status.text = "Headers: " + goog.response.headers.inspect
+ end
+ end
+ end
diff --git a/Tests/curl/m2.rb b/Tests/curl/m2.rb
new file mode 100644
index 00000000..520dd6a7
--- /dev/null
+++ b/Tests/curl/m2.rb
@@ -0,0 +1,12 @@
+ Shoes.app do
+ stack do
+ title "Downloading Google image", :size => 16
+ @status = para "One moment..."
+
+ download "http://www.google.com/logos/nasa50th.gif",
+ :save => "nasa50th.gif" do
+ @status.text = "Okay, is downloaded."
+ end
+ end
+ end
+
diff --git a/Tests/curl/m3.rb b/Tests/curl/m3.rb
new file mode 100644
index 00000000..e33b2ed4
--- /dev/null
+++ b/Tests/curl/m3.rb
@@ -0,0 +1,11 @@
+ Shoes.app do
+ stack do
+ title "GET Google", :size => 16
+ @status = para "One moment..."
+
+ download "http://www.google.com/search?q=shoes",
+ :method => "GET" do |dump|
+ @status.text = dump.response.body
+ end
+ end
+ end
diff --git a/Tests/curl/m4.rb b/Tests/curl/m4.rb
new file mode 100644
index 00000000..931e167e
--- /dev/null
+++ b/Tests/curl/m4.rb
@@ -0,0 +1,5 @@
+ Shoes.app do
+ button "Red Shoes" do
+ image "http://shoesrb.com/img/shoes-icon.png"
+ end
+ end
diff --git a/Tests/curl/typ.rb b/Tests/curl/typ.rb
new file mode 100644
index 00000000..ff1ee612
--- /dev/null
+++ b/Tests/curl/typ.rb
@@ -0,0 +1,30 @@
+require 'typhoeus'
+Shoes.app do
+ button "typheous" do
+ st_time = Time.now
+ filesz = 0
+ downloaded_file = File.open 'huge.iso', 'wb'
+ @th = Thread.new do
+ request = Typhoeus::Request.new("http://walkabout.mvmanila.com/public/share/Ytm-2.exe")
+ request.on_headers do |response|
+ if response.code != 200
+ raise "Request failed"
+ end
+ puts "length #{response.headers['Content-Length']}"
+ filesz = response.headers['Content-Length'].to_i
+ end
+ request.on_body do |chunk|
+ $stdout.puts "."
+ downloaded_file.write(chunk)
+ end
+ request.on_complete do |response|
+ downloaded_file.close
+ end_time = Time.now
+ elapsed = end_time.to_i - st_time.to_i
+ $stderr.puts "Finished in #{elapsed} secs #{(filesz/1024)/elapsed} KB/s"
+ @th.join
+ end
+ request.run
+ end
+ end
+end
diff --git a/Tests/decoration.rb b/Tests/decoration.rb
new file mode 100644
index 00000000..4fbc7129
--- /dev/null
+++ b/Tests/decoration.rb
@@ -0,0 +1,14 @@
+Shoes.app do
+ stack do
+ para "Test decorations - title bar, resize controls"
+ button "remove" do
+ app.decorated = false
+ @p.text = app.decorated? ? "True" : "False"
+ end
+ button "restore" do
+ app.decorated = true
+ @p.text = app.decorated? ? "True" : "False"
+ end
+ @p = para "True"
+ end
+end
diff --git a/Tests/opacity.rb b/Tests/opacity.rb
new file mode 100644
index 00000000..03586857
--- /dev/null
+++ b/Tests/opacity.rb
@@ -0,0 +1,13 @@
+Shoes.app do
+ stack do
+ para "Click the button to reduce opacity to %90"
+ button "reduce" do
+ app.opacity = 0.90
+ para "Opacity is #{app.opacity}\n"
+ end
+ button "normal" do
+ app.opacity = 1.0
+ para "normal\n"
+ end
+ end
+end
diff --git a/Tests/spinner.rb b/Tests/spinner.rb
new file mode 100644
index 00000000..3c788ec9
--- /dev/null
+++ b/Tests/spinner.rb
@@ -0,0 +1,15 @@
+Shoes.app do
+ flow do
+ @n = spinner
+ @m = spinner
+ @o = spinner start: true
+ end
+
+ click do |btn, left, top|
+ @m.started? ? @m.stop : @m.start
+ end
+
+ start do
+ @n.start
+ end
+end
diff --git a/Tests/switch.rb b/Tests/switch.rb
new file mode 100644
index 00000000..d041fbb3
--- /dev/null
+++ b/Tests/switch.rb
@@ -0,0 +1,28 @@
+Shoes.app do
+ flow do
+ switch; para
+ end
+
+ flow do
+ @n = switch(active: true) do
+ @p.text = (@n.active? ? "true": "false") unless @p.nil?
+ end
+ @p = para
+ end
+
+ flow do
+ @m = switch width: 80
+ @m.click do
+ #$stderr.puts "Click"
+ @m.active? ? @e.start : @e.stop
+ end
+ @e = every(1) { |count| @q.text = count unless @q.nil? & @m.active? }
+ @q = para ""
+ end
+
+ start do
+ @e.stop
+ @p.text = @n.active? ? "true" : "false"
+ @m.active = false
+ end
+end
diff --git a/Tests/systray/back.rb b/Tests/systray/back.rb
new file mode 100644
index 00000000..87e7dbd5
--- /dev/null
+++ b/Tests/systray/back.rb
@@ -0,0 +1,20 @@
+Shoes.app do
+ stack do
+ para "Generate 10 systray calls - 30 seconds appart."
+ para "Press button to start and cover the app window with another app"
+ ctr = 0;
+ button "Notify" do
+ @ev = every 30 do
+ ctr += 1
+ icp = ''
+ if ctr % 3 != 0
+ icp = "#{DIR}/static/shoes-icon.png"
+ else
+ icp = "#{DIR}/static/shoes-icon-red.png"
+ end
+ systray title: "Shoes Notify Test", message: "message ##{ctr}", icon: icp
+ @ev.stop if ctr >= 10
+ end
+ end
+ end
+end
diff --git a/Tests/systray/note.rb b/Tests/systray/note.rb
new file mode 100644
index 00000000..9b273b17
--- /dev/null
+++ b/Tests/systray/note.rb
@@ -0,0 +1,16 @@
+Shoes.app do
+ stack do
+ para "Press button and look in your system's notification area"
+ ctr = 0;
+ button "Notify" do
+ ctr += 1
+ icp = ''
+ if ctr % 3 != 0
+ icp = "#{DIR}/static/shoes-icon.png"
+ else
+ icp = "#{DIR}/static/shoes-icon-red.png"
+ end
+ systray title: "Shoes Notify Test", message: "message ##{ctr}", icon: icp
+ end
+ end
+end
diff --git a/Tests/tooltips.rb b/Tests/tooltips.rb
new file mode 100644
index 00000000..8c1d9312
--- /dev/null
+++ b/Tests/tooltips.rb
@@ -0,0 +1,20 @@
+Shoes.app do
+ para "Do we have a button tooltip?"
+ @btn = button "Quit", tooltip: "kill Shoes" do
+ Shoes.quit
+ end
+ flow do
+ @chk = check tooltip: "check button will do something"
+ para "watch"
+ end
+ @eb = edit_box tooltip: "enter something"
+ @el = edit_line tooltip: "something you type into"
+ @lb = list_box tooltip: "pull it"
+ start do
+ @btn.tooltip = "This will will exit shoes properly"
+ @chk.tooltip = "This will alter reality"
+ @eb.tooltip = "Something different"
+ @el.tooltip = "you type here"
+ @lb.tooltip = "Pick a card, any card"
+ end
+end
diff --git a/app.yaml b/app.yaml
index 45a2ba79..8d133361 100644
--- a/app.yaml
+++ b/app.yaml
@@ -1,7 +1,7 @@
name: Shoes
major: 3
minor: 3
-tiny: 3
+tiny: 4
release: walkabout
revision: git
icons:
diff --git a/bugs/bug038.rb b/bugs/bug038.rb
index 4005f342..a6dff485 100644
--- a/bugs/bug038.rb
+++ b/bugs/bug038.rb
@@ -1,7 +1,7 @@
Shoes.app {
stack(:top => 20) {
[black, blue, red, green].each { |n|
- stack(:height => 80) { background n }
+ stack(:height => 80) { background n, scroll: true }
stack(:height => 80) {}
}
}
diff --git a/bugs/bug179.rb b/bugs/bug179.rb
new file mode 100644
index 00000000..11ab3914
--- /dev/null
+++ b/bugs/bug179.rb
@@ -0,0 +1,43 @@
+Shoes.app width: 600, height: 500 do
+ stack do
+ para "Quick fun"
+ flow do
+ button "Button", font: "Menlo Bold 14",width: 200, stroke: red,
+ tooltip: "Menlo Bold 14" do
+ para "menlo bold button"
+ end
+ button "icon", width: 80, height: 30, icon: "#{DIR}/static/icon-info.png",
+ tooltip: "info button" do
+ end
+ end
+ para "What is normal?"
+ flow do
+ button "Normal", tooltip: "Normal" do para "normal 1" end
+ button "Normal", tooltip: "Arial 12", font: "Arial 12" do para "normal 2./csh " end
+ end
+ para "try some font names"
+ flow do
+ button "Curry", font: "Courier New Italic 12",
+ tooltip: "Courier New Italic 12" do end
+ button "Short", font: "Monaco 17", tooltip: "Monaco 17" do end
+ end
+ para "testing icon/title interactions"
+ flow do
+ button "left", width: 80, icon: "#{DIR}/static/icon-info.png",
+ titlepos: "left", tooltip: "title left" do
+ end
+ button "only icon", width: 80, icon: "#{DIR}/static/icon-info.png",
+ titlepos: "none", tooltip: "just icon" do
+ end
+ button "above", width: 80, height: 120, icon: "#{DIR}/static/icon-info.png",
+ titlepos: "top" do
+ para "above button pressed"
+ end
+ end
+ para "testing defaults and fail - open console"
+ flow do
+ button "Fail 1", font: "Monaco" do end
+ button "Fail 2", tooltip: "unknown font", font: "missing font 12" do end
+ end
+ end
+end
diff --git a/bugs/bug329.rb b/bugs/bug329.rb
new file mode 100644
index 00000000..b20479d8
--- /dev/null
+++ b/bugs/bug329.rb
@@ -0,0 +1,25 @@
+Shoes.app do
+ stack do
+ @p = para
+ end
+
+ stack(left: self.width / 4, top: 10) do
+ button("hello")
+ flow { check; para "check?" }
+ edit_box
+ edit_line
+ list_box :items => ["one", "two", "three"]
+ progress
+ stack do
+ radio; para strong("one")
+ radio; para strong("two")
+ end
+ slider
+ spinner
+ switch
+ end
+
+ click do |btn, left, top|
+ @p.text = "click: #{btn}, #{left}, #{top}\n"
+ end
+end
diff --git a/bugs/bug355.rb b/bugs/bug355.rb
new file mode 100644
index 00000000..daa55ef1
--- /dev/null
+++ b/bugs/bug355.rb
@@ -0,0 +1,9 @@
+Shoes.app(title: " v1.0", width: 300, height: 500, resizable: true ) do
+ background green
+ @main = stack left: 0.05, top: 0.15, width: 0.9, height: 0.8, scroll: true do
+ background beige, scroll: true
+ 100.times do |i|
+ para "#{i+1} times"
+ end
+ end
+end
diff --git a/bugs/bug359.rb b/bugs/bug359.rb
new file mode 100644
index 00000000..f36ed6f9
--- /dev/null
+++ b/bugs/bug359.rb
@@ -0,0 +1,14 @@
+Shoes.app do
+ @my_stack = stack do
+ background yellow
+ para 'number 1'
+ para 'number 2'
+ para 'number 3'
+ para 'number 4'
+ para 'number 5'
+ end
+# before(@my_stack.contents[2] ) do
+ @my_stack.before(@my_stack.contents[2] ) do
+ para 'number 1.5'
+ end
+end
diff --git a/bugs/bug370.rb b/bugs/bug370.rb
new file mode 100644
index 00000000..1c7626a8
--- /dev/null
+++ b/bugs/bug370.rb
@@ -0,0 +1,26 @@
+MAXWIDTH = 1600
+MAXHEIGHT = 900
+
+Shoes.app(width: 300, height: 100) do
+ @width, @height = app.width, app.height
+ stack margin: 10 do
+ flow do
+ slider fraction: (@width / MAXWIDTH.to_f) do |s|
+ @width = (s.fraction * MAXWIDTH)
+ end
+ para "width", margin_left: 10
+ end
+ flow do
+ slider fraction: (@height / MAXHEIGHT.to_f) do |s|
+ @height = (s.fraction * MAXHEIGHT)
+ end
+ para "height", margin_left: 10
+ end
+ end
+
+ animate(24) do
+ if ((app.width != @width) or (app.height != @height))
+ app.resize @width, @height
+ end
+ end
+end
diff --git a/gtk3.22.15-deprecations.txt b/gtk3.22.15-deprecations.txt
new file mode 100644
index 00000000..5385bc66
--- /dev/null
+++ b/gtk3.22.15-deprecations.txt
@@ -0,0 +1,352 @@
+rake
+mkdir -p /usr/home/ccoupe/build/freebsd
+setup: dir=/usr/home/ccoupe/Projects/shoes3
+copy_gems dir=/usr/home/ccoupe/Projects/shoes3 x86_64-linux
+Copying prebuilt gem /usr/home/ccoupe/gems/rb23/built/freebsd/chipmunk-6.1.3.4
+Lib copy = lib
+Copying prebuilt gem /usr/home/ccoupe/gems/rb23/built/freebsd/sqlite3-1.3.13
+Lib copy = lib
+Copying prebuilt gem /usr/home/ccoupe/gems/rb23/built/freebsd/mini_portile2-2.2.0
+Lib copy = lib
+Copying prebuilt gem /usr/home/ccoupe/gems/rb23/built/freebsd/nokogiri-1.8.0
+Lib copy = lib
+Copying prebuilt gem /usr/home/ccoupe/gems/rb23/built/freebsd/rb-readline-0.5.4
+Lib copy = lib
+Copying prebuilt gem /usr/home/ccoupe/gems/rb23/built/freebsd/byebug-9.1.0
+Lib copy = lib
+Copying prebuilt gem /usr/home/ccoupe/gems/rb23/built/freebsd/ffi-1.9.18
+Lib copy = lib
+Copying prebuilt gem /usr/home/ccoupe/gems/rb23/built/freebsd/activesupport-5.1.3
+Lib copy = lib
+Copying prebuilt gem /usr/home/ccoupe/gems/rb23/built/freebsd/concurrent-ruby-1.0.5
+Lib copy = lib
+Copying prebuilt gem /usr/home/ccoupe/gems/rb23/built/freebsd/i18n-0.8.6
+Lib copy = lib
+Copying prebuilt gem /usr/home/ccoupe/gems/rb23/built/freebsd/multi_json-1.12.1
+Lib copy = lib
+Copying prebuilt gem /usr/home/ccoupe/gems/rb23/built/freebsd/picky-4.31.3
+Lib copy = lib
+Copying prebuilt gem /usr/home/ccoupe/gems/rb23/built/freebsd/rack_fast_escape-2009.06.24
+Lib copy = lib
+Copying prebuilt gem /usr/home/ccoupe/gems/rb23/built/freebsd/thread_safe-0.3.6
+Lib copy = lib
+Copying prebuilt gem /usr/home/ccoupe/gems/rb23/built/freebsd/tzinfo-1.2.3
+Lib copy = lib
+Copying prebuilt gem /usr/home/ccoupe/gems/rb23/built/freebsd/url_escape-2009.06.24
+Ext weird copy = ["/opt/lib/ruby/gems/2.3.0/extensions/x86_64-freebsd-11/2.3.0/url_escape-2009.06.24", "ext"]
+Copying prebuilt gem /usr/home/ccoupe/gems/rb23/built/freebsd/yajl-ruby-1.3.0
+Lib copy = lib
+Copying prebuilt gem /usr/home/ccoupe/gems/rb23/built/freebsd/ethon-0.10.1
+Lib copy = lib
+Copying prebuilt gem /usr/home/ccoupe/gems/rb23/built/freebsd/typhoeus-1.1.2
+Lib copy = lib
+touch /usr/home/ccoupe/build/freebsd/tmp/zzsetup.done
+Build Products in /usr/home/ccoupe/build/freebsd/tmp
+cc -o /usr/home/ccoupe/build/freebsd/tmp/app.o -I. -c -g -O0 -DRUBY_HTTP -DBSD -DSHOES_GTK -fPIC -Wno-unused-variable -I/usr/include -I/opt/include/ruby-2.3.0/x86_64-freebsd11.1 -I/opt/include/ruby-2.3.0 -I/usr/local/include/gtk-3.0 -I/usr/local/include/pango-1.0 -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -I/usr/local/include -I/usr/local/include/cairo -I/usr/local/include/pixman-1 -I/usr/local/include/freetype2 -I/usr/local/include/libdrm -I/usr/local/include/libpng16 -I/usr/local/include/harfbuzz -I/usr/local/include/gdk-pixbuf-2.0 -I/usr/local/include/gio-unix-2.0/ -I/usr/local/include/atk-1.0 -D_THREAD_SAFE -I/usr/local/include/at-spi2-atk/2.0 -I/usr/local/include/at-spi-2.0 -I/usr/local/include/dbus-1.0 -I/usr/local/lib/dbus-1.0/include -pthread -I/usr/include/ -I/usr/local/include/librsvg-2.0/librsvg shoes/app.c
+cc -o /usr/home/ccoupe/build/freebsd/tmp/canvas.o -I. -c -g -O0 -DRUBY_HTTP -DBSD -DSHOES_GTK -fPIC -Wno-unused-variable -I/usr/include -I/opt/include/ruby-2.3.0/x86_64-freebsd11.1 -I/opt/include/ruby-2.3.0 -I/usr/local/include/gtk-3.0 -I/usr/local/include/pango-1.0 -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -I/usr/local/include -I/usr/local/include/cairo -I/usr/local/include/pixman-1 -I/usr/local/include/freetype2 -I/usr/local/include/libdrm -I/usr/local/include/libpng16 -I/usr/local/include/harfbuzz -I/usr/local/include/gdk-pixbuf-2.0 -I/usr/local/include/gio-unix-2.0/ -I/usr/local/include/atk-1.0 -D_THREAD_SAFE -I/usr/local/include/at-spi2-atk/2.0 -I/usr/local/include/at-spi-2.0 -I/usr/local/include/dbus-1.0 -I/usr/local/lib/dbus-1.0/include -pthread -I/usr/include/ -I/usr/local/include/librsvg-2.0/librsvg shoes/canvas.c
+cc -o /usr/home/ccoupe/build/freebsd/tmp/image.o -I. -c -g -O0 -DRUBY_HTTP -DBSD -DSHOES_GTK -fPIC -Wno-unused-variable -I/usr/include -I/opt/include/ruby-2.3.0/x86_64-freebsd11.1 -I/opt/include/ruby-2.3.0 -I/usr/local/include/gtk-3.0 -I/usr/local/include/pango-1.0 -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -I/usr/local/include -I/usr/local/include/cairo -I/usr/local/include/pixman-1 -I/usr/local/include/freetype2 -I/usr/local/include/libdrm -I/usr/local/include/libpng16 -I/usr/local/include/harfbuzz -I/usr/local/include/gdk-pixbuf-2.0 -I/usr/local/include/gio-unix-2.0/ -I/usr/local/include/atk-1.0 -D_THREAD_SAFE -I/usr/local/include/at-spi2-atk/2.0 -I/usr/local/include/at-spi-2.0 -I/usr/local/include/dbus-1.0 -I/usr/local/lib/dbus-1.0/include -pthread -I/usr/include/ -I/usr/local/include/librsvg-2.0/librsvg shoes/image.c
+cc -o /usr/home/ccoupe/build/freebsd/tmp/internal.o -I. -c -g -O0 -DRUBY_HTTP -DBSD -DSHOES_GTK -fPIC -Wno-unused-variable -I/usr/include -I/opt/include/ruby-2.3.0/x86_64-freebsd11.1 -I/opt/include/ruby-2.3.0 -I/usr/local/include/gtk-3.0 -I/usr/local/include/pango-1.0 -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -I/usr/local/include -I/usr/local/include/cairo -I/usr/local/include/pixman-1 -I/usr/local/include/freetype2 -I/usr/local/include/libdrm -I/usr/local/include/libpng16 -I/usr/local/include/harfbuzz -I/usr/local/include/gdk-pixbuf-2.0 -I/usr/local/include/gio-unix-2.0/ -I/usr/local/include/atk-1.0 -D_THREAD_SAFE -I/usr/local/include/at-spi2-atk/2.0 -I/usr/local/include/at-spi-2.0 -I/usr/local/include/dbus-1.0 -I/usr/local/lib/dbus-1.0/include -pthread -I/usr/include/ -I/usr/local/include/librsvg-2.0/librsvg shoes/internal.c
+cc -o /usr/home/ccoupe/build/freebsd/tmp/main.o -I. -c -g -O0 -DRUBY_HTTP -DBSD -DSHOES_GTK -fPIC -Wno-unused-variable -I/usr/include -I/opt/include/ruby-2.3.0/x86_64-freebsd11.1 -I/opt/include/ruby-2.3.0 -I/usr/local/include/gtk-3.0 -I/usr/local/include/pango-1.0 -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -I/usr/local/include -I/usr/local/include/cairo -I/usr/local/include/pixman-1 -I/usr/local/include/freetype2 -I/usr/local/include/libdrm -I/usr/local/include/libpng16 -I/usr/local/include/harfbuzz -I/usr/local/include/gdk-pixbuf-2.0 -I/usr/local/include/gio-unix-2.0/ -I/usr/local/include/atk-1.0 -D_THREAD_SAFE -I/usr/local/include/at-spi2-atk/2.0 -I/usr/local/include/at-spi-2.0 -I/usr/local/include/dbus-1.0 -I/usr/local/lib/dbus-1.0/include -pthread -I/usr/include/ -I/usr/local/include/librsvg-2.0/librsvg shoes/main.c
+cc -o /usr/home/ccoupe/build/freebsd/tmp/ruby.o -I. -c -g -O0 -DRUBY_HTTP -DBSD -DSHOES_GTK -fPIC -Wno-unused-variable -I/usr/include -I/opt/include/ruby-2.3.0/x86_64-freebsd11.1 -I/opt/include/ruby-2.3.0 -I/usr/local/include/gtk-3.0 -I/usr/local/include/pango-1.0 -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -I/usr/local/include -I/usr/local/include/cairo -I/usr/local/include/pixman-1 -I/usr/local/include/freetype2 -I/usr/local/include/libdrm -I/usr/local/include/libpng16 -I/usr/local/include/harfbuzz -I/usr/local/include/gdk-pixbuf-2.0 -I/usr/local/include/gio-unix-2.0/ -I/usr/local/include/atk-1.0 -D_THREAD_SAFE -I/usr/local/include/at-spi2-atk/2.0 -I/usr/local/include/at-spi-2.0 -I/usr/local/include/dbus-1.0 -I/usr/local/lib/dbus-1.0/include -pthread -I/usr/include/ -I/usr/local/include/librsvg-2.0/librsvg shoes/ruby.c
+shoes/ruby.c:865:5: warning: implicit declaration of function
+ 'shoes_systray_init' is invalid in C99 [-Wimplicit-function-declaration]
+ SHOES_TYPES_INIT;
+ ^
+./shoes/types/types.h:48:3: note: expanded from macro 'SHOES_TYPES_INIT'
+ shoes_systray_init(); \
+ ^
+1 warning generated.
+cc -o /usr/home/ccoupe/build/freebsd/tmp/version.o -I. -c -g -O0 -DRUBY_HTTP -DBSD -DSHOES_GTK -fPIC -Wno-unused-variable -I/usr/include -I/opt/include/ruby-2.3.0/x86_64-freebsd11.1 -I/opt/include/ruby-2.3.0 -I/usr/local/include/gtk-3.0 -I/usr/local/include/pango-1.0 -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -I/usr/local/include -I/usr/local/include/cairo -I/usr/local/include/pixman-1 -I/usr/local/include/freetype2 -I/usr/local/include/libdrm -I/usr/local/include/libpng16 -I/usr/local/include/harfbuzz -I/usr/local/include/gdk-pixbuf-2.0 -I/usr/local/include/gio-unix-2.0/ -I/usr/local/include/atk-1.0 -D_THREAD_SAFE -I/usr/local/include/at-spi2-atk/2.0 -I/usr/local/include/at-spi-2.0 -I/usr/local/include/dbus-1.0 -I/usr/local/lib/dbus-1.0/include -pthread -I/usr/include/ -I/usr/local/include/librsvg-2.0/librsvg shoes/version.c
+cc -o /usr/home/ccoupe/build/freebsd/tmp/world.o -I. -c -g -O0 -DRUBY_HTTP -DBSD -DSHOES_GTK -fPIC -Wno-unused-variable -I/usr/include -I/opt/include/ruby-2.3.0/x86_64-freebsd11.1 -I/opt/include/ruby-2.3.0 -I/usr/local/include/gtk-3.0 -I/usr/local/include/pango-1.0 -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -I/usr/local/include -I/usr/local/include/cairo -I/usr/local/include/pixman-1 -I/usr/local/include/freetype2 -I/usr/local/include/libdrm -I/usr/local/include/libpng16 -I/usr/local/include/harfbuzz -I/usr/local/include/gdk-pixbuf-2.0 -I/usr/local/include/gio-unix-2.0/ -I/usr/local/include/atk-1.0 -D_THREAD_SAFE -I/usr/local/include/at-spi2-atk/2.0 -I/usr/local/include/at-spi-2.0 -I/usr/local/include/dbus-1.0 -I/usr/local/lib/dbus-1.0/include -pthread -I/usr/include/ -I/usr/local/include/librsvg-2.0/librsvg shoes/world.c
+shoes/world.c:90:25: warning: incompatible pointer types passing 'int **' to
+ parameter of type 'char ***' [-Wincompatible-pointer-types]
+ ruby_sysinit(&zedc, &zeda);
+ ^~~~~
+/opt/include/ruby-2.3.0/ruby/ruby.h:2166:38: note: passing argument to parameter
+ 'argv' here
+void ruby_sysinit(int *argc, char ***argv);
+ ^
+1 warning generated.
+touch /usr/home/ccoupe/build/freebsd/tmp/zzbase.done
+compiling /usr/home/ccoupe/build/freebsd/tmp/http/rbload.o
+cc -I. -c -o /usr/home/ccoupe/build/freebsd/tmp/http/rbload.o -g -O0 -DRUBY_HTTP -DBSD -DSHOES_GTK -fPIC -Wno-unused-variable -I/usr/include -I/opt/include/ruby-2.3.0/x86_64-freebsd11.1 -I/opt/include/ruby-2.3.0 -I/usr/local/include/gtk-3.0 -I/usr/local/include/pango-1.0 -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -I/usr/local/include -I/usr/local/include/cairo -I/usr/local/include/pixman-1 -I/usr/local/include/freetype2 -I/usr/local/include/libdrm -I/usr/local/include/libpng16 -I/usr/local/include/harfbuzz -I/usr/local/include/gdk-pixbuf-2.0 -I/usr/local/include/gio-unix-2.0/ -I/usr/local/include/atk-1.0 -D_THREAD_SAFE -I/usr/local/include/at-spi2-atk/2.0 -I/usr/local/include/at-spi-2.0 -I/usr/local/include/dbus-1.0 -I/usr/local/lib/dbus-1.0/include -pthread -I/usr/include/ -I/usr/local/include/librsvg-2.0/librsvg shoes/http/rbload.c
+touch /usr/home/ccoupe/build/freebsd/tmp/http/zzdownload.done
+cc -o /usr/home/ccoupe/build/freebsd/tmp/plot/chart_series.o -I. -c -g -O0 -DRUBY_HTTP -DBSD -DSHOES_GTK -fPIC -Wno-unused-variable -I/usr/include -I/opt/include/ruby-2.3.0/x86_64-freebsd11.1 -I/opt/include/ruby-2.3.0 -I/usr/local/include/gtk-3.0 -I/usr/local/include/pango-1.0 -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -I/usr/local/include -I/usr/local/include/cairo -I/usr/local/include/pixman-1 -I/usr/local/include/freetype2 -I/usr/local/include/libdrm -I/usr/local/include/libpng16 -I/usr/local/include/harfbuzz -I/usr/local/include/gdk-pixbuf-2.0 -I/usr/local/include/gio-unix-2.0/ -I/usr/local/include/atk-1.0 -D_THREAD_SAFE -I/usr/local/include/at-spi2-atk/2.0 -I/usr/local/include/at-spi-2.0 -I/usr/local/include/dbus-1.0 -I/usr/local/lib/dbus-1.0/include -pthread -I/usr/include/ -I/usr/local/include/librsvg-2.0/librsvg shoes/plot/chart_series.c
+cc -o /usr/home/ccoupe/build/freebsd/tmp/plot/plot.o -I. -c -g -O0 -DRUBY_HTTP -DBSD -DSHOES_GTK -fPIC -Wno-unused-variable -I/usr/include -I/opt/include/ruby-2.3.0/x86_64-freebsd11.1 -I/opt/include/ruby-2.3.0 -I/usr/local/include/gtk-3.0 -I/usr/local/include/pango-1.0 -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -I/usr/local/include -I/usr/local/include/cairo -I/usr/local/include/pixman-1 -I/usr/local/include/freetype2 -I/usr/local/include/libdrm -I/usr/local/include/libpng16 -I/usr/local/include/harfbuzz -I/usr/local/include/gdk-pixbuf-2.0 -I/usr/local/include/gio-unix-2.0/ -I/usr/local/include/atk-1.0 -D_THREAD_SAFE -I/usr/local/include/at-spi2-atk/2.0 -I/usr/local/include/at-spi-2.0 -I/usr/local/include/dbus-1.0 -I/usr/local/lib/dbus-1.0/include -pthread -I/usr/include/ -I/usr/local/include/librsvg-2.0/librsvg shoes/plot/plot.c
+cc -o /usr/home/ccoupe/build/freebsd/tmp/plot/plot_column.o -I. -c -g -O0 -DRUBY_HTTP -DBSD -DSHOES_GTK -fPIC -Wno-unused-variable -I/usr/include -I/opt/include/ruby-2.3.0/x86_64-freebsd11.1 -I/opt/include/ruby-2.3.0 -I/usr/local/include/gtk-3.0 -I/usr/local/include/pango-1.0 -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -I/usr/local/include -I/usr/local/include/cairo -I/usr/local/include/pixman-1 -I/usr/local/include/freetype2 -I/usr/local/include/libdrm -I/usr/local/include/libpng16 -I/usr/local/include/harfbuzz -I/usr/local/include/gdk-pixbuf-2.0 -I/usr/local/include/gio-unix-2.0/ -I/usr/local/include/atk-1.0 -D_THREAD_SAFE -I/usr/local/include/at-spi2-atk/2.0 -I/usr/local/include/at-spi-2.0 -I/usr/local/include/dbus-1.0 -I/usr/local/lib/dbus-1.0/include -pthread -I/usr/include/ -I/usr/local/include/librsvg-2.0/librsvg shoes/plot/plot_column.c
+cc -o /usr/home/ccoupe/build/freebsd/tmp/plot/plot_line.o -I. -c -g -O0 -DRUBY_HTTP -DBSD -DSHOES_GTK -fPIC -Wno-unused-variable -I/usr/include -I/opt/include/ruby-2.3.0/x86_64-freebsd11.1 -I/opt/include/ruby-2.3.0 -I/usr/local/include/gtk-3.0 -I/usr/local/include/pango-1.0 -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -I/usr/local/include -I/usr/local/include/cairo -I/usr/local/include/pixman-1 -I/usr/local/include/freetype2 -I/usr/local/include/libdrm -I/usr/local/include/libpng16 -I/usr/local/include/harfbuzz -I/usr/local/include/gdk-pixbuf-2.0 -I/usr/local/include/gio-unix-2.0/ -I/usr/local/include/atk-1.0 -D_THREAD_SAFE -I/usr/local/include/at-spi2-atk/2.0 -I/usr/local/include/at-spi-2.0 -I/usr/local/include/dbus-1.0 -I/usr/local/lib/dbus-1.0/include -pthread -I/usr/include/ -I/usr/local/include/librsvg-2.0/librsvg shoes/plot/plot_line.c
+cc -o /usr/home/ccoupe/build/freebsd/tmp/plot/plot_pie.o -I. -c -g -O0 -DRUBY_HTTP -DBSD -DSHOES_GTK -fPIC -Wno-unused-variable -I/usr/include -I/opt/include/ruby-2.3.0/x86_64-freebsd11.1 -I/opt/include/ruby-2.3.0 -I/usr/local/include/gtk-3.0 -I/usr/local/include/pango-1.0 -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -I/usr/local/include -I/usr/local/include/cairo -I/usr/local/include/pixman-1 -I/usr/local/include/freetype2 -I/usr/local/include/libdrm -I/usr/local/include/libpng16 -I/usr/local/include/harfbuzz -I/usr/local/include/gdk-pixbuf-2.0 -I/usr/local/include/gio-unix-2.0/ -I/usr/local/include/atk-1.0 -D_THREAD_SAFE -I/usr/local/include/at-spi2-atk/2.0 -I/usr/local/include/at-spi-2.0 -I/usr/local/include/dbus-1.0 -I/usr/local/lib/dbus-1.0/include -pthread -I/usr/include/ -I/usr/local/include/librsvg-2.0/librsvg shoes/plot/plot_pie.c
+cc -o /usr/home/ccoupe/build/freebsd/tmp/plot/plot_radar.o -I. -c -g -O0 -DRUBY_HTTP -DBSD -DSHOES_GTK -fPIC -Wno-unused-variable -I/usr/include -I/opt/include/ruby-2.3.0/x86_64-freebsd11.1 -I/opt/include/ruby-2.3.0 -I/usr/local/include/gtk-3.0 -I/usr/local/include/pango-1.0 -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -I/usr/local/include -I/usr/local/include/cairo -I/usr/local/include/pixman-1 -I/usr/local/include/freetype2 -I/usr/local/include/libdrm -I/usr/local/include/libpng16 -I/usr/local/include/harfbuzz -I/usr/local/include/gdk-pixbuf-2.0 -I/usr/local/include/gio-unix-2.0/ -I/usr/local/include/atk-1.0 -D_THREAD_SAFE -I/usr/local/include/at-spi2-atk/2.0 -I/usr/local/include/at-spi-2.0 -I/usr/local/include/dbus-1.0 -I/usr/local/lib/dbus-1.0/include -pthread -I/usr/include/ -I/usr/local/include/librsvg-2.0/librsvg shoes/plot/plot_radar.c
+cc -o /usr/home/ccoupe/build/freebsd/tmp/plot/plot_scatter.o -I. -c -g -O0 -DRUBY_HTTP -DBSD -DSHOES_GTK -fPIC -Wno-unused-variable -I/usr/include -I/opt/include/ruby-2.3.0/x86_64-freebsd11.1 -I/opt/include/ruby-2.3.0 -I/usr/local/include/gtk-3.0 -I/usr/local/include/pango-1.0 -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -I/usr/local/include -I/usr/local/include/cairo -I/usr/local/include/pixman-1 -I/usr/local/include/freetype2 -I/usr/local/include/libdrm -I/usr/local/include/libpng16 -I/usr/local/include/harfbuzz -I/usr/local/include/gdk-pixbuf-2.0 -I/usr/local/include/gio-unix-2.0/ -I/usr/local/include/atk-1.0 -D_THREAD_SAFE -I/usr/local/include/at-spi2-atk/2.0 -I/usr/local/include/at-spi-2.0 -I/usr/local/include/dbus-1.0 -I/usr/local/lib/dbus-1.0/include -pthread -I/usr/include/ -I/usr/local/include/librsvg-2.0/librsvg shoes/plot/plot_scatter.c
+cc -o /usr/home/ccoupe/build/freebsd/tmp/plot/plot_util.o -I. -c -g -O0 -DRUBY_HTTP -DBSD -DSHOES_GTK -fPIC -Wno-unused-variable -I/usr/include -I/opt/include/ruby-2.3.0/x86_64-freebsd11.1 -I/opt/include/ruby-2.3.0 -I/usr/local/include/gtk-3.0 -I/usr/local/include/pango-1.0 -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -I/usr/local/include -I/usr/local/include/cairo -I/usr/local/include/pixman-1 -I/usr/local/include/freetype2 -I/usr/local/include/libdrm -I/usr/local/include/libpng16 -I/usr/local/include/harfbuzz -I/usr/local/include/gdk-pixbuf-2.0 -I/usr/local/include/gio-unix-2.0/ -I/usr/local/include/atk-1.0 -D_THREAD_SAFE -I/usr/local/include/at-spi2-atk/2.0 -I/usr/local/include/at-spi-2.0 -I/usr/local/include/dbus-1.0 -I/usr/local/lib/dbus-1.0/include -pthread -I/usr/include/ -I/usr/local/include/librsvg-2.0/librsvg shoes/plot/plot_util.c
+touch /usr/home/ccoupe/build/freebsd/tmp/plot/zzplot.done
+cc -o /usr/home/ccoupe/build/freebsd/tmp/console/tesi.o -I. -c -g -O0 -DRUBY_HTTP -DBSD -DSHOES_GTK -fPIC -Wno-unused-variable -I/usr/include -I/opt/include/ruby-2.3.0/x86_64-freebsd11.1 -I/opt/include/ruby-2.3.0 -I/usr/local/include/gtk-3.0 -I/usr/local/include/pango-1.0 -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -I/usr/local/include -I/usr/local/include/cairo -I/usr/local/include/pixman-1 -I/usr/local/include/freetype2 -I/usr/local/include/libdrm -I/usr/local/include/libpng16 -I/usr/local/include/harfbuzz -I/usr/local/include/gdk-pixbuf-2.0 -I/usr/local/include/gio-unix-2.0/ -I/usr/local/include/atk-1.0 -D_THREAD_SAFE -I/usr/local/include/at-spi2-atk/2.0 -I/usr/local/include/at-spi-2.0 -I/usr/local/include/dbus-1.0 -I/usr/local/lib/dbus-1.0/include -pthread -I/usr/include/ -I/usr/local/include/librsvg-2.0/librsvg shoes/console/tesi.c
+cc -o /usr/home/ccoupe/build/freebsd/tmp/console/colortab.o -I. -c -g -O0 -DRUBY_HTTP -DBSD -DSHOES_GTK -fPIC -Wno-unused-variable -I/usr/include -I/opt/include/ruby-2.3.0/x86_64-freebsd11.1 -I/opt/include/ruby-2.3.0 -I/usr/local/include/gtk-3.0 -I/usr/local/include/pango-1.0 -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -I/usr/local/include -I/usr/local/include/cairo -I/usr/local/include/pixman-1 -I/usr/local/include/freetype2 -I/usr/local/include/libdrm -I/usr/local/include/libpng16 -I/usr/local/include/harfbuzz -I/usr/local/include/gdk-pixbuf-2.0 -I/usr/local/include/gio-unix-2.0/ -I/usr/local/include/atk-1.0 -D_THREAD_SAFE -I/usr/local/include/at-spi2-atk/2.0 -I/usr/local/include/at-spi-2.0 -I/usr/local/include/dbus-1.0 -I/usr/local/lib/dbus-1.0/include -pthread -I/usr/include/ -I/usr/local/include/librsvg-2.0/librsvg shoes/console/colortab.c
+cc -o /usr/home/ccoupe/build/freebsd/tmp/console/gtk-terminal.o -I. -c -g -O0 -DRUBY_HTTP -DBSD -DSHOES_GTK -fPIC -Wno-unused-variable -I/usr/include -I/opt/include/ruby-2.3.0/x86_64-freebsd11.1 -I/opt/include/ruby-2.3.0 -I/usr/local/include/gtk-3.0 -I/usr/local/include/pango-1.0 -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -I/usr/local/include -I/usr/local/include/cairo -I/usr/local/include/pixman-1 -I/usr/local/include/freetype2 -I/usr/local/include/libdrm -I/usr/local/include/libpng16 -I/usr/local/include/harfbuzz -I/usr/local/include/gdk-pixbuf-2.0 -I/usr/local/include/gio-unix-2.0/ -I/usr/local/include/atk-1.0 -D_THREAD_SAFE -I/usr/local/include/at-spi2-atk/2.0 -I/usr/local/include/at-spi-2.0 -I/usr/local/include/dbus-1.0 -I/usr/local/lib/dbus-1.0/include -pthread -I/usr/include/ -I/usr/local/include/librsvg-2.0/librsvg shoes/console/gtk-terminal.c
+shoes/console/gtk-terminal.c:560:5: warning: 'gtk_widget_override_font' is
+ deprecated [-Wdeprecated-declarations]
+ gtk_widget_override_font (announce, bpfd);
+ ^
+/usr/local/include/gtk-3.0/gtk/gtkwidget.h:1153:14: note:
+ 'gtk_widget_override_font' has been explicitly marked deprecated here
+void gtk_widget_override_font (GtkWidge...
+ ^
+shoes/console/gtk-terminal.c:597:5: warning: 'gtk_widget_override_color' is
+ deprecated [-Wdeprecated-declarations]
+ gtk_widget_override_color(canvas, GTK_STATE_FLAG_NORMAL, &fg_color);
+ ^
+/usr/local/include/gtk-3.0/gtk/gtkwidget.h:1144:14: note:
+ 'gtk_widget_override_color' has been explicitly marked deprecated here
+void gtk_widget_override_color (GtkWidget *widget,
+ ^
+shoes/console/gtk-terminal.c:602:5: warning:
+ 'gtk_widget_override_background_color' is deprecated
+ [-Wdeprecated-declarations]
+ gtk_widget_override_background_color(canvas, GTK_STATE_FLAG_NORMAL, ...
+ ^
+/usr/local/include/gtk-3.0/gtk/gtkwidget.h:1148:14: note:
+ 'gtk_widget_override_background_color' has been explicitly marked
+ deprecated here
+void gtk_widget_override_background_color (GtkWidget *widget,
+ ^
+shoes/console/gtk-terminal.c:609:5: warning: 'gtk_widget_override_font' is
+ deprecated [-Wdeprecated-declarations]
+ gtk_widget_override_font (canvas, pfd);
+ ^
+/usr/local/include/gtk-3.0/gtk/gtkwidget.h:1153:14: note:
+ 'gtk_widget_override_font' has been explicitly marked deprecated here
+void gtk_widget_override_font (GtkWidge...
+ ^
+4 warnings generated.
+touch /usr/home/ccoupe/build/freebsd/tmp/console/zzconsole.done
+cc -o /usr/home/ccoupe/build/freebsd/tmp/types/button.o -I. -c -g -O0 -DRUBY_HTTP -DBSD -DSHOES_GTK -fPIC -Wno-unused-variable -I/usr/include -I/opt/include/ruby-2.3.0/x86_64-freebsd11.1 -I/opt/include/ruby-2.3.0 -I/usr/local/include/gtk-3.0 -I/usr/local/include/pango-1.0 -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -I/usr/local/include -I/usr/local/include/cairo -I/usr/local/include/pixman-1 -I/usr/local/include/freetype2 -I/usr/local/include/libdrm -I/usr/local/include/libpng16 -I/usr/local/include/harfbuzz -I/usr/local/include/gdk-pixbuf-2.0 -I/usr/local/include/gio-unix-2.0/ -I/usr/local/include/atk-1.0 -D_THREAD_SAFE -I/usr/local/include/at-spi2-atk/2.0 -I/usr/local/include/at-spi-2.0 -I/usr/local/include/dbus-1.0 -I/usr/local/lib/dbus-1.0/include -pthread -I/usr/include/ -I/usr/local/include/librsvg-2.0/librsvg shoes/types/button.c
+cc -o /usr/home/ccoupe/build/freebsd/tmp/types/check.o -I. -c -g -O0 -DRUBY_HTTP -DBSD -DSHOES_GTK -fPIC -Wno-unused-variable -I/usr/include -I/opt/include/ruby-2.3.0/x86_64-freebsd11.1 -I/opt/include/ruby-2.3.0 -I/usr/local/include/gtk-3.0 -I/usr/local/include/pango-1.0 -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -I/usr/local/include -I/usr/local/include/cairo -I/usr/local/include/pixman-1 -I/usr/local/include/freetype2 -I/usr/local/include/libdrm -I/usr/local/include/libpng16 -I/usr/local/include/harfbuzz -I/usr/local/include/gdk-pixbuf-2.0 -I/usr/local/include/gio-unix-2.0/ -I/usr/local/include/atk-1.0 -D_THREAD_SAFE -I/usr/local/include/at-spi2-atk/2.0 -I/usr/local/include/at-spi-2.0 -I/usr/local/include/dbus-1.0 -I/usr/local/lib/dbus-1.0/include -pthread -I/usr/include/ -I/usr/local/include/librsvg-2.0/librsvg shoes/types/check.c
+cc -o /usr/home/ccoupe/build/freebsd/tmp/types/color.o -I. -c -g -O0 -DRUBY_HTTP -DBSD -DSHOES_GTK -fPIC -Wno-unused-variable -I/usr/include -I/opt/include/ruby-2.3.0/x86_64-freebsd11.1 -I/opt/include/ruby-2.3.0 -I/usr/local/include/gtk-3.0 -I/usr/local/include/pango-1.0 -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -I/usr/local/include -I/usr/local/include/cairo -I/usr/local/include/pixman-1 -I/usr/local/include/freetype2 -I/usr/local/include/libdrm -I/usr/local/include/libpng16 -I/usr/local/include/harfbuzz -I/usr/local/include/gdk-pixbuf-2.0 -I/usr/local/include/gio-unix-2.0/ -I/usr/local/include/atk-1.0 -D_THREAD_SAFE -I/usr/local/include/at-spi2-atk/2.0 -I/usr/local/include/at-spi-2.0 -I/usr/local/include/dbus-1.0 -I/usr/local/lib/dbus-1.0/include -pthread -I/usr/include/ -I/usr/local/include/librsvg-2.0/librsvg shoes/types/color.c
+cc -o /usr/home/ccoupe/build/freebsd/tmp/types/download.o -I. -c -g -O0 -DRUBY_HTTP -DBSD -DSHOES_GTK -fPIC -Wno-unused-variable -I/usr/include -I/opt/include/ruby-2.3.0/x86_64-freebsd11.1 -I/opt/include/ruby-2.3.0 -I/usr/local/include/gtk-3.0 -I/usr/local/include/pango-1.0 -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -I/usr/local/include -I/usr/local/include/cairo -I/usr/local/include/pixman-1 -I/usr/local/include/freetype2 -I/usr/local/include/libdrm -I/usr/local/include/libpng16 -I/usr/local/include/harfbuzz -I/usr/local/include/gdk-pixbuf-2.0 -I/usr/local/include/gio-unix-2.0/ -I/usr/local/include/atk-1.0 -D_THREAD_SAFE -I/usr/local/include/at-spi2-atk/2.0 -I/usr/local/include/at-spi-2.0 -I/usr/local/include/dbus-1.0 -I/usr/local/lib/dbus-1.0/include -pthread -I/usr/include/ -I/usr/local/include/librsvg-2.0/librsvg shoes/types/download.c
+cc -o /usr/home/ccoupe/build/freebsd/tmp/types/edit_box.o -I. -c -g -O0 -DRUBY_HTTP -DBSD -DSHOES_GTK -fPIC -Wno-unused-variable -I/usr/include -I/opt/include/ruby-2.3.0/x86_64-freebsd11.1 -I/opt/include/ruby-2.3.0 -I/usr/local/include/gtk-3.0 -I/usr/local/include/pango-1.0 -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -I/usr/local/include -I/usr/local/include/cairo -I/usr/local/include/pixman-1 -I/usr/local/include/freetype2 -I/usr/local/include/libdrm -I/usr/local/include/libpng16 -I/usr/local/include/harfbuzz -I/usr/local/include/gdk-pixbuf-2.0 -I/usr/local/include/gio-unix-2.0/ -I/usr/local/include/atk-1.0 -D_THREAD_SAFE -I/usr/local/include/at-spi2-atk/2.0 -I/usr/local/include/at-spi-2.0 -I/usr/local/include/dbus-1.0 -I/usr/local/lib/dbus-1.0/include -pthread -I/usr/include/ -I/usr/local/include/librsvg-2.0/librsvg shoes/types/edit_box.c
+cc -o /usr/home/ccoupe/build/freebsd/tmp/types/edit_line.o -I. -c -g -O0 -DRUBY_HTTP -DBSD -DSHOES_GTK -fPIC -Wno-unused-variable -I/usr/include -I/opt/include/ruby-2.3.0/x86_64-freebsd11.1 -I/opt/include/ruby-2.3.0 -I/usr/local/include/gtk-3.0 -I/usr/local/include/pango-1.0 -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -I/usr/local/include -I/usr/local/include/cairo -I/usr/local/include/pixman-1 -I/usr/local/include/freetype2 -I/usr/local/include/libdrm -I/usr/local/include/libpng16 -I/usr/local/include/harfbuzz -I/usr/local/include/gdk-pixbuf-2.0 -I/usr/local/include/gio-unix-2.0/ -I/usr/local/include/atk-1.0 -D_THREAD_SAFE -I/usr/local/include/at-spi2-atk/2.0 -I/usr/local/include/at-spi-2.0 -I/usr/local/include/dbus-1.0 -I/usr/local/lib/dbus-1.0/include -pthread -I/usr/include/ -I/usr/local/include/librsvg-2.0/librsvg shoes/types/edit_line.c
+cc -o /usr/home/ccoupe/build/freebsd/tmp/types/effect.o -I. -c -g -O0 -DRUBY_HTTP -DBSD -DSHOES_GTK -fPIC -Wno-unused-variable -I/usr/include -I/opt/include/ruby-2.3.0/x86_64-freebsd11.1 -I/opt/include/ruby-2.3.0 -I/usr/local/include/gtk-3.0 -I/usr/local/include/pango-1.0 -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -I/usr/local/include -I/usr/local/include/cairo -I/usr/local/include/pixman-1 -I/usr/local/include/freetype2 -I/usr/local/include/libdrm -I/usr/local/include/libpng16 -I/usr/local/include/harfbuzz -I/usr/local/include/gdk-pixbuf-2.0 -I/usr/local/include/gio-unix-2.0/ -I/usr/local/include/atk-1.0 -D_THREAD_SAFE -I/usr/local/include/at-spi2-atk/2.0 -I/usr/local/include/at-spi-2.0 -I/usr/local/include/dbus-1.0 -I/usr/local/lib/dbus-1.0/include -pthread -I/usr/include/ -I/usr/local/include/librsvg-2.0/librsvg shoes/types/effect.c
+cc -o /usr/home/ccoupe/build/freebsd/tmp/types/image.o -I. -c -g -O0 -DRUBY_HTTP -DBSD -DSHOES_GTK -fPIC -Wno-unused-variable -I/usr/include -I/opt/include/ruby-2.3.0/x86_64-freebsd11.1 -I/opt/include/ruby-2.3.0 -I/usr/local/include/gtk-3.0 -I/usr/local/include/pango-1.0 -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -I/usr/local/include -I/usr/local/include/cairo -I/usr/local/include/pixman-1 -I/usr/local/include/freetype2 -I/usr/local/include/libdrm -I/usr/local/include/libpng16 -I/usr/local/include/harfbuzz -I/usr/local/include/gdk-pixbuf-2.0 -I/usr/local/include/gio-unix-2.0/ -I/usr/local/include/atk-1.0 -D_THREAD_SAFE -I/usr/local/include/at-spi2-atk/2.0 -I/usr/local/include/at-spi-2.0 -I/usr/local/include/dbus-1.0 -I/usr/local/lib/dbus-1.0/include -pthread -I/usr/include/ -I/usr/local/include/librsvg-2.0/librsvg shoes/types/image.c
+cc -o /usr/home/ccoupe/build/freebsd/tmp/types/list_box.o -I. -c -g -O0 -DRUBY_HTTP -DBSD -DSHOES_GTK -fPIC -Wno-unused-variable -I/usr/include -I/opt/include/ruby-2.3.0/x86_64-freebsd11.1 -I/opt/include/ruby-2.3.0 -I/usr/local/include/gtk-3.0 -I/usr/local/include/pango-1.0 -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -I/usr/local/include -I/usr/local/include/cairo -I/usr/local/include/pixman-1 -I/usr/local/include/freetype2 -I/usr/local/include/libdrm -I/usr/local/include/libpng16 -I/usr/local/include/harfbuzz -I/usr/local/include/gdk-pixbuf-2.0 -I/usr/local/include/gio-unix-2.0/ -I/usr/local/include/atk-1.0 -D_THREAD_SAFE -I/usr/local/include/at-spi2-atk/2.0 -I/usr/local/include/at-spi-2.0 -I/usr/local/include/dbus-1.0 -I/usr/local/lib/dbus-1.0/include -pthread -I/usr/include/ -I/usr/local/include/librsvg-2.0/librsvg shoes/types/list_box.c
+cc -o /usr/home/ccoupe/build/freebsd/tmp/types/native.o -I. -c -g -O0 -DRUBY_HTTP -DBSD -DSHOES_GTK -fPIC -Wno-unused-variable -I/usr/include -I/opt/include/ruby-2.3.0/x86_64-freebsd11.1 -I/opt/include/ruby-2.3.0 -I/usr/local/include/gtk-3.0 -I/usr/local/include/pango-1.0 -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -I/usr/local/include -I/usr/local/include/cairo -I/usr/local/include/pixman-1 -I/usr/local/include/freetype2 -I/usr/local/include/libdrm -I/usr/local/include/libpng16 -I/usr/local/include/harfbuzz -I/usr/local/include/gdk-pixbuf-2.0 -I/usr/local/include/gio-unix-2.0/ -I/usr/local/include/atk-1.0 -D_THREAD_SAFE -I/usr/local/include/at-spi2-atk/2.0 -I/usr/local/include/at-spi-2.0 -I/usr/local/include/dbus-1.0 -I/usr/local/lib/dbus-1.0/include -pthread -I/usr/include/ -I/usr/local/include/librsvg-2.0/librsvg shoes/types/native.c
+cc -o /usr/home/ccoupe/build/freebsd/tmp/types/pattern.o -I. -c -g -O0 -DRUBY_HTTP -DBSD -DSHOES_GTK -fPIC -Wno-unused-variable -I/usr/include -I/opt/include/ruby-2.3.0/x86_64-freebsd11.1 -I/opt/include/ruby-2.3.0 -I/usr/local/include/gtk-3.0 -I/usr/local/include/pango-1.0 -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -I/usr/local/include -I/usr/local/include/cairo -I/usr/local/include/pixman-1 -I/usr/local/include/freetype2 -I/usr/local/include/libdrm -I/usr/local/include/libpng16 -I/usr/local/include/harfbuzz -I/usr/local/include/gdk-pixbuf-2.0 -I/usr/local/include/gio-unix-2.0/ -I/usr/local/include/atk-1.0 -D_THREAD_SAFE -I/usr/local/include/at-spi2-atk/2.0 -I/usr/local/include/at-spi-2.0 -I/usr/local/include/dbus-1.0 -I/usr/local/lib/dbus-1.0/include -pthread -I/usr/include/ -I/usr/local/include/librsvg-2.0/librsvg shoes/types/pattern.c
+cc -o /usr/home/ccoupe/build/freebsd/tmp/types/plot.o -I. -c -g -O0 -DRUBY_HTTP -DBSD -DSHOES_GTK -fPIC -Wno-unused-variable -I/usr/include -I/opt/include/ruby-2.3.0/x86_64-freebsd11.1 -I/opt/include/ruby-2.3.0 -I/usr/local/include/gtk-3.0 -I/usr/local/include/pango-1.0 -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -I/usr/local/include -I/usr/local/include/cairo -I/usr/local/include/pixman-1 -I/usr/local/include/freetype2 -I/usr/local/include/libdrm -I/usr/local/include/libpng16 -I/usr/local/include/harfbuzz -I/usr/local/include/gdk-pixbuf-2.0 -I/usr/local/include/gio-unix-2.0/ -I/usr/local/include/atk-1.0 -D_THREAD_SAFE -I/usr/local/include/at-spi2-atk/2.0 -I/usr/local/include/at-spi-2.0 -I/usr/local/include/dbus-1.0 -I/usr/local/lib/dbus-1.0/include -pthread -I/usr/include/ -I/usr/local/include/librsvg-2.0/librsvg shoes/types/plot.c
+cc -o /usr/home/ccoupe/build/freebsd/tmp/types/progress.o -I. -c -g -O0 -DRUBY_HTTP -DBSD -DSHOES_GTK -fPIC -Wno-unused-variable -I/usr/include -I/opt/include/ruby-2.3.0/x86_64-freebsd11.1 -I/opt/include/ruby-2.3.0 -I/usr/local/include/gtk-3.0 -I/usr/local/include/pango-1.0 -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -I/usr/local/include -I/usr/local/include/cairo -I/usr/local/include/pixman-1 -I/usr/local/include/freetype2 -I/usr/local/include/libdrm -I/usr/local/include/libpng16 -I/usr/local/include/harfbuzz -I/usr/local/include/gdk-pixbuf-2.0 -I/usr/local/include/gio-unix-2.0/ -I/usr/local/include/atk-1.0 -D_THREAD_SAFE -I/usr/local/include/at-spi2-atk/2.0 -I/usr/local/include/at-spi-2.0 -I/usr/local/include/dbus-1.0 -I/usr/local/lib/dbus-1.0/include -pthread -I/usr/include/ -I/usr/local/include/librsvg-2.0/librsvg shoes/types/progress.c
+cc -o /usr/home/ccoupe/build/freebsd/tmp/types/radio.o -I. -c -g -O0 -DRUBY_HTTP -DBSD -DSHOES_GTK -fPIC -Wno-unused-variable -I/usr/include -I/opt/include/ruby-2.3.0/x86_64-freebsd11.1 -I/opt/include/ruby-2.3.0 -I/usr/local/include/gtk-3.0 -I/usr/local/include/pango-1.0 -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -I/usr/local/include -I/usr/local/include/cairo -I/usr/local/include/pixman-1 -I/usr/local/include/freetype2 -I/usr/local/include/libdrm -I/usr/local/include/libpng16 -I/usr/local/include/harfbuzz -I/usr/local/include/gdk-pixbuf-2.0 -I/usr/local/include/gio-unix-2.0/ -I/usr/local/include/atk-1.0 -D_THREAD_SAFE -I/usr/local/include/at-spi2-atk/2.0 -I/usr/local/include/at-spi-2.0 -I/usr/local/include/dbus-1.0 -I/usr/local/lib/dbus-1.0/include -pthread -I/usr/include/ -I/usr/local/include/librsvg-2.0/librsvg shoes/types/radio.c
+cc -o /usr/home/ccoupe/build/freebsd/tmp/types/shape.o -I. -c -g -O0 -DRUBY_HTTP -DBSD -DSHOES_GTK -fPIC -Wno-unused-variable -I/usr/include -I/opt/include/ruby-2.3.0/x86_64-freebsd11.1 -I/opt/include/ruby-2.3.0 -I/usr/local/include/gtk-3.0 -I/usr/local/include/pango-1.0 -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -I/usr/local/include -I/usr/local/include/cairo -I/usr/local/include/pixman-1 -I/usr/local/include/freetype2 -I/usr/local/include/libdrm -I/usr/local/include/libpng16 -I/usr/local/include/harfbuzz -I/usr/local/include/gdk-pixbuf-2.0 -I/usr/local/include/gio-unix-2.0/ -I/usr/local/include/atk-1.0 -D_THREAD_SAFE -I/usr/local/include/at-spi2-atk/2.0 -I/usr/local/include/at-spi-2.0 -I/usr/local/include/dbus-1.0 -I/usr/local/lib/dbus-1.0/include -pthread -I/usr/include/ -I/usr/local/include/librsvg-2.0/librsvg shoes/types/shape.c
+cc -o /usr/home/ccoupe/build/freebsd/tmp/types/slider.o -I. -c -g -O0 -DRUBY_HTTP -DBSD -DSHOES_GTK -fPIC -Wno-unused-variable -I/usr/include -I/opt/include/ruby-2.3.0/x86_64-freebsd11.1 -I/opt/include/ruby-2.3.0 -I/usr/local/include/gtk-3.0 -I/usr/local/include/pango-1.0 -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -I/usr/local/include -I/usr/local/include/cairo -I/usr/local/include/pixman-1 -I/usr/local/include/freetype2 -I/usr/local/include/libdrm -I/usr/local/include/libpng16 -I/usr/local/include/harfbuzz -I/usr/local/include/gdk-pixbuf-2.0 -I/usr/local/include/gio-unix-2.0/ -I/usr/local/include/atk-1.0 -D_THREAD_SAFE -I/usr/local/include/at-spi2-atk/2.0 -I/usr/local/include/at-spi-2.0 -I/usr/local/include/dbus-1.0 -I/usr/local/lib/dbus-1.0/include -pthread -I/usr/include/ -I/usr/local/include/librsvg-2.0/librsvg shoes/types/slider.c
+cc -o /usr/home/ccoupe/build/freebsd/tmp/types/spinner.o -I. -c -g -O0 -DRUBY_HTTP -DBSD -DSHOES_GTK -fPIC -Wno-unused-variable -I/usr/include -I/opt/include/ruby-2.3.0/x86_64-freebsd11.1 -I/opt/include/ruby-2.3.0 -I/usr/local/include/gtk-3.0 -I/usr/local/include/pango-1.0 -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -I/usr/local/include -I/usr/local/include/cairo -I/usr/local/include/pixman-1 -I/usr/local/include/freetype2 -I/usr/local/include/libdrm -I/usr/local/include/libpng16 -I/usr/local/include/harfbuzz -I/usr/local/include/gdk-pixbuf-2.0 -I/usr/local/include/gio-unix-2.0/ -I/usr/local/include/atk-1.0 -D_THREAD_SAFE -I/usr/local/include/at-spi2-atk/2.0 -I/usr/local/include/at-spi-2.0 -I/usr/local/include/dbus-1.0 -I/usr/local/lib/dbus-1.0/include -pthread -I/usr/include/ -I/usr/local/include/librsvg-2.0/librsvg shoes/types/spinner.c
+cc -o /usr/home/ccoupe/build/freebsd/tmp/types/svg.o -I. -c -g -O0 -DRUBY_HTTP -DBSD -DSHOES_GTK -fPIC -Wno-unused-variable -I/usr/include -I/opt/include/ruby-2.3.0/x86_64-freebsd11.1 -I/opt/include/ruby-2.3.0 -I/usr/local/include/gtk-3.0 -I/usr/local/include/pango-1.0 -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -I/usr/local/include -I/usr/local/include/cairo -I/usr/local/include/pixman-1 -I/usr/local/include/freetype2 -I/usr/local/include/libdrm -I/usr/local/include/libpng16 -I/usr/local/include/harfbuzz -I/usr/local/include/gdk-pixbuf-2.0 -I/usr/local/include/gio-unix-2.0/ -I/usr/local/include/atk-1.0 -D_THREAD_SAFE -I/usr/local/include/at-spi2-atk/2.0 -I/usr/local/include/at-spi-2.0 -I/usr/local/include/dbus-1.0 -I/usr/local/lib/dbus-1.0/include -pthread -I/usr/include/ -I/usr/local/include/librsvg-2.0/librsvg shoes/types/svg.c
+cc -o /usr/home/ccoupe/build/freebsd/tmp/types/switch.o -I. -c -g -O0 -DRUBY_HTTP -DBSD -DSHOES_GTK -fPIC -Wno-unused-variable -I/usr/include -I/opt/include/ruby-2.3.0/x86_64-freebsd11.1 -I/opt/include/ruby-2.3.0 -I/usr/local/include/gtk-3.0 -I/usr/local/include/pango-1.0 -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -I/usr/local/include -I/usr/local/include/cairo -I/usr/local/include/pixman-1 -I/usr/local/include/freetype2 -I/usr/local/include/libdrm -I/usr/local/include/libpng16 -I/usr/local/include/harfbuzz -I/usr/local/include/gdk-pixbuf-2.0 -I/usr/local/include/gio-unix-2.0/ -I/usr/local/include/atk-1.0 -D_THREAD_SAFE -I/usr/local/include/at-spi2-atk/2.0 -I/usr/local/include/at-spi-2.0 -I/usr/local/include/dbus-1.0 -I/usr/local/lib/dbus-1.0/include -pthread -I/usr/include/ -I/usr/local/include/librsvg-2.0/librsvg shoes/types/switch.c
+cc -o /usr/home/ccoupe/build/freebsd/tmp/types/systray.o -I. -c -g -O0 -DRUBY_HTTP -DBSD -DSHOES_GTK -fPIC -Wno-unused-variable -I/usr/include -I/opt/include/ruby-2.3.0/x86_64-freebsd11.1 -I/opt/include/ruby-2.3.0 -I/usr/local/include/gtk-3.0 -I/usr/local/include/pango-1.0 -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -I/usr/local/include -I/usr/local/include/cairo -I/usr/local/include/pixman-1 -I/usr/local/include/freetype2 -I/usr/local/include/libdrm -I/usr/local/include/libpng16 -I/usr/local/include/harfbuzz -I/usr/local/include/gdk-pixbuf-2.0 -I/usr/local/include/gio-unix-2.0/ -I/usr/local/include/atk-1.0 -D_THREAD_SAFE -I/usr/local/include/at-spi2-atk/2.0 -I/usr/local/include/at-spi-2.0 -I/usr/local/include/dbus-1.0 -I/usr/local/lib/dbus-1.0/include -pthread -I/usr/include/ -I/usr/local/include/librsvg-2.0/librsvg shoes/types/systray.c
+shoes/types/systray.c:12:1: warning: type specifier missing, defaults to 'int'
+ [-Wimplicit-int]
+shoes_systray_init() {
+^
+shoes/types/systray.c:17:1: warning: control reaches end of non-void function
+ [-Wreturn-type]
+}
+^
+2 warnings generated.
+cc -o /usr/home/ccoupe/build/freebsd/tmp/types/text.o -I. -c -g -O0 -DRUBY_HTTP -DBSD -DSHOES_GTK -fPIC -Wno-unused-variable -I/usr/include -I/opt/include/ruby-2.3.0/x86_64-freebsd11.1 -I/opt/include/ruby-2.3.0 -I/usr/local/include/gtk-3.0 -I/usr/local/include/pango-1.0 -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -I/usr/local/include -I/usr/local/include/cairo -I/usr/local/include/pixman-1 -I/usr/local/include/freetype2 -I/usr/local/include/libdrm -I/usr/local/include/libpng16 -I/usr/local/include/harfbuzz -I/usr/local/include/gdk-pixbuf-2.0 -I/usr/local/include/gio-unix-2.0/ -I/usr/local/include/atk-1.0 -D_THREAD_SAFE -I/usr/local/include/at-spi2-atk/2.0 -I/usr/local/include/at-spi-2.0 -I/usr/local/include/dbus-1.0 -I/usr/local/lib/dbus-1.0/include -pthread -I/usr/include/ -I/usr/local/include/librsvg-2.0/librsvg shoes/types/text.c
+cc -o /usr/home/ccoupe/build/freebsd/tmp/types/text_link.o -I. -c -g -O0 -DRUBY_HTTP -DBSD -DSHOES_GTK -fPIC -Wno-unused-variable -I/usr/include -I/opt/include/ruby-2.3.0/x86_64-freebsd11.1 -I/opt/include/ruby-2.3.0 -I/usr/local/include/gtk-3.0 -I/usr/local/include/pango-1.0 -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -I/usr/local/include -I/usr/local/include/cairo -I/usr/local/include/pixman-1 -I/usr/local/include/freetype2 -I/usr/local/include/libdrm -I/usr/local/include/libpng16 -I/usr/local/include/harfbuzz -I/usr/local/include/gdk-pixbuf-2.0 -I/usr/local/include/gio-unix-2.0/ -I/usr/local/include/atk-1.0 -D_THREAD_SAFE -I/usr/local/include/at-spi2-atk/2.0 -I/usr/local/include/at-spi-2.0 -I/usr/local/include/dbus-1.0 -I/usr/local/lib/dbus-1.0/include -pthread -I/usr/include/ -I/usr/local/include/librsvg-2.0/librsvg shoes/types/text_link.c
+cc -o /usr/home/ccoupe/build/freebsd/tmp/types/text_view.o -I. -c -g -O0 -DRUBY_HTTP -DBSD -DSHOES_GTK -fPIC -Wno-unused-variable -I/usr/include -I/opt/include/ruby-2.3.0/x86_64-freebsd11.1 -I/opt/include/ruby-2.3.0 -I/usr/local/include/gtk-3.0 -I/usr/local/include/pango-1.0 -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -I/usr/local/include -I/usr/local/include/cairo -I/usr/local/include/pixman-1 -I/usr/local/include/freetype2 -I/usr/local/include/libdrm -I/usr/local/include/libpng16 -I/usr/local/include/harfbuzz -I/usr/local/include/gdk-pixbuf-2.0 -I/usr/local/include/gio-unix-2.0/ -I/usr/local/include/atk-1.0 -D_THREAD_SAFE -I/usr/local/include/at-spi2-atk/2.0 -I/usr/local/include/at-spi-2.0 -I/usr/local/include/dbus-1.0 -I/usr/local/lib/dbus-1.0/include -pthread -I/usr/include/ -I/usr/local/include/librsvg-2.0/librsvg shoes/types/text_view.c
+cc -o /usr/home/ccoupe/build/freebsd/tmp/types/textblock.o -I. -c -g -O0 -DRUBY_HTTP -DBSD -DSHOES_GTK -fPIC -Wno-unused-variable -I/usr/include -I/opt/include/ruby-2.3.0/x86_64-freebsd11.1 -I/opt/include/ruby-2.3.0 -I/usr/local/include/gtk-3.0 -I/usr/local/include/pango-1.0 -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -I/usr/local/include -I/usr/local/include/cairo -I/usr/local/include/pixman-1 -I/usr/local/include/freetype2 -I/usr/local/include/libdrm -I/usr/local/include/libpng16 -I/usr/local/include/harfbuzz -I/usr/local/include/gdk-pixbuf-2.0 -I/usr/local/include/gio-unix-2.0/ -I/usr/local/include/atk-1.0 -D_THREAD_SAFE -I/usr/local/include/at-spi2-atk/2.0 -I/usr/local/include/at-spi-2.0 -I/usr/local/include/dbus-1.0 -I/usr/local/lib/dbus-1.0/include -pthread -I/usr/include/ -I/usr/local/include/librsvg-2.0/librsvg shoes/types/textblock.c
+cc -o /usr/home/ccoupe/build/freebsd/tmp/types/timerbase.o -I. -c -g -O0 -DRUBY_HTTP -DBSD -DSHOES_GTK -fPIC -Wno-unused-variable -I/usr/include -I/opt/include/ruby-2.3.0/x86_64-freebsd11.1 -I/opt/include/ruby-2.3.0 -I/usr/local/include/gtk-3.0 -I/usr/local/include/pango-1.0 -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -I/usr/local/include -I/usr/local/include/cairo -I/usr/local/include/pixman-1 -I/usr/local/include/freetype2 -I/usr/local/include/libdrm -I/usr/local/include/libpng16 -I/usr/local/include/harfbuzz -I/usr/local/include/gdk-pixbuf-2.0 -I/usr/local/include/gio-unix-2.0/ -I/usr/local/include/atk-1.0 -D_THREAD_SAFE -I/usr/local/include/at-spi2-atk/2.0 -I/usr/local/include/at-spi-2.0 -I/usr/local/include/dbus-1.0 -I/usr/local/lib/dbus-1.0/include -pthread -I/usr/include/ -I/usr/local/include/librsvg-2.0/librsvg shoes/types/timerbase.c
+cc -o /usr/home/ccoupe/build/freebsd/tmp/types/video.o -I. -c -g -O0 -DRUBY_HTTP -DBSD -DSHOES_GTK -fPIC -Wno-unused-variable -I/usr/include -I/opt/include/ruby-2.3.0/x86_64-freebsd11.1 -I/opt/include/ruby-2.3.0 -I/usr/local/include/gtk-3.0 -I/usr/local/include/pango-1.0 -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -I/usr/local/include -I/usr/local/include/cairo -I/usr/local/include/pixman-1 -I/usr/local/include/freetype2 -I/usr/local/include/libdrm -I/usr/local/include/libpng16 -I/usr/local/include/harfbuzz -I/usr/local/include/gdk-pixbuf-2.0 -I/usr/local/include/gio-unix-2.0/ -I/usr/local/include/atk-1.0 -D_THREAD_SAFE -I/usr/local/include/at-spi2-atk/2.0 -I/usr/local/include/at-spi-2.0 -I/usr/local/include/dbus-1.0 -I/usr/local/lib/dbus-1.0/include -pthread -I/usr/include/ -I/usr/local/include/librsvg-2.0/librsvg shoes/types/video.c
+touch /usr/home/ccoupe/build/freebsd/tmp/types/zzwidgets.done
+cc -o /usr/home/ccoupe/build/freebsd/tmp/native/gtk.o -I. -c -g -O0 -DRUBY_HTTP -DBSD -DSHOES_GTK -fPIC -Wno-unused-variable -I/usr/include -I/opt/include/ruby-2.3.0/x86_64-freebsd11.1 -I/opt/include/ruby-2.3.0 -I/usr/local/include/gtk-3.0 -I/usr/local/include/pango-1.0 -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -I/usr/local/include -I/usr/local/include/cairo -I/usr/local/include/pixman-1 -I/usr/local/include/freetype2 -I/usr/local/include/libdrm -I/usr/local/include/libpng16 -I/usr/local/include/harfbuzz -I/usr/local/include/gdk-pixbuf-2.0 -I/usr/local/include/gio-unix-2.0/ -I/usr/local/include/atk-1.0 -D_THREAD_SAFE -I/usr/local/include/at-spi2-atk/2.0 -I/usr/local/include/at-spi-2.0 -I/usr/local/include/dbus-1.0 -I/usr/local/lib/dbus-1.0/include -pthread -I/usr/include/ -I/usr/local/include/librsvg-2.0/librsvg shoes/native/gtk.c
+shoes/native/gtk.c:128:63: warning: incompatible pointer to integer conversion
+ passing 'void *' to parameter of type 'int' [-Wint-conversion]
+ status = g_application_run (G_APPLICATION (shoes_GtkApp), NULL, NULL);
+ ^~~~
+/usr/include/sys/_null.h:32:14: note: expanded from macro 'NULL'
+#define NULL ((void *)0)
+ ^~~~~~~~~~~
+/usr/local/include/glib-2.0/gio/gapplication.h:205:100: note: passing argument
+ to parameter 'argc' here
+ ...int argc,
+ ^
+shoes/native/gtk.c:627:13: warning: 'gdk_cursor_new' is deprecated
+ [-Wdeprecated-declarations]
+ c = gdk_cursor_new(GDK_HAND2);
+ ^
+/usr/local/include/gtk-3.0/gdk/gdkcursor.h:228:12: note: 'gdk_cursor_new' has
+ been explicitly marked deprecated here
+GdkCursor* gdk_cursor_new (GdkCursorType cursor_type);
+ ^
+shoes/native/gtk.c:629:13: warning: 'gdk_cursor_new' is deprecated
+ [-Wdeprecated-declarations]
+ c = gdk_cursor_new(GDK_ARROW);
+ ^
+/usr/local/include/gtk-3.0/gdk/gdkcursor.h:228:12: note: 'gdk_cursor_new' has
+ been explicitly marked deprecated here
+GdkCursor* gdk_cursor_new (GdkCursorType cursor_type);
+ ^
+shoes/native/gtk.c:631:13: warning: 'gdk_cursor_new' is deprecated
+ [-Wdeprecated-declarations]
+ c = gdk_cursor_new(GDK_XTERM);
+ ^
+/usr/local/include/gtk-3.0/gdk/gdkcursor.h:228:12: note: 'gdk_cursor_new' has
+ been explicitly marked deprecated here
+GdkCursor* gdk_cursor_new (GdkCursorType cursor_type);
+ ^
+shoes/native/gtk.c:678:5: warning: 'gtk_window_set_opacity' is deprecated
+ [-Wdeprecated-declarations]
+ gtk_window_set_opacity(GTK_WINDOW(app->os.window), opacity);
+ ^
+/usr/local/include/gtk-3.0/gtk/gtkwindow.h:200:12: note:
+ 'gtk_window_set_opacity' has been explicitly marked deprecated here
+void gtk_window_set_opacity (GtkWindow *window,
+ ^
+shoes/native/gtk.c:686:12: warning: 'gtk_window_get_opacity' is deprecated
+ [-Wdeprecated-declarations]
+ return gtk_window_get_opacity(GTK_WINDOW(app->os.window));
+ ^
+/usr/local/include/gtk-3.0/gtk/gtkwindow.h:203:12: note:
+ 'gtk_window_get_opacity' has been explicitly marked deprecated here
+gdouble gtk_window_get_opacity (GtkWindow *window);
+ ^
+shoes/native/gtk.c:867:19: warning: 'gdk_cairo_create' is deprecated
+ [-Wdeprecated-declarations]
+ cairo_t *cr = gdk_cairo_create(win);
+ ^
+/usr/local/include/gtk-3.0/gdk/gdkcairo.h:35:12: note: 'gdk_cairo_create' has
+ been explicitly marked deprecated here
+cairo_t * gdk_cairo_create (GdkWindow *window);
+ ^
+shoes/native/gtk.c:1125:43: warning: expression which evaluates to zero treated
+ as a null pointer constant of type 'const gchar *' (aka 'const char *')
+ [-Wnon-literal-null-conversion]
+ gtk_style_context_lookup_color(style, GTK_STATE_NORMAL, &bg);
+ ^~~~~~~~~~~~~~~~
+shoes/native/gtk.c:1133:43: warning: expression which evaluates to zero treated
+ as a null pointer constant of type 'const gchar *' (aka 'const char *')
+ [-Wnon-literal-null-conversion]
+ gtk_style_context_lookup_color(style, GTK_STATE_NORMAL, &bg);
+ ^~~~~~~~~~~~~~~~
+shoes/native/gtk.c:1208:5: warning: 'gtk_misc_set_alignment' is deprecated
+ [-Wdeprecated-declarations]
+ gtk_misc_set_alignment(GTK_MISC(question), 0, 0);
+ ^
+/usr/local/include/gtk-3.0/gtk/deprecated/gtkmisc.h:72:6: note:
+ 'gtk_misc_set_alignment' has been explicitly marked deprecated here
+void gtk_misc_set_alignment (GtkMisc *misc,
+ ^
+shoes/native/gtk.c:1208:28: warning: 'gtk_misc_get_type' is deprecated
+ [-Wdeprecated-declarations]
+ gtk_misc_set_alignment(GTK_MISC(question), 0, 0);
+ ^
+/usr/local/include/gtk-3.0/gtk/deprecated/gtkmisc.h:39:67: note: expanded from
+ macro 'GTK_MISC'
+#define GTK_MISC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_T...
+ ^
+/usr/local/include/gtk-3.0/gtk/deprecated/gtkmisc.h:38:32: note: expanded from
+ macro 'GTK_TYPE_MISC'
+#define GTK_TYPE_MISC (gtk_misc_get_type ())
+ ^
+/usr/local/include/gtk-3.0/gtk/deprecated/gtkmisc.h:70:9: note:
+ 'gtk_misc_get_type' has been explicitly marked deprecated here
+GType gtk_misc_get_type (void) G_GNUC_CONST;
+ ^
+shoes/native/gtk.c:1260:5: warning: 'gtk_misc_set_alignment' is deprecated
+ [-Wdeprecated-declarations]
+ gtk_misc_set_alignment(GTK_MISC(question), 0, 0);
+ ^
+/usr/local/include/gtk-3.0/gtk/deprecated/gtkmisc.h:72:6: note:
+ 'gtk_misc_set_alignment' has been explicitly marked deprecated here
+void gtk_misc_set_alignment (GtkMisc *misc,
+ ^
+shoes/native/gtk.c:1260:28: warning: 'gtk_misc_get_type' is deprecated
+ [-Wdeprecated-declarations]
+ gtk_misc_set_alignment(GTK_MISC(question), 0, 0);
+ ^
+/usr/local/include/gtk-3.0/gtk/deprecated/gtkmisc.h:39:67: note: expanded from
+ macro 'GTK_MISC'
+#define GTK_MISC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_T...
+ ^
+/usr/local/include/gtk-3.0/gtk/deprecated/gtkmisc.h:38:32: note: expanded from
+ macro 'GTK_TYPE_MISC'
+#define GTK_TYPE_MISC (gtk_misc_get_type ())
+ ^
+/usr/local/include/gtk-3.0/gtk/deprecated/gtkmisc.h:70:9: note:
+ 'gtk_misc_get_type' has been explicitly marked deprecated here
+GType gtk_misc_get_type (void) G_GNUC_CONST;
+ ^
+13 warnings generated.
+cc -o /usr/home/ccoupe/build/freebsd/tmp/native/gtkbuttonalt.o -I. -c -g -O0 -DRUBY_HTTP -DBSD -DSHOES_GTK -fPIC -Wno-unused-variable -I/usr/include -I/opt/include/ruby-2.3.0/x86_64-freebsd11.1 -I/opt/include/ruby-2.3.0 -I/usr/local/include/gtk-3.0 -I/usr/local/include/pango-1.0 -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -I/usr/local/include -I/usr/local/include/cairo -I/usr/local/include/pixman-1 -I/usr/local/include/freetype2 -I/usr/local/include/libdrm -I/usr/local/include/libpng16 -I/usr/local/include/harfbuzz -I/usr/local/include/gdk-pixbuf-2.0 -I/usr/local/include/gio-unix-2.0/ -I/usr/local/include/atk-1.0 -D_THREAD_SAFE -I/usr/local/include/at-spi2-atk/2.0 -I/usr/local/include/at-spi-2.0 -I/usr/local/include/dbus-1.0 -I/usr/local/lib/dbus-1.0/include -pthread -I/usr/include/ -I/usr/local/include/librsvg-2.0/librsvg shoes/native/gtk/gtkbuttonalt.c
+cc -o /usr/home/ccoupe/build/freebsd/tmp/native/gtkcheck.o -I. -c -g -O0 -DRUBY_HTTP -DBSD -DSHOES_GTK -fPIC -Wno-unused-variable -I/usr/include -I/opt/include/ruby-2.3.0/x86_64-freebsd11.1 -I/opt/include/ruby-2.3.0 -I/usr/local/include/gtk-3.0 -I/usr/local/include/pango-1.0 -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -I/usr/local/include -I/usr/local/include/cairo -I/usr/local/include/pixman-1 -I/usr/local/include/freetype2 -I/usr/local/include/libdrm -I/usr/local/include/libpng16 -I/usr/local/include/harfbuzz -I/usr/local/include/gdk-pixbuf-2.0 -I/usr/local/include/gio-unix-2.0/ -I/usr/local/include/atk-1.0 -D_THREAD_SAFE -I/usr/local/include/at-spi2-atk/2.0 -I/usr/local/include/at-spi-2.0 -I/usr/local/include/dbus-1.0 -I/usr/local/lib/dbus-1.0/include -pthread -I/usr/include/ -I/usr/local/include/librsvg-2.0/librsvg shoes/native/gtk/gtkcheck.c
+cc -o /usr/home/ccoupe/build/freebsd/tmp/native/gtkcomboboxtextalt.o -I. -c -g -O0 -DRUBY_HTTP -DBSD -DSHOES_GTK -fPIC -Wno-unused-variable -I/usr/include -I/opt/include/ruby-2.3.0/x86_64-freebsd11.1 -I/opt/include/ruby-2.3.0 -I/usr/local/include/gtk-3.0 -I/usr/local/include/pango-1.0 -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -I/usr/local/include -I/usr/local/include/cairo -I/usr/local/include/pixman-1 -I/usr/local/include/freetype2 -I/usr/local/include/libdrm -I/usr/local/include/libpng16 -I/usr/local/include/harfbuzz -I/usr/local/include/gdk-pixbuf-2.0 -I/usr/local/include/gio-unix-2.0/ -I/usr/local/include/atk-1.0 -D_THREAD_SAFE -I/usr/local/include/at-spi2-atk/2.0 -I/usr/local/include/at-spi-2.0 -I/usr/local/include/dbus-1.0 -I/usr/local/lib/dbus-1.0/include -pthread -I/usr/include/ -I/usr/local/include/librsvg-2.0/librsvg shoes/native/gtk/gtkcomboboxtextalt.c
+cc -o /usr/home/ccoupe/build/freebsd/tmp/native/gtkeditbox.o -I. -c -g -O0 -DRUBY_HTTP -DBSD -DSHOES_GTK -fPIC -Wno-unused-variable -I/usr/include -I/opt/include/ruby-2.3.0/x86_64-freebsd11.1 -I/opt/include/ruby-2.3.0 -I/usr/local/include/gtk-3.0 -I/usr/local/include/pango-1.0 -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -I/usr/local/include -I/usr/local/include/cairo -I/usr/local/include/pixman-1 -I/usr/local/include/freetype2 -I/usr/local/include/libdrm -I/usr/local/include/libpng16 -I/usr/local/include/harfbuzz -I/usr/local/include/gdk-pixbuf-2.0 -I/usr/local/include/gio-unix-2.0/ -I/usr/local/include/atk-1.0 -D_THREAD_SAFE -I/usr/local/include/at-spi2-atk/2.0 -I/usr/local/include/at-spi-2.0 -I/usr/local/include/dbus-1.0 -I/usr/local/lib/dbus-1.0/include -pthread -I/usr/include/ -I/usr/local/include/librsvg-2.0/librsvg shoes/native/gtk/gtkeditbox.c
+cc -o /usr/home/ccoupe/build/freebsd/tmp/native/gtkeditline.o -I. -c -g -O0 -DRUBY_HTTP -DBSD -DSHOES_GTK -fPIC -Wno-unused-variable -I/usr/include -I/opt/include/ruby-2.3.0/x86_64-freebsd11.1 -I/opt/include/ruby-2.3.0 -I/usr/local/include/gtk-3.0 -I/usr/local/include/pango-1.0 -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -I/usr/local/include -I/usr/local/include/cairo -I/usr/local/include/pixman-1 -I/usr/local/include/freetype2 -I/usr/local/include/libdrm -I/usr/local/include/libpng16 -I/usr/local/include/harfbuzz -I/usr/local/include/gdk-pixbuf-2.0 -I/usr/local/include/gio-unix-2.0/ -I/usr/local/include/atk-1.0 -D_THREAD_SAFE -I/usr/local/include/at-spi2-atk/2.0 -I/usr/local/include/at-spi-2.0 -I/usr/local/include/dbus-1.0 -I/usr/local/lib/dbus-1.0/include -pthread -I/usr/include/ -I/usr/local/include/librsvg-2.0/librsvg shoes/native/gtk/gtkeditline.c
+cc -o /usr/home/ccoupe/build/freebsd/tmp/native/gtkentryalt.o -I. -c -g -O0 -DRUBY_HTTP -DBSD -DSHOES_GTK -fPIC -Wno-unused-variable -I/usr/include -I/opt/include/ruby-2.3.0/x86_64-freebsd11.1 -I/opt/include/ruby-2.3.0 -I/usr/local/include/gtk-3.0 -I/usr/local/include/pango-1.0 -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -I/usr/local/include -I/usr/local/include/cairo -I/usr/local/include/pixman-1 -I/usr/local/include/freetype2 -I/usr/local/include/libdrm -I/usr/local/include/libpng16 -I/usr/local/include/harfbuzz -I/usr/local/include/gdk-pixbuf-2.0 -I/usr/local/include/gio-unix-2.0/ -I/usr/local/include/atk-1.0 -D_THREAD_SAFE -I/usr/local/include/at-spi2-atk/2.0 -I/usr/local/include/at-spi-2.0 -I/usr/local/include/dbus-1.0 -I/usr/local/lib/dbus-1.0/include -pthread -I/usr/include/ -I/usr/local/include/librsvg-2.0/librsvg shoes/native/gtk/gtkentryalt.c
+cc -o /usr/home/ccoupe/build/freebsd/tmp/native/gtkfixedalt.o -I. -c -g -O0 -DRUBY_HTTP -DBSD -DSHOES_GTK -fPIC -Wno-unused-variable -I/usr/include -I/opt/include/ruby-2.3.0/x86_64-freebsd11.1 -I/opt/include/ruby-2.3.0 -I/usr/local/include/gtk-3.0 -I/usr/local/include/pango-1.0 -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -I/usr/local/include -I/usr/local/include/cairo -I/usr/local/include/pixman-1 -I/usr/local/include/freetype2 -I/usr/local/include/libdrm -I/usr/local/include/libpng16 -I/usr/local/include/harfbuzz -I/usr/local/include/gdk-pixbuf-2.0 -I/usr/local/include/gio-unix-2.0/ -I/usr/local/include/atk-1.0 -D_THREAD_SAFE -I/usr/local/include/at-spi2-atk/2.0 -I/usr/local/include/at-spi-2.0 -I/usr/local/include/dbus-1.0 -I/usr/local/lib/dbus-1.0/include -pthread -I/usr/include/ -I/usr/local/include/librsvg-2.0/librsvg shoes/native/gtk/gtkfixedalt.c
+cc -o /usr/home/ccoupe/build/freebsd/tmp/native/gtkprogressbaralt.o -I. -c -g -O0 -DRUBY_HTTP -DBSD -DSHOES_GTK -fPIC -Wno-unused-variable -I/usr/include -I/opt/include/ruby-2.3.0/x86_64-freebsd11.1 -I/opt/include/ruby-2.3.0 -I/usr/local/include/gtk-3.0 -I/usr/local/include/pango-1.0 -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -I/usr/local/include -I/usr/local/include/cairo -I/usr/local/include/pixman-1 -I/usr/local/include/freetype2 -I/usr/local/include/libdrm -I/usr/local/include/libpng16 -I/usr/local/include/harfbuzz -I/usr/local/include/gdk-pixbuf-2.0 -I/usr/local/include/gio-unix-2.0/ -I/usr/local/include/atk-1.0 -D_THREAD_SAFE -I/usr/local/include/at-spi2-atk/2.0 -I/usr/local/include/at-spi-2.0 -I/usr/local/include/dbus-1.0 -I/usr/local/lib/dbus-1.0/include -pthread -I/usr/include/ -I/usr/local/include/librsvg-2.0/librsvg shoes/native/gtk/gtkprogressbaralt.c
+cc -o /usr/home/ccoupe/build/freebsd/tmp/native/gtkradio.o -I. -c -g -O0 -DRUBY_HTTP -DBSD -DSHOES_GTK -fPIC -Wno-unused-variable -I/usr/include -I/opt/include/ruby-2.3.0/x86_64-freebsd11.1 -I/opt/include/ruby-2.3.0 -I/usr/local/include/gtk-3.0 -I/usr/local/include/pango-1.0 -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -I/usr/local/include -I/usr/local/include/cairo -I/usr/local/include/pixman-1 -I/usr/local/include/freetype2 -I/usr/local/include/libdrm -I/usr/local/include/libpng16 -I/usr/local/include/harfbuzz -I/usr/local/include/gdk-pixbuf-2.0 -I/usr/local/include/gio-unix-2.0/ -I/usr/local/include/atk-1.0 -D_THREAD_SAFE -I/usr/local/include/at-spi2-atk/2.0 -I/usr/local/include/at-spi-2.0 -I/usr/local/include/dbus-1.0 -I/usr/local/lib/dbus-1.0/include -pthread -I/usr/include/ -I/usr/local/include/librsvg-2.0/librsvg shoes/native/gtk/gtkradio.c
+cc -o /usr/home/ccoupe/build/freebsd/tmp/native/gtkscrolledwindowalt.o -I. -c -g -O0 -DRUBY_HTTP -DBSD -DSHOES_GTK -fPIC -Wno-unused-variable -I/usr/include -I/opt/include/ruby-2.3.0/x86_64-freebsd11.1 -I/opt/include/ruby-2.3.0 -I/usr/local/include/gtk-3.0 -I/usr/local/include/pango-1.0 -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -I/usr/local/include -I/usr/local/include/cairo -I/usr/local/include/pixman-1 -I/usr/local/include/freetype2 -I/usr/local/include/libdrm -I/usr/local/include/libpng16 -I/usr/local/include/harfbuzz -I/usr/local/include/gdk-pixbuf-2.0 -I/usr/local/include/gio-unix-2.0/ -I/usr/local/include/atk-1.0 -D_THREAD_SAFE -I/usr/local/include/at-spi2-atk/2.0 -I/usr/local/include/at-spi-2.0 -I/usr/local/include/dbus-1.0 -I/usr/local/lib/dbus-1.0/include -pthread -I/usr/include/ -I/usr/local/include/librsvg-2.0/librsvg shoes/native/gtk/gtkscrolledwindowalt.c
+cc -o /usr/home/ccoupe/build/freebsd/tmp/native/gtkspinner.o -I. -c -g -O0 -DRUBY_HTTP -DBSD -DSHOES_GTK -fPIC -Wno-unused-variable -I/usr/include -I/opt/include/ruby-2.3.0/x86_64-freebsd11.1 -I/opt/include/ruby-2.3.0 -I/usr/local/include/gtk-3.0 -I/usr/local/include/pango-1.0 -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -I/usr/local/include -I/usr/local/include/cairo -I/usr/local/include/pixman-1 -I/usr/local/include/freetype2 -I/usr/local/include/libdrm -I/usr/local/include/libpng16 -I/usr/local/include/harfbuzz -I/usr/local/include/gdk-pixbuf-2.0 -I/usr/local/include/gio-unix-2.0/ -I/usr/local/include/atk-1.0 -D_THREAD_SAFE -I/usr/local/include/at-spi2-atk/2.0 -I/usr/local/include/at-spi-2.0 -I/usr/local/include/dbus-1.0 -I/usr/local/lib/dbus-1.0/include -pthread -I/usr/include/ -I/usr/local/include/librsvg-2.0/librsvg shoes/native/gtk/gtkspinner.c
+cc -o /usr/home/ccoupe/build/freebsd/tmp/native/gtkswitch.o -I. -c -g -O0 -DRUBY_HTTP -DBSD -DSHOES_GTK -fPIC -Wno-unused-variable -I/usr/include -I/opt/include/ruby-2.3.0/x86_64-freebsd11.1 -I/opt/include/ruby-2.3.0 -I/usr/local/include/gtk-3.0 -I/usr/local/include/pango-1.0 -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -I/usr/local/include -I/usr/local/include/cairo -I/usr/local/include/pixman-1 -I/usr/local/include/freetype2 -I/usr/local/include/libdrm -I/usr/local/include/libpng16 -I/usr/local/include/harfbuzz -I/usr/local/include/gdk-pixbuf-2.0 -I/usr/local/include/gio-unix-2.0/ -I/usr/local/include/atk-1.0 -D_THREAD_SAFE -I/usr/local/include/at-spi2-atk/2.0 -I/usr/local/include/at-spi-2.0 -I/usr/local/include/dbus-1.0 -I/usr/local/lib/dbus-1.0/include -pthread -I/usr/include/ -I/usr/local/include/librsvg-2.0/librsvg shoes/native/gtk/gtkswitch.c
+cc -o /usr/home/ccoupe/build/freebsd/tmp/native/gtksystray.o -I. -c -g -O0 -DRUBY_HTTP -DBSD -DSHOES_GTK -fPIC -Wno-unused-variable -I/usr/include -I/opt/include/ruby-2.3.0/x86_64-freebsd11.1 -I/opt/include/ruby-2.3.0 -I/usr/local/include/gtk-3.0 -I/usr/local/include/pango-1.0 -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -I/usr/local/include -I/usr/local/include/cairo -I/usr/local/include/pixman-1 -I/usr/local/include/freetype2 -I/usr/local/include/libdrm -I/usr/local/include/libpng16 -I/usr/local/include/harfbuzz -I/usr/local/include/gdk-pixbuf-2.0 -I/usr/local/include/gio-unix-2.0/ -I/usr/local/include/atk-1.0 -D_THREAD_SAFE -I/usr/local/include/at-spi2-atk/2.0 -I/usr/local/include/at-spi-2.0 -I/usr/local/include/dbus-1.0 -I/usr/local/lib/dbus-1.0/include -pthread -I/usr/include/ -I/usr/local/include/librsvg-2.0/librsvg shoes/native/gtk/gtksystray.c
+shoes/native/gtk/gtksystray.c:28:19: warning: 'gtk_status_icon_new_from_file' is
+ deprecated [-Wdeprecated-declarations]
+ stsicon = gtk_status_icon_new_from_file(path);
+ ^
+/usr/local/include/gtk-3.0/gtk/deprecated/gtkstatusicon.h:88:23: note:
+ 'gtk_status_icon_new_from_file' has been explicitly marked deprecated here
+GtkStatusIcon *gtk_status_icon_new_from_file (const gcha...
+ ^
+shoes/native/gtk/gtksystray.c:34:9: warning: 'gtk_status_icon_set_from_file' is
+ deprecated [-Wdeprecated-declarations]
+ gtk_status_icon_set_from_file (stsicon, stspath);
+ ^
+/usr/local/include/gtk-3.0/gtk/deprecated/gtkstatusicon.h:100:23: note:
+ 'gtk_status_icon_set_from_file' has been explicitly marked deprecated here
+void gtk_status_icon_set_from_file (GtkStatusIco...
+ ^
+shoes/native/gtk/gtksystray.c:36:5: warning: 'gtk_status_icon_set_title' is
+ deprecated [-Wdeprecated-declarations]
+ gtk_status_icon_set_title(stsicon, title);
+ ^
+/usr/local/include/gtk-3.0/gtk/deprecated/gtkstatusicon.h:143:23: note:
+ 'gtk_status_icon_set_title' has been explicitly marked deprecated here
+void gtk_status_icon_set_title (GtkStatusIco...
+ ^
+shoes/native/gtk/gtksystray.c:37:5: warning: 'gtk_status_icon_set_tooltip_text'
+ is deprecated [-Wdeprecated-declarations]
+ gtk_status_icon_set_tooltip_text(stsicon, message);
+ ^
+/usr/local/include/gtk-3.0/gtk/deprecated/gtkstatusicon.h:137:23: note:
+ 'gtk_status_icon_set_tooltip_text' has been explicitly marked deprecated
+ here
+void gtk_status_icon_set_tooltip_text (GtkStatusIco...
+ ^
+4 warnings generated.
+cc -o /usr/home/ccoupe/build/freebsd/tmp/native/gtktextview.o -I. -c -g -O0 -DRUBY_HTTP -DBSD -DSHOES_GTK -fPIC -Wno-unused-variable -I/usr/include -I/opt/include/ruby-2.3.0/x86_64-freebsd11.1 -I/opt/include/ruby-2.3.0 -I/usr/local/include/gtk-3.0 -I/usr/local/include/pango-1.0 -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -I/usr/local/include -I/usr/local/include/cairo -I/usr/local/include/pixman-1 -I/usr/local/include/freetype2 -I/usr/local/include/libdrm -I/usr/local/include/libpng16 -I/usr/local/include/harfbuzz -I/usr/local/include/gdk-pixbuf-2.0 -I/usr/local/include/gio-unix-2.0/ -I/usr/local/include/atk-1.0 -D_THREAD_SAFE -I/usr/local/include/at-spi2-atk/2.0 -I/usr/local/include/at-spi-2.0 -I/usr/local/include/dbus-1.0 -I/usr/local/lib/dbus-1.0/include -pthread -I/usr/include/ -I/usr/local/include/librsvg-2.0/librsvg shoes/native/gtk/gtktextview.c
+cc -o /usr/home/ccoupe/build/freebsd/tmp/native/gtktimerbase.o -I. -c -g -O0 -DRUBY_HTTP -DBSD -DSHOES_GTK -fPIC -Wno-unused-variable -I/usr/include -I/opt/include/ruby-2.3.0/x86_64-freebsd11.1 -I/opt/include/ruby-2.3.0 -I/usr/local/include/gtk-3.0 -I/usr/local/include/pango-1.0 -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -I/usr/local/include -I/usr/local/include/cairo -I/usr/local/include/pixman-1 -I/usr/local/include/freetype2 -I/usr/local/include/libdrm -I/usr/local/include/libpng16 -I/usr/local/include/harfbuzz -I/usr/local/include/gdk-pixbuf-2.0 -I/usr/local/include/gio-unix-2.0/ -I/usr/local/include/atk-1.0 -D_THREAD_SAFE -I/usr/local/include/at-spi2-atk/2.0 -I/usr/local/include/at-spi-2.0 -I/usr/local/include/dbus-1.0 -I/usr/local/lib/dbus-1.0/include -pthread -I/usr/include/ -I/usr/local/include/librsvg-2.0/librsvg shoes/native/gtk/gtktimerbase.c
+cc -o /usr/home/ccoupe/build/freebsd/tmp/native/gtkvideo.o -I. -c -g -O0 -DRUBY_HTTP -DBSD -DSHOES_GTK -fPIC -Wno-unused-variable -I/usr/include -I/opt/include/ruby-2.3.0/x86_64-freebsd11.1 -I/opt/include/ruby-2.3.0 -I/usr/local/include/gtk-3.0 -I/usr/local/include/pango-1.0 -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -I/usr/local/include -I/usr/local/include/cairo -I/usr/local/include/pixman-1 -I/usr/local/include/freetype2 -I/usr/local/include/libdrm -I/usr/local/include/libpng16 -I/usr/local/include/harfbuzz -I/usr/local/include/gdk-pixbuf-2.0 -I/usr/local/include/gio-unix-2.0/ -I/usr/local/include/atk-1.0 -D_THREAD_SAFE -I/usr/local/include/at-spi2-atk/2.0 -I/usr/local/include/at-spi-2.0 -I/usr/local/include/dbus-1.0 -I/usr/local/lib/dbus-1.0/include -pthread -I/usr/include/ -I/usr/local/include/librsvg-2.0/librsvg shoes/native/gtk/gtkvideo.c
+shoes/native/gtk/gtkvideo.c:41:5: warning:
+ 'gtk_widget_override_background_color' is deprecated
+ [-Wdeprecated-declarations]
+ gtk_widget_override_background_color(GTK_WIDGET(da), 0, &color);
+ ^
+/usr/local/include/gtk-3.0/gtk/gtkwidget.h:1148:14: note:
+ 'gtk_widget_override_background_color' has been explicitly marked
+ deprecated here
+void gtk_widget_override_background_color (GtkWidget *widget,
+ ^
+1 warning generated.
+touch /usr/home/ccoupe/build/freebsd/tmp/native/zznative.done
+cp static/manual-en.txt /usr/home/ccoupe/build/freebsd/static/manual-en.txt
+touch /usr/home/ccoupe/build/freebsd/tmp/copyonly/zzmanual.done
+cp lib/shoes.rb /usr/home/ccoupe/build/freebsd/lib/shoes.rb
+touch /usr/home/ccoupe/build/freebsd/tmp/copyonly/zzshoesrb.done
+cc -o /usr/home/ccoupe/build/freebsd/tmp/version.o -I. -c -g -O0 -DRUBY_HTTP -DBSD -DSHOES_GTK -fPIC -Wno-unused-variable -I/usr/include -I/opt/include/ruby-2.3.0/x86_64-freebsd11.1 -I/opt/include/ruby-2.3.0 -I/usr/local/include/gtk-3.0 -I/usr/local/include/pango-1.0 -I/usr/local/include/glib-2.0 -I/usr/local/lib/glib-2.0/include -I/usr/local/include -I/usr/local/include/cairo -I/usr/local/include/pixman-1 -I/usr/local/include/freetype2 -I/usr/local/include/libdrm -I/usr/local/include/libpng16 -I/usr/local/include/harfbuzz -I/usr/local/include/gdk-pixbuf-2.0 -I/usr/local/include/gio-unix-2.0/ -I/usr/local/include/atk-1.0 -D_THREAD_SAFE -I/usr/local/include/at-spi2-atk/2.0 -I/usr/local/include/at-spi-2.0 -I/usr/local/include/dbus-1.0 -I/usr/local/lib/dbus-1.0/include -pthread -I/usr/include/ -I/usr/local/include/librsvg-2.0/librsvg shoes/version.c
+new_so: /usr/home/ccoupe/build/freebsd from /usr/home/ccoupe/build/freebsd/libshoes.so
+cc -o /usr/home/ccoupe/build/freebsd/libshoes.so /usr/home/ccoupe/build/freebsd/tmp/app.o /usr/home/ccoupe/build/freebsd/tmp/canvas.o /usr/home/ccoupe/build/freebsd/tmp/image.o /usr/home/ccoupe/build/freebsd/tmp/internal.o /usr/home/ccoupe/build/freebsd/tmp/main.o /usr/home/ccoupe/build/freebsd/tmp/ruby.o /usr/home/ccoupe/build/freebsd/tmp/version.o /usr/home/ccoupe/build/freebsd/tmp/world.o /usr/home/ccoupe/build/freebsd/tmp/http/rbload.o /usr/home/ccoupe/build/freebsd/tmp/plot/chart_series.o /usr/home/ccoupe/build/freebsd/tmp/plot/plot.o /usr/home/ccoupe/build/freebsd/tmp/plot/plot_column.o /usr/home/ccoupe/build/freebsd/tmp/plot/plot_line.o /usr/home/ccoupe/build/freebsd/tmp/plot/plot_pie.o /usr/home/ccoupe/build/freebsd/tmp/plot/plot_radar.o /usr/home/ccoupe/build/freebsd/tmp/plot/plot_scatter.o /usr/home/ccoupe/build/freebsd/tmp/plot/plot_util.o /usr/home/ccoupe/build/freebsd/tmp/console/colortab.o /usr/home/ccoupe/build/freebsd/tmp/console/gtk-terminal.o /usr/home/ccoupe/build/freebsd/tmp/console/tesi.o /usr/home/ccoupe/build/freebsd/tmp/types/button.o /usr/home/ccoupe/build/freebsd/tmp/types/check.o /usr/home/ccoupe/build/freebsd/tmp/types/color.o /usr/home/ccoupe/build/freebsd/tmp/types/download.o /usr/home/ccoupe/build/freebsd/tmp/types/edit_box.o /usr/home/ccoupe/build/freebsd/tmp/types/edit_line.o /usr/home/ccoupe/build/freebsd/tmp/types/effect.o /usr/home/ccoupe/build/freebsd/tmp/types/image.o /usr/home/ccoupe/build/freebsd/tmp/types/list_box.o /usr/home/ccoupe/build/freebsd/tmp/types/native.o /usr/home/ccoupe/build/freebsd/tmp/types/pattern.o /usr/home/ccoupe/build/freebsd/tmp/types/plot.o /usr/home/ccoupe/build/freebsd/tmp/types/progress.o /usr/home/ccoupe/build/freebsd/tmp/types/radio.o /usr/home/ccoupe/build/freebsd/tmp/types/shape.o /usr/home/ccoupe/build/freebsd/tmp/types/slider.o /usr/home/ccoupe/build/freebsd/tmp/types/spinner.o /usr/home/ccoupe/build/freebsd/tmp/types/svg.o /usr/home/ccoupe/build/freebsd/tmp/types/switch.o /usr/home/ccoupe/build/freebsd/tmp/types/systray.o /usr/home/ccoupe/build/freebsd/tmp/types/text.o /usr/home/ccoupe/build/freebsd/tmp/types/text_link.o /usr/home/ccoupe/build/freebsd/tmp/types/text_view.o /usr/home/ccoupe/build/freebsd/tmp/types/textblock.o /usr/home/ccoupe/build/freebsd/tmp/types/timerbase.o /usr/home/ccoupe/build/freebsd/tmp/types/video.o /usr/home/ccoupe/build/freebsd/tmp/native/gtk.o /usr/home/ccoupe/build/freebsd/tmp/native/gtkbuttonalt.o /usr/home/ccoupe/build/freebsd/tmp/native/gtkcheck.o /usr/home/ccoupe/build/freebsd/tmp/native/gtkcomboboxtextalt.o /usr/home/ccoupe/build/freebsd/tmp/native/gtkeditbox.o /usr/home/ccoupe/build/freebsd/tmp/native/gtkeditline.o /usr/home/ccoupe/build/freebsd/tmp/native/gtkentryalt.o /usr/home/ccoupe/build/freebsd/tmp/native/gtkfixedalt.o /usr/home/ccoupe/build/freebsd/tmp/native/gtkprogressbaralt.o /usr/home/ccoupe/build/freebsd/tmp/native/gtkradio.o /usr/home/ccoupe/build/freebsd/tmp/native/gtkscrolledwindowalt.o /usr/home/ccoupe/build/freebsd/tmp/native/gtkspinner.o /usr/home/ccoupe/build/freebsd/tmp/native/gtkswitch.o /usr/home/ccoupe/build/freebsd/tmp/native/gtksystray.o /usr/home/ccoupe/build/freebsd/tmp/native/gtktextview.o /usr/home/ccoupe/build/freebsd/tmp/native/gtktimerbase.o /usr/home/ccoupe/build/freebsd/tmp/native/gtkvideo.o -fPIC -shared -L/usr/lib/x86_64-linux-gnu -L/usr/local/lib -lgtk-3 -lgdk-3 -lpangocairo-1.0 -lpango-1.0 -latk-1.0 -lcairo-gobject -lcairo -lpthread -lgdk_pixbuf-2.0 -lgio-2.0 -lgobject-2.0 -lglib-2.0 -lintl -lgif -ljpeg -rdynamic -Wl,-export-dynamic -L/opt/lib -lruby -lelf -lexecinfo -lprocstat -lthr -lcrypt -lm -L/usr/local/lib -lcairo -lpthread -L/usr/local/lib -lpango-1.0 -lgobject-2.0 -lglib-2.0 -lintl /usr/local/lib/librsvg-2.so
+new_link: arg=/usr/home/ccoupe/build/freebsd/shoes
+cc -o /usr/home/ccoupe/build/freebsd/shoes-bin /usr/home/ccoupe/build/freebsd/tmp/main.o -L/usr/home/ccoupe/build/freebsd -lshoes -L/usr/home/ccoupe/build/freebsd -lgif -ljpeg -rdynamic -Wl,-export-dynamic -L/opt/lib -lruby -lelf -lexecinfo -lprocstat -lthr -lcrypt -lm -L/usr/local/lib -lcairo -lpthread -L/usr/local/lib -lpango-1.0 -lgobject-2.0 -lglib-2.0 -lintl /usr/local/lib/librsvg-2.so
+echo 'cd "$OLDPWD"
+LD_LIBRARY_PATH=$APPPATH $APPPATH/shoes-bin "$@"' >> /usr/home/ccoupe/build/freebsd/shoes
+echo 'cd "$OLDPWD"
+LD_LIBRARY_PATH=$APPPATH gdb $APPPATH/shoes-bin "$@"' >> /usr/home/ccoupe/build/freebsd/debug
+$
diff --git a/lib/shoes.rb b/lib/shoes.rb
index 11b824a3..b7483f11 100644
--- a/lib/shoes.rb
+++ b/lib/shoes.rb
@@ -147,7 +147,7 @@ def self.package_app
end
def self.splash
- font "#{DIR}/fonts/Lacuna.ttf"
+ font "#{DIR}/fonts/Lacuna.ttf" unless Shoes::FONTS.include? "Lacuna"
Shoes.app width: 598, height: 520, resizable: false do
background "#{DIR}/static/splash.png"
style(Para, align: 'center', weight: 'bold', font: 'Lacuna Regular', size: 13)
@@ -171,7 +171,7 @@ def self.splash
#para link(strong("Profile an App")) {Shoes.profiler and close}, :margin => 10, :margin_bottom => 4
para link(strong("Bundle an App (shy)")) { Shoes.package_app and close }, :margin => 10, :margin_bottom => 4
para link(strong("Package an App with Shoes")) {Shoes.app_package and close }, :margin => 10, :margin_bottom => 4
-# para link("Obsolete: Package") { Shoes.make_pack and close }, :margin => 10, :margin_bottom => 4
+ #para link("Obsolete: Package") { Shoes.make_pack and close }, :margin => 10, :margin_bottom => 4
end
para 'Alt-Slash opens the console', stroke: '#00', align: 'center'
end
@@ -266,6 +266,8 @@ def self.run(path)
# This is the real entry point for shows. It's called from the C startup code
def self.args!(osx_launch = nil)
+ require_relative "shoes/deprecated"
+
if (ARGV.empty?)
Shoes.splash if !osx_launch || osx_launch == '0'
return true
diff --git a/lib/shoes/app_package.rb b/lib/shoes/app_package.rb
index d3aed32f..f4f95da0 100644
--- a/lib/shoes/app_package.rb
+++ b/lib/shoes/app_package.rb
@@ -183,8 +183,8 @@
end
@select_panel.clear
@select_panel.background white
- @platforms.each_key do |k|
- ln = @platforms[k]
+ @platforms.each_key do |k|
+ ln = @platforms[k]
flds = ln.split(' ')
parts = flds[2].split('-')
@select_panel.append do
@@ -200,7 +200,7 @@
para " #{parts[0]} #{parts[1]}"
end
end
- end
+ end
else
@info_panel = para "Failed"
end
@@ -237,7 +237,7 @@ def platform_merge ln
return # short circuit - ignore .runs in 3.2.15+
when /osx\-.*\.tgz$/
@platforms['OSX'] = ln
- when /armhf\.run$/
+ when /armhf\.run$/
@platforms['Linux_Raspberry'] = ln
when /i686\.run$/
@platforms['Linux_i686'] = ln
@@ -249,6 +249,8 @@ def platform_merge ln
@platforms['Linux_i686'] = ln
when /x86_64\.install$/
@platforms['Linux_x86_64'] = ln
+ when /freebsd\.install/
+ @platforms['FreeBSD 11.1'] = ln
when /tar\.gz$/
tarball = ln
else
@@ -376,6 +378,7 @@ def dnlif_linux installname
# the packed install.sh
arch = installname[/(\w+)\.install$/]
arch.gsub!(/\.install/,"")
+ debug "dnlif #{installname} => #{arch}"
@options['app'] = $script_path
@options['arch'] = arch
@options['dnlhost'] = @dnlhost
@@ -419,6 +422,7 @@ def repack_linux arch
@options['packtmp'] = LIB_DIR
@options['relname'] = Shoes::RELEASE_NAME
@options['shoesdist'] = @work_path
+ $stderr.puts "repack_linux #{@options.inspect}"
PackShoes.repack_linux @options do |msg|
@pkgstat.text = msg
end
diff --git a/lib/shoes/cacert.pem b/lib/shoes/cacert.pem
new file mode 100644
index 00000000..8f1357b6
--- /dev/null
+++ b/lib/shoes/cacert.pem
@@ -0,0 +1,3955 @@
+##
+## Bundle of CA Root Certificates
+##
+## Certificate data from Mozilla as of: Wed Jun 7 03:12:05 2017 GMT
+##
+## This is a bundle of X.509 certificates of public Certificate Authorities
+## (CA). These were automatically extracted from Mozilla's root certificates
+## file (certdata.txt). This file can be found in the mozilla source tree:
+## https://hg.mozilla.org/releases/mozilla-release/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt
+##
+## It contains the certificates in PEM format and therefore
+## can be directly used with curl / libcurl / php_curl, or with
+## an Apache+mod_ssl webserver for SSL client authentication.
+## Just configure this file as the SSLCACertificateFile.
+##
+## Conversion done with mk-ca-bundle.pl version 1.27.
+## SHA256: 93753268e1c596aee21893fb1c6975338389132f15c942ed65fc394a904371d7
+##
+
+
+GlobalSign Root CA
+==================
+-----BEGIN CERTIFICATE-----
+MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkGA1UEBhMCQkUx
+GTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jvb3QgQ0ExGzAZBgNVBAMTEkds
+b2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAwMDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNV
+BAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYD
+VQQDExJHbG9iYWxTaWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDa
+DuaZjc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavpxy0Sy6sc
+THAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp1Wrjsok6Vjk4bwY8iGlb
+Kk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdGsnUOhugZitVtbNV4FpWi6cgKOOvyJBNP
+c1STE4U6G7weNLWLBYy5d4ux2x8gkasJU26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrX
+gzT/LCrBbBlDSgeF59N89iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV
+HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0BAQUF
+AAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOzyj1hTdNGCbM+w6Dj
+Y1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE38NflNUVyRRBnMRddWQVDf9VMOyG
+j/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymPAbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhH
+hm4qxFYxldBniYUr+WymXUadDKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveC
+X4XSQRjbgbMEHMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A==
+-----END CERTIFICATE-----
+
+GlobalSign Root CA - R2
+=======================
+-----BEGIN CERTIFICATE-----
+MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4GA1UECxMXR2xv
+YmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2Jh
+bFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxT
+aWduIFJvb3QgQ0EgLSBSMjETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2ln
+bjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6
+ErPLv4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8eoLrvozp
+s6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklqtTleiDTsvHgMCJiEbKjN
+S7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzdC9XZzPnqJworc5HGnRusyMvo4KD0L5CL
+TfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pazq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6C
+ygPCm48CAwEAAaOBnDCBmTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E
+FgQUm+IHV2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5nbG9i
+YWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG3lm0mi3f3BmGLjAN
+BgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4GsJ0/WwbgcQ3izDJr86iw8bmEbTUsp
+9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu
+01yiPqFbQfXf5WRDLenVOavSot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG7
+9G+dwfCMNYxdAfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7
+TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg==
+-----END CERTIFICATE-----
+
+Verisign Class 3 Public Primary Certification Authority - G3
+============================================================
+-----BEGIN CERTIFICATE-----
+MIIEGjCCAwICEQCbfgZJoz5iudXukEhxKe9XMA0GCSqGSIb3DQEBBQUAMIHKMQswCQYDVQQGEwJV
+UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv
+cmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl
+IG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNh
+dGlvbiBBdXRob3JpdHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQsw
+CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRy
+dXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhv
+cml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkg
+Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
+ggEBAMu6nFL8eB8aHm8bN3O9+MlrlBIwT/A2R/XQkQr1F8ilYcEWQE37imGQ5XYgwREGfassbqb1
+EUGO+i2tKmFZpGcmTNDovFJbcCAEWNF6yaRpvIMXZK0Fi7zQWM6NjPXr8EJJC52XJ2cybuGukxUc
+cLwgTS8Y3pKI6GyFVxEa6X7jJhFUokWWVYPKMIno3Nij7SqAP395ZVc+FSBmCC+Vk7+qRy+oRpfw
+EuL+wgorUeZ25rdGt+INpsyow0xZVYnm6FNcHOqd8GIWC6fJXwzw3sJ2zq/3avL6QaaiMxTJ5Xpj
+055iN9WFZZ4O5lMkdBteHRJTW8cs54NJOxWuimi5V5cCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEA
+ERSWwauSCPc/L8my/uRan2Te2yFPhpk0djZX3dAVL8WtfxUfN2JzPtTnX84XA9s1+ivbrmAJXx5f
+j267Cz3qWhMeDGBvtcC1IyIuBwvLqXTLR7sdwdela8wv0kL9Sd2nic9TutoAWii/gt/4uhMdUIaC
+/Y4wjylGsB49Ndo4YhYYSq3mtlFs3q9i6wHQHiT+eo8SGhJouPtmmRQURVyu565pF4ErWjfJXir0
+xuKhXFSbplQAz/DxwceYMBo7Nhbbo27q/a2ywtrvAkcTisDxszGtTxzhT5yvDwyd93gN2PQ1VoDa
+t20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ==
+-----END CERTIFICATE-----
+
+Entrust.net Premium 2048 Secure Server CA
+=========================================
+-----BEGIN CERTIFICATE-----
+MIIEKjCCAxKgAwIBAgIEOGPe+DANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChMLRW50cnVzdC5u
+ZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBpbmNvcnAuIGJ5IHJlZi4gKGxp
+bWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNV
+BAMTKkVudHJ1c3QubmV0IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQx
+NzUwNTFaFw0yOTA3MjQxNDE1MTJaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3
+d3d3LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTEl
+MCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50cnVzdC5u
+ZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgpMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
+MIIBCgKCAQEArU1LqRKGsuqjIAcVFmQqK0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOL
+Gp18EzoOH1u3Hs/lJBQesYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSr
+hRSGlVuXMlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVTXTzW
+nLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/HoZdenoVve8AjhUi
+VBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH4QIDAQABo0IwQDAOBgNVHQ8BAf8E
+BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUVeSB0RGAvtiJuQijMfmhJAkWuXAwDQYJ
+KoZIhvcNAQEFBQADggEBADubj1abMOdTmXx6eadNl9cZlZD7Bh/KM3xGY4+WZiT6QBshJ8rmcnPy
+T/4xmf3IDExoU8aAghOY+rat2l098c5u9hURlIIM7j+VrxGrD9cv3h8Dj1csHsm7mhpElesYT6Yf
+zX1XEC+bBAlahLVu2B064dae0Wx5XnkcFMXj0EyTO2U87d89vqbllRrDtRnDvV5bu/8j72gZyxKT
+J1wDLW8w0B62GqzeWvfRqqgnpv55gcR5mTNXuhKwqeBCbJPKVt7+bYQLCIt+jerXmCHG8+c8eS9e
+nNFMFY3h7CI3zJpDC5fcgJCNs2ebb0gIFVbPv/ErfF6adulZkMV8gzURZVE=
+-----END CERTIFICATE-----
+
+Baltimore CyberTrust Root
+=========================
+-----BEGIN CERTIFICATE-----
+MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJRTESMBAGA1UE
+ChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYDVQQDExlCYWx0aW1vcmUgQ3li
+ZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoXDTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMC
+SUUxEjAQBgNVBAoTCUJhbHRpbW9yZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFs
+dGltb3JlIEN5YmVyVHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKME
+uyKrmD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjrIZ3AQSsB
+UnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeKmpYcqWe4PwzV9/lSEy/C
+G9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSuXmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9
+XbIGevOF6uvUA65ehD5f/xXtabz5OTZydc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjpr
+l3RjM71oGDHweI12v/yejl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoI
+VDaGezq1BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEB
+BQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT929hkTI7gQCvlYpNRh
+cL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3WgxjkzSswF07r51XgdIGn9w/xZchMB5
+hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsa
+Y71k5h+3zvDyny67G7fyUIhzksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9H
+RCwBXbsdtTLSR9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp
+-----END CERTIFICATE-----
+
+AddTrust Low-Value Services Root
+================================
+-----BEGIN CERTIFICATE-----
+MIIEGDCCAwCgAwIBAgIBATANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQGEwJTRTEUMBIGA1UEChML
+QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSEwHwYDVQQDExhBZGRU
+cnVzdCBDbGFzcyAxIENBIFJvb3QwHhcNMDAwNTMwMTAzODMxWhcNMjAwNTMwMTAzODMxWjBlMQsw
+CQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBO
+ZXR3b3JrMSEwHwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3QwggEiMA0GCSqGSIb3DQEB
+AQUAA4IBDwAwggEKAoIBAQCWltQhSWDia+hBBwzexODcEyPNwTXH+9ZOEQpnXvUGW2ulCDtbKRY6
+54eyNAbFvAWlA3yCyykQruGIgb3WntP+LVbBFc7jJp0VLhD7Bo8wBN6ntGO0/7Gcrjyvd7ZWxbWr
+oulpOj0OM3kyP3CCkplhbY0wCI9xP6ZIVxn4JdxLZlyldI+Yrsj5wAYi56xz36Uu+1LcsRVlIPo1
+Zmne3yzxbrww2ywkEtvrNTVokMsAsJchPXQhI2U0K7t4WaPW4XY5mqRJjox0r26kmqPZm9I4XJui
+GMx1I4S+6+JNM3GOGvDC+Mcdoq0Dlyz4zyXG9rgkMbFjXZJ/Y/AlyVMuH79NAgMBAAGjgdIwgc8w
+HQYDVR0OBBYEFJWxtPCUtr3H2tERCSG+wa9J/RB7MAsGA1UdDwQEAwIBBjAPBgNVHRMBAf8EBTAD
+AQH/MIGPBgNVHSMEgYcwgYSAFJWxtPCUtr3H2tERCSG+wa9J/RB7oWmkZzBlMQswCQYDVQQGEwJT
+RTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSEw
+HwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBACxt
+ZBsfzQ3duQH6lmM0MkhHma6X7f1yFqZzR1r0693p9db7RcwpiURdv0Y5PejuvE1Uhh4dbOMXJ0Ph
+iVYrqW9yTkkz43J8KiOavD7/KCrto/8cI7pDVwlnTUtiBi34/2ydYB7YHEt9tTEv2dB8Xfjea4MY
+eDdXL+gzB2ffHsdrKpV2ro9Xo/D0UrSpUwjP4E/TelOL/bscVjby/rK25Xa71SJlpz/+0WatC7xr
+mYbvP33zGDLKe8bjq2RGlfgmadlVg3sslgf/WSxEo8bl6ancoWOAWiFeIc9TVPC6b4nbqKqVz4vj
+ccweGyBECMB6tkD9xOQ14R0WHNC8K47Wcdk=
+-----END CERTIFICATE-----
+
+AddTrust External Root
+======================
+-----BEGIN CERTIFICATE-----
+MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEUMBIGA1UEChML
+QWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYD
+VQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEw
+NDgzOFowbzELMAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRU
+cnVzdCBFeHRlcm5hbCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0Eg
+Um9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvtH7xsD821
++iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9uMq/NzgtHj6RQa1wVsfw
+Tz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzXmk6vBbOmcZSccbNQYArHE504B4YCqOmo
+aSYYkKtMsE8jqzpPhNjfzp/haW+710LXa0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy
+2xSoRcRdKn23tNbE7qzNE0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv7
+7+ldU9U0WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYDVR0P
+BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0Jvf6xCZU7wO94CTL
+VBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEmMCQGA1UECxMdQWRk
+VHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsxIjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENB
+IFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZl
+j7DYd7usQWxHYINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5
+6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvCNr4TDea9Y355
+e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEXc4g/VhsxOBi0cQ+azcgOno4u
+G+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5amnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ=
+-----END CERTIFICATE-----
+
+AddTrust Public Services Root
+=============================
+-----BEGIN CERTIFICATE-----
+MIIEFTCCAv2gAwIBAgIBATANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQGEwJTRTEUMBIGA1UEChML
+QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSAwHgYDVQQDExdBZGRU
+cnVzdCBQdWJsaWMgQ0EgUm9vdDAeFw0wMDA1MzAxMDQxNTBaFw0yMDA1MzAxMDQxNTBaMGQxCzAJ
+BgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQIE5l
+dHdvcmsxIDAeBgNVBAMTF0FkZFRydXN0IFB1YmxpYyBDQSBSb290MIIBIjANBgkqhkiG9w0BAQEF
+AAOCAQ8AMIIBCgKCAQEA6Rowj4OIFMEg2Dybjxt+A3S72mnTRqX4jsIMEZBRpS9mVEBV6tsfSlbu
+nyNu9DnLoblv8n75XYcmYZ4c+OLspoH4IcUkzBEMP9smcnrHAZcHF/nXGCwwfQ56HmIexkvA/X1i
+d9NEHif2P0tEs7c42TkfYNVRknMDtABp4/MUTu7R3AnPdzRGULD4EfL+OHn3Bzn+UZKXC1sIXzSG
+Aa2Il+tmzV7R/9x98oTaunet3IAIx6eH1lWfl2royBFkuucZKT8Rs3iQhCBSWxHveNCD9tVIkNAw
+HM+A+WD+eeSI8t0A65RF62WUaUC6wNW0uLp9BBGo6zEFlpROWCGOn9Bg/QIDAQABo4HRMIHOMB0G
+A1UdDgQWBBSBPjfYkrAfd59ctKtzquf2NGAv+jALBgNVHQ8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB
+/zCBjgYDVR0jBIGGMIGDgBSBPjfYkrAfd59ctKtzquf2NGAv+qFopGYwZDELMAkGA1UEBhMCU0Ux
+FDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQLExRBZGRUcnVzdCBUVFAgTmV0d29yazEgMB4G
+A1UEAxMXQWRkVHJ1c3QgUHVibGljIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBAAP3FUr4
+JNojVhaTdt02KLmuG7jD8WS6IBh4lSknVwW8fCr0uVFV2ocC3g8WFzH4qnkuCRO7r7IgGRLlk/lL
++YPoRNWyQSW/iHVv/xD8SlTQX/D67zZzfRs2RcYhbbQVuE7PnFylPVoAjgbjPGsye/Kf8Lb93/Ao
+GEjwxrzQvzSAlsJKsW2Ox5BF3i9nrEUEo3rcVZLJR2bYGozH7ZxOmuASu7VqTITh4SINhwBk/ox9
+Yjllpu9CtoAlEmEBqCQTcAARJl/6NVDFSMwGR+gn2HCNX2TmoUQmXiLsks3/QppEIW1cxeMiHV9H
+EufOX1362KqxMy3ZdvJOOjMMK7MtkAY=
+-----END CERTIFICATE-----
+
+AddTrust Qualified Certificates Root
+====================================
+-----BEGIN CERTIFICATE-----
+MIIEHjCCAwagAwIBAgIBATANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJTRTEUMBIGA1UEChML
+QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSMwIQYDVQQDExpBZGRU
+cnVzdCBRdWFsaWZpZWQgQ0EgUm9vdDAeFw0wMDA1MzAxMDQ0NTBaFw0yMDA1MzAxMDQ0NTBaMGcx
+CzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQ
+IE5ldHdvcmsxIzAhBgNVBAMTGkFkZFRydXN0IFF1YWxpZmllZCBDQSBSb290MIIBIjANBgkqhkiG
+9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5B6a/twJWoekn0e+EV+vhDTbYjx5eLfpMLXsDBwqxBb/4Oxx
+64r1EW7tTw2R0hIYLUkVAcKkIhPHEWT/IhKauY5cLwjPcWqzZwFZ8V1G87B4pfYOQnrjfxvM0PC3
+KP0q6p6zsLkEqv32x7SxuCqg+1jxGaBvcCV+PmlKfw8i2O+tCBGaKZnhqkRFmhJePp1tUvznoD1o
+L/BLcHwTOK28FSXx1s6rosAx1i+f4P8UWfyEk9mHfExUE+uf0S0R+Bg6Ot4l2ffTQO2kBhLEO+GR
+wVY18BTcZTYJbqukB8c10cIDMzZbdSZtQvESa0NvS3GU+jQd7RNuyoB/mC9suWXY6QIDAQABo4HU
+MIHRMB0GA1UdDgQWBBQ5lYtii1zJ1IC6WA+XPxUIQ8yYpzALBgNVHQ8EBAMCAQYwDwYDVR0TAQH/
+BAUwAwEB/zCBkQYDVR0jBIGJMIGGgBQ5lYtii1zJ1IC6WA+XPxUIQ8yYp6FrpGkwZzELMAkGA1UE
+BhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQLExRBZGRUcnVzdCBUVFAgTmV0d29y
+azEjMCEGA1UEAxMaQWRkVHJ1c3QgUXVhbGlmaWVkIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQAD
+ggEBABmrder4i2VhlRO6aQTvhsoToMeqT2QbPxj2qC0sVY8FtzDqQmodwCVRLae/DLPt7wh/bDxG
+GuoYQ992zPlmhpwsaPXpF/gxsxjE1kh9I0xowX67ARRvxdlu3rsEQmr49lx95dr6h+sNNVJn0J6X
+dgWTP5XHAeZpVTh/EGGZyeNfpso+gmNIquIISD6q8rKFYqa0p9m9N5xotS1WfbC3P6CxB9bpT9ze
+RXEwMn8bLgn5v1Kh7sKAPgZcLlVAwRv1cEWw3F369nJad9Jjzc9YiQBCYz95OdBEsIJuQRno3eDB
+iFrRHnGTHyQwdOUeqN48Jzd/g66ed8/wMLH/S5noxqE=
+-----END CERTIFICATE-----
+
+Entrust Root Certification Authority
+====================================
+-----BEGIN CERTIFICATE-----
+MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMCVVMxFjAUBgNV
+BAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0Lm5ldC9DUFMgaXMgaW5jb3Jw
+b3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMWKGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsG
+A1UEAxMkRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0
+MloXDTI2MTEyNzIwNTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMu
+MTkwNwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSByZWZlcmVu
+Y2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNVBAMTJEVudHJ1c3QgUm9v
+dCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
+ALaVtkNC+sZtKm9I35RMOVcF7sN5EUFoNu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYsz
+A9u3g3s+IIRe7bJWKKf44LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOww
+Cj0Yzfv9KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGIrb68
+j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi94DkZfs0Nw4pgHBN
+rziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOBsDCBrTAOBgNVHQ8BAf8EBAMCAQYw
+DwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAigA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1
+MzQyWjAfBgNVHSMEGDAWgBRokORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DH
+hmak8fdLQ/uEvW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA
+A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9tO1KzKtvn1ISM
+Y/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6ZuaAGAT/3B+XxFNSRuzFVJ7yVTa
+v52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTS
+W3iDVuycNsMm4hH2Z0kdkquM++v/eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0
+tHuu2guQOHXvgR1m0vdXcDazv/wor3ElhVsT/h5/WrQ8
+-----END CERTIFICATE-----
+
+GeoTrust Global CA
+==================
+-----BEGIN CERTIFICATE-----
+MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVTMRYwFAYDVQQK
+Ew1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9iYWwgQ0EwHhcNMDIwNTIxMDQw
+MDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5j
+LjEbMBkGA1UEAxMSR2VvVHJ1c3QgR2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
+CgKCAQEA2swYYzD99BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjo
+BbdqfnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDviS2Aelet
+8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU1XupGc1V3sjs0l44U+Vc
+T4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+bw8HHa8sHo9gOeL6NlMTOdReJivbPagU
+vTLrGAMoUgRx5aszPeE4uwc2hGKceeoWMPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTAD
+AQH/MB0GA1UdDgQWBBTAephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVk
+DBF9qn1luMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKInZ57Q
+zxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfStQWVYrmm3ok9Nns4
+d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcFPseKUgzbFbS9bZvlxrFUaKnjaZC2
+mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Unhw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6p
+XE0zX5IJL4hmXXeXxx12E6nV5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvm
+Mw==
+-----END CERTIFICATE-----
+
+GeoTrust Global CA 2
+====================
+-----BEGIN CERTIFICATE-----
+MIIDZjCCAk6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBEMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN
+R2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMUR2VvVHJ1c3QgR2xvYmFsIENBIDIwHhcNMDQwMzA0MDUw
+MDAwWhcNMTkwMzA0MDUwMDAwWjBEMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5j
+LjEdMBsGA1UEAxMUR2VvVHJ1c3QgR2xvYmFsIENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
+ggEKAoIBAQDvPE1APRDfO1MA4Wf+lGAVPoWI8YkNkMgoI5kF6CsgncbzYEbYwbLVjDHZ3CB5JIG/
+NTL8Y2nbsSpr7iFY8gjpeMtvy/wWUsiRxP89c96xPqfCfWbB9X5SJBri1WeR0IIQ13hLTytCOb1k
+LUCgsBDTOEhGiKEMuzozKmKY+wCdE1l/bztyqu6mD4b5BWHqZ38MN5aL5mkWRxHCJ1kDs6ZgwiFA
+Vvqgx306E+PsV8ez1q6diYD3Aecs9pYrEw15LNnA5IZ7S4wMcoKK+xfNAGw6EzywhIdLFnopsk/b
+HdQL82Y3vdj2V7teJHq4PIu5+pIaGoSe2HSPqht/XvT+RSIhAgMBAAGjYzBhMA8GA1UdEwEB/wQF
+MAMBAf8wHQYDVR0OBBYEFHE4NvICMVNHK266ZUapEBVYIAUJMB8GA1UdIwQYMBaAFHE4NvICMVNH
+K266ZUapEBVYIAUJMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQUFAAOCAQEAA/e1K6tdEPx7
+srJerJsOflN4WT5CBP51o62sgU7XAotexC3IUnbHLB/8gTKY0UvGkpMzNTEv/NgdRN3ggX+d6Yvh
+ZJFiCzkIjKx0nVnZellSlxG5FntvRdOW2TF9AjYPnDtuzywNA0ZF66D0f0hExghAzN4bcLUprbqL
+OzRldRtxIR0sFAqwlpW41uryZfspuk/qkZN0abby/+Ea0AzRdoXLiiW9l14sbxWZJue2Kf8i7MkC
+x1YAzUm5s2x7UwQa4qjJqhIFI8LO57sEAszAR6LkxCkvW0VXiVHuPOtSCP8HNR6fNWpHSlaY0VqF
+H4z1Ir+rzoPz4iIprn2DQKi6bA==
+-----END CERTIFICATE-----
+
+GeoTrust Universal CA
+=====================
+-----BEGIN CERTIFICATE-----
+MIIFaDCCA1CgAwIBAgIBATANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN
+R2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgVW5pdmVyc2FsIENBMB4XDTA0MDMwNDA1
+MDAwMFoXDTI5MDMwNDA1MDAwMFowRTELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IElu
+Yy4xHjAcBgNVBAMTFUdlb1RydXN0IFVuaXZlcnNhbCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIP
+ADCCAgoCggIBAKYVVaCjxuAfjJ0hUNfBvitbtaSeodlyWL0AG0y/YckUHUWCq8YdgNY96xCcOq9t
+JPi8cQGeBvV8Xx7BDlXKg5pZMK4ZyzBIle0iN430SppyZj6tlcDgFgDgEB8rMQ7XlFTTQjOgNB0e
+RXbdT8oYN+yFFXoZCPzVx5zw8qkuEKmS5j1YPakWaDwvdSEYfyh3peFhF7em6fgemdtzbvQKoiFs
+7tqqhZJmr/Z6a4LauiIINQ/PQvE1+mrufislzDoR5G2vc7J2Ha3QsnhnGqQ5HFELZ1aD/ThdDc7d
+8Lsrlh/eezJS/R27tQahsiFepdaVaH/wmZ7cRQg+59IJDTWU3YBOU5fXtQlEIGQWFwMCTFMNaN7V
+qnJNk22CDtucvc+081xdVHppCZbW2xHBjXWotM85yM48vCR85mLK4b19p71XZQvk/iXttmkQ3Cga
+Rr0BHdCXteGYO8A3ZNY9lO4L4fUorgtWv3GLIylBjobFS1J72HGrH4oVpjuDWtdYAVHGTEHZf9hB
+Z3KiKN9gg6meyHv8U3NyWfWTehd2Ds735VzZC1U0oqpbtWpU5xPKV+yXbfReBi9Fi1jUIxaS5BZu
+KGNZMN9QAZxjiRqf2xeUgnA3wySemkfWWspOqGmJch+RbNt+nhutxx9z3SxPGWX9f5NAEC7S8O08
+ni4oPmkmM8V7AgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNq7LqqwDLiIJlF0
+XG0D08DYj3rWMB8GA1UdIwQYMBaAFNq7LqqwDLiIJlF0XG0D08DYj3rWMA4GA1UdDwEB/wQEAwIB
+hjANBgkqhkiG9w0BAQUFAAOCAgEAMXjmx7XfuJRAyXHEqDXsRh3ChfMoWIawC/yOsjmPRFWrZIRc
+aanQmjg8+uUfNeVE44B5lGiku8SfPeE0zTBGi1QrlaXv9z+ZhP015s8xxtxqv6fXIwjhmF7DWgh2
+qaavdy+3YL1ERmrvl/9zlcGO6JP7/TG37FcREUWbMPEaiDnBTzynANXH/KttgCJwpQzgXQQpAvvL
+oJHRfNbDflDVnVi+QTjruXU8FdmbyUqDWcDaU/0zuzYYm4UPFd3uLax2k7nZAY1IEKj79TiG8dsK
+xr2EoyNB3tZ3b4XUhRxQ4K5RirqNPnbiucon8l+f725ZDQbYKxek0nxru18UGkiPGkzns0ccjkxF
+KyDuSN/n3QmOGKjaQI2SJhFTYXNd673nxE0pN2HrrDktZy4W1vUAg4WhzH92xH3kt0tm7wNFYGm2
+DFKWkoRepqO1pD4r2czYG0eq8kTaT/kD6PAUyz/zg97QwVTjt+gKN02LIFkDMBmhLMi9ER/frslK
+xfMnZmaGrGiR/9nmUxwPi1xpZQomyB40w11Re9epnAahNt3ViZS82eQtDF4JbAiXfKM9fJP/P6EU
+p8+1Xevb2xzEdt+Iub1FBZUbrvxGakyvSOPOrg/SfuvmbJxPgWp6ZKy7PtXny3YuxadIwVyQD8vI
+P/rmMuGNG2+k5o7Y+SlIis5z/iw=
+-----END CERTIFICATE-----
+
+GeoTrust Universal CA 2
+=======================
+-----BEGIN CERTIFICATE-----
+MIIFbDCCA1SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBHMQswCQYDVQQGEwJVUzEWMBQGA1UEChMN
+R2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVyc2FsIENBIDIwHhcNMDQwMzA0
+MDUwMDAwWhcNMjkwMzA0MDUwMDAwWjBHMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3Qg
+SW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVyc2FsIENBIDIwggIiMA0GCSqGSIb3DQEBAQUA
+A4ICDwAwggIKAoICAQCzVFLByT7y2dyxUxpZKeexw0Uo5dfR7cXFS6GqdHtXr0om/Nj1XqduGdt0
+DE81WzILAePb63p3NeqqWuDW6KFXlPCQo3RWlEQwAx5cTiuFJnSCegx2oG9NzkEtoBUGFF+3Qs17
+j1hhNNwqCPkuwwGmIkQcTAeC5lvO0Ep8BNMZcyfwqph/Lq9O64ceJHdqXbboW0W63MOhBW9Wjo8Q
+JqVJwy7XQYci4E+GymC16qFjwAGXEHm9ADwSbSsVsaxLse4YuU6W3Nx2/zu+z18DwPw76L5GG//a
+QMJS9/7jOvdqdzXQ2o3rXhhqMcceujwbKNZrVMaqW9eiLBsZzKIC9ptZvTdrhrVtgrrY6slWvKk2
+WP0+GfPtDCapkzj4T8FdIgbQl+rhrcZV4IErKIM6+vR7IVEAvlI4zs1meaj0gVbi0IMJR1FbUGrP
+20gaXT73y/Zl92zxlfgCOzJWgjl6W70viRu/obTo/3+NjN8D8WBOWBFM66M/ECuDmgFz2ZRthAAn
+ZqzwcEAJQpKtT5MNYQlRJNiS1QuUYbKHsu3/mjX/hVTK7URDrBs8FmtISgocQIgfksILAAX/8sgC
+SqSqqcyZlpwvWOB94b67B9xfBHJcMTTD7F8t4D1kkCLm0ey4Lt1ZrtmhN79UNdxzMk+MBB4zsslG
+8dhcyFVQyWi9qLo2CQIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR281Xh+qQ2
++/CfXGJx7Tz0RzgQKzAfBgNVHSMEGDAWgBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAOBgNVHQ8BAf8E
+BAMCAYYwDQYJKoZIhvcNAQEFBQADggIBAGbBxiPz2eAubl/oz66wsCVNK/g7WJtAJDday6sWSf+z
+dXkzoS9tcBc0kf5nfo/sm+VegqlVHy/c1FEHEv6sFj4sNcZj/NwQ6w2jqtB8zNHQL1EuxBRa3ugZ
+4T7GzKQp5y6EqgYweHZUcyiYWTjgAA1i00J9IZ+uPTqM1fp3DRgrFg5fNuH8KrUwJM/gYwx7WBr+
+mbpCErGR9Hxo4sjoryzqyX6uuyo9DRXcNJW2GHSoag/HtPQTxORb7QrSpJdMKu0vbBKJPfEncKpq
+A1Ihn0CoZ1Dy81of398j9tx4TuaYT1U6U+Pv8vSfx3zYWK8pIpe44L2RLrB27FcRz+8pRPPphXpg
+Y+RdM4kX2TGq2tbzGDVyz4crL2MjhF2EjD9XoIj8mZEoJmmZ1I+XRL6O1UixpCgp8RW04eWe3fiP
+pm8m1wk8OhwRDqZsN/etRIcsKMfYdIKz0G9KV7s1KSegi+ghp4dkNl3M2Basx7InQJJVOCiNUW7d
+FGdTbHFcJoRNdVq2fmBWqU2t+5sel/MN2dKXVHfaPRK34B7vCAas+YWH6aLcr34YEoP9VhdBLtUp
+gn2Z9DH2canPLAEnpQW5qrJITirvn5NSUZU8UnOOVkwXQMAJKOSLakhT2+zNVVXxxvjpoixMptEm
+X36vWkzaH6byHCx+rgIW0lbQL1dTR+iS
+-----END CERTIFICATE-----
+
+Visa eCommerce Root
+===================
+-----BEGIN CERTIFICATE-----
+MIIDojCCAoqgAwIBAgIQE4Y1TR0/BvLB+WUF1ZAcYjANBgkqhkiG9w0BAQUFADBrMQswCQYDVQQG
+EwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRlcm5hdGlvbmFsIFNlcnZpY2Ug
+QXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNvbW1lcmNlIFJvb3QwHhcNMDIwNjI2MDIxODM2
+WhcNMjIwNjI0MDAxNjEyWjBrMQswCQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMm
+VmlzYSBJbnRlcm5hdGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNv
+bW1lcmNlIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvV95WHm6h2mCxlCfL
+F9sHP4CFT8icttD0b0/Pmdjh28JIXDqsOTPHH2qLJj0rNfVIsZHBAk4ElpF7sDPwsRROEW+1QK8b
+RaVK7362rPKgH1g/EkZgPI2h4H3PVz4zHvtH8aoVlwdVZqW1LS7YgFmypw23RuwhY/81q6UCzyr0
+TP579ZRdhE2o8mCP2w4lPJ9zcc+U30rq299yOIzzlr3xF7zSujtFWsan9sYXiwGd/BmoKoMWuDpI
+/k4+oKsGGelT84ATB+0tvz8KPFUgOSwsAGl0lUq8ILKpeeUYiZGo3BxN77t+Nwtd/jmliFKMAGzs
+GHxBvfaLdXe6YJ2E5/4tAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEG
+MB0GA1UdDgQWBBQVOIMPPyw/cDMezUb+B4wg4NfDtzANBgkqhkiG9w0BAQUFAAOCAQEAX/FBfXxc
+CLkr4NWSR/pnXKUTwwMhmytMiUbPWU3J/qVAtmPN3XEolWcRzCSs00Rsca4BIGsDoo8Ytyk6feUW
+YFN4PMCvFYP3j1IzJL1kk5fui/fbGKhtcbP3LBfQdCVp9/5rPJS+TUtBjE7ic9DjkCJzQ83z7+pz
+zkWKsKZJ/0x9nXGIxHYdkFsd7v3M9+79YKWxehZx0RbQfBI8bGmX265fOZpwLwU8GUYEmSA20GBu
+YQa7FkKMcPcw++DbZqMAAb3mLNqRX6BGi01qnD093QVG/na/oAo85ADmJ7f/hC3euiInlhBx6yLt
+398znM/jra6O1I7mT1GvFpLgXPYHDw==
+-----END CERTIFICATE-----
+
+Certum Root CA
+==============
+-----BEGIN CERTIFICATE-----
+MIIDDDCCAfSgAwIBAgIDAQAgMA0GCSqGSIb3DQEBBQUAMD4xCzAJBgNVBAYTAlBMMRswGQYDVQQK
+ExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBDQTAeFw0wMjA2MTExMDQ2Mzla
+Fw0yNzA2MTExMDQ2MzlaMD4xCzAJBgNVBAYTAlBMMRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8u
+by4xEjAQBgNVBAMTCUNlcnR1bSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM6x
+wS7TT3zNJc4YPk/EjG+AanPIW1H4m9LcuwBcsaD8dQPugfCI7iNS6eYVM42sLQnFdvkrOYCJ5JdL
+kKWoePhzQ3ukYbDYWMzhbGZ+nPMJXlVjhNWo7/OxLjBos8Q82KxujZlakE403Daaj4GIULdtlkIJ
+89eVgw1BS7Bqa/j8D35in2fE7SZfECYPCE/wpFcozo+47UX2bu4lXapuOb7kky/ZR6By6/qmW6/K
+Uz/iDsaWVhFu9+lmqSbYf5VT7QqFiLpPKaVCjF62/IUgAKpoC6EahQGcxEZjgoi2IrHu/qpGWX7P
+NSzVttpd90gzFFS269lvzs2I1qsb2pY7HVkCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkq
+hkiG9w0BAQUFAAOCAQEAuI3O7+cUus/usESSbLQ5PqKEbq24IXfS1HeCh+YgQYHu4vgRt2PRFze+
+GXYkHAQaTOs9qmdvLdTN/mUxcMUbpgIKumB7bVjCmkn+YzILa+M6wKyrO7Do0wlRjBCDxjTgxSvg
+GrZgFCdsMneMvLJymM/NzD+5yCRCFNZX/OYmQ6kd5YCQzgNUKD73P9P4Te1qCjqTE5s7FCMTY5w/
+0YcneeVMUeMBrYVdGjux1XMQpNPyvG5k9VpWkKjHDkx0Dy5xO/fIR/RpbxXyEV6DHpx8Uq79AtoS
+qFlnGNu8cN2bsWntgM6JQEhqDjXKKWYVIZQs6GAqm4VKQPNriiTsBhYscw==
+-----END CERTIFICATE-----
+
+Comodo AAA Services root
+========================
+-----BEGIN CERTIFICATE-----
+MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEbMBkGA1UECAwS
+R3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0Eg
+TGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAw
+MFoXDTI4MTIzMTIzNTk1OVowezELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hl
+c3RlcjEQMA4GA1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNV
+BAMMGEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
+ggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQuaBtDFcCLNSS1UY8y2bmhG
+C1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe3M/vg4aijJRPn2jymJBGhCfHdr/jzDUs
+i14HZGWCwEiwqJH5YZ92IFCokcdmtet4YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszW
+Y19zjNoFmag4qMsXeDZRrOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjH
+Ypy+g8cmez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQUoBEK
+Iz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wewYDVR0f
+BHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20vQUFBQ2VydGlmaWNhdGVTZXJ2aWNl
+cy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29tb2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2Vz
+LmNybDANBgkqhkiG9w0BAQUFAAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm
+7l3sAg9g1o1QGE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz
+Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2G9w84FoVxp7Z
+8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsil2D4kF501KKaU73yqWjgom7C
+12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg==
+-----END CERTIFICATE-----
+
+Comodo Secure Services root
+===========================
+-----BEGIN CERTIFICATE-----
+MIIEPzCCAyegAwIBAgIBATANBgkqhkiG9w0BAQUFADB+MQswCQYDVQQGEwJHQjEbMBkGA1UECAwS
+R3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0Eg
+TGltaXRlZDEkMCIGA1UEAwwbU2VjdXJlIENlcnRpZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAw
+MDAwMFoXDTI4MTIzMTIzNTk1OVowfjELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFu
+Y2hlc3RlcjEQMA4GA1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxJDAi
+BgNVBAMMG1NlY3VyZSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ADCCAQoCggEBAMBxM4KK0HDrc4eCQNUd5MvJDkKQ+d40uaG6EfQlhfPMcm3ye5drswfxdySRXyWP
+9nQ95IDC+DwN879A6vfIUtFyb+/Iq0G4bi4XKpVpDM3SHpR7LZQdqnXXs5jLrLxkU0C8j6ysNstc
+rbvd4JQX7NFc0L/vpZXJkMWwrPsbQ996CF23uPJAGysnnlDOXmWCiIxe004MeuoIkbY2qitC++rC
+oznl2yY4rYsK7hljxxwk3wN42ubqwUcaCwtGCd0C/N7Lh1/XMGNooa7cMqG6vv5Eq2i2pRcV/b3V
+p6ea5EQz6YiO/O1R65NxTq0B50SOqy3LqP4BSUjwwN3HaNiS/j0CAwEAAaOBxzCBxDAdBgNVHQ4E
+FgQUPNiTiMLAggnMAZkGkyDpnnAJY08wDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8w
+gYEGA1UdHwR6MHgwO6A5oDeGNWh0dHA6Ly9jcmwuY29tb2RvY2EuY29tL1NlY3VyZUNlcnRpZmlj
+YXRlU2VydmljZXMuY3JsMDmgN6A1hjNodHRwOi8vY3JsLmNvbW9kby5uZXQvU2VjdXJlQ2VydGlm
+aWNhdGVTZXJ2aWNlcy5jcmwwDQYJKoZIhvcNAQEFBQADggEBAIcBbSMdflsXfcFhMs+P5/OKlFlm
+4J4oqF7Tt/Q05qo5spcWxYJvMqTpjOev/e/C6LlLqqP05tqNZSH7uoDrJiiFGv45jN5bBAS0VPmj
+Z55B+glSzAVIqMk/IQQezkhr/IXownuvf7fM+F86/TXGDe+X3EyrEeFryzHRbPtIgKvcnDe4IRRL
+DXE97IMzbtFuMhbsmMcWi1mmNKsFVy2T96oTy9IT4rcuO81rUBcJaD61JlfutuC23bkpgHl9j6Pw
+pCikFcSF9CfUa7/lXORlAnZUtOM3ZiTTGWHIUhDlizeauan5Hb/qmZJhlv8BzaFfDbxxvA6sCx1H
+RR3B7Hzs/Sk=
+-----END CERTIFICATE-----
+
+Comodo Trusted Services root
+============================
+-----BEGIN CERTIFICATE-----
+MIIEQzCCAyugAwIBAgIBATANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJHQjEbMBkGA1UECAwS
+R3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRowGAYDVQQKDBFDb21vZG8gQ0Eg
+TGltaXRlZDElMCMGA1UEAwwcVHJ1c3RlZCBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczAeFw0wNDAxMDEw
+MDAwMDBaFw0yODEyMzEyMzU5NTlaMH8xCzAJBgNVBAYTAkdCMRswGQYDVQQIDBJHcmVhdGVyIE1h
+bmNoZXN0ZXIxEDAOBgNVBAcMB1NhbGZvcmQxGjAYBgNVBAoMEUNvbW9kbyBDQSBMaW1pdGVkMSUw
+IwYDVQQDDBxUcnVzdGVkIENlcnRpZmljYXRlIFNlcnZpY2VzMIIBIjANBgkqhkiG9w0BAQEFAAOC
+AQ8AMIIBCgKCAQEA33FvNlhTWvI2VFeAxHQIIO0Yfyod5jWaHiWsnOWWfnJSoBVC21ndZHoa0Lh7
+3TkVvFVIxO06AOoxEbrycXQaZ7jPM8yoMa+j49d/vzMtTGo87IvDktJTdyR0nAducPy9C1t2ul/y
+/9c3S0pgePfw+spwtOpZqqPOSC+pw7ILfhdyFgymBwwbOM/JYrc/oJOlh0Hyt3BAd9i+FHzjqMB6
+juljatEPmsbS9Is6FARW1O24zG71++IsWL1/T2sr92AkWCTOJu80kTrV44HQsvAEAtdbtz6SrGsS
+ivnkBbA7kUlcsutT6vifR4buv5XAwAaf0lteERv0xwQ1KdJVXOTt6wIDAQABo4HJMIHGMB0GA1Ud
+DgQWBBTFe1i97doladL3WRaoszLAeydb9DAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB
+/zCBgwYDVR0fBHwwejA8oDqgOIY2aHR0cDovL2NybC5jb21vZG9jYS5jb20vVHJ1c3RlZENlcnRp
+ZmljYXRlU2VydmljZXMuY3JsMDqgOKA2hjRodHRwOi8vY3JsLmNvbW9kby5uZXQvVHJ1c3RlZENl
+cnRpZmljYXRlU2VydmljZXMuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQDIk4E7ibSvuIQSTI3S8Ntw
+uleGFTQQuS9/HrCoiWChisJ3DFBKmwCL2Iv0QeLQg4pKHBQGsKNoBXAxMKdTmw7pSqBYaWcOrp32
+pSxBvzwGa+RZzG0Q8ZZvH9/0BAKkn0U+yNj6NkZEUD+Cl5EfKNsYEYwq5GWDVxISjBc/lDb+XbDA
+BHcTuPQV1T84zJQ6VdCsmPW6AF/ghhmBeC8owH7TzEIK9a5QoNE+xqFx7D+gIIxmOom0jtTYsU0l
+R+4viMi14QVFwL4Ucd56/Y57fU0IlqUSc/AtyjcndBInTMu2l+nZrghtWjlA3QVHdWpaIbOjGM9O
+9y5Xt5hwXsjEeLBi
+-----END CERTIFICATE-----
+
+QuoVadis Root CA
+================
+-----BEGIN CERTIFICATE-----
+MIIF0DCCBLigAwIBAgIEOrZQizANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJCTTEZMBcGA1UE
+ChMQUXVvVmFkaXMgTGltaXRlZDElMCMGA1UECxMcUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0
+eTEuMCwGA1UEAxMlUXVvVmFkaXMgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMTAz
+MTkxODMzMzNaFw0yMTAzMTcxODMzMzNaMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRp
+cyBMaW1pdGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQD
+EyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEF
+AAOCAQ8AMIIBCgKCAQEAv2G1lVO6V/z68mcLOhrfEYBklbTRvM16z/Ypli4kVEAkOPcahdxYTMuk
+J0KX0J+DisPkBgNbAKVRHnAEdOLB1Dqr1607BxgFjv2DrOpm2RgbaIr1VxqYuvXtdj182d6UajtL
+F8HVj71lODqV0D1VNk7feVcxKh7YWWVJWCCYfqtffp/p1k3sg3Spx2zY7ilKhSoGFPlU5tPaZQeL
+YzcS19Dsw3sgQUSj7cugF+FxZc4dZjH3dgEZyH0DWLaVSR2mEiboxgx24ONmy+pdpibu5cxfvWen
+AScOospUxbF6lR1xHkopigPcakXBpBlebzbNw6Kwt/5cOOJSvPhEQ+aQuwIDAQABo4ICUjCCAk4w
+PQYIKwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwczovL29jc3AucXVvdmFkaXNvZmZzaG9y
+ZS5jb20wDwYDVR0TAQH/BAUwAwEB/zCCARoGA1UdIASCAREwggENMIIBCQYJKwYBBAG+WAABMIH7
+MIHUBggrBgEFBQcCAjCBxxqBxFJlbGlhbmNlIG9uIHRoZSBRdW9WYWRpcyBSb290IENlcnRpZmlj
+YXRlIGJ5IGFueSBwYXJ0eSBhc3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJs
+ZSBzdGFuZGFyZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNlcnRpZmljYXRpb24gcHJh
+Y3RpY2VzLCBhbmQgdGhlIFF1b1ZhZGlzIENlcnRpZmljYXRlIFBvbGljeS4wIgYIKwYBBQUHAgEW
+Fmh0dHA6Ly93d3cucXVvdmFkaXMuYm0wHQYDVR0OBBYEFItLbe3TKbkGGew5Oanwl4Rqy+/fMIGu
+BgNVHSMEgaYwgaOAFItLbe3TKbkGGew5Oanwl4Rqy+/foYGEpIGBMH8xCzAJBgNVBAYTAkJNMRkw
+FwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0
+aG9yaXR5MS4wLAYDVQQDEyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggQ6
+tlCLMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAitQUtf70mpKnGdSkfnIYj9lo
+fFIk3WdvOXrEql494liwTXCYhGHoG+NpGA7O+0dQoE7/8CQfvbLO9Sf87C9TqnN7Az10buYWnuul
+LsS/VidQK2K6vkscPFVcQR0kvoIgR13VRH56FmjffU1RcHhXHTMe/QKZnAzNCgVPx7uOpHX6Sm2x
+gI4JVrmcGmD+XcHXetwReNDWXcG31a0ymQM6isxUJTkxgXsTIlG6Rmyhu576BGxJJnSP0nPrzDCi
+5upZIof4l/UO/erMkqQWxFIY6iHOsfHmhIHluqmGKPJDWl0Snawe2ajlCmqnf6CHKc/yiU3U7MXi
+5nrQNiOKSnQ2+Q==
+-----END CERTIFICATE-----
+
+QuoVadis Root CA 2
+==================
+-----BEGIN CERTIFICATE-----
+MIIFtzCCA5+gAwIBAgICBQkwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoT
+EFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJvb3QgQ0EgMjAeFw0wNjExMjQx
+ODI3MDBaFw0zMTExMjQxODIzMzNaMEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM
+aW1pdGVkMRswGQYDVQQDExJRdW9WYWRpcyBSb290IENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4IC
+DwAwggIKAoICAQCaGMpLlA0ALa8DKYrwD4HIrkwZhR0In6spRIXzL4GtMh6QRr+jhiYaHv5+HBg6
+XJxgFyo6dIMzMH1hVBHL7avg5tKifvVrbxi3Cgst/ek+7wrGsxDp3MJGF/hd/aTa/55JWpzmM+Yk
+lvc/ulsrHHo1wtZn/qtmUIttKGAr79dgw8eTvI02kfN/+NsRE8Scd3bBrrcCaoF6qUWD4gXmuVbB
+lDePSHFjIuwXZQeVikvfj8ZaCuWw419eaxGrDPmF60Tp+ARz8un+XJiM9XOva7R+zdRcAitMOeGy
+lZUtQofX1bOQQ7dsE/He3fbE+Ik/0XX1ksOR1YqI0JDs3G3eicJlcZaLDQP9nL9bFqyS2+r+eXyt
+66/3FsvbzSUr5R/7mp/iUcw6UwxI5g69ybR2BlLmEROFcmMDBOAENisgGQLodKcftslWZvB1Jdxn
+wQ5hYIizPtGo/KPaHbDRsSNU30R2be1B2MGyIrZTHN81Hdyhdyox5C315eXbyOD/5YDXC2Og/zOh
+D7osFRXql7PSorW+8oyWHhqPHWykYTe5hnMz15eWniN9gqRMgeKh0bpnX5UHoycR7hYQe7xFSkyy
+BNKr79X9DFHOUGoIMfmR2gyPZFwDwzqLID9ujWc9Otb+fVuIyV77zGHcizN300QyNQliBJIWENie
+J0f7OyHj+OsdWwIDAQABo4GwMIGtMA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1Ud
+DgQWBBQahGK8SEwzJQTU7tD2A8QZRtGUazBuBgNVHSMEZzBlgBQahGK8SEwzJQTU7tD2A8QZRtGU
+a6FJpEcwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMT
+ElF1b1ZhZGlzIFJvb3QgQ0EgMoICBQkwDQYJKoZIhvcNAQEFBQADggIBAD4KFk2fBluornFdLwUv
+Z+YTRYPENvbzwCYMDbVHZF34tHLJRqUDGCdViXh9duqWNIAXINzng/iN/Ae42l9NLmeyhP3ZRPx3
+UIHmfLTJDQtyU/h2BwdBR5YM++CCJpNVjP4iH2BlfF/nJrP3MpCYUNQ3cVX2kiF495V5+vgtJodm
+VjB3pjd4M1IQWK4/YY7yarHvGH5KWWPKjaJW1acvvFYfzznB4vsKqBUsfU16Y8Zsl0Q80m/DShcK
++JDSV6IZUaUtl0HaB0+pUNqQjZRG4T7wlP0QADj1O+hA4bRuVhogzG9Yje0uRY/W6ZM/57Es3zrW
+IozchLsib9D45MY56QSIPMO661V6bYCZJPVsAfv4l7CUW+v90m/xd2gNNWQjrLhVoQPRTUIZ3Ph1
+WVaj+ahJefivDrkRoHy3au000LYmYjgahwz46P0u05B/B5EqHdZ+XIWDmbA4CD/pXvk1B+TJYm5X
+f6dQlfe6yJvmjqIBxdZmv3lh8zwc4bmCXF2gw+nYSL0ZohEUGW6yhhtoPkg3Goi3XZZenMfvJ2II
+4pEZXNLxId26F0KCl3GBUzGpn/Z9Yr9y4aOTHcyKJloJONDO1w2AFrR4pTqHTI2KpdVGl/IsELm8
+VCLAAVBpQ570su9t+Oza8eOx79+Rj1QqCyXBJhnEUhAFZdWCEOrCMc0u
+-----END CERTIFICATE-----
+
+QuoVadis Root CA 3
+==================
+-----BEGIN CERTIFICATE-----
+MIIGnTCCBIWgAwIBAgICBcYwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0xGTAXBgNVBAoT
+EFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJvb3QgQ0EgMzAeFw0wNjExMjQx
+OTExMjNaFw0zMTExMjQxOTA2NDRaMEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM
+aW1pdGVkMRswGQYDVQQDExJRdW9WYWRpcyBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4IC
+DwAwggIKAoICAQDMV0IWVJzmmNPTTe7+7cefQzlKZbPoFog02w1ZkXTPkrgEQK0CSzGrvI2RaNgg
+DhoB4hp7Thdd4oq3P5kazethq8Jlph+3t723j/z9cI8LoGe+AaJZz3HmDyl2/7FWeUUrH556VOij
+KTVopAFPD6QuN+8bv+OPEKhyq1hX51SGyMnzW9os2l2ObjyjPtr7guXd8lyyBTNvijbO0BNO/79K
+DDRMpsMhvVAEVeuxu537RR5kFd5VAYwCdrXLoT9CabwvvWhDFlaJKjdhkf2mrk7AyxRllDdLkgbv
+BNDInIjbC3uBr7E9KsRlOni27tyAsdLTmZw67mtaa7ONt9XOnMK+pUsvFrGeaDsGb659n/je7Mwp
+p5ijJUMv7/FfJuGITfhebtfZFG4ZM2mnO4SJk8RTVROhUXhA+LjJou57ulJCg54U7QVSWllWp5f8
+nT8KKdjcT5EOE7zelaTfi5m+rJsziO+1ga8bxiJTyPbH7pcUsMV8eFLI8M5ud2CEpukqdiDtWAEX
+MJPpGovgc2PZapKUSU60rUqFxKMiMPwJ7Wgic6aIDFUhWMXhOp8q3crhkODZc6tsgLjoC2SToJyM
+Gf+z0gzskSaHirOi4XCPLArlzW1oUevaPwV/izLmE1xr/l9A4iLItLRkT9a6fUg+qGkM17uGcclz
+uD87nSVL2v9A6wIDAQABo4IBlTCCAZEwDwYDVR0TAQH/BAUwAwEB/zCB4QYDVR0gBIHZMIHWMIHT
+BgkrBgEEAb5YAAMwgcUwgZMGCCsGAQUFBwICMIGGGoGDQW55IHVzZSBvZiB0aGlzIENlcnRpZmlj
+YXRlIGNvbnN0aXR1dGVzIGFjY2VwdGFuY2Ugb2YgdGhlIFF1b1ZhZGlzIFJvb3QgQ0EgMyBDZXJ0
+aWZpY2F0ZSBQb2xpY3kgLyBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0YXRlbWVudC4wLQYIKwYB
+BQUHAgEWIWh0dHA6Ly93d3cucXVvdmFkaXNnbG9iYWwuY29tL2NwczALBgNVHQ8EBAMCAQYwHQYD
+VR0OBBYEFPLAE+CCQz777i9nMpY1XNu4ywLQMG4GA1UdIwRnMGWAFPLAE+CCQz777i9nMpY1XNu4
+ywLQoUmkRzBFMQswCQYDVQQGEwJCTTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDEbMBkGA1UE
+AxMSUXVvVmFkaXMgUm9vdCBDQSAzggIFxjANBgkqhkiG9w0BAQUFAAOCAgEAT62gLEz6wPJv92ZV
+qyM07ucp2sNbtrCD2dDQ4iH782CnO11gUyeim/YIIirnv6By5ZwkajGxkHon24QRiSemd1o417+s
+hvzuXYO8BsbRd2sPbSQvS3pspweWyuOEn62Iix2rFo1bZhfZFvSLgNLd+LJ2w/w4E6oM3kJpK27z
+POuAJ9v1pkQNn1pVWQvVDVJIxa6f8i+AxeoyUDUSly7B4f/xI4hROJ/yZlZ25w9Rl6VSDE1JUZU2
+Pb+iSwwQHYaZTKrzchGT5Or2m9qoXadNt54CrnMAyNojA+j56hl0YgCUyyIgvpSnWbWCar6ZeXqp
+8kokUvd0/bpO5qgdAm6xDYBEwa7TIzdfu4V8K5Iu6H6li92Z4b8nby1dqnuH/grdS/yO9SbkbnBC
+bjPsMZ57k8HkyWkaPcBrTiJt7qtYTcbQQcEr6k8Sh17rRdhs9ZgC06DYVYoGmRmioHfRMJ6szHXu
+g/WwYjnPbFfiTNKRCw51KBuav/0aQ/HKd/s7j2G4aSgWQgRecCocIdiP4b0jWy10QJLZYxkNc91p
+vGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeTmJlglFwjz1onl14LBQaTNx47aTbr
+qZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK4SVhM7JZG+Ju1zdXtg2pEto=
+-----END CERTIFICATE-----
+
+Security Communication Root CA
+==============================
+-----BEGIN CERTIFICATE-----
+MIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMP
+U0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEw
+HhcNMDMwOTMwMDQyMDQ5WhcNMjMwOTMwMDQyMDQ5WjBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMP
+U0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEw
+ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCzs/5/022x7xZ8V6UMbXaKL0u/ZPtM7orw
+8yl89f/uKuDp6bpbZCKamm8sOiZpUQWZJtzVHGpxxpp9Hp3dfGzGjGdnSj74cbAZJ6kJDKaVv0uM
+DPpVmDvY6CKhS3E4eayXkmmziX7qIWgGmBSWh9JhNrxtJ1aeV+7AwFb9Ms+k2Y7CI9eNqPPYJayX
+5HA49LY6tJ07lyZDo6G8SVlyTCMwhwFY9k6+HGhWZq/NQV3Is00qVUarH9oe4kA92819uZKAnDfd
+DJZkndwi92SL32HeFZRSFaB9UslLqCHJxrHty8OVYNEP8Ktw+N/LTX7s1vqr2b1/VPKl6Xn62dZ2
+JChzAgMBAAGjPzA9MB0GA1UdDgQWBBSgc0mZaNyFW2XjmygvV5+9M7wHSDALBgNVHQ8EBAMCAQYw
+DwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaECpqLvkT115swW1F7NgE+vGkl3g
+0dNq/vu+m22/xwVtWSDEHPC32oRYAmP6SBbvT6UL90qY8j+eG61Ha2POCEfrUj94nK9NrvjVT8+a
+mCoQQTlSxN3Zmw7vkwGusi7KaEIkQmywszo+zenaSMQVy+n5Bw+SUEmK3TGXX8npN6o7WWWXlDLJ
+s58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJUJRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ
+6rBK+1YWc26sTfcioU+tHXotRSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAi
+FL39vmwLAw==
+-----END CERTIFICATE-----
+
+Sonera Class 2 Root CA
+======================
+-----BEGIN CERTIFICATE-----
+MIIDIDCCAgigAwIBAgIBHTANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEPMA0GA1UEChMG
+U29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MyIENBMB4XDTAxMDQwNjA3Mjk0MFoXDTIxMDQw
+NjA3Mjk0MFowOTELMAkGA1UEBhMCRkkxDzANBgNVBAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJh
+IENsYXNzMiBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJAXSjWdyvANlsdE+hY3
+/Ei9vX+ALTU74W+oZ6m/AxxNjG8yR9VBaKQTBME1DJqEQ/xcHf+Js+gXGM2RX/uJ4+q/Tl18GybT
+dXnt5oTjV+WtKcT0OijnpXuENmmz/V52vaMtmdOQTiMofRhj8VQ7Jp12W5dCsv+u8E7s3TmVToMG
+f+dJQMjFAbJUWmYdPfz56TwKnoG4cPABi+QjVHzIrviQHgCWctRUz2EjvOr7nQKV0ba5cTppCD8P
+tOFCx4j1P5iop7oc4HFx71hXgVB6XGt0Rg6DA5jDjqhu8nYybieDwnPz3BjotJPqdURrBGAgcVeH
+nfO+oJAjPYok4doh28MCAwEAAaMzMDEwDwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQISqCqWITT
+XjwwCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQBazof5FnIVV0sd2ZvnoiYw7JNn39Yt
+0jSv9zilzqsWuasvfDXLrNAPtEwr/IDva4yRXzZ299uzGxnq9LIR/WFxRL8oszodv7ND6J+/3DEI
+cbCdjdY0RzKQxmUk96BKfARzjzlvF4xytb1LyHr4e4PDKE6cCepnP7JnBBvDFNr450kkkdAdavph
+Oe9r5yF1BgfYErQhIHBCcYHaPJo2vqZbDWpsmh+Re/n570K6Tk6ezAyNlNzZRZxe7EJQY670XcSx
+EtzKO6gunRRaBXW37Ndj4ro1tgQIkejanZz2ZrUYrAqmVCY0M9IbwdR/GjqOC6oybtv8TyWf2TLH
+llpwrN9M
+-----END CERTIFICATE-----
+
+UTN USERFirst Hardware Root CA
+==============================
+-----BEGIN CERTIFICATE-----
+MIIEdDCCA1ygAwIBAgIQRL4Mi1AAJLQR0zYq/mUK/TANBgkqhkiG9w0BAQUFADCBlzELMAkGA1UE
+BhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhl
+IFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHzAd
+BgNVBAMTFlVUTi1VU0VSRmlyc3QtSGFyZHdhcmUwHhcNOTkwNzA5MTgxMDQyWhcNMTkwNzA5MTgx
+OTIyWjCBlzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0
+eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8vd3d3LnVz
+ZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3QtSGFyZHdhcmUwggEiMA0GCSqGSIb3
+DQEBAQUAA4IBDwAwggEKAoIBAQCx98M4P7Sof885glFn0G2f0v9Y8+efK+wNiVSZuTiZFvfgIXlI
+wrthdBKWHTxqctU8EGc6Oe0rE81m65UJM6Rsl7HoxuzBdXmcRl6Nq9Bq/bkqVRcQVLMZ8Jr28bFd
+tqdt++BxF2uiiPsA3/4aMXcMmgF6sTLjKwEHOG7DpV4jvEWbe1DByTCP2+UretNb+zNAHqDVmBe8
+i4fDidNdoI6yqqr2jmmIBsX6iSHzCJ1pLgkzmykNRg+MzEk0sGlRvfkGzWitZky8PqxhvQqIDsjf
+Pe58BEydCl5rkdbux+0ojatNh4lz0G6k0B4WixThdkQDf2Os5M1JnMWS9KsyoUhbAgMBAAGjgbkw
+gbYwCwYDVR0PBAQDAgHGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFKFyXyYbKJhDlV0HN9WF
+lp1L0sNFMEQGA1UdHwQ9MDswOaA3oDWGM2h0dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9VVE4tVVNF
+UkZpcnN0LUhhcmR3YXJlLmNybDAxBgNVHSUEKjAoBggrBgEFBQcDAQYIKwYBBQUHAwUGCCsGAQUF
+BwMGBggrBgEFBQcDBzANBgkqhkiG9w0BAQUFAAOCAQEARxkP3nTGmZev/K0oXnWO6y1n7k57K9cM
+//bey1WiCuFMVGWTYGufEpytXoMs61quwOQt9ABjHbjAbPLPSbtNk28GpgoiskliCE7/yMgUsogW
+XecB5BKV5UU0s4tpvc+0hY91UZ59Ojg6FEgSxvunOxqNDYJAB+gECJChicsZUN/KHAG8HQQZexB2
+lzvukJDKxA4fFm517zP4029bHpbj4HR3dHuKom4t3XbWOTCC8KucUvIqx69JXn7HaOWCgchqJ/kn
+iCrVWFCVH/A7HFe7fRQ5YiuayZSSKqMiDP+JJn1fIytH1xUdqWqeUQ0qUZ6B+dQ7XnASfxAynB67
+nfhmqA==
+-----END CERTIFICATE-----
+
+Camerfirma Chambers of Commerce Root
+====================================
+-----BEGIN CERTIFICATE-----
+MIIEvTCCA6WgAwIBAgIBADANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJFVTEnMCUGA1UEChMe
+QUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1i
+ZXJzaWduLm9yZzEiMCAGA1UEAxMZQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdDAeFw0wMzA5MzAx
+NjEzNDNaFw0zNzA5MzAxNjEzNDRaMH8xCzAJBgNVBAYTAkVVMScwJQYDVQQKEx5BQyBDYW1lcmZp
+cm1hIFNBIENJRiBBODI3NDMyODcxIzAhBgNVBAsTGmh0dHA6Ly93d3cuY2hhbWJlcnNpZ24ub3Jn
+MSIwIAYDVQQDExlDaGFtYmVycyBvZiBDb21tZXJjZSBSb290MIIBIDANBgkqhkiG9w0BAQEFAAOC
+AQ0AMIIBCAKCAQEAtzZV5aVdGDDg2olUkfzIx1L4L1DZ77F1c2VHfRtbunXF/KGIJPov7coISjlU
+xFF6tdpg6jg8gbLL8bvZkSM/SAFwdakFKq0fcfPJVD0dBmpAPrMMhe5cG3nCYsS4No41XQEMIwRH
+NaqbYE6gZj3LJgqcQKH0XZi/caulAGgq7YN6D6IUtdQis4CwPAxaUWktWBiP7Zme8a7ileb2R6jW
+DA+wWFjbw2Y3npuRVDM30pQcakjJyfKl2qUMI/cjDpwyVV5xnIQFUZot/eZOKjRa3spAN2cMVCFV
+d9oKDMyXroDclDZK9D7ONhMeU+SsTjoF7Nuucpw4i9A5O4kKPnf+dQIBA6OCAUQwggFAMBIGA1Ud
+EwEB/wQIMAYBAf8CAQwwPAYDVR0fBDUwMzAxoC+gLYYraHR0cDovL2NybC5jaGFtYmVyc2lnbi5v
+cmcvY2hhbWJlcnNyb290LmNybDAdBgNVHQ4EFgQU45T1sU3p26EpW1eLTXYGduHRooowDgYDVR0P
+AQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzAnBgNVHREEIDAegRxjaGFtYmVyc3Jvb3RAY2hh
+bWJlcnNpZ24ub3JnMCcGA1UdEgQgMB6BHGNoYW1iZXJzcm9vdEBjaGFtYmVyc2lnbi5vcmcwWAYD
+VR0gBFEwTzBNBgsrBgEEAYGHLgoDATA+MDwGCCsGAQUFBwIBFjBodHRwOi8vY3BzLmNoYW1iZXJz
+aWduLm9yZy9jcHMvY2hhbWJlcnNyb290Lmh0bWwwDQYJKoZIhvcNAQEFBQADggEBAAxBl8IahsAi
+fJ/7kPMa0QOx7xP5IV8EnNrJpY0nbJaHkb5BkAFyk+cefV/2icZdp0AJPaxJRUXcLo0waLIJuvvD
+L8y6C98/d3tGfToSJI6WjzwFCm/SlCgdbQzALogi1djPHRPH8EjX1wWnz8dHnjs8NMiAT9QUu/wN
+UPf6s+xCX6ndbcj0dc97wXImsQEcXCz9ek60AcUFV7nnPKoF2YjpB0ZBzu9Bga5Y34OirsrXdx/n
+ADydb47kMgkdTXg0eDQ8lJsm7U9xxhl6vSAiSFr+S30Dt+dYvsYyTnQeaN2oaFuzPu5ifdmA6Ap1
+erfutGWaIZDgqtCYvDi1czyL+Nw=
+-----END CERTIFICATE-----
+
+Camerfirma Global Chambersign Root
+==================================
+-----BEGIN CERTIFICATE-----
+MIIExTCCA62gAwIBAgIBADANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJFVTEnMCUGA1UEChMe
+QUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1i
+ZXJzaWduLm9yZzEgMB4GA1UEAxMXR2xvYmFsIENoYW1iZXJzaWduIFJvb3QwHhcNMDMwOTMwMTYx
+NDE4WhcNMzcwOTMwMTYxNDE4WjB9MQswCQYDVQQGEwJFVTEnMCUGA1UEChMeQUMgQ2FtZXJmaXJt
+YSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEg
+MB4GA1UEAxMXR2xvYmFsIENoYW1iZXJzaWduIFJvb3QwggEgMA0GCSqGSIb3DQEBAQUAA4IBDQAw
+ggEIAoIBAQCicKLQn0KuWxfH2H3PFIP8T8mhtxOviteePgQKkotgVvq0Mi+ITaFgCPS3CU6gSS9J
+1tPfnZdan5QEcOw/Wdm3zGaLmFIoCQLfxS+EjXqXd7/sQJ0lcqu1PzKY+7e3/HKE5TWH+VX6ox8O
+by4o3Wmg2UIQxvi1RMLQQ3/bvOSiPGpVeAp3qdjqGTK3L/5cPxvusZjsyq16aUXjlg9V9ubtdepl
+6DJWk0aJqCWKZQbua795B9Dxt6/tLE2Su8CoX6dnfQTyFQhwrJLWfQTSM/tMtgsL+xrJxI0DqX5c
+8lCrEqWhz0hQpe/SyBoT+rB/sYIcd2oPX9wLlY/vQ37mRQklAgEDo4IBUDCCAUwwEgYDVR0TAQH/
+BAgwBgEB/wIBDDA/BgNVHR8EODA2MDSgMqAwhi5odHRwOi8vY3JsLmNoYW1iZXJzaWduLm9yZy9j
+aGFtYmVyc2lnbnJvb3QuY3JsMB0GA1UdDgQWBBRDnDafsJ4wTcbOX60Qq+UDpfqpFDAOBgNVHQ8B
+Af8EBAMCAQYwEQYJYIZIAYb4QgEBBAQDAgAHMCoGA1UdEQQjMCGBH2NoYW1iZXJzaWducm9vdEBj
+aGFtYmVyc2lnbi5vcmcwKgYDVR0SBCMwIYEfY2hhbWJlcnNpZ25yb290QGNoYW1iZXJzaWduLm9y
+ZzBbBgNVHSAEVDBSMFAGCysGAQQBgYcuCgEBMEEwPwYIKwYBBQUHAgEWM2h0dHA6Ly9jcHMuY2hh
+bWJlcnNpZ24ub3JnL2Nwcy9jaGFtYmVyc2lnbnJvb3QuaHRtbDANBgkqhkiG9w0BAQUFAAOCAQEA
+PDtwkfkEVCeR4e3t/mh/YV3lQWVPMvEYBZRqHN4fcNs+ezICNLUMbKGKfKX0j//U2K0X1S0E0T9Y
+gOKBWYi+wONGkyT+kL0mojAt6JcmVzWJdJYY9hXiryQZVgICsroPFOrGimbBhkVVi76SvpykBMdJ
+PJ7oKXqJ1/6v/2j1pReQvayZzKWGVwlnRtvWFsJG8eSpUPWP0ZIV018+xgBJOm5YstHRJw0lyDL4
+IBHNfTIzSJRUTN3cecQwn+uOuFW114hcxWokPbLTBQNRxgfvzBRydD1ucs4YKIxKoHflCStFREes
+t2d/AYoFWpO+ocH/+OcOZ6RHSXZddZAa9SaP8A==
+-----END CERTIFICATE-----
+
+XRamp Global CA Root
+====================
+-----BEGIN CERTIFICATE-----
+MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCBgjELMAkGA1UE
+BhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2Vj
+dXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB
+dXRob3JpdHkwHhcNMDQxMTAxMTcxNDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMx
+HjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkg
+U2VydmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3Jp
+dHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS638eMpSe2OAtp87ZOqCwu
+IR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCPKZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMx
+foArtYzAQDsRhtDLooY2YKTVMIJt2W7QDxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FE
+zG+gSqmUsE3a56k0enI4qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqs
+AxcZZPRaJSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNViPvry
+xS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1Ud
+EwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASsjVy16bYbMDYGA1UdHwQvMC0wK6Ap
+oCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMC
+AQEwDQYJKoZIhvcNAQEFBQADggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc
+/Kh4ZzXxHfARvbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt
+qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLaIR9NmXmd4c8n
+nxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSyi6mx5O+aGtA9aZnuqCij4Tyz
+8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQO+7ETPTsJ3xCwnR8gooJybQDJbw=
+-----END CERTIFICATE-----
+
+Go Daddy Class 2 CA
+===================
+-----BEGIN CERTIFICATE-----
+MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMY
+VGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRp
+ZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkG
+A1UEBhMCVVMxITAfBgNVBAoTGFRoZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28g
+RGFkZHkgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQAD
+ggENADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCAPVYYYwhv
+2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6wwdhFJ2+qN1j3hybX2C32
+qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXiEqITLdiOr18SPaAIBQi2XKVlOARFmR6j
+YGB0xUGlcmIbYsUfb18aQr4CUWWoriMYavx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmY
+vLEHZ6IVDd2gWMZEewo+YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0O
+BBYEFNLEsNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h/t2o
+atTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMu
+MTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwG
+A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wim
+PQoZ+YeAEW5p5JYXMP80kWNyOO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKt
+I3lpjbi2Tc7PTMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ
+HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mERdEr/VxqHD3VI
+Ls9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5CufReYNnyicsbkqWletNw+vHX/b
+vZ8=
+-----END CERTIFICATE-----
+
+Starfield Class 2 CA
+====================
+-----BEGIN CERTIFICATE-----
+MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzElMCMGA1UEChMc
+U3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZpZWxkIENsYXNzIDIg
+Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQwNjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBo
+MQswCQYDVQQGEwJVUzElMCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAG
+A1UECxMpU3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqG
+SIb3DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf8MOh2tTY
+bitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN+lq2cwQlZut3f+dZxkqZ
+JRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVm
+epsZGD3/cVE8MC5fvj13c7JdBmzDI1aaK4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSN
+F4Azbl5KXZnJHoe0nRrA1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HF
+MIHCMB0GA1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fRzt0f
+hvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNo
+bm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBDbGFzcyAyIENlcnRpZmljYXRpb24g
+QXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGs
+afPzWdqbAYcaT1epoXkJKtv3L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLM
+PUxA2IGvd56Deruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl
+xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynpVSJYACPq4xJD
+KVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEYWQPJIrSPnNVeKtelttQKbfi3
+QBFGmh95DmK/D5fs4C8fF5Q=
+-----END CERTIFICATE-----
+
+StartCom Certification Authority
+================================
+-----BEGIN CERTIFICATE-----
+MIIHyTCCBbGgAwIBAgIBATANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJJTDEWMBQGA1UEChMN
+U3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmlu
+ZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0
+NjM2WhcNMzYwOTE3MTk0NjM2WjB9MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRk
+LjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMg
+U3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw
+ggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZkpMyONvg45iPwbm2xPN1y
+o4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rfOQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/
+Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/CJi/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/d
+eMotHweXMAEtcnn6RtYTKqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt
+2PZE4XNiHzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMMAv+Z
+6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w+2OqqGwaVLRcJXrJ
+osmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/
+untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVc
+UjyJthkqcwEKDwOzEmDyei+B26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT
+37uMdBNSSwIDAQABo4ICUjCCAk4wDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAa4wHQYDVR0OBBYE
+FE4L7xqkQFulF2mHMMo0aEPQQa7yMGQGA1UdHwRdMFswLKAqoCiGJmh0dHA6Ly9jZXJ0LnN0YXJ0
+Y29tLm9yZy9zZnNjYS1jcmwuY3JsMCugKaAnhiVodHRwOi8vY3JsLnN0YXJ0Y29tLm9yZy9zZnNj
+YS1jcmwuY3JsMIIBXQYDVR0gBIIBVDCCAVAwggFMBgsrBgEEAYG1NwEBATCCATswLwYIKwYBBQUH
+AgEWI2h0dHA6Ly9jZXJ0LnN0YXJ0Y29tLm9yZy9wb2xpY3kucGRmMDUGCCsGAQUFBwIBFilodHRw
+Oi8vY2VydC5zdGFydGNvbS5vcmcvaW50ZXJtZWRpYXRlLnBkZjCB0AYIKwYBBQUHAgIwgcMwJxYg
+U3RhcnQgQ29tbWVyY2lhbCAoU3RhcnRDb20pIEx0ZC4wAwIBARqBl0xpbWl0ZWQgTGlhYmlsaXR5
+LCByZWFkIHRoZSBzZWN0aW9uICpMZWdhbCBMaW1pdGF0aW9ucyogb2YgdGhlIFN0YXJ0Q29tIENl
+cnRpZmljYXRpb24gQXV0aG9yaXR5IFBvbGljeSBhdmFpbGFibGUgYXQgaHR0cDovL2NlcnQuc3Rh
+cnRjb20ub3JnL3BvbGljeS5wZGYwEQYJYIZIAYb4QgEBBAQDAgAHMDgGCWCGSAGG+EIBDQQrFilT
+dGFydENvbSBGcmVlIFNTTCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTANBgkqhkiG9w0BAQUFAAOC
+AgEAFmyZ9GYMNPXQhV59CuzaEE44HF7fpiUFS5Eyweg78T3dRAlbB0mKKctmArexmvclmAk8jhvh
+3TaHK0u7aNM5Zj2gJsfyOZEdUauCe37Vzlrk4gNXcGmXCPleWKYK34wGmkUWFjgKXlf2Ysd6AgXm
+vB618p70qSmD+LIU424oh0TDkBreOKk8rENNZEXO3SipXPJzewT4F+irsfMuXGRuczE6Eri8sxHk
+fY+BUZo7jYn0TZNmezwD7dOaHZrzZVD1oNB1ny+v8OqCQ5j4aZyJecRDjkZy42Q2Eq/3JR44iZB3
+fsNrarnDy0RLrHiQi+fHLB5LEUTINFInzQpdn4XBidUaePKVEFMy3YCEZnXZtWgo+2EuvoSoOMCZ
+EoalHmdkrQYuL6lwhceWD3yJZfWOQ1QOq92lgDmUYMA0yZZwLKMS9R9Ie70cfmu3nZD0Ijuu+Pwq
+yvqCUqDvr0tVk+vBtfAii6w0TiYiBKGHLHVKt+V9E9e4DGTANtLJL4YSjCMJwRuCO3NJo2pXh5Tl
+1njFmUNj403gdy3hZZlyaQQaRwnmDwFWJPsfvw55qVguucQJAX6Vum0ABj6y6koQOdjQK/W/7HW/
+lwLFCRsI3FU34oH7N4RDYiDK51ZLZer+bMEkkyShNOsF/5oirpt9P/FlUQqmMGqz9IgcgA38coro
+g14=
+-----END CERTIFICATE-----
+
+Taiwan GRCA
+===========
+-----BEGIN CERTIFICATE-----
+MIIFcjCCA1qgAwIBAgIQH51ZWtcvwgZEpYAIaeNe9jANBgkqhkiG9w0BAQUFADA/MQswCQYDVQQG
+EwJUVzEwMC4GA1UECgwnR292ZXJubWVudCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4X
+DTAyMTIwNTEzMjMzM1oXDTMyMTIwNTEzMjMzM1owPzELMAkGA1UEBhMCVFcxMDAuBgNVBAoMJ0dv
+dmVybm1lbnQgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQAD
+ggIPADCCAgoCggIBAJoluOzMonWoe/fOW1mKydGGEghU7Jzy50b2iPN86aXfTEc2pBsBHH8eV4qN
+w8XRIePaJD9IK/ufLqGU5ywck9G/GwGHU5nOp/UKIXZ3/6m3xnOUT0b3EEk3+qhZSV1qgQdW8or5
+BtD3cCJNtLdBuTK4sfCxw5w/cP1T3YGq2GN49thTbqGsaoQkclSGxtKyyhwOeYHWtXBiCAEuTk8O
+1RGvqa/lmr/czIdtJuTJV6L7lvnM4T9TjGxMfptTCAtsF/tnyMKtsc2AtJfcdgEWFelq16TheEfO
+htX7MfP6Mb40qij7cEwdScevLJ1tZqa2jWR+tSBqnTuBto9AAGdLiYa4zGX+FVPpBMHWXx1E1wov
+J5pGfaENda1UhhXcSTvxls4Pm6Dso3pdvtUqdULle96ltqqvKKyskKw4t9VoNSZ63Pc78/1Fm9G7
+Q3hub/FCVGqY8A2tl+lSXunVanLeavcbYBT0peS2cWeqH+riTcFCQP5nRhc4L0c/cZyu5SHKYS1t
+B6iEfC3uUSXxY5Ce/eFXiGvviiNtsea9P63RPZYLhY3Naye7twWb7LuRqQoHEgKXTiCQ8P8NHuJB
+O9NAOueNXdpm5AKwB1KYXA6OM5zCppX7VRluTI6uSw+9wThNXo+EHWbNxWCWtFJaBYmOlXqYwZE8
+lSOyDvR5tMl8wUohAgMBAAGjajBoMB0GA1UdDgQWBBTMzO/MKWCkO7GStjz6MmKPrCUVOzAMBgNV
+HRMEBTADAQH/MDkGBGcqBwAEMTAvMC0CAQAwCQYFKw4DAhoFADAHBgVnKgMAAAQUA5vwIhP/lSg2
+09yewDL7MTqKUWUwDQYJKoZIhvcNAQEFBQADggIBAECASvomyc5eMN1PhnR2WPWus4MzeKR6dBcZ
+TulStbngCnRiqmjKeKBMmo4sIy7VahIkv9Ro04rQ2JyftB8M3jh+Vzj8jeJPXgyfqzvS/3WXy6Tj
+Zwj/5cAWtUgBfen5Cv8b5Wppv3ghqMKnI6mGq3ZW6A4M9hPdKmaKZEk9GhiHkASfQlK3T8v+R0F2
+Ne//AHY2RTKbxkaFXeIksB7jSJaYV0eUVXoPQbFEJPPB/hprv4j9wabak2BegUqZIJxIZhm1AHlU
+D7gsL0u8qV1bYH+Mh6XgUmMqvtg7hUAV/h62ZT/FS9p+tXo1KaMuephgIqP0fSdOLeq0dDzpD6Qz
+DxARvBMB1uUO07+1EqLhRSPAzAhuYbeJq4PjJB7mXQfnHyA+z2fI56wwbSdLaG5LKlwCCDTb+Hbk
+Z6MmnD+iMsJKxYEYMRBWqoTvLQr/uB930r+lWKBi5NdLkXWNiYCYfm3LU05er/ayl4WXudpVBrkk
+7tfGOB5jGxI7leFYrPLfhNVfmS8NVVvmONsuP3LpSIXLuykTjx44VbnzssQwmSNOXfJIoRIM3BKQ
+CZBUkQM8R+XVyWXgt0t97EfTsws+rZ7QdAAO671RrcDeLMDDav7v3Aun+kbfYNucpllQdSNpc5Oy
++fwC00fmcc4QAu4njIT/rEUNE1yDMuAlpYYsfPQS
+-----END CERTIFICATE-----
+
+Swisscom Root CA 1
+==================
+-----BEGIN CERTIFICATE-----
+MIIF2TCCA8GgAwIBAgIQXAuFXAvnWUHfV8w/f52oNjANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQG
+EwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsTHERpZ2l0YWwgQ2VydGlmaWNhdGUgU2Vy
+dmljZXMxGzAZBgNVBAMTElN3aXNzY29tIFJvb3QgQ0EgMTAeFw0wNTA4MTgxMjA2MjBaFw0yNTA4
+MTgyMjA2MjBaMGQxCzAJBgNVBAYTAmNoMREwDwYDVQQKEwhTd2lzc2NvbTElMCMGA1UECxMcRGln
+aXRhbCBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczEbMBkGA1UEAxMSU3dpc3Njb20gUm9vdCBDQSAxMIIC
+IjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0LmwqAzZuz8h+BvVM5OAFmUgdbI9m2BtRsiM
+MW8Xw/qabFbtPMWRV8PNq5ZJkCoZSx6jbVfd8StiKHVFXqrWW/oLJdihFvkcxC7mlSpnzNApbjyF
+NDhhSbEAn9Y6cV9Nbc5fuankiX9qUvrKm/LcqfmdmUc/TilftKaNXXsLmREDA/7n29uj/x2lzZAe
+AR81sH8A25Bvxn570e56eqeqDFdvpG3FEzuwpdntMhy0XmeLVNxzh+XTF3xmUHJd1BpYwdnP2IkC
+b6dJtDZd0KTeByy2dbcokdaXvij1mB7qWybJvbCXc9qukSbraMH5ORXWZ0sKbU/Lz7DkQnGMU3nn
+7uHbHaBuHYwadzVcFh4rUx80i9Fs/PJnB3r1re3WmquhsUvhzDdf/X/NTa64H5xD+SpYVUNFvJbN
+cA78yeNmuk6NO4HLFWR7uZToXTNShXEuT46iBhFRyePLoW4xCGQMwtI89Tbo19AOeCMgkckkKmUp
+WyL3Ic6DXqTz3kvTaI9GdVyDCW4pa8RwjPWd1yAv/0bSKzjCL3UcPX7ape8eYIVpQtPM+GP+HkM5
+haa2Y0EQs3MevNP6yn0WR+Kn1dCjigoIlmJWbjTb2QK5MHXjBNLnj8KwEUAKrNVxAmKLMb7dxiNY
+MUJDLXT5xp6mig/p/r+D5kNXJLrvRjSq1xIBOO0CAwEAAaOBhjCBgzAOBgNVHQ8BAf8EBAMCAYYw
+HQYDVR0hBBYwFDASBgdghXQBUwABBgdghXQBUwABMBIGA1UdEwEB/wQIMAYBAf8CAQcwHwYDVR0j
+BBgwFoAUAyUv3m+CATpcLNwroWm1Z9SM0/0wHQYDVR0OBBYEFAMlL95vggE6XCzcK6FptWfUjNP9
+MA0GCSqGSIb3DQEBBQUAA4ICAQA1EMvspgQNDQ/NwNurqPKIlwzfky9NfEBWMXrrpA9gzXrzvsMn
+jgM+pN0S734edAY8PzHyHHuRMSG08NBsl9Tpl7IkVh5WwzW9iAUPWxAaZOHHgjD5Mq2eUCzneAXQ
+MbFamIp1TpBcahQq4FJHgmDmHtqBsfsUC1rxn9KVuj7QG9YVHaO+htXbD8BJZLsuUBlL0iT43R4H
+VtA4oJVwIHaM190e3p9xxCPvgxNcoyQVTSlAPGrEqdi3pkSlDfTgnXceQHAm/NrZNuR55LU/vJtl
+vrsRls/bxig5OgjOR1tTWsWZ/l2p3e9M1MalrQLmjAcSHm8D0W+go/MpvRLHUKKwf4ipmXeascCl
+OS5cfGniLLDqN2qk4Vrh9VDlg++luyqI54zb/W1elxmofmZ1a3Hqv7HHb6D0jqTsNFFbjCYDcKF3
+1QESVwA12yPeDooomf2xEG9L/zgtYE4snOtnta1J7ksfrK/7DZBaZmBwXarNeNQk7shBoJMBkpxq
+nvy5JMWzFYJ+vq6VK+uxwNrjAWALXmmshFZhvnEX/h0TD/7Gh0Xp/jKgGg0TpJRVcaUWi7rKibCy
+x/yP2FS1k2Kdzs9Z+z0YzirLNRWCXf9UIltxUvu3yf5gmwBBZPCqKuy2QkPOiWaByIufOVQDJdMW
+NY6E0F/6MBr1mmz0DlP5OlvRHA==
+-----END CERTIFICATE-----
+
+DigiCert Assured ID Root CA
+===========================
+-----BEGIN CERTIFICATE-----
+MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQG
+EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQw
+IgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzEx
+MTEwMDAwMDAwWjBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQL
+ExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0Ew
+ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7cJpSIqvTO
+9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYPmDI2dsze3Tyoou9q+yHy
+UmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW
+/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpy
+oeb6pNnVFzF1roV9Iq4/AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whf
+GHdPAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRF
+66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYunpyGd823IDzANBgkq
+hkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRCdWKuh+vy1dneVrOfzM4UKLkNl2Bc
+EkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTffwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38Fn
+SbNd67IJKusm7Xi+fT8r87cmNW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i
+8b5QZ7dsvfPxH2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe
++o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g==
+-----END CERTIFICATE-----
+
+DigiCert Global Root CA
+=======================
+-----BEGIN CERTIFICATE-----
+MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBhMQswCQYDVQQG
+EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAw
+HgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBDQTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAw
+MDAwMDBaMGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3
+dy5kaWdpY2VydC5jb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkq
+hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsBCSDMAZOn
+TjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97nh6Vfe63SKMI2tavegw5
+BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt43C/dxC//AH2hdmoRBBYMql1GNXRor5H
+4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7PT19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y
+7vrTC0LUq7dBMtoM1O/4gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQAB
+o2MwYTAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbRTLtm
+8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUwDQYJKoZIhvcNAQEF
+BQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/EsrhMAtudXH/vTBH1jLuG2cenTnmCmr
+EbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIt
+tep3Sp+dWOIrWcBAI+0tKIJFPnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886
+UAb3LujEV0lsYSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk
+CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=
+-----END CERTIFICATE-----
+
+DigiCert High Assurance EV Root CA
+==================================
+-----BEGIN CERTIFICATE-----
+MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBsMQswCQYDVQQG
+EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSsw
+KQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5jZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAw
+MFoXDTMxMTExMDAwMDAwMFowbDELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ
+MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFu
+Y2UgRVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm+9S75S0t
+Mqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTWPNt0OKRKzE0lgvdKpVMS
+OO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEMxChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3
+MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFBIk5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQ
+NAQTXKFx01p8VdteZOE3hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUe
+h10aUAsgEsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMB
+Af8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaAFLE+w2kD+L9HAdSY
+JhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3NecnzyIZgYIVyHbIUf4KmeqvxgydkAQ
+V8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6zeM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFp
+myPInngiK3BD41VHMWEZ71jFhS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkK
+mNEVX58Svnw2Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe
+vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep+OkuE6N36B9K
+-----END CERTIFICATE-----
+
+Certplus Class 2 Primary CA
+===========================
+-----BEGIN CERTIFICATE-----
+MIIDkjCCAnqgAwIBAgIRAIW9S/PY2uNp9pTXX8OlRCMwDQYJKoZIhvcNAQEFBQAwPTELMAkGA1UE
+BhMCRlIxETAPBgNVBAoTCENlcnRwbHVzMRswGQYDVQQDExJDbGFzcyAyIFByaW1hcnkgQ0EwHhcN
+OTkwNzA3MTcwNTAwWhcNMTkwNzA2MjM1OTU5WjA9MQswCQYDVQQGEwJGUjERMA8GA1UEChMIQ2Vy
+dHBsdXMxGzAZBgNVBAMTEkNsYXNzIDIgUHJpbWFyeSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP
+ADCCAQoCggEBANxQltAS+DXSCHh6tlJw/W/uz7kRy1134ezpfgSN1sxvc0NXYKwzCkTsA18cgCSR
+5aiRVhKC9+Ar9NuuYS6JEI1rbLqzAr3VNsVINyPi8Fo3UjMXEuLRYE2+L0ER4/YXJQyLkcAbmXuZ
+Vg2v7tK8R1fjeUl7NIknJITesezpWE7+Tt9avkGtrAjFGA7v0lPubNCdEgETjdyAYveVqUSISnFO
+YFWe2yMZeVYHDD9jC1yw4r5+FfyUM1hBOHTE4Y+L3yasH7WLO7dDWWuwJKZtkIvEcupdM5i3y95e
+e++U8Rs+yskhwcWYAqqi9lt3m/V+llU0HGdpwPFC40es/CgcZlUCAwEAAaOBjDCBiTAPBgNVHRME
+CDAGAQH/AgEKMAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQU43Mt38sOKAze3bOkynm4jrvoMIkwEQYJ
+YIZIAYb4QgEBBAQDAgEGMDcGA1UdHwQwMC4wLKAqoCiGJmh0dHA6Ly93d3cuY2VydHBsdXMuY29t
+L0NSTC9jbGFzczIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCnVM+IRBnL39R/AN9WM2K191EBkOvD
+P9GIROkkXe/nFL0gt5o8AP5tn9uQ3Nf0YtaLcF3n5QRIqWh8yfFC82x/xXp8HVGIutIKPidd3i1R
+TtMTZGnkLuPT55sJmabglZvOGtd/vjzOUrMRFcEPF80Du5wlFbqidon8BvEY0JNLDnyCt6X09l/+
+7UCmnYR0ObncHoUW2ikbhiMAybuJfm6AiB4vFLQDJKgybwOaRywwvlbGp0ICcBvqQNi6BQNwB6SW
+//1IMwrh3KWBkJtN3X3n57LNXMhqlfil9o3EXXgIvnsG1knPGTZQIy4I5p4FTUcY1Rbpsda2ENW7
+l7+ijrRU
+-----END CERTIFICATE-----
+
+DST Root CA X3
+==============
+-----BEGIN CERTIFICATE-----
+MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/MSQwIgYDVQQK
+ExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMTDkRTVCBSb290IENBIFgzMB4X
+DTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVowPzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1
+cmUgVHJ1c3QgQ28uMRcwFQYDVQQDEw5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQAD
+ggEPADCCAQoCggEBAN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmT
+rE4Orz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEqOLl5CjH9
+UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9bxiqKqy69cK3FCxolkHRy
+xXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40d
+utolucbY38EVAjqr2m7xPi71XAicPNaDaeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0T
+AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQ
+MA0GCSqGSIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69ikug
+dB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXrAvHRAosZy5Q6XkjE
+GB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZzR8srzJmwN0jP41ZL9c8PDHIyh8bw
+RLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubS
+fZGL+T0yjWW06XyxV3bqxbYoOb8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ
+-----END CERTIFICATE-----
+
+DST ACES CA X6
+==============
+-----BEGIN CERTIFICATE-----
+MIIECTCCAvGgAwIBAgIQDV6ZCtadt3js2AdWO4YV2TANBgkqhkiG9w0BAQUFADBbMQswCQYDVQQG
+EwJVUzEgMB4GA1UEChMXRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QxETAPBgNVBAsTCERTVCBBQ0VT
+MRcwFQYDVQQDEw5EU1QgQUNFUyBDQSBYNjAeFw0wMzExMjAyMTE5NThaFw0xNzExMjAyMTE5NTha
+MFsxCzAJBgNVBAYTAlVTMSAwHgYDVQQKExdEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdDERMA8GA1UE
+CxMIRFNUIEFDRVMxFzAVBgNVBAMTDkRTVCBBQ0VTIENBIFg2MIIBIjANBgkqhkiG9w0BAQEFAAOC
+AQ8AMIIBCgKCAQEAuT31LMmU3HWKlV1j6IR3dma5WZFcRt2SPp/5DgO0PWGSvSMmtWPuktKe1jzI
+DZBfZIGxqAgNTNj50wUoUrQBJcWVHAx+PhCEdc/BGZFjz+iokYi5Q1K7gLFViYsx+tC3dr5BPTCa
+pCIlF3PoHuLTrCq9Wzgh1SpL11V94zpVvddtawJXa+ZHfAjIgrrep4c9oW24MFbCswKBXy314pow
+GCi4ZtPLAZZv6opFVdbgnf9nKxcCpk4aahELfrd755jWjHZvwTvbUJN+5dCOHze4vbrGn2zpfDPy
+MjwmR/onJALJfh1biEITajV8fTXpLmaRcpPVMibEdPVTo7NdmvYJywIDAQABo4HIMIHFMA8GA1Ud
+EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgHGMB8GA1UdEQQYMBaBFHBraS1vcHNAdHJ1c3Rkc3Qu
+Y29tMGIGA1UdIARbMFkwVwYKYIZIAWUDAgEBATBJMEcGCCsGAQUFBwIBFjtodHRwOi8vd3d3LnRy
+dXN0ZHN0LmNvbS9jZXJ0aWZpY2F0ZXMvcG9saWN5L0FDRVMtaW5kZXguaHRtbDAdBgNVHQ4EFgQU
+CXIGThhDD+XWzMNqizF7eI+og7gwDQYJKoZIhvcNAQEFBQADggEBAKPYjtay284F5zLNAdMEA+V2
+5FYrnJmQ6AgwbN99Pe7lv7UkQIRJ4dEorsTCOlMwiPH1d25Ryvr/ma8kXxug/fKshMrfqfBfBC6t
+Fr8hlxCBPeP/h40y3JTlR4peahPJlJU90u7INJXQgNStMgiAVDzgvVJT11J8smk/f3rPanTK+gQq
+nExaBqXpIK1FZg9p8d2/6eMyi/rgwYZNcjwu2JN4Cir42NInPRmJX1p7ijvMDNpRrscL9yuwNwXs
+vFcj4jjSm2jzVhKIT0J8uDHEtdvkyCE06UgRNe76x5JXxZ805Mf29w4LTJxoeHtxMcfrHuBnQfO3
+oKfN5XozNmr6mis=
+-----END CERTIFICATE-----
+
+SwissSign Gold CA - G2
+======================
+-----BEGIN CERTIFICATE-----
+MIIFujCCA6KgAwIBAgIJALtAHEP1Xk+wMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNVBAYTAkNIMRUw
+EwYDVQQKEwxTd2lzc1NpZ24gQUcxHzAdBgNVBAMTFlN3aXNzU2lnbiBHb2xkIENBIC0gRzIwHhcN
+MDYxMDI1MDgzMDM1WhcNMzYxMDI1MDgzMDM1WjBFMQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dp
+c3NTaWduIEFHMR8wHQYDVQQDExZTd2lzc1NpZ24gR29sZCBDQSAtIEcyMIICIjANBgkqhkiG9w0B
+AQEFAAOCAg8AMIICCgKCAgEAr+TufoskDhJuqVAtFkQ7kpJcyrhdhJJCEyq8ZVeCQD5XJM1QiyUq
+t2/876LQwB8CJEoTlo8jE+YoWACjR8cGp4QjK7u9lit/VcyLwVcfDmJlD909Vopz2q5+bbqBHH5C
+jCA12UNNhPqE21Is8w4ndwtrvxEvcnifLtg+5hg3Wipy+dpikJKVyh+c6bM8K8vzARO/Ws/BtQpg
+vd21mWRTuKCWs2/iJneRjOBiEAKfNA+k1ZIzUd6+jbqEemA8atufK+ze3gE/bk3lUIbLtK/tREDF
+ylqM2tIrfKjuvqblCqoOpd8FUrdVxyJdMmqXl2MT28nbeTZ7hTpKxVKJ+STnnXepgv9VHKVxaSvR
+AiTysybUa9oEVeXBCsdtMDeQKuSeFDNeFhdVxVu1yzSJkvGdJo+hB9TGsnhQ2wwMC3wLjEHXuend
+jIj3o02yMszYF9rNt85mndT9Xv+9lz4pded+p2JYryU0pUHHPbwNUMoDAw8IWh+Vc3hiv69yFGkO
+peUDDniOJihC8AcLYiAQZzlG+qkDzAQ4embvIIO1jEpWjpEA/I5cgt6IoMPiaG59je883WX0XaxR
+7ySArqpWl2/5rX3aYT+YdzylkbYcjCbaZaIJbcHiVOO5ykxMgI93e2CaHt+28kgeDrpOVG2Y4OGi
+GqJ3UM/EY5LsRxmd6+ZrzsECAwEAAaOBrDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUw
+AwEB/zAdBgNVHQ4EFgQUWyV7lqRlUX64OfPAeGZe6Drn8O4wHwYDVR0jBBgwFoAUWyV7lqRlUX64
+OfPAeGZe6Drn8O4wRgYDVR0gBD8wPTA7BglghXQBWQECAQEwLjAsBggrBgEFBQcCARYgaHR0cDov
+L3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBACe645R88a7A3hfm
+5djV9VSwg/S7zV4Fe0+fdWavPOhWfvxyeDgD2StiGwC5+OlgzczOUYrHUDFu4Up+GC9pWbY9ZIEr
+44OE5iKHjn3g7gKZYbge9LgriBIWhMIxkziWMaa5O1M/wySTVltpkuzFwbs4AOPsF6m43Md8AYOf
+Mke6UiI0HTJ6CVanfCU2qT1L2sCCbwq7EsiHSycR+R4tx5M/nttfJmtS2S6K8RTGRI0Vqbe/vd6m
+Gu6uLftIdxf+u+yvGPUqUfA5hJeVbG4bwyvEdGB5JbAKJ9/fXtI5z0V9QkvfsywexcZdylU6oJxp
+mo/a77KwPJ+HbBIrZXAVUjEaJM9vMSNQH4xPjyPDdEFjHFWoFN0+4FFQz/EbMFYOkrCChdiDyyJk
+vC24JdVUorgG6q2SpCSgwYa1ShNqR88uC1aVVMvOmttqtKay20EIhid392qgQmwLOM7XdVAyksLf
+KzAiSNDVQTglXaTpXZ/GlHXQRf0wl0OPkKsKx4ZzYEppLd6leNcG2mqeSz53OiATIgHQv2ieY2Br
+NU0LbbqhPcCT4H8js1WtciVORvnSFu+wZMEBnunKoGqYDs/YYPIvSbjkQuE4NRb0yG5P94FW6Lqj
+viOvrv1vA+ACOzB2+httQc8Bsem4yWb02ybzOqR08kkkW8mw0FfB+j564ZfJ
+-----END CERTIFICATE-----
+
+SwissSign Silver CA - G2
+========================
+-----BEGIN CERTIFICATE-----
+MIIFvTCCA6WgAwIBAgIITxvUL1S7L0swDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCQ0gxFTAT
+BgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMB4X
+DTA2MTAyNTA4MzI0NloXDTM2MTAyNTA4MzI0NlowRzELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3
+aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMIICIjANBgkqhkiG
+9w0BAQEFAAOCAg8AMIICCgKCAgEAxPGHf9N4Mfc4yfjDmUO8x/e8N+dOcbpLj6VzHVxumK4DV644
+N0MvFz0fyM5oEMF4rhkDKxD6LHmD9ui5aLlV8gREpzn5/ASLHvGiTSf5YXu6t+WiE7brYT7QbNHm
++/pe7R20nqA1W6GSy/BJkv6FCgU+5tkL4k+73JU3/JHpMjUi0R86TieFnbAVlDLaYQ1HTWBCrpJH
+6INaUFjpiou5XaHc3ZlKHzZnu0jkg7Y360g6rw9njxcH6ATK72oxh9TAtvmUcXtnZLi2kUpCe2Uu
+MGoM9ZDulebyzYLs2aFK7PayS+VFheZteJMELpyCbTapxDFkH4aDCyr0NQp4yVXPQbBH6TCfmb5h
+qAaEuSh6XzjZG6k4sIN/c8HDO0gqgg8hm7jMqDXDhBuDsz6+pJVpATqJAHgE2cn0mRmrVn5bi4Y5
+FZGkECwJMoBgs5PAKrYYC51+jUnyEEp/+dVGLxmSo5mnJqy7jDzmDrxHB9xzUfFwZC8I+bRHHTBs
+ROopN4WSaGa8gzj+ezku01DwH/teYLappvonQfGbGHLy9YR0SslnxFSuSGTfjNFusB3hB48IHpmc
+celM2KX3RxIfdNFRnobzwqIjQAtz20um53MGjMGg6cFZrEb65i/4z3GcRm25xBWNOHkDRUjvxF3X
+CO6HOSKGsg0PWEP3calILv3q1h8CAwEAAaOBrDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/
+BAUwAwEB/zAdBgNVHQ4EFgQUF6DNweRBtjpbO8tFnb0cwpj6hlgwHwYDVR0jBBgwFoAUF6DNweRB
+tjpbO8tFnb0cwpj6hlgwRgYDVR0gBD8wPTA7BglghXQBWQEDAQEwLjAsBggrBgEFBQcCARYgaHR0
+cDovL3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBAHPGgeAn0i0P
+4JUw4ppBf1AsX19iYamGamkYDHRJ1l2E6kFSGG9YrVBWIGrGvShpWJHckRE1qTodvBqlYJ7YH39F
+kWnZfrt4csEGDyrOj4VwYaygzQu4OSlWhDJOhrs9xCrZ1x9y7v5RoSJBsXECYxqCsGKrXlcSH9/L
+3XWgwF15kIwb4FDm3jH+mHtwX6WQ2K34ArZv02DdQEsixT2tOnqfGhpHkXkzuoLcMmkDlm4fS/Bx
+/uNncqCxv1yL5PqZIseEuRuNI5c/7SXgz2W79WEE790eslpBIlqhn10s6FvJbakMDHiqYMZWjwFa
+DGi8aRl5xB9+lwW/xekkUV7U1UtT7dkjWjYDZaPBA61BMPNGG4WQr2W11bHkFlt4dR2Xem1ZqSqP
+e97Dh4kQmUlzeMg9vVE1dCrV8X5pGyq7O70luJpaPXJhkGaH7gzWTdQRdAtq/gsD/KNVV4n+Ssuu
+WxcFyPKNIzFTONItaj+CuY0IavdeQXRuwxF+B6wpYJE/OMpXEA29MC/HpeZBoNquBYeaoKRlbEwJ
+DIm6uNO5wJOKMPqN5ZprFQFOZ6raYlY+hAhm0sQ2fac+EPyI4NSA5QC9qvNOBqN6avlicuMJT+ub
+DgEj8Z+7fNzcbBGXJbLytGMU0gYqZ4yD9c7qB9iaah7s5Aq7KkzrCWA5zspi2C5u
+-----END CERTIFICATE-----
+
+GeoTrust Primary Certification Authority
+========================================
+-----BEGIN CERTIFICATE-----
+MIIDfDCCAmSgAwIBAgIQGKy1av1pthU6Y2yv2vrEoTANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQG
+EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjExMC8GA1UEAxMoR2VvVHJ1c3QgUHJpbWFyeSBD
+ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjExMjcwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMFgx
+CzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTEwLwYDVQQDEyhHZW9UcnVzdCBQ
+cmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
+CgKCAQEAvrgVe//UfH1nrYNke8hCUy3f9oQIIGHWAVlqnEQRr+92/ZV+zmEwu3qDXwK9AWbK7hWN
+b6EwnL2hhZ6UOvNWiAAxz9juapYC2e0DjPt1befquFUWBRaa9OBesYjAZIVcFU2Ix7e64HXprQU9
+nceJSOC7KMgD4TCTZF5SwFlwIjVXiIrxlQqD17wxcwE07e9GceBrAqg1cmuXm2bgyxx5X9gaBGge
+RwLmnWDiNpcB3841kt++Z8dtd1k7j53WkBWUvEI0EME5+bEnPn7WinXFsq+W06Lem+SYvn3h6YGt
+tm/81w7a4DSwDRp35+MImO9Y+pyEtzavwt+s0vQQBnBxNQIDAQABo0IwQDAPBgNVHRMBAf8EBTAD
+AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQULNVQQZcVi/CPNmFbSvtr2ZnJM5IwDQYJKoZI
+hvcNAQEFBQADggEBAFpwfyzdtzRP9YZRqSa+S7iq8XEN3GHHoOo0Hnp3DwQ16CePbJC/kRYkRj5K
+Ts4rFtULUh38H2eiAkUxT87z+gOneZ1TatnaYzr4gNfTmeGl4b7UVXGYNTq+k+qurUKykG/g/CFN
+NWMziUnWm07Kx+dOCQD32sfvmWKZd7aVIl6KoKv0uHiYyjgZmclynnjNS6yvGaBzEi38wkG6gZHa
+Floxt/m0cYASSJlyc1pZU8FjUjPtp8nSOQJw+uCxQmYpqptR7TBUIhRf2asdweSU8Pj1K/fqynhG
+1riR/aYNKxoUAT6A8EKglQdebc3MS6RFjasS6LPeWuWgfOgPIh1a6Vk=
+-----END CERTIFICATE-----
+
+thawte Primary Root CA
+======================
+-----BEGIN CERTIFICATE-----
+MIIEIDCCAwigAwIBAgIQNE7VVyDV7exJ9C/ON9srbTANBgkqhkiG9w0BAQUFADCBqTELMAkGA1UE
+BhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2
+aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhv
+cml6ZWQgdXNlIG9ubHkxHzAdBgNVBAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMDYxMTE3
+MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCBqTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwg
+SW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMv
+KGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNVBAMT
+FnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCs
+oPD7gFnUnMekz52hWXMJEEUMDSxuaPFsW0hoSVk3/AszGcJ3f8wQLZU0HObrTQmnHNK4yZc2AreJ
+1CRfBsDMRJSUjQJib+ta3RGNKJpchJAQeg29dGYvajig4tVUROsdB58Hum/u6f1OCyn1PoSgAfGc
+q/gcfomk6KHYcWUNo1F77rzSImANuVud37r8UVsLr5iy6S7pBOhih94ryNdOwUxkHt3Ph1i6Sk/K
+aAcdHJ1KxtUvkcx8cXIcxcBn6zL9yZJclNqFwJu/U30rCfSMnZEfl2pSy94JNqR32HuHUETVPm4p
+afs5SSYeCaWAe0At6+gnhcn+Yf1+5nyXHdWdAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYD
+VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBR7W0XPr87Lev0xkhpqtvNG61dIUDANBgkqhkiG9w0BAQUF
+AAOCAQEAeRHAS7ORtvzw6WfUDW5FvlXok9LOAz/t2iWwHVfLHjp2oEzsUHboZHIMpKnxuIvW1oeE
+uzLlQRHAd9mzYJ3rG9XRbkREqaYB7FViHXe4XI5ISXycO1cRrK1zN44veFyQaEfZYGDm/Ac9IiAX
+xPcW6cTYcvnIc3zfFi8VqT79aie2oetaupgf1eNNZAqdE8hhuvU5HIe6uL17In/2/qxAeeWsEG89
+jxt5dovEN7MhGITlNgDrYyCZuen+MwS7QcjBAvlEYyCegc5C09Y/LHbTY5xZ3Y+m4Q6gLkH3LpVH
+z7z9M/P2C2F+fpErgUfCJzDupxBdN49cOSvkBPB7jVaMaA==
+-----END CERTIFICATE-----
+
+VeriSign Class 3 Public Primary Certification Authority - G5
+============================================================
+-----BEGIN CERTIFICATE-----
+MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCByjELMAkGA1UE
+BhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBO
+ZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVk
+IHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRp
+ZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCB
+yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2ln
+biBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2lnbiwgSW5jLiAtIEZvciBh
+dXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmlt
+YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
+ggEKAoIBAQCvJAgIKXo1nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKz
+j/i5Vbext0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIzSdhD
+Y2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQGBO+QueQA5N06tRn/
+Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+rCpSx4/VBEnkjWNHiDxpg8v+R70r
+fk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/
+BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2Uv
+Z2lmMCEwHzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy
+aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKvMzEzMA0GCSqG
+SIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzEp6B4Eq1iDkVwZMXnl2YtmAl+
+X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKE
+KQsTb47bDN0lAtukixlE0kF6BWlKWE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiC
+Km0oHw0LxOXnGiYZ4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vE
+ZV8NhnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq
+-----END CERTIFICATE-----
+
+SecureTrust CA
+==============
+-----BEGIN CERTIFICATE-----
+MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBIMQswCQYDVQQG
+EwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xFzAVBgNVBAMTDlNlY3VyZVRy
+dXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIzMTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAe
+BgNVBAoTF1NlY3VyZVRydXN0IENvcnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCC
+ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQX
+OZEzZum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO0gMdA+9t
+DWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIaowW8xQmxSPmjL8xk037uH
+GFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b
+01k/unK8RCSc43Oz969XL0Imnal0ugBS8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmH
+ursCAwEAAaOBnTCBmjATBgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/
+BAUwAwEB/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCegJYYj
+aHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQAwDQYJ
+KoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt36Z3q059c4EVlew3KW+JwULKUBRSu
+SceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHf
+mbx8IVQr5Fiiu1cprp6poxkmD5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZ
+nMUFdAvnZyPSCPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR
+3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE=
+-----END CERTIFICATE-----
+
+Secure Global CA
+================
+-----BEGIN CERTIFICATE-----
+MIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQG
+EwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBH
+bG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkxMjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEg
+MB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwg
+Q0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jx
+YDiJiQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa/FHtaMbQ
+bqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJjnIFHovdRIWCQtBJwB1g
+8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnIHmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYV
+HDGA76oYa8J719rO+TMg1fW9ajMtgQT7sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi
+0XPnj3pDAgMBAAGjgZ0wgZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1Ud
+EwEB/wQFMAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCswKaAn
+oCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsGAQQBgjcVAQQDAgEA
+MA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0LURYD7xh8yOOvaliTFGCRsoTciE6+
+OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXOH0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cn
+CDpOGR86p1hcF895P4vkp9MmI50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/5
+3CYNv6ZHdAbYiNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc
+f8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW
+-----END CERTIFICATE-----
+
+COMODO Certification Authority
+==============================
+-----BEGIN CERTIFICATE-----
+MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCBgTELMAkGA1UE
+BhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgG
+A1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNVBAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1
+dGhvcml0eTAeFw0wNjEyMDEwMDAwMDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEb
+MBkGA1UECBMSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFD
+T01PRE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0aG9yaXR5
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3UcEbVASY06m/weaKXTuH
++7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI2GqGd0S7WWaXUF601CxwRM/aN5VCaTww
+xHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV
+4EajcNxo2f8ESIl33rXp+2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA
+1KGzqSX+DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5OnKVI
+rLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW/zAOBgNVHQ8BAf8E
+BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6gPKA6hjhodHRwOi8vY3JsLmNvbW9k
+b2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9uQXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOC
+AQEAPpiem/Yb6dc5t3iuHXIYSdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CP
+OGEIqB6BCsAvIC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/
+RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4zJVSk/BwJVmc
+IGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5ddBA6+C4OmF4O5MBKgxTMVBbkN
++8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IBZQ==
+-----END CERTIFICATE-----
+
+Network Solutions Certificate Authority
+=======================================
+-----BEGIN CERTIFICATE-----
+MIID5jCCAs6gAwIBAgIQV8szb8JcFuZHFhfjkDFo4DANBgkqhkiG9w0BAQUFADBiMQswCQYDVQQG
+EwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMuMTAwLgYDVQQDEydOZXR3b3Jr
+IFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDYxMjAxMDAwMDAwWhcNMjkxMjMx
+MjM1OTU5WjBiMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMu
+MTAwLgYDVQQDEydOZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0G
+CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkvH6SMG3G2I4rC7xGzuAnlt7e+foS0zwzc7MEL7xx
+jOWftiJgPl9dzgn/ggwbmlFQGiaJ3dVhXRncEg8tCqJDXRfQNJIg6nPPOCwGJgl6cvf6UDL4wpPT
+aaIjzkGxzOTVHzbRijr4jGPiFFlp7Q3Tf2vouAPlT2rlmGNpSAW+Lv8ztumXWWn4Zxmuk2GWRBXT
+crA/vGp97Eh/jcOrqnErU2lBUzS1sLnFBgrEsEX1QV1uiUV7PTsmjHTC5dLRfbIR1PtYMiKagMnc
+/Qzpf14Dl847ABSHJ3A4qY5usyd2mFHgBeMhqxrVhSI8KbWaFsWAqPS7azCPL0YCorEMIuDTAgMB
+AAGjgZcwgZQwHQYDVR0OBBYEFCEwyfsA106Y2oeqKtCnLrFAMadMMA4GA1UdDwEB/wQEAwIBBjAP
+BgNVHRMBAf8EBTADAQH/MFIGA1UdHwRLMEkwR6BFoEOGQWh0dHA6Ly9jcmwubmV0c29sc3NsLmNv
+bS9OZXR3b3JrU29sdXRpb25zQ2VydGlmaWNhdGVBdXRob3JpdHkuY3JsMA0GCSqGSIb3DQEBBQUA
+A4IBAQC7rkvnt1frf6ott3NHhWrB5KUd5Oc86fRZZXe1eltajSU24HqXLjjAV2CDmAaDn7l2em5Q
+4LqILPxFzBiwmZVRDuwduIj/h1AcgsLj4DKAv6ALR8jDMe+ZZzKATxcheQxpXN5eNK4CtSbqUN9/
+GGUsyfJj4akH/nxxH2szJGoeBfcFaMBqEssuXmHLrijTfsK0ZpEmXzwuJF/LWA/rKOyvEZbz3Htv
+wKeI8lN3s2Berq4o2jUsbzRF0ybh3uxbTydrFny9RAQYgrOJeRcQcT16ohZO9QHNpGxlaKFJdlxD
+ydi8NmdspZS11My5vWo1ViHe2MPr+8ukYEywVaCge1ey
+-----END CERTIFICATE-----
+
+COMODO ECC Certification Authority
+==================================
+-----BEGIN CERTIFICATE-----
+MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTELMAkGA1UEBhMC
+R0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UE
+ChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBB
+dXRob3JpdHkwHhcNMDgwMzA2MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0Ix
+GzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR
+Q09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRo
+b3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSRFtSrYpn1PlILBs5BAH+X
+4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0JcfRK9ChQtP6IHG4/bC8vCVlbpVsLM5ni
+wz2J+Wos77LTBumjQjBAMB0GA1UdDgQWBBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8E
+BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VG
+FAkK+qDmfQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdvGDeA
+U/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY=
+-----END CERTIFICATE-----
+
+Security Communication EV RootCA1
+=================================
+-----BEGIN CERTIFICATE-----
+MIIDfTCCAmWgAwIBAgIBADANBgkqhkiG9w0BAQUFADBgMQswCQYDVQQGEwJKUDElMCMGA1UEChMc
+U0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEqMCgGA1UECxMhU2VjdXJpdHkgQ29tbXVuaWNh
+dGlvbiBFViBSb290Q0ExMB4XDTA3MDYwNjAyMTIzMloXDTM3MDYwNjAyMTIzMlowYDELMAkGA1UE
+BhMCSlAxJTAjBgNVBAoTHFNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4xKjAoBgNVBAsTIVNl
+Y3VyaXR5IENvbW11bmljYXRpb24gRVYgUm9vdENBMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
+AQoCggEBALx/7FebJOD+nLpCeamIivqA4PUHKUPqjgo0No0c+qe1OXj/l3X3L+SqawSERMqm4miO
+/VVQYg+kcQ7OBzgtQoVQrTyWb4vVog7P3kmJPdZkLjjlHmy1V4qe70gOzXppFodEtZDkBp2uoQSX
+WHnvIEqCa4wiv+wfD+mEce3xDuS4GBPMVjZd0ZoeUWs5bmB2iDQL87PRsJ3KYeJkHcFGB7hj3R4z
+ZbOOCVVSPbW9/wfrrWFVGCypaZhKqkDFMxRldAD5kd6vA0jFQFTcD4SQaCDFkpbcLuUCRarAX1T4
+bepJz11sS6/vmsJWXMY1VkJqMF/Cq/biPT+zyRGPMUzXn0kCAwEAAaNCMEAwHQYDVR0OBBYEFDVK
+9U2vP9eCOKyrcWUXdYydVZPmMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqG
+SIb3DQEBBQUAA4IBAQCoh+ns+EBnXcPBZsdAS5f8hxOQWsTvoMpfi7ent/HWtWS3irO4G8za+6xm
+iEHO6Pzk2x6Ipu0nUBsCMCRGef4Eh3CXQHPRwMFXGZpppSeZq51ihPZRwSzJIxXYKLerJRO1RuGG
+Av8mjMSIkh1W/hln8lXkgKNrnKt34VFxDSDbEJrbvXZ5B3eZKK2aXtqxT0QsNY6llsf9g/BYxnnW
+mHyojf6GPgcWkuF75x3sM3Z+Qi5KhfmRiWiEA4Glm5q+4zfFVKtWOxgtQaQM+ELbmaDgcm+7XeEW
+T1MKZPlO9L9OVL14bIjqv5wTJMJwaaJ/D8g8rQjJsJhAoyrniIPtd490
+-----END CERTIFICATE-----
+
+OISTE WISeKey Global Root GA CA
+===============================
+-----BEGIN CERTIFICATE-----
+MIID8TCCAtmgAwIBAgIQQT1yx/RrH4FDffHSKFTfmjANBgkqhkiG9w0BAQUFADCBijELMAkGA1UE
+BhMCQ0gxEDAOBgNVBAoTB1dJU2VLZXkxGzAZBgNVBAsTEkNvcHlyaWdodCAoYykgMjAwNTEiMCAG
+A1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBH
+bG9iYWwgUm9vdCBHQSBDQTAeFw0wNTEyMTExNjAzNDRaFw0zNzEyMTExNjA5NTFaMIGKMQswCQYD
+VQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEbMBkGA1UECxMSQ29weXJpZ2h0IChjKSAyMDA1MSIw
+IAYDVQQLExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5
+IEdsb2JhbCBSb290IEdBIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAy0+zAJs9
+Nt350UlqaxBJH+zYK7LG+DKBKUOVTJoZIyEVRd7jyBxRVVuuk+g3/ytr6dTqvirdqFEr12bDYVxg
+Asj1znJ7O7jyTmUIms2kahnBAbtzptf2w93NvKSLtZlhuAGio9RN1AU9ka34tAhxZK9w8RxrfvbD
+d50kc3vkDIzh2TbhmYsFmQvtRTEJysIA2/dyoJaqlYfQjse2YXMNdmaM3Bu0Y6Kff5MTMPGhJ9vZ
+/yxViJGg4E8HsChWjBgbl0SOid3gF27nKu+POQoxhILYQBRJLnpB5Kf+42TMwVlxSywhp1t94B3R
+LoGbw9ho972WG6xwsRYUC9tguSYBBQIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUw
+AwEB/zAdBgNVHQ4EFgQUswN+rja8sHnR3JQmthG+IbJphpQwEAYJKwYBBAGCNxUBBAMCAQAwDQYJ
+KoZIhvcNAQEFBQADggEBAEuh/wuHbrP5wUOxSPMowB0uyQlB+pQAHKSkq0lPjz0e701vvbyk9vIm
+MMkQyh2I+3QZH4VFvbBsUfk2ftv1TDI6QU9bR8/oCy22xBmddMVHxjtqD6wU2zz0c5ypBd8A3HR4
++vg1YFkCExh8vPtNsCBtQ7tgMHpnM1zFmdH4LTlSc/uMqpclXHLZCB6rTjzjgTGfA6b7wP4piFXa
+hNVQA7bihKOmNqoROgHhGEvWRGizPflTdISzRpFGlgC3gCy24eMQ4tui5yiPAZZiFj4A4xylNoEY
+okxSdsARo27mHbrjWr42U8U+dY+GaSlYU7Wcu2+fXMUY7N0v4ZjJ/L7fCg0=
+-----END CERTIFICATE-----
+
+Certigna
+========
+-----BEGIN CERTIFICATE-----
+MIIDqDCCApCgAwIBAgIJAP7c4wEPyUj/MA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNVBAYTAkZSMRIw
+EAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hMB4XDTA3MDYyOTE1MTMwNVoXDTI3
+MDYyOTE1MTMwNVowNDELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczERMA8GA1UEAwwI
+Q2VydGlnbmEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDIaPHJ1tazNHUmgh7stL7q
+XOEm7RFHYeGifBZ4QCHkYJ5ayGPhxLGWkv8YbWkj4Sti993iNi+RB7lIzw7sebYs5zRLcAglozyH
+GxnygQcPOJAZ0xH+hrTy0V4eHpbNgGzOOzGTtvKg0KmVEn2lmsxryIRWijOp5yIVUxbwzBfsV1/p
+ogqYCd7jX5xv3EjjhQsVWqa6n6xI4wmy9/Qy3l40vhx4XUJbzg4ij02Q130yGLMLLGq/jj8UEYkg
+DncUtT2UCIf3JR7VsmAA7G8qKCVuKj4YYxclPz5EIBb2JsglrgVKtOdjLPOMFlN+XPsRGgjBRmKf
+Irjxwo1p3Po6WAbfAgMBAAGjgbwwgbkwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUGu3+QTmQ
+tCRZvgHyUtVF9lo53BEwZAYDVR0jBF0wW4AUGu3+QTmQtCRZvgHyUtVF9lo53BGhOKQ2MDQxCzAJ
+BgNVBAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hggkA/tzjAQ/J
+SP8wDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzANBgkqhkiG9w0BAQUFAAOCAQEA
+hQMeknH2Qq/ho2Ge6/PAD/Kl1NqV5ta+aDY9fm4fTIrv0Q8hbV6lUmPOEvjvKtpv6zf+EwLHyzs+
+ImvaYS5/1HI93TDhHkxAGYwP15zRgzB7mFncfca5DClMoTOi62c6ZYTTluLtdkVwj7Ur3vkj1klu
+PBS1xp81HlDQwY9qcEQCYsuuHWhBp6pX6FOqB9IG9tUUBguRA3UsbHK1YZWaDYu5Def131TN3ubY
+1gkIl2PlwS6wt0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw
+WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg==
+-----END CERTIFICATE-----
+
+Deutsche Telekom Root CA 2
+==========================
+-----BEGIN CERTIFICATE-----
+MIIDnzCCAoegAwIBAgIBJjANBgkqhkiG9w0BAQUFADBxMQswCQYDVQQGEwJERTEcMBoGA1UEChMT
+RGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxlU2VjIFRydXN0IENlbnRlcjEjMCEG
+A1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290IENBIDIwHhcNOTkwNzA5MTIxMTAwWhcNMTkwNzA5
+MjM1OTAwWjBxMQswCQYDVQQGEwJERTEcMBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0G
+A1UECxMWVC1UZWxlU2VjIFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBS
+b290IENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrC6M14IspFLEUha88EOQ5
+bzVdSq7d6mGNlUn0b2SjGmBmpKlAIoTZ1KXleJMOaAGtuU1cOs7TuKhCQN/Po7qCWWqSG6wcmtoI
+KyUn+WkjR/Hg6yx6m/UTAtB+NHzCnjwAWav12gz1MjwrrFDa1sPeg5TKqAyZMg4ISFZbavva4VhY
+AUlfckE8FQYBjl2tqriTtM2e66foai1SNNs671x1Udrb8zH57nGYMsRUFUQM+ZtV7a3fGAigo4aK
+Se5TBY8ZTNXeWHmb0mocQqvF1afPaA+W5OFhmHZhyJF81j4A4pFQh+GdCuatl9Idxjp9y7zaAzTV
+jlsB9WoHtxa2bkp/AgMBAAGjQjBAMB0GA1UdDgQWBBQxw3kbuvVT1xfgiXotF2wKsyudMzAPBgNV
+HRMECDAGAQH/AgEFMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAlGRZrTlk5ynr
+E/5aw4sTV8gEJPB0d8Bg42f76Ymmg7+Wgnxu1MM9756AbrsptJh6sTtU6zkXR34ajgv8HzFZMQSy
+zhfzLMdiNlXiItiJVbSYSKpk+tYcNthEeFpaIzpXl/V6ME+un2pMSyuOoAPjPuCp1NJ70rOo4nI8
+rZ7/gFnkm0W09juwzTkZmDLl6iFhkOQxIY40sfcvNUqFENrnijchvllj4PKFiDFT1FQUhXB59C4G
+dyd1Lx+4ivn+xbrYNuSD7Odlt79jWvNGr4GUN9RBjNYj1h7P9WgbRGOiWrqnNVmh5XAFmw4jV5mU
+Cm26OWMohpLzGITY+9HPBVZkVw==
+-----END CERTIFICATE-----
+
+Cybertrust Global Root
+======================
+-----BEGIN CERTIFICATE-----
+MIIDoTCCAomgAwIBAgILBAAAAAABD4WqLUgwDQYJKoZIhvcNAQEFBQAwOzEYMBYGA1UEChMPQ3li
+ZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2JhbCBSb290MB4XDTA2MTIxNTA4
+MDAwMFoXDTIxMTIxNTA4MDAwMFowOzEYMBYGA1UEChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQD
+ExZDeWJlcnRydXN0IEdsb2JhbCBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
++Mi8vRRQZhP/8NN57CPytxrHjoXxEnOmGaoQ25yiZXRadz5RfVb23CO21O1fWLE3TdVJDm71aofW
+0ozSJ8bi/zafmGWgE07GKmSb1ZASzxQG9Dvj1Ci+6A74q05IlG2OlTEQXO2iLb3VOm2yHLtgwEZL
+AfVJrn5GitB0jaEMAs7u/OePuGtm839EAL9mJRQr3RAwHQeWP032a7iPt3sMpTjr3kfb1V05/Iin
+89cqdPHoWqI7n1C6poxFNcJQZZXcY4Lv3b93TZxiyWNzFtApD0mpSPCzqrdsxacwOUBdrsTiXSZT
+8M4cIwhhqJQZugRiQOwfOHB3EgZxpzAYXSUnpQIDAQABo4GlMIGiMA4GA1UdDwEB/wQEAwIBBjAP
+BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBS2CHsNesysIEyGVjJez6tuhS1wVzA/BgNVHR8EODA2
+MDSgMqAwhi5odHRwOi8vd3d3Mi5wdWJsaWMtdHJ1c3QuY29tL2NybC9jdC9jdHJvb3QuY3JsMB8G
+A1UdIwQYMBaAFLYIew16zKwgTIZWMl7Pq26FLXBXMA0GCSqGSIb3DQEBBQUAA4IBAQBW7wojoFRO
+lZfJ+InaRcHUowAl9B8Tq7ejhVhpwjCt2BWKLePJzYFa+HMjWqd8BfP9IjsO0QbE2zZMcwSO5bAi
+5MXzLqXZI+O4Tkogp24CJJ8iYGd7ix1yCcUxXOl5n4BHPa2hCwcUPUf/A2kaDAtE52Mlp3+yybh2
+hO0j9n0Hq0V+09+zv+mKts2oomcrUtW3ZfA5TGOgkXmTUg9U3YO7n9GPp1Nzw8v/MOx8BLjYRB+T
+X3EJIrduPuocA06dGiBh+4E37F78CkWr1+cXVdCg6mCbpvbjjFspwgZgFJ0tl0ypkxWdYcQBX0jW
+WL1WMRJOEcgh4LMRkWXbtKaIOM5V
+-----END CERTIFICATE-----
+
+ePKI Root Certification Authority
+=================================
+-----BEGIN CERTIFICATE-----
+MIIFsDCCA5igAwIBAgIQFci9ZUdcr7iXAF7kBtK8nTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQG
+EwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0ZC4xKjAoBgNVBAsMIWVQS0kg
+Um9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNDEyMjAwMjMxMjdaFw0zNDEyMjAwMjMx
+MjdaMF4xCzAJBgNVBAYTAlRXMSMwIQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEq
+MCgGA1UECwwhZVBLSSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0B
+AQEFAAOCAg8AMIICCgKCAgEA4SUP7o3biDN1Z82tH306Tm2d0y8U82N0ywEhajfqhFAHSyZbCUNs
+IZ5qyNUD9WBpj8zwIuQf5/dqIjG3LBXy4P4AakP/h2XGtRrBp0xtInAhijHyl3SJCRImHJ7K2RKi
+lTza6We/CKBk49ZCt0Xvl/T29de1ShUCWH2YWEtgvM3XDZoTM1PRYfl61dd4s5oz9wCGzh1NlDiv
+qOx4UXCKXBCDUSH3ET00hl7lSM2XgYI1TBnsZfZrxQWh7kcT1rMhJ5QQCtkkO7q+RBNGMD+XPNjX
+12ruOzjjK9SXDrkb5wdJfzcq+Xd4z1TtW0ado4AOkUPB1ltfFLqfpo0kR0BZv3I4sjZsN/+Z0V0O
+WQqraffAsgRFelQArr5T9rXn4fg8ozHSqf4hUmTFpmfwdQcGlBSBVcYn5AGPF8Fqcde+S/uUWH1+
+ETOxQvdibBjWzwloPn9s9h6PYq2lY9sJpx8iQkEeb5mKPtf5P0B6ebClAZLSnT0IFaUQAS2zMnao
+lQ2zepr7BxB4EW/hj8e6DyUadCrlHJhBmd8hh+iVBmoKs2pHdmX2Os+PYhcZewoozRrSgx4hxyy/
+vv9haLdnG7t4TY3OZ+XkwY63I2binZB1NJipNiuKmpS5nezMirH4JYlcWrYvjB9teSSnUmjDhDXi
+Zo1jDiVN1Rmy5nk3pyKdVDECAwEAAaNqMGgwHQYDVR0OBBYEFB4M97Zn8uGSJglFwFU5Lnc/Qkqi
+MAwGA1UdEwQFMAMBAf8wOQYEZyoHAAQxMC8wLQIBADAJBgUrDgMCGgUAMAcGBWcqAwAABBRFsMLH
+ClZ87lt4DJX5GFPBphzYEDANBgkqhkiG9w0BAQUFAAOCAgEACbODU1kBPpVJufGBuvl2ICO1J2B0
+1GqZNF5sAFPZn/KmsSQHRGoqxqWOeBLoR9lYGxMqXnmbnwoqZ6YlPwZpVnPDimZI+ymBV3QGypzq
+KOg4ZyYr8dW1P2WT+DZdjo2NQCCHGervJ8A9tDkPJXtoUHRVnAxZfVo9QZQlUgjgRywVMRnVvwdV
+xrsStZf0X4OFunHB2WyBEXYKCrC/gpf36j36+uwtqSiUO1bd0lEursC9CBWMd1I0ltabrNMdjmEP
+NXubrjlpC2JgQCA2j6/7Nu4tCEoduL+bXPjqpRugc6bY+G7gMwRfaKonh+3ZwZCc7b3jajWvY9+r
+GNm65ulK6lCKD2GTHuItGeIwlDWSXQ62B68ZgI9HkFFLLk3dheLSClIKF5r8GrBQAuUBo2M3IUxE
+xJtRmREOc5wGj1QupyheRDmHVi03vYVElOEMSyycw5KFNGHLD7ibSkNS/jQ6fbjpKdx2qcgw+BRx
+gMYeNkh0IkFch4LoGHGLQYlE535YW6i4jRPpp2zDR+2zGp1iro2C6pSe3VkQw63d4k3jMdXH7Ojy
+sP6SHhYKGvzZ8/gntsm+HbRsZJB/9OTEW9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmOD
+BCEIZ43ygknQW/2xzQ+DhNQ+IIX3Sj0rnP0qCglN6oH4EZw=
+-----END CERTIFICATE-----
+
+T\xc3\x9c\x42\xC4\xB0TAK UEKAE K\xC3\xB6k Sertifika Hizmet Sa\xC4\x9Flay\xc4\xb1\x63\xc4\xb1s\xc4\xb1 - S\xC3\xBCr\xC3\xBCm 3
+=============================================================================================================================
+-----BEGIN CERTIFICATE-----
+MIIFFzCCA/+gAwIBAgIBETANBgkqhkiG9w0BAQUFADCCASsxCzAJBgNVBAYTAlRSMRgwFgYDVQQH
+DA9HZWJ6ZSAtIEtvY2FlbGkxRzBFBgNVBAoMPlTDvHJraXllIEJpbGltc2VsIHZlIFRla25vbG9q
+aWsgQXJhxZ90xLFybWEgS3VydW11IC0gVMOcQsSwVEFLMUgwRgYDVQQLDD9VbHVzYWwgRWxla3Ry
+b25payB2ZSBLcmlwdG9sb2ppIEFyYcWfdMSxcm1hIEVuc3RpdMO8c8O8IC0gVUVLQUUxIzAhBgNV
+BAsMGkthbXUgU2VydGlmaWthc3lvbiBNZXJrZXppMUowSAYDVQQDDEFUw5xCxLBUQUsgVUVLQUUg
+S8O2ayBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsSAtIFPDvHLDvG0gMzAeFw0wNzA4
+MjQxMTM3MDdaFw0xNzA4MjExMTM3MDdaMIIBKzELMAkGA1UEBhMCVFIxGDAWBgNVBAcMD0dlYnpl
+IC0gS29jYWVsaTFHMEUGA1UECgw+VMO8cmtpeWUgQmlsaW1zZWwgdmUgVGVrbm9sb2ppayBBcmHF
+n3TEsXJtYSBLdXJ1bXUgLSBUw5xCxLBUQUsxSDBGBgNVBAsMP1VsdXNhbCBFbGVrdHJvbmlrIHZl
+IEtyaXB0b2xvamkgQXJhxZ90xLFybWEgRW5zdGl0w7xzw7wgLSBVRUtBRTEjMCEGA1UECwwaS2Ft
+dSBTZXJ0aWZpa2FzeW9uIE1lcmtlemkxSjBIBgNVBAMMQVTDnELEsFRBSyBVRUtBRSBLw7ZrIFNl
+cnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxIC0gU8O8csO8bSAzMIIBIjANBgkqhkiG9w0B
+AQEFAAOCAQ8AMIIBCgKCAQEAim1L/xCIOsP2fpTo6iBkcK4hgb46ezzb8R1Sf1n68yJMlaCQvEhO
+Eav7t7WNeoMojCZG2E6VQIdhn8WebYGHV2yKO7Rm6sxA/OOqbLLLAdsyv9Lrhc+hDVXDWzhXcLh1
+xnnRFDDtG1hba+818qEhTsXOfJlfbLm4IpNQp81McGq+agV/E5wrHur+R84EpW+sky58K5+eeROR
+6Oqeyjh1jmKwlZMq5d/pXpduIF9fhHpEORlAHLpVK/swsoHvhOPc7Jg4OQOFCKlUAwUp8MmPi+oL
+hmUZEdPpCSPeaJMDyTYcIW7OjGbxmTDY17PDHfiBLqi9ggtm/oLL4eAagsNAgQIDAQABo0IwQDAd
+BgNVHQ4EFgQUvYiHyY/2pAoLquvF/pEjnatKijIwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF
+MAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAB18+kmPNOm3JpIWmgV050vQbTlswyb2zrgxvMTfvCr4
+N5EY3ATIZJkrGG2AA1nJrvhY0D7twyOfaTyGOBye79oneNGEN3GKPEs5z35FBtYt2IpNeBLWrcLT
+y9LQQfMmNkqblWwM7uXRQydmwYj3erMgbOqwaSvHIOgMA8RBBZniP+Rr+KCGgceExh/VS4ESshYh
+LBOhgLJeDEoTniDYYkCrkOpkSi+sDQESeUWoL4cZaMjihccwsnX5OD+ywJO0a+IDRM5noN+J1q2M
+dqMTw5RhK2vZbMEHCiIHhWyFJEapvj+LeISCfiQMnf2BN+MlqO02TpUsyZyQ2uypQjyttgI=
+-----END CERTIFICATE-----
+
+certSIGN ROOT CA
+================
+-----BEGIN CERTIFICATE-----
+MIIDODCCAiCgAwIBAgIGIAYFFnACMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNVBAYTAlJPMREwDwYD
+VQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBDQTAeFw0wNjA3MDQxNzIwMDRa
+Fw0zMTA3MDQxNzIwMDRaMDsxCzAJBgNVBAYTAlJPMREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UE
+CxMQY2VydFNJR04gUk9PVCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALczuX7I
+JUqOtdu0KBuqV5Do0SLTZLrTk+jUrIZhQGpgV2hUhE28alQCBf/fm5oqrl0Hj0rDKH/v+yv6efHH
+rfAQUySQi2bJqIirr1qjAOm+ukbuW3N7LBeCgV5iLKECZbO9xSsAfsT8AzNXDe3i+s5dRdY4zTW2
+ssHQnIFKquSyAVwdj1+ZxLGt24gh65AIgoDzMKND5pCCrlUoSe1b16kQOA7+j0xbm0bqQfWwCHTD
+0IgztnzXdN/chNFDDnU5oSVAKOp4yw4sLjmdjItuFhwvJoIQ4uNllAoEwF73XVv4EOLQunpL+943
+AAAaWyjj0pxzPjKHmKHJUS/X3qwzs08CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8B
+Af8EBAMCAcYwHQYDVR0OBBYEFOCMm9slSbPxfIbWskKHC9BroNnkMA0GCSqGSIb3DQEBBQUAA4IB
+AQA+0hyJLjX8+HXd5n9liPRyTMks1zJO890ZeUe9jjtbkw9QSSQTaxQGcu8J06Gh40CEyecYMnQ8
+SG4Pn0vU9x7Tk4ZkVJdjclDVVc/6IJMCopvDI5NOFlV2oHB5bc0hH88vLbwZ44gx+FkagQnIl6Z0
+x2DEW8xXjrJ1/RsCCdtZb3KTafcxQdaIOL+Hsr0Wefmq5L6IJd1hJyMctTEHBDa0GpC9oHRxUIlt
+vBTjD4au8as+x6AJzKNI0eDbZOeStc+vckNwi/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7Nz
+TogVZ96edhBiIL5VaZVDADlN9u6wWk5JRFRYX0KD
+-----END CERTIFICATE-----
+
+CNNIC ROOT
+==========
+-----BEGIN CERTIFICATE-----
+MIIDVTCCAj2gAwIBAgIESTMAATANBgkqhkiG9w0BAQUFADAyMQswCQYDVQQGEwJDTjEOMAwGA1UE
+ChMFQ05OSUMxEzARBgNVBAMTCkNOTklDIFJPT1QwHhcNMDcwNDE2MDcwOTE0WhcNMjcwNDE2MDcw
+OTE0WjAyMQswCQYDVQQGEwJDTjEOMAwGA1UEChMFQ05OSUMxEzARBgNVBAMTCkNOTklDIFJPT1Qw
+ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDTNfc/c3et6FtzF8LRb+1VvG7q6KR5smzD
+o+/hn7E7SIX1mlwhIhAsxYLO2uOabjfhhyzcuQxauohV3/2q2x8x6gHx3zkBwRP9SFIhxFXf2tiz
+VHa6dLG3fdfA6PZZxU3Iva0fFNrfWEQlMhkqx35+jq44sDB7R3IJMfAw28Mbdim7aXZOV/kbZKKT
+VrdvmW7bCgScEeOAH8tjlBAKqeFkgjH5jCftppkA9nCTGPihNIaj3XrCGHn2emU1z5DrvTOTn1Or
+czvmmzQgLx3vqR1jGqCA2wMv+SYahtKNu6m+UjqHZ0gNv7Sg2Ca+I19zN38m5pIEo3/PIKe38zrK
+y5nLAgMBAAGjczBxMBEGCWCGSAGG+EIBAQQEAwIABzAfBgNVHSMEGDAWgBRl8jGtKvf33VKWCscC
+wQ7vptU7ETAPBgNVHRMBAf8EBTADAQH/MAsGA1UdDwQEAwIB/jAdBgNVHQ4EFgQUZfIxrSr3991S
+lgrHAsEO76bVOxEwDQYJKoZIhvcNAQEFBQADggEBAEs17szkrr/Dbq2flTtLP1se31cpolnKOOK5
+Gv+e5m4y3R6u6jW39ZORTtpC4cMXYFDy0VwmuYK36m3knITnA3kXr5g9lNvHugDnuL8BV8F3RTIM
+O/G0HAiw/VGgod2aHRM2mm23xzy54cXZF/qD1T0VoDy7HgviyJA/qIYM/PmLXoXLT1tLYhFHxUV8
+BS9BsZ4QaRuZluBVeftOhpm4lNqGOGqTo+fLbuXf6iFViZx9fX+Y9QCJ7uOEwFyWtcVG6kbghVW2
+G8kS1sHNzYDzAgE8yGnLRUhj2JTQ7IUOO04RZfSCjKY9ri4ilAnIXOo8gV0WKgOXFlUJ24pBgp5m
+mxE=
+-----END CERTIFICATE-----
+
+GeoTrust Primary Certification Authority - G3
+=============================================
+-----BEGIN CERTIFICATE-----
+MIID/jCCAuagAwIBAgIQFaxulBmyeUtB9iepwxgPHzANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UE
+BhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChjKSAyMDA4IEdlb1RydXN0
+IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFy
+eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEczMB4XDTA4MDQwMjAwMDAwMFoXDTM3MTIwMTIz
+NTk1OVowgZgxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAo
+YykgMjAwOCBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNVBAMT
+LUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMzCCASIwDQYJKoZI
+hvcNAQEBBQADggEPADCCAQoCggEBANziXmJYHTNXOTIz+uvLh4yn1ErdBojqZI4xmKU4kB6Yzy5j
+K/BGvESyiaHAKAxJcCGVn2TAppMSAmUmhsalifD614SgcK9PGpc/BkTVyetyEH3kMSj7HGHmKAdE
+c5IiaacDiGydY8hS2pgn5whMcD60yRLBxWeDXTPzAxHsatBT4tG6NmCUgLthY2xbF37fQJQeqw3C
+IShwiP/WJmxsYAQlTlV+fe+/lEjetx3dcI0FX4ilm/LC7urRQEFtYjgdVgbFA0dRIBn8exALDmKu
+dlW/X3e+PkkBUz2YJQN2JFodtNuJ6nnltrM7P7pMKEF/BqxqjsHQ9gUdfeZChuOl1UcCAwEAAaNC
+MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMR5yo6hTgMdHNxr
+2zFblD4/MH8tMA0GCSqGSIb3DQEBCwUAA4IBAQAtxRPPVoB7eni9n64smefv2t+UXglpp+duaIy9
+cr5HqQ6XErhK8WTTOd8lNNTBzU6B8A8ExCSzNJbGpqow32hhc9f5joWJ7w5elShKKiePEI4ufIbE
+Ap7aDHdlDkQNkv39sxY2+hENHYwOB4lqKVb3cvTdFZx3NWZXqxNT2I7BQMXXExZacse3aQHEerGD
+AWh9jUGhlBjBJVz88P6DAod8DQ3PLghcSkANPuyBYeYk28rgDi0Hsj5W3I31QYUHSJsMC8tJP33s
+t/3LjWeJGqvtux6jAAgIFyqCXDFdRootD4abdNlF+9RAsXqqaC2Gspki4cErx5z481+oghLrGREt
+-----END CERTIFICATE-----
+
+thawte Primary Root CA - G2
+===========================
+-----BEGIN CERTIFICATE-----
+MIICiDCCAg2gAwIBAgIQNfwmXNmET8k9Jj1Xm67XVjAKBggqhkjOPQQDAzCBhDELMAkGA1UEBhMC
+VVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjE4MDYGA1UECxMvKGMpIDIwMDcgdGhhd3RlLCBJbmMu
+IC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAiBgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3Qg
+Q0EgLSBHMjAeFw0wNzExMDUwMDAwMDBaFw0zODAxMTgyMzU5NTlaMIGEMQswCQYDVQQGEwJVUzEV
+MBMGA1UEChMMdGhhd3RlLCBJbmMuMTgwNgYDVQQLEy8oYykgMjAwNyB0aGF3dGUsIEluYy4gLSBG
+b3IgYXV0aG9yaXplZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAt
+IEcyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEotWcgnuVnfFSeIf+iha/BebfowJPDQfGAFG6DAJS
+LSKkQjnE/o/qycG+1E3/n3qe4rF8mq2nhglzh9HnmuN6papu+7qzcMBniKI11KOasf2twu8x+qi5
+8/sIxpHR+ymVo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQU
+mtgAMADna3+FGO6Lts6KDPgR4bswCgYIKoZIzj0EAwMDaQAwZgIxAN344FdHW6fmCsO99YCKlzUN
+G4k8VIZ3KMqh9HneteY4sPBlcIx/AlTCv//YoT7ZzwIxAMSNlPzcU9LcnXgWHxUzI1NS41oxXZ3K
+rr0TKUQNJ1uo52icEvdYPy5yAlejj6EULg==
+-----END CERTIFICATE-----
+
+thawte Primary Root CA - G3
+===========================
+-----BEGIN CERTIFICATE-----
+MIIEKjCCAxKgAwIBAgIQYAGXt0an6rS0mtZLL/eQ+zANBgkqhkiG9w0BAQsFADCBrjELMAkGA1UE
+BhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2
+aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIwMDggdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhv
+cml6ZWQgdXNlIG9ubHkxJDAiBgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMzAeFw0w
+ODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIGuMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhh
+d3RlLCBJbmMuMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9uMTgwNgYD
+VQQLEy8oYykgMjAwOCB0aGF3dGUsIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTEkMCIG
+A1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAtIEczMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
+MIIBCgKCAQEAsr8nLPvb2FvdeHsbnndmgcs+vHyu86YnmjSjaDFxODNi5PNxZnmxqWWjpYvVj2At
+P0LMqmsywCPLLEHd5N/8YZzic7IilRFDGF/Eth9XbAoFWCLINkw6fKXRz4aviKdEAhN0cXMKQlkC
++BsUa0Lfb1+6a4KinVvnSr0eAXLbS3ToO39/fR8EtCab4LRarEc9VbjXsCZSKAExQGbY2SS99irY
+7CFJXJv2eul/VTV+lmuNk5Mny5K76qxAwJ/C+IDPXfRa3M50hqY+bAtTyr2SzhkGcuYMXDhpxwTW
+vGzOW/b3aJzcJRVIiKHpqfiYnODz1TEoYRFsZ5aNOZnLwkUkOQIDAQABo0IwQDAPBgNVHRMBAf8E
+BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUrWyqlGCc7eT/+j4KdCtjA/e2Wb8wDQYJ
+KoZIhvcNAQELBQADggEBABpA2JVlrAmSicY59BDlqQ5mU1143vokkbvnRFHfxhY0Cu9qRFHqKweK
+A3rD6z8KLFIWoCtDuSWQP3CpMyVtRRooOyfPqsMpQhvfO0zAMzRbQYi/aytlryjvsvXDqmbOe1bu
+t8jLZ8HJnBoYuMTDSQPxYA5QzUbF83d597YV4Djbxy8ooAw/dyZ02SUS2jHaGh7cKUGRIjxpp7sC
+8rZcJwOJ9Abqm+RyguOhCcHpABnTPtRwa7pxpqpYrvS76Wy274fMm7v/OeZWYdMKp8RcTGB7BXcm
+er/YB1IsYvdwY9k5vG8cwnncdimvzsUsZAReiDZuMdRAGmI0Nj81Aa6sY6A=
+-----END CERTIFICATE-----
+
+GeoTrust Primary Certification Authority - G2
+=============================================
+-----BEGIN CERTIFICATE-----
+MIICrjCCAjWgAwIBAgIQPLL0SAoA4v7rJDteYD7DazAKBggqhkjOPQQDAzCBmDELMAkGA1UEBhMC
+VVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChjKSAyMDA3IEdlb1RydXN0IElu
+Yy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBD
+ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMB4XDTA3MTEwNTAwMDAwMFoXDTM4MDExODIzNTk1
+OVowgZgxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykg
+MjAwNyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNVBAMTLUdl
+b1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMjB2MBAGByqGSM49AgEG
+BSuBBAAiA2IABBWx6P0DFUPlrOuHNxFi79KDNlJ9RVcLSo17VDs6bl8VAsBQps8lL33KSLjHUGMc
+KiEIfJo22Av+0SbFWDEwKCXzXV2juLaltJLtbCyf691DiaI8S0iRHVDsJt/WYC69IaNCMEAwDwYD
+VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBVfNVdRVfslsq0DafwBo/q+
+EVXVMAoGCCqGSM49BAMDA2cAMGQCMGSWWaboCd6LuvpaiIjwH5HTRqjySkwCY/tsXzjbLkGTqQ7m
+ndwxHLKgpxgceeHHNgIwOlavmnRs9vuD4DPTCF+hnMJbn0bWtsuRBmOiBuczrD6ogRLQy7rQkgu2
+npaqBA+K
+-----END CERTIFICATE-----
+
+VeriSign Universal Root Certification Authority
+===============================================
+-----BEGIN CERTIFICATE-----
+MIIEuTCCA6GgAwIBAgIQQBrEZCGzEyEDDrvkEhrFHTANBgkqhkiG9w0BAQsFADCBvTELMAkGA1UE
+BhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBO
+ZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwOCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVk
+IHVzZSBvbmx5MTgwNgYDVQQDEy9WZXJpU2lnbiBVbml2ZXJzYWwgUm9vdCBDZXJ0aWZpY2F0aW9u
+IEF1dGhvcml0eTAeFw0wODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIG9MQswCQYDVQQGEwJV
+UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv
+cmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl
+IG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNhbCBSb290IENlcnRpZmljYXRpb24gQXV0
+aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx2E3XrEBNNti1xWb/1hajCMj
+1mCOkdeQmIN65lgZOIzF9uVkhbSicfvtvbnazU0AtMgtc6XHaXGVHzk8skQHnOgO+k1KxCHfKWGP
+MiJhgsWHH26MfF8WIFFE0XBPV+rjHOPMee5Y2A7Cs0WTwCznmhcrewA3ekEzeOEz4vMQGn+HLL72
+9fdC4uW/h2KJXwBL38Xd5HVEMkE6HnFuacsLdUYI0crSK5XQz/u5QGtkjFdN/BMReYTtXlT2NJ8I
+AfMQJQYXStrxHXpma5hgZqTZ79IugvHw7wnqRMkVauIDbjPTrJ9VAMf2CGqUuV/c4DPxhGD5WycR
+tPwW8rtWaoAljQIDAQABo4GyMIGvMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMG0G
+CCsGAQUFBwEMBGEwX6FdoFswWTBXMFUWCWltYWdlL2dpZjAhMB8wBwYFKw4DAhoEFI/l0xqGrI2O
+a8PPgGrUSBgsexkuMCUWI2h0dHA6Ly9sb2dvLnZlcmlzaWduLmNvbS92c2xvZ28uZ2lmMB0GA1Ud
+DgQWBBS2d/ppSEefUxLVwuoHMnYH0ZcHGTANBgkqhkiG9w0BAQsFAAOCAQEASvj4sAPmLGd75JR3
+Y8xuTPl9Dg3cyLk1uXBPY/ok+myDjEedO2Pzmvl2MpWRsXe8rJq+seQxIcaBlVZaDrHC1LGmWazx
+Y8u4TB1ZkErvkBYoH1quEPuBUDgMbMzxPcP1Y+Oz4yHJJDnp/RVmRvQbEdBNc6N9Rvk97ahfYtTx
+P/jgdFcrGJ2BtMQo2pSXpXDrrB2+BxHw1dvd5Yzw1TKwg+ZX4o+/vqGqvz0dtdQ46tewXDpPaj+P
+wGZsY6rp2aQW9IHRlRQOfc2VNNnSj3BzgXucfr2YYdhFh5iQxeuGMMY1v/D/w1WIg0vvBZIGcfK4
+mJO37M2CYfE45k+XmCpajQ==
+-----END CERTIFICATE-----
+
+VeriSign Class 3 Public Primary Certification Authority - G4
+============================================================
+-----BEGIN CERTIFICATE-----
+MIIDhDCCAwqgAwIBAgIQL4D+I4wOIg9IZxIokYesszAKBggqhkjOPQQDAzCByjELMAkGA1UEBhMC
+VVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3
+b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVz
+ZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmlj
+YXRpb24gQXV0aG9yaXR5IC0gRzQwHhcNMDcxMTA1MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCByjEL
+MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBU
+cnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRo
+b3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5
+IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASnVnp8
+Utpkmw4tXNherJI9/gHmGUo9FANL+mAnINmDiWn6VMaaGF5VKmTeBvaNSjutEDxlPZCIBIngMGGz
+rl0Bp3vefLK+ymVhAIau2o970ImtTR1ZmkGxvEeA3J5iw/mjgbIwga8wDwYDVR0TAQH/BAUwAwEB
+/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEw
+HzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVyaXNpZ24u
+Y29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFLMWkf3upm7ktS5Jj4d4gYDs5bG1MAoGCCqGSM49BAMD
+A2gAMGUCMGYhDBgmYFo4e1ZC4Kf8NoRRkSAsdk1DPcQdhCPQrNZ8NQbOzWm9kA3bbEhCHQ6qQgIx
+AJw9SDkjOVgaFRJZap7v1VmyHVIsmXHNxynfGyphe3HR3vPA5Q06Sqotp9iGKt0uEA==
+-----END CERTIFICATE-----
+
+NetLock Arany (Class Gold) Főtanúsítvány
+========================================
+-----BEGIN CERTIFICATE-----
+MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQGEwJIVTERMA8G
+A1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3MDUGA1UECwwuVGFuw7pzw610
+dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNlcnZpY2VzKTE1MDMGA1UEAwwsTmV0TG9jayBB
+cmFueSAoQ2xhc3MgR29sZCkgRsWRdGFuw7pzw610dsOhbnkwHhcNMDgxMjExMTUwODIxWhcNMjgx
+MjA2MTUwODIxWjCBpzELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRUwEwYDVQQKDAxO
+ZXRMb2NrIEtmdC4xNzA1BgNVBAsMLlRhbsO6c8OtdHbDoW55a2lhZMOzayAoQ2VydGlmaWNhdGlv
+biBTZXJ2aWNlcykxNTAzBgNVBAMMLE5ldExvY2sgQXJhbnkgKENsYXNzIEdvbGQpIEbFkXRhbsO6
+c8OtdHbDoW55MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxCRec75LbRTDofTjl5Bu
+0jBFHjzuZ9lk4BqKf8owyoPjIMHj9DrTlF8afFttvzBPhCf2nx9JvMaZCpDyD/V/Q4Q3Y1GLeqVw
+/HpYzY6b7cNGbIRwXdrzAZAj/E4wqX7hJ2Pn7WQ8oLjJM2P+FpD/sLj916jAwJRDC7bVWaaeVtAk
+H3B5r9s5VA1lddkVQZQBr17s9o3x/61k/iCa11zr/qYfCGSji3ZVrR47KGAuhyXoqq8fxmRGILdw
+fzzeSNuWU7c5d+Qa4scWhHaXWy+7GRWF+GmF9ZmnqfI0p6m2pgP8b4Y9VHx2BJtr+UBdADTHLpl1
+neWIA6pN+APSQnbAGwIDAKiLo0UwQzASBgNVHRMBAf8ECDAGAQH/AgEEMA4GA1UdDwEB/wQEAwIB
+BjAdBgNVHQ4EFgQUzPpnk/C2uNClwB7zU/2MU9+D15YwDQYJKoZIhvcNAQELBQADggEBAKt/7hwW
+qZw8UQCgwBEIBaeZ5m8BiFRhbvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTta
+YtOUZcTh5m2C+C8lcLIhJsFyUR+MLMOEkMNaj7rP9KdlpeuY0fsFskZ1FSNqb4VjMIDw1Z4fKRzC
+bLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2FuLjbvrW5Kfna
+NwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2XjG4Kvte9nHfRCaexOYNkbQu
+dZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E=
+-----END CERTIFICATE-----
+
+Staat der Nederlanden Root CA - G2
+==================================
+-----BEGIN CERTIFICATE-----
+MIIFyjCCA7KgAwIBAgIEAJiWjDANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJOTDEeMBwGA1UE
+CgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFhdCBkZXIgTmVkZXJsYW5kZW4g
+Um9vdCBDQSAtIEcyMB4XDTA4MDMyNjExMTgxN1oXDTIwMDMyNTExMDMxMFowWjELMAkGA1UEBhMC
+TkwxHjAcBgNVBAoMFVN0YWF0IGRlciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5l
+ZGVybGFuZGVuIFJvb3QgQ0EgLSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMVZ
+5291qj5LnLW4rJ4L5PnZyqtdj7U5EILXr1HgO+EASGrP2uEGQxGZqhQlEq0i6ABtQ8SpuOUfiUtn
+vWFI7/3S4GCI5bkYYCjDdyutsDeqN95kWSpGV+RLufg3fNU254DBtvPUZ5uW6M7XxgpT0GtJlvOj
+CwV3SPcl5XCsMBQgJeN/dVrlSPhOewMHBPqCYYdu8DvEpMfQ9XQ+pV0aCPKbJdL2rAQmPlU6Yiil
+e7Iwr/g3wtG61jj99O9JMDeZJiFIhQGp5Rbn3JBV3w/oOM2ZNyFPXfUib2rFEhZgF1XyZWampzCR
+OME4HYYEhLoaJXhena/MUGDWE4dS7WMfbWV9whUYdMrhfmQpjHLYFhN9C0lK8SgbIHRrxT3dsKpI
+CT0ugpTNGmXZK4iambwYfp/ufWZ8Pr2UuIHOzZgweMFvZ9C+X+Bo7d7iscksWXiSqt8rYGPy5V65
+48r6f1CGPqI0GAwJaCgRHOThuVw+R7oyPxjMW4T182t0xHJ04eOLoEq9jWYv6q012iDTiIJh8BIi
+trzQ1aTsr1SIJSQ8p22xcik/Plemf1WvbibG/ufMQFxRRIEKeN5KzlW/HdXZt1bv8Hb/C3m1r737
+qWmRRpdogBQ2HbN/uymYNqUg+oJgYjOk7Na6B6duxc8UpufWkjTYgfX8HV2qXB72o007uPc5AgMB
+AAGjgZcwgZQwDwYDVR0TAQH/BAUwAwEB/zBSBgNVHSAESzBJMEcGBFUdIAAwPzA9BggrBgEFBQcC
+ARYxaHR0cDovL3d3dy5wa2lvdmVyaGVpZC5ubC9wb2xpY2llcy9yb290LXBvbGljeS1HMjAOBgNV
+HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJFoMocVHYnitfGsNig0jQt8YojrMA0GCSqGSIb3DQEBCwUA
+A4ICAQCoQUpnKpKBglBu4dfYszk78wIVCVBR7y29JHuIhjv5tLySCZa59sCrI2AGeYwRTlHSeYAz
++51IvuxBQ4EffkdAHOV6CMqqi3WtFMTC6GY8ggen5ieCWxjmD27ZUD6KQhgpxrRW/FYQoAUXvQwj
+f/ST7ZwaUb7dRUG/kSS0H4zpX897IZmflZ85OkYcbPnNe5yQzSipx6lVu6xiNGI1E0sUOlWDuYaN
+kqbG9AclVMwWVxJKgnjIFNkXgiYtXSAfea7+1HAWFpWD2DU5/1JddRwWxRNVz0fMdWVSSt7wsKfk
+CpYL+63C4iWEst3kvX5ZbJvw8NjnyvLplzh+ib7M+zkXYT9y2zqR2GUBGR2tUKRXCnxLvJxxcypF
+URmFzI79R6d0lR2o0a9OF7FpJsKqeFdbxU2n5Z4FF5TKsl+gSRiNNOkmbEgeqmiSBeGCc1qb3Adb
+CG19ndeNIdn8FCCqwkXfP+cAslHkwvgFuXkajDTznlvkN1trSt8sV4pAWja63XVECDdCcAz+3F4h
+oKOKwJCcaNpQ5kUQR3i2TtJlycM33+FCY7BXN0Ute4qcvwXqZVUz9zkQxSgqIXobisQk+T8VyJoV
+IPVVYpbtbZNQvOSqeK3Zywplh6ZmwcSBo3c6WB4L7oOLnR7SUqTMHW+wmG2UMbX4cQrcufx9MmDm
+66+KAQ==
+-----END CERTIFICATE-----
+
+Hongkong Post Root CA 1
+=======================
+-----BEGIN CERTIFICATE-----
+MIIDMDCCAhigAwIBAgICA+gwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCSEsxFjAUBgNVBAoT
+DUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3QgUm9vdCBDQSAxMB4XDTAzMDUx
+NTA1MTMxNFoXDTIzMDUxNTA0NTIyOVowRzELMAkGA1UEBhMCSEsxFjAUBgNVBAoTDUhvbmdrb25n
+IFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3QgUm9vdCBDQSAxMIIBIjANBgkqhkiG9w0BAQEF
+AAOCAQ8AMIIBCgKCAQEArP84tulmAknjorThkPlAj3n54r15/gK97iSSHSL22oVyaf7XPwnU3ZG1
+ApzQjVrhVcNQhrkpJsLj2aDxaQMoIIBFIi1WpztUlVYiWR8o3x8gPW2iNr4joLFutbEnPzlTCeqr
+auh0ssJlXI6/fMN4hM2eFvz1Lk8gKgifd/PFHsSaUmYeSF7jEAaPIpjhZY4bXSNmO7ilMlHIhqqh
+qZ5/dpTCpmy3QfDVyAY45tQM4vM7TG1QjMSDJ8EThFk9nnV0ttgCXjqQesBCNnLsak3c78QA3xMY
+V18meMjWCnl3v/evt3a5pQuEF10Q6m/hq5URX208o1xNg1vysxmKgIsLhwIDAQABoyYwJDASBgNV
+HRMBAf8ECDAGAQH/AgEDMA4GA1UdDwEB/wQEAwIBxjANBgkqhkiG9w0BAQUFAAOCAQEADkbVPK7i
+h9legYsCmEEIjEy82tvuJxuC52pF7BaLT4Wg87JwvVqWuspube5Gi27nKi6Wsxkz67SfqLI37pio
+l7Yutmcn1KZJ/RyTZXaeQi/cImyaT/JaFTmxcdcrUehtHJjA2Sr0oYJ71clBoiMBdDhViw+5Lmei
+IAQ32pwL0xch4I+XeTRvhEgCIDMb5jREn5Fw9IBehEPCKdJsEhTkYY2sEJCehFC78JZvRZ+K88ps
+T/oROhUVRsPNH4NbLUES7VBnQRM9IauUiqpOfMGx+6fWtScvl6tu4B3i0RwsH0Ti/L6RoZz71ilT
+c4afU9hDDl3WY4JxHYB0yvbiAmvZWg==
+-----END CERTIFICATE-----
+
+SecureSign RootCA11
+===================
+-----BEGIN CERTIFICATE-----
+MIIDbTCCAlWgAwIBAgIBATANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQGEwJKUDErMCkGA1UEChMi
+SmFwYW4gQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcywgSW5jLjEcMBoGA1UEAxMTU2VjdXJlU2lnbiBS
+b290Q0ExMTAeFw0wOTA0MDgwNDU2NDdaFw0yOTA0MDgwNDU2NDdaMFgxCzAJBgNVBAYTAkpQMSsw
+KQYDVQQKEyJKYXBhbiBDZXJ0aWZpY2F0aW9uIFNlcnZpY2VzLCBJbmMuMRwwGgYDVQQDExNTZWN1
+cmVTaWduIFJvb3RDQTExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/XeqpRyQBTvL
+TJszi1oURaTnkBbR31fSIRCkF/3frNYfp+TbfPfs37gD2pRY/V1yfIw/XwFndBWW4wI8h9uuywGO
+wvNmxoVF9ALGOrVisq/6nL+k5tSAMJjzDbaTj6nU2DbysPyKyiyhFTOVMdrAG/LuYpmGYz+/3ZMq
+g6h2uRMft85OQoWPIucuGvKVCbIFtUROd6EgvanyTgp9UK31BQ1FT0Zx/Sg+U/sE2C3XZR1KG/rP
+O7AxmjVuyIsG0wCR8pQIZUyxNAYAeoni8McDWc/V1uinMrPmmECGxc0nEovMe863ETxiYAcjPitA
+bpSACW22s293bzUIUPsCh8U+iQIDAQABo0IwQDAdBgNVHQ4EFgQUW/hNT7KlhtQ60vFjmqC+CfZX
+t94wDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAKCh
+OBZmLqdWHyGcBvod7bkixTgm2E5P7KN/ed5GIaGHd48HCJqypMWvDzKYC3xmKbabfSVSSUOrTC4r
+bnpwrxYO4wJs+0LmGJ1F2FXI6Dvd5+H0LgscNFxsWEr7jIhQX5Ucv+2rIrVls4W6ng+4reV6G4pQ
+Oh29Dbx7VFALuUKvVaAYga1lme++5Jy/xIWrQbJUb9wlze144o4MjQlJ3WN7WmmWAiGovVJZ6X01
+y8hSyn+B/tlr0/cR7SXf+Of5pPpyl4RTDaXQMhhRdlkUbA/r7F+AjHVDg8OFmP9Mni0N5HeDk061
+lgeLKBObjBmNQSdJQO7e5iNEOdyhIta6A/I=
+-----END CERTIFICATE-----
+
+ACEDICOM Root
+=============
+-----BEGIN CERTIFICATE-----
+MIIFtTCCA52gAwIBAgIIYY3HhjsBggUwDQYJKoZIhvcNAQEFBQAwRDEWMBQGA1UEAwwNQUNFRElD
+T00gUm9vdDEMMAoGA1UECwwDUEtJMQ8wDQYDVQQKDAZFRElDT00xCzAJBgNVBAYTAkVTMB4XDTA4
+MDQxODE2MjQyMloXDTI4MDQxMzE2MjQyMlowRDEWMBQGA1UEAwwNQUNFRElDT00gUm9vdDEMMAoG
+A1UECwwDUEtJMQ8wDQYDVQQKDAZFRElDT00xCzAJBgNVBAYTAkVTMIICIjANBgkqhkiG9w0BAQEF
+AAOCAg8AMIICCgKCAgEA/5KV4WgGdrQsyFhIyv2AVClVYyT/kGWbEHV7w2rbYgIB8hiGtXxaOLHk
+WLn709gtn70yN78sFW2+tfQh0hOR2QetAQXW8713zl9CgQr5auODAKgrLlUTY4HKRxx7XBZXehuD
+YAQ6PmXDzQHe3qTWDLqO3tkE7hdWIpuPY/1NFgu3e3eM+SW10W2ZEi5PGrjm6gSSrj0RuVFCPYew
+MYWveVqc/udOXpJPQ/yrOq2lEiZmueIM15jO1FillUAKt0SdE3QrwqXrIhWYENiLxQSfHY9g5QYb
+m8+5eaA9oiM/Qj9r+hwDezCNzmzAv+YbX79nuIQZ1RXve8uQNjFiybwCq0Zfm/4aaJQ0PZCOrfbk
+HQl/Sog4P75n/TSW9R28MHTLOO7VbKvU/PQAtwBbhTIWdjPp2KOZnQUAqhbm84F9b32qhm2tFXTT
+xKJxqvQUfecyuB+81fFOvW8XAjnXDpVCOscAPukmYxHqC9FK/xidstd7LzrZlvvoHpKuE1XI2Sf2
+3EgbsCTBheN3nZqk8wwRHQ3ItBTutYJXCb8gWH8vIiPYcMt5bMlL8qkqyPyHK9caUPgn6C9D4zq9
+2Fdx/c6mUlv53U3t5fZvie27k5x2IXXwkkwp9y+cAS7+UEaeZAwUswdbxcJzbPEHXEUkFDWug/Fq
+TYl6+rPYLWbwNof1K1MCAwEAAaOBqjCBpzAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKaz
+4SsrSbbXc6GqlPUB53NlTKxQMA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUprPhKytJttdzoaqU
+9QHnc2VMrFAwRAYDVR0gBD0wOzA5BgRVHSAAMDEwLwYIKwYBBQUHAgEWI2h0dHA6Ly9hY2VkaWNv
+bS5lZGljb21ncm91cC5jb20vZG9jMA0GCSqGSIb3DQEBBQUAA4ICAQDOLAtSUWImfQwng4/F9tqg
+aHtPkl7qpHMyEVNEskTLnewPeUKzEKbHDZ3Ltvo/Onzqv4hTGzz3gvoFNTPhNahXwOf9jU8/kzJP
+eGYDdwdY6ZXIfj7QeQCM8htRM5u8lOk6e25SLTKeI6RF+7YuE7CLGLHdztUdp0J/Vb77W7tH1Pwk
+zQSulgUV1qzOMPPKC8W64iLgpq0i5ALudBF/TP94HTXa5gI06xgSYXcGCRZj6hitoocf8seACQl1
+ThCojz2GuHURwCRiipZ7SkXp7FnFvmuD5uHorLUwHv4FB4D54SMNUI8FmP8sX+g7tq3PgbUhh8oI
+KiMnMCArz+2UW6yyetLHKKGKC5tNSixthT8Jcjxn4tncB7rrZXtaAWPWkFtPF2Y9fwsZo5NjEFIq
+nxQWWOLcpfShFosOkYuByptZ+thrkQdlVV9SH686+5DdaaVbnG0OLLb6zqylfDJKZ0DcMDQj3dcE
+I2bw/FWAp/tmGYI1Z2JwOV5vx+qQQEQIHriy1tvuWacNGHk0vFQYXlPKNFHtRQrmjseCNj6nOGOp
+MCwXEGCSn1WHElkQwg9naRHMTh5+Spqtr0CodaxWkHS4oJyleW/c6RrIaQXpuvoDs3zk4E7Czp3o
+tkYNbn5XOmeUwssfnHdKZ05phkOTOPu220+DkdRgfks+KzgHVZhepA==
+-----END CERTIFICATE-----
+
+Microsec e-Szigno Root CA 2009
+==============================
+-----BEGIN CERTIFICATE-----
+MIIECjCCAvKgAwIBAgIJAMJ+QwRORz8ZMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYDVQQGEwJIVTER
+MA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jv
+c2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5o
+dTAeFw0wOTA2MTYxMTMwMThaFw0yOTEyMzAxMTMwMThaMIGCMQswCQYDVQQGEwJIVTERMA8GA1UE
+BwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUt
+U3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5odTCCASIw
+DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOn4j/NjrdqG2KfgQvvPkd6mJviZpWNwrZuuyjNA
+fW2WbqEORO7hE52UQlKavXWFdCyoDh2Tthi3jCyoz/tccbna7P7ofo/kLx2yqHWH2Leh5TvPmUpG
+0IMZfcChEhyVbUr02MelTTMuhTlAdX4UfIASmFDHQWe4oIBhVKZsTh/gnQ4H6cm6M+f+wFUoLAKA
+pxn1ntxVUwOXewdI/5n7N4okxFnMUBBjjqqpGrCEGob5X7uxUG6k0QrM1XF+H6cbfPVTbiJfyyvm
+1HxdrtbCxkzlBQHZ7Vf8wSN5/PrIJIOV87VqUQHQd9bpEqH5GoP7ghu5sJf0dgYzQ0mg/wu1+rUC
+AwEAAaOBgDB+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTLD8bf
+QkPMPcu1SCOhGnqmKrs0aDAfBgNVHSMEGDAWgBTLD8bfQkPMPcu1SCOhGnqmKrs0aDAbBgNVHREE
+FDASgRBpbmZvQGUtc3ppZ25vLmh1MA0GCSqGSIb3DQEBCwUAA4IBAQDJ0Q5eLtXMs3w+y/w9/w0o
+lZMEyL/azXm4Q5DwpL7v8u8hmLzU1F0G9u5C7DBsoKqpyvGvivo/C3NqPuouQH4frlRheesuCDfX
+I/OMn74dseGkddug4lQUsbocKaQY9hK6ohQU4zE1yED/t+AFdlfBHFny+L/k7SViXITwfn4fs775
+tyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c2Pm2G2JwCz02
+yULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5tHMN1Rq41Bab2XD0h7lbwyYIi
+LXpUq3DDfSJlgnCW
+-----END CERTIFICATE-----
+
+GlobalSign Root CA - R3
+=======================
+-----BEGIN CERTIFICATE-----
+MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4GA1UECxMXR2xv
+YmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2Jh
+bFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxT
+aWduIFJvb3QgQ0EgLSBSMzETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2ln
+bjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWt
+iHL8RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsTgHeMCOFJ
+0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmmKPZpO/bLyCiR5Z2KYVc3
+rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zdQQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjl
+OCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZXriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2
+xmmFghcCAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE
+FI/wS3+oLkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZURUm7
+lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMpjjM5RcOO5LlXbKr8
+EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK6fBdRoyV3XpYKBovHd7NADdBj+1E
+bddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQXmcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18
+YIvDQVETI53O9zJrlAGomecsMx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7r
+kpeDMdmztcpHWD9f
+-----END CERTIFICATE-----
+
+Autoridad de Certificacion Firmaprofesional CIF A62634068
+=========================================================
+-----BEGIN CERTIFICATE-----
+MIIGFDCCA/ygAwIBAgIIU+w77vuySF8wDQYJKoZIhvcNAQEFBQAwUTELMAkGA1UEBhMCRVMxQjBA
+BgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2
+MjYzNDA2ODAeFw0wOTA1MjAwODM4MTVaFw0zMDEyMzEwODM4MTVaMFExCzAJBgNVBAYTAkVTMUIw
+QAYDVQQDDDlBdXRvcmlkYWQgZGUgQ2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBB
+NjI2MzQwNjgwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDD
+Utd9thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQMcas9UX4P
+B99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefGL9ItWY16Ck6WaVICqjaY
+7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15iNA9wBj4gGFrO93IbJWyTdBSTo3OxDqqH
+ECNZXyAFGUftaI6SEspd/NYrspI8IM/hX68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyI
+plD9amML9ZMWGxmPsu2bm8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctX
+MbScyJCyZ/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirjaEbsX
+LZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/TKI8xWVvTyQKmtFLK
+bpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF6NkBiDkal4ZkQdU7hwxu+g/GvUgU
+vzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVhOSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMBIGA1Ud
+EwEB/wQIMAYBAf8CAQEwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRlzeurNR4APn7VdMActHNH
+DhpkLzCBpgYDVR0gBIGeMIGbMIGYBgRVHSAAMIGPMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmZp
+cm1hcHJvZmVzaW9uYWwuY29tL2NwczBcBggrBgEFBQcCAjBQHk4AUABhAHMAZQBvACAAZABlACAA
+bABhACAAQgBvAG4AYQBuAG8AdgBhACAANAA3ACAAQgBhAHIAYwBlAGwAbwBuAGEAIAAwADgAMAAx
+ADcwDQYJKoZIhvcNAQEFBQADggIBABd9oPm03cXF661LJLWhAqvdpYhKsg9VSytXjDvlMd3+xDLx
+51tkljYyGOylMnfX40S2wBEqgLk9am58m9Ot/MPWo+ZkKXzR4Tgegiv/J2Wv+xYVxC5xhOW1//qk
+R71kMrv2JYSiJ0L1ILDCExARzRAVukKQKtJE4ZYm6zFIEv0q2skGz3QeqUvVhyj5eTSSPi5E6PaP
+T481PyWzOdxjKpBrIF/EUhJOlywqrJ2X3kjyo2bbwtKDlaZmp54lD+kLM5FlClrD2VQS3a/DTg4f
+Jl4N3LON7NWBcN7STyQF82xO9UxJZo3R/9ILJUFI/lGExkKvgATP0H5kSeTy36LssUzAKh3ntLFl
+osS88Zj0qnAHY7S42jtM+kAiMFsRpvAFDsYCA0irhpuF3dvd6qJ2gHN99ZwExEWN57kci57q13XR
+crHedUTnQn3iV2t93Jm8PYMo6oCTjcVMZcFwgbg4/EMxsvYDNEeyrPsiBsse3RdHHF9mudMaotoR
+saS8I8nkvof/uZS2+F0gStRf571oe2XyFR7SOqkt6dhrJKyXWERHrVkY8SFlcN7ONGCoQPHzPKTD
+KCOM/iczQ0CgFzzr6juwcqajuUpLXhZI9LK8yIySxZ2frHI2vDSANGupi5LAuBft7HZT9SQBjLMi
+6Et8Vcad+qMUu2WFbm5PEn4KPJ2V
+-----END CERTIFICATE-----
+
+Izenpe.com
+==========
+-----BEGIN CERTIFICATE-----
+MIIF8TCCA9mgAwIBAgIQALC3WhZIX7/hy/WL1xnmfTANBgkqhkiG9w0BAQsFADA4MQswCQYDVQQG
+EwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6ZW5wZS5jb20wHhcNMDcxMjEz
+MTMwODI4WhcNMzcxMjEzMDgyNzI1WjA4MQswCQYDVQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMu
+QS4xEzARBgNVBAMMCkl6ZW5wZS5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDJ
+03rKDx6sp4boFmVqscIbRTJxldn+EFvMr+eleQGPicPK8lVx93e+d5TzcqQsRNiekpsUOqHnJJAK
+ClaOxdgmlOHZSOEtPtoKct2jmRXagaKH9HtuJneJWK3W6wyyQXpzbm3benhB6QiIEn6HLmYRY2xU
++zydcsC8Lv/Ct90NduM61/e0aL6i9eOBbsFGb12N4E3GVFWJGjMxCrFXuaOKmMPsOzTFlUFpfnXC
+PCDFYbpRR6AgkJOhkEvzTnyFRVSa0QUmQbC1TR0zvsQDyCV8wXDbO/QJLVQnSKwv4cSsPsjLkkxT
+OTcj7NMB+eAJRE1NZMDhDVqHIrytG6P+JrUV86f8hBnp7KGItERphIPzidF0BqnMC9bC3ieFUCbK
+F7jJeodWLBoBHmy+E60QrLUk9TiRodZL2vG70t5HtfG8gfZZa88ZU+mNFctKy6lvROUbQc/hhqfK
+0GqfvEyNBjNaooXlkDWgYlwWTvDjovoDGrQscbNYLN57C9saD+veIR8GdwYDsMnvmfzAuU8Lhij+
+0rnq49qlw0dpEuDb8PYZi+17cNcC1u2HGCgsBCRMd+RIihrGO5rUD8r6ddIBQFqNeb+Lz0vPqhbB
+leStTIo+F5HUsWLlguWABKQDfo2/2n+iD5dPDNMN+9fR5XJ+HMh3/1uaD7euBUbl8agW7EekFwID
+AQABo4H2MIHzMIGwBgNVHREEgagwgaWBD2luZm9AaXplbnBlLmNvbaSBkTCBjjFHMEUGA1UECgw+
+SVpFTlBFIFMuQS4gLSBDSUYgQTAxMzM3MjYwLVJNZXJjLlZpdG9yaWEtR2FzdGVpeiBUMTA1NSBG
+NjIgUzgxQzBBBgNVBAkMOkF2ZGEgZGVsIE1lZGl0ZXJyYW5lbyBFdG9yYmlkZWEgMTQgLSAwMTAx
+MCBWaXRvcmlhLUdhc3RlaXowDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0O
+BBYEFB0cZQ6o8iV7tJHP5LGx5r1VdGwFMA0GCSqGSIb3DQEBCwUAA4ICAQB4pgwWSp9MiDrAyw6l
+Fn2fuUhfGI8NYjb2zRlrrKvV9pF9rnHzP7MOeIWblaQnIUdCSnxIOvVFfLMMjlF4rJUT3sb9fbga
+kEyrkgPH7UIBzg/YsfqikuFgba56awmqxinuaElnMIAkejEWOVt+8Rwu3WwJrfIxwYJOubv5vr8q
+hT/AQKM6WfxZSzwoJNu0FXWuDYi6LnPAvViH5ULy617uHjAimcs30cQhbIHsvm0m5hzkQiCeR7Cs
+g1lwLDXWrzY0tM07+DKo7+N4ifuNRSzanLh+QBxh5z6ikixL8s36mLYp//Pye6kfLqCTVyvehQP5
+aTfLnnhqBbTFMXiJ7HqnheG5ezzevh55hM6fcA5ZwjUukCox2eRFekGkLhObNA5me0mrZJfQRsN5
+nXJQY6aYWwa9SG3YOYNw6DXwBdGqvOPbyALqfP2C2sJbUjWumDqtujWTI6cfSN01RpiyEGjkpTHC
+ClguGYEQyVB1/OpaFs4R1+7vUIgtYf8/QnMFlEPVjjxOAToZpR9GTnfQXeWBIiGH/pR9hNiTrdZo
+Q0iy2+tzJOeRf1SktoA+naM8THLCV8Sg1Mw4J87VBp6iSNnpn86CcDaTmjvfliHjWbcM2pE38P1Z
+WrOZyGlsQyYBNWNgVYkDOnXYukrZVP/u3oDYLdE41V4tC5h9Pmzb/CaIxw==
+-----END CERTIFICATE-----
+
+Chambers of Commerce Root - 2008
+================================
+-----BEGIN CERTIFICATE-----
+MIIHTzCCBTegAwIBAgIJAKPaQn6ksa7aMA0GCSqGSIb3DQEBBQUAMIGuMQswCQYDVQQGEwJFVTFD
+MEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNv
+bS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMu
+QS4xKTAnBgNVBAMTIENoYW1iZXJzIG9mIENvbW1lcmNlIFJvb3QgLSAyMDA4MB4XDTA4MDgwMTEy
+Mjk1MFoXDTM4MDczMTEyMjk1MFowga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNl
+ZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29tL2FkZHJlc3MpMRIwEAYDVQQF
+EwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVyZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJl
+cnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDgwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
+AQCvAMtwNyuAWko6bHiUfaN/Gh/2NdW928sNRHI+JrKQUrpjOyhYb6WzbZSm891kDFX29ufyIiKA
+XuFixrYp4YFs8r/lfTJqVKAyGVn+H4vXPWCGhSRv4xGzdz4gljUha7MI2XAuZPeEklPWDrCQiorj
+h40G072QDuKZoRuGDtqaCrsLYVAGUvGef3bsyw/QHg3PmTA9HMRFEFis1tPo1+XqxQEHd9ZR5gN/
+ikilTWh1uem8nk4ZcfUyS5xtYBkL+8ydddy/Js2Pk3g5eXNeJQ7KXOt3EgfLZEFHcpOrUMPrCXZk
+NNI5t3YRCQ12RcSprj1qr7V9ZS+UWBDsXHyvfuK2GNnQm05aSd+pZgvMPMZ4fKecHePOjlO+Bd5g
+D2vlGts/4+EhySnB8esHnFIbAURRPHsl18TlUlRdJQfKFiC4reRB7noI/plvg6aRArBsNlVq5331
+lubKgdaX8ZSD6e2wsWsSaR6s+12pxZjptFtYer49okQ6Y1nUCyXeG0+95QGezdIp1Z8XGQpvvwyQ
+0wlf2eOKNcx5Wk0ZN5K3xMGtr/R5JJqyAQuxr1yW84Ay+1w9mPGgP0revq+ULtlVmhduYJ1jbLhj
+ya6BXBg14JC7vjxPNyK5fuvPnnchpj04gftI2jE9K+OJ9dC1vX7gUMQSibMjmhAxhduub+84Mxh2
+EQIDAQABo4IBbDCCAWgwEgYDVR0TAQH/BAgwBgEB/wIBDDAdBgNVHQ4EFgQU+SSsD7K1+HnA+mCI
+G8TZTQKeFxkwgeMGA1UdIwSB2zCB2IAU+SSsD7K1+HnA+mCIG8TZTQKeFxmhgbSkgbEwga4xCzAJ
+BgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNlZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNh
+bWVyZmlybWEuY29tL2FkZHJlc3MpMRIwEAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENh
+bWVyZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDiC
+CQCj2kJ+pLGu2jAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUH
+AgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZIhvcNAQEFBQADggIBAJASryI1
+wqM58C7e6bXpeHxIvj99RZJe6dqxGfwWPJ+0W2aeaufDuV2I6A+tzyMP3iU6XsxPpcG1Lawk0lgH
+3qLPaYRgM+gQDROpI9CF5Y57pp49chNyM/WqfcZjHwj0/gF/JM8rLFQJ3uIrbZLGOU8W6jx+ekbU
+RWpGqOt1glanq6B8aBMz9p0w8G8nOSQjKpD9kCk18pPfNKXG9/jvjA9iSnyu0/VU+I22mlaHFoI6
+M6taIgj3grrqLuBHmrS1RaMFO9ncLkVAO+rcf+g769HsJtg1pDDFOqxXnrN2pSB7+R5KBWIBpih1
+YJeSDW4+TTdDDZIVnBgizVGZoCkaPF+KMjNbMMeJL0eYD6MDxvbxrN8y8NmBGuScvfaAFPDRLLmF
+9dijscilIeUcE5fuDr3fKanvNFNb0+RqE4QGtjICxFKuItLcsiFCGtpA8CnJ7AoMXOLQusxI0zcK
+zBIKinmwPQN/aUv0NCB9szTqjktk9T79syNnFQ0EuPAtwQlRPLJsFfClI9eDdOTlLsn+mCdCxqvG
+nrDQWzilm1DefhiYtUU79nm06PcaewaD+9CL2rvHvRirCG88gGtAPxkZumWK5r7VXNM21+9AUiRg
+OGcEMeyP84LG3rlV8zsxkVrctQgVrXYlCg17LofiDKYGvCYQbTed7N14jHyAxfDZd0jQ
+-----END CERTIFICATE-----
+
+Global Chambersign Root - 2008
+==============================
+-----BEGIN CERTIFICATE-----
+MIIHSTCCBTGgAwIBAgIJAMnN0+nVfSPOMA0GCSqGSIb3DQEBBQUAMIGsMQswCQYDVQQGEwJFVTFD
+MEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNv
+bS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMu
+QS4xJzAlBgNVBAMTHkdsb2JhbCBDaGFtYmVyc2lnbiBSb290IC0gMjAwODAeFw0wODA4MDExMjMx
+NDBaFw0zODA3MzExMjMxNDBaMIGsMQswCQYDVQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUg
+Y3VycmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJ
+QTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAlBgNVBAMTHkdsb2JhbCBD
+aGFtYmVyc2lnbiBSb290IC0gMjAwODCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMDf
+VtPkOpt2RbQT2//BthmLN0EYlVJH6xedKYiONWwGMi5HYvNJBL99RDaxccy9Wglz1dmFRP+RVyXf
+XjaOcNFccUMd2drvXNL7G706tcuto8xEpw2uIRU/uXpbknXYpBI4iRmKt4DS4jJvVpyR1ogQC7N0
+ZJJ0YPP2zxhPYLIj0Mc7zmFLmY/CDNBAspjcDahOo7kKrmCgrUVSY7pmvWjg+b4aqIG7HkF4ddPB
+/gBVsIdU6CeQNR1MM62X/JcumIS/LMmjv9GYERTtY/jKmIhYF5ntRQOXfjyGHoiMvvKRhI9lNNgA
+TH23MRdaKXoKGCQwoze1eqkBfSbW+Q6OWfH9GzO1KTsXO0G2Id3UwD2ln58fQ1DJu7xsepeY7s2M
+H/ucUa6LcL0nn3HAa6x9kGbo1106DbDVwo3VyJ2dwW3Q0L9R5OP4wzg2rtandeavhENdk5IMagfe
+Ox2YItaswTXbo6Al/3K1dh3ebeksZixShNBFks4c5eUzHdwHU1SjqoI7mjcv3N2gZOnm3b2u/GSF
+HTynyQbehP9r6GsaPMWis0L7iwk+XwhSx2LE1AVxv8Rk5Pihg+g+EpuoHtQ2TS9x9o0o9oOpE9Jh
+wZG7SMA0j0GMS0zbaRL/UJScIINZc+18ofLx/d33SdNDWKBWY8o9PeU1VlnpDsogzCtLkykPAgMB
+AAGjggFqMIIBZjASBgNVHRMBAf8ECDAGAQH/AgEMMB0GA1UdDgQWBBS5CcqcHtvTbDprru1U8VuT
+BjUuXjCB4QYDVR0jBIHZMIHWgBS5CcqcHtvTbDprru1U8VuTBjUuXqGBsqSBrzCBrDELMAkGA1UE
+BhMCRVUxQzBBBgNVBAcTOk1hZHJpZCAoc2VlIGN1cnJlbnQgYWRkcmVzcyBhdCB3d3cuY2FtZXJm
+aXJtYS5jb20vYWRkcmVzcykxEjAQBgNVBAUTCUE4Mjc0MzI4NzEbMBkGA1UEChMSQUMgQ2FtZXJm
+aXJtYSBTLkEuMScwJQYDVQQDEx5HbG9iYWwgQ2hhbWJlcnNpZ24gUm9vdCAtIDIwMDiCCQDJzdPp
+1X0jzjAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUHAgEWHGh0
+dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZIhvcNAQEFBQADggIBAICIf3DekijZBZRG
+/5BXqfEv3xoNa/p8DhxJJHkn2EaqbylZUohwEurdPfWbU1Rv4WCiqAm57OtZfMY18dwY6fFn5a+6
+ReAJ3spED8IXDneRRXozX1+WLGiLwUePmJs9wOzL9dWCkoQ10b42OFZyMVtHLaoXpGNR6woBrX/s
+dZ7LoR/xfxKxueRkf2fWIyr0uDldmOghp+G9PUIadJpwr2hsUF1Jz//7Dl3mLEfXgTpZALVza2Mg
+9jFFCDkO9HB+QHBaP9BrQql0PSgvAm11cpUJjUhjxsYjV5KTXjXBjfkK9yydYhz2rXzdpjEetrHH
+foUm+qRqtdpjMNHvkzeyZi99Bffnt0uYlDXA2TopwZ2yUDMdSqlapskD7+3056huirRXhOukP9Du
+qqqHW2Pok+JrqNS4cnhrG+055F3Lm6qH1U9OAP7Zap88MQ8oAgF9mOinsKJknnn4SPIVqczmyETr
+P3iZ8ntxPjzxmKfFGBI/5rsoM0LpRQp8bfKGeS/Fghl9CYl8slR2iK7ewfPM4W7bMdaTrpmg7yVq
+c5iJWzouE4gev8CSlDQb4ye3ix5vQv/n6TebUB0tovkC7stYWDpxvGjjqsGvHCgfotwjZT+B6q6Z
+09gwzxMNTxXJhLynSC34MCN32EZLeW32jO06f2ARePTpm67VVMB0gNELQp/B
+-----END CERTIFICATE-----
+
+Go Daddy Root Certificate Authority - G2
+========================================
+-----BEGIN CERTIFICATE-----
+MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMxEDAOBgNVBAgT
+B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoTEUdvRGFkZHkuY29tLCBJbmMu
+MTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5
+MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6
+b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8G
+A1UEAxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI
+hvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKDE6bFIEMBO4Tx5oVJnyfq
+9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD
++qK+ihVqf94Lw7YZFAXK6sOoBJQ7RnwyDfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutd
+fMh8+7ArU6SSYmlRJQVhGkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMl
+NAJWJwGRtDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEAAaNC
+MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFDqahQcQZyi27/a9
+BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmXWWcDYfF+OwYxdS2hII5PZYe096ac
+vNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r
+5N9ss4UXnT3ZJE95kTXWXwTrgIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYV
+N8Gb5DKj7Tjo2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO
+LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI4uJEvlz36hz1
+-----END CERTIFICATE-----
+
+Starfield Root Certificate Authority - G2
+=========================================
+-----BEGIN CERTIFICATE-----
+MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMxEDAOBgNVBAgT
+B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNobm9s
+b2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVsZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0
+eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAw
+DgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQg
+VGVjaG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZpY2F0ZSBB
+dXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL3twQP89o/8ArFv
+W59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMgnLRJdzIpVv257IzdIvpy3Cdhl+72WoTs
+bhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNk
+N3mSwOxGXn/hbVNMYq/NHwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7Nf
+ZTD4p7dNdloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0HZbU
+JtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
+AQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0GCSqGSIb3DQEBCwUAA4IBAQARWfol
+TwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjUsHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx
+4mcujJUDJi5DnUox9g61DLu34jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUw
+F5okxBDgBPfg8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K
+pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1mMpYjn0q7pBZ
+c2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0
+-----END CERTIFICATE-----
+
+Starfield Services Root Certificate Authority - G2
+==================================================
+-----BEGIN CERTIFICATE-----
+MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMxEDAOBgNVBAgT
+B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNobm9s
+b2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVsZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRl
+IEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNV
+BAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxT
+dGFyZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2VydmljZXMg
+Um9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
+AQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20pOsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2
+h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm28xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4Pa
+hHQUw2eeBGg6345AWh1KTs9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLP
+LJGmpufehRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk6mFB
+rMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAwDwYDVR0TAQH/BAUw
+AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+qAdcwKziIorhtSpzyEZGDMA0GCSqG
+SIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMIbw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPP
+E95Dz+I0swSdHynVv/heyNXBve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTy
+xQGjhdByPq1zqwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd
+iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn0q23KXB56jza
+YyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCNsSi6
+-----END CERTIFICATE-----
+
+AffirmTrust Commercial
+======================
+-----BEGIN CERTIFICATE-----
+MIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UEBhMCVVMxFDAS
+BgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBDb21tZXJjaWFsMB4XDTEw
+MDEyOTE0MDYwNloXDTMwMTIzMTE0MDYwNlowRDELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmly
+bVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBDb21tZXJjaWFsMIIBIjANBgkqhkiG9w0BAQEF
+AAOCAQ8AMIIBCgKCAQEA9htPZwcroRX1BiLLHwGy43NFBkRJLLtJJRTWzsO3qyxPxkEylFf6Eqdb
+DuKPHx6GGaeqtS25Xw2Kwq+FNXkyLbscYjfysVtKPcrNcV/pQr6U6Mje+SJIZMblq8Yrba0F8PrV
+C8+a5fBQpIs7R6UjW3p6+DM/uO+Zl+MgwdYoic+U+7lF7eNAFxHUdPALMeIrJmqbTFeurCA+ukV6
+BfO9m2kVrn1OIGPENXY6BwLJN/3HR+7o8XYdcxXyl6S1yHp52UKqK39c/s4mT6NmgTWvRLpUHhww
+MmWd5jyTXlBOeuM61G7MGvv50jeuJCqrVwMiKA1JdX+3KNp1v47j3A55MQIDAQABo0IwQDAdBgNV
+HQ4EFgQUnZPGU4teyq8/nx4P5ZmVvCT2lI8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
+AQYwDQYJKoZIhvcNAQELBQADggEBAFis9AQOzcAN/wr91LoWXym9e2iZWEnStB03TX8nfUYGXUPG
+hi4+c7ImfU+TqbbEKpqrIZcUsd6M06uJFdhrJNTxFq7YpFzUf1GO7RgBsZNjvbz4YYCanrHOQnDi
+qX0GJX0nof5v7LMeJNrjS1UaADs1tDvZ110w/YETifLCBivtZ8SOyUOyXGsViQK8YvxO8rUzqrJv
+0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9gN53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0kh
+sUlHRUe072o0EclNmsxZt9YCnlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8=
+-----END CERTIFICATE-----
+
+AffirmTrust Networking
+======================
+-----BEGIN CERTIFICATE-----
+MIIDTDCCAjSgAwIBAgIIfE8EORzUmS0wDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UEBhMCVVMxFDAS
+BgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBOZXR3b3JraW5nMB4XDTEw
+MDEyOTE0MDgyNFoXDTMwMTIzMTE0MDgyNFowRDELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmly
+bVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBOZXR3b3JraW5nMIIBIjANBgkqhkiG9w0BAQEF
+AAOCAQ8AMIIBCgKCAQEAtITMMxcua5Rsa2FSoOujz3mUTOWUgJnLVWREZY9nZOIG41w3SfYvm4SE
+Hi3yYJ0wTsyEheIszx6e/jarM3c1RNg1lho9Nuh6DtjVR6FqaYvZ/Ls6rnla1fTWcbuakCNrmreI
+dIcMHl+5ni36q1Mr3Lt2PpNMCAiMHqIjHNRqrSK6mQEubWXLviRmVSRLQESxG9fhwoXA3hA/Pe24
+/PHxI1Pcv2WXb9n5QHGNfb2V1M6+oF4nI979ptAmDgAp6zxG8D1gvz9Q0twmQVGeFDdCBKNwV6gb
+h+0t+nvujArjqWaJGctB+d1ENmHP4ndGyH329JKBNv3bNPFyfvMMFr20FQIDAQABo0IwQDAdBgNV
+HQ4EFgQUBx/S55zawm6iQLSwelAQUHTEyL0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
+AQYwDQYJKoZIhvcNAQEFBQADggEBAIlXshZ6qML91tmbmzTCnLQyFE2npN/svqe++EPbkTfOtDIu
+UFUaNU52Q3Eg75N3ThVwLofDwR1t3Mu1J9QsVtFSUzpE0nPIxBsFZVpikpzuQY0x2+c06lkh1QF6
+12S4ZDnNye2v7UsDSKegmQGA3GWjNq5lWUhPgkvIZfFXHeVZLgo/bNjR9eUJtGxUAArgFU2HdW23
+WJZa3W3SAKD0m0i+wzekujbgfIeFlxoVot4uolu9rxj5kFDNcFn4J2dHy8egBzp90SxdbBk6ZrV9
+/ZFvgrG+CJPbFEfxojfHRZ48x3evZKiT3/Zpg4Jg8klCNO1aAFSFHBY2kgxc+qatv9s=
+-----END CERTIFICATE-----
+
+AffirmTrust Premium
+===================
+-----BEGIN CERTIFICATE-----
+MIIFRjCCAy6gAwIBAgIIbYwURrGmCu4wDQYJKoZIhvcNAQEMBQAwQTELMAkGA1UEBhMCVVMxFDAS
+BgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVzdCBQcmVtaXVtMB4XDTEwMDEy
+OTE0MTAzNloXDTQwMTIzMTE0MTAzNlowQTELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRy
+dXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVzdCBQcmVtaXVtMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A
+MIICCgKCAgEAxBLfqV/+Qd3d9Z+K4/as4Tx4mrzY8H96oDMq3I0gW64tb+eT2TZwamjPjlGjhVtn
+BKAQJG9dKILBl1fYSCkTtuG+kU3fhQxTGJoeJKJPj/CihQvL9Cl/0qRY7iZNyaqoe5rZ+jjeRFcV
+5fiMyNlI4g0WJx0eyIOFJbe6qlVBzAMiSy2RjYvmia9mx+n/K+k8rNrSs8PhaJyJ+HoAVt70VZVs
++7pk3WKL3wt3MutizCaam7uqYoNMtAZ6MMgpv+0GTZe5HMQxK9VfvFMSF5yZVylmd2EhMQcuJUmd
+GPLu8ytxjLW6OQdJd/zvLpKQBY0tL3d770O/Nbua2Plzpyzy0FfuKE4mX4+QaAkvuPjcBukumj5R
+p9EixAqnOEhss/n/fauGV+O61oV4d7pD6kh/9ti+I20ev9E2bFhc8e6kGVQa9QPSdubhjL08s9NI
+S+LI+H+SqHZGnEJlPqQewQcDWkYtuJfzt9WyVSHvutxMAJf7FJUnM7/oQ0dG0giZFmA7mn7S5u04
+6uwBHjxIVkkJx0w3AJ6IDsBz4W9m6XJHMD4Q5QsDyZpCAGzFlH5hxIrff4IaC1nEWTJ3s7xgaVY5
+/bQGeyzWZDbZvUjthB9+pSKPKrhC9IK31FOQeE4tGv2Bb0TXOwF0lkLgAOIua+rF7nKsu7/+6qqo
++Nz2snmKtmcCAwEAAaNCMEAwHQYDVR0OBBYEFJ3AZ6YMItkm9UWrpmVSESfYRaxjMA8GA1UdEwEB
+/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBDAUAA4ICAQCzV00QYk465KzquByv
+MiPIs0laUZx2KI15qldGF9X1Uva3ROgIRL8YhNILgM3FEv0AVQVhh0HctSSePMTYyPtwni94loMg
+Nt58D2kTiKV1NpgIpsbfrM7jWNa3Pt668+s0QNiigfV4Py/VpfzZotReBA4Xrf5B8OWycvpEgjNC
+6C1Y91aMYj+6QrCcDFx+LmUmXFNPALJ4fqENmS2NuB2OosSw/WDQMKSOyARiqcTtNd56l+0OOF6S
+L5Nwpamcb6d9Ex1+xghIsV5n61EIJenmJWtSKZGc0jlzCFfemQa0W50QBuHCAKi4HEoCChTQwUHK
++4w1IX2COPKpVJEZNZOUbWo6xbLQu4mGk+ibyQ86p3q4ofB4Rvr8Ny/lioTz3/4E2aFooC8k4gmV
+BtWVyuEklut89pMFu+1z6S3RdTnX5yTb2E5fQ4+e0BQ5v1VwSJlXMbSc7kqYA5YwH2AG7hsj/oFg
+IxpHYoWlzBk0gG+zrBrjn/B7SK3VAdlntqlyk+otZrWyuOQ9PLLvTIzq6we/qzWaVYa8GKa1qF60
+g2xraUDTn9zxw2lrueFtCfTxqlB2Cnp9ehehVZZCmTEJ3WARjQUwfuaORtGdFNrHF+QFlozEJLUb
+zxQHskD4o55BhrwE0GuWyCqANP2/7waj3VjFhT0+j/6eKeC2uAloGRwYQw==
+-----END CERTIFICATE-----
+
+AffirmTrust Premium ECC
+=======================
+-----BEGIN CERTIFICATE-----
+MIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMCVVMxFDASBgNV
+BAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQcmVtaXVtIEVDQzAeFw0xMDAx
+MjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJBgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1U
+cnVzdDEgMB4GA1UEAwwXQWZmaXJtVHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQA
+IgNiAAQNMF4bFZ0D0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQ
+N8O9ss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0GA1UdDgQW
+BBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAK
+BggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/VsaobgxCd05DhT1wV/GzTjxi+zygk8N53X
+57hG8f2h4nECMEJZh0PUUd+60wkyWs6Iflc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKM
+eQ==
+-----END CERTIFICATE-----
+
+Certum Trusted Network CA
+=========================
+-----BEGIN CERTIFICATE-----
+MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBMMSIwIAYDVQQK
+ExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlv
+biBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBUcnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIy
+MTIwNzM3WhcNMjkxMjMxMTIwNzM3WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBU
+ZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5
+MSIwIAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0BAQEFAAOC
+AQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rHUV+rpDKmYYe2bg+G0jAC
+l/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LMTXPb865Px1bVWqeWifrzq2jUI4ZZJ88J
+J7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVUBBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4
+fOQtf/WsX+sWn7Et0brMkUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0
+cvW0QM8xAcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNVHRMB
+Af8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNVHQ8BAf8EBAMCAQYw
+DQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15ysHhE49wcrwn9I0j6vSrEuVUEtRCj
+jSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfLI9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1
+mS1FhIrlQgnXdAIv94nYmem8J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5aj
+Zt3hrvJBW8qYVoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI
+03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw=
+-----END CERTIFICATE-----
+
+Certinomis - Autorité Racine
+============================
+-----BEGIN CERTIFICATE-----
+MIIFnDCCA4SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJGUjETMBEGA1UEChMK
+Q2VydGlub21pczEXMBUGA1UECxMOMDAwMiA0MzM5OTg5MDMxJjAkBgNVBAMMHUNlcnRpbm9taXMg
+LSBBdXRvcml0w6kgUmFjaW5lMB4XDTA4MDkxNzA4Mjg1OVoXDTI4MDkxNzA4Mjg1OVowYzELMAkG
+A1UEBhMCRlIxEzARBgNVBAoTCkNlcnRpbm9taXMxFzAVBgNVBAsTDjAwMDIgNDMzOTk4OTAzMSYw
+JAYDVQQDDB1DZXJ0aW5vbWlzIC0gQXV0b3JpdMOpIFJhY2luZTCCAiIwDQYJKoZIhvcNAQEBBQAD
+ggIPADCCAgoCggIBAJ2Fn4bT46/HsmtuM+Cet0I0VZ35gb5j2CN2DpdUzZlMGvE5x4jYF1AMnmHa
+wE5V3udauHpOd4cN5bjr+p5eex7Ezyh0x5P1FMYiKAT5kcOrJ3NqDi5N8y4oH3DfVS9O7cdxbwly
+Lu3VMpfQ8Vh30WC8Tl7bmoT2R2FFK/ZQpn9qcSdIhDWerP5pqZ56XjUl+rSnSTV3lqc2W+HN3yNw
+2F1MpQiD8aYkOBOo7C+ooWfHpi2GR+6K/OybDnT0K0kCe5B1jPyZOQE51kqJ5Z52qz6WKDgmi92N
+jMD2AR5vpTESOH2VwnHu7XSu5DaiQ3XV8QCb4uTXzEIDS3h65X27uK4uIJPT5GHfceF2Z5c/tt9q
+c1pkIuVC28+BA5PY9OMQ4HL2AHCs8MF6DwV/zzRpRbWT5BnbUhYjBYkOjUjkJW+zeL9i9Qf6lSTC
+lrLooyPCXQP8w9PlfMl1I9f09bze5N/NgL+RiH2nE7Q5uiy6vdFrzPOlKO1Enn1So2+WLhl+HPNb
+xxaOu2B9d2ZHVIIAEWBsMsGoOBvrbpgT1u449fCfDu/+MYHB0iSVL1N6aaLwD4ZFjliCK0wi1F6g
+530mJ0jfJUaNSih8hp75mxpZuWW/Bd22Ql095gBIgl4g9xGC3srYn+Y3RyYe63j3YcNBZFgCQfna
+4NH4+ej9Uji29YnfAgMBAAGjWzBZMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G
+A1UdDgQWBBQNjLZh2kS40RR9w759XkjwzspqsDAXBgNVHSAEEDAOMAwGCiqBegFWAgIAAQEwDQYJ
+KoZIhvcNAQEFBQADggIBACQ+YAZ+He86PtvqrxyaLAEL9MW12Ukx9F1BjYkMTv9sov3/4gbIOZ/x
+WqndIlgVqIrTseYyCYIDbNc/CMf4uboAbbnW/FIyXaR/pDGUu7ZMOH8oMDX/nyNTt7buFHAAQCva
+R6s0fl6nVjBhK4tDrP22iCj1a7Y+YEq6QpA0Z43q619FVDsXrIvkxmUP7tCMXWY5zjKn2BCXwH40
+nJ+U8/aGH88bc62UeYdocMMzpXDn2NU4lG9jeeu/Cg4I58UvD0KgKxRA/yHgBcUn4YQRE7rWhh1B
+CxMjidPJC+iKunqjo3M3NYB9Ergzd0A4wPpeMNLytqOx1qKVl4GbUu1pTP+A5FPbVFsDbVRfsbjv
+JL1vnxHDx2TCDyhihWZeGnuyt++uNckZM6i4J9szVb9o4XVIRFb7zdNIu0eJOqxp9YDG5ERQL1TE
+qkPFMTFYvZbF6nVsmnWxTfj3l/+WFvKXTej28xH5On2KOG4Ey+HTRRWqpdEdnV1j6CTmNhTih60b
+WfVEm/vXd3wfAXBioSAaosUaKPQhA+4u2cGA6rnZgtZbdsLLO7XSAPCjDuGtbkD326C00EauFddE
+wk01+dIL8hf2rGbVJLJP0RyZwG71fet0BLj5TXcJ17TPBzAJ8bgAVtkXFhYKK4bfjwEZGuW7gmP/
+vgt2Fl43N+bYdJeimUV5
+-----END CERTIFICATE-----
+
+TWCA Root Certification Authority
+=================================
+-----BEGIN CERTIFICATE-----
+MIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzESMBAGA1UECgwJ
+VEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlmaWNh
+dGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMzWhcNMzAxMjMxMTU1OTU5WjBfMQswCQYDVQQG
+EwJUVzESMBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NB
+IFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
+AoIBAQCwfnK4pAOU5qfeCTiRShFAh6d8WWQUe7UREN3+v9XAu1bihSX0NXIP+FPQQeFEAcK0HMMx
+QhZHhTMidrIKbw/lJVBPhYa+v5guEGcevhEFhgWQxFnQfHgQsIBct+HHK3XLfJ+utdGdIzdjp9xC
+oi2SBBtQwXu4PhvJVgSLL1KbralW6cH/ralYhzC2gfeXRfwZVzsrb+RH9JlF/h3x+JejiB03HFyP
+4HYlmlD4oFT/RJB2I9IyxsOrBr/8+7/zrX2SYgJbKdM1o5OaQ2RgXbL6Mv87BK9NQGr5x+PvI/1r
+y+UPizgN7gr8/g+YnzAx3WxSZfmLgb4i4RxYA7qRG4kHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIB
+BjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqOFsmjd6LWvJPelSDGRjjCDWmujANBgkqhkiG
+9w0BAQUFAAOCAQEAPNV3PdrfibqHDAhUaiBQkr6wQT25JmSDCi/oQMCXKCeCMErJk/9q56YAf4lC
+mtYR5VPOL8zy2gXE/uJQxDqGfczafhAJO5I1KlOy/usrBdlsXebQ79NqZp4VKIV66IIArB6nCWlW
+QtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62Dlhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVY
+T0bf+215WfKEIlKuD8z7fDvnaspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocny
+Yh0igzyXxfkZYiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw==
+-----END CERTIFICATE-----
+
+Security Communication RootCA2
+==============================
+-----BEGIN CERTIFICATE-----
+MIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJKUDElMCMGA1UEChMc
+U0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UECxMeU2VjdXJpdHkgQ29tbXVuaWNh
+dGlvbiBSb290Q0EyMB4XDTA5MDUyOTA1MDAzOVoXDTI5MDUyOTA1MDAzOVowXTELMAkGA1UEBhMC
+SlAxJTAjBgNVBAoTHFNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4xJzAlBgNVBAsTHlNlY3Vy
+aXR5IENvbW11bmljYXRpb24gUm9vdENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
+ANAVOVKxUrO6xVmCxF1SrjpDZYBLx/KWvNs2l9amZIyoXvDjChz335c9S672XewhtUGrzbl+dp++
++T42NKA7wfYxEUV0kz1XgMX5iZnK5atq1LXaQZAQwdbWQonCv/Q4EpVMVAX3NuRFg3sUZdbcDE3R
+3n4MqzvEFb46VqZab3ZpUql6ucjrappdUtAtCms1FgkQhNBqyjoGADdH5H5XTz+L62e4iKrFvlNV
+spHEfbmwhRkGeC7bYRr6hfVKkaHnFtWOojnflLhwHyg/i/xAXmODPIMqGplrz95Zajv8bxbXH/1K
+EOtOghY6rCcMU/Gt1SSwawNQwS08Ft1ENCcadfsCAwEAAaNCMEAwHQYDVR0OBBYEFAqFqXdlBZh8
+QIH4D5csOPEK7DzPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEB
+CwUAA4IBAQBMOqNErLlFsceTfsgLCkLfZOoc7llsCLqJX2rKSpWeeo8HxdpFcoJxDjrSzG+ntKEj
+u/Ykn8sX/oymzsLS28yN/HH8AynBbF0zX2S2ZTuJbxh2ePXcokgfGT+Ok+vx+hfuzU7jBBJV1uXk
+3fs+BXziHV7Gp7yXT2g69ekuCkO2r1dcYmh8t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6q
+tnRGEmyR7jTV7JqR50S+kDFy1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29
+mvVXIwAHIRc/SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03
+-----END CERTIFICATE-----
+
+EC-ACC
+======
+-----BEGIN CERTIFICATE-----
+MIIFVjCCBD6gAwIBAgIQ7is969Qh3hSoYqwE893EATANBgkqhkiG9w0BAQUFADCB8zELMAkGA1UE
+BhMCRVMxOzA5BgNVBAoTMkFnZW5jaWEgQ2F0YWxhbmEgZGUgQ2VydGlmaWNhY2lvIChOSUYgUS0w
+ODAxMTc2LUkpMSgwJgYDVQQLEx9TZXJ2ZWlzIFB1YmxpY3MgZGUgQ2VydGlmaWNhY2lvMTUwMwYD
+VQQLEyxWZWdldSBodHRwczovL3d3dy5jYXRjZXJ0Lm5ldC92ZXJhcnJlbCAoYykwMzE1MDMGA1UE
+CxMsSmVyYXJxdWlhIEVudGl0YXRzIGRlIENlcnRpZmljYWNpbyBDYXRhbGFuZXMxDzANBgNVBAMT
+BkVDLUFDQzAeFw0wMzAxMDcyMzAwMDBaFw0zMTAxMDcyMjU5NTlaMIHzMQswCQYDVQQGEwJFUzE7
+MDkGA1UEChMyQWdlbmNpYSBDYXRhbGFuYSBkZSBDZXJ0aWZpY2FjaW8gKE5JRiBRLTA4MDExNzYt
+SSkxKDAmBgNVBAsTH1NlcnZlaXMgUHVibGljcyBkZSBDZXJ0aWZpY2FjaW8xNTAzBgNVBAsTLFZl
+Z2V1IGh0dHBzOi8vd3d3LmNhdGNlcnQubmV0L3ZlcmFycmVsIChjKTAzMTUwMwYDVQQLEyxKZXJh
+cnF1aWEgRW50aXRhdHMgZGUgQ2VydGlmaWNhY2lvIENhdGFsYW5lczEPMA0GA1UEAxMGRUMtQUND
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsyLHT+KXQpWIR4NA9h0X84NzJB5R85iK
+w5K4/0CQBXCHYMkAqbWUZRkiFRfCQ2xmRJoNBD45b6VLeqpjt4pEndljkYRm4CgPukLjbo73FCeT
+ae6RDqNfDrHrZqJyTxIThmV6PttPB/SnCWDaOkKZx7J/sxaVHMf5NLWUhdWZXqBIoH7nF2W4onW4
+HvPlQn2v7fOKSGRdghST2MDk/7NQcvJ29rNdQlB50JQ+awwAvthrDk4q7D7SzIKiGGUzE3eeml0a
+E9jD2z3Il3rucO2n5nzbcc8tlGLfbdb1OL4/pYUKGbio2Al1QnDE6u/LDsg0qBIimAy4E5S2S+zw
+0JDnJwIDAQABo4HjMIHgMB0GA1UdEQQWMBSBEmVjX2FjY0BjYXRjZXJ0Lm5ldDAPBgNVHRMBAf8E
+BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUoMOLRKo3pUW/l4Ba0fF4opvpXY0wfwYD
+VR0gBHgwdjB0BgsrBgEEAfV4AQMBCjBlMCwGCCsGAQUFBwIBFiBodHRwczovL3d3dy5jYXRjZXJ0
+Lm5ldC92ZXJhcnJlbDA1BggrBgEFBQcCAjApGidWZWdldSBodHRwczovL3d3dy5jYXRjZXJ0Lm5l
+dC92ZXJhcnJlbCAwDQYJKoZIhvcNAQEFBQADggEBAKBIW4IB9k1IuDlVNZyAelOZ1Vr/sXE7zDkJ
+lF7W2u++AVtd0x7Y/X1PzaBB4DSTv8vihpw3kpBWHNzrKQXlxJ7HNd+KDM3FIUPpqojlNcAZQmNa
+Al6kSBg6hW/cnbw/nZzBh7h6YQjpdwt/cKt63dmXLGQehb+8dJahw3oS7AwaboMMPOhyRp/7SNVe
+l+axofjk70YllJyJ22k4vuxcDlbHZVHlUIiIv0LVKz3l+bqeLrPK9HOSAgu+TGbrIP65y7WZf+a2
+E/rKS03Z7lNGBjvGTq2TWoF+bCpLagVFjPIhpDGQh2xlnJ2lYJU6Un/10asIbvPuW/mIPX64b24D
+5EI=
+-----END CERTIFICATE-----
+
+Hellenic Academic and Research Institutions RootCA 2011
+=======================================================
+-----BEGIN CERTIFICATE-----
+MIIEMTCCAxmgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBlTELMAkGA1UEBhMCR1IxRDBCBgNVBAoT
+O0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9y
+aXR5MUAwPgYDVQQDEzdIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25z
+IFJvb3RDQSAyMDExMB4XDTExMTIwNjEzNDk1MloXDTMxMTIwMTEzNDk1MlowgZUxCzAJBgNVBAYT
+AkdSMUQwQgYDVQQKEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25z
+IENlcnQuIEF1dGhvcml0eTFAMD4GA1UEAxM3SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNo
+IEluc3RpdHV0aW9ucyBSb290Q0EgMjAxMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
+AKlTAOMupvaO+mDYLZU++CwqVE7NuYRhlFhPjz2L5EPzdYmNUeTDN9KKiE15HrcS3UN4SoqS5tdI
+1Q+kOilENbgH9mgdVc04UfCMJDGFr4PJfel3r+0ae50X+bOdOFAPplp5kYCvN66m0zH7tSYJnTxa
+71HFK9+WXesyHgLacEnsbgzImjeN9/E2YEsmLIKe0HjzDQ9jpFEw4fkrJxIH2Oq9GGKYsFk3fb7u
+8yBRQlqD75O6aRXxYp2fmTmCobd0LovUxQt7L/DICto9eQqakxylKHJzkUOap9FNhYS5qXSPFEDH
+3N6sQWRstBmbAmNtJGSPRLIl6s5ddAxjMlyNh+UCAwEAAaOBiTCBhjAPBgNVHRMBAf8EBTADAQH/
+MAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQUppFC/RNhSiOeCKQp5dgTBCPuQSUwRwYDVR0eBEAwPqA8
+MAWCAy5ncjAFggMuZXUwBoIELmVkdTAGggQub3JnMAWBAy5ncjAFgQMuZXUwBoEELmVkdTAGgQQu
+b3JnMA0GCSqGSIb3DQEBBQUAA4IBAQAf73lB4XtuP7KMhjdCSk4cNx6NZrokgclPEg8hwAOXhiVt
+XdMiKahsog2p6z0GW5k6x8zDmjR/qw7IThzh+uTczQ2+vyT+bOdrwg3IBp5OjWEopmr95fZi6hg8
+TqBTnbI6nOulnJEWtk2C4AwFSKls9cz4y51JtPACpf1wA+2KIaWuE4ZJwzNzvoc7dIsXRSZMFpGD
+/md9zU1jZ/rzAxKWeAaNsWftjj++n08C9bMJL/NMh98qy5V8AcysNnq/onN694/BtZqhFLKPM58N
+7yLcZnuEvUUXBj08yrl3NI/K6s8/MT7jiOOASSXIl7WdmplNsDz4SgCbZN2fOUvRJ9e4
+-----END CERTIFICATE-----
+
+Actalis Authentication Root CA
+==============================
+-----BEGIN CERTIFICATE-----
+MIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UEBhMCSVQxDjAM
+BgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8wMzM1ODUyMDk2NzEnMCUGA1UE
+AwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290IENBMB4XDTExMDkyMjExMjIwMloXDTMwMDky
+MjExMjIwMlowazELMAkGA1UEBhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlz
+IFMucC5BLi8wMzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290
+IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAp8bEpSmkLO/lGMWwUKNvUTufClrJ
+wkg4CsIcoBh/kbWHuUA/3R1oHwiD1S0eiKD4j1aPbZkCkpAW1V8IbInX4ay8IMKx4INRimlNAJZa
+by/ARH6jDuSRzVju3PvHHkVH3Se5CAGfpiEd9UEtL0z9KK3giq0itFZljoZUj5NDKd45RnijMCO6
+zfB9E1fAXdKDa0hMxKufgFpbOr3JpyI/gCczWw63igxdBzcIy2zSekciRDXFzMwujt0q7bd9Zg1f
+YVEiVRvjRuPjPdA1YprbrxTIW6HMiRvhMCb8oJsfgadHHwTrozmSBp+Z07/T6k9QnBn+locePGX2
+oxgkg4YQ51Q+qDp2JE+BIcXjDwL4k5RHILv+1A7TaLndxHqEguNTVHnd25zS8gebLra8Pu2Fbe8l
+EfKXGkJh90qX6IuxEAf6ZYGyojnP9zz/GPvG8VqLWeICrHuS0E4UT1lF9gxeKF+w6D9Fz8+vm2/7
+hNN3WpVvrJSEnu68wEqPSpP4RCHiMUVhUE4Q2OM1fEwZtN4Fv6MGn8i1zeQf1xcGDXqVdFUNaBr8
+EBtiZJ1t4JWgw5QHVw0U5r0F+7if5t+L4sbnfpb2U8WANFAoWPASUHEXMLrmeGO89LKtmyuy/uE5
+jF66CyCU3nuDuP/jVo23Eek7jPKxwV2dpAtMK9myGPW1n0sCAwEAAaNjMGEwHQYDVR0OBBYEFFLY
+iDrIn3hm7YnzezhwlMkCAjbQMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUUtiIOsifeGbt
+ifN7OHCUyQICNtAwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQALe3KHwGCmSUyI
+WOYdiPcUZEim2FgKDk8TNd81HdTtBjHIgT5q1d07GjLukD0R0i70jsNjLiNmsGe+b7bAEzlgqqI0
+JZN1Ut6nna0Oh4lScWoWPBkdg/iaKWW+9D+a2fDzWochcYBNy+A4mz+7+uAwTc+G02UQGRjRlwKx
+K3JCaKygvU5a2hi/a5iB0P2avl4VSM0RFbnAKVy06Ij3Pjaut2L9HmLecHgQHEhb2rykOLpn7VU+
+Xlff1ANATIGk0k9jpwlCCRT8AKnCgHNPLsBA2RF7SOp6AsDT6ygBJlh0wcBzIm2Tlf05fbsq4/aC
+4yyXX04fkZT6/iyj2HYauE2yOE+b+h1IYHkm4vP9qdCa6HCPSXrW5b0KDtst842/6+OkfcvHlXHo
+2qN8xcL4dJIEG4aspCJTQLas/kx2z/uUMsA1n3Y/buWQbqCmJqK4LL7RK4X9p2jIugErsWx0Hbhz
+lefut8cl8ABMALJ+tguLHPPAUJ4lueAI3jZm/zel0btUZCzJJ7VLkn5l/9Mt4blOvH+kQSGQQXem
+OR/qnuOf0GZvBeyqdn6/axag67XH/JJULysRJyU3eExRarDzzFhdFPFqSBX/wge2sY0PjlxQRrM9
+vwGYT7JZVEc+NHt4bVaTLnPqZih4zR0Uv6CPLy64Lo7yFIrM6bV8+2ydDKXhlg==
+-----END CERTIFICATE-----
+
+Trustis FPS Root CA
+===================
+-----BEGIN CERTIFICATE-----
+MIIDZzCCAk+gAwIBAgIQGx+ttiD5JNM2a/fH8YygWTANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQG
+EwJHQjEYMBYGA1UEChMPVHJ1c3RpcyBMaW1pdGVkMRwwGgYDVQQLExNUcnVzdGlzIEZQUyBSb290
+IENBMB4XDTAzMTIyMzEyMTQwNloXDTI0MDEyMTExMzY1NFowRTELMAkGA1UEBhMCR0IxGDAWBgNV
+BAoTD1RydXN0aXMgTGltaXRlZDEcMBoGA1UECxMTVHJ1c3RpcyBGUFMgUm9vdCBDQTCCASIwDQYJ
+KoZIhvcNAQEBBQADggEPADCCAQoCggEBAMVQe547NdDfxIzNjpvto8A2mfRC6qc+gIMPpqdZh8mQ
+RUN+AOqGeSoDvT03mYlmt+WKVoaTnGhLaASMk5MCPjDSNzoiYYkchU59j9WvezX2fihHiTHcDnlk
+H5nSW7r+f2C/revnPDgpai/lkQtV/+xvWNUtyd5MZnGPDNcE2gfmHhjjvSkCqPoc4Vu5g6hBSLwa
+cY3nYuUtsuvffM/bq1rKMfFMIvMFE/eC+XN5DL7XSxzA0RU8k0Fk0ea+IxciAIleH2ulrG6nS4zt
+o3Lmr2NNL4XSFDWaLk6M6jKYKIahkQlBOrTh4/L68MkKokHdqeMDx4gVOxzUGpTXn2RZEm0CAwEA
+AaNTMFEwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBS6+nEleYtXQSUhhgtx67JkDoshZzAd
+BgNVHQ4EFgQUuvpxJXmLV0ElIYYLceuyZA6LIWcwDQYJKoZIhvcNAQEFBQADggEBAH5Y//01GX2c
+GE+esCu8jowU/yyg2kdbw++BLa8F6nRIW/M+TgfHbcWzk88iNVy2P3UnXwmWzaD+vkAMXBJV+JOC
+yinpXj9WV4s4NvdFGkwozZ5BuO1WTISkQMi4sKUraXAEasP41BIy+Q7DsdwyhEQsb8tGD+pmQQ9P
+8Vilpg0ND2HepZ5dfWWhPBfnqFVO76DH7cZEf1T1o+CP8HxVIo8ptoGj4W1OLBuAZ+ytIJ8MYmHV
+l/9D7S3B2l0pKoU/rGXuhg8FjZBf3+6f9L/uHfuY5H+QK4R4EA5sSVPvFVtlRkpdr7r7OnIdzfYl
+iB6XzCGcKQENZetX2fNXlrtIzYE=
+-----END CERTIFICATE-----
+
+StartCom Certification Authority
+================================
+-----BEGIN CERTIFICATE-----
+MIIHhzCCBW+gAwIBAgIBLTANBgkqhkiG9w0BAQsFADB9MQswCQYDVQQGEwJJTDEWMBQGA1UEChMN
+U3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmlu
+ZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0
+NjM3WhcNMzYwOTE3MTk0NjM2WjB9MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRk
+LjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMg
+U3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw
+ggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZkpMyONvg45iPwbm2xPN1y
+o4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rfOQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/
+Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/CJi/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/d
+eMotHweXMAEtcnn6RtYTKqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt
+2PZE4XNiHzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMMAv+Z
+6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w+2OqqGwaVLRcJXrJ
+osmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/
+untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVc
+UjyJthkqcwEKDwOzEmDyei+B26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT
+37uMdBNSSwIDAQABo4ICEDCCAgwwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD
+VR0OBBYEFE4L7xqkQFulF2mHMMo0aEPQQa7yMB8GA1UdIwQYMBaAFE4L7xqkQFulF2mHMMo0aEPQ
+Qa7yMIIBWgYDVR0gBIIBUTCCAU0wggFJBgsrBgEEAYG1NwEBATCCATgwLgYIKwYBBQUHAgEWImh0
+dHA6Ly93d3cuc3RhcnRzc2wuY29tL3BvbGljeS5wZGYwNAYIKwYBBQUHAgEWKGh0dHA6Ly93d3cu
+c3RhcnRzc2wuY29tL2ludGVybWVkaWF0ZS5wZGYwgc8GCCsGAQUFBwICMIHCMCcWIFN0YXJ0IENv
+bW1lcmNpYWwgKFN0YXJ0Q29tKSBMdGQuMAMCAQEagZZMaW1pdGVkIExpYWJpbGl0eSwgcmVhZCB0
+aGUgc2VjdGlvbiAqTGVnYWwgTGltaXRhdGlvbnMqIG9mIHRoZSBTdGFydENvbSBDZXJ0aWZpY2F0
+aW9uIEF1dGhvcml0eSBQb2xpY3kgYXZhaWxhYmxlIGF0IGh0dHA6Ly93d3cuc3RhcnRzc2wuY29t
+L3BvbGljeS5wZGYwEQYJYIZIAYb4QgEBBAQDAgAHMDgGCWCGSAGG+EIBDQQrFilTdGFydENvbSBG
+cmVlIFNTTCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTANBgkqhkiG9w0BAQsFAAOCAgEAjo/n3JR5
+fPGFf59Jb2vKXfuM/gTFwWLRfUKKvFO3lANmMD+x5wqnUCBVJX92ehQN6wQOQOY+2IirByeDqXWm
+N3PH/UvSTa0XQMhGvjt/UfzDtgUx3M2FIk5xt/JxXrAaxrqTi3iSSoX4eA+D/i+tLPfkpLst0OcN
+Org+zvZ49q5HJMqjNTbOx8aHmNrs++myziebiMMEofYLWWivydsQD032ZGNcpRJvkrKTlMeIFw6T
+tn5ii5B/q06f/ON1FE8qMt9bDeD1e5MNq6HPh+GlBEXoPBKlCcWw0bdT82AUuoVpaiF8H3VhFyAX
+e2w7QSlc4axa0c2Mm+tgHRns9+Ww2vl5GKVFP0lDV9LdJNUso/2RjSe15esUBppMeyG7Oq0wBhjA
+2MFrLH9ZXF2RsXAiV+uKa0hK1Q8p7MZAwC+ITGgBF3f0JBlPvfrhsiAhS90a2Cl9qrjeVOwhVYBs
+HvUwyKMQ5bLmKhQxw4UtjJixhlpPiVktucf3HMiKf8CdBUrmQk9io20ppB+Fq9vlgcitKj1MXVuE
+JnHEhV5xJMqlG2zYYdMa4FTbzrqpMrUi9nNBCV24F10OD5mQ1kfabwo6YigUZ4LZ8dCAWZvLMdib
+D4x3TrVoivJs9iQOLWxwxXPR3hTQcY+203sC9uO41Alua551hDnmfyWl8kgAwKQB2j8=
+-----END CERTIFICATE-----
+
+StartCom Certification Authority G2
+===================================
+-----BEGIN CERTIFICATE-----
+MIIFYzCCA0ugAwIBAgIBOzANBgkqhkiG9w0BAQsFADBTMQswCQYDVQQGEwJJTDEWMBQGA1UEChMN
+U3RhcnRDb20gTHRkLjEsMCoGA1UEAxMjU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg
+RzIwHhcNMTAwMTAxMDEwMDAxWhcNMzkxMjMxMjM1OTAxWjBTMQswCQYDVQQGEwJJTDEWMBQGA1UE
+ChMNU3RhcnRDb20gTHRkLjEsMCoGA1UEAxMjU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3Jp
+dHkgRzIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2iTZbB7cgNr2Cu+EWIAOVeq8O
+o1XJJZlKxdBWQYeQTSFgpBSHO839sj60ZwNq7eEPS8CRhXBF4EKe3ikj1AENoBB5uNsDvfOpL9HG
+4A/LnooUCri99lZi8cVytjIl2bLzvWXFDSxu1ZJvGIsAQRSCb0AgJnooD/Uefyf3lLE3PbfHkffi
+Aez9lInhzG7TNtYKGXmu1zSCZf98Qru23QumNK9LYP5/Q0kGi4xDuFby2X8hQxfqp0iVAXV16iul
+Q5XqFYSdCI0mblWbq9zSOdIxHWDirMxWRST1HFSr7obdljKF+ExP6JV2tgXdNiNnvP8V4so75qbs
+O+wmETRIjfaAKxojAuuKHDp2KntWFhxyKrOq42ClAJ8Em+JvHhRYW6Vsi1g8w7pOOlz34ZYrPu8H
+vKTlXcxNnw3h3Kq74W4a7I/htkxNeXJdFzULHdfBR9qWJODQcqhaX2YtENwvKhOuJv4KHBnM0D4L
+nMgJLvlblnpHnOl68wVQdJVznjAJ85eCXuaPOQgeWeU1FEIT/wCc976qUM/iUUjXuG+v+E5+M5iS
+FGI6dWPPe/regjupuznixL0sAA7IF6wT700ljtizkC+p2il9Ha90OrInwMEePnWjFqmveiJdnxMa
+z6eg6+OGCtP95paV1yPIN93EfKo2rJgaErHgTuixO/XWb/Ew1wIDAQABo0IwQDAPBgNVHRMBAf8E
+BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUS8W0QGutHLOlHGVuRjaJhwUMDrYwDQYJ
+KoZIhvcNAQELBQADggIBAHNXPyzVlTJ+N9uWkusZXn5T50HsEbZH77Xe7XRcxfGOSeD8bpkTzZ+K
+2s06Ctg6Wgk/XzTQLwPSZh0avZyQN8gMjgdalEVGKua+etqhqaRpEpKwfTbURIfXUfEpY9Z1zRbk
+J4kd+MIySP3bmdCPX1R0zKxnNBFi2QwKN4fRoxdIjtIXHfbX/dtl6/2o1PXWT6RbdejF0mCy2wl+
+JYt7ulKSnj7oxXehPOBKc2thz4bcQ///If4jXSRK9dNtD2IEBVeC2m6kMyV5Sy5UGYvMLD0w6dEG
+/+gyRr61M3Z3qAFdlsHB1b6uJcDJHgoJIIihDsnzb02CVAAgp9KP5DlUFy6NHrgbuxu9mk47EDTc
+nIhT76IxW1hPkWLIwpqazRVdOKnWvvgTtZ8SafJQYqz7Fzf07rh1Z2AQ+4NQ+US1dZxAF7L+/Xld
+blhYXzD8AK6vM8EOTmy6p6ahfzLbOOCxchcKK5HsamMm7YnUeMx0HgX4a/6ManY5Ka5lIxKVCCIc
+l85bBu4M4ru8H0ST9tg4RQUh7eStqxK2A6RCLi3ECToDZ2mEmuFZkIoohdVddLHRDiBYmxOlsGOm
+7XtH/UVVMKTumtTm4ofvmMkyghEpIrwACjFeLQ/Ajulrso8uBtjRkcfGEvRM/TAXw8HaOFvjqerm
+obp573PYtlNXLfbQ4ddI
+-----END CERTIFICATE-----
+
+Buypass Class 2 Root CA
+=======================
+-----BEGIN CERTIFICATE-----
+MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU
+QnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3MgQ2xhc3MgMiBSb290IENBMB4X
+DTEwMTAyNjA4MzgwM1oXDTQwMTAyNjA4MzgwM1owTjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1
+eXBhc3MgQVMtOTgzMTYzMzI3MSAwHgYDVQQDDBdCdXlwYXNzIENsYXNzIDIgUm9vdCBDQTCCAiIw
+DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANfHXvfBB9R3+0Mh9PT1aeTuMgHbo4Yf5FkNuud1
+g1Lr6hxhFUi7HQfKjK6w3Jad6sNgkoaCKHOcVgb/S2TwDCo3SbXlzwx87vFKu3MwZfPVL4O2fuPn
+9Z6rYPnT8Z2SdIrkHJasW4DptfQxh6NR/Md+oW+OU3fUl8FVM5I+GC911K2GScuVr1QGbNgGE41b
+/+EmGVnAJLqBcXmQRFBoJJRfuLMR8SlBYaNByyM21cHxMlAQTn/0hpPshNOOvEu/XAFOBz3cFIqU
+CqTqc/sLUegTBxj6DvEr0VQVfTzh97QZQmdiXnfgolXsttlpF9U6r0TtSsWe5HonfOV116rLJeff
+awrbD02TTqigzXsu8lkBarcNuAeBfos4GzjmCleZPe4h6KP1DBbdi+w0jpwqHAAVF41og9JwnxgI
+zRFo1clrUs3ERo/ctfPYV3Me6ZQ5BL/T3jjetFPsaRyifsSP5BtwrfKi+fv3FmRmaZ9JUaLiFRhn
+Bkp/1Wy1TbMz4GHrXb7pmA8y1x1LPC5aAVKRCfLf6o3YBkBjqhHk/sM3nhRSP/TizPJhk9H9Z2vX
+Uq6/aKtAQ6BXNVN48FP4YUIHZMbXb5tMOA1jrGKvNouicwoN9SG9dKpN6nIDSdvHXx1iY8f93ZHs
+M+71bbRuMGjeyNYmsHVee7QHIJihdjK4TWxPAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYD
+VR0OBBYEFMmAd+BikoL1RpzzuvdMw964o605MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsF
+AAOCAgEAU18h9bqwOlI5LJKwbADJ784g7wbylp7ppHR/ehb8t/W2+xUbP6umwHJdELFx7rxP462s
+A20ucS6vxOOto70MEae0/0qyexAQH6dXQbLArvQsWdZHEIjzIVEpMMpghq9Gqx3tOluwlN5E40EI
+osHsHdb9T7bWR9AUC8rmyrV7d35BH16Dx7aMOZawP5aBQW9gkOLo+fsicdl9sz1Gv7SEr5AcD48S
+aq/v7h56rgJKihcrdv6sVIkkLE8/trKnToyokZf7KcZ7XC25y2a2t6hbElGFtQl+Ynhw/qlqYLYd
+DnkM/crqJIByw5c/8nerQyIKx+u2DISCLIBrQYoIwOula9+ZEsuK1V6ADJHgJgg2SMX6OBE1/yWD
+LfJ6v9r9jv6ly0UsH8SIU653DtmadsWOLB2jutXsMq7Aqqz30XpN69QH4kj3Io6wpJ9qzo6ysmD0
+oyLQI+uUWnpp3Q+/QFesa1lQ2aOZ4W7+jQF5JyMV3pKdewlNWudLSDBaGOYKbeaP4NK75t98biGC
+wWg5TbSYWGZizEqQXsP6JwSxeRV0mcy+rSDeJmAc61ZRpqPq5KM/p/9h3PFaTWwyI0PurKju7koS
+CTxdccK+efrCh2gdC/1cacwG0Jp9VJkqyTkaGa9LKkPzY11aWOIv4x3kqdbQCtCev9eBCfHJxyYN
+rJgWVqA=
+-----END CERTIFICATE-----
+
+Buypass Class 3 Root CA
+=======================
+-----BEGIN CERTIFICATE-----
+MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU
+QnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3MgQ2xhc3MgMyBSb290IENBMB4X
+DTEwMTAyNjA4Mjg1OFoXDTQwMTAyNjA4Mjg1OFowTjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1
+eXBhc3MgQVMtOTgzMTYzMzI3MSAwHgYDVQQDDBdCdXlwYXNzIENsYXNzIDMgUm9vdCBDQTCCAiIw
+DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKXaCpUWUOOV8l6ddjEGMnqb8RB2uACatVI2zSRH
+sJ8YZLya9vrVediQYkwiL944PdbgqOkcLNt4EemOaFEVcsfzM4fkoF0LXOBXByow9c3EN3coTRiR
+5r/VUv1xLXA+58bEiuPwKAv0dpihi4dVsjoT/Lc+JzeOIuOoTyrvYLs9tznDDgFHmV0ST9tD+leh
+7fmdvhFHJlsTmKtdFoqwNxxXnUX/iJY2v7vKB3tvh2PX0DJq1l1sDPGzbjniazEuOQAnFN44wOwZ
+ZoYS6J1yFhNkUsepNxz9gjDthBgd9K5c/3ATAOux9TN6S9ZV+AWNS2mw9bMoNlwUxFFzTWsL8TQH
+2xc519woe2v1n/MuwU8XKhDzzMro6/1rqy6any2CbgTUUgGTLT2G/H783+9CHaZr77kgxve9oKeV
+/afmiSTYzIw0bOIjL9kSGiG5VZFvC5F5GQytQIgLcOJ60g7YaEi7ghM5EFjp2CoHxhLbWNvSO1UQ
+RwUVZ2J+GGOmRj8JDlQyXr8NYnon74Do29lLBlo3WiXQCBJ31G8JUJc9yB3D34xFMFbG02SrZvPA
+Xpacw8Tvw3xrizp5f7NJzz3iiZ+gMEuFuZyUJHmPfWupRWgPK9Dx2hzLabjKSWJtyNBjYt1gD1iq
+j6G8BaVmos8bdrKEZLFMOVLAMLrwjEsCsLa3AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYD
+VR0OBBYEFEe4zf/lb+74suwvTg75JbCOPGvDMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsF
+AAOCAgEAACAjQTUEkMJAYmDv4jVM1z+s4jSQuKFvdvoWFqRINyzpkMLyPPgKn9iB5btb2iUspKdV
+cSQy9sgL8rxq+JOssgfCX5/bzMiKqr5qb+FJEMwx14C7u8jYog5kV+qi9cKpMRXSIGrs/CIBKM+G
+uIAeqcwRpTzyFrNHnfzSgCHEy9BHcEGhyoMZCCxt8l13nIoUE9Q2HJLw5QY33KbmkJs4j1xrG0aG
+Q0JfPgEHU1RdZX33inOhmlRaHylDFCfChQ+1iHsaO5S3HWCntZznKWlXWpuTekMwGwPXYshApqr8
+ZORK15FTAaggiG6cX0S5y2CBNOxv033aSF/rtJC8LakcC6wc1aJoIIAE1vyxjy+7SjENSoYc6+I2
+KSb12tjE8nVhz36udmNKekBlk4f4HoCMhuWG1o8O/FMsYOgWYRqiPkN7zTlgVGr18okmAWiDSKIz
+6MkEkbIRNBE+6tBDGR8Dk5AM/1E9V/RBbuHLoL7ryWPNbczk+DaqaJ3tvV2XcEQNtg413OEMXbug
+UZTLfhbrES+jkkXITHHZvMmZUldGL1DPvTVp9D0VzgalLA8+9oG6lLvDu79leNKGef9JOxqDDPDe
+eOzI8k1MGt6CKfjBWtrt7uYnXuhF0J0cUahoq0Tj0Itq4/g7u9xN12TyUb7mqqta6THuBrxzvxNi
+Cp/HuZc=
+-----END CERTIFICATE-----
+
+T-TeleSec GlobalRoot Class 3
+============================
+-----BEGIN CERTIFICATE-----
+MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoM
+IlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBU
+cnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwHhcNMDgx
+MDAxMTAyOTU2WhcNMzMxMDAxMjM1OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lz
+dGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBD
+ZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwggEiMA0GCSqGSIb3
+DQEBAQUAA4IBDwAwggEKAoIBAQC9dZPwYiJvJK7genasfb3ZJNW4t/zN8ELg63iIVl6bmlQdTQyK
+9tPPcPRStdiTBONGhnFBSivwKixVA9ZIw+A5OO3yXDw/RLyTPWGrTs0NvvAgJ1gORH8EGoel15YU
+NpDQSXuhdfsaa3Ox+M6pCSzyU9XDFES4hqX2iys52qMzVNn6chr3IhUciJFrf2blw2qAsCTz34ZF
+iP0Zf3WHHx+xGwpzJFu5ZeAsVMhg02YXP+HMVDNzkQI6pn97djmiH5a2OK61yJN0HZ65tOVgnS9W
+0eDrXltMEnAMbEQgqxHY9Bn20pxSN+f6tsIxO0rUFJmtxxr1XV/6B7h8DR/Wgx6zAgMBAAGjQjBA
+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS1A/d2O2GCahKqGFPr
+AyGUv/7OyjANBgkqhkiG9w0BAQsFAAOCAQEAVj3vlNW92nOyWL6ukK2YJ5f+AbGwUgC4TeQbIXQb
+fsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ1GSFS5mvJQQeyUapl96Cshtwn5z2r3Ex3XsFpSzT
+ucpH9sry9uetuUg/vBa3wW306gmv7PO15wWeph6KU1HWk4HMdJP2udqmJQV0eVp+QD6CSyYRMG7h
+P0HHRwA11fXT91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml
+e9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4pTpPDpFQUWw==
+-----END CERTIFICATE-----
+
+EE Certification Centre Root CA
+===============================
+-----BEGIN CERTIFICATE-----
+MIIEAzCCAuugAwIBAgIQVID5oHPtPwBMyonY43HmSjANBgkqhkiG9w0BAQUFADB1MQswCQYDVQQG
+EwJFRTEiMCAGA1UECgwZQVMgU2VydGlmaXRzZWVyaW1pc2tlc2t1czEoMCYGA1UEAwwfRUUgQ2Vy
+dGlmaWNhdGlvbiBDZW50cmUgUm9vdCBDQTEYMBYGCSqGSIb3DQEJARYJcGtpQHNrLmVlMCIYDzIw
+MTAxMDMwMTAxMDMwWhgPMjAzMDEyMTcyMzU5NTlaMHUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKDBlB
+UyBTZXJ0aWZpdHNlZXJpbWlza2Vza3VzMSgwJgYDVQQDDB9FRSBDZXJ0aWZpY2F0aW9uIENlbnRy
+ZSBSb290IENBMRgwFgYJKoZIhvcNAQkBFglwa2lAc2suZWUwggEiMA0GCSqGSIb3DQEBAQUAA4IB
+DwAwggEKAoIBAQDIIMDs4MVLqwd4lfNE7vsLDP90jmG7sWLqI9iroWUyeuuOF0+W2Ap7kaJjbMeM
+TC55v6kF/GlclY1i+blw7cNRfdCT5mzrMEvhvH2/UpvObntl8jixwKIy72KyaOBhU8E2lf/slLo2
+rpwcpzIP5Xy0xm90/XsY6KxX7QYgSzIwWFv9zajmofxwvI6Sc9uXp3whrj3B9UiHbCe9nyV0gVWw
+93X2PaRka9ZP585ArQ/dMtO8ihJTmMmJ+xAdTX7Nfh9WDSFwhfYggx/2uh8Ej+p3iDXE/+pOoYtN
+P2MbRMNE1CV2yreN1x5KZmTNXMWcg+HCCIia7E6j8T4cLNlsHaFLAgMBAAGjgYowgYcwDwYDVR0T
+AQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBLyWj7qVhy/zQas8fElyalL1BSZ
+MEUGA1UdJQQ+MDwGCCsGAQUFBwMCBggrBgEFBQcDAQYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEF
+BQcDCAYIKwYBBQUHAwkwDQYJKoZIhvcNAQEFBQADggEBAHv25MANqhlHt01Xo/6tu7Fq1Q+e2+Rj
+xY6hUFaTlrg4wCQiZrxTFGGVv9DHKpY5P30osxBAIWrEr7BSdxjhlthWXePdNl4dp1BUoMUq5KqM
+lIpPnTX/dqQGE5Gion0ARD9V04I8GtVbvFZMIi5GQ4okQC3zErg7cBqklrkar4dBGmoYDQZPxz5u
+uSlNDUmJEYcyW+ZLBMjkXOZ0c5RdFpgTlf7727FE5TpwrDdr5rMzcijJs1eg9gIWiAYLtqZLICjU
+3j2LrTcFU3T+bsy8QxdxXvnFzBqpYe73dgzzcvRyrc9yAjYHR8/vGVCJYMzpJJUPwssd8m92kMfM
+dcGWxZ0=
+-----END CERTIFICATE-----
+
+TURKTRUST Certificate Services Provider Root 2007
+=================================================
+-----BEGIN CERTIFICATE-----
+MIIEPTCCAyWgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBvzE/MD0GA1UEAww2VMOcUktUUlVTVCBF
+bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMQswCQYDVQQGEwJUUjEP
+MA0GA1UEBwwGQW5rYXJhMV4wXAYDVQQKDFVUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUg
+QmlsacWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLiAoYykgQXJhbMSxayAyMDA3MB4X
+DTA3MTIyNTE4MzcxOVoXDTE3MTIyMjE4MzcxOVowgb8xPzA9BgNVBAMMNlTDnFJLVFJVU1QgRWxl
+a3Ryb25payBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsTELMAkGA1UEBhMCVFIxDzAN
+BgNVBAcMBkFua2FyYTFeMFwGA1UECgxVVMOcUktUUlVTVCBCaWxnaSDEsGxldGnFn2ltIHZlIEJp
+bGnFn2ltIEfDvHZlbmxpxJ9pIEhpem1ldGxlcmkgQS7Fni4gKGMpIEFyYWzEsWsgMjAwNzCCASIw
+DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKu3PgqMyKVYFeaK7yc9SrToJdPNM8Ig3BnuiD9N
+YvDdE3ePYakqtdTyuTFYKTsvP2qcb3N2Je40IIDu6rfwxArNK4aUyeNgsURSsloptJGXg9i3phQv
+KUmi8wUG+7RP2qFsmmaf8EMJyupyj+sA1zU511YXRxcw9L6/P8JorzZAwan0qafoEGsIiveGHtya
+KhUG9qPw9ODHFNRRf8+0222vR5YXm3dx2KdxnSQM9pQ/hTEST7ruToK4uT6PIzdezKKqdfcYbwnT
+rqdUKDT74eA7YH2gvnmJhsifLfkKS8RQouf9eRbHegsYz85M733WB2+Y8a+xwXrXgTW4qhe04MsC
+AwEAAaNCMEAwHQYDVR0OBBYEFCnFkKslrxHkYb+j/4hhkeYO/pyBMA4GA1UdDwEB/wQEAwIBBjAP
+BgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQAQDdr4Ouwo0RSVgrESLFF6QSU2TJ/s
+Px+EnWVUXKgWAkD6bho3hO9ynYYKVZ1WKKxmLNA6VpM0ByWtCLCPyA8JWcqdmBzlVPi5RX9ql2+I
+aE1KBiY3iAIOtsbWcpnOa3faYjGkVh+uX4132l32iPwa2Z61gfAyuOOI0JzzaqC5mxRZNTZPz/OO
+Xl0XrRWV2N2y1RVuAE6zS89mlOTgzbUF2mNXi+WzqtvALhyQRNsaXRik7r4EW5nVcV9VZWRi1aKb
+BFmGyGJ353yCRWo9F7/snXUMrqNvWtMvmDb08PUZqxFdyKbjKlhqQgnDvZImZjINXQhVdP+MmNAK
+poRq0Tl9
+-----END CERTIFICATE-----
+
+D-TRUST Root Class 3 CA 2 2009
+==============================
+-----BEGIN CERTIFICATE-----
+MIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQK
+DAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTAe
+Fw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NThaME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxE
+LVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTCCASIw
+DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANOySs96R+91myP6Oi/WUEWJNTrGa9v+2wBoqOAD
+ER03UAifTUpolDWzU9GUY6cgVq/eUXjsKj3zSEhQPgrfRlWLJ23DEE0NkVJD2IfgXU42tSHKXzlA
+BF9bfsyjxiupQB7ZNoTWSPOSHjRGICTBpFGOShrvUD9pXRl/RcPHAY9RySPocq60vFYJfxLLHLGv
+KZAKyVXMD9O0Gu1HNVpK7ZxzBCHQqr0ME7UAyiZsxGsMlFqVlNpQmvH/pStmMaTJOKDfHR+4CS7z
+p+hnUquVH+BGPtikw8paxTGA6Eian5Rp/hnd2HN8gcqW3o7tszIFZYQ05ub9VxC1X3a/L7AQDcUC
+AwEAAaOCARowggEWMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP3aFMSfMN4hvR5COfyrYyNJ
+4PGEMA4GA1UdDwEB/wQEAwIBBjCB0wYDVR0fBIHLMIHIMIGAoH6gfIZ6bGRhcDovL2RpcmVjdG9y
+eS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwUm9vdCUyMENsYXNzJTIwMyUyMENBJTIwMiUyMDIw
+MDksTz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRlcmV2b2NhdGlvbmxpc3QwQ6BBoD+G
+PWh0dHA6Ly93d3cuZC10cnVzdC5uZXQvY3JsL2QtdHJ1c3Rfcm9vdF9jbGFzc18zX2NhXzJfMjAw
+OS5jcmwwDQYJKoZIhvcNAQELBQADggEBAH+X2zDI36ScfSF6gHDOFBJpiBSVYEQBrLLpME+bUMJm
+2H6NMLVwMeniacfzcNsgFYbQDfC+rAF1hM5+n02/t2A7nPPKHeJeaNijnZflQGDSNiH+0LS4F9p0
+o3/U37CYAqxva2ssJSRyoWXuJVrl5jLn8t+rSfrzkGkj2wTZ51xY/GXUl77M/C4KzCUqNQT4YJEV
+dT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8PIWmawomDeCTmGCufsYkl4ph
+X5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3YJohw1+qRzT65ysCQblrGXnRl11z+o+I=
+-----END CERTIFICATE-----
+
+D-TRUST Root Class 3 CA 2 EV 2009
+=================================
+-----BEGIN CERTIFICATE-----
+MIIEQzCCAyugAwIBAgIDCYP0MA0GCSqGSIb3DQEBCwUAMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQK
+DAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAw
+OTAeFw0wOTExMDUwODUwNDZaFw0yOTExMDUwODUwNDZaMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQK
+DAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAw
+OTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJnxhDRwui+3MKCOvXwEz75ivJn9gpfS
+egpnljgJ9hBOlSJzmY3aFS3nBfwZcyK3jpgAvDw9rKFs+9Z5JUut8Mxk2og+KbgPCdM03TP1YtHh
+zRnp7hhPTFiu4h7WDFsVWtg6uMQYZB7jM7K1iXdODL/ZlGsTl28So/6ZqQTMFexgaDbtCHu39b+T
+7WYxg4zGcTSHThfqr4uRjRxWQa4iN1438h3Z0S0NL2lRp75mpoo6Kr3HGrHhFPC+Oh25z1uxav60
+sUYgovseO3Dvk5h9jHOW8sXvhXCtKSb8HgQ+HKDYD8tSg2J87otTlZCpV6LqYQXY+U3EJ/pure35
+11H3a6UCAwEAAaOCASQwggEgMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNOUikxiEyoZLsyv
+cop9NteaHNxnMA4GA1UdDwEB/wQEAwIBBjCB3QYDVR0fBIHVMIHSMIGHoIGEoIGBhn9sZGFwOi8v
+ZGlyZWN0b3J5LmQtdHJ1c3QubmV0L0NOPUQtVFJVU1QlMjBSb290JTIwQ2xhc3MlMjAzJTIwQ0El
+MjAyJTIwRVYlMjAyMDA5LE89RC1UcnVzdCUyMEdtYkgsQz1ERT9jZXJ0aWZpY2F0ZXJldm9jYXRp
+b25saXN0MEagRKBChkBodHRwOi8vd3d3LmQtdHJ1c3QubmV0L2NybC9kLXRydXN0X3Jvb3RfY2xh
+c3NfM19jYV8yX2V2XzIwMDkuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQA07XtaPKSUiO8aEXUHL7P+
+PPoeUSbrh/Yp3uDx1MYkCenBz1UbtDDZzhr+BlGmFaQt77JLvyAoJUnRpjZ3NOhk31KxEcdzes05
+nsKtjHEh8lprr988TlWvsoRlFIm5d8sqMb7Po23Pb0iUMkZv53GMoKaEGTcH8gNFCSuGdXzfX2lX
+ANtu2KZyIktQ1HWYVt+3GP9DQ1CuekR78HlR10M9p9OB0/DJT7naxpeG0ILD5EJt/rDiZE4OJudA
+NCa1CInXCGNjOCd1HjPqbqjdn5lPdE2BiYBL3ZqXKVwvvoFBuYz/6n1gBp7N1z3TLqMVvKjmJuVv
+w9y4AyHqnxbxLFS1
+-----END CERTIFICATE-----
+
+PSCProcert
+==========
+-----BEGIN CERTIFICATE-----
+MIIJhjCCB26gAwIBAgIBCzANBgkqhkiG9w0BAQsFADCCAR4xPjA8BgNVBAMTNUF1dG9yaWRhZCBk
+ZSBDZXJ0aWZpY2FjaW9uIFJhaXogZGVsIEVzdGFkbyBWZW5lem9sYW5vMQswCQYDVQQGEwJWRTEQ
+MA4GA1UEBxMHQ2FyYWNhczEZMBcGA1UECBMQRGlzdHJpdG8gQ2FwaXRhbDE2MDQGA1UEChMtU2lz
+dGVtYSBOYWNpb25hbCBkZSBDZXJ0aWZpY2FjaW9uIEVsZWN0cm9uaWNhMUMwQQYDVQQLEzpTdXBl
+cmludGVuZGVuY2lhIGRlIFNlcnZpY2lvcyBkZSBDZXJ0aWZpY2FjaW9uIEVsZWN0cm9uaWNhMSUw
+IwYJKoZIhvcNAQkBFhZhY3JhaXpAc3VzY2VydGUuZ29iLnZlMB4XDTEwMTIyODE2NTEwMFoXDTIw
+MTIyNTIzNTk1OVowgdExJjAkBgkqhkiG9w0BCQEWF2NvbnRhY3RvQHByb2NlcnQubmV0LnZlMQ8w
+DQYDVQQHEwZDaGFjYW8xEDAOBgNVBAgTB01pcmFuZGExKjAoBgNVBAsTIVByb3ZlZWRvciBkZSBD
+ZXJ0aWZpY2Fkb3MgUFJPQ0VSVDE2MDQGA1UEChMtU2lzdGVtYSBOYWNpb25hbCBkZSBDZXJ0aWZp
+Y2FjaW9uIEVsZWN0cm9uaWNhMQswCQYDVQQGEwJWRTETMBEGA1UEAxMKUFNDUHJvY2VydDCCAiIw
+DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANW39KOUM6FGqVVhSQ2oh3NekS1wwQYalNo97BVC
+wfWMrmoX8Yqt/ICV6oNEolt6Vc5Pp6XVurgfoCfAUFM+jbnADrgV3NZs+J74BCXfgI8Qhd19L3uA
+3VcAZCP4bsm+lU/hdezgfl6VzbHvvnpC2Mks0+saGiKLt38GieU89RLAu9MLmV+QfI4tL3czkkoh
+RqipCKzx9hEC2ZUWno0vluYC3XXCFCpa1sl9JcLB/KpnheLsvtF8PPqv1W7/U0HU9TI4seJfxPmO
+EO8GqQKJ/+MMbpfg353bIdD0PghpbNjU5Db4g7ayNo+c7zo3Fn2/omnXO1ty0K+qP1xmk6wKImG2
+0qCZyFSTXai20b1dCl53lKItwIKOvMoDKjSuc/HUtQy9vmebVOvh+qBa7Dh+PsHMosdEMXXqP+UH
+0quhJZb25uSgXTcYOWEAM11G1ADEtMo88aKjPvM6/2kwLkDd9p+cJsmWN63nOaK/6mnbVSKVUyqU
+td+tFjiBdWbjxywbk5yqjKPK2Ww8F22c3HxT4CAnQzb5EuE8XL1mv6JpIzi4mWCZDlZTOpx+FIyw
+Bm/xhnaQr/2v/pDGj59/i5IjnOcVdo/Vi5QTcmn7K2FjiO/mpF7moxdqWEfLcU8UC17IAggmosvp
+r2uKGcfLFFb14dq12fy/czja+eevbqQ34gcnAgMBAAGjggMXMIIDEzASBgNVHRMBAf8ECDAGAQH/
+AgEBMDcGA1UdEgQwMC6CD3N1c2NlcnRlLmdvYi52ZaAbBgVghl4CAqASDBBSSUYtRy0yMDAwNDAz
+Ni0wMB0GA1UdDgQWBBRBDxk4qpl/Qguk1yeYVKIXTC1RVDCCAVAGA1UdIwSCAUcwggFDgBStuyId
+xuDSAaj9dlBSk+2YwU2u06GCASakggEiMIIBHjE+MDwGA1UEAxM1QXV0b3JpZGFkIGRlIENlcnRp
+ZmljYWNpb24gUmFpeiBkZWwgRXN0YWRvIFZlbmV6b2xhbm8xCzAJBgNVBAYTAlZFMRAwDgYDVQQH
+EwdDYXJhY2FzMRkwFwYDVQQIExBEaXN0cml0byBDYXBpdGFsMTYwNAYDVQQKEy1TaXN0ZW1hIE5h
+Y2lvbmFsIGRlIENlcnRpZmljYWNpb24gRWxlY3Ryb25pY2ExQzBBBgNVBAsTOlN1cGVyaW50ZW5k
+ZW5jaWEgZGUgU2VydmljaW9zIGRlIENlcnRpZmljYWNpb24gRWxlY3Ryb25pY2ExJTAjBgkqhkiG
+9w0BCQEWFmFjcmFpekBzdXNjZXJ0ZS5nb2IudmWCAQowDgYDVR0PAQH/BAQDAgEGME0GA1UdEQRG
+MESCDnByb2NlcnQubmV0LnZloBUGBWCGXgIBoAwMClBTQy0wMDAwMDKgGwYFYIZeAgKgEgwQUklG
+LUotMzE2MzUzNzMtNzB2BgNVHR8EbzBtMEagRKBChkBodHRwOi8vd3d3LnN1c2NlcnRlLmdvYi52
+ZS9sY3IvQ0VSVElGSUNBRE8tUkFJWi1TSEEzODRDUkxERVIuY3JsMCOgIaAfhh1sZGFwOi8vYWNy
+YWl6LnN1c2NlcnRlLmdvYi52ZTA3BggrBgEFBQcBAQQrMCkwJwYIKwYBBQUHMAGGG2h0dHA6Ly9v
+Y3NwLnN1c2NlcnRlLmdvYi52ZTBBBgNVHSAEOjA4MDYGBmCGXgMBAjAsMCoGCCsGAQUFBwIBFh5o
+dHRwOi8vd3d3LnN1c2NlcnRlLmdvYi52ZS9kcGMwDQYJKoZIhvcNAQELBQADggIBACtZ6yKZu4Sq
+T96QxtGGcSOeSwORR3C7wJJg7ODU523G0+1ng3dS1fLld6c2suNUvtm7CpsR72H0xpkzmfWvADmN
+g7+mvTV+LFwxNG9s2/NkAZiqlCxB3RWGymspThbASfzXg0gTB1GEMVKIu4YXx2sviiCtxQuPcD4q
+uxtxj7mkoP3YldmvWb8lK5jpY5MvYB7Eqvh39YtsL+1+LrVPQA3uvFd359m21D+VJzog1eWuq2w1
+n8GhHVnchIHuTQfiSLaeS5UtQbHh6N5+LwUeaO6/u5BlOsju6rEYNxxik6SgMexxbJHmpHmJWhSn
+FFAFTKQAVzAswbVhltw+HoSvOULP5dAssSS830DD7X9jSr3hTxJkhpXzsOfIt+FTvZLm8wyWuevo
+5pLtp4EJFAv8lXrPj9Y0TzYS3F7RNHXGRoAvlQSMx4bEqCaJqD8Zm4G7UaRKhqsLEQ+xrmNTbSjq
+3TNWOByyrYDT13K9mmyZY+gAu0F2BbdbmRiKw7gSXFbPVgx96OLP7bx0R/vu0xdOIk9W/1DzLuY5
+poLWccret9W6aAjtmcz9opLLabid+Qqkpj5PkygqYWwHJgD/ll9ohri4zspV4KuxPX+Y1zMOWj3Y
+eMLEYC/HYvBhkdI4sPaeVdtAgAUSM84dkpvRabP/v/GSCmE1P93+hvS84Bpxs2Km
+-----END CERTIFICATE-----
+
+China Internet Network Information Center EV Certificates Root
+==============================================================
+-----BEGIN CERTIFICATE-----
+MIID9zCCAt+gAwIBAgIESJ8AATANBgkqhkiG9w0BAQUFADCBijELMAkGA1UEBhMCQ04xMjAwBgNV
+BAoMKUNoaW5hIEludGVybmV0IE5ldHdvcmsgSW5mb3JtYXRpb24gQ2VudGVyMUcwRQYDVQQDDD5D
+aGluYSBJbnRlcm5ldCBOZXR3b3JrIEluZm9ybWF0aW9uIENlbnRlciBFViBDZXJ0aWZpY2F0ZXMg
+Um9vdDAeFw0xMDA4MzEwNzExMjVaFw0zMDA4MzEwNzExMjVaMIGKMQswCQYDVQQGEwJDTjEyMDAG
+A1UECgwpQ2hpbmEgSW50ZXJuZXQgTmV0d29yayBJbmZvcm1hdGlvbiBDZW50ZXIxRzBFBgNVBAMM
+PkNoaW5hIEludGVybmV0IE5ldHdvcmsgSW5mb3JtYXRpb24gQ2VudGVyIEVWIENlcnRpZmljYXRl
+cyBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAm35z7r07eKpkQ0H1UN+U8i6y
+jUqORlTSIRLIOTJCBumD1Z9S7eVnAztUwYyZmczpwA//DdmEEbK40ctb3B75aDFk4Zv6dOtouSCV
+98YPjUesWgbdYavi7NifFy2cyjw1l1VxzUOFsUcW9SxTgHbP0wBkvUCZ3czY28Sf1hNfQYOL+Q2H
+klY0bBoQCxfVWhyXWIQ8hBouXJE0bhlffxdpxWXvayHG1VA6v2G5BY3vbzQ6sm8UY78WO5upKv23
+KzhmBsUs4qpnHkWnjQRmQvaPK++IIGmPMowUc9orhpFjIpryp9vOiYurXccUwVswah+xt54ugQEC
+7c+WXmPbqOY4twIDAQABo2MwYTAfBgNVHSMEGDAWgBR8cks5x8DbYqVPm6oYNJKiyoOCWTAPBgNV
+HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUfHJLOcfA22KlT5uqGDSSosqD
+glkwDQYJKoZIhvcNAQEFBQADggEBACrDx0M3j92tpLIM7twUbY8opJhJywyA6vPtI2Z1fcXTIWd5
+0XPFtQO3WKwMVC/GVhMPMdoG52U7HW8228gd+f2ABsqjPWYWqJ1MFn3AlUa1UeTiH9fqBk1jjZaM
+7+czV0I664zBechNdn3e9rG3geCg+aF4RhcaVpjwTj2rHO3sOdwHSPdj/gauwqRcalsyiMXHM4Ws
+ZkJHwlgkmeHlPuV1LI5D1l08eB6olYIpUNHRFrrvwb562bTYzB5MRuF3sTGrvSrIzo9uoV1/A3U0
+5K2JRVRevq4opbs/eHnrc7MKDf2+yfdWrPa37S+bISnHOLaVxATywy39FCqQmbkHzJ8=
+-----END CERTIFICATE-----
+
+Swisscom Root CA 2
+==================
+-----BEGIN CERTIFICATE-----
+MIIF2TCCA8GgAwIBAgIQHp4o6Ejy5e/DfEoeWhhntjANBgkqhkiG9w0BAQsFADBkMQswCQYDVQQG
+EwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsTHERpZ2l0YWwgQ2VydGlmaWNhdGUgU2Vy
+dmljZXMxGzAZBgNVBAMTElN3aXNzY29tIFJvb3QgQ0EgMjAeFw0xMTA2MjQwODM4MTRaFw0zMTA2
+MjUwNzM4MTRaMGQxCzAJBgNVBAYTAmNoMREwDwYDVQQKEwhTd2lzc2NvbTElMCMGA1UECxMcRGln
+aXRhbCBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczEbMBkGA1UEAxMSU3dpc3Njb20gUm9vdCBDQSAyMIIC
+IjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAlUJOhJ1R5tMJ6HJaI2nbeHCOFvErjw0DzpPM
+LgAIe6szjPTpQOYXTKueuEcUMncy3SgM3hhLX3af+Dk7/E6J2HzFZ++r0rk0X2s682Q2zsKwzxNo
+ysjL67XiPS4h3+os1OD5cJZM/2pYmLcX5BtS5X4HAB1f2uY+lQS3aYg5oUFgJWFLlTloYhyxCwWJ
+wDaCFCE/rtuh/bxvHGCGtlOUSbkrRsVPACu/obvLP+DHVxxX6NZp+MEkUp2IVd3Chy50I9AU/SpH
+Wrumnf2U5NGKpV+GY3aFy6//SSj8gO1MedK75MDvAe5QQQg1I3ArqRa0jG6F6bYRzzHdUyYb3y1a
+SgJA/MTAtukxGggo5WDDH8SQjhBiYEQN7Aq+VRhxLKX0srwVYv8c474d2h5Xszx+zYIdkeNL6yxS
+NLCK/RJOlrDrcH+eOfdmQrGrrFLadkBXeyq96G4DsguAhYidDMfCd7Camlf0uPoTXGiTOmekl9Ab
+mbeGMktg2M7v0Ax/lZ9vh0+Hio5fCHyqW/xavqGRn1V9TrALacywlKinh/LTSlDcX3KwFnUey7QY
+Ypqwpzmqm59m2I2mbJYV4+by+PGDYmy7Velhk6M99bFXi08jsJvllGov34zflVEpYKELKeRcVVi3
+qPyZ7iVNTA6z00yPhOgpD/0QVAKFyPnlw4vP5w8CAwEAAaOBhjCBgzAOBgNVHQ8BAf8EBAMCAYYw
+HQYDVR0hBBYwFDASBgdghXQBUwIBBgdghXQBUwIBMBIGA1UdEwEB/wQIMAYBAf8CAQcwHQYDVR0O
+BBYEFE0mICKJS9PVpAqhb97iEoHF8TwuMB8GA1UdIwQYMBaAFE0mICKJS9PVpAqhb97iEoHF8Twu
+MA0GCSqGSIb3DQEBCwUAA4ICAQAyCrKkG8t9voJXiblqf/P0wS4RfbgZPnm3qKhyN2abGu2sEzsO
+v2LwnN+ee6FTSA5BesogpxcbtnjsQJHzQq0Qw1zv/2BZf82Fo4s9SBwlAjxnffUy6S8w5X2lejjQ
+82YqZh6NM4OKb3xuqFp1mrjX2lhIREeoTPpMSQpKwhI3qEAMw8jh0FcNlzKVxzqfl9NX+Ave5XLz
+o9v/tdhZsnPdTSpxsrpJ9csc1fV5yJmz/MFMdOO0vSk3FQQoHt5FRnDsr7p4DooqzgB53MBfGWcs
+a0vvaGgLQ+OswWIJ76bdZWGgr4RVSJFSHMYlkSrQwSIjYVmvRRGFHQEkNI/Ps/8XciATwoCqISxx
+OQ7Qj1zB09GOInJGTB2Wrk9xseEFKZZZ9LuedT3PDTcNYtsmjGOpI99nBjx8Oto0QuFmtEYE3saW
+mA9LSHokMnWRn6z3aOkquVVlzl1h0ydw2Df+n7mvoC5Wt6NlUe07qxS/TFED6F+KBZvuim6c779o
++sjaC+NCydAXFJy3SuCvkychVSa1ZC+N8f+mQAWFBVzKBxlcCxMoTFh/wqXvRdpg065lYZ1Tg3TC
+rvJcwhbtkj6EPnNgiLx29CzP0H1907he0ZESEOnN3col49XtmS++dYFLJPlFRpTJKSFTnCZFqhMX
+5OfNeOI5wSsSnqaeG8XmDtkx2Q==
+-----END CERTIFICATE-----
+
+Swisscom Root EV CA 2
+=====================
+-----BEGIN CERTIFICATE-----
+MIIF4DCCA8igAwIBAgIRAPL6ZOJ0Y9ON/RAdBB92ylgwDQYJKoZIhvcNAQELBQAwZzELMAkGA1UE
+BhMCY2gxETAPBgNVBAoTCFN3aXNzY29tMSUwIwYDVQQLExxEaWdpdGFsIENlcnRpZmljYXRlIFNl
+cnZpY2VzMR4wHAYDVQQDExVTd2lzc2NvbSBSb290IEVWIENBIDIwHhcNMTEwNjI0MDk0NTA4WhcN
+MzEwNjI1MDg0NTA4WjBnMQswCQYDVQQGEwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsT
+HERpZ2l0YWwgQ2VydGlmaWNhdGUgU2VydmljZXMxHjAcBgNVBAMTFVN3aXNzY29tIFJvb3QgRVYg
+Q0EgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMT3HS9X6lds93BdY7BxUglgRCgz
+o3pOCvrY6myLURYaVa5UJsTMRQdBTxB5f3HSek4/OE6zAMaVylvNwSqD1ycfMQ4jFrclyxy0uYAy
+Xhqdk/HoPGAsp15XGVhRXrwsVgu42O+LgrQ8uMIkqBPHoCE2G3pXKSinLr9xJZDzRINpUKTk4Rti
+GZQJo/PDvO/0vezbE53PnUgJUmfANykRHvvSEaeFGHR55E+FFOtSN+KxRdjMDUN/rhPSays/p8Li
+qG12W0OfvrSdsyaGOx9/5fLoZigWJdBLlzin5M8J0TbDC77aO0RYjb7xnglrPvMyxyuHxuxenPaH
+Za0zKcQvidm5y8kDnftslFGXEBuGCxobP/YCfnvUxVFkKJ3106yDgYjTdLRZncHrYTNaRdHLOdAG
+alNgHa/2+2m8atwBz735j9m9W8E6X47aD0upm50qKGsaCnw8qyIL5XctcfaCNYGu+HuB5ur+rPQa
+m3Rc6I8k9l2dRsQs0h4rIWqDJ2dVSqTjyDKXZpBy2uPUZC5f46Fq9mDU5zXNysRojddxyNMkM3Ox
+bPlq4SjbX8Y96L5V5jcb7STZDxmPX2MYWFCBUWVv8p9+agTnNCRxunZLWB4ZvRVgRaoMEkABnRDi
+xzgHcgplwLa7JSnaFp6LNYth7eVxV4O1PHGf40+/fh6Bn0GXAgMBAAGjgYYwgYMwDgYDVR0PAQH/
+BAQDAgGGMB0GA1UdIQQWMBQwEgYHYIV0AVMCAgYHYIV0AVMCAjASBgNVHRMBAf8ECDAGAQH/AgED
+MB0GA1UdDgQWBBRF2aWBbj2ITY1x0kbBbkUe88SAnTAfBgNVHSMEGDAWgBRF2aWBbj2ITY1x0kbB
+bkUe88SAnTANBgkqhkiG9w0BAQsFAAOCAgEAlDpzBp9SSzBc1P6xXCX5145v9Ydkn+0UjrgEjihL
+j6p7jjm02Vj2e6E1CqGdivdj5eu9OYLU43otb98TPLr+flaYC/NUn81ETm484T4VvwYmneTwkLbU
+wp4wLh/vx3rEUMfqe9pQy3omywC0Wqu1kx+AiYQElY2NfwmTv9SoqORjbdlk5LgpWgi/UOGED1V7
+XwgiG/W9mR4U9s70WBCCswo9GcG/W6uqmdjyMb3lOGbcWAXH7WMaLgqXfIeTK7KK4/HsGOV1timH
+59yLGn602MnTihdsfSlEvoqq9X46Lmgxk7lq2prg2+kupYTNHAq4Sgj5nPFhJpiTt3tm7JFe3VE/
+23MPrQRYCd0EApUKPtN236YQHoA96M2kZNEzx5LH4k5E4wnJTsJdhw4Snr8PyQUQ3nqjsTzyP6Wq
+J3mtMX0f/fwZacXduT98zca0wjAefm6S139hdlqP65VNvBFuIXxZN5nQBrz5Bm0yFqXZaajh3DyA
+HmBR3NdUIR7KYndP+tiPsys6DXhyyWhBWkdKwqPrGtcKqzwyVcgKEZzfdNbwQBUdyLmPtTbFr/gi
+uMod89a2GQ+fYWVq6nTIfI/DT11lgh/ZDYnadXL77/FHZxOzyNEZiCcmmpl5fx7kLD977vHeTYuW
+l8PVP3wbI+2ksx0WckNLIOFZfsLorSa/ovc=
+-----END CERTIFICATE-----
+
+CA Disig Root R1
+================
+-----BEGIN CERTIFICATE-----
+MIIFaTCCA1GgAwIBAgIJAMMDmu5QkG4oMA0GCSqGSIb3DQEBBQUAMFIxCzAJBgNVBAYTAlNLMRMw
+EQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMuMRkwFwYDVQQDExBDQSBEaXNp
+ZyBSb290IFIxMB4XDTEyMDcxOTA5MDY1NloXDTQyMDcxOTA5MDY1NlowUjELMAkGA1UEBhMCU0sx
+EzARBgNVBAcTCkJyYXRpc2xhdmExEzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERp
+c2lnIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCqw3j33Jijp1pedxiy
+3QRkD2P9m5YJgNXoqqXinCaUOuiZc4yd39ffg/N4T0Dhf9Kn0uXKE5Pn7cZ3Xza1lK/oOI7bm+V8
+u8yN63Vz4STN5qctGS7Y1oprFOsIYgrY3LMATcMjfF9DCCMyEtztDK3AfQ+lekLZWnDZv6fXARz2
+m6uOt0qGeKAeVjGu74IKgEH3G8muqzIm1Cxr7X1r5OJeIgpFy4QxTaz+29FHuvlglzmxZcfe+5nk
+CiKxLU3lSCZpq+Kq8/v8kiky6bM+TR8noc2OuRf7JT7JbvN32g0S9l3HuzYQ1VTW8+DiR0jm3hTa
+YVKvJrT1cU/J19IG32PK/yHoWQbgCNWEFVP3Q+V8xaCJmGtzxmjOZd69fwX3se72V6FglcXM6pM6
+vpmumwKjrckWtc7dXpl4fho5frLABaTAgqWjR56M6ly2vGfb5ipN0gTco65F97yLnByn1tUD3AjL
+LhbKXEAz6GfDLuemROoRRRw1ZS0eRWEkG4IupZ0zXWX4Qfkuy5Q/H6MMMSRE7cderVC6xkGbrPAX
+ZcD4XW9boAo0PO7X6oifmPmvTiT6l7Jkdtqr9O3jw2Dv1fkCyC2fg69naQanMVXVz0tv/wQFx1is
+XxYb5dKj6zHbHzMVTdDypVP1y+E9Tmgt2BLdqvLmTZtJ5cUoobqwWsagtQIDAQABo0IwQDAPBgNV
+HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUiQq0OJMa5qvum5EY+fU8PjXQ
+04IwDQYJKoZIhvcNAQEFBQADggIBADKL9p1Kyb4U5YysOMo6CdQbzoaz3evUuii+Eq5FLAR0rBNR
+xVgYZk2C2tXck8An4b58n1KeElb21Zyp9HWc+jcSjxyT7Ff+Bw+r1RL3D65hXlaASfX8MPWbTx9B
+LxyE04nH4toCdu0Jz2zBuByDHBb6lM19oMgY0sidbvW9adRtPTXoHqJPYNcHKfyyo6SdbhWSVhlM
+CrDpfNIZTUJG7L399ldb3Zh+pE3McgODWF3vkzpBemOqfDqo9ayk0d2iLbYq/J8BjuIQscTK5Gfb
+VSUZP/3oNn6z4eGBrxEWi1CXYBmCAMBrTXO40RMHPuq2MU/wQppt4hF05ZSsjYSVPCGvxdpHyN85
+YmLLW1AL14FABZyb7bq2ix4Eb5YgOe2kfSnbSM6C3NQCjR0EMVrHS/BsYVLXtFHCgWzN4funodKS
+ds+xDzdYpPJScWc/DIh4gInByLUfkmO+p3qKViwaqKactV2zY9ATIKHrkWzQjX2v3wvkF7mGnjix
+lAxYjOBVqjtjbZqJYLhkKpLGN/R+Q0O3c+gB53+XD9fyexn9GtePyfqFa3qdnom2piiZk4hA9z7N
+UaPK6u95RyG1/jLix8NRb76AdPCkwzryT+lf3xkK8jsTQ6wxpLPn6/wY1gGp8yqPNg7rtLG8t0zJ
+a7+h89n07eLw4+1knj0vllJPgFOL
+-----END CERTIFICATE-----
+
+CA Disig Root R2
+================
+-----BEGIN CERTIFICATE-----
+MIIFaTCCA1GgAwIBAgIJAJK4iNuwisFjMA0GCSqGSIb3DQEBCwUAMFIxCzAJBgNVBAYTAlNLMRMw
+EQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMuMRkwFwYDVQQDExBDQSBEaXNp
+ZyBSb290IFIyMB4XDTEyMDcxOTA5MTUzMFoXDTQyMDcxOTA5MTUzMFowUjELMAkGA1UEBhMCU0sx
+EzARBgNVBAcTCkJyYXRpc2xhdmExEzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERp
+c2lnIFJvb3QgUjIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCio8QACdaFXS1tFPbC
+w3OeNcJxVX6B+6tGUODBfEl45qt5WDza/3wcn9iXAng+a0EE6UG9vgMsRfYvZNSrXaNHPWSb6Wia
+xswbP7q+sos0Ai6YVRn8jG+qX9pMzk0DIaPY0jSTVpbLTAwAFjxfGs3Ix2ymrdMxp7zo5eFm1tL7
+A7RBZckQrg4FY8aAamkw/dLukO8NJ9+flXP04SXabBbeQTg06ov80egEFGEtQX6sx3dOy1FU+16S
+GBsEWmjGycT6txOgmLcRK7fWV8x8nhfRyyX+hk4kLlYMeE2eARKmK6cBZW58Yh2EhN/qwGu1pSqV
+g8NTEQxzHQuyRpDRQjrOQG6Vrf/GlK1ul4SOfW+eioANSW1z4nuSHsPzwfPrLgVv2RvPN3YEyLRa
+5Beny912H9AZdugsBbPWnDTYltxhh5EF5EQIM8HauQhl1K6yNg3ruji6DOWbnuuNZt2Zz9aJQfYE
+koopKW1rOhzndX0CcQ7zwOe9yxndnWCywmZgtrEE7snmhrmaZkCo5xHtgUUDi/ZnWejBBhG93c+A
+Ak9lQHhcR1DIm+YfgXvkRKhbhZri3lrVx/k6RGZL5DJUfORsnLMOPReisjQS1n6yqEm70XooQL6i
+Fh/f5DcfEXP7kAplQ6INfPgGAVUzfbANuPT1rqVCV3w2EYx7XsQDnYx5nQIDAQABo0IwQDAPBgNV
+HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUtZn4r7CU9eMg1gqtzk5WpC5u
+Qu0wDQYJKoZIhvcNAQELBQADggIBACYGXnDnZTPIgm7ZnBc6G3pmsgH2eDtpXi/q/075KMOYKmFM
+tCQSin1tERT3nLXK5ryeJ45MGcipvXrA1zYObYVybqjGom32+nNjf7xueQgcnYqfGopTpti72TVV
+sRHFqQOzVju5hJMiXn7B9hJSi+osZ7z+Nkz1uM/Rs0mSO9MpDpkblvdhuDvEK7Z4bLQjb/D907Je
+dR+Zlais9trhxTF7+9FGs9K8Z7RiVLoJ92Owk6Ka+elSLotgEqv89WBW7xBci8QaQtyDW2QOy7W8
+1k/BfDxujRNt+3vrMNDcTa/F1balTFtxyegxvug4BkihGuLq0t4SOVga/4AOgnXmt8kHbA7v/zjx
+mHHEt38OFdAlab0inSvtBfZGR6ztwPDUO+Ls7pZbkBNOHlY667DvlruWIxG68kOGdGSVyCh13x01
+utI3gzhTODY7z2zp+WsO0PsE6E9312UBeIYMej4hYvF/Y3EMyZ9E26gnonW+boE+18DrG5gPcFw0
+sorMwIUY6256s/daoQe/qUKS82Ail+QUoQebTnbAjn39pCXHR+3/H3OszMOl6W8KjptlwlCFtaOg
+UxLMVYdh84GuEEZhvUQhuMI9dM9+JDX6HAcOmz0iyu8xL4ysEr3vQCj8KWefshNPZiTEUxnpHikV
+7+ZtsH8tZ/3zbBt1RqPlShfppNcL
+-----END CERTIFICATE-----
+
+ACCVRAIZ1
+=========
+-----BEGIN CERTIFICATE-----
+MIIH0zCCBbugAwIBAgIIXsO3pkN/pOAwDQYJKoZIhvcNAQEFBQAwQjESMBAGA1UEAwwJQUNDVlJB
+SVoxMRAwDgYDVQQLDAdQS0lBQ0NWMQ0wCwYDVQQKDARBQ0NWMQswCQYDVQQGEwJFUzAeFw0xMTA1
+MDUwOTM3MzdaFw0zMDEyMzEwOTM3MzdaMEIxEjAQBgNVBAMMCUFDQ1ZSQUlaMTEQMA4GA1UECwwH
+UEtJQUNDVjENMAsGA1UECgwEQUNDVjELMAkGA1UEBhMCRVMwggIiMA0GCSqGSIb3DQEBAQUAA4IC
+DwAwggIKAoICAQCbqau/YUqXry+XZpp0X9DZlv3P4uRm7x8fRzPCRKPfmt4ftVTdFXxpNRFvu8gM
+jmoYHtiP2Ra8EEg2XPBjs5BaXCQ316PWywlxufEBcoSwfdtNgM3802/J+Nq2DoLSRYWoG2ioPej0
+RGy9ocLLA76MPhMAhN9KSMDjIgro6TenGEyxCQ0jVn8ETdkXhBilyNpAlHPrzg5XPAOBOp0KoVdD
+aaxXbXmQeOW1tDvYvEyNKKGno6e6Ak4l0Squ7a4DIrhrIA8wKFSVf+DuzgpmndFALW4ir50awQUZ
+0m/A8p/4e7MCQvtQqR0tkw8jq8bBD5L/0KIV9VMJcRz/RROE5iZe+OCIHAr8Fraocwa48GOEAqDG
+WuzndN9wrqODJerWx5eHk6fGioozl2A3ED6XPm4pFdahD9GILBKfb6qkxkLrQaLjlUPTAYVtjrs7
+8yM2x/474KElB0iryYl0/wiPgL/AlmXz7uxLaL2diMMxs0Dx6M/2OLuc5NF/1OVYm3z61PMOm3WR
+5LpSLhl+0fXNWhn8ugb2+1KoS5kE3fj5tItQo05iifCHJPqDQsGH+tUtKSpacXpkatcnYGMN285J
+9Y0fkIkyF/hzQ7jSWpOGYdbhdQrqeWZ2iE9x6wQl1gpaepPluUsXQA+xtrn13k/c4LOsOxFwYIRK
+Q26ZIMApcQrAZQIDAQABo4ICyzCCAscwfQYIKwYBBQUHAQEEcTBvMEwGCCsGAQUFBzAChkBodHRw
+Oi8vd3d3LmFjY3YuZXMvZmlsZWFkbWluL0FyY2hpdm9zL2NlcnRpZmljYWRvcy9yYWl6YWNjdjEu
+Y3J0MB8GCCsGAQUFBzABhhNodHRwOi8vb2NzcC5hY2N2LmVzMB0GA1UdDgQWBBTSh7Tj3zcnk1X2
+VuqB5TbMjB4/vTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNKHtOPfNyeTVfZW6oHlNsyM
+Hj+9MIIBcwYDVR0gBIIBajCCAWYwggFiBgRVHSAAMIIBWDCCASIGCCsGAQUFBwICMIIBFB6CARAA
+QQB1AHQAbwByAGkAZABhAGQAIABkAGUAIABDAGUAcgB0AGkAZgBpAGMAYQBjAGkA8wBuACAAUgBh
+AO0AegAgAGQAZQAgAGwAYQAgAEEAQwBDAFYAIAAoAEEAZwBlAG4AYwBpAGEAIABkAGUAIABUAGUA
+YwBuAG8AbABvAGcA7QBhACAAeQAgAEMAZQByAHQAaQBmAGkAYwBhAGMAaQDzAG4AIABFAGwAZQBj
+AHQAcgDzAG4AaQBjAGEALAAgAEMASQBGACAAUQA0ADYAMAAxADEANQA2AEUAKQAuACAAQwBQAFMA
+IABlAG4AIABoAHQAdABwADoALwAvAHcAdwB3AC4AYQBjAGMAdgAuAGUAczAwBggrBgEFBQcCARYk
+aHR0cDovL3d3dy5hY2N2LmVzL2xlZ2lzbGFjaW9uX2MuaHRtMFUGA1UdHwROMEwwSqBIoEaGRGh0
+dHA6Ly93d3cuYWNjdi5lcy9maWxlYWRtaW4vQXJjaGl2b3MvY2VydGlmaWNhZG9zL3JhaXphY2N2
+MV9kZXIuY3JsMA4GA1UdDwEB/wQEAwIBBjAXBgNVHREEEDAOgQxhY2N2QGFjY3YuZXMwDQYJKoZI
+hvcNAQEFBQADggIBAJcxAp/n/UNnSEQU5CmH7UwoZtCPNdpNYbdKl02125DgBS4OxnnQ8pdpD70E
+R9m+27Up2pvZrqmZ1dM8MJP1jaGo/AaNRPTKFpV8M9xii6g3+CfYCS0b78gUJyCpZET/LtZ1qmxN
+YEAZSUNUY9rizLpm5U9EelvZaoErQNV/+QEnWCzI7UiRfD+mAM/EKXMRNt6GGT6d7hmKG9Ww7Y49
+nCrADdg9ZuM8Db3VlFzi4qc1GwQA9j9ajepDvV+JHanBsMyZ4k0ACtrJJ1vnE5Bc5PUzolVt3OAJ
+TS+xJlsndQAJxGJ3KQhfnlmstn6tn1QwIgPBHnFk/vk4CpYY3QIUrCPLBhwepH2NDd4nQeit2hW3
+sCPdK6jT2iWH7ehVRE2I9DZ+hJp4rPcOVkkO1jMl1oRQQmwgEh0q1b688nCBpHBgvgW1m54ERL5h
+I6zppSSMEYCUWqKiuUnSwdzRp+0xESyeGabu4VXhwOrPDYTkF7eifKXeVSUG7szAh1xA2syVP1Xg
+Nce4hL60Xc16gwFy7ofmXx2utYXGJt/mwZrpHgJHnyqobalbz+xFd3+YJ5oyXSrjhO7FmGYvliAd
+3djDJ9ew+f7Zfc3Qn48LFFhRny+Lwzgt3uiP1o2HpPVWQxaZLPSkVrQ0uGE3ycJYgBugl6H8WY3p
+EfbRD0tVNEYqi4Y7
+-----END CERTIFICATE-----
+
+TWCA Global Root CA
+===================
+-----BEGIN CERTIFICATE-----
+MIIFQTCCAymgAwIBAgICDL4wDQYJKoZIhvcNAQELBQAwUTELMAkGA1UEBhMCVFcxEjAQBgNVBAoT
+CVRBSVdBTi1DQTEQMA4GA1UECxMHUm9vdCBDQTEcMBoGA1UEAxMTVFdDQSBHbG9iYWwgUm9vdCBD
+QTAeFw0xMjA2MjcwNjI4MzNaFw0zMDEyMzExNTU5NTlaMFExCzAJBgNVBAYTAlRXMRIwEAYDVQQK
+EwlUQUlXQU4tQ0ExEDAOBgNVBAsTB1Jvb3QgQ0ExHDAaBgNVBAMTE1RXQ0EgR2xvYmFsIFJvb3Qg
+Q0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCwBdvI64zEbooh745NnHEKH1Jw7W2C
+nJfF10xORUnLQEK1EjRsGcJ0pDFfhQKX7EMzClPSnIyOt7h52yvVavKOZsTuKwEHktSz0ALfUPZV
+r2YOy+BHYC8rMjk1Ujoog/h7FsYYuGLWRyWRzvAZEk2tY/XTP3VfKfChMBwqoJimFb3u/Rk28OKR
+Q4/6ytYQJ0lM793B8YVwm8rqqFpD/G2Gb3PpN0Wp8DbHzIh1HrtsBv+baz4X7GGqcXzGHaL3SekV
+tTzWoWH1EfcFbx39Eb7QMAfCKbAJTibc46KokWofwpFFiFzlmLhxpRUZyXx1EcxwdE8tmx2RRP1W
+KKD+u4ZqyPpcC1jcxkt2yKsi2XMPpfRaAok/T54igu6idFMqPVMnaR1sjjIsZAAmY2E2TqNGtz99
+sy2sbZCilaLOz9qC5wc0GZbpuCGqKX6mOL6OKUohZnkfs8O1CWfe1tQHRvMq2uYiN2DLgbYPoA/p
+yJV/v1WRBXrPPRXAb94JlAGD1zQbzECl8LibZ9WYkTunhHiVJqRaCPgrdLQABDzfuBSO6N+pjWxn
+kjMdwLfS7JLIvgm/LCkFbwJrnu+8vyq8W8BQj0FwcYeyTbcEqYSjMq+u7msXi7Kx/mzhkIyIqJdI
+zshNy/MGz19qCkKxHh53L46g5pIOBvwFItIm4TFRfTLcDwIDAQABoyMwITAOBgNVHQ8BAf8EBAMC
+AQYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAXzSBdu+WHdXltdkCY4QWwa6g
+cFGn90xHNcgL1yg9iXHZqjNB6hQbbCEAwGxCGX6faVsgQt+i0trEfJdLjbDorMjupWkEmQqSpqsn
+LhpNgb+E1HAerUf+/UqdM+DyucRFCCEK2mlpc3INvjT+lIutwx4116KD7+U4x6WFH6vPNOw/KP4M
+8VeGTslV9xzU2KV9Bnpv1d8Q34FOIWWxtuEXeZVFBs5fzNxGiWNoRI2T9GRwoD2dKAXDOXC4Ynsg
+/eTb6QihuJ49CcdP+yz4k3ZB3lLg4VfSnQO8d57+nile98FRYB/e2guyLXW3Q0iT5/Z5xoRdgFlg
+lPx4mI88k1HtQJAH32RjJMtOcQWh15QaiDLxInQirqWm2BJpTGCjAu4r7NRjkgtevi92a6O2JryP
+A9gK8kxkRr05YuWW6zRjESjMlfGt7+/cgFhI6Uu46mWs6fyAtbXIRfmswZ/ZuepiiI7E8UuDEq3m
+i4TWnsLrgxifarsbJGAzcMzs9zLzXNl5fe+epP7JI8Mk7hWSsT2RTyaGvWZzJBPqpK5jwa19hAM8
+EHiGG3njxPPyBJUgriOCxLM6AGK/5jYk4Ve6xx6QddVfP5VhK8E7zeWzaGHQRiapIVJpLesux+t3
+zqY6tQMzT3bR51xUAV3LePTJDL/PEo4XLSNolOer/qmyKwbQBM0=
+-----END CERTIFICATE-----
+
+TeliaSonera Root CA v1
+======================
+-----BEGIN CERTIFICATE-----
+MIIFODCCAyCgAwIBAgIRAJW+FqD3LkbxezmCcvqLzZYwDQYJKoZIhvcNAQEFBQAwNzEUMBIGA1UE
+CgwLVGVsaWFTb25lcmExHzAdBgNVBAMMFlRlbGlhU29uZXJhIFJvb3QgQ0EgdjEwHhcNMDcxMDE4
+MTIwMDUwWhcNMzIxMDE4MTIwMDUwWjA3MRQwEgYDVQQKDAtUZWxpYVNvbmVyYTEfMB0GA1UEAwwW
+VGVsaWFTb25lcmEgUm9vdCBDQSB2MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMK+
+6yfwIaPzaSZVfp3FVRaRXP3vIb9TgHot0pGMYzHw7CTww6XScnwQbfQ3t+XmfHnqjLWCi65ItqwA
+3GV17CpNX8GH9SBlK4GoRz6JI5UwFpB/6FcHSOcZrr9FZ7E3GwYq/t75rH2D+1665I+XZ75Ljo1k
+B1c4VWk0Nj0TSO9P4tNmHqTPGrdeNjPUtAa9GAH9d4RQAEX1jF3oI7x+/jXh7VB7qTCNGdMJjmhn
+Xb88lxhTuylixcpecsHHltTbLaC0H2kD7OriUPEMPPCs81Mt8Bz17Ww5OXOAFshSsCPN4D7c3TxH
+oLs1iuKYaIu+5b9y7tL6pe0S7fyYGKkmdtwoSxAgHNN/Fnct7W+A90m7UwW7XWjH1Mh1Fj+JWov3
+F0fUTPHSiXk+TT2YqGHeOh7S+F4D4MHJHIzTjU3TlTazN19jY5szFPAtJmtTfImMMsJu7D0hADnJ
+oWjiUIMusDor8zagrC/kb2HCUQk5PotTubtn2txTuXZZNp1D5SDgPTJghSJRt8czu90VL6R4pgd7
+gUY2BIbdeTXHlSw7sKMXNeVzH7RcWe/a6hBle3rQf5+ztCo3O3CLm1u5K7fsslESl1MpWtTwEhDc
+TwK7EpIvYtQ/aUN8Ddb8WHUBiJ1YFkveupD/RwGJBmr2X7KQarMCpgKIv7NHfirZ1fpoeDVNAgMB
+AAGjPzA9MA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBTwj1k4ALP1j5qW
+DNXr+nuqF+gTEjANBgkqhkiG9w0BAQUFAAOCAgEAvuRcYk4k9AwI//DTDGjkk0kiP0Qnb7tt3oNm
+zqjMDfz1mgbldxSR651Be5kqhOX//CHBXfDkH1e3damhXwIm/9fH907eT/j3HEbAek9ALCI18Bmx
+0GtnLLCo4MBANzX2hFxc469CeP6nyQ1Q6g2EdvZR74NTxnr/DlZJLo961gzmJ1TjTQpgcmLNkQfW
+pb/ImWvtxBnmq0wROMVvMeJuScg/doAmAyYp4Db29iBT4xdwNBedY2gea+zDTYa4EzAvXUYNR0PV
+G6pZDrlcjQZIrXSHX8f8MVRBE+LHIQ6e4B4N4cB7Q4WQxYpYxmUKeFfyxiMPAdkgS94P+5KFdSpc
+c41teyWRyu5FrgZLAMzTsVlQ2jqIOylDRl6XK1TOU2+NSueW+r9xDkKLfP0ooNBIytrEgUy7onOT
+JsjrDNYmiLbAJM+7vVvrdX3pCI6GMyx5dwlppYn8s3CQh3aP0yK7Qs69cwsgJirQmz1wHiRszYd2
+qReWt88NkvuOGKmYSdGe/mBEciG5Ge3C9THxOUiIkCR1VBatzvT4aRRkOfujuLpwQMcnHL/EVlP6
+Y2XQ8xwOFvVrhlhNGNTkDY6lnVuR3HYkUD/GKvvZt5y11ubQ2egZixVxSK236thZiNSQvxaz2ems
+WWFUyBy6ysHK4bkgTI86k4mloMy/0/Z1pHWWbVY=
+-----END CERTIFICATE-----
+
+E-Tugra Certification Authority
+===============================
+-----BEGIN CERTIFICATE-----
+MIIGSzCCBDOgAwIBAgIIamg+nFGby1MwDQYJKoZIhvcNAQELBQAwgbIxCzAJBgNVBAYTAlRSMQ8w
+DQYDVQQHDAZBbmthcmExQDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamls
+ZXJpIHZlIEhpem1ldGxlcmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBN
+ZXJrZXppMSgwJgYDVQQDDB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTEzMDMw
+NTEyMDk0OFoXDTIzMDMwMzEyMDk0OFowgbIxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmEx
+QDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhpem1ldGxl
+cmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBNZXJrZXppMSgwJgYDVQQD
+DB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEFAAOCAg8A
+MIICCgKCAgEA4vU/kwVRHoViVF56C/UYB4Oufq9899SKa6VjQzm5S/fDxmSJPZQuVIBSOTkHS0vd
+hQd2h8y/L5VMzH2nPbxHD5hw+IyFHnSOkm0bQNGZDbt1bsipa5rAhDGvykPL6ys06I+XawGb1Q5K
+CKpbknSFQ9OArqGIW66z6l7LFpp3RMih9lRozt6Plyu6W0ACDGQXwLWTzeHxE2bODHnv0ZEoq1+g
+ElIwcxmOj+GMB6LDu0rw6h8VqO4lzKRG+Bsi77MOQ7osJLjFLFzUHPhdZL3Dk14opz8n8Y4e0ypQ
+BaNV2cvnOVPAmJ6MVGKLJrD3fY185MaeZkJVgkfnsliNZvcHfC425lAcP9tDJMW/hkd5s3kc91r0
+E+xs+D/iWR+V7kI+ua2oMoVJl0b+SzGPWsutdEcf6ZG33ygEIqDUD13ieU/qbIWGvaimzuT6w+Gz
+rt48Ue7LE3wBf4QOXVGUnhMMti6lTPk5cDZvlsouDERVxcr6XQKj39ZkjFqzAQqptQpHF//vkUAq
+jqFGOjGY5RH8zLtJVor8udBhmm9lbObDyz51Sf6Pp+KJxWfXnUYTTjF2OySznhFlhqt/7x3U+Lzn
+rFpct1pHXFXOVbQicVtbC/DP3KBhZOqp12gKY6fgDT+gr9Oq0n7vUaDmUStVkhUXU8u3Zg5mTPj5
+dUyQ5xJwx0UCAwEAAaNjMGEwHQYDVR0OBBYEFC7j27JJ0JxUeVz6Jyr+zE7S6E5UMA8GA1UdEwEB
+/wQFMAMBAf8wHwYDVR0jBBgwFoAULuPbsknQnFR5XPonKv7MTtLoTlQwDgYDVR0PAQH/BAQDAgEG
+MA0GCSqGSIb3DQEBCwUAA4ICAQAFNzr0TbdF4kV1JI+2d1LoHNgQk2Xz8lkGpD4eKexd0dCrfOAK
+kEh47U6YA5n+KGCRHTAduGN8qOY1tfrTYXbm1gdLymmasoR6d5NFFxWfJNCYExL/u6Au/U5Mh/jO
+XKqYGwXgAEZKgoClM4so3O0409/lPun++1ndYYRP0lSWE2ETPo+Aab6TR7U1Q9Jauz1c77NCR807
+VRMGsAnb/WP2OogKmW9+4c4bU2pEZiNRCHu8W1Ki/QY3OEBhj0qWuJA3+GbHeJAAFS6LrVE1Uweo
+a2iu+U48BybNCAVwzDk/dr2l02cmAYamU9JgO3xDf1WKvJUawSg5TB9D0pH0clmKuVb8P7Sd2nCc
+dlqMQ1DujjByTd//SffGqWfZbawCEeI6FiWnWAjLb1NBnEg4R2gz0dfHj9R0IdTDBZB6/86WiLEV
+KV0jq9BgoRJP3vQXzTLlyb/IQ639Lo7xr+L0mPoSHyDYwKcMhcWQ9DstliaxLL5Mq+ux0orJ23gT
+Dx4JnW2PAJ8C2sH6H3p6CcRK5ogql5+Ji/03X186zjhZhkuvcQu02PJwT58yE+Owp1fl2tpDy4Q0
+8ijE6m30Ku/Ba3ba+367hTzSU8JNvnHhRdH9I2cNE3X7z2VnIp2usAnRCf8dNL/+I5c30jn6PQ0G
+C7TbO6Orb1wdtn7os4I07QZcJA==
+-----END CERTIFICATE-----
+
+T-TeleSec GlobalRoot Class 2
+============================
+-----BEGIN CERTIFICATE-----
+MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoM
+IlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBU
+cnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwHhcNMDgx
+MDAxMTA0MDE0WhcNMzMxMDAxMjM1OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lz
+dGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBD
+ZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwggEiMA0GCSqGSIb3
+DQEBAQUAA4IBDwAwggEKAoIBAQCqX9obX+hzkeXaXPSi5kfl82hVYAUdAqSzm1nzHoqvNK38DcLZ
+SBnuaY/JIPwhqgcZ7bBcrGXHX+0CfHt8LRvWurmAwhiCFoT6ZrAIxlQjgeTNuUk/9k9uN0goOA/F
+vudocP05l03Sx5iRUKrERLMjfTlH6VJi1hKTXrcxlkIF+3anHqP1wvzpesVsqXFP6st4vGCvx970
+2cu+fjOlbpSD8DT6IavqjnKgP6TeMFvvhk1qlVtDRKgQFRzlAVfFmPHmBiiRqiDFt1MmUUOyCxGV
+WOHAD3bZwI18gfNycJ5v/hqO2V81xrJvNHy+SE/iWjnX2J14np+GPgNeGYtEotXHAgMBAAGjQjBA
+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS/WSA2AHmgoCJrjNXy
+YdK4LMuCSjANBgkqhkiG9w0BAQsFAAOCAQEAMQOiYQsfdOhyNsZt+U2e+iKo4YFWz827n+qrkRk4
+r6p8FU3ztqONpfSO9kSpp+ghla0+AGIWiPACuvxhI+YzmzB6azZie60EI4RYZeLbK4rnJVM3YlNf
+vNoBYimipidx5joifsFvHZVwIEoHNN/q/xWA5brXethbdXwFeilHfkCoMRN3zUA7tFFHei4R40cR
+3p1m0IvVVGb6g1XqfMIpiRvpb7PO4gWEyS8+eIVibslfwXhjdFjASBgMmTnrpMwatXlajRWc2BQN
+9noHV8cigwUtPJslJj0Ys6lDfMjIq2SPDqO/nBudMNva0Bkuqjzx+zOAduTNrRlPBSeOE6Fuwg==
+-----END CERTIFICATE-----
+
+Atos TrustedRoot 2011
+=====================
+-----BEGIN CERTIFICATE-----
+MIIDdzCCAl+gAwIBAgIIXDPLYixfszIwDQYJKoZIhvcNAQELBQAwPDEeMBwGA1UEAwwVQXRvcyBU
+cnVzdGVkUm9vdCAyMDExMQ0wCwYDVQQKDARBdG9zMQswCQYDVQQGEwJERTAeFw0xMTA3MDcxNDU4
+MzBaFw0zMDEyMzEyMzU5NTlaMDwxHjAcBgNVBAMMFUF0b3MgVHJ1c3RlZFJvb3QgMjAxMTENMAsG
+A1UECgwEQXRvczELMAkGA1UEBhMCREUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCV
+hTuXbyo7LjvPpvMpNb7PGKw+qtn4TaA+Gke5vJrf8v7MPkfoepbCJI419KkM/IL9bcFyYie96mvr
+54rMVD6QUM+A1JX76LWC1BTFtqlVJVfbsVD2sGBkWXppzwO3bw2+yj5vdHLqqjAqc2K+SZFhyBH+
+DgMq92og3AIVDV4VavzjgsG1xZ1kCWyjWZgHJ8cblithdHFsQ/H3NYkQ4J7sVaE3IqKHBAUsR320
+HLliKWYoyrfhk/WklAOZuXCFteZI6o1Q/NnezG8HDt0Lcp2AMBYHlT8oDv3FdU9T1nSatCQujgKR
+z3bFmx5VdJx4IbHwLfELn8LVlhgf8FQieowHAgMBAAGjfTB7MB0GA1UdDgQWBBSnpQaxLKYJYO7R
+l+lwrrw7GWzbITAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKelBrEspglg7tGX6XCuvDsZ
+bNshMBgGA1UdIAQRMA8wDQYLKwYBBAGwLQMEAQEwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEB
+CwUAA4IBAQAmdzTblEiGKkGdLD4GkGDEjKwLVLgfuXvTBznk+j57sj1O7Z8jvZfza1zv7v1Apt+h
+k6EKhqzvINB5Ab149xnYJDE0BAGmuhWawyfc2E8PzBhj/5kPDpFrdRbhIfzYJsdHt6bPWHJxfrrh
+TZVHO8mvbaG0weyJ9rQPOLXiZNwlz6bb65pcmaHFCN795trV1lpFDMS3wrUU77QR/w4VtfX128a9
+61qn8FYiqTxlVMYVqL2Gns2Dlmh6cYGJ4Qvh6hEbaAjMaZ7snkGeRDImeuKHCnE96+RapNLbxc3G
+3mB/ufNPRJLvKrcYPqcZ2Qt9sTdBQrC6YB3y/gkRsPCHe6ed
+-----END CERTIFICATE-----
+
+QuoVadis Root CA 1 G3
+=====================
+-----BEGIN CERTIFICATE-----
+MIIFYDCCA0igAwIBAgIUeFhfLq0sGUvjNwc1NBMotZbUZZMwDQYJKoZIhvcNAQELBQAwSDELMAkG
+A1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAcBgNVBAMTFVF1b1ZhZGlzIFJv
+b3QgQ0EgMSBHMzAeFw0xMjAxMTIxNzI3NDRaFw00MjAxMTIxNzI3NDRaMEgxCzAJBgNVBAYTAkJN
+MRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDEg
+RzMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCgvlAQjunybEC0BJyFuTHK3C3kEakE
+PBtVwedYMB0ktMPvhd6MLOHBPd+C5k+tR4ds7FtJwUrVu4/sh6x/gpqG7D0DmVIB0jWerNrwU8lm
+PNSsAgHaJNM7qAJGr6Qc4/hzWHa39g6QDbXwz8z6+cZM5cOGMAqNF34168Xfuw6cwI2H44g4hWf6
+Pser4BOcBRiYz5P1sZK0/CPTz9XEJ0ngnjybCKOLXSoh4Pw5qlPafX7PGglTvF0FBM+hSo+LdoIN
+ofjSxxR3W5A2B4GbPgb6Ul5jxaYA/qXpUhtStZI5cgMJYr2wYBZupt0lwgNm3fME0UDiTouG9G/l
+g6AnhF4EwfWQvTA9xO+oabw4m6SkltFi2mnAAZauy8RRNOoMqv8hjlmPSlzkYZqn0ukqeI1RPToV
+7qJZjqlc3sX5kCLliEVx3ZGZbHqfPT2YfF72vhZooF6uCyP8Wg+qInYtyaEQHeTTRCOQiJ/GKubX
+9ZqzWB4vMIkIG1SitZgj7Ah3HJVdYdHLiZxfokqRmu8hqkkWCKi9YSgxyXSthfbZxbGL0eUQMk1f
+iyA6PEkfM4VZDdvLCXVDaXP7a3F98N/ETH3Goy7IlXnLc6KOTk0k+17kBL5yG6YnLUlamXrXXAkg
+t3+UuU/xDRxeiEIbEbfnkduebPRq34wGmAOtzCjvpUfzUwIDAQABo0IwQDAPBgNVHRMBAf8EBTAD
+AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUo5fW816iEOGrRZ88F2Q87gFwnMwwDQYJKoZI
+hvcNAQELBQADggIBABj6W3X8PnrHX3fHyt/PX8MSxEBd1DKquGrX1RUVRpgjpeaQWxiZTOOtQqOC
+MTaIzen7xASWSIsBx40Bz1szBpZGZnQdT+3Btrm0DWHMY37XLneMlhwqI2hrhVd2cDMT/uFPpiN3
+GPoajOi9ZcnPP/TJF9zrx7zABC4tRi9pZsMbj/7sPtPKlL92CiUNqXsCHKnQO18LwIE6PWThv6ct
+Tr1NxNgpxiIY0MWscgKCP6o6ojoilzHdCGPDdRS5YCgtW2jgFqlmgiNR9etT2DGbe+m3nUvriBbP
++V04ikkwj+3x6xn0dxoxGE1nVGwvb2X52z3sIexe9PSLymBlVNFxZPT5pqOBMzYzcfCkeF9OrYMh
+3jRJjehZrJ3ydlo28hP0r+AJx2EqbPfgna67hkooby7utHnNkDPDs3b69fBsnQGQ+p6Q9pxyz0fa
+wx/kNSBT8lTR32GDpgLiJTjehTItXnOQUl1CxM49S+H5GYQd1aJQzEH7QRTDvdbJWqNjZgKAvQU6
+O0ec7AAmTPWIUb+oI38YB7AL7YsmoWTTYUrrXJ/es69nA7Mf3W1daWhpq1467HxpvMc7hU6eFbm0
+FU/DlXpY18ls6Wy58yljXrQs8C097Vpl4KlbQMJImYFtnh8GKjwStIsPm6Ik8KaN1nrgS7ZklmOV
+hMJKzRwuJIczYOXD
+-----END CERTIFICATE-----
+
+QuoVadis Root CA 2 G3
+=====================
+-----BEGIN CERTIFICATE-----
+MIIFYDCCA0igAwIBAgIURFc0JFuBiZs18s64KztbpybwdSgwDQYJKoZIhvcNAQELBQAwSDELMAkG
+A1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAcBgNVBAMTFVF1b1ZhZGlzIFJv
+b3QgQ0EgMiBHMzAeFw0xMjAxMTIxODU5MzJaFw00MjAxMTIxODU5MzJaMEgxCzAJBgNVBAYTAkJN
+MRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDIg
+RzMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQChriWyARjcV4g/Ruv5r+LrI3HimtFh
+ZiFfqq8nUeVuGxbULX1QsFN3vXg6YOJkApt8hpvWGo6t/x8Vf9WVHhLL5hSEBMHfNrMWn4rjyduY
+NM7YMxcoRvynyfDStNVNCXJJ+fKH46nafaF9a7I6JaltUkSs+L5u+9ymc5GQYaYDFCDy54ejiK2t
+oIz/pgslUiXnFgHVy7g1gQyjO/Dh4fxaXc6AcW34Sas+O7q414AB+6XrW7PFXmAqMaCvN+ggOp+o
+MiwMzAkd056OXbxMmO7FGmh77FOm6RQ1o9/NgJ8MSPsc9PG/Srj61YxxSscfrf5BmrODXfKEVu+l
+V0POKa2Mq1W/xPtbAd0jIaFYAI7D0GoT7RPjEiuA3GfmlbLNHiJuKvhB1PLKFAeNilUSxmn1uIZo
+L1NesNKqIcGY5jDjZ1XHm26sGahVpkUG0CM62+tlXSoREfA7T8pt9DTEceT/AFr2XK4jYIVz8eQQ
+sSWu1ZK7E8EM4DnatDlXtas1qnIhO4M15zHfeiFuuDIIfR0ykRVKYnLP43ehvNURG3YBZwjgQQvD
+6xVu+KQZ2aKrr+InUlYrAoosFCT5v0ICvybIxo/gbjh9Uy3l7ZizlWNof/k19N+IxWA1ksB8aRxh
+lRbQ694Lrz4EEEVlWFA4r0jyWbYW8jwNkALGcC4BrTwV1wIDAQABo0IwQDAPBgNVHRMBAf8EBTAD
+AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQU7edvdlq/YOxJW8ald7tyFnGbxD0wDQYJKoZI
+hvcNAQELBQADggIBAJHfgD9DCX5xwvfrs4iP4VGyvD11+ShdyLyZm3tdquXK4Qr36LLTn91nMX66
+AarHakE7kNQIXLJgapDwyM4DYvmL7ftuKtwGTTwpD4kWilhMSA/ohGHqPHKmd+RCroijQ1h5fq7K
+pVMNqT1wvSAZYaRsOPxDMuHBR//47PERIjKWnML2W2mWeyAMQ0GaW/ZZGYjeVYg3UQt4XAoeo0L9
+x52ID8DyeAIkVJOviYeIyUqAHerQbj5hLja7NQ4nlv1mNDthcnPxFlxHBlRJAHpYErAK74X9sbgz
+dWqTHBLmYF5vHX/JHyPLhGGfHoJE+V+tYlUkmlKY7VHnoX6XOuYvHxHaU4AshZ6rNRDbIl9qxV6X
+U/IyAgkwo1jwDQHVcsaxfGl7w/U2Rcxhbl5MlMVerugOXou/983g7aEOGzPuVBj+D77vfoRrQ+Nw
+mNtddbINWQeFFSM51vHfqSYP1kjHs6Yi9TM3WpVHn3u6GBVv/9YUZINJ0gpnIdsPNWNgKCLjsZWD
+zYWm3S8P52dSbrsvhXz1SnPnxT7AvSESBT/8twNJAlvIJebiVDj1eYeMHVOyToV7BjjHLPj4sHKN
+JeV3UvQDHEimUF+IIDBu8oJDqz2XhOdT+yHBTw8imoa4WSr2Rz0ZiC3oheGe7IUIarFsNMkd7Egr
+O3jtZsSOeWmD3n+M
+-----END CERTIFICATE-----
+
+QuoVadis Root CA 3 G3
+=====================
+-----BEGIN CERTIFICATE-----
+MIIFYDCCA0igAwIBAgIULvWbAiin23r/1aOp7r0DoM8Sah0wDQYJKoZIhvcNAQELBQAwSDELMAkG
+A1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAcBgNVBAMTFVF1b1ZhZGlzIFJv
+b3QgQ0EgMyBHMzAeFw0xMjAxMTIyMDI2MzJaFw00MjAxMTIyMDI2MzJaMEgxCzAJBgNVBAYTAkJN
+MRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDMg
+RzMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCzyw4QZ47qFJenMioKVjZ/aEzHs286
+IxSR/xl/pcqs7rN2nXrpixurazHb+gtTTK/FpRp5PIpM/6zfJd5O2YIyC0TeytuMrKNuFoM7pmRL
+Mon7FhY4futD4tN0SsJiCnMK3UmzV9KwCoWdcTzeo8vAMvMBOSBDGzXRU7Ox7sWTaYI+FrUoRqHe
+6okJ7UO4BUaKhvVZR74bbwEhELn9qdIoyhA5CcoTNs+cra1AdHkrAj80//ogaX3T7mH1urPnMNA3
+I4ZyYUUpSFlob3emLoG+B01vr87ERRORFHAGjx+f+IdpsQ7vw4kZ6+ocYfx6bIrc1gMLnia6Et3U
+VDmrJqMz6nWB2i3ND0/kA9HvFZcba5DFApCTZgIhsUfei5pKgLlVj7WiL8DWM2fafsSntARE60f7
+5li59wzweyuxwHApw0BiLTtIadwjPEjrewl5qW3aqDCYz4ByA4imW0aucnl8CAMhZa634RylsSqi
+Md5mBPfAdOhx3v89WcyWJhKLhZVXGqtrdQtEPREoPHtht+KPZ0/l7DxMYIBpVzgeAVuNVejH38DM
+dyM0SXV89pgR6y3e7UEuFAUCf+D+IOs15xGsIs5XPd7JMG0QA4XN8f+MFrXBsj6IbGB/kE+V9/Yt
+rQE5BwT6dYB9v0lQ7e/JxHwc64B+27bQ3RP+ydOc17KXqQIDAQABo0IwQDAPBgNVHRMBAf8EBTAD
+AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUxhfQvKjqAkPyGwaZXSuQILnXnOQwDQYJKoZI
+hvcNAQELBQADggIBADRh2Va1EodVTd2jNTFGu6QHcrxfYWLopfsLN7E8trP6KZ1/AvWkyaiTt3px
+KGmPc+FSkNrVvjrlt3ZqVoAh313m6Tqe5T72omnHKgqwGEfcIHB9UqM+WXzBusnIFUBhynLWcKzS
+t/Ac5IYp8M7vaGPQtSCKFWGafoaYtMnCdvvMujAWzKNhxnQT5WvvoxXqA/4Ti2Tk08HS6IT7SdEQ
+TXlm66r99I0xHnAUrdzeZxNMgRVhvLfZkXdxGYFgu/BYpbWcC/ePIlUnwEsBbTuZDdQdm2NnL9Du
+DcpmvJRPpq3t/O5jrFc/ZSXPsoaP0Aj/uHYUbt7lJ+yreLVTubY/6CD50qi+YUbKh4yE8/nxoGib
+Ih6BJpsQBJFxwAYf3KDTuVan45gtf4Od34wrnDKOMpTwATwiKp9Dwi7DmDkHOHv8XgBCH/MyJnmD
+hPbl8MFREsALHgQjDFSlTC9JxUrRtm5gDWv8a4uFJGS3iQ6rJUdbPM9+Sb3H6QrG2vd+DhcI00iX
+0HGS8A85PjRqHH3Y8iKuu2n0M7SmSFXRDw4m6Oy2Cy2nhTXN/VnIn9HNPlopNLk9hM6xZdRZkZFW
+dSHBd575euFgndOtBBj0fOtek49TSiIp+EgrPk2GrFt/ywaZWWDYWGWVjUTR939+J399roD1B0y2
+PpxxVJkES/1Y+Zj0
+-----END CERTIFICATE-----
+
+DigiCert Assured ID Root G2
+===========================
+-----BEGIN CERTIFICATE-----
+MIIDljCCAn6gAwIBAgIQC5McOtY5Z+pnI7/Dr5r0SzANBgkqhkiG9w0BAQsFADBlMQswCQYDVQQG
+EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQw
+IgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIwHhcNMTMwODAxMTIwMDAwWhcNMzgw
+MTE1MTIwMDAwWjBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQL
+ExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIw
+ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ5ygvUj82ckmIkzTz+GoeMVSAn61UQbVH
+35ao1K+ALbkKz3X9iaV9JPrjIgwrvJUXCzO/GU1BBpAAvQxNEP4HteccbiJVMWWXvdMX0h5i89vq
+bFCMP4QMls+3ywPgym2hFEwbid3tALBSfK+RbLE4E9HpEgjAALAcKxHad3A2m67OeYfcgnDmCXRw
+VWmvo2ifv922ebPynXApVfSr/5Vh88lAbx3RvpO704gqu52/clpWcTs/1PPRCv4o76Pu2ZmvA9OP
+YLfykqGxvYmJHzDNw6YuYjOuFgJ3RFrngQo8p0Quebg/BLxcoIfhG69Rjs3sLPr4/m3wOnyqi+Rn
+lTGNAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBTO
+w0q5mVXyuNtgv6l+vVa1lzan1jANBgkqhkiG9w0BAQsFAAOCAQEAyqVVjOPIQW5pJ6d1Ee88hjZv
+0p3GeDgdaZaikmkuOGybfQTUiaWxMTeKySHMq2zNixya1r9I0jJmwYrA8y8678Dj1JGG0VDjA9tz
+d29KOVPt3ibHtX2vK0LRdWLjSisCx1BL4GnilmwORGYQRI+tBev4eaymG+g3NJ1TyWGqolKvSnAW
+hsI6yLETcDbYz+70CjTVW0z9B5yiutkBclzzTcHdDrEcDcRjvq30FPuJ7KJBDkzMyFdA0G4Dqs0M
+jomZmWzwPDCvON9vvKO+KSAnq3T/EyJ43pdSVR6DtVQgA+6uwE9W3jfMw3+qBCe703e4YtsXfJwo
+IhNzbM8m9Yop5w==
+-----END CERTIFICATE-----
+
+DigiCert Assured ID Root G3
+===========================
+-----BEGIN CERTIFICATE-----
+MIICRjCCAc2gAwIBAgIQC6Fa+h3foLVJRK/NJKBs7DAKBggqhkjOPQQDAzBlMQswCQYDVQQGEwJV
+UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQwIgYD
+VQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1
+MTIwMDAwWjBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwdjAQ
+BgcqhkjOPQIBBgUrgQQAIgNiAAQZ57ysRGXtzbg/WPuNsVepRC0FFfLvC/8QdJ+1YlJfZn4f5dwb
+RXkLzMZTCp2NXQLZqVneAlr2lSoOjThKiknGvMYDOAdfVdp+CW7if17QRSAPWXYQ1qAk8C3eNvJs
+KTmjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBTL0L2p4ZgF
+UaFNN6KDec6NHSrkhDAKBggqhkjOPQQDAwNnADBkAjAlpIFFAmsSS3V0T8gj43DydXLefInwz5Fy
+YZ5eEJJZVrmDxxDnOOlYJjZ91eQ0hjkCMHw2U/Aw5WJjOpnitqM7mzT6HtoQknFekROn3aRukswy
+1vUhZscv6pZjamVFkpUBtA==
+-----END CERTIFICATE-----
+
+DigiCert Global Root G2
+=======================
+-----BEGIN CERTIFICATE-----
+MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBhMQswCQYDVQQG
+EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAw
+HgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUx
+MjAwMDBaMGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3
+dy5kaWdpY2VydC5jb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkq
+hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI2/Ou8jqJ
+kTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx1x7e/dfgy5SDN67sH0NO
+3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQq2EGnI/yuum06ZIya7XzV+hdG82MHauV
+BJVJ8zUtluNJbd134/tJS7SsVQepj5WztCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyM
+UNGPHgm+F6HmIcr9g+UQvIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQAB
+o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV5uNu
+5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY1Yl9PMWLSn/pvtsr
+F9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4NeF22d+mQrvHRAiGfzZ0JFrabA0U
+WTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NGFdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBH
+QRFXGU7Aj64GxJUTFy8bJZ918rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/
+iyK5S9kJRaTepLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl
+MrY=
+-----END CERTIFICATE-----
+
+DigiCert Global Root G3
+=======================
+-----BEGIN CERTIFICATE-----
+MIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQswCQYDVQQGEwJV
+UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAwHgYD
+VQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAw
+MDBaMGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5k
+aWdpY2VydC5jb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMHYwEAYHKoZIzj0C
+AQYFK4EEACIDYgAE3afZu4q4C/sLfyHS8L6+c/MzXRq8NOrexpu80JX28MzQC7phW1FGfp4tn+6O
+YwwX7Adw9c+ELkCDnOg/QW07rdOkFFk2eJ0DQ+4QE2xy3q6Ip6FrtUPOZ9wj/wMco+I+o0IwQDAP
+BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNp
+Yim8S8YwCgYIKoZIzj0EAwMDaAAwZQIxAK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y
+3maTD/HMsQmP3Wyr+mt/oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34
+VOKa5Vt8sycX
+-----END CERTIFICATE-----
+
+DigiCert Trusted Root G4
+========================
+-----BEGIN CERTIFICATE-----
+MIIFkDCCA3igAwIBAgIQBZsbV56OITLiOQe9p3d1XDANBgkqhkiG9w0BAQwFADBiMQswCQYDVQQG
+EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSEw
+HwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1
+MTIwMDAwWjBiMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
+d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0G
+CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3yithZwuEp
+pz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1Ifxp4VpX6+n6lXFllVcq9o
+k3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDVySAdYyktzuxeTsiT+CFhmzTrBcZe7Fsa
+vOvJz82sNEBfsXpm7nfISKhmV1efVFiODCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGY
+QJB5w3jHtrHEtWoYOAMQjdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6
+MUSaM0C/CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCiEhtm
+mnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADMfRyVw4/3IbKyEbe7
+f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QYuKZ3AeEPlAwhHbJUKSWJbOUOUlFH
+dL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXKchYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8
+oR7FwI+isX4KJpn15GkvmB0t9dmpsh3lGwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud
+DwEB/wQEAwIBhjAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wDQYJKoZIhvcNAQEMBQAD
+ggIBALth2X2pbL4XxJEbw6GiAI3jZGgPVs93rnD5/ZpKmbnJeFwMDF/k5hQpVgs2SV1EY+CtnJYY
+ZhsjDT156W1r1lT40jzBQ0CuHVD1UvyQO7uYmWlrx8GnqGikJ9yd+SeuMIW59mdNOj6PWTkiU0Tr
+yF0Dyu1Qen1iIQqAyHNm0aAFYF/opbSnr6j3bTWcfFqK1qI4mfN4i/RN0iAL3gTujJtHgXINwBQy
+7zBZLq7gcfJW5GqXb5JQbZaNaHqasjYUegbyJLkJEVDXCLG4iXqEI2FCKeWjzaIgQdfRnGTZ6iah
+ixTXTBmyUEFxPT9NcCOGDErcgdLMMpSEDQgJlxxPwO5rIHQw0uA5NBCFIRUBCOhVMt5xSdkoF1BN
+5r5N0XWs0Mr7QbhDparTwwVETyw2m+L64kW4I1NsBm9nVX9GtUw/bihaeSbSpKhil9Ie4u1Ki7wb
+/UdKDd9nZn6yW0HQO+T0O/QEY+nvwlQAUaCKKsnOeMzV6ocEGLPOr0mIr/OSmbaz5mEP0oUA51Aa
+5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1/YldvIViHTLSoCtU7ZpXwdv6EM8Zt4tK
+G48BtieVU+i2iW1bvGjUI+iLUaJW+fCmgKDWHrO8Dw9TdSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP
+82Z+
+-----END CERTIFICATE-----
+
+WoSign
+======
+-----BEGIN CERTIFICATE-----
+MIIFdjCCA16gAwIBAgIQXmjWEXGUY1BWAGjzPsnFkTANBgkqhkiG9w0BAQUFADBVMQswCQYDVQQG
+EwJDTjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQxKjAoBgNVBAMTIUNlcnRpZmljYXRpb24g
+QXV0aG9yaXR5IG9mIFdvU2lnbjAeFw0wOTA4MDgwMTAwMDFaFw0zOTA4MDgwMTAwMDFaMFUxCzAJ
+BgNVBAYTAkNOMRowGAYDVQQKExFXb1NpZ24gQ0EgTGltaXRlZDEqMCgGA1UEAxMhQ2VydGlmaWNh
+dGlvbiBBdXRob3JpdHkgb2YgV29TaWduMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA
+vcqNrLiRFVaXe2tcesLea9mhsMMQI/qnobLMMfo+2aYpbxY94Gv4uEBf2zmoAHqLoE1UfcIiePyO
+CbiohdfMlZdLdNiefvAA5A6JrkkoRBoQmTIPJYhTpA2zDxIIFgsDcSccf+Hb0v1naMQFXQoOXXDX
+2JegvFNBmpGN9J42Znp+VsGQX+axaCA2pIwkLCxHC1l2ZjC1vt7tj/id07sBMOby8w7gLJKA84X5
+KIq0VC6a7fd2/BVoFutKbOsuEo/Uz/4Mx1wdC34FMr5esAkqQtXJTpCzWQ27en7N1QhatH/YHGkR
++ScPewavVIMYe+HdVHpRaG53/Ma/UkpmRqGyZxq7o093oL5d//xWC0Nyd5DKnvnyOfUNqfTq1+ez
+EC8wQjchzDBwyYaYD8xYTYO7feUapTeNtqwylwA6Y3EkHp43xP901DfA4v6IRmAR3Qg/UDaruHqk
+lWJqbrDKaiFaafPz+x1wOZXzp26mgYmhiMU7ccqjUu6Du/2gd/Tkb+dC221KmYo0SLwX3OSACCK2
+8jHAPwQ+658geda4BmRkAjHXqc1S+4RFaQkAKtxVi8QGRkvASh0JWzko/amrzgD5LkhLJuYwTKVY
+yrREgk/nkR4zw7CT/xH8gdLKH3Ep3XZPkiWvHYG3Dy+MwwbMLyejSuQOmbp8HkUff6oZRZb9/D0C
+AwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFOFmzw7R
+8bNLtwYgFP6HEtX2/vs+MA0GCSqGSIb3DQEBBQUAA4ICAQCoy3JAsnbBfnv8rWTjMnvMPLZdRtP1
+LOJwXcgu2AZ9mNELIaCJWSQBnfmvCX0KI4I01fx8cpm5o9dU9OpScA7F9dY74ToJMuYhOZO9sxXq
+T2r09Ys/L3yNWC7F4TmgPsc9SnOeQHrAK2GpZ8nzJLmzbVUsWh2eJXLOC62qx1ViC777Y7NhRCOj
+y+EaDveaBk3e1CNOIZZbOVtXHS9dCF4Jef98l7VNg64N1uajeeAz0JmWAjCnPv/So0M/BVoG6kQC
+2nz4SNAzqfkHx5Xh9T71XXG68pWpdIhhWeO/yloTunK0jF02h+mmxTwTv97QRCbut+wucPrXnbes
+5cVAWubXbHssw1abR80LzvobtCHXt2a49CUwi1wNuepnsvRtrtWhnk/Yn+knArAdBtaP4/tIEp9/
+EaEQPkxROpaw0RPxx9gmrjrKkcRpnd8BKWRRb2jaFOwIQZeQjdCygPLPwj2/kWjFgGcexGATVdVh
+mVd8upUPYUk6ynW8yQqTP2cOEvIo4jEbwFcW3wh8GcF+Dx+FHgo2fFt+J7x6v+Db9NpSvd4MVHAx
+kUOVyLzwPt0JfjBkUO1/AaQzZ01oT74V77D2AhGiGxMlOtzCWfHjXEa7ZywCRuoeSKbmW9m1vFGi
+kpbbqsY3Iqb+zCB0oy2pLmvLwIIRIbWTee5Ehr7XHuQe+w==
+-----END CERTIFICATE-----
+
+WoSign China
+============
+-----BEGIN CERTIFICATE-----
+MIIFWDCCA0CgAwIBAgIQUHBrzdgT/BtOOzNy0hFIjTANBgkqhkiG9w0BAQsFADBGMQswCQYDVQQG
+EwJDTjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQxGzAZBgNVBAMMEkNBIOayg+mAmuagueiv
+geS5pjAeFw0wOTA4MDgwMTAwMDFaFw0zOTA4MDgwMTAwMDFaMEYxCzAJBgNVBAYTAkNOMRowGAYD
+VQQKExFXb1NpZ24gQ0EgTGltaXRlZDEbMBkGA1UEAwwSQ0Eg5rKD6YCa5qC56K+B5LmmMIICIjAN
+BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0EkhHiX8h8EqwqzbdoYGTufQdDTc7WU1/FDWiD+k
+8H/rD195L4mx/bxjWDeTmzj4t1up+thxx7S8gJeNbEvxUNUqKaqoGXqW5pWOdO2XCld19AXbbQs5
+uQF/qvbW2mzmBeCkTVL829B0txGMe41P/4eDrv8FAxNXUDf+jJZSEExfv5RxadmWPgxDT74wwJ85
+dE8GRV2j1lY5aAfMh09Qd5Nx2UQIsYo06Yms25tO4dnkUkWMLhQfkWsZHWgpLFbE4h4TV2TwYeO5
+Ed+w4VegG63XX9Gv2ystP9Bojg/qnw+LNVgbExz03jWhCl3W6t8Sb8D7aQdGctyB9gQjF+BNdeFy
+b7Ao65vh4YOhn0pdr8yb+gIgthhid5E7o9Vlrdx8kHccREGkSovrlXLp9glk3Kgtn3R46MGiCWOc
+76DbT52VqyBPt7D3h1ymoOQ3OMdc4zUPLK2jgKLsLl3Az+2LBcLmc272idX10kaO6m1jGx6KyX2m
++Jzr5dVjhU1zZmkR/sgO9MHHZklTfuQZa/HpelmjbX7FF+Ynxu8b22/8DU0GAbQOXDBGVWCvOGU6
+yke6rCzMRh+yRpY/8+0mBe53oWprfi1tWFxK1I5nuPHa1UaKJ/kR8slC/k7e3x9cxKSGhxYzoacX
+GKUN5AXlK8IrC6KVkLn9YDxOiT7nnO4fuwECAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1Ud
+EwEB/wQFMAMBAf8wHQYDVR0OBBYEFOBNv9ybQV0T6GTwp+kVpOGBwboxMA0GCSqGSIb3DQEBCwUA
+A4ICAQBqinA4WbbaixjIvirTthnVZil6Xc1bL3McJk6jfW+rtylNpumlEYOnOXOvEESS5iVdT2H6
+yAa+Tkvv/vMx/sZ8cApBWNromUuWyXi8mHwCKe0JgOYKOoICKuLJL8hWGSbueBwj/feTZU7n85iY
+r83d2Z5AiDEoOqsuC7CsDCT6eiaY8xJhEPRdF/d+4niXVOKM6Cm6jBAyvd0zaziGfjk9DgNyp115
+j0WKWa5bIW4xRtVZjc8VX90xJc/bYNaBRHIpAlf2ltTW/+op2znFuCyKGo3Oy+dCMYYFaA6eFN0A
+kLppRQjbbpCBhqcqBT/mhDn4t/lXX0ykeVoQDF7Va/81XwVRHmyjdanPUIPTfPRm94KNPQx96N97
+qA4bLJyuQHCH2u2nFoJavjVsIE4iYdm8UXrNemHcSxH5/mc0zy4EZmFcV5cjjPOGG0jfKq+nwf/Y
+jj4Du9gqsPoUJbJRa4ZDhS4HIxaAjUz7tGM7zMN07RujHv41D198HRaG9Q7DlfEvr10lO1Hm13ZB
+ONFLAzkopR6RctR9q5czxNM+4Gm2KHmgCY0c0f9BckgG/Jou5yD5m6Leie2uPAmvylezkolwQOQv
+T8Jwg0DXJCxr5wkf09XHwQj02w47HAcLQxGEIYbpgNR12KvxAmLBsX5VYc8T1yaw15zLKYs4SgsO
+kI26oQ==
+-----END CERTIFICATE-----
+
+COMODO RSA Certification Authority
+==================================
+-----BEGIN CERTIFICATE-----
+MIIF2DCCA8CgAwIBAgIQTKr5yttjb+Af907YWwOGnTANBgkqhkiG9w0BAQwFADCBhTELMAkGA1UE
+BhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgG
+A1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlv
+biBBdXRob3JpdHkwHhcNMTAwMTE5MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMC
+R0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UE
+ChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBB
+dXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCR6FSS0gpWsawNJN3Fz0Rn
+dJkrN6N9I3AAcbxT38T6KhKPS38QVr2fcHK3YX/JSw8Xpz3jsARh7v8Rl8f0hj4K+j5c+ZPmNHrZ
+FGvnnLOFoIJ6dq9xkNfs/Q36nGz637CC9BR++b7Epi9Pf5l/tfxnQ3K9DADWietrLNPtj5gcFKt+
+5eNu/Nio5JIk2kNrYrhV/erBvGy2i/MOjZrkm2xpmfh4SDBF1a3hDTxFYPwyllEnvGfDyi62a+pG
+x8cgoLEfZd5ICLqkTqnyg0Y3hOvozIFIQ2dOciqbXL1MGyiKXCJ7tKuY2e7gUYPDCUZObT6Z+pUX
+2nwzV0E8jVHtC7ZcryxjGt9XyD+86V3Em69FmeKjWiS0uqlWPc9vqv9JWL7wqP/0uK3pN/u6uPQL
+OvnoQ0IeidiEyxPx2bvhiWC4jChWrBQdnArncevPDt09qZahSL0896+1DSJMwBGB7FY79tOi4lu3
+sgQiUpWAk2nojkxl8ZEDLXB0AuqLZxUpaVICu9ffUGpVRr+goyhhf3DQw6KqLCGqR84onAZFdr+C
+GCe01a60y1Dma/RMhnEw6abfFobg2P9A3fvQQoh/ozM6LlweQRGBY84YcWsr7KaKtzFcOmpH4MN5
+WdYgGq/yapiqcrxXStJLnbsQ/LBMQeXtHT1eKJ2czL+zUdqnR+WEUwIDAQABo0IwQDAdBgNVHQ4E
+FgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8w
+DQYJKoZIhvcNAQEMBQADggIBAArx1UaEt65Ru2yyTUEUAJNMnMvlwFTPoCWOAvn9sKIN9SCYPBMt
+rFaisNZ+EZLpLrqeLppysb0ZRGxhNaKatBYSaVqM4dc+pBroLwP0rmEdEBsqpIt6xf4FpuHA1sj+
+nq6PK7o9mfjYcwlYRm6mnPTXJ9OV2jeDchzTc+CiR5kDOF3VSXkAKRzH7JsgHAckaVd4sjn8OoSg
+tZx8jb8uk2IntznaFxiuvTwJaP+EmzzV1gsD41eeFPfR60/IvYcjt7ZJQ3mFXLrrkguhxuhoqEwW
+sRqZCuhTLJK7oQkYdQxlqHvLI7cawiiFwxv/0Cti76R7CZGYZ4wUAc1oBmpjIXUDgIiKboHGhfKp
+pC3n9KUkEEeDys30jXlYsQab5xoq2Z0B15R97QNKyvDb6KkBPvVWmckejkk9u+UJueBPSZI9FoJA
+zMxZxuY67RIuaTxslbH9qh17f4a+Hg4yRvv7E491f0yLS0Zj/gA0QHDBw7mh3aZw4gSzQbzpgJHq
+ZJx64SIDqZxubw5lT2yHh17zbqD5daWbQOhTsiedSrnAdyGN/4fy3ryM7xfft0kL0fJuMAsaDk52
+7RH89elWsn2/x20Kk4yl0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7I
+LaZRfyHBNVOFBkpdn627G190
+-----END CERTIFICATE-----
+
+USERTrust RSA Certification Authority
+=====================================
+-----BEGIN CERTIFICATE-----
+MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCBiDELMAkGA1UE
+BhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQK
+ExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNh
+dGlvbiBBdXRob3JpdHkwHhcNMTAwMjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UE
+BhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQK
+ExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNh
+dGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCAEmUXNg7D2wiz
+0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2j
+Y0K2dvKpOyuR+OJv0OwWIJAJPuLodMkYtJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFn
+RghRy4YUVD+8M/5+bJz/Fp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O
++T23LLb2VN3I5xI6Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT79uq
+/nROacdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6c0Plfg6lZrEpfDKE
+Y1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmTYo61Zs8liM2EuLE/pDkP2QKe6xJM
+lXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97lc6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8
+yexDJtC/QV9AqURE9JnnV4eeUB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+
+eLf8ZxXhyVeEHg9j1uliutZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo0IwQDAd
+BgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF
+MAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPFUp/L+M+ZBn8b2kMVn54CVVeW
+FPFSPCeHlCjtHzoBN6J2/FNQwISbxmtOuowhT6KOVWKR82kV2LyI48SqC/3vqOlLVSoGIG1VeCkZ
+7l8wXEskEVX/JJpuXior7gtNn3/3ATiUFJVDBwn7YKnuHKsSjKCaXqeYalltiz8I+8jRRa8YFWSQ
+Eg9zKC7F4iRO/Fjs8PRF/iKz6y+O0tlFYQXBl2+odnKPi4w2r78NBc5xjeambx9spnFixdjQg3IM
+8WcRiQycE0xyNN+81XHfqnHd4blsjDwSXWXavVcStkNr/+XeTWYRUc+ZruwXtuhxkYzeSf7dNXGi
+FSeUHM9h4ya7b6NnJSFd5t0dCy5oGzuCr+yDZ4XUmFF0sbmZgIn/f3gZXHlKYC6SQK5MNyosycdi
+yA5d9zZbyuAlJQG03RoHnHcAP9Dc1ew91Pq7P8yF1m9/qS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9c
+J2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRBVXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGw
+sAvgnEzDHNb842m1R0aBL6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gx
+Q+6IHdfGjjxDah2nGN59PRbxYvnKkKj9
+-----END CERTIFICATE-----
+
+USERTrust ECC Certification Authority
+=====================================
+-----BEGIN CERTIFICATE-----
+MIICjzCCAhWgAwIBAgIQXIuZxVqUxdJxVt7NiYDMJjAKBggqhkjOPQQDAzCBiDELMAkGA1UEBhMC
+VVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU
+aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlv
+biBBdXRob3JpdHkwHhcNMTAwMjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMC
+VVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU
+aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlv
+biBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQarFRaqfloI+d61SRvU8Za2EurxtW2
+0eZzca7dnNYMYf3boIkDuAUU7FfO7l0/4iGzzvfUinngo4N+LZfQYcTxmdwlkWOrfzCjtHDix6Ez
+nPO/LlxTsV+zfTJ/ijTjeXmjQjBAMB0GA1UdDgQWBBQ64QmG1M8ZwpZ2dEl23OA1xmNjmjAOBgNV
+HQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjA2Z6EWCNzklwBB
+HU6+4WMBzzuqQhFkoJ2UOQIReVx7Hfpkue4WQrO/isIJxOzksU0CMQDpKmFHjFJKS04YcPbWRNZu
+9YO6bVi9JNlWSOrvxKJGgYhqOkbRqZtNyWHa0V1Xahg=
+-----END CERTIFICATE-----
+
+GlobalSign ECC Root CA - R4
+===========================
+-----BEGIN CERTIFICATE-----
+MIIB4TCCAYegAwIBAgIRKjikHJYKBN5CsiilC+g0mAIwCgYIKoZIzj0EAwIwUDEkMCIGA1UECxMb
+R2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD
+EwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoXDTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMb
+R2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD
+EwpHbG9iYWxTaWduMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuMZ5049sJQ6fLjkZHAOkrprl
+OQcJFspjsbmG+IpXwVfOQvpzofdlQv8ewQCybnMO/8ch5RikqtlxP6jUuc6MHaNCMEAwDgYDVR0P
+AQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFFSwe61FuOJAf/sKbvu+M8k8o4TV
+MAoGCCqGSM49BAMCA0gAMEUCIQDckqGgE6bPA7DmxCGXkPoUVy0D7O48027KqGx2vKLeuwIgJ6iF
+JzWbVsaj8kfSt24bAgAXqmemFZHe+pTsewv4n4Q=
+-----END CERTIFICATE-----
+
+GlobalSign ECC Root CA - R5
+===========================
+-----BEGIN CERTIFICATE-----
+MIICHjCCAaSgAwIBAgIRYFlJ4CYuu1X5CneKcflK2GwwCgYIKoZIzj0EAwMwUDEkMCIGA1UECxMb
+R2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD
+EwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoXDTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMb
+R2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD
+EwpHbG9iYWxTaWduMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAER0UOlvt9Xb/pOdEh+J8LttV7HpI6
+SFkc8GIxLcB6KP4ap1yztsyX50XUWPrRd21DosCHZTQKH3rd6zwzocWdTaRvQZU4f8kehOvRnkmS
+h5SHDDqFSmafnVmTTZdhBoZKo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAd
+BgNVHQ4EFgQUPeYpSJvqB8ohREom3m7e0oPQn1kwCgYIKoZIzj0EAwMDaAAwZQIxAOVpEslu28Yx
+uglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg515dTguDnFt2KaAJJiFqYgIwcdK1j1zqO+F4CYWodZI7
+yFz9SO8NdCKoCOJuxUnOxwy8p2Fp8fc74SrL+SvzZpA3
+-----END CERTIFICATE-----
+
+Staat der Nederlanden Root CA - G3
+==================================
+-----BEGIN CERTIFICATE-----
+MIIFdDCCA1ygAwIBAgIEAJiiOTANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJOTDEeMBwGA1UE
+CgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFhdCBkZXIgTmVkZXJsYW5kZW4g
+Um9vdCBDQSAtIEczMB4XDTEzMTExNDExMjg0MloXDTI4MTExMzIzMDAwMFowWjELMAkGA1UEBhMC
+TkwxHjAcBgNVBAoMFVN0YWF0IGRlciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5l
+ZGVybGFuZGVuIFJvb3QgQ0EgLSBHMzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAL4y
+olQPcPssXFnrbMSkUeiFKrPMSjTysF/zDsccPVMeiAho2G89rcKezIJnByeHaHE6n3WWIkYFsO2t
+x1ueKt6c/DrGlaf1F2cY5y9JCAxcz+bMNO14+1Cx3Gsy8KL+tjzk7FqXxz8ecAgwoNzFs21v0IJy
+EavSgWhZghe3eJJg+szeP4TrjTgzkApyI/o1zCZxMdFyKJLZWyNtZrVtB0LrpjPOktvA9mxjeM3K
+Tj215VKb8b475lRgsGYeCasH/lSJEULR9yS6YHgamPfJEf0WwTUaVHXvQ9Plrk7O53vDxk5hUUur
+mkVLoR9BvUhTFXFkC4az5S6+zqQbwSmEorXLCCN2QyIkHxcE1G6cxvx/K2Ya7Irl1s9N9WMJtxU5
+1nus6+N86U78dULI7ViVDAZCopz35HCz33JvWjdAidiFpNfxC95DGdRKWCyMijmev4SH8RY7Ngzp
+07TKbBlBUgmhHbBqv4LvcFEhMtwFdozL92TkA1CvjJFnq8Xy7ljY3r735zHPbMk7ccHViLVlvMDo
+FxcHErVc0qsgk7TmgoNwNsXNo42ti+yjwUOH5kPiNL6VizXtBznaqB16nzaeErAMZRKQFWDZJkBE
+41ZgpRDUajz9QdwOWke275dhdU/Z/seyHdTtXUmzqWrLZoQT1Vyg3N9udwbRcXXIV2+vD3dbAgMB
+AAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRUrfrHkleu
+yjWcLhL75LpdINyUVzANBgkqhkiG9w0BAQsFAAOCAgEAMJmdBTLIXg47mAE6iqTnB/d6+Oea31BD
+U5cqPco8R5gu4RV78ZLzYdqQJRZlwJ9UXQ4DO1t3ApyEtg2YXzTdO2PCwyiBwpwpLiniyMMB8jPq
+KqrMCQj3ZWfGzd/TtiunvczRDnBfuCPRy5FOCvTIeuXZYzbB1N/8Ipf3YF3qKS9Ysr1YvY2WTxB1
+v0h7PVGHoTx0IsL8B3+A3MSs/mrBcDCw6Y5p4ixpgZQJut3+TcCDjJRYwEYgr5wfAvg1VUkvRtTA
+8KCWAg8zxXHzniN9lLf9OtMJgwYh/WA9rjLA0u6NpvDntIJ8CsxwyXmA+P5M9zWEGYox+wrZ13+b
+8KKaa8MFSu1BYBQw0aoRQm7TIwIEC8Zl3d1Sd9qBa7Ko+gE4uZbqKmxnl4mUnrzhVNXkanjvSr0r
+mj1AfsbAddJu+2gw7OyLnflJNZoaLNmzlTnVHpL3prllL+U9bTpITAjc5CgSKL59NVzq4BZ+Extq
+1z7XnvwtdbLBFNUjA9tbbws+eC8N3jONFrdI54OagQ97wUNNVQQXOEpR1VmiiXTTn74eS9fGbbeI
+JG9gkaSChVtWQbzQRKtqE77RLFi3EjNYsjdj3BP1lB0/QFH1T/U67cjF68IeHRaVesd+QnGTbksV
+tzDfqu1XhUisHWrdOWnk4Xl4vs4Fv6EM94B7IWcnMFk=
+-----END CERTIFICATE-----
+
+Staat der Nederlanden EV Root CA
+================================
+-----BEGIN CERTIFICATE-----
+MIIFcDCCA1igAwIBAgIEAJiWjTANBgkqhkiG9w0BAQsFADBYMQswCQYDVQQGEwJOTDEeMBwGA1UE
+CgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSkwJwYDVQQDDCBTdGFhdCBkZXIgTmVkZXJsYW5kZW4g
+RVYgUm9vdCBDQTAeFw0xMDEyMDgxMTE5MjlaFw0yMjEyMDgxMTEwMjhaMFgxCzAJBgNVBAYTAk5M
+MR4wHAYDVQQKDBVTdGFhdCBkZXIgTmVkZXJsYW5kZW4xKTAnBgNVBAMMIFN0YWF0IGRlciBOZWRl
+cmxhbmRlbiBFViBSb290IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA48d+ifkk
+SzrSM4M1LGns3Amk41GoJSt5uAg94JG6hIXGhaTK5skuU6TJJB79VWZxXSzFYGgEt9nCUiY4iKTW
+O0Cmws0/zZiTs1QUWJZV1VD+hq2kY39ch/aO5ieSZxeSAgMs3NZmdO3dZ//BYY1jTw+bbRcwJu+r
+0h8QoPnFfxZpgQNH7R5ojXKhTbImxrpsX23Wr9GxE46prfNeaXUmGD5BKyF/7otdBwadQ8QpCiv8
+Kj6GyzyDOvnJDdrFmeK8eEEzduG/L13lpJhQDBXd4Pqcfzho0LKmeqfRMb1+ilgnQ7O6M5HTp5gV
+XJrm0w912fxBmJc+qiXbj5IusHsMX/FjqTf5m3VpTCgmJdrV8hJwRVXj33NeN/UhbJCONVrJ0yPr
+08C+eKxCKFhmpUZtcALXEPlLVPxdhkqHz3/KRawRWrUgUY0viEeXOcDPusBCAUCZSCELa6fS/ZbV
+0b5GnUngC6agIk440ME8MLxwjyx1zNDFjFE7PZQIZCZhfbnDZY8UnCHQqv0XcgOPvZuM5l5Tnrmd
+74K74bzickFbIZTTRTeU0d8JOV3nI6qaHcptqAqGhYqCvkIH1vI4gnPah1vlPNOePqc7nvQDs/nx
+fRN0Av+7oeX6AHkcpmZBiFxgV6YuCcS6/ZrPpx9Aw7vMWgpVSzs4dlG4Y4uElBbmVvMCAwEAAaNC
+MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFP6rAJCYniT8qcwa
+ivsnuL8wbqg7MA0GCSqGSIb3DQEBCwUAA4ICAQDPdyxuVr5Os7aEAJSrR8kN0nbHhp8dB9O2tLsI
+eK9p0gtJ3jPFrK3CiAJ9Brc1AsFgyb/E6JTe1NOpEyVa/m6irn0F3H3zbPB+po3u2dfOWBfoqSmu
+c0iH55vKbimhZF8ZE/euBhD/UcabTVUlT5OZEAFTdfETzsemQUHSv4ilf0X8rLiltTMMgsT7B/Zq
+5SWEXwbKwYY5EdtYzXc7LMJMD16a4/CrPmEbUCTCwPTxGfARKbalGAKb12NMcIxHowNDXLldRqAN
+b/9Zjr7dn3LDWyvfjFvO5QxGbJKyCqNMVEIYFRIYvdr8unRu/8G2oGTYqV9Vrp9canaW2HNnh/tN
+f1zuacpzEPuKqf2evTY4SUmH9A4U8OmHuD+nT3pajnnUk+S7aFKErGzp85hwVXIy+TSrK0m1zSBi
+5Dp6Z2Orltxtrpfs/J92VoguZs9btsmksNcFuuEnL5O7Jiqik7Ab846+HUCjuTaPPoIaGl6I6lD4
+WeKDRikL40Rc4ZW2aZCaFG+XroHPaO+Zmr615+F/+PoTRxZMzG0IQOeLeG9QgkRQP2YGiqtDhFZK
+DyAthg710tvSeopLzaXoTvFeJiUBWSOgftL2fiFX1ye8FVdMpEbB4IMeDExNH08GGeL5qPQ6gqGy
+eUN51q1veieQA6TqJIc/2b3Z6fJfUEkc7uzXLg==
+-----END CERTIFICATE-----
+
+IdenTrust Commercial Root CA 1
+==============================
+-----BEGIN CERTIFICATE-----
+MIIFYDCCA0igAwIBAgIQCgFCgAAAAUUjyES1AAAAAjANBgkqhkiG9w0BAQsFADBKMQswCQYDVQQG
+EwJVUzESMBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBS
+b290IENBIDEwHhcNMTQwMTE2MTgxMjIzWhcNMzQwMTE2MTgxMjIzWjBKMQswCQYDVQQGEwJVUzES
+MBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBSb290IENB
+IDEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCnUBneP5k91DNG8W9RYYKyqU+PZ4ld
+hNlT3Qwo2dfw/66VQ3KZ+bVdfIrBQuExUHTRgQ18zZshq0PirK1ehm7zCYofWjK9ouuU+ehcCuz/
+mNKvcbO0U59Oh++SvL3sTzIwiEsXXlfEU8L2ApeN2WIrvyQfYo3fw7gpS0l4PJNgiCL8mdo2yMKi
+1CxUAGc1bnO/AljwpN3lsKImesrgNqUZFvX9t++uP0D1bVoE/c40yiTcdCMbXTMTEl3EASX2MN0C
+XZ/g1Ue9tOsbobtJSdifWwLziuQkkORiT0/Br4sOdBeo0XKIanoBScy0RnnGF7HamB4HWfp1IYVl
+3ZBWzvurpWCdxJ35UrCLvYf5jysjCiN2O/cz4ckA82n5S6LgTrx+kzmEB/dEcH7+B1rlsazRGMzy
+NeVJSQjKVsk9+w8YfYs7wRPCTY/JTw436R+hDmrfYi7LNQZReSzIJTj0+kuniVyc0uMNOYZKdHzV
+WYfCP04MXFL0PfdSgvHqo6z9STQaKPNBiDoT7uje/5kdX7rL6B7yuVBgwDHTc+XvvqDtMwt0viAg
+xGds8AgDelWAf0ZOlqf0Hj7h9tgJ4TNkK2PXMl6f+cB7D3hvl7yTmvmcEpB4eoCHFddydJxVdHix
+uuFucAS6T6C6aMN7/zHwcz09lCqxC0EOoP5NiGVreTO01wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMC
+AQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU7UQZwNPwBovupHu+QucmVMiONnYwDQYJKoZI
+hvcNAQELBQADggIBAA2ukDL2pkt8RHYZYR4nKM1eVO8lvOMIkPkp165oCOGUAFjvLi5+U1KMtlwH
+6oi6mYtQlNeCgN9hCQCTrQ0U5s7B8jeUeLBfnLOic7iPBZM4zY0+sLj7wM+x8uwtLRvM7Kqas6pg
+ghstO8OEPVeKlh6cdbjTMM1gCIOQ045U8U1mwF10A0Cj7oV+wh93nAbowacYXVKV7cndJZ5t+qnt
+ozo00Fl72u1Q8zW/7esUTTHHYPTa8Yec4kjixsU3+wYQ+nVZZjFHKdp2mhzpgq7vmrlR94gjmmmV
+YjzlVYA211QC//G5Xc7UI2/YRYRKW2XviQzdFKcgyxilJbQN+QHwotL0AMh0jqEqSI5l2xPE4iUX
+feu+h1sXIFRRk0pTAwvsXcoz7WL9RccvW9xYoIA55vrX/hMUpu09lEpCdNTDd1lzzY9GvlU47/ro
+kTLql1gEIt44w8y8bckzOmoKaT+gyOpyj4xjhiO9bTyWnpXgSUyqorkqG5w2gXjtw+hG4iZZRHUe
+2XWJUc0QhJ1hYMtd+ZciTY6Y5uN/9lu7rs3KSoFrXgvzUeF0K+l+J6fZmUlO+KWA2yUPHGNiiskz
+Z2s8EIPGrd6ozRaOjfAHN3Gf8qv8QfXBi+wAN10J5U6A7/qxXDgGpRtK4dw4LTzcqx+QGtVKnO7R
+cGzM7vRX+Bi6hG6H
+-----END CERTIFICATE-----
+
+IdenTrust Public Sector Root CA 1
+=================================
+-----BEGIN CERTIFICATE-----
+MIIFZjCCA06gAwIBAgIQCgFCgAAAAUUjz0Z8AAAAAjANBgkqhkiG9w0BAQsFADBNMQswCQYDVQQG
+EwJVUzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3Rv
+ciBSb290IENBIDEwHhcNMTQwMTE2MTc1MzMyWhcNMzQwMTE2MTc1MzMyWjBNMQswCQYDVQQGEwJV
+UzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3RvciBS
+b290IENBIDEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2IpT8pEiv6EdrCvsnduTy
+P4o7ekosMSqMjbCpwzFrqHd2hCa2rIFCDQjrVVi7evi8ZX3yoG2LqEfpYnYeEe4IFNGyRBb06tD6
+Hi9e28tzQa68ALBKK0CyrOE7S8ItneShm+waOh7wCLPQ5CQ1B5+ctMlSbdsHyo+1W/CD80/HLaXI
+rcuVIKQxKFdYWuSNG5qrng0M8gozOSI5Cpcu81N3uURF/YTLNiCBWS2ab21ISGHKTN9T0a9SvESf
+qy9rg3LvdYDaBjMbXcjaY8ZNzaxmMc3R3j6HEDbhuaR672BQssvKplbgN6+rNBM5Jeg5ZuSYeqoS
+mJxZZoY+rfGwyj4GD3vwEUs3oERte8uojHH01bWRNszwFcYr3lEXsZdMUD2xlVl8BX0tIdUAvwFn
+ol57plzy9yLxkA2T26pEUWbMfXYD62qoKjgZl3YNa4ph+bz27nb9cCvdKTz4Ch5bQhyLVi9VGxyh
+LrXHFub4qjySjmm2AcG1hp2JDws4lFTo6tyePSW8Uybt1as5qsVATFSrsrTZ2fjXctscvG29ZV/v
+iDUqZi/u9rNl8DONfJhBaUYPQxxp+pu10GFqzcpL2UyQRqsVWaFHVCkugyhfHMKiq3IXAAaOReyL
+4jM9f9oZRORicsPfIsbyVtTdX5Vy7W1f90gDW/3FKqD2cyOEEBsB5wIDAQABo0IwQDAOBgNVHQ8B
+Af8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU43HgntinQtnbcZFrlJPrw6PRFKMw
+DQYJKoZIhvcNAQELBQADggIBAEf63QqwEZE4rU1d9+UOl1QZgkiHVIyqZJnYWv6IAcVYpZmxI1Qj
+t2odIFflAWJBF9MJ23XLblSQdf4an4EKwt3X9wnQW3IV5B4Jaj0z8yGa5hV+rVHVDRDtfULAj+7A
+mgjVQdZcDiFpboBhDhXAuM/FSRJSzL46zNQuOAXeNf0fb7iAaJg9TaDKQGXSc3z1i9kKlT/YPyNt
+GtEqJBnZhbMX73huqVjRI9PHE+1yJX9dsXNw0H8GlwmEKYBhHfpe/3OsoOOJuBxxFcbeMX8S3OFt
+m6/n6J91eEyrRjuazr8FGF1NFTwWmhlQBJqymm9li1JfPFgEKCXAZmExfrngdbkaqIHWchezxQMx
+NRF4eKLg6TCMf4DfWN88uieW4oA0beOY02QnrEh+KHdcxiVhJfiFDGX6xDIvpZgF5PgLZxYWxoK4
+Mhn5+bl53B/N66+rDt0b20XkeucC4pVd/GnwU2lhlXV5C15V5jgclKlZM57IcXR5f1GJtshquDDI
+ajjDbp7hNxbqBWJMWxJH7ae0s1hWx0nzfxJoCTFx8G34Tkf71oXuxVhAGaQdp/lLQzfcaFpPz+vC
+ZHTetBXZ9FRUGi8c15dxVJCO2SCdUyt/q4/i6jC8UDfv8Ue1fXwsBOxonbRJRBD0ckscZOf85muQ
+3Wl9af0AVqW3rLatt8o+Ae+c
+-----END CERTIFICATE-----
+
+Entrust Root Certification Authority - G2
+=========================================
+-----BEGIN CERTIFICATE-----
+MIIEPjCCAyagAwIBAgIESlOMKDANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMCVVMxFjAUBgNV
+BAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVy
+bXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ug
+b25seTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIw
+HhcNMDkwNzA3MTcyNTU0WhcNMzAxMjA3MTc1NTU0WjCBvjELMAkGA1UEBhMCVVMxFjAUBgNVBAoT
+DUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMx
+OTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25s
+eTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIwggEi
+MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6hLZy254Ma+KZ6TABp3bqMriVQRrJ2mFOWHLP
+/vaCeb9zYQYKpSfYs1/TRU4cctZOMvJyig/3gxnQaoCAAEUesMfnmr8SVycco2gvCoe9amsOXmXz
+HHfV1IWNcCG0szLni6LVhjkCsbjSR87kyUnEO6fe+1R9V77w6G7CebI6C1XiUJgWMhNcL3hWwcKU
+s/Ja5CeanyTXxuzQmyWC48zCxEXFjJd6BmsqEZ+pCm5IO2/b1BEZQvePB7/1U1+cPvQXLOZprE4y
+TGJ36rfo5bs0vBmLrpxR57d+tVOxMyLlbc9wPBr64ptntoP0jaWvYkxN4FisZDQSA/i2jZRjJKRx
+AgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqciZ6
+0B7vfec7aVHUbI2fkBJmqzANBgkqhkiG9w0BAQsFAAOCAQEAeZ8dlsa2eT8ijYfThwMEYGprmi5Z
+iXMRrEPR9RP/jTkrwPK9T3CMqS/qF8QLVJ7UG5aYMzyorWKiAHarWWluBh1+xLlEjZivEtRh2woZ
+Rkfz6/djwUAFQKXSt/S1mja/qYh2iARVBCuch38aNzx+LaUa2NSJXsq9rD1s2G2v1fN2D807iDgi
+nWyTmsQ9v4IbZT+mD12q/OWyFcq1rca8PdCE6OoGcrBNOTJ4vz4RnAuknZoh8/CbCzB428Hch0P+
+vGOaysXCHMnHjf87ElgI5rY97HosTvuDls4MPGmHVHOkc8KT/1EQrBVUAdj8BbGJoX90g5pJ19xO
+e4pIb4tF9g==
+-----END CERTIFICATE-----
+
+Entrust Root Certification Authority - EC1
+==========================================
+-----BEGIN CERTIFICATE-----
+MIIC+TCCAoCgAwIBAgINAKaLeSkAAAAAUNCR+TAKBggqhkjOPQQDAzCBvzELMAkGA1UEBhMCVVMx
+FjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVn
+YWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDEyIEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXpl
+ZCB1c2Ugb25seTEzMDEGA1UEAxMqRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5
+IC0gRUMxMB4XDTEyMTIxODE1MjUzNloXDTM3MTIxODE1NTUzNlowgb8xCzAJBgNVBAYTAlVTMRYw
+FAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0L2xlZ2Fs
+LXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxMiBFbnRydXN0LCBJbmMuIC0gZm9yIGF1dGhvcml6ZWQg
+dXNlIG9ubHkxMzAxBgNVBAMTKkVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAt
+IEVDMTB2MBAGByqGSM49AgEGBSuBBAAiA2IABIQTydC6bUF74mzQ61VfZgIaJPRbiWlH47jCffHy
+AsWfoPZb1YsGGYZPUxBtByQnoaD41UcZYUx9ypMn6nQM72+WCf5j7HBdNq1nd67JnXxVRDqiY1Ef
+9eNi1KlHBz7MIKNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE
+FLdj5xrdjekIplWDpOBqUEFlEUJJMAoGCCqGSM49BAMDA2cAMGQCMGF52OVCR98crlOZF7ZvHH3h
+vxGU0QOIdeSNiaSKd0bebWHvAvX7td/M/k7//qnmpwIwW5nXhTcGtXsI/esni0qU+eH6p44mCOh8
+kmhtc9hvJqwhAriZtyZBWyVgrtBIGu4G
+-----END CERTIFICATE-----
+
+CFCA EV ROOT
+============
+-----BEGIN CERTIFICATE-----
+MIIFjTCCA3WgAwIBAgIEGErM1jANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJDTjEwMC4GA1UE
+CgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQDDAxDRkNB
+IEVWIFJPT1QwHhcNMTIwODA4MDMwNzAxWhcNMjkxMjMxMDMwNzAxWjBWMQswCQYDVQQGEwJDTjEw
+MC4GA1UECgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQD
+DAxDRkNBIEVWIFJPT1QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDXXWvNED8fBVnV
+BU03sQ7smCuOFR36k0sXgiFxEFLXUWRwFsJVaU2OFW2fvwwbwuCjZ9YMrM8irq93VCpLTIpTUnrD
+7i7es3ElweldPe6hL6P3KjzJIx1qqx2hp/Hz7KDVRM8Vz3IvHWOX6Jn5/ZOkVIBMUtRSqy5J35DN
+uF++P96hyk0g1CXohClTt7GIH//62pCfCqktQT+x8Rgp7hZZLDRJGqgG16iI0gNyejLi6mhNbiyW
+ZXvKWfry4t3uMCz7zEasxGPrb382KzRzEpR/38wmnvFyXVBlWY9ps4deMm/DGIq1lY+wejfeWkU7
+xzbh72fROdOXW3NiGUgthxwG+3SYIElz8AXSG7Ggo7cbcNOIabla1jj0Ytwli3i/+Oh+uFzJlU9f
+py25IGvPa931DfSCt/SyZi4QKPaXWnuWFo8BGS1sbn85WAZkgwGDg8NNkt0yxoekN+kWzqotaK8K
+gWU6cMGbrU1tVMoqLUuFG7OA5nBFDWteNfB/O7ic5ARwiRIlk9oKmSJgamNgTnYGmE69g60dWIol
+hdLHZR4tjsbftsbhf4oEIRUpdPA+nJCdDC7xij5aqgwJHsfVPKPtl8MeNPo4+QgO48BdK4PRVmrJ
+tqhUUy54Mmc9gn900PvhtgVguXDbjgv5E1hvcWAQUhC5wUEJ73IfZzF4/5YFjQIDAQABo2MwYTAf
+BgNVHSMEGDAWgBTj/i39KNALtbq2osS/BqoFjJP7LzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB
+/wQEAwIBBjAdBgNVHQ4EFgQU4/4t/SjQC7W6tqLEvwaqBYyT+y8wDQYJKoZIhvcNAQELBQADggIB
+ACXGumvrh8vegjmWPfBEp2uEcwPenStPuiB/vHiyz5ewG5zz13ku9Ui20vsXiObTej/tUxPQ4i9q
+ecsAIyjmHjdXNYmEwnZPNDatZ8POQQaIxffu2Bq41gt/UP+TqhdLjOztUmCypAbqTuv0axn96/Ua
+4CUqmtzHQTb3yHQFhDmVOdYLO6Qn+gjYXB74BGBSESgoA//vU2YApUo0FmZ8/Qmkrp5nGm9BC2sG
+E5uPhnEFtC+NiWYzKXZUmhH4J/qyP5Hgzg0b8zAarb8iXRvTvyUFTeGSGn+ZnzxEk8rUQElsgIfX
+BDrDMlI1Dlb4pd19xIsNER9Tyx6yF7Zod1rg1MvIB671Oi6ON7fQAUtDKXeMOZePglr4UeWJoBjn
+aH9dCi77o0cOPaYjesYBx4/IXr9tgFa+iiS6M+qf4TIRnvHST4D2G0CvOJ4RUHlzEhLN5mydLIhy
+PDCBBpEi6lmt2hkuIsKNuYyH4Ga8cyNfIWRjgEj1oDwYPZTISEEdQLpe/v5WOaHIz16eGWRGENoX
+kbcFgKyLmZJ956LYBws2J+dIeWCKw9cTXPhyQN9Ky8+ZAAoACxGV2lZFA4gKn2fQ1XmxqI1AbQ3C
+ekD6819kR5LLU7m7Wc5P/dAVUwHY3+vZ5nbv0CO7O6l5s9UCKc2Jo5YPSjXnTkLAdc0Hz+Ys63su
+-----END CERTIFICATE-----
+
+TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı H5
+====================================================
+-----BEGIN CERTIFICATE-----
+MIIEJzCCAw+gAwIBAgIHAI4X/iQggTANBgkqhkiG9w0BAQsFADCBsTELMAkGA1UEBhMCVFIxDzAN
+BgNVBAcMBkFua2FyYTFNMEsGA1UECgxEVMOcUktUUlVTVCBCaWxnaSDEsGxldGnFn2ltIHZlIEJp
+bGnFn2ltIEfDvHZlbmxpxJ9pIEhpem1ldGxlcmkgQS7Fni4xQjBABgNVBAMMOVTDnFJLVFJVU1Qg
+RWxla3Ryb25payBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsSBINTAeFw0xMzA0MzAw
+ODA3MDFaFw0yMzA0MjgwODA3MDFaMIGxMQswCQYDVQQGEwJUUjEPMA0GA1UEBwwGQW5rYXJhMU0w
+SwYDVQQKDERUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnE
+n2kgSGl6bWV0bGVyaSBBLsWeLjFCMEAGA1UEAww5VMOcUktUUlVTVCBFbGVrdHJvbmlrIFNlcnRp
+ZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxIEg1MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
+CgKCAQEApCUZ4WWe60ghUEoI5RHwWrom/4NZzkQqL/7hzmAD/I0Dpe3/a6i6zDQGn1k19uwsu537
+jVJp45wnEFPzpALFp/kRGml1bsMdi9GYjZOHp3GXDSHHmflS0yxjXVW86B8BSLlg/kJK9siArs1m
+ep5Fimh34khon6La8eHBEJ/rPCmBp+EyCNSgBbGM+42WAA4+Jd9ThiI7/PS98wl+d+yG6w8z5UNP
+9FR1bSmZLmZaQ9/LXMrI5Tjxfjs1nQ/0xVqhzPMggCTTV+wVunUlm+hkS7M0hO8EuPbJbKoCPrZV
+4jI3X/xml1/N1p7HIL9Nxqw/dV8c7TKcfGkAaZHjIxhT6QIDAQABo0IwQDAdBgNVHQ4EFgQUVpkH
+HtOsDGlktAxQR95DLL4gwPswDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZI
+hvcNAQELBQADggEBAJ5FdnsXSDLyOIspve6WSk6BGLFRRyDN0GSxDsnZAdkJzsiZ3GglE9Rc8qPo
+BP5yCccLqh0lVX6Wmle3usURehnmp349hQ71+S4pL+f5bFgWV1Al9j4uPqrtd3GqqpmWRgqujuwq
+URawXs3qZwQcWDD1YIq9pr1N5Za0/EKJAWv2cMhQOQwt1WbZyNKzMrcbGW3LM/nfpeYVhDfwwvJl
+lpKQd/Ct9JDpEXjXk4nAPQu6KfTomZ1yju2dL+6SfaHx/126M2CFYv4HAqGEVka+lgqaE9chTLd8
+B59OTj+RdPsnnRHM3eaxynFNExc5JsUpISuTKWqW+qtB4Uu2NQvAmxU=
+-----END CERTIFICATE-----
+
+Certinomis - Root CA
+====================
+-----BEGIN CERTIFICATE-----
+MIIFkjCCA3qgAwIBAgIBATANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJGUjETMBEGA1UEChMK
+Q2VydGlub21pczEXMBUGA1UECxMOMDAwMiA0MzM5OTg5MDMxHTAbBgNVBAMTFENlcnRpbm9taXMg
+LSBSb290IENBMB4XDTEzMTAyMTA5MTcxOFoXDTMzMTAyMTA5MTcxOFowWjELMAkGA1UEBhMCRlIx
+EzARBgNVBAoTCkNlcnRpbm9taXMxFzAVBgNVBAsTDjAwMDIgNDMzOTk4OTAzMR0wGwYDVQQDExRD
+ZXJ0aW5vbWlzIC0gUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANTMCQos
+P5L2fxSeC5yaah1AMGT9qt8OHgZbn1CF6s2Nq0Nn3rD6foCWnoR4kkjW4znuzuRZWJflLieY6pOo
+d5tK8O90gC3rMB+12ceAnGInkYjwSond3IjmFPnVAy//ldu9n+ws+hQVWZUKxkd8aRi5pwP5ynap
+z8dvtF4F/u7BUrJ1Mofs7SlmO/NKFoL21prbcpjp3vDFTKWrteoB4owuZH9kb/2jJZOLyKIOSY00
+8B/sWEUuNKqEUL3nskoTuLAPrjhdsKkb5nPJWqHZZkCqqU2mNAKthH6yI8H7KsZn9DS2sJVqM09x
+RLWtwHkziOC/7aOgFLScCbAK42C++PhmiM1b8XcF4LVzbsF9Ri6OSyemzTUK/eVNfaoqoynHWmgE
+6OXWk6RiwsXm9E/G+Z8ajYJJGYrKWUM66A0ywfRMEwNvbqY/kXPLynNvEiCL7sCCeN5LLsJJwx3t
+FvYk9CcbXFcx3FXuqB5vbKziRcxXV4p1VxngtViZSTYxPDMBbRZKzbgqg4SGm/lg0h9tkQPTYKbV
+PZrdd5A9NaSfD171UkRpucC63M9933zZxKyGIjK8e2uR73r4F2iw4lNVYC2vPsKD2NkJK/DAZNuH
+i5HMkesE/Xa0lZrmFAYb1TQdvtj/dBxThZngWVJKYe2InmtJiUZ+IFrZ50rlau7SZRFDAgMBAAGj
+YzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTvkUz1pcMw6C8I
+6tNxIqSSaHh02TAfBgNVHSMEGDAWgBTvkUz1pcMw6C8I6tNxIqSSaHh02TANBgkqhkiG9w0BAQsF
+AAOCAgEAfj1U2iJdGlg+O1QnurrMyOMaauo++RLrVl89UM7g6kgmJs95Vn6RHJk/0KGRHCwPT5iV
+WVO90CLYiF2cN/z7ZMF4jIuaYAnq1fohX9B0ZedQxb8uuQsLrbWwF6YSjNRieOpWauwK0kDDPAUw
+Pk2Ut59KA9N9J0u2/kTO+hkzGm2kQtHdzMjI1xZSg081lLMSVX3l4kLr5JyTCcBMWwerx20RoFAX
+lCOotQqSD7J6wWAsOMwaplv/8gzjqh8c3LigkyfeY+N/IZ865Z764BNqdeuWXGKRlI5nU7aJ+BIJ
+y29SWwNyhlCVCNSNh4YVH5Uk2KRvms6knZtt0rJ2BobGVgjF6wnaNsIbW0G+YSrjcOa4pvi2WsS9
+Iff/ql+hbHY5ZtbqTFXhADObE5hjyW/QASAJN1LnDE8+zbz1X5YnpyACleAu6AdBBR8Vbtaw5Bng
+DwKTACdyxYvRVB9dSsNAl35VpnzBMwQUAR1JIGkLGZOdblgi90AMRgwjY/M50n92Uaf0yKHxDHYi
+I0ZSKS3io0EHVmmY0gUJvGnHWmHNj4FgFU2A3ZDifcRQ8ow7bkrHxuaAKzyBvBGAFhAn1/DNP3nM
+cyrDflOR1m749fPH0FFNjkulW+YZFzvWgQncItzujrnEj1PhZ7szuIgVRs/taTX/dQ1G885x4cVr
+hkIGuUE=
+-----END CERTIFICATE-----
+
+OISTE WISeKey Global Root GB CA
+===============================
+-----BEGIN CERTIFICATE-----
+MIIDtTCCAp2gAwIBAgIQdrEgUnTwhYdGs/gjGvbCwDANBgkqhkiG9w0BAQsFADBtMQswCQYDVQQG
+EwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNl
+ZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwgUm9vdCBHQiBDQTAeFw0xNDEyMDExNTAw
+MzJaFw0zOTEyMDExNTEwMzFaMG0xCzAJBgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYD
+VQQLExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEds
+b2JhbCBSb290IEdCIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2Be3HEokKtaX
+scriHvt9OO+Y9bI5mE4nuBFde9IllIiCFSZqGzG7qFshISvYD06fWvGxWuR51jIjK+FTzJlFXHtP
+rby/h0oLS5daqPZI7H17Dc0hBt+eFf1Biki3IPShehtX1F1Q/7pn2COZH8g/497/b1t3sWtuuMlk
+9+HKQUYOKXHQuSP8yYFfTvdv37+ErXNku7dCjmn21HYdfp2nuFeKUWdy19SouJVUQHMD9ur06/4o
+Qnc/nSMbsrY9gBQHTC5P99UKFg29ZkM3fiNDecNAhvVMKdqOmq0NpQSHiB6F4+lT1ZvIiwNjeOvg
+GUpuuy9rM2RYk61pv48b74JIxwIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB
+/zAdBgNVHQ4EFgQUNQ/INmNe4qPs+TtmFc5RUuORmj0wEAYJKwYBBAGCNxUBBAMCAQAwDQYJKoZI
+hvcNAQELBQADggEBAEBM+4eymYGQfp3FsLAmzYh7KzKNbrghcViXfa43FK8+5/ea4n32cZiZBKpD
+dHij40lhPnOMTZTg+XHEthYOU3gf1qKHLwI5gSk8rxWYITD+KJAAjNHhy/peyP34EEY7onhCkRd0
+VQreUGdNZtGn//3ZwLWoo4rOZvUPQ82nK1d7Y0Zqqi5S2PTt4W2tKZB4SLrhI6qjiey1q5bAtEui
+HZeeevJuQHHfaPFlTc58Bd9TZaml8LGXBHAVRgOY1NK/VLSgWH1Sb9pWJmLU2NuJMW8c8CLC02Ic
+Nc1MaRVUGpCY3useX8p3x8uOPUNpnJpY0CQ73xtAln41rYHHTnG6iBM=
+-----END CERTIFICATE-----
+
+Certification Authority of WoSign G2
+====================================
+-----BEGIN CERTIFICATE-----
+MIIDfDCCAmSgAwIBAgIQayXaioidfLwPBbOxemFFRDANBgkqhkiG9w0BAQsFADBYMQswCQYDVQQG
+EwJDTjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQxLTArBgNVBAMTJENlcnRpZmljYXRpb24g
+QXV0aG9yaXR5IG9mIFdvU2lnbiBHMjAeFw0xNDExMDgwMDU4NThaFw00NDExMDgwMDU4NThaMFgx
+CzAJBgNVBAYTAkNOMRowGAYDVQQKExFXb1NpZ24gQ0EgTGltaXRlZDEtMCsGA1UEAxMkQ2VydGlm
+aWNhdGlvbiBBdXRob3JpdHkgb2YgV29TaWduIEcyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
+CgKCAQEAvsXEoCKASU+/2YcRxlPhuw+9YH+v9oIOH9ywjj2X4FA8jzrvZjtFB5sg+OPXJYY1kBai
+XW8wGQiHC38Gsp1ij96vkqVg1CuAmlI/9ZqD6TRay9nVYlzmDuDfBpgOgHzKtB0TiGsOqCR3A9Du
+W/PKaZE1OVbFbeP3PU9ekzgkyhjpJMuSA93MHD0JcOQg5PGurLtzaaNjOg9FD6FKmsLRY6zLEPg9
+5k4ot+vElbGs/V6r+kHLXZ1L3PR8du9nfwB6jdKgGlxNIuG12t12s9R23164i5jIFFTMaxeSt+BK
+v0mUYQs4kI9dJGwlezt52eJ+na2fmKEG/HgUYFf47oB3sQIDAQABo0IwQDAOBgNVHQ8BAf8EBAMC
+AQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU+mCp62XF3RYUCE4MD42b4Pdkr2cwDQYJKoZI
+hvcNAQELBQADggEBAFfDejaCnI2Y4qtAqkePx6db7XznPWZaOzG73/MWM5H8fHulwqZm46qwtyeY
+P0nXYGdnPzZPSsvxFPpahygc7Y9BMsaV+X3avXtbwrAh449G3CE4Q3RM+zD4F3LBMvzIkRfEzFg3
+TgvMWvchNSiDbGAtROtSjFA9tWwS1/oJu2yySrHFieT801LYYRf+epSEj3m2M1m6D8QL4nCgS3gu
++sif/a+RZQp4OBXllxcU3fngLDT4ONCEIgDAFFEYKwLcMFrw6AF8NTojrwjkr6qOKEJJLvD1mTS+
+7Q9LGOHSJDy7XUe3IfKN0QqZjuNuPq1w4I+5ysxugTH2e5x6eeRncRg=
+-----END CERTIFICATE-----
+
+CA WoSign ECC Root
+==================
+-----BEGIN CERTIFICATE-----
+MIICCTCCAY+gAwIBAgIQaEpYcIBr8I8C+vbe6LCQkDAKBggqhkjOPQQDAzBGMQswCQYDVQQGEwJD
+TjEaMBgGA1UEChMRV29TaWduIENBIExpbWl0ZWQxGzAZBgNVBAMTEkNBIFdvU2lnbiBFQ0MgUm9v
+dDAeFw0xNDExMDgwMDU4NThaFw00NDExMDgwMDU4NThaMEYxCzAJBgNVBAYTAkNOMRowGAYDVQQK
+ExFXb1NpZ24gQ0EgTGltaXRlZDEbMBkGA1UEAxMSQ0EgV29TaWduIEVDQyBSb290MHYwEAYHKoZI
+zj0CAQYFK4EEACIDYgAE4f2OuEMkq5Z7hcK6C62N4DrjJLnSsb6IOsq/Srj57ywvr1FQPEd1bPiU
+t5v8KB7FVMxjnRZLU8HnIKvNrCXSf4/CwVqCXjCLelTOA7WRf6qU0NGKSMyCBSah1VES1ns2o0Iw
+QDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUqv3VWqP2h4syhf3R
+MluARZPzA7gwCgYIKoZIzj0EAwMDaAAwZQIxAOSkhLCB1T2wdKyUpOgOPQB0TKGXa/kNUTyh2Tv0
+Daupn75OcsqF1NnstTJFGG+rrQIwfcf3aWMvoeGY7xMQ0Xk/0f7qO3/eVvSQsRUR2LIiFdAvwyYu
+a/GRspBl9JrmkO5K
+-----END CERTIFICATE-----
+
+SZAFIR ROOT CA2
+===============
+-----BEGIN CERTIFICATE-----
+MIIDcjCCAlqgAwIBAgIUPopdB+xV0jLVt+O2XwHrLdzk1uQwDQYJKoZIhvcNAQELBQAwUTELMAkG
+A1UEBhMCUEwxKDAmBgNVBAoMH0tyYWpvd2EgSXpiYSBSb3psaWN6ZW5pb3dhIFMuQS4xGDAWBgNV
+BAMMD1NaQUZJUiBST09UIENBMjAeFw0xNTEwMTkwNzQzMzBaFw0zNTEwMTkwNzQzMzBaMFExCzAJ
+BgNVBAYTAlBMMSgwJgYDVQQKDB9LcmFqb3dhIEl6YmEgUm96bGljemVuaW93YSBTLkEuMRgwFgYD
+VQQDDA9TWkFGSVIgUk9PVCBDQTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC3vD5Q
+qEvNQLXOYeeWyrSh2gwisPq1e3YAd4wLz32ohswmUeQgPYUM1ljj5/QqGJ3a0a4m7utT3PSQ1hNK
+DJA8w/Ta0o4NkjrcsbH/ON7Dui1fgLkCvUqdGw+0w8LBZwPd3BucPbOw3gAeqDRHu5rr/gsUvTaE
+2g0gv/pby6kWIK05YO4vdbbnl5z5Pv1+TW9NL++IDWr63fE9biCloBK0TXC5ztdyO4mTp4CEHCdJ
+ckm1/zuVnsHMyAHs6A6KCpbns6aH5db5BSsNl0BwPLqsdVqc1U2dAgrSS5tmS0YHF2Wtn2yIANwi
+ieDhZNRnvDF5YTy7ykHNXGoAyDw4jlivAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0P
+AQH/BAQDAgEGMB0GA1UdDgQWBBQuFqlKGLXLzPVvUPMjX/hd56zwyDANBgkqhkiG9w0BAQsFAAOC
+AQEAtXP4A9xZWx126aMqe5Aosk3AM0+qmrHUuOQn/6mWmc5G4G18TKI4pAZw8PRBEew/R40/cof5
+O/2kbytTAOD/OblqBw7rHRz2onKQy4I9EYKL0rufKq8h5mOGnXkZ7/e7DDWQw4rtTw/1zBLZpD67
+oPwglV9PJi8RI4NOdQcPv5vRtB3pEAT+ymCPoky4rc/hkA/NrgrHXXu3UNLUYfrVFdvXn4dRVOul
+4+vJhaAlIDf7js4MNIThPIGyd05DpYhfhmehPea0XGG2Ptv+tyjFogeutcrKjSoS75ftwjCkySp6
++/NNIxuZMzSgLvWpCz/UXeHPhJ/iGcJfitYgHuNztw==
+-----END CERTIFICATE-----
+
+Certum Trusted Network CA 2
+===========================
+-----BEGIN CERTIFICATE-----
+MIIF0jCCA7qgAwIBAgIQIdbQSk8lD8kyN/yqXhKN6TANBgkqhkiG9w0BAQ0FADCBgDELMAkGA1UE
+BhMCUEwxIjAgBgNVBAoTGVVuaXpldG8gVGVjaG5vbG9naWVzIFMuQS4xJzAlBgNVBAsTHkNlcnR1
+bSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEkMCIGA1UEAxMbQ2VydHVtIFRydXN0ZWQgTmV0d29y
+ayBDQSAyMCIYDzIwMTExMDA2MDgzOTU2WhgPMjA0NjEwMDYwODM5NTZaMIGAMQswCQYDVQQGEwJQ
+TDEiMCAGA1UEChMZVW5pemV0byBUZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENl
+cnRpZmljYXRpb24gQXV0aG9yaXR5MSQwIgYDVQQDExtDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENB
+IDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC9+Xj45tWADGSdhhuWZGc/IjoedQF9
+7/tcZ4zJzFxrqZHmuULlIEub2pt7uZld2ZuAS9eEQCsn0+i6MLs+CRqnSZXvK0AkwpfHp+6bJe+o
+CgCXhVqqndwpyeI1B+twTUrWwbNWuKFBOJvR+zF/j+Bf4bE/D44WSWDXBo0Y+aomEKsq09DRZ40b
+Rr5HMNUuctHFY9rnY3lEfktjJImGLjQ/KUxSiyqnwOKRKIm5wFv5HdnnJ63/mgKXwcZQkpsCLL2p
+uTRZCr+ESv/f/rOf69me4Jgj7KZrdxYq28ytOxykh9xGc14ZYmhFV+SQgkK7QtbwYeDBoz1mo130
+GO6IyY0XRSmZMnUCMe4pJshrAua1YkV/NxVaI2iJ1D7eTiew8EAMvE0Xy02isx7QBlrd9pPPV3WZ
+9fqGGmd4s7+W/jTcvedSVuWz5XV710GRBdxdaeOVDUO5/IOWOZV7bIBaTxNyxtd9KXpEulKkKtVB
+Rgkg/iKgtlswjbyJDNXXcPiHUv3a76xRLgezTv7QCdpw75j6VuZt27VXS9zlLCUVyJ4ueE742pye
+hizKV/Ma5ciSixqClnrDvFASadgOWkaLOusm+iPJtrCBvkIApPjW/jAux9JG9uWOdf3yzLnQh1vM
+BhBgu4M1t15n3kfsmUjxpKEV/q2MYo45VU85FrmxY53/twIDAQABo0IwQDAPBgNVHRMBAf8EBTAD
+AQH/MB0GA1UdDgQWBBS2oVQ5AsOgP46KvPrU+Bym0ToO/TAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZI
+hvcNAQENBQADggIBAHGlDs7k6b8/ONWJWsQCYftMxRQXLYtPU2sQF/xlhMcQSZDe28cmk4gmb3DW
+Al45oPePq5a1pRNcgRRtDoGCERuKTsZPpd1iHkTfCVn0W3cLN+mLIMb4Ck4uWBzrM9DPhmDJ2vuA
+L55MYIR4PSFk1vtBHxgP58l1cb29XN40hz5BsA72udY/CROWFC/emh1auVbONTqwX3BNXuMp8SMo
+clm2q8KMZiYcdywmdjWLKKdpoPk79SPdhRB0yZADVpHnr7pH1BKXESLjokmUbOe3lEu6LaTaM4tM
+pkT/WjzGHWTYtTHkpjx6qFcL2+1hGsvxznN3Y6SHb0xRONbkX8eftoEq5IVIeVheO/jbAoJnwTnb
+w3RLPTYe+SmTiGhbqEQZIfCn6IENLOiTNrQ3ssqwGyZ6miUfmpqAnksqP/ujmv5zMnHCnsZy4Ypo
+J/HkD7TETKVhk/iXEAcqMCWpuchxuO9ozC1+9eB+D4Kob7a6bINDd82Kkhehnlt4Fj1F4jNy3eFm
+ypnTycUm/Q1oBEauttmbjL4ZvrHG8hnjXALKLNhvSgfZyTXaQHXyxKcZb55CEJh15pWLYLztxRLX
+is7VmFxWlgPF7ncGNf/P5O4/E2Hu29othfDNrp2yGAlFw5Khchf8R7agCyzxxN5DaAhqXzvwdmP7
+zAYspsbiDrW5viSP
+-----END CERTIFICATE-----
+
+Hellenic Academic and Research Institutions RootCA 2015
+=======================================================
+-----BEGIN CERTIFICATE-----
+MIIGCzCCA/OgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBpjELMAkGA1UEBhMCR1IxDzANBgNVBAcT
+BkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0
+aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNl
+YXJjaCBJbnN0aXR1dGlvbnMgUm9vdENBIDIwMTUwHhcNMTUwNzA3MTAxMTIxWhcNNDAwNjMwMTAx
+MTIxWjCBpjELMAkGA1UEBhMCR1IxDzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMg
+QWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNV
+BAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9vdENBIDIw
+MTUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDC+Kk/G4n8PDwEXT2QNrCROnk8Zlrv
+bTkBSRq0t89/TSNTt5AA4xMqKKYx8ZEA4yjsriFBzh/a/X0SWwGDD7mwX5nh8hKDgE0GPt+sr+eh
+iGsxr/CL0BgzuNtFajT0AoAkKAoCFZVedioNmToUW/bLy1O8E00BiDeUJRtCvCLYjqOWXjrZMts+
+6PAQZe104S+nfK8nNLspfZu2zwnI5dMK/IhlZXQK3HMcXM1AsRzUtoSMTFDPaI6oWa7CJ06CojXd
+FPQf/7J31Ycvqm59JCfnxssm5uX+Zwdj2EUN3TpZZTlYepKZcj2chF6IIbjV9Cz82XBST3i4vTwr
+i5WY9bPRaM8gFH5MXF/ni+X1NYEZN9cRCLdmvtNKzoNXADrDgfgXy5I2XdGj2HUb4Ysn6npIQf1F
+GQatJ5lOwXBH3bWfgVMS5bGMSF0xQxfjjMZ6Y5ZLKTBOhE5iGV48zpeQpX8B653g+IuJ3SWYPZK2
+fu/Z8VFRfS0myGlZYeCsargqNhEEelC9MoS+L9xy1dcdFkfkR2YgP/SWxa+OAXqlD3pk9Q0Yh9mu
+iNX6hME6wGkoLfINaFGq46V3xqSQDqE3izEjR8EJCOtu93ib14L8hCCZSRm2Ekax+0VVFqmjZayc
+Bw/qa9wfLgZy7IaIEuQt218FL+TwA9MmM+eAws1CoRc0CwIDAQABo0IwQDAPBgNVHRMBAf8EBTAD
+AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUcRVnyMjJvXVdctA4GGqd83EkVAswDQYJKoZI
+hvcNAQELBQADggIBAHW7bVRLqhBYRjTyYtcWNl0IXtVsyIe9tC5G8jH4fOpCtZMWVdyhDBKg2mF+
+D1hYc2Ryx+hFjtyp8iY/xnmMsVMIM4GwVhO+5lFc2JsKT0ucVlMC6U/2DWDqTUJV6HwbISHTGzrM
+d/K4kPFox/la/vot9L/J9UUbzjgQKjeKeaO04wlshYaT/4mWJ3iBj2fjRnRUjtkNaeJK9E10A/+y
+d+2VZ5fkscWrv2oj6NSU4kQoYsRL4vDY4ilrGnB+JGGTe08DMiUNRSQrlrRGar9KC/eaj8GsGsVn
+82800vpzY4zvFrCopEYq+OsS7HK07/grfoxSwIuEVPkvPuNVqNxmsdnhX9izjFk0WaSrT2y7Hxjb
+davYy5LNlDhhDgcGH0tGEPEVvo2FXDtKK4F5D7Rpn0lQl033DlZdwJVqwjbDG2jJ9SrcR5q+ss7F
+Jej6A7na+RZukYT1HCjI/CbM1xyQVqdfbzoEvM14iQuODy+jqk+iGxI9FghAD/FGTNeqewjBCvVt
+J94Cj8rDtSvK6evIIVM4pcw72Hc3MKJP2W/R8kCtQXoXxdZKNYm3QdV8hn9VTYNKpXMgwDqvkPGa
+JI7ZjnHKe7iG2rKPmT4dEw0SEe7Uq/DpFXYC5ODfqiAeW2GFZECpkJcNrVPSWh2HagCXZWK0vm9q
+p/UsQu0yrbYhnr68
+-----END CERTIFICATE-----
+
+Hellenic Academic and Research Institutions ECC RootCA 2015
+===========================================================
+-----BEGIN CERTIFICATE-----
+MIICwzCCAkqgAwIBAgIBADAKBggqhkjOPQQDAjCBqjELMAkGA1UEBhMCR1IxDzANBgNVBAcTBkF0
+aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9u
+cyBDZXJ0LiBBdXRob3JpdHkxRDBCBgNVBAMTO0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJj
+aCBJbnN0aXR1dGlvbnMgRUNDIFJvb3RDQSAyMDE1MB4XDTE1MDcwNzEwMzcxMloXDTQwMDYzMDEw
+MzcxMlowgaoxCzAJBgNVBAYTAkdSMQ8wDQYDVQQHEwZBdGhlbnMxRDBCBgNVBAoTO0hlbGxlbmlj
+IEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9yaXR5MUQwQgYD
+VQQDEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIEVDQyBSb290
+Q0EgMjAxNTB2MBAGByqGSM49AgEGBSuBBAAiA2IABJKgQehLgoRc4vgxEZmGZE4JJS+dQS8KrjVP
+dJWyUWRrjWvmP3CV8AVER6ZyOFB2lQJajq4onvktTpnvLEhvTCUp6NFxW98dwXU3tNf6e3pCnGoK
+Vlp8aQuqgAkkbH7BRqNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0O
+BBYEFLQiC4KZJAEOnLvkDv2/+5cgk5kqMAoGCCqGSM49BAMCA2cAMGQCMGfOFmI4oqxiRaeplSTA
+GiecMjvAwNW6qef4BENThe5SId6d9SWDPp5YSy/XZxMOIQIwBeF1Ad5o7SofTUwJCA3sS61kFyjn
+dc5FZXIhF8siQQ6ME5g4mlRtm8rifOoCWCKR
+-----END CERTIFICATE-----
+
+Certplus Root CA G1
+===================
+-----BEGIN CERTIFICATE-----
+MIIFazCCA1OgAwIBAgISESBVg+QtPlRWhS2DN7cs3EYRMA0GCSqGSIb3DQEBDQUAMD4xCzAJBgNV
+BAYTAkZSMREwDwYDVQQKDAhDZXJ0cGx1czEcMBoGA1UEAwwTQ2VydHBsdXMgUm9vdCBDQSBHMTAe
+Fw0xNDA1MjYwMDAwMDBaFw0zODAxMTUwMDAwMDBaMD4xCzAJBgNVBAYTAkZSMREwDwYDVQQKDAhD
+ZXJ0cGx1czEcMBoGA1UEAwwTQ2VydHBsdXMgUm9vdCBDQSBHMTCCAiIwDQYJKoZIhvcNAQEBBQAD
+ggIPADCCAgoCggIBANpQh7bauKk+nWT6VjOaVj0W5QOVsjQcmm1iBdTYj+eJZJ+622SLZOZ5KmHN
+r49aiZFluVj8tANfkT8tEBXgfs+8/H9DZ6itXjYj2JizTfNDnjl8KvzsiNWI7nC9hRYt6kuJPKNx
+Qv4c/dMcLRC4hlTqQ7jbxofaqK6AJc96Jh2qkbBIb6613p7Y1/oA/caP0FG7Yn2ksYyy/yARujVj
+BYZHYEMzkPZHogNPlk2dT8Hq6pyi/jQu3rfKG3akt62f6ajUeD94/vI4CTYd0hYCyOwqaK/1jpTv
+LRN6HkJKHRUxrgwEV/xhc/MxVoYxgKDEEW4wduOU8F8ExKyHcomYxZ3MVwia9Az8fXoFOvpHgDm2
+z4QTd28n6v+WZxcIbekN1iNQMLAVdBM+5S//Ds3EC0pd8NgAM0lm66EYfFkuPSi5YXHLtaW6uOrc
+4nBvCGrch2c0798wct3zyT8j/zXhviEpIDCB5BmlIOklynMxdCm+4kLV87ImZsdo/Rmz5yCTmehd
+4F6H50boJZwKKSTUzViGUkAksnsPmBIgJPaQbEfIDbsYIC7Z/fyL8inqh3SV4EJQeIQEQWGw9CEj
+jy3LKCHyamz0GqbFFLQ3ZU+V/YDI+HLlJWvEYLF7bY5KinPOWftwenMGE9nTdDckQQoRb5fc5+R+
+ob0V8rqHDz1oihYHAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0G
+A1UdDgQWBBSowcCbkahDFXxdBie0KlHYlwuBsTAfBgNVHSMEGDAWgBSowcCbkahDFXxdBie0KlHY
+lwuBsTANBgkqhkiG9w0BAQ0FAAOCAgEAnFZvAX7RvUz1isbwJh/k4DgYzDLDKTudQSk0YcbX8ACh
+66Ryj5QXvBMsdbRX7gp8CXrc1cqh0DQT+Hern+X+2B50ioUHj3/MeXrKls3N/U/7/SMNkPX0XtPG
+YX2eEeAC7gkE2Qfdpoq3DIMku4NQkv5gdRE+2J2winq14J2by5BSS7CTKtQ+FjPlnsZlFT5kOwQ/
+2wyPX1wdaR+v8+khjPPvl/aatxm2hHSco1S1cE5j2FddUyGbQJJD+tZ3VTNPZNX70Cxqjm0lpu+F
+6ALEUz65noe8zDUa3qHpimOHZR4RKttjd5cUvpoUmRGywO6wT/gUITJDT5+rosuoD6o7BlXGEilX
+CNQ314cnrUlZp5GrRHpejXDbl85IULFzk/bwg2D5zfHhMf1bfHEhYxQUqq/F3pN+aLHsIqKqkHWe
+tUNy6mSjhEv9DKgma3GX7lZjZuhCVPnHHd/Qj1vfyDBviP4NxDMcU6ij/UgQ8uQKTuEVV/xuZDDC
+VRHc6qnNSlSsKWNEz0pAoNZoWRsz+e86i9sgktxChL8Bq4fA1SCC28a5g4VCXA9DO2pJNdWY9BW/
++mGBDAkgGNLQFwzLSABQ6XaCjGTXOqAHVcweMcDvOrRl++O/QmueD6i9a5jc2NvLi6Td11n0bt3+
+qsOR0C5CB8AMTVPNJLFMWx5R9N/pkvo=
+-----END CERTIFICATE-----
+
+Certplus Root CA G2
+===================
+-----BEGIN CERTIFICATE-----
+MIICHDCCAaKgAwIBAgISESDZkc6uo+jF5//pAq/Pc7xVMAoGCCqGSM49BAMDMD4xCzAJBgNVBAYT
+AkZSMREwDwYDVQQKDAhDZXJ0cGx1czEcMBoGA1UEAwwTQ2VydHBsdXMgUm9vdCBDQSBHMjAeFw0x
+NDA1MjYwMDAwMDBaFw0zODAxMTUwMDAwMDBaMD4xCzAJBgNVBAYTAkZSMREwDwYDVQQKDAhDZXJ0
+cGx1czEcMBoGA1UEAwwTQ2VydHBsdXMgUm9vdCBDQSBHMjB2MBAGByqGSM49AgEGBSuBBAAiA2IA
+BM0PW1aC3/BFGtat93nwHcmsltaeTpwftEIRyoa/bfuFo8XlGVzX7qY/aWfYeOKmycTbLXku54uN
+Am8xIk0G42ByRZ0OQneezs/lf4WbGOT8zC5y0xaTTsqZY1yhBSpsBqNjMGEwDgYDVR0PAQH/BAQD
+AgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNqDYwJ5jtpMxjwjFNiPwyCrKGBZMB8GA1Ud
+IwQYMBaAFNqDYwJ5jtpMxjwjFNiPwyCrKGBZMAoGCCqGSM49BAMDA2gAMGUCMHD+sAvZ94OX7PNV
+HdTcswYO/jOYnYs5kGuUIe22113WTNchp+e/IQ8rzfcq3IUHnQIxAIYUFuXcsGXCwI4Un78kFmjl
+vPl5adytRSv3tjFzzAalU5ORGpOucGpnutee5WEaXw==
+-----END CERTIFICATE-----
+
+OpenTrust Root CA G1
+====================
+-----BEGIN CERTIFICATE-----
+MIIFbzCCA1egAwIBAgISESCzkFU5fX82bWTCp59rY45nMA0GCSqGSIb3DQEBCwUAMEAxCzAJBgNV
+BAYTAkZSMRIwEAYDVQQKDAlPcGVuVHJ1c3QxHTAbBgNVBAMMFE9wZW5UcnVzdCBSb290IENBIEcx
+MB4XDTE0MDUyNjA4NDU1MFoXDTM4MDExNTAwMDAwMFowQDELMAkGA1UEBhMCRlIxEjAQBgNVBAoM
+CU9wZW5UcnVzdDEdMBsGA1UEAwwUT3BlblRydXN0IFJvb3QgQ0EgRzEwggIiMA0GCSqGSIb3DQEB
+AQUAA4ICDwAwggIKAoICAQD4eUbalsUwXopxAy1wpLuwxQjczeY1wICkES3d5oeuXT2R0odsN7fa
+Yp6bwiTXj/HbpqbfRm9RpnHLPhsxZ2L3EVs0J9V5ToybWL0iEA1cJwzdMOWo010hOHQX/uMftk87
+ay3bfWAfjH1MBcLrARYVmBSO0ZB3Ij/swjm4eTrwSSTilZHcYTSSjFR077F9jAHiOH3BX2pfJLKO
+YheteSCtqx234LSWSE9mQxAGFiQD4eCcjsZGT44ameGPuY4zbGneWK2gDqdkVBFpRGZPTBKnjix9
+xNRbxQA0MMHZmf4yzgeEtE7NCv82TWLxp2NX5Ntqp66/K7nJ5rInieV+mhxNaMbBGN4zK1FGSxyO
+9z0M+Yo0FMT7MzUj8czxKselu7Cizv5Ta01BG2Yospb6p64KTrk5M0ScdMGTHPjgniQlQ/GbI4Kq
+3ywgsNw2TgOzfALU5nsaqocTvz6hdLubDuHAk5/XpGbKuxs74zD0M1mKB3IDVedzagMxbm+WG+Oi
+n6+Sx+31QrclTDsTBM8clq8cIqPQqwWyTBIjUtz9GVsnnB47ev1CI9sjgBPwvFEVVJSmdz7QdFG9
+URQIOTfLHzSpMJ1ShC5VkLG631UAC9hWLbFJSXKAqWLXwPYYEQRVzXR7z2FwefR7LFxckvzluFqr
+TJOVoSfupb7PcSNCupt2LQIDAQABo2MwYTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB
+/zAdBgNVHQ4EFgQUl0YhVyE12jZVx/PxN3DlCPaTKbYwHwYDVR0jBBgwFoAUl0YhVyE12jZVx/Px
+N3DlCPaTKbYwDQYJKoZIhvcNAQELBQADggIBAB3dAmB84DWn5ph76kTOZ0BP8pNuZtQ5iSas000E
+PLuHIT839HEl2ku6q5aCgZG27dmxpGWX4m9kWaSW7mDKHyP7Rbr/jyTwyqkxf3kfgLMtMrpkZ2Cv
+uVnN35pJ06iCsfmYlIrM4LvgBBuZYLFGZdwIorJGnkSI6pN+VxbSFXJfLkur1J1juONI5f6ELlgK
+n0Md/rcYkoZDSw6cMoYsYPXpSOqV7XAp8dUv/TW0V8/bhUiZucJvbI/NeJWsZCj9VrDDb8O+WVLh
+X4SPgPL0DTatdrOjteFkdjpY3H1PXlZs5VVZV6Xf8YpmMIzUUmI4d7S+KNfKNsSbBfD4Fdvb8e80
+nR14SohWZ25g/4/Ii+GOvUKpMwpZQhISKvqxnUOOBZuZ2mKtVzazHbYNeS2WuOvyDEsMpZTGMKcm
+GS3tTAZQMPH9WD25SxdfGbRqhFS0OE85og2WaMMolP3tLR9Ka0OWLpABEPs4poEL0L9109S5zvE/
+bw4cHjdx5RiHdRk/ULlepEU0rbDK5uUTdg8xFKmOLZTW1YVNcxVPS/KyPu1svf0OnWZzsD2097+o
+4BGkxK51CUpjAEggpsadCwmKtODmzj7HPiY46SvepghJAwSQiumPv+i2tCqjI40cHLI5kqiPAlxA
+OXXUc0ECd97N4EOH1uS6SsNsEn/+KuYj1oxx
+-----END CERTIFICATE-----
+
+OpenTrust Root CA G2
+====================
+-----BEGIN CERTIFICATE-----
+MIIFbzCCA1egAwIBAgISESChaRu/vbm9UpaPI+hIvyYRMA0GCSqGSIb3DQEBDQUAMEAxCzAJBgNV
+BAYTAkZSMRIwEAYDVQQKDAlPcGVuVHJ1c3QxHTAbBgNVBAMMFE9wZW5UcnVzdCBSb290IENBIEcy
+MB4XDTE0MDUyNjAwMDAwMFoXDTM4MDExNTAwMDAwMFowQDELMAkGA1UEBhMCRlIxEjAQBgNVBAoM
+CU9wZW5UcnVzdDEdMBsGA1UEAwwUT3BlblRydXN0IFJvb3QgQ0EgRzIwggIiMA0GCSqGSIb3DQEB
+AQUAA4ICDwAwggIKAoICAQDMtlelM5QQgTJT32F+D3Y5z1zCU3UdSXqWON2ic2rxb95eolq5cSG+
+Ntmh/LzubKh8NBpxGuga2F8ORAbtp+Dz0mEL4DKiltE48MLaARf85KxP6O6JHnSrT78eCbY2albz
+4e6WiWYkBuTNQjpK3eCasMSCRbP+yatcfD7J6xcvDH1urqWPyKwlCm/61UWY0jUJ9gNDlP7ZvyCV
+eYCYitmJNbtRG6Q3ffyZO6v/v6wNj0OxmXsWEH4db0fEFY8ElggGQgT4hNYdvJGmQr5J1WqIP7wt
+UdGejeBSzFfdNTVY27SPJIjki9/ca1TSgSuyzpJLHB9G+h3Ykst2Z7UJmQnlrBcUVXDGPKBWCgOz
+3GIZ38i1MH/1PCZ1Eb3XG7OHngevZXHloM8apwkQHZOJZlvoPGIytbU6bumFAYueQ4xncyhZW+vj
+3CzMpSZyYhK05pyDRPZRpOLAeiRXyg6lPzq1O4vldu5w5pLeFlwoW5cZJ5L+epJUzpM5ChaHvGOz
+9bGTXOBut9Dq+WIyiET7vycotjCVXRIouZW+j1MY5aIYFuJWpLIsEPUdN6b4t/bQWVyJ98LVtZR0
+0dX+G7bw5tYee9I8y6jj9RjzIR9u701oBnstXW5DiabA+aC/gh7PU3+06yzbXfZqfUAkBXKJOAGT
+y3HCOV0GEfZvePg3DTmEJwIDAQABo2MwYTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB
+/zAdBgNVHQ4EFgQUajn6QiL35okATV59M4PLuG53hq8wHwYDVR0jBBgwFoAUajn6QiL35okATV59
+M4PLuG53hq8wDQYJKoZIhvcNAQENBQADggIBAJjLq0A85TMCl38th6aP1F5Kr7ge57tx+4BkJamz
+Gj5oXScmp7oq4fBXgwpkTx4idBvpkF/wrM//T2h6OKQQbA2xx6R3gBi2oihEdqc0nXGEL8pZ0keI
+mUEiyTCYYW49qKgFbdEfwFFEVn8nNQLdXpgKQuswv42hm1GqO+qTRmTFAHneIWv2V6CG1wZy7HBG
+S4tz3aAhdT7cHcCP009zHIXZ/n9iyJVvttN7jLpTwm+bREx50B1ws9efAvSyB7DH5fitIw6mVskp
+EndI2S9G/Tvw/HRwkqWOOAgfZDC2t0v7NqwQjqBSM2OdAzVWxWm9xiNaJ5T2pBL4LTM8oValX9YZ
+6e18CL13zSdkzJTaTkZQh+D5wVOAHrut+0dSixv9ovneDiK3PTNZbNTe9ZUGMg1RGUFcPk8G97kr
+gCf2o6p6fAbhQ8MTOWIaNr3gKC6UAuQpLmBVrkA9sHSSXvAgZJY/X0VdiLWK2gKgW0VU3jg9CcCo
+SmVGFvyqv1ROTVu+OEO3KMqLM6oaJbolXCkvW0pujOotnCr2BXbgd5eAiN1nE28daCSLT7d0geX0
+YJ96Vdc+N9oWaz53rK4YcJUIeSkDiv7BO7M/Gg+kO14fWKGVyasvc0rQLW6aWQ9VGHgtPFGml4vm
+u7JwqkwR3v98KzfUetF3NI/n+UL3PIEMS1IK
+-----END CERTIFICATE-----
+
+OpenTrust Root CA G3
+====================
+-----BEGIN CERTIFICATE-----
+MIICITCCAaagAwIBAgISESDm+Ez8JLC+BUCs2oMbNGA/MAoGCCqGSM49BAMDMEAxCzAJBgNVBAYT
+AkZSMRIwEAYDVQQKDAlPcGVuVHJ1c3QxHTAbBgNVBAMMFE9wZW5UcnVzdCBSb290IENBIEczMB4X
+DTE0MDUyNjAwMDAwMFoXDTM4MDExNTAwMDAwMFowQDELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCU9w
+ZW5UcnVzdDEdMBsGA1UEAwwUT3BlblRydXN0IFJvb3QgQ0EgRzMwdjAQBgcqhkjOPQIBBgUrgQQA
+IgNiAARK7liuTcpm3gY6oxH84Bjwbhy6LTAMidnW7ptzg6kjFYwvWYpa3RTqnVkrQ7cG7DK2uu5B
+ta1doYXM6h0UZqNnfkbilPPntlahFVmhTzeXuSIevRHr9LIfXsMUmuXZl5mjYzBhMA4GA1UdDwEB
+/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRHd8MUi2I5DMlv4VBN0BBY3JWIbTAf
+BgNVHSMEGDAWgBRHd8MUi2I5DMlv4VBN0BBY3JWIbTAKBggqhkjOPQQDAwNpADBmAjEAj6jcnboM
+BBf6Fek9LykBl7+BFjNAk2z8+e2AcG+qj9uEwov1NcoG3GRvaBbhj5G5AjEA2Euly8LQCGzpGPta
+3U1fJAuwACEl74+nBCZx4nxp5V2a+EEfOzmTk51V6s2N8fvB
+-----END CERTIFICATE-----
+
+ISRG Root X1
+============
+-----BEGIN CERTIFICATE-----
+MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAwTzELMAkGA1UE
+BhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2VhcmNoIEdyb3VwMRUwEwYDVQQD
+EwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQG
+EwJVUzEpMCcGA1UEChMgSW50ZXJuZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMT
+DElTUkcgUm9vdCBYMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54r
+Vygch77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+0TM8ukj1
+3Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6UA5/TR5d8mUgjU+g4rk8K
+b4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sWT8KOEUt+zwvo/7V3LvSye0rgTBIlDHCN
+Aymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyHB5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ
+4Q7e2RCOFvu396j3x+UCB5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf
+1b0SHzUvKBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWnOlFu
+hjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTnjh8BCNAw1FtxNrQH
+usEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbwqHyGO0aoSCqI3Haadr8faqU9GY/r
+OPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CIrU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4G
+A1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY
+9umbbjANBgkqhkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL
+ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ3BebYhtF8GaV
+0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KKNFtY2PwByVS5uCbMiogziUwt
+hDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJw
+TdwJx4nLCgdNbOhdjsnvzqvHu7UrTkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nx
+e5AW0wdeRlN8NwdCjNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZA
+JzVcoyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq4RgqsahD
+YVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPAmRGunUHBcnWEvgJBQl9n
+JEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57demyPxgcYxn/eR44/KJ4EBs+lVDR3veyJ
+m+kXQ99b21/+jh5Xos1AnX5iItreGCc=
+-----END CERTIFICATE-----
+
+AC RAIZ FNMT-RCM
+================
+-----BEGIN CERTIFICATE-----
+MIIFgzCCA2ugAwIBAgIPXZONMGc2yAYdGsdUhGkHMA0GCSqGSIb3DQEBCwUAMDsxCzAJBgNVBAYT
+AkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJWiBGTk1ULVJDTTAeFw0wODEw
+MjkxNTU5NTZaFw0zMDAxMDEwMDAwMDBaMDsxCzAJBgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJD
+TTEZMBcGA1UECwwQQUMgUkFJWiBGTk1ULVJDTTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC
+ggIBALpxgHpMhm5/yBNtwMZ9HACXjywMI7sQmkCpGreHiPibVmr75nuOi5KOpyVdWRHbNi63URcf
+qQgfBBckWKo3Shjf5TnUV/3XwSyRAZHiItQDwFj8d0fsjz50Q7qsNI1NOHZnjrDIbzAzWHFctPVr
+btQBULgTfmxKo0nRIBnuvMApGGWn3v7v3QqQIecaZ5JCEJhfTzC8PhxFtBDXaEAUwED653cXeuYL
+j2VbPNmaUtu1vZ5Gzz3rkQUCwJaydkxNEJY7kvqcfw+Z374jNUUeAlz+taibmSXaXvMiwzn15Cou
+08YfxGyqxRxqAQVKL9LFwag0Jl1mpdICIfkYtwb1TplvqKtMUejPUBjFd8g5CSxJkjKZqLsXF3mw
+WsXmo8RZZUc1g16p6DULmbvkzSDGm0oGObVo/CK67lWMK07q87Hj/LaZmtVC+nFNCM+HHmpxffnT
+tOmlcYF7wk5HlqX2doWjKI/pgG6BU6VtX7hI+cL5NqYuSf+4lsKMB7ObiFj86xsc3i1w4peSMKGJ
+47xVqCfWS+2QrYv6YyVZLag13cqXM7zlzced0ezvXg5KkAYmY6252TUtB7p2ZSysV4999AeU14EC
+ll2jB0nVetBX+RvnU0Z1qrB5QstocQjpYL05ac70r8NWQMetUqIJ5G+GR4of6ygnXYMgrwTJbFaa
+i0b1AgMBAAGjgYMwgYAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE
+FPd9xf3E6Jobd2Sn9R2gzL+HYJptMD4GA1UdIAQ3MDUwMwYEVR0gADArMCkGCCsGAQUFBwIBFh1o
+dHRwOi8vd3d3LmNlcnQuZm5tdC5lcy9kcGNzLzANBgkqhkiG9w0BAQsFAAOCAgEAB5BK3/MjTvDD
+nFFlm5wioooMhfNzKWtN/gHiqQxjAb8EZ6WdmF/9ARP67Jpi6Yb+tmLSbkyU+8B1RXxlDPiyN8+s
+D8+Nb/kZ94/sHvJwnvDKuO+3/3Y3dlv2bojzr2IyIpMNOmqOFGYMLVN0V2Ue1bLdI4E7pWYjJ2cJ
+j+F3qkPNZVEI7VFY/uY5+ctHhKQV8Xa7pO6kO8Rf77IzlhEYt8llvhjho6Tc+hj507wTmzl6NLrT
+Qfv6MooqtyuGC2mDOL7Nii4LcK2NJpLuHvUBKwrZ1pebbuCoGRw6IYsMHkCtA+fdZn71uSANA+iW
++YJF1DngoABd15jmfZ5nc8OaKveri6E6FO80vFIOiZiaBECEHX5FaZNXzuvO+FB8TxxuBEOb+dY7
+Ixjp6o7RTUaN8Tvkasq6+yO3m/qZASlaWFot4/nUbQ4mrcFuNLwy+AwF+mWj2zs3gyLp1txyM/1d
+8iC9djwj2ij3+RvrWWTV3F9yfiD8zYm1kGdNYno/Tq0dwzn+evQoFt9B9kiABdcPUXmsEKvU7ANm
+5mqwujGSQkBqvjrTcuFqN1W8rB2Vt2lh8kORdOag0wokRqEIr9baRRmW1FMdW4R58MD3R++Lj8UG
+rp1MYp3/RgT408m2ECVAdf4WqslKYIYvuu8wd+RU4riEmViAqhOLUTpPSPaLtrM=
+-----END CERTIFICATE-----
+
+Amazon Root CA 1
+================
+-----BEGIN CERTIFICATE-----
+MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsFADA5MQswCQYD
+VQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSAxMB4XDTE1
+MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpv
+bjEZMBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
+ggEBALJ4gHHKeNXjca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgH
+FzZM9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qwIFAGbHrQ
+gLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6VOujw5H5SNz/0egwLX0t
+dHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L93FcXmn/6pUCyziKrlA4b9v7LWIbxcce
+VOF34GfID5yHI9Y/QCB/IIDEgEw+OyQmjgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB
+/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3
+DQEBCwUAA4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDIU5PM
+CCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUsN+gDS63pYaACbvXy
+8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vvo/ufQJVtMVT8QtPHRh8jrdkPSHCa
+2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2
+xJNDd2ZhwLnoQdeXeGADbkpyrqXRfboQnoZsG4q5WTP468SQvvG5
+-----END CERTIFICATE-----
+
+Amazon Root CA 2
+================
+-----BEGIN CERTIFICATE-----
+MIIFQTCCAymgAwIBAgITBmyf0pY1hp8KD+WGePhbJruKNzANBgkqhkiG9w0BAQwFADA5MQswCQYD
+VQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSAyMB4XDTE1
+MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpv
+bjEZMBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC
+ggIBAK2Wny2cSkxKgXlRmeyKy2tgURO8TW0G/LAIjd0ZEGrHJgw12MBvIITplLGbhQPDW9tK6Mj4
+kHbZW0/jTOgGNk3Mmqw9DJArktQGGWCsN0R5hYGCrVo34A3MnaZMUnbqQ523BNFQ9lXg1dKmSYXp
+N+nKfq5clU1Imj+uIFptiJXZNLhSGkOQsL9sBbm2eLfq0OQ6PBJTYv9K8nu+NQWpEjTj82R0Yiw9
+AElaKP4yRLuH3WUnAnE72kr3H9rN9yFVkE8P7K6C4Z9r2UXTu/Bfh+08LDmG2j/e7HJV63mjrdvd
+fLC6HM783k81ds8P+HgfajZRRidhW+mez/CiVX18JYpvL7TFz4QuK/0NURBs+18bvBt+xa47mAEx
+kv8LV/SasrlX6avvDXbR8O70zoan4G7ptGmh32n2M8ZpLpcTnqWHsFcQgTfJU7O7f/aS0ZzQGPSS
+btqDT6ZjmUyl+17vIWR6IF9sZIUVyzfpYgwLKhbcAS4y2j5L9Z469hdAlO+ekQiG+r5jqFoz7Mt0
+Q5X5bGlSNscpb/xVA1wf+5+9R+vnSUeVC06JIglJ4PVhHvG/LopyboBZ/1c6+XUyo05f7O0oYtlN
+c/LMgRdg7c3r3NunysV+Ar3yVAhU/bQtCSwXVEqY0VThUWcI0u1ufm8/0i2BWSlmy5A5lREedCf+
+3euvAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSw
+DPBMMPQFWAJI/TPlUq9LhONmUjANBgkqhkiG9w0BAQwFAAOCAgEAqqiAjw54o+Ci1M3m9Zh6O+oA
+A7CXDpO8Wqj2LIxyh6mx/H9z/WNxeKWHWc8w4Q0QshNabYL1auaAn6AFC2jkR2vHat+2/XcycuUY
++gn0oJMsXdKMdYV2ZZAMA3m3MSNjrXiDCYZohMr/+c8mmpJ5581LxedhpxfL86kSk5Nrp+gvU5LE
+YFiwzAJRGFuFjWJZY7attN6a+yb3ACfAXVU3dJnJUH/jWS5E4ywl7uxMMne0nxrpS10gxdr9HIcW
+xkPo1LsmmkVwXqkLN1PiRnsn/eBG8om3zEK2yygmbtmlyTrIQRNg91CMFa6ybRoVGld45pIq2WWQ
+gj9sAq+uEjonljYE1x2igGOpm/HlurR8FLBOybEfdF849lHqm/osohHUqS0nGkWxr7JOcQ3AWEbW
+aQbLU8uz/mtBzUF+fUwPfHJ5elnNXkoOrJupmHN5fLT0zLm4BwyydFy4x2+IoZCn9Kr5v2c69BoV
+Yh63n749sSmvZ6ES8lgQGVMDMBu4Gon2nL2XA46jCfMdiyHxtN/kHNGfZQIG6lzWE7OE76KlXIx3
+KadowGuuQNKotOrN8I1LOJwZmhsoVLiJkO/KdYE+HvJkJMcYr07/R54H9jVlpNMKVv/1F2Rs76gi
+JUmTtt8AF9pYfl3uxRuw0dFfIRDH+fO6AgonB8Xx1sfT4PsJYGw=
+-----END CERTIFICATE-----
+
+Amazon Root CA 3
+================
+-----BEGIN CERTIFICATE-----
+MIIBtjCCAVugAwIBAgITBmyf1XSXNmY/Owua2eiedgPySjAKBggqhkjOPQQDAjA5MQswCQYDVQQG
+EwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSAzMB4XDTE1MDUy
+NjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZ
+MBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCmXp8ZB
+f8ANm+gBG1bG8lKlui2yEujSLtf6ycXYqm0fc4E7O5hrOXwzpcVOho6AF2hiRVd9RFgdszflZwjr
+Zt6jQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSrttvXBp43
+rDCGB5Fwx5zEGbF4wDAKBggqhkjOPQQDAgNJADBGAiEA4IWSoxe3jfkrBqWTrBqYaGFy+uGh0Psc
+eGCmQ5nFuMQCIQCcAu/xlJyzlvnrxir4tiz+OpAUFteMYyRIHN8wfdVoOw==
+-----END CERTIFICATE-----
+
+Amazon Root CA 4
+================
+-----BEGIN CERTIFICATE-----
+MIIB8jCCAXigAwIBAgITBmyf18G7EEwpQ+Vxe3ssyBrBDjAKBggqhkjOPQQDAzA5MQswCQYDVQQG
+EwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSA0MB4XDTE1MDUy
+NjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZ
+MBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgNDB2MBAGByqGSM49AgEGBSuBBAAiA2IABNKrijdPo1MN
+/sGKe0uoe0ZLY7Bi9i0b2whxIdIA6GO9mif78DluXeo9pcmBqqNbIJhFXRbb/egQbeOc4OO9X4Ri
+83BkM6DLJC9wuoihKqB1+IGuYgbEgds5bimwHvouXKNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV
+HQ8BAf8EBAMCAYYwHQYDVR0OBBYEFNPsxzplbszh2naaVvuc84ZtV+WBMAoGCCqGSM49BAMDA2gA
+MGUCMDqLIfG9fhGt0O9Yli/W651+kI0rz2ZVwyzjKKlwCkcO8DdZEv8tmZQoTipPNU0zWgIxAOp1
+AE47xDqUEpHJWEadIRNyp4iciuRMStuW1KyLa2tJElMzrdfkviT8tQp21KW8EA==
+-----END CERTIFICATE-----
+
+LuxTrust Global Root 2
+======================
+-----BEGIN CERTIFICATE-----
+MIIFwzCCA6ugAwIBAgIUCn6m30tEntpqJIWe5rgV0xZ/u7EwDQYJKoZIhvcNAQELBQAwRjELMAkG
+A1UEBhMCTFUxFjAUBgNVBAoMDUx1eFRydXN0IFMuQS4xHzAdBgNVBAMMFkx1eFRydXN0IEdsb2Jh
+bCBSb290IDIwHhcNMTUwMzA1MTMyMTU3WhcNMzUwMzA1MTMyMTU3WjBGMQswCQYDVQQGEwJMVTEW
+MBQGA1UECgwNTHV4VHJ1c3QgUy5BLjEfMB0GA1UEAwwWTHV4VHJ1c3QgR2xvYmFsIFJvb3QgMjCC
+AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANeFl78RmOnwYoNMPIf5U2o3C/IPPIfOb9wm
+Kb3FibrJgz337spbxm1Jc7TJRqMbNBM/wYlFV/TZsfs2ZUv7COJIcRHIbjuend+JZTemhfY7RBi2
+xjcwYkSSl2l9QjAk5A0MiWtj3sXh306pFGxT4GHO9hcvHTy95iJMHZP1EMShduxq3sVs35a0VkBC
+wGKSMKEtFZSg0iAGCW5qbeXrt77U8PEVfIvmTroTzEsnXpk8F12PgX8zPU/TPxvsXD/wPEx1bvKm
+1Z3aLQdjAsZy6ZS8TEmVT4hSyNvoaYL4zDRbIvCGp4m9SAptZoFtyMhk+wHh9OHe2Z7d21vUKpkm
+FRseTJIpgp7VkoGSQXAZ96Tlk0u8d2cx3Rz9MXANF5kM+Qw5GSoXtTBxVdUPrljhPS80m8+f9niF
+wpN6cj5mj5wWEWCPnolvZ77gR1o7DJpni89Gxq44o/KnvObWhWszJHAiS8sIm7vI+AIpHb4gDEa/
+a4ebsypmQjVGbKq6rfmYe+lQVRQxv7HaLe2ArWgk+2mr2HETMOZns4dA/Yl+8kPREd8vZS9kzl8U
+ubG/Mb2HeFpZZYiq/FkySIbWTLkpS5XTdvN3JW1CHDiDTf2jX5t/Lax5Gw5CMZdjpPuKadUiDTSQ
+MC6otOBttpSsvItO13D8xTiOZCXhTTmQzsmHhFhxAgMBAAGjgagwgaUwDwYDVR0TAQH/BAUwAwEB
+/zBCBgNVHSAEOzA5MDcGByuBKwEBAQowLDAqBggrBgEFBQcCARYeaHR0cHM6Ly9yZXBvc2l0b3J5
+Lmx1eHRydXN0Lmx1MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBT/GCh2+UgFLKGu8SsbK7JT
++Et8szAdBgNVHQ4EFgQU/xgodvlIBSyhrvErGyuyU/hLfLMwDQYJKoZIhvcNAQELBQADggIBAGoZ
+FO1uecEsh9QNcH7X9njJCwROxLHOk3D+sFTAMs2ZMGQXvw/l4jP9BzZAcg4atmpZ1gDlaCDdLnIN
+H2pkMSCEfUmmWjfrRcmF9dTHF5kH5ptV5AzoqbTOjFu1EVzPig4N1qx3gf4ynCSecs5U89BvolbW
+7MM3LGVYvlcAGvI1+ut7MV3CwRI9loGIlonBWVx65n9wNOeD4rHh4bhY79SV5GCc8JaXcozrhAIu
+ZY+kt9J/Z93I055cqqmkoCUUBpvsT34tC38ddfEz2O3OuHVtPlu5mB0xDVbYQw8wkbIEa91WvpWA
+VWe+2M2D2RjuLg+GLZKecBPs3lHJQ3gCpU3I+V/EkVhGFndadKpAvAefMLmx9xIX3eP/JEAdemrR
+TxgKqpAd60Ae36EeRJIQmvKN4dFLRp7oRUKX6kWZ8+xm1QL68qZKJKrezrnK+T+Tb/mjuuqlPpmt
+/f97mfVl7vBZKGfXkJWkE4SphMHozs51k2MavDzq1WQfLSoSOcbDWjLtR5EWDrw4wVDej8oqkDQc
+7kGUnF4ZLvhFSZl0kbAEb+MEWrGrKqv+x9CWttrhSmQGbmBNvUJO/3jaJMobtNeWOWyu8Q6qp31I
+iyBMz2TWuJdGsE7RKlY6oJO9r4Ak4Ap+58rVyuiFVdw2KuGUaJPHZnJED4AhMmwlxyOAgwrr
+-----END CERTIFICATE-----
+
+TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1
+=============================================
+-----BEGIN CERTIFICATE-----
+MIIEYzCCA0ugAwIBAgIBATANBgkqhkiG9w0BAQsFADCB0jELMAkGA1UEBhMCVFIxGDAWBgNVBAcT
+D0dlYnplIC0gS29jYWVsaTFCMEAGA1UEChM5VHVya2l5ZSBCaWxpbXNlbCB2ZSBUZWtub2xvamlr
+IEFyYXN0aXJtYSBLdXJ1bXUgLSBUVUJJVEFLMS0wKwYDVQQLEyRLYW11IFNlcnRpZmlrYXN5b24g
+TWVya2V6aSAtIEthbXUgU00xNjA0BgNVBAMTLVRVQklUQUsgS2FtdSBTTSBTU0wgS29rIFNlcnRp
+ZmlrYXNpIC0gU3VydW0gMTAeFw0xMzExMjUwODI1NTVaFw00MzEwMjUwODI1NTVaMIHSMQswCQYD
+VQQGEwJUUjEYMBYGA1UEBxMPR2ViemUgLSBLb2NhZWxpMUIwQAYDVQQKEzlUdXJraXllIEJpbGlt
+c2VsIHZlIFRla25vbG9qaWsgQXJhc3Rpcm1hIEt1cnVtdSAtIFRVQklUQUsxLTArBgNVBAsTJEth
+bXUgU2VydGlmaWthc3lvbiBNZXJrZXppIC0gS2FtdSBTTTE2MDQGA1UEAxMtVFVCSVRBSyBLYW11
+IFNNIFNTTCBLb2sgU2VydGlmaWthc2kgLSBTdXJ1bSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
+MIIBCgKCAQEAr3UwM6q7a9OZLBI3hNmNe5eA027n/5tQlT6QlVZC1xl8JoSNkvoBHToP4mQ4t4y8
+6Ij5iySrLqP1N+RAjhgleYN1Hzv/bKjFxlb4tO2KRKOrbEz8HdDc72i9z+SqzvBV96I01INrN3wc
+wv61A+xXzry0tcXtAA9TNypN9E8Mg/uGz8v+jE69h/mniyFXnHrfA2eJLJ2XYacQuFWQfw4tJzh0
+3+f92k4S400VIgLI4OD8D62K18lUUMw7D8oWgITQUVbDjlZ/iSIzL+aFCr2lqBs23tPcLG07xxO9
+WSMs5uWk99gL7eqQQESolbuT1dCANLZGeA4fAJNG4e7p+exPFwIDAQABo0IwQDAdBgNVHQ4EFgQU
+ZT/HiobGPN08VFw1+DrtUgxHV8gwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJ
+KoZIhvcNAQELBQADggEBACo/4fEyjq7hmFxLXs9rHmoJ0iKpEsdeV31zVmSAhHqT5Am5EM2fKifh
+AHe+SMg1qIGf5LgsyX8OsNJLN13qudULXjS99HMpw+0mFZx+CFOKWI3QSyjfwbPfIPP54+M638yc
+lNhOT8NrF7f3cuitZjO1JVOr4PhMqZ398g26rrnZqsZr+ZO7rqu4lzwDGrpDxpa5RXI4s6ehlj2R
+e37AIVNMh+3yC1SVUZPVIqUNivGTDj5UDrDYyU7c8jEyVupk+eq1nRZmQnLzf9OxMUP8pI4X8W0j
+q5Rm+K37DwhuJi1/FwcJsoz7UMCflo3Ptv0AnVoUmr8CRPXBwp8iXqIPoeM=
+-----END CERTIFICATE-----
diff --git a/lib/shoes/cache.rb b/lib/shoes/cache.rb
index 5d1cebaf..26ae4efd 100644
--- a/lib/shoes/cache.rb
+++ b/lib/shoes/cache.rb
@@ -1,9 +1,11 @@
require 'fileutils'
include FileUtils
-# add it download.rb monkey patches Shoes download -replaces curl
+# download.rb monkey patches Shoes download -replaces curl
require_relative 'download.rb'
# locate ~/.shoes
require 'tmpdir'
+require 'rubygems' # Loads a Gem class
+
lib_dir = nil
homes = []
homes << [ENV['LOCALAPPDATA'], File.join( ENV['LOCALAPPDATA'], 'Shoes')] if ENV['LOCALAPPDATA']
@@ -18,7 +20,8 @@
end
LIB_DIR = lib_dir || File.join(Dir::tmpdir, "shoes")
#LIB_DIR.gsub! /\\/, '\/'
-LIB_DIR.gsub! /\\+/, "/"
+#LIB_DIR.gsub! /\\+/, "/"
+LIB_DIR.gsub!(/\\/, '/') # should not be needed?
tight_shoes = Shoes::RELEASE_TYPE =~ /TIGHT/
rbv = RbConfig::CONFIG['ruby_version']
@@ -29,6 +32,12 @@
$:.unshift SITE_LIB_DIR
$:.unshift GEM_DIR
ENV['GEM_HOME'] = GEM_DIR
+ np = []
+ ENV['PATH'].split(':').each do |p|
+ np << p unless p =~ /\/.(rvm|rbenv)\//
+ end
+ ENV['PATH'] = np.join(':')
+ #$stderr.puts "replaced $PATH with #{ENV['PATH']}"
else
#puts "LOOSE Shoes #{RUBY_VERSION} #{DIR}"
$:.unshift ENV['GEM_HOME'] if ENV['GEM_HOME']
@@ -49,10 +58,6 @@
$:.unshift DIR+"/lib/ruby/#{rv}/#{RbConfig::CONFIG['arch']}"
$:.unshift DIR+"/lib/ruby/#{rv}"
$:.unshift DIR+"/lib/shoes"
- # May encounter ENV['GEM_PATH'] in the wild.
- #if ENV['GEM_PATH']
- # ENV['GEM_PATH'].split(':').each {|p| $:.unshift p }
- #end
end
CACHE_DIR = File.join(LIB_DIR, '+cache')
@@ -87,10 +92,9 @@
'LDFLAGS' => "-L. -L#{DIR}",
'rubylibprefix' => "#{DIR}/ruby"
}
- #debug "DYLD = #{ENV['DYLD_LIBRARY_PATH']} DIR = #{DIR}"
RbConfig::CONFIG.merge! config
RbConfig::MAKEFILE_CONFIG.merge! config
- # Add refs to Shoes builtin Gems (but not exts?)
+ # Add paths to Shoes builtin Gems TODO: may not be needed
GEM_CENTRAL_DIR = File.join(DIR, 'lib/ruby/gems/' + RbConfig::CONFIG['ruby_version'])
Dir[GEM_CENTRAL_DIR + "/gems/*"].each do |gdir|
$: << "#{gdir}/lib"
@@ -114,20 +118,45 @@
ShoesGemJailBreak = true
else
if ENV['GEM_PATH']
- # disable GEM_PATH if its in use otherwise funny things occur.
- ENV.delete('GEM_PATH')
+ # replace GEM_PATH
+ ENV['GEM_PATH'] = "#{GEM_DIR}:#{GEM_CENTRAL_DIR}"
+ Gem.use_paths(GEM_DIR, [GEM_DIR, GEM_CENTRAL_DIR])
+ Gem.refresh
end
ShoesGemJailBreak = false
end
else # Loose Shoes
ShoesGemJailBreak = true
- # 'rubylibprefix' then 'libdir' for gem's rb and so
- # FIXME - lib/shoes/setup.rb uses GEM_DIR and GEM_CENTRAL_DIR
- # Set this to where the users/system Ruby keeps things.
+ # NOTE - lib/shoes/setup.rb uses GEM_DIR and GEM_CENTRAL_DIR
+ # GEM_DIR would point to ~/.shoes/+gem and we don't want that
+ # GEM_CENTRAL_DIR points to Ruby's gems
+ # TODO: assumes rvm or system ruby BUT system ruby could be RVM
+ # Doesn't deal with rbenv setups
if ENV['GEM_HOME'] && ENV['GEM_HOME'] =~ /home\/.*\/.rvm/
- GEM_CENTRAL_DIR = GEM_DIR = ENV['GEM_HOME']
+ GEM_CENTRAL_DIR = GEM_DIR = ENV['GEM_HOME']
else
- puts "Please set GEM_HOME env var or use rvm"
+ # here from a Menu launch of a loose shoes -- GEM_HOME, GEM_PATH do not exist
+ # only minlin and minbsd can do this - they probably shouldn't attempt it, but still?
+ # We guess where the gems are
+ gp = "" #path to rubygems internal store
+ binloc = RbConfig::CONFIG['prefix']
+ rbv = RbConfig::CONFIG['ruby_version']
+ if binloc =~ /home\/.*\/.rvm/
+ gp = "#{ENV['HOME']}/.rvm/gems/ruby-#{RUBY_VERSION}"
+ elsif binloc =~ /\/usr\//
+ # ruby is installed in system dirs - bsd?
+ gp = "#{binloc}/lib/ruby/gems/#{rbv}"
+ else
+ gp = "Missing"
+ end
+ #debug "Trying to use #{gp} and #{ip}"
+ GEM_CENTRAL_DIR = GEM_DIR = gp # don't use ~/.shoes/+gem/
+ Dir[GEM_CENTRAL_DIR + "/gems/*"].each do |gdir|
+ #debug "adding to loadpath: #{gdir}"
+ $: << "#{gdir}/lib"
+ end
+ Gem.use_paths(GEM_DIR, [GEM_DIR, GEM_CENTRAL_DIR])
+ Gem.refresh
end
end
# find vlc libs
diff --git a/lib/shoes/chipmunk.rb b/lib/shoes/chipmunk.rb
index 92c3308e..851feee4 100644
--- a/lib/shoes/chipmunk.rb
+++ b/lib/shoes/chipmunk.rb
@@ -1,4 +1,5 @@
-require 'chipmunk.so'
+#require 'chipmunk.so' #ext
+require 'chipmunk/chipmunk.so' #gem
module ChipMunk
def cp_space
diff --git a/lib/shoes/cobbler.rb b/lib/shoes/cobbler.rb
index cec984f0..2af6b603 100644
--- a/lib/shoes/cobbler.rb
+++ b/lib/shoes/cobbler.rb
@@ -289,29 +289,34 @@ def imgdeletef
def cp_samples_screen
@panel.clear
@panel.append do
- para "Copy samples to a directory you can see and edit."
- para "Chose a directory that you want the Samples directory"
- para "to be created inside of."
- button "Select Directory for a copy of" do
- # OSX is a bit brain dead for ask_save_folder
- if destdir = ask_save_folder()
- @panel.append do
- para "Copy #{DIR}/samples/* to #{destdir}/Samples ?"
- button "OK" do
- @panel.append do
- @lb = edit_box
- end
- ary = []
- require 'fileutils'
- mkdir_p destdir
- sampdir = File.join DIR, 'samples'
- cd sampdir do
- Dir.glob('*').each do |fp|
- cp fp, destdir
- ary << fp
- @lb.text = ary.join("\n")
- end
- end
+ para "Copy samples to a directory you can see and edit."
+ para "Chose a directory that you want the samples directories"
+ para "to be created inside of."
+ button "Select Directory for a copy to" do
+ # OSX is a bit brain dead for ask_save_folder
+ if destdir = ask_save_folder()
+ @panel.append do
+ para "Copy #{DIR}/samples/* to #{destdir} ?"
+ button "OK" do
+ @panel.append do
+ @lb = edit_box width: 400
+ end
+ ary = []
+ require 'fileutils'
+ mkdir_p destdir
+ sampdir = File.join DIR, 'samples'
+ ary.push "In #{destdir}"
+ cd sampdir do
+ Dir.glob('*') do |d| # simple, good, expert in a perfect world
+ mkdir_p "#{destdir}/#{d}"
+ Dir.glob("#{d}/*").each do |f|
+ cp_r f, "#{destdir}/#{d}"
+ ary << f
+ end
+ end
+ @lb.text = ary.join("\n")
+ end
+ #alert "copied"
end
end
end
diff --git a/lib/shoes/deprecated.rb b/lib/shoes/deprecated.rb
new file mode 100644
index 00000000..a0681644
--- /dev/null
+++ b/lib/shoes/deprecated.rb
@@ -0,0 +1,23 @@
+require 'rubygems'
+
+class Shoes
+ module Types
+ class Background
+ extend Gem::Deprecate
+
+ deprecate :to_pattern, :none, 2017, 10
+ end
+
+ class Border
+ extend Gem::Deprecate
+
+ deprecate :to_pattern, :none, 2017, 10
+ end
+
+ class Color
+ extend Gem::Deprecate
+
+ deprecate :to_pattern, :none, 2017, 10
+ end
+ end
+end
diff --git a/lib/shoes/download.rb b/lib/shoes/download.rb
index 684e5bd3..306b648b 100644
--- a/lib/shoes/download.rb
+++ b/lib/shoes/download.rb
@@ -32,8 +32,11 @@ def start_download(url)
uri_opts[:content_length_proc] = content_length_proc
uri_opts[:progress_proc] = progress_proc if @opts[:progress]
uri_opts[:redirect_to_https] = true
- uri_opts[:ssl_verify_mode] = OpenSSL::SSL::VERIFY_NONE
-
+ #uri_opts[:ssl_verify_mode] = OpenSSL::SSL::VERIFY_NONE
+ uri_opts[:ssl_verify_mode] = OpenSSL::SSL::VERIFY_PEER
+ if RUBY_PLATFORM =~ /mingw|darwin/
+ uri_opts[:ssl_ca_cert] = File.join(DIR, "lib/shoes/cacert.pem")
+ end
open url, uri_opts do |f|
# everything has been downloaded at this point. f is a tempfile
finish_download f
diff --git a/lib/shoes/help.rb b/lib/shoes/help.rb
index 744e8bfc..fa74fb19 100644
--- a/lib/shoes/help.rb
+++ b/lib/shoes/help.rb
@@ -134,10 +134,12 @@ def dewikify(str, intro = false)
def sample_page
folder = File.join DIR, 'samples'
h = {}
- Dir.glob(File.join folder, '**/**').each do |file|
- if File.extname(file) == '.rb'
- key = File.basename(file).split('-')[0]
- h[key] ? h[key].push(file) : h[key] = [file]
+ ['simple', 'good', 'expert'].each do |d|
+ Dir.glob(File.join folder, d, "*").each do |file|
+ if File.extname(file) == '.rb'
+ key = File.basename(file)
+ h[d] ? h[d].push(file) : h[d] = [file]
+ end
end
end
stack do
@@ -145,7 +147,7 @@ def sample_page
subtitle k
flow do
v.sort.each do |file|
- para link(File.basename(file).split('-')[1..-1].join('-')[0..-4]){
+ para link(File.basename(file, '.rb')) {
Dir.chdir(folder){eval IO.read(file).force_encoding("UTF-8"), TOPLEVEL_BINDING}
}
end
diff --git a/lib/shoes/image.rb b/lib/shoes/image.rb
index 6f4a7e78..89158d94 100644
--- a/lib/shoes/image.rb
+++ b/lib/shoes/image.rb
@@ -1,7 +1,7 @@
require 'shoes/open-uri-patch'
require 'shoes/HttpResponse'
require 'openssl'
-#require 'digest/sha1'
+require 'digest/sha1'
class Shoes
def self.image_temp_path uri, uext
@@ -27,7 +27,12 @@ def self.image_download_sync url, opts
begin
uri_opts = {}
uri_opts[:redirect_to_https] = true
- uri_opts[:ssl_verify_mode] = OpenSSL::SSL::VERIFY_NONE
+ #uri_opts[:ssl_verify_mode] = OpenSSL::SSL::VERIFY_NONE
+ uri_opts[:ssl_verify_mode] = OpenSSL::SSL::VERIFY_PEER
+ if RUBY_PLATFORM =~ /mingw|darwin/
+ $stderr.puts "fixing ssl"
+ uri_opts[:ssl_ca_cert] = File.join(DIR, "lib/shoes/cacert.pem")
+ end
open url, uri_opts do |f|
# everything has been downloaded at this point.
# f is a tempfile like creature
diff --git a/lib/shoes/packshoes.rb b/lib/shoes/packshoes.rb
index cd75e038..0310de22 100644
--- a/lib/shoes/packshoes.rb
+++ b/lib/shoes/packshoes.rb
@@ -128,7 +128,6 @@ def PackShoes.dnlif_linux opts
end
def PackShoes.repack_linux opts, &blk
- #opts.each {|k, v| puts "#{k} => #{v}"}
arch = opts['arch']
script = custom_installer opts
name = File.basename(script).gsub(/\.\w+$/, '')
@@ -143,29 +142,29 @@ def PackShoes.repack_linux opts, &blk
blk.call"Expanding #{arch} distribution. Patience is needed"
end
# skip to the tar contents in the .run
- size = Shy.hrun(pkgf)
- # Copy the rest to a new file
- wk_dir = File.join(opts['packtmp'], "+tmp")
+ size = Shy.hrun(pkgf)
+ # Copy the rest to a new file
+ wk_dir = File.join(opts['packtmp'], "+tmp")
FileUtils.mkdir_p(wk_dir)
- wkf = open(File.join(wk_dir,"run.gz"),'wb')
- buff = ''
- while pkgf.read(32768, buff) != nil do
- wkf.write(buff)
- end
- wkf.close
- if blk
- blk.call "Start extract"
- end
- @tarmodes = {}
- fastxzf(wkf, tmp_dir, @tarmodes)
+ wkf = open(File.join(wk_dir,"run.gz"),'wb')
+ buff = ''
+ while pkgf.read(32768, buff) != nil do
+ wkf.write(buff)
+ end
+ wkf.close
+ if blk
+ blk.call "Start extract"
+ end
+ @tarmodes = {}
+ fastxzf(wkf, tmp_dir, @tarmodes)
FileUtils.rm_rf(wk_dir)
if blk
blk.call "Copy script and stubs"
end
FileUtils.cp(script, File.join(tmp_dir, File.basename(script)))
File.open(File.join(tmp_dir, "sh-install"), 'wb') do |a|
- rewrite a, File.join(DIR, "static", "stubs", "sh-install"),
- 'SCRIPT' => "./#{File.basename(script)}"
+ rewrite a, File.join(DIR, "static", "stubs", "sh-install"),
+ 'SCRIPT' => "./#{File.basename(script)}"
end
FileUtils.chmod 0755, File.join(tmp_dir, "sh-install")
# add sh-install and script to the modes list
@@ -173,7 +172,6 @@ def PackShoes.repack_linux opts, &blk
@tarmodes['sh-install'] = "0755".oct
# debug - dump @tarmodes
#@tarmodes.each { |k,v| puts "#{k} #{sprintf('%4o',v)}" }
-
if blk
blk.call "Compute size and compress"
@@ -198,12 +196,12 @@ def PackShoes.repack_linux opts, &blk
end
md5, fsize = Shy.md5sum(tgz_path), File.size(tgz_path)
File.open(run_path, 'wb') do |f|
- rewrite f, File.join(DIR, "static", "stubs", "blank.run"),
- 'CRC' => '0000000000', 'MD5' => md5, 'LABEL' => app_name, 'NAME' => name,
- 'SIZE' => fsize, 'RAWSIZE' => (raw / 1024) + 1, 'TIME' => Time.now, 'FULLSIZE' => raw
+ rewrite f, File.join(DIR, "static", "stubs", "blank.run"),
+ 'CRC' => '0000000000', 'MD5' => md5, 'LABEL' => app_name, 'NAME' => name,
+ 'SIZE' => fsize, 'RAWSIZE' => (raw / 1024) + 1, 'TIME' => Time.now, 'FULLSIZE' => raw
File.open(tgz_path, 'rb') do |f2|
f.write f2.read(8192) until f2.eof
- end
+ end
end
if blk
blk.call "Done packing Linux"
@@ -441,6 +439,8 @@ def PackShoes.repack_osx opts, &blk
6.0
CFBundlePackageType
APPL
+ NSHighResolutionCapable
+ true
IFMajorVersion
#{vers[0]}
IFMinorVersion
@@ -526,40 +526,40 @@ def PackShoes.rewrite a, before, hsh
end
def PackShoes.fastxzf infile, outdir, modes = {}, osx = ''
- #from blog post http://dracoater.blogspot.com/2013/10/extracting-files-from-targz-with-ruby.html
- # modified by Cecil Coupe - Jun 27+, 2014. Thanks to Juri Timošin
-
- tar_longlink = '././@LongLink'
-
- Gem::Package::TarReader.new( Zlib::GzipReader.open infile ) do |tar|
- dest = nil
- tar.each do |entry|
- if entry.full_name == tar_longlink
- dest = File.join outdir, entry.read.strip
- next
- end
- dest ||= File.join outdir, entry.full_name
- hashname = entry.full_name.gsub('./','')
- hashname.gsub!(/Shoes.app/, osx) if osx
- hashname.chomp!('/')
- #@pkgstat.text = hashname
- modes[hashname] = entry.header.mode
- if entry.directory?
- FileUtils.rm_rf dest unless File.directory? dest
- FileUtils.mkdir_p dest, :mode => entry.header.mode, :verbose => false
- elsif entry.file?
- FileUtils.rm_rf dest unless File.file? dest
- File.open dest, "wb" do |f|
- f.print entry.read
- end
- FileUtils.chmod entry.header.mode, dest, :verbose => false
- elsif entry.header.typeflag == '2' #Symlink!
- #puts "Symlink #{entry.header.linkname} Ignore"
- # File.symlink entry.header.linkname, dest
- end
- dest = nil
- end
- end
+ #from blog post http://dracoater.blogspot.com/2013/10/extracting-files-from-targz-with-ruby.html
+ # modified by Cecil Coupe - Jun 27+, 2014. Thanks to Juri Timošin
+
+ tar_longlink = '././@LongLink'
+
+ Gem::Package::TarReader.new( Zlib::GzipReader.open infile ) do |tar|
+ dest = nil
+ tar.each do |entry|
+ if entry.full_name == tar_longlink
+ dest = File.join outdir, entry.read.strip
+ next
+ end
+ dest ||= File.join outdir, entry.full_name
+ hashname = entry.full_name.gsub('./','')
+ hashname.gsub!(/Shoes.app/, osx) if osx
+ hashname.chomp!('/')
+ #@pkgstat.text = hashname
+ modes[hashname] = entry.header.mode
+ if entry.directory?
+ FileUtils.rm_rf dest unless File.directory? dest
+ FileUtils.mkdir_p dest, :mode => entry.header.mode, :verbose => false
+ elsif entry.file?
+ FileUtils.rm_rf dest unless File.file? dest
+ File.open dest, "wb" do |f|
+ f.print entry.read
+ end
+ FileUtils.chmod entry.header.mode, dest, :verbose => false
+ elsif entry.header.typeflag == '2' #Symlink!
+ #puts "Symlink #{entry.header.linkname} Ignore"
+ # File.symlink entry.header.linkname, dest
+ end
+ dest = nil
+ end
+ end
end
def PackShoes.fastcf outf, indir, modes
diff --git a/lib/shoes/videoffi.rb b/lib/shoes/videoffi.rb
index 9ae8a4de..14a821a9 100644
--- a/lib/shoes/videoffi.rb
+++ b/lib/shoes/videoffi.rb
@@ -506,6 +506,8 @@ def height; @video.height; end # ditto
def left; @video.left; end
def top; @video.top; end
+ def tooltip; @video.tooltip; end
+ def tooltip=(tooltip); @video.tooltip = tooltip; end
end
diff --git a/make/bsd/freebsd/env.rb b/make/bsd/freebsd/env.rb
new file mode 100644
index 00000000..0a54c6f6
--- /dev/null
+++ b/make/bsd/freebsd/env.rb
@@ -0,0 +1,92 @@
+# Build a 64 bit Linux Tight Shoes (from a 64 bit host)
+# In this case Unbuntu 14.04 to debian 7.2 in a chroot.
+# You should modify your custom.yaml
+cf =(ENV['ENV_CUSTOM'] || "#{TGT_ARCH}-custom.yaml")
+if File.exists? cf
+ custmz = YAML.load_file(cf)
+ ShoesDeps = custmz['Deps']
+ EXT_RUBY = custmz['Ruby']
+ APP['GDB'] = 'basic' if custmz['Debug'] == true
+ APP['GEMLOC'] = custmz['Gemloc'] if custmz['Gemloc']
+ APP['EXTLOC'] = custmz['Extloc'] if custmz['Extloc']
+ APP['EXTLIST'] = custmz['Exts'] if custmz['Exts']
+ APP['GEMLIST'] = custmz['Gems'] if custmz['Gems']
+ APP['INCLGEMS'] = custmz['InclGems'] if custmz['InclGems']
+else
+ abort "missing custom.yaml"
+end
+
+APP['GTK'] = 'gtk+-3.0' # installer needs this to name the output
+SHOES_TGT_ARCH = 'x86_64-linux'
+SHOES_GEM_ARCH = "#{Gem::Platform.local}"
+# Setup some shortcuts for the library locations
+arch = 'x86_64-linux-gnu'
+uldir = "#{ShoesDeps}/usr/lib"
+ularch = "#{ShoesDeps}/usr/lib/#{arch}"
+larch = "#{ShoesDeps}/lib/#{arch}"
+lcllib = "/usr/local/lib"
+# Set appropriately
+CC = "cc"
+pkgruby ="#{EXT_RUBY}/lib/pkgconfig/ruby-2.3.pc"
+pkggtk ="/usr/local/libdata/pkgconfig/gtk+-3.0.pc"
+# Use Ruby or curl for downloads
+RUBY_HTTP = true
+
+ADD_DLL = []
+
+# Target environment
+#CAIRO_CFLAGS = `pkg-config --cflags cairo`.strip
+CAIRO_LIB = `pkgconf --libs cairo`.strip
+#PANGO_CFLAGS = `pkg-config --cflags pango`.strip
+PANGO_LIB = `pkgconf --libs pango`.strip
+
+png_lib = 'png'
+
+if APP['GDB']
+ LINUX_CFLAGS = " -g -O0"
+else
+ LINUX_CFLAGS = " -O -Wall"
+end
+LINUX_CFLAGS << " -DRUBY_HTTP -DBSD"
+LINUX_CFLAGS << " -DSHOES_GTK -fPIC -Wno-unused-variable"
+LINUX_CFLAGS << " -I#{ShoesDeps}/usr/include "
+LINUX_CFLAGS << `pkgconf --cflags "#{pkgruby}"`.strip+" "
+LINUX_CFLAGS << `pkgconf --cflags "#{pkggtk}"`.strip+" "
+LINUX_CFLAGS << " -I#{ShoesDeps}/usr/include/ "
+#LINUX_CFLAGS << "-I/usr/include/librsvg-2.0/librsvg "
+#MISC_LIB = ' /usr/lib/x86_64-linux-gnu/librsvg-2.so'
+
+LINUX_CFLAGS << " -I/usr/local/include/librsvg-2.0/librsvg "
+MISC_LIB = " /usr/local/lib/librsvg-2.so"
+#LINUX_LIB_NAMES = %W[ungif jpeg]
+LINUX_LIB_NAMES = %W[gif jpeg]
+
+DLEXT = "so"
+LINUX_LDFLAGS = "-fPIC -shared -L#{ularch} "
+LINUX_LDFLAGS << `pkgconf --libs "#{pkggtk}"`.strip+" "
+# use the ruby link info
+RUBY_LDFLAGS = "-rdynamic -Wl,-export-dynamic "
+RUBY_LDFLAGS << "-L#{EXT_RUBY}/lib -lruby "
+RUBY_LDFLAGS << "-lelf -lexecinfo -lprocstat -lthr -lcrypt -lm "
+
+LINUX_LIBS = LINUX_LIB_NAMES.map { |x| "-l#{x}" }.join(' ')
+
+LINUX_LIBS << " #{CURL_LDFLAGS if !RUBY_HTTP} #{RUBY_LDFLAGS} #{CAIRO_LIB} #{PANGO_LIB} #{MISC_LIB}"
+
+SOLOCS = {}
+#SOLOCS['ungif'] = "#{uldir}/libungif.so.4.1.6"
+SOLOCS['gif'] = "/usr/local/lib/libgif.so.7.0.0"
+SOLOCS['jpeg'] = "/usr/local/lib//libjpeg.so.8.1.2"
+SOLOCS['libyaml'] = "/usr/local/lib/libyaml-0.so.2.0.4"
+SOLOCS['pcre'] = "/usr/local/lib/libpcre.so.1.2.8"
+#SOLOCS['crypto'] = "#{ularch}/libcrypto.so.1.0.0" #needed ?
+SOLOCS['ssl'] = "/usr/lib/libssl.so.8"
+SOLOCS['sqlite'] = "/usr/local/lib/libsqlite3.so.0.8.6"
+SOLOCS['ffi'] = "/usr/local/lib/libffi.so.6.0.4"
+SOLOCS['rsvg2'] = "/usr/local/lib/librsvg-2.so.2.40.17"
+SOLOCS['curl'] = "/usr/local/lib/libcurl.so.4.4.0"
+
+# sigh, curl and tyhpoeus - processed in setup.rb
+SYMLNK = {}
+SYMLNK['libcurl.so.4.4.0'] = ['libcurl.so', 'libcurl.so.4']
+
diff --git a/make/bsd/freebsd/setup.rb b/make/bsd/freebsd/setup.rb
new file mode 100644
index 00000000..dc529940
--- /dev/null
+++ b/make/bsd/freebsd/setup.rb
@@ -0,0 +1,48 @@
+# This is a big gulp of copying.
+require 'fileutils'
+module Make
+ include FileUtils
+
+ def static_setup (so_list)
+ $stderr.puts "setup: dir=#{`pwd`}"
+ rbvt = RUBY_V
+ rbvm = RUBY_V[/^\d+\.\d+/]
+ rbvm = '23' # TODO hack
+ mkdir_p "#{TGT_DIR}/lib"
+ mkdir_p "#{TGT_DIR}/fonts"
+ cp_r "fonts", "#{TGT_DIR}/fonts"
+ mkdir_p "#{TGT_DIR}/lib"
+ cp "lib/shoes.rb", "#{TGT_DIR}/lib"
+ cp_r "lib/shoes", "#{TGT_DIR}/lib"
+ cp_r "lib/exerb", "#{TGT_DIR}/lib"
+ cp_r "samples", "#{TGT_DIR}/samples"
+ cp_r "static", "#{TGT_DIR}/static"
+ cp "README.md", "#{TGT_DIR}/README.txt"
+ cp "CHANGELOG", "#{TGT_DIR}/CHANGELOG.txt"
+ cp "COPYING", "#{TGT_DIR}/COPYING.txt"
+ # clean out leftovers from last build
+ rm_f "#{TGT_DIR}/libruby.so" if File.exist? "#{TGT_DIR}/libruby.so"
+ rm_f "#{TGT_DIR}/libruby.so.#{rbvm}" if File.exist? "#{TGT_DIR}/libruby.so.#{rbvm}"
+ rm_f "#{TGT_DIR}/libruby.so.#{rbvt}" if File.exist? "#{TGT_DIR}/libruby.so.#{rbvt}"
+ cp_r "#{EXT_RUBY}/lib/ruby", "#{TGT_DIR}/lib" #, remove_destination: true
+ # copy and link libruby.so
+ cp "#{EXT_RUBY}/lib/libruby.so.#{rbvm}", "#{TGT_DIR}"
+ # copy include files - it might help build gems
+ mkdir_p "#{TGT_DIR}/lib/ruby/include/ruby-#{rbvt}"
+ cp_r "#{EXT_RUBY}/include/ruby-#{rbvt}/", "#{TGT_DIR}/lib/ruby/include"
+ chdir TGT_DIR do
+ ln_s "libruby.so.#{rbvm}", "libruby.so"
+ end
+ SOLOCS.each_value do |path|
+ cp "#{path}", "#{TGT_DIR}"
+ end
+ chdir TGT_DIR do
+ SYMLNK.each do |k, v|
+ v.each do |syml|
+ ln_s k, syml
+ end
+ end
+ end
+ end
+end
+
diff --git a/make/bsd/freebsd/tasks.rb b/make/bsd/freebsd/tasks.rb
new file mode 100644
index 00000000..70a6cc19
--- /dev/null
+++ b/make/bsd/freebsd/tasks.rb
@@ -0,0 +1,178 @@
+module Make
+ include FileUtils
+
+ def cc(t)
+ sh "#{CC} -I. -c -o#{t.name} #{LINUX_CFLAGS} #{t.source}"
+ end
+
+ # Subs in special variables
+ def rewrite before, after, reg = /\#\{(\w+)\}/, reg2 = '\1'
+ File.open(after, 'w') do |a|
+ File.open(before) do |b|
+ b.each do |line|
+ a << line.gsub(reg) do
+ if reg2.include? '\1'
+ reg2.gsub(%r!\\1!, Object.const_get($1))
+ else
+ reg2
+ end
+ end
+ end
+ end
+ end
+ end
+end
+
+
+include FileUtils
+
+class MakeBSD
+ extend Make
+
+ class << self
+ def setup_system_resources
+ cp APP['icons']['gtk'], "#{TGT_DIR}/static/app-icon.png"
+ end
+
+
+ def new_so (name)
+ tgts = name.split('/')
+ tgtd = tgts[0]
+ tgtd = File.dirname(name)
+ $stderr.puts "new_so: #{tgtd} from #{name}"
+ objs = []
+ SubDirs.each do |f|
+ d = File.dirname(f)
+ objs = objs + FileList["#{d}/*.o"]
+ end
+ # TODO fix: gtk - needs to dig deeper vs osx
+ objs = objs + FileList["shoes/native/gtk/*.o"]
+ main_o = 'shoes/main.o'
+ objs = objs - [main_o]
+ sh "#{CC} -o #{tgtd}/libshoes.#{DLEXT} #{objs.join(' ')} #{LINUX_LDFLAGS} #{LINUX_LIBS}"
+ end
+
+ def new_link(name)
+ #name is actually a file path
+ puts "new_link: arg=#{name}"
+ dpath = File.dirname(name)
+ fname = File.basename(name)
+ bin = "#{fname}-bin"
+ sh "#{CC} -o #{dpath}/#{bin} #{dpath}/tmp/main.o -L#{dpath} -lshoes -L#{TGT_DIR} #{LINUX_LIBS}"
+ rewrite "platform/nix/shoes.launch", name, %r!/shoes-bin!, "/#{NAME}-bin"
+ sh %{echo 'cd "$OLDPWD"\nLD_LIBRARY_PATH=$APPPATH $APPPATH/#{File.basename(bin)} "$@"' >> #{name}}
+ chmod 0755, "#{name}"
+ # write a gdb launched shoes
+ rewrite "platform/nix/shoes.launch", "#{TGT_DIR}/debug", %r!/shoes-bin!, "/#{NAME}-bin"
+ sh %{echo 'cd "$OLDPWD"\nLD_LIBRARY_PATH=$APPPATH gdb $APPPATH/#{File.basename(bin)} "$@"' >> #{TGT_DIR}/debug}
+ chmod 0755, "#{TGT_DIR}/debug"
+ end
+
+
+ # make a .install with all the bits and pieces.
+ def make_installer
+ gtkv = '3'
+ arch = 'freebsd'
+ appname = "#{APP['name'].downcase}"
+ rlname = "#{appname}-#{APP['VERSION']}-gtk#{gtkv}-#{arch}"
+ #puts "Creating Pkg for #{rlname}"
+ pkg = ""
+ if APP['Bld_Pre']
+ pkg = "#{APP['Bld_Pre']}pkg"
+ mkdir_p pkg
+ else
+ pkg = 'pkg'
+ end
+ rm_r "#{pkg}/#{rlname}" if File.exists? "#{pkg}/#{rlname}"
+ cp_r "VERSION.txt", "#{TGT_DIR}"
+ mkdir_p "#{pkg}/#{rlname}"
+ sh "cp -r #{TGT_DIR}/* #{pkg}/#{rlname}"
+ Dir.chdir "#{pkg}/#{rlname}" do
+ rm_r "#{APP['Bld_Tmp']}"
+ rm_r "pkg" if File.exist? "pkg"
+ make_desktop
+ make_uninstall_script
+ make_install_script
+ make_smaller unless APP['GDB']
+ end
+ Dir.chdir "#{pkg}" do
+ puts `pwd`
+ sh "makeself #{rlname} #{rlname}.install #{appname} ./shoes-install.sh "
+ end
+ if APP['Bld_Pre']
+ # copy installer to the shoes3 source pkg/ dir (on an nfs server?)
+ cp "#{pkg}/#{rlname}.install", "pkg"
+ end
+ end
+
+ def make_desktop
+ File.open("Shoes.desktop.tmpl",'w') do |f|
+ f << "[Desktop Entry]\n"
+ f << "Name=Shoes #{APP['NAME'].capitalize}\n"
+ f << "Exec={hdir}/.shoes/#{APP['NAME']}/shoes\n"
+ f << "StartupNotify=true\n"
+ f << "Terminal=false\n"
+ f << "Type=Application\n"
+ f << "Comment=Ruby Graphical Programming\n"
+ f << "Icon={hdir}/.shoes/#{APP['NAME']}/static/app-icon.png\n"
+ f << "Categories=Application;Development;Education;\n"
+ end
+ File.open("Shoes.remove.tmpl",'w') do |f|
+ f << "[Desktop Entry]\n"
+ f << "Name=Uninstall Shoes #{APP['NAME'].capitalize}\n"
+ f << "Exec={hdir}/.shoes/#{APP['NAME']}/shoes-uninstall.sh\n"
+ f << "StartupNotify=true\n"
+ f << "Terminal=false\n"
+ f << "Type=Application\n"
+ f << "Comment=Delete Shoes\n"
+ f << "Icon={hdir}/.shoes/#{APP['NAME']}/static/app-icon.png\n"
+ f << "Categories=Application;Development;Education;\n"
+ end
+ end
+
+ def make_uninstall_script
+ File.open("shoes-uninstall.sh", 'w') do |f|
+ f << "#!/bin/sh\n"
+ f << "#pwd\n"
+ f << "cd $HOME/.shoes/#{APP['NAME']}\n"
+ f << "xdg-desktop-menu uninstall Shoes.remove.desktop\n"
+ f << "xdg-desktop-menu uninstall Shoes.desktop\n"
+ f << "cd ../\n"
+ f << "rm -rf #{APP['NAME']}\n"
+ end
+ chmod "+x", "shoes-uninstall.sh"
+ end
+
+ # the install script that runs on the user's system can be simple.
+ # Copy things from where it's run to ~/.shoes/federales/ and then
+ # sed the desktop file and copy it with xdg-desktop-menu
+ def make_install_script
+ File.open("shoes-install.sh", 'w') do |f|
+ f << "#!/bin/sh\n"
+ f << "#pwd\n"
+ f << "ddir=$HOME/.shoes/#{APP['NAME']}\n"
+ f << "#echo $ddir\n"
+ f << "mkdir -p $ddir\n"
+ f << "cp -r * $ddir/\n"
+ f << "sed -e \"s@{hdir}@$HOME@\" Shoes.desktop\n"
+ f << "cp Shoes.desktop $ddir/Shoes.desktop\n"
+ f << "xdg-desktop-menu install --novendor Shoes.desktop\n"
+ f << "sed -e \"s@{hdir}@$HOME@\" Shoes.remove.desktop\n"
+ f << "cp Shoes.remove.desktop $ddir/Shoes.remove.desktop\n"
+ f << "xdg-desktop-menu install --novendor Shoes.remove.desktop\n"
+ f << "echo \"Shoes has been copied to $ddir. and menus created\"\n"
+ f << "echo \"If you don't see Shoes in the menu, logout and login\"\n"
+ end
+ chmod "+x", "shoes-install.sh"
+ end
+
+ # run strip on the libraries, remove unneeded ruby code (tk,
+ # readline and more)
+ def make_smaller
+ puts "Shrinking #{`pwd`}"
+ sh "strip *.so"
+ sh "strip *.so.*"
+ Dir.glob("lib/ruby/**/*.so").each {|lib| sh "strip #{lib}"}
+ end
+ end
+end
diff --git a/make/bsd/minbsd/env.rb b/make/bsd/minbsd/env.rb
new file mode 100644
index 00000000..c49f48b2
--- /dev/null
+++ b/make/bsd/minbsd/env.rb
@@ -0,0 +1,83 @@
+# This is for a freebds only build (loose shoes)
+# It is safe and desireable to use RbConfig::CONFIG settings
+# Will not build gems or copy gems - uses the host ruby.
+# Cannot be distributed.
+require 'rbconfig'
+
+APP['GDB'] = "true" # true => compile -g, don't strip symbols
+if APP['GDB']
+ LINUX_CFLAGS = "-g -O0"
+else
+ LINUX_CFLAGS = "-O -Wall"
+end
+
+# figure out which ruby we need.
+rv = RUBY_VERSION[/\d.\d/]
+
+LINUX_CFLAGS << " -DRUBY_HTTP -DBSD"
+LINUX_CFLAGS << " -DRUBY_1_9"
+LINUX_CFLAGS << " -DDEBUG" if ENV['DEBUG']
+LINUX_CFLAGS << " -DSHOES_GTK -fPIC"
+# Following line may need handcrafting
+LINUX_CFLAGS << " -I/usr/include/"
+LINUX_CFLAGS << " #{`pkgconf --cflags gtk+-3.0`.strip}"
+
+CC = "cc"
+
+# Query pkg-config for cflags and link settings
+EXT_RUBY = RbConfig::CONFIG['prefix']
+RUBY_CFLAGS = " #{`pkgconf --cflags /usr/local/libdata/pkgconfig/ruby-#{rv}.pc`.strip}"
+# Ruby 2.1.2 with RVM has a bug. Workaround or wait for perfection?
+rlib = `pkgconf --libs /usr/local/libdata/pkgconfig/ruby-#{rv}.pc`.strip
+# 2.2.3 is missing -L'$${ORIGIN}/../lib' in LIBRUBYARG_SHARED in .pc
+if !rlib[/\-L/]
+ #puts "missing -L in #{rlib}"
+ rlib = "-L#{EXT_RUBY}/lib "+rlib
+end
+if rlib[/{ORIGIN/]
+ #abort "Bug found #{rlib}"
+ RUBY_LIB = rlib.gsub(/\$\\{ORIGIN\\}/, "#{EXT_RUBY}/lib")
+ #RUBY_LIB = rlib
+else
+ RUBY_LIB = rlib
+end
+CAIRO_CFLAGS = `pkgconf --cflags cairo`.strip
+CAIRO_LIB = `pkgconf --libs cairo`.strip
+PANGO_CFLAGS = `pkgconf --cflags pango`.strip
+PANGO_LIB = `pkgconf --libs pango`.strip
+GTK_FLAGS = "#{`pkgconf --cflags gtk+-3.0`.strip}"
+GTK_LIB = "#{`pkgconf --libs gtk+-3.0`.strip}"
+
+MISC_LIB = " -lgif -ljpeg"
+
+# don't use pkg-config for librsvg-2.0 - a warning.
+MISC_CFLAGS = ' '
+
+MISC_CFLAGS << "-I/usr/local/include/librsvg-2.0/librsvg "
+MISC_LIB << " /usr/local/lib/librsvg-2.so"
+
+# collect flags together
+LINUX_CFLAGS << " #{RUBY_CFLAGS} #{GTK_FLAGS} #{CAIRO_CFLAGS} #{PANGO_CFLAGS} #{MISC_CFLAGS}"
+
+# collect link settings together. Does order matter?
+LINUX_LIBS = "#{RUBY_LIB} #{GTK_LIB} #{CAIRO_LIB} #{PANGO_LIB} #{MISC_LIB}"
+LINUX_LIBS << " -lfontconfig" # if APP['GTK'] == "gtk+-3.0"
+# the following is only used to link the shoes code with main.o
+LINUX_LDFLAGS = "-L. -rdynamic -Wl,-export-dynamic"
+
+# Main Rakefile and tasks.rb needs the below Constants
+ADD_DLL = []
+DLEXT = "so"
+SOLOCS = {} # needed to match Rakefile expectations.
+=begin
+# to save settings
+bld_args = {}
+bld_args['CC'] = CC
+bld_args['ADD_DLL'] = []
+bld_args['DLEXT'] = "so"
+bld_args['SOLOCS'] = {}
+bld_args['LINUX_CFLAGS'] = LINUX_CFLAGS
+bld_args['LINUX_LDFLAGS'] = LINUX_LDFLAGS
+bld_args['LINUX_LIBS'] = LINUX_LIBS
+File.open("#{TGT_DIR}/build.yaml", 'w') {|f| YAML.dump(bld_args, f)}
+=end
diff --git a/make/bsd/minbsd/setup.rb b/make/bsd/minbsd/setup.rb
new file mode 100644
index 00000000..7e9dca87
--- /dev/null
+++ b/make/bsd/minbsd/setup.rb
@@ -0,0 +1,49 @@
+module Make
+ include FileUtils
+
+
+ # Set up symlinks to lib/shoes and lib/shoes.rb so that they
+ # can be edited and tested without a rake clean/build every time we
+ # change a lib/shoes/*.rb
+ # They'll be copied (not linked) when rake install occurs. Be very
+ # careful. Only Link to FILES, not to directories. Fileutils.ln_s may
+ # not be the same as linux ln -s.
+ def static_setup (solocs)
+ srcloc= `pwd`.strip
+ puts "setup: #{srcloc}"
+=begin
+ cp_r "fonts", "#{TGT_DIR}/fonts"
+ mkdir_p "#{TGT_DIR}/lib/shoes"
+ Dir.chdir "#{TGT_DIR}/lib/shoes" do
+ Dir["#{srcloc}/lib/shoes/*.rb"].each do |f|
+ #puts "SymLinking #{f}"
+ ln_s f, "." unless File.symlink? File.basename(f)
+ end
+ end
+ Dir.chdir "#{TGT_DIR}/lib" do
+ ln_s "#{srcloc}/lib/shoes.rb" , "shoes.rb" unless File.symlink? "shoes.rb"
+ # link to exerb
+ ln_s "#{srcloc}/lib/exerb", "exerb" unless File.symlink? "exerb"
+ end
+
+ #cp_r "samples", "#{TGT_DIR}/samples"
+ mkdir_p "#{TGT_DIR}/samples"
+ ['simple', 'good', 'expert'].each do |d|
+ mkdir_p "#{TGT_DIR}/samples/#{d}"
+ Dir.chdir "#{TGT_DIR}/samples/#{d}" do
+ Dir["../../../samples/#{d}/*"].each do |f|
+ ln_s f, '.' unless File.symlink? File.basename(f)
+ end
+ end
+ end
+=end
+ ln_s "#{srcloc}/lib", TGT_DIR
+ ln_s "#{srcloc}/samples", TGT_DIR
+ ln_s "#{srcloc}/static", TGT_DIR
+ ln_s "#{srcloc}/fonts", TGT_DIR
+
+ cp "README.md", TGT_DIR
+ cp "CHANGELOG", TGT_DIR
+ cp "COPYING", TGT_DIR
+ end
+end
diff --git a/make/bsd/minbsd/tasks.rb b/make/bsd/minbsd/tasks.rb
new file mode 100644
index 00000000..ac53d249
--- /dev/null
+++ b/make/bsd/minbsd/tasks.rb
@@ -0,0 +1,173 @@
+module Make
+ include FileUtils
+
+ def cc(t)
+ sh "#{CC} -I. -c -o#{t.name} #{LINUX_CFLAGS} #{t.source}"
+ end
+
+ # Subs in special variables
+ def rewrite before, after, reg = /\#\{(\w+)\}/, reg2 = '\1'
+ File.open(after, 'w') do |a|
+ File.open(before) do |b|
+ b.each do |line|
+ a << line.gsub(reg) do
+ if reg2.include? '\1'
+ reg2.gsub(%r!\\1!, Object.const_get($1))
+ else
+ reg2
+ end
+ end
+ end
+ end
+ end
+ end
+
+ def copy_files glob, dir
+ FileList[glob].each { |f| cp_r f, dir }
+ end
+
+ # a stub, loose linux doesn't copy gems but the Builder will call it
+ def copy_gems
+ end
+
+end
+
+
+include FileUtils
+
+class MakeBSD
+ extend Make
+
+ class << self
+
+ def setup_system_resources
+ cp APP['icons']['gtk'], "#{TGT_DIR}/static/app-icon.png"
+ end
+
+ # this is called from the file task based new_builder
+ def new_so (name)
+ tgts = File.expand_path(name)
+ tgtd = File.dirname(name)
+ $stderr.puts "new_so: #{tgtd} from #{tgts}"
+ objs = []
+ SubDirs.each do |f|
+ d = File.dirname(f)
+ objs = objs + FileList["#{d}/*.o"]
+ end
+ objs = objs + FileList["shoes/native/gtk/*.o"]
+ main_o = 'shoes/main.o'
+ objs = objs - [main_o]
+ sh "ar -rc #{tgtd}/shoes.lib #{objs.join(' ')}"
+ sh "ranlib #{tgtd}/shoes.lib"
+ end
+
+ def new_link name
+ tgts = File.expand_path(name)
+ tgtd = File.dirname(name)
+ $stderr.puts "new_link: #{tgtd} from #{name}"
+ sh "#{CC} -o #{TGT_DIR}/shoes #{TGT_DIR}/#{APP['Bld_Tmp']}/main.o #{TGT_DIR}/shoes.lib #{LINUX_LDFLAGS} #{LINUX_LIBS}"
+ end
+
+ def make_installer
+ if !File.exists? "crosscompile"
+ puts "Sorry, you can't create a binary installer for your Shoes"
+ puts "We can't know where their ruby is installed or how it's"
+ puts "configured. Rubyies newer than 1.9.1 can hardcode installation information"
+ puts "about where they are installed so they can't be copied to"
+ puts "other systems which is what Shoes does. If your desire is strong"
+ puts "you can set up a cross compiling arrangement. See the notes/"
+ puts "folder"
+ end
+ end
+
+ def make_userinstall
+ user = ENV['USER']
+ home = ENV['HOME']
+ hdir = "#{home}/.shoes/#{APP['NAME']}"
+ if File.exists? hdir
+ # so we can install many times to test installing many times
+ puts "Removing old lib"
+ rm_r hdir
+ end
+ mkdir_p hdir
+ cp_r "#{TGT_DIR}/fonts", "#{hdir}/fonts"
+ cp_r "#{TGT_DIR}/samples", "#{hdir}/samples"
+ cp_r "#{TGT_DIR}/static", "#{hdir}/static"
+ cp "#{TGT_DIR}/README.md", "#{hdir}/README.txt"
+ cp "#{TGT_DIR}/CHANGELOG", "#{hdir}/CHANGELOG.txt"
+ cp "#{TGT_DIR}/COPYING", "#{hdir}/COPYING.txt"
+ cp "#{TGT_DIR}/VERSION.txt", "#{hdir}"
+ cp "#{TGT_DIR}/shoes" , "#{hdir}"
+ cp "#{TGT_DIR}/shoes.lib",hdir
+ mkdir_p "#{hdir}/lib"
+ #sh "cp -r #{TGT_DIR}/lib/ruby #{hdir}/lib"
+ # bit of a hack here. Don't copy symlinks in dist/lib
+ sh "cp -r #{TGT_DIR}/lib/shoes #{hdir}/lib"
+ sh "cp -r #{TGT_DIR}/lib/shoes.rb #{hdir}/lib/"
+ sh "cp -r #{TGT_DIR}/lib/exerb #{hdir}/lib"
+ Dir.chdir hdir do
+ make_desktop
+ make_uninstall_script
+ make_install_script
+ # run the generated install script to build menus
+ sh "./shoes-install.sh"
+ end
+ end
+
+ def make_desktop
+ File.open("Shoes.desktop.tmpl",'w') do |f|
+ f << "[Desktop Entry]\n"
+ f << "Name=Shoes #{APP['NAME'].capitalize}\n"
+ f << "Exec={hdir}/.shoes/#{APP['NAME']}/shoes\n"
+ f << "StartupNotify=true\n"
+ f << "Terminal=false\n"
+ f << "Type=Application\n"
+ f << "Comment=Ruby Graphical Programming\n"
+ f << "Icon={hdir}/.shoes/#{APP['NAME']}/static/app-icon.png\n"
+ f << "Categories=Application;Development;Education;\n"
+ end
+ File.open("Shoes.remove.tmpl",'w') do |f|
+ f << "[Desktop Entry]\n"
+ f << "Name=Uninstall Shoes #{APP['NAME'].capitalize}\n"
+ f << "Exec={hdir}/.shoes/#{APP['NAME']}/shoes-uninstall.sh\n"
+ f << "StartupNotify=true\n"
+ f << "Terminal=false\n"
+ f << "Type=Application\n"
+ f << "Comment=Delete Shoes\n"
+ f << "Icon={hdir}/.shoes/#{APP['NAME']}/static/app-icon.png\n"
+ f << "Categories=Application;Development;Education;\n"
+ end
+ end
+
+ def make_uninstall_script
+ File.open("shoes-uninstall.sh", 'w') do |f|
+ f << "#!/usr/bin/env bash\n"
+ f << "#pwd\n"
+ f << "cd $HOME/.shoes/#{APP['NAME']}\n"
+ f << "xdg-desktop-menu uninstall Shoes.remove.desktop\n"
+ f << "xdg-desktop-menu uninstall Shoes.desktop\n"
+ f << "cd ../\n"
+ f << "rm -rf #{APP['NAME']}\n"
+ end
+ chmod "+x", "shoes-uninstall.sh"
+ end
+
+ # Note: this is different from make_install script for Tight Shoes
+ def make_install_script
+ File.open("shoes-install.sh", 'w') do |f|
+ f << "#!/usr/bin/env bash\n"
+ f << "#pwd\n"
+ f << "ddir=$HOME/.shoes/#{APP['NAME']}\n"
+ f << "cd $ddir\n"
+ f << "sed -e \"s@{hdir}@$HOME@\" Shoes.desktop\n"
+ f << "xdg-desktop-menu install --novendor Shoes.desktop\n"
+ f << "sed -e \"s@{hdir}@$HOME@\" Shoes.remove.desktop\n"
+ f << "xdg-desktop-menu install --novendor Shoes.remove.desktop\n"
+ f << "echo \"Shoes has been copied to $ddir. and menus created\"\n"
+ f << "echo \"If you don't see Shoes in the menu, logout and login\"\n"
+ end
+ chmod "+x", "shoes-install.sh"
+ end
+
+ end
+end
diff --git a/make/bsd/none/env.rb b/make/bsd/none/env.rb
new file mode 100644
index 00000000..22212dbb
--- /dev/null
+++ b/make/bsd/none/env.rb
@@ -0,0 +1,4 @@
+# just enough allow a rake -T
+CC = "gcc"
+DLEXT = "so"
+LINUX_CFLAGS = []
diff --git a/make/bsd/none/tasks.rb b/make/bsd/none/tasks.rb
new file mode 100644
index 00000000..038e78a7
--- /dev/null
+++ b/make/bsd/none/tasks.rb
@@ -0,0 +1,28 @@
+module Make
+ include FileUtils
+
+ def cc(t)
+ #sh "#{CC} -I. -c -o#{t.name} #{WINDOWS_CFLAGS} #{t.source}"
+ end
+
+ # Subs in special variables
+ def rewrite before, after, reg = /\#\{(\w+)\}/, reg2 = '\1'
+ File.open(after, 'w') do |a|
+ File.open(before) do |b|
+ b.each do |line|
+ a << line.gsub(reg) do
+ if reg2.include? '\1'
+ reg2.gsub(%r!\\1!, Object.const_get($1))
+ else
+ reg2
+ end
+ end
+ end
+ end
+ end
+ end
+
+end
+class MakeBSD
+ extend Make
+end
diff --git a/make/darwin/loose/env.rb b/make/darwin/loose/env.rb
deleted file mode 100644
index 28a2d9c5..00000000
--- a/make/darwin/loose/env.rb
+++ /dev/null
@@ -1,76 +0,0 @@
-EXT_RUBY = File.exists?("deps/ruby") ? "deps/ruby" : RbConfig::CONFIG['prefix']
-
-# use the platform Ruby claims
-require 'rbconfig'
-
-CC = ENV['CC'] ? ENV['CC'] : "gcc"
-file_list = ["shoes/*.c"] + %w{shoes/native/cocoa.m shoes/http/nsurl.m}
-
-SRC = FileList[*file_list]
-OBJ = SRC.map do |x|
- x.gsub(/\.\w+$/, '.o')
-end
-
-ADD_DLL = []
-
-# Darwin build environment
-# CJC - overly complicated. Just fail if one of the pkg-config's goes wrong
-pkg_config = `which pkg-config` != ""
-pkgs = `pkg-config --list-all`.split("\n").map {|p| p.split.first} unless not pkg_config
-if pkg_config and pkgs.include?("cairo") and pkgs.include?("pango")
- CAIRO_CFLAGS = ENV['CAIRO_CFLAGS'] || `pkg-config --cflags cairo`.strip
- CAIRO_LIB = ENV['CAIRO_LIB'] ? "-L#{ENV['CAIRO_LIB']}" : `pkg-config --libs cairo`.strip
- PANGO_CFLAGS = ENV['PANGO_CFLAGS'] || `pkg-config --cflags pango`.strip
- PANGO_LIB = ENV['PANGO_LIB'] ? "-L#{ENV['PANGO_LIB']}" : `pkg-config --libs pango`.strip
-else
- # Hack for when pkg-config is not yet installed
- # CJC - this is ugly. Just fail early
- #puts "DON'T have pkg-config"
- CAIRO_CFLAGS, CAIRO_LIB, PANGO_CFLAGS, PANGO_LIB = "", "", "", ""
-end
-png_lib = 'png'
-
-LINUX_CFLAGS = %[-Wall #{ENV['GLIB_CFLAGS']} -I#{ENV['SHOES_DEPS_PATH'] || "/usr"}/include #{CAIRO_CFLAGS} #{PANGO_CFLAGS} -I#{RbConfig::CONFIG['archdir']}]
-if RbConfig::CONFIG['rubyhdrdir']
- LINUX_CFLAGS << " -I#{RbConfig::CONFIG['rubyhdrdir']} -I#{RbConfig::CONFIG['rubyhdrdir']}/#{SHOES_RUBY_ARCH}"
-end
-
-LINUX_LIB_NAMES = %W[#{RUBY_SO} cairo pangocairo-1.0 gif]
-
-#FLAGS.each do |flag|
-# LINUX_CFLAGS << " -D#{flag}" if ENV[flag]
-#end
-
-if ENV['DEBUG']
- LINUX_CFLAGS << " -g -O0 "
-else
- LINUX_CFLAGS << " -O "
-end
-LINUX_CFLAGS << " -DRUBY_1_9"
-
-DLEXT = "dylib"
-LINUX_CFLAGS << " -DSHOES_QUARTZ -Wall -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wredundant-decls -fpascal-strings #{RbConfig::CONFIG["CFLAGS"]} -x objective-c -fobjc-exceptions"
-LINUX_LDFLAGS = "-framework Cocoa -framework Carbon -dynamiclib -Wl,-single_module INSTALL_NAME"
-LINUX_LIB_NAMES << 'pixman-1' << 'jpeg.8'
-
-#OSX_SDK = '/Developer/SDKs/MacOSX10.6.sdk'
-#ENV['MACOSX_DEPLOYMENT_TARGET'] = '10.6'
-OSX_SDK = '/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk'
-ENV['MACOSX_DEPLOYMENT_TARGET'] = '10.9'
-
-case ENV['SHOES_OSX_ARCH']
-when "universal"
- OSX_ARCH = "-arch i386 -arch x86_64"
-when "i386"
- OSX_ARCH = '-arch i386'
-else
- OSX_ARCH = '-arch x86_64'
-end
-
-LINUX_CFLAGS << " -isysroot #{OSX_SDK} #{OSX_ARCH}"
-LINUX_LDFLAGS << " #{OSX_ARCH}"
-
-LINUX_LIBS = LINUX_LIB_NAMES.map { |x| "-l#{x}" }.join(' ')
-
-LINUX_LIBS << " -L#{RbConfig::CONFIG['libdir']} #{CAIRO_LIB} #{PANGO_LIB}"
-
diff --git a/make/darwin/loose/tasks.rb b/make/darwin/loose/tasks.rb
deleted file mode 100644
index 964e0a5e..00000000
--- a/make/darwin/loose/tasks.rb
+++ /dev/null
@@ -1,240 +0,0 @@
-require File.expand_path('make/make')
-
-include FileUtils
-
-class MakeDarwin
- extend Make
-
- class << self
- def copy_ext xdir, libdir
- Dir.chdir(xdir) do
- `ruby extconf.rb; make`
- end
- copy_files "#{xdir}/*.bundle", libdir
- end
-
- def copy_files_to_dist
- if ENV['APP']
- if APP['clone']
- sh APP['clone'].gsub(/^git /, "#{GIT} --git-dir=#{ENV['APP']}/.git ")
- else
- cp_r ENV['APP'], "#{TGT_DIR}/app"
- end
- if APP['ignore']
- APP['ignore'].each do |nn|
- rm_rf "#{TGT_DIR}/app/#{nn}"
- end
- end
- end
- cp_r "fonts", "#{TGT_DIR}/fonts"
- cp_r "lib", "#{TGT_DIR}/lib"
- cp_r "samples", "#{TGT_DIR}/samples"
- cp_r "static", "#{TGT_DIR}/static"
- cp "README.md", "#{TGT_DIR}/README.txt"
- cp "CHANGELOG", "#{TGT_DIR}/CHANGELOG.txt"
- cp "COPYING", "#{TGT_DIR}/COPYING.txt"
- end
-
- def pre_build
- puts "osx pre_build #{TGT_DIR} from #{`pwd`}"
- end
-
- def copy_ext_osx xdir, libdir
- Dir.chdir(xdir) do
- `ruby extconf.rb; make`
- end
- copy_files "#{xdir}/*.bundle", libdir
- end
-
- def common_build
- puts "Common build called"
- mkdir_p "#{TGT_DIR}/lib/ruby/#{RUBY_V}/#{SHOES_RUBY_ARCH}"
- # FIXME: too lazy to figure out install_name_tool for this:
- cd TGT_DIR do
- dirp = RbConfig::CONFIG['libdir']
- so = RbConfig::CONFIG['LIBRUBY_SO']
- ln_s "#{dirp}/#{so}", so unless File.exist? so
- end
- #cp_r "#{EXT_RUBY}/lib/ruby/#{RUBY_V}", "dist/ruby/lib"
- #cp_r "#{EXT_RUBY}/lib/ruby/#{RUBY_V}", "#{TGT_DIR}/lib/ruby"
- #cp "#{EXT_RUBY}/lib/libruby.dylib", "#{TGT_DIR}"
- %w[req/rake/lib/*].each do |rdir|
- #FileList[rdir].each { |rlib| cp_r rlib, "dist/ruby/lib" }
- FileList[rdir].each { |rlib| cp_r rlib, "#{TGT_DIR}/lib/ruby/#{RUBY_V}" }
- end
- #%w[req/binject/ext/binject_c req/bloopsaphone/ext/bloops req/chipmunk/ext/chipmunk].
- # each { |xdir| copy_ext_osx xdir, "dist/ruby/lib/#{SHOES_RUBY_ARCH}" }
- %w[req/chipmunk/ext/chipmunk].
- each { |xdir| copy_ext_osx xdir, "#{TGT_DIR}/lib/ruby/#{RUBY_V}/#{SHOES_RUBY_ARCH}" }
-
- gdir = "#{TGT_DIR}/ruby/gems/#{RUBY_V}"
- #{'hpricot' => 'lib', 'json' => 'lib/json/ext', 'sqlite3' => 'lib'}.each do |gemn, xdir|
- {}.each do |gemn, xdir|
- spec = eval(File.read("req/#{gemn}/gemspec"))
- mkdir_p "#{gdir}/specifications"
- mkdir_p "#{gdir}/gems/#{spec.full_name}/lib"
- FileList["req/#{gemn}/lib/*"].each { |rlib| cp_r rlib, "#{gdir}/gems/#{spec.full_name}/lib" }
- mkdir_p "#{gdir}/gems/#{spec.full_name}/#{xdir}"
- FileList["req/#{gemn}/ext/*"].each { |elib| copy_ext_osx elib, "#{gdir}/gems/#{spec.full_name}/#{xdir}" }
- cp "req/#{gemn}/gemspec", "#{gdir}/specifications/#{spec.full_name}.gemspec"
- end
- end
-
- # Get a list of linked libraries for lib (discard the non-indented lines)
- def get_dylibs lib
- `otool -L #{lib}`.split("\n").inject([]) do |dylibs, line|
- if line =~ /^\S/ or line =~ /System|@executable_path|libobjc/
- dylibs
- else
- dylibs << line.gsub(/\s\(compatibility.*$/, '').strip
- end
- end
- end
-
- def dylibs_to_change lib
- `otool -L #{lib}`.split("\n").inject([]) do |dylibs, line|
- if line =~ /^\S/ or line =~ /System|@executable_path|libobjc/
- dylibs
- else
- dylibs << line.gsub(/\s\(compatibility.*$/, '').strip
- end
- end
- end
-
- def change_install_names
- cd "#{TGT_DIR}" do
- ["#{NAME}-bin", "pango-querymodules", *Dir['*.dylib'], *Dir['pango/modules/*.so']].each do |f|
- sh "install_name_tool -id @executable_path/#{File.basename f} #{f}"
- dylibs = dylibs_to_change(f)
- dylibs.each do |dylib|
- # another Cecil hack
- chmod 0755, dylib if File.writable? dylib
- sh "install_name_tool -change #{dylib} @executable_path/#{File.basename dylib} #{f}"
- end
- end
- end
- end
-
- def copy_pango_modules_to_dist
- puts "Entering copy_pango_modules_to_dist"
- modules_file = `brew --prefix`.chomp << '/etc/pango/pango.modules'
- modules_path = File.open(modules_file) {|f| f.grep(/^# ModulesPath = (.*)$/){$1}.first}
- mkdir_p "#{TGT_DIR}/pango"
- cp_r modules_path, "#{TGT_DIR}/pango"
- # Another Cecil hack ahead
- Dir.glob("#{TGT_DIR}/pango/modules/*").each do |f|
- chmod 0755, f unless File.writable? f
- end
- cp `which pango-querymodules`.chomp, "#{TGT_DIR}/"
- # another hack
- chmod 0755, "#{TGT_DIR}/pango-querymodules"
- end
-
-
- def copy_deps_to_dist
- puts "Entering copy_deps_to_dist"
- copy_pango_modules_to_dist
- # Generate a list of dependencies straight from the generated files.
- # Start with dependencies of shoes-bin and pango-querymodules, and then
- # add the dependencies of those dependencies.
- dylibs = dylibs_to_change("#{TGT_DIR}/#{NAME}-bin")
- dylibs.concat dylibs_to_change("#{TGT_DIR}/pango-querymodules")
- dupes = []
- dylibs.each do |dylib|
- dylibs_to_change(dylib).each do |d|
- if dylibs.map {|lib| File.basename(lib)}.include?(File.basename(d))
- dupes << d
- else
- dylibs << d
- end
- end
- end
- #dylibs.each {|libn| cp "#{libn}", "dist/" unless File.exists? "dist/#{libn}"}
- # clunky hack begins - Homebrew keg issue? ro duplicates do exist
- # make my own dups hash - not the same as dupes.
- dups = {}
- dylibs.each do |libn|
- keyf = File.basename libn
- if !dups[keyf]
- cp "#{libn}", "#{TGT_DIR}/" unless File.exists? "#{TGT_DIR}/#{keyf}"
- dups[keyf] = true
- chmod 0755, "#{TGT_DIR}/#{keyf}" unless File.writable? "#{TGT_DIR}/#{keyf}"
- end
- end
- end
-
- def setup_system_resources
- tmpd = "/tmp"
- mkdir_p tmpd
- puts "Perfoming :setup_system_resources from #{`pwd`} to dir #{tmpd} "
- rm_rf "#{tmpd}/#{APPNAME}.app"
- mkdir "#{tmpd}/#{APPNAME}.app"
- mkdir "#{tmpd}/#{APPNAME}.app/Contents"
- cp_r "#{TGT_DIR}", "#{tmpd}/#{APPNAME}.app/Contents/MacOS"
- mkdir "#{tmpd}/#{APPNAME}.app/Contents/Resources"
- mkdir "#{tmpd}/#{APPNAME}.app/Contents/Resources/English.lproj"
- sh "ditto \"#{APP['icons']['osx']}\" \"#{tmpd}/#{APPNAME}.app/App.icns\""
- sh "ditto \"#{APP['icons']['osx']}\" \"#{tmpd}/#{APPNAME}.app/Contents/Resources/App.icns\""
- rewrite "platform/mac/Info.plist", "#{tmpd}/#{APPNAME}.app/Contents/Info.plist"
- cp "platform/mac/version.plist", "#{tmpd}/#{APPNAME}.app/Contents/"
- #rewrite "platform/mac/pangorc", "#{tmpd}/#{APPNAME}.app/Contents/MacOS/pangorc"
- cp "platform/mac/command-manual.rb", "#{tmpd}/#{APPNAME}.app/Contents/MacOS/"
- rewrite "platform/mac/simple-launch", "#{tmpd}/#{APPNAME}.app/Contents/MacOS/#{NAME}-launch"
- chmod 0755, "#{tmpd}/#{APPNAME}.app/Contents/MacOS/#{NAME}-launch"
- chmod 0755, "#{tmpd}/#{APPNAME}.app/Contents/MacOS/#{NAME}-bin"
- rewrite "platform/mac/shoes", "#{tmpd}/#{APPNAME}.app/Contents/MacOS/#{NAME}"
- chmod 0755, "#{tmpd}/#{APPNAME}.app/Contents/MacOS/#{NAME}"
- #chmod_R 0755, "#{tmpd}/#{APPNAME}.app/Contents/MacOS/pango-querymodules"
- # cp InfoPlist.strings YourApp.app/Contents/Resources/English.lproj/
- `echo -n 'APPL????' > "#{tmpd}/#{APPNAME}.app/Contents/PkgInfo"`
- rm_rf "#{TGT_DIR}/#{APPNAME}.app"
- #NFS=ENV['NFS_ALTP']
- mv "#{tmpd}/#{APPNAME}.app", "#{TGT_DIR}"
- end
-
- def make_stub
- ENV['MACOSX_DEPLOYMENT_TARGET'] = '10.4'
- sh "gcc -O -isysroot /Developer/SDKs/MacOSX10.4u.sdk -arch i386 -arch ppc -framework Cocoa -o stub platform/mac/stub.m -I."
- end
-
- def make_app(name)
- puts "Entering make_app"
- bin = "#{TGT_DIR}/#{NAME}-bin"
- rm_f "#{TGT_DIR}/#{NAME}"
- rm_f bin
- sh "#{CC} -L#{TGT_DIR} -o #{bin} bin/main.o #{LINUX_LIBS} -lshoes #{OSX_ARCH} -L/usr/local/lib -lgif"
- end
-
- def make_so(name)
- puts "Central make_so"
- name = "#{TGT_DIR}/lib#{SONAME}.#{DLEXT}"
- #ldflags = LINUX_LDFLAGS.sub! /INSTALL_NAME/, "-install_name @executable_path/lib#{SONAME}.#{DLEXT}"
- ldflags = LINUX_LDFLAGS.sub! /INSTALL_NAME/, ""
- sh "#{CC} -o #{name} #{OBJ.join(' ')} #{LINUX_LDFLAGS} #{LINUX_LIBS}"
- end
-
- def make_installer
- abort "Sorry, you can't distribute a Loose Shoes. It's tightly linked to your\
-configuration that the other user won't have. You can build a Tight Shoes\
-which is more universal. See 'rake -T' 'rake osx:setup:mavericks' perhaps?"
- dmg_ds, dmg_jpg = "platform/mac/dmg_ds_store", "static/shoes-dmg.jpg"
- if APP['dmg']
- dmg_ds, dmg_jpg = APP['dmg']['ds_store'], APP['dmg']['background']
- end
-
- mkdir_p "pkg"
- rm_rf "dmg"
- mkdir_p "dmg"
- cp_r "#{APPNAME}.app", "dmg"
- unless ENV['APP']
- mv "dmg/#{APPNAME}.app/Contents/MacOS/samples", "dmg/samples"
- end
- ln_s "/Applications", "dmg/Applications"
- sh "chmod +x dmg/\"#{APPNAME}.app\"/Contents/MacOS/#{NAME}"
- sh "chmod +x dmg/\"#{APPNAME}.app\"/Contents/MacOS/#{NAME}-bin"
- sh "chmod +x dmg/\"#{APPNAME}.app\"/Contents/MacOS/#{NAME}-launch"
- sh "DYLD_LIBRARY_PATH= platform/mac/pkg-dmg --target pkg/#{PKG}.dmg --source dmg --volname '#{APPNAME}' --copy #{dmg_ds}:/.DS_Store --mkdir /.background --copy #{dmg_jpg}:/.background" # --format UDRW"
- rm_rf "dmg"
- end
- end
-end
diff --git a/make/darwin/none/env.rb b/make/darwin/none/env.rb
new file mode 100644
index 00000000..5afd680f
--- /dev/null
+++ b/make/darwin/none/env.rb
@@ -0,0 +1,6 @@
+# just enough allow a rake -T
+EXT_RUBY = File.exists?("deps/ruby") ? "deps/ruby" : RbConfig::CONFIG['prefix']
+CC = "gcc"
+DLEXT = "dll"
+LINUX_CFLAGS = []
+
diff --git a/make/darwin/none/tasks.rb b/make/darwin/none/tasks.rb
new file mode 100644
index 00000000..e36a6768
--- /dev/null
+++ b/make/darwin/none/tasks.rb
@@ -0,0 +1,28 @@
+module Make
+ include FileUtils
+
+ def cc(t)
+ #sh "#{CC} -I. -c -o#{t.name} #{WINDOWS_CFLAGS} #{t.source}"
+ end
+
+ # Subs in special variables
+ def rewrite before, after, reg = /\#\{(\w+)\}/, reg2 = '\1'
+ File.open(after, 'w') do |a|
+ File.open(before) do |b|
+ b.each do |line|
+ a << line.gsub(reg) do
+ if reg2.include? '\1'
+ reg2.gsub(%r!\\1!, Object.const_get($1))
+ else
+ reg2
+ end
+ end
+ end
+ end
+ end
+ end
+
+end
+class MakeDarwin
+ extend Make
+end
diff --git a/make/darwin/xmavericks/env.rb b/make/darwin/xmavericks/env.rb
index d561f01f..1a6e1da2 100644
--- a/make/darwin/xmavericks/env.rb
+++ b/make/darwin/xmavericks/env.rb
@@ -1,16 +1,15 @@
# xmavericks (10.9) build Assumes:
-# (1) deps are in BREWLOC
-# (2) Ruby was built -C --enable-shared --enable-load-relative & installed in BREWLOC
+# (1) deps are in ShoesDeps
+# (2) Ruby was built -C --enable-shared --enable-load-relative & installed in ShoesDeps
# (3) 10.9 SDK is installed (ln -s if need) in Xcode.app/....
include FileUtils
-
cf =(ENV['ENV_CUSTOM'] || "#{TGT_ARCH}-custom.yaml")
if File.exists? cf
custmz = YAML.load_file(cf)
- BREWLOC = custmz['Deps']
+ ShoesDeps = custmz['Deps']
EXT_RUBY = custmz['Ruby'] ? custmz['Ruby'] : RbConfig::CONFIG['prefix']
puts "For #{EXT_RUBY}"
- ENV['GDB'] = 'basic' if custmz['Debug'] == true
+ APP['GDB'] = 'basic' if custmz['Debug'] == true
ENV['CDEFS'] = custmz['CFLAGS'] if custmz['CFLAGS']
APP['GEMLOC'] = custmz['Gemloc'] if custmz['Gemloc']
APP['EXTLOC'] = custmz['Extloc'] if custmz['Extloc']
@@ -18,20 +17,14 @@
APP['GEMLIST'] = custmz['Gems'] if custmz['Gems']
APP['INCLGEMS'] = custmz['InclGems'] if custmz['InclGems']
ENV['CDEFS'] = custmz['CFLAGS'] if custmz['CFLAGS']
- ENV['SQLLOC'] = BREWLOC
+ ENV['SQLLOC'] = ShoesDeps
else
abort "You must have a #{TGT_ARCH}-custom.yaml"
end
CC = ENV['CC'] ? ENV['CC'] : "gcc"
-file_list = %w{shoes/console/tesi.c shoes/console/colortab.c shoes/console/cocoa-term.m shoes/native/cocoa.m shoes/http/nsurl.m} +
- ["shoes/*.c"] + ["shoes/plot/*.c"]
-file_list << 'shoes/video/video.c'
-SRC = FileList[*file_list]
-OBJ = SRC.map do |x|
- x.gsub(/\.\w+$/, '.o')
-end
-if ENV['DEBUG'] || ENV['GDB']
+
+if APP['GDB']
LINUX_CFLAGS = " -g"
else
LINUX_CFLAGS = " -O"
@@ -41,18 +34,18 @@
# nothing is going to change for 10.9 deps - don't bother with pkg-config
# because it does go wrong in this situation.
-GLIB_CFLAGS = "-I#{BREWLOC}/include/glib-2.0 -I#{BREWLOC}/lib/glib-2.0/include"
-GLIB_CFLAGS << " -I#{BREWLOC}/include/librsvg-2.0/librsvg -I#{BREWLOC}/include/gdk-pixbuf-2.0/"
-GLIB_LDFLAGS = "-L#{BREWLOC}/lib -lglib-2.0 -lgobject-2.0 -lintl #{BREWLOC}/lib/librsvg-2.2.dylib"
-CAIRO_CFLAGS = "-I#{BREWLOC}/include/cairo"
-CAIRO_LDFLAGS = "-L#{BREWLOC}/lib -lcairo"
-PANGO_CFLAGS = "-I#{BREWLOC}/include/pango-1.0"
-PANGO_LDFLAGS = "-L#{BREWLOC}/lib -lpango-1.0"
-#RUBY_CFLAGS = "-I#{BREWLOC}/include/ruby-2.1.0/x86_64-darwin13.0 -I#{BREWLOC}/include/ruby-2.1.0 "
-RUBY_CFLAGS = "-I#{BREWLOC}/include/ruby-2.2.0/x86_64-darwin13 -I#{BREWLOC}/include/ruby-2.2.0 "
-RUBY_LDFLAGS = "-L#{BREWLOC}lib/ -Wl,-undefined,dynamic_lookup -Wl,-multiply_defined,suppress -lruby.2.1.0 -lpthread -ldl -lobjc "
+GLIB_CFLAGS = "-I#{ShoesDeps}/include/glib-2.0 -I#{ShoesDeps}/lib/glib-2.0/include"
+GLIB_CFLAGS << " -I#{ShoesDeps}/include/librsvg-2.0/librsvg -I#{ShoesDeps}/include/gdk-pixbuf-2.0/"
+GLIB_LDFLAGS = "-L#{ShoesDeps}/lib -lglib-2.0 -lgobject-2.0 -lintl #{ShoesDeps}/lib/librsvg-2.2.dylib"
+CAIRO_CFLAGS = "-I#{ShoesDeps}/include/cairo"
+CAIRO_LDFLAGS = "-L#{ShoesDeps}/lib -lcairo"
+PANGO_CFLAGS = "-I#{ShoesDeps}/include/pango-1.0"
+PANGO_LDFLAGS = "-L#{ShoesDeps}/lib -lpango-1.0"
+#RUBY_CFLAGS = "-I#{ShoesDeps}/include/ruby-2.1.0/x86_64-darwin13.0 -I#{ShoesDeps}/include/ruby-2.1.0 "
+RUBY_CFLAGS = "-I#{ShoesDeps}/include/ruby-2.3.0/x86_64-darwin13 -I#{ShoesDeps}/include/ruby-2.3.0 "
+RUBY_LDFLAGS = "-L#{ShoesDeps}lib/ -Wl,-undefined,dynamic_lookup -Wl,-multiply_defined,suppress -lruby.2.3.0 -lpthread -ldl -lobjc "
-LINUX_CFLAGS << " -I#{BREWLOC}/include #{GLIB_CFLAGS} #{RUBY_CFLAGS} #{CAIRO_CFLAGS} #{PANGO_CFLAGS}"
+LINUX_CFLAGS << " -I#{ShoesDeps}/include #{GLIB_CFLAGS} #{RUBY_CFLAGS} #{CAIRO_CFLAGS} #{PANGO_CFLAGS}"
LINUX_LIB_NAMES = %W[#{RUBY_SO} cairo pangocairo-1.0 gif]
@@ -72,17 +65,23 @@
LINUX_CFLAGS << ' -Wno-incompatible-pointer-types-discards-qualifiers'
OSX_ARCH = '-arch x86_64'
-# These env vars are used in chipmunk, sqlite3 extconf.rb
+# These env vars are used in chipmunk, sqlite3 extconf.rb - not needed in 3.3.3+?
#SHOES_TGT_ARCH = SHOES_GEM_ARCH ='x86_64-darwin13.0'
SHOES_TGT_ARCH = SHOES_GEM_ARCH ='x86_64-darwin13'
ENV['CC'] = CC
ENV['TGT_RUBY_PATH'] = EXT_RUBY
ENV['TGT_ARCH'] = SHOES_TGT_ARCH
-ENV['TGT_RUBY_V'] = '2.1.0' # library version - all 2.1.x rubys
+ENV['TGT_RUBY_V'] = '2.3.0' # library version - all 2.3.x rubys
ENV['SYSROOT'] = " -isysroot #{OSX_SDK} #{OSX_ARCH}"
LINUX_CFLAGS << " -isysroot #{OSX_SDK} #{OSX_ARCH}"
-LINUX_LDFLAGS << " -isysroot #{OSX_SDK} #{OSX_ARCH} -L#{BREWLOC}/lib/ #{GLIB_LDFLAGS}"
+LINUX_LDFLAGS << " -isysroot #{OSX_SDK} #{OSX_ARCH} -L#{ShoesDeps}/lib/ #{GLIB_LDFLAGS}"
-LINUX_LIBS = " -l#{RUBY_SO} -L#{BREWLOC}/lib -l cairo -L#{BREWLOC}/lib -lpangocairo-1.0 -L#{BREWLOC}/lib -lgif -ljpeg"
+LINUX_LIBS = " -l#{RUBY_SO} -L#{ShoesDeps}/lib -l cairo -L#{ShoesDeps}/lib -lpangocairo-1.0 -L#{ShoesDeps}/lib -lgif -ljpeg"
LINUX_LIBS << " -L#{TGT_DIR} #{CAIRO_LDFLAGS} #{PANGO_LDFLAGS} #{GLIB_LDFLAGS}"
+
+libdll = "#{ShoesDeps}/lib"
+SOLOCS = {
+ 'curl' => "#{libdll}/libcurl.dylib"
+}
+
diff --git a/make/darwin/xmavericks/setup.rb b/make/darwin/xmavericks/setup.rb
new file mode 100644
index 00000000..c6fa4433
--- /dev/null
+++ b/make/darwin/xmavericks/setup.rb
@@ -0,0 +1,41 @@
+# This is a big gulp of copying.
+require 'fileutils'
+module Make
+ include FileUtils
+
+ def static_setup (so_list)
+ $stderr.puts "setup: dir=#{`pwd`} for #{TGT_DIR}"
+ #rm_rf "#{TGT_DIR}"
+ mkdir_p "#{TGT_DIR}/#{APP['Bld_Tmp']}"
+ # copy Ruby, dylib, includes - have them in place before
+ # we build exts (chipmunk).
+ puts "Ruby at #{EXT_RUBY}"
+ rbvt = RUBY_V
+ rbvm = RUBY_V[/^\d+\.\d+/]
+ mkdir_p "#{TGT_DIR}/lib"
+ # clean out leftovers from last build
+ rm_f "#{TGT_DIR}/libruby.dylib" if File.exist? "#{TGT_DIR}/libruby.dylib"
+ rm_f "#{TGT_DIR}/libruby.#{rbvm}.dylib" if File.exist? "#{TGT_DIR}/libruby.#{rbvm}.dylib"
+ rm_f "#{TGT_DIR}/libruby.#{rbvt}.dylib" if File.exist? "#{TGT_DIR}/libruby.#{rbvt}.dylib"
+ mkdir_p "#{TGT_DIR}/lib/ruby/#{rbvm}.0/#{RUBY_PLATFORM}"
+ cp_r "#{EXT_RUBY}/lib/ruby", "#{TGT_DIR}/lib"
+ # copy and link libruby.dylib
+ cp "#{EXT_RUBY}/lib/libruby.#{rbvt}.dylib", "#{TGT_DIR}"
+ # copy include files - it might help build gems
+ mkdir_p "#{TGT_DIR}/lib/ruby/include/ruby-#{rbvt}"
+ cp_r "#{EXT_RUBY}/include/ruby-#{rbvt}/", "#{TGT_DIR}/lib/ruby/include"
+ SOLOCS.each do |k, v|
+ cp v, TGT_DIR
+ end
+
+ # copy some static stuff
+ cp_r "fonts", "#{TGT_DIR}/fonts"
+ cp_r "lib", "#{TGT_DIR}"
+ cp_r "samples", "#{TGT_DIR}/samples"
+ cp_r "static", "#{TGT_DIR}/static"
+ cp "README.md", "#{TGT_DIR}/README.txt"
+ cp "CHANGELOG", "#{TGT_DIR}/CHANGELOG.txt"
+ cp "COPYING", "#{TGT_DIR}/COPYING.txt"
+ end
+end
+
diff --git a/make/darwin/xmavericks/tasks.rb b/make/darwin/xmavericks/tasks.rb
index eec15fbc..e9f9198d 100644
--- a/make/darwin/xmavericks/tasks.rb
+++ b/make/darwin/xmavericks/tasks.rb
@@ -2,29 +2,6 @@
module Make
include FileUtils
- def copy_files_to_dist
- if ENV['APP']
- if APP['clone']
- sh APP['clone'].gsub(/^git /, "#{GIT} --git-dir=#{ENV['APP']}/.git ")
- else
- cp_r ENV['APP'], "#{TGT_DIR}/app"
- end
- if APP['ignore']
- APP['ignore'].each do |nn|
- rm_rf "#{TGT_DIR}/app/#{nn}"
- end
- end
- end
-
- cp_r "fonts", "#{TGT_DIR}/fonts"
- cp_r "lib", "#{TGT_DIR}"
- cp_r "samples", "#{TGT_DIR}/samples"
- cp_r "static", "#{TGT_DIR}/static"
- cp "README.md", "#{TGT_DIR}/README.txt"
- cp "CHANGELOG", "#{TGT_DIR}/CHANGELOG.txt"
- cp "COPYING", "#{TGT_DIR}/COPYING.txt"
- end
-
def cc(t)
sh "#{CC} -I. -c -o#{t.name} #{LINUX_CFLAGS} #{t.source}"
end
@@ -45,21 +22,23 @@ def rewrite before, after, reg = /\#\{(\w+)\}/, reg2 = '\1'
end
end
end
-
- def copy_files glob, dir
- FileList[glob].each { |f| cp_r f, dir }
- end
-
- def common_build
- copy_gems
- end
-
- # Check the environment
- def env(x)
- unless ENV[x]
- abort "Your #{x} environment variable is not set!"
+
+ def rewrite_ary before, after, reg = /\#\{(\w+\[\'\w+\'\])\}/, reg2 = '\1'
+ File.open(after, 'w') do |a|
+ File.open(before) do |b|
+ b.each do |line|
+ a << line.gsub(reg) do
+ if reg2.include? '\1'
+ #reg2.gsub(%r!\\1!, Object.const_get($1))
+ sub = eval $1
+ reg2.gsub(%r!\\1!, sub)
+ else
+ reg2
+ end
+ end
+ end
+ end
end
- ENV[x]
end
end
@@ -68,68 +47,6 @@ class MakeDarwin
class << self
- def pre_build
- puts "Entering osx pre_build #{TGT_DIR}"
- rm_rf "#{TGT_DIR}"
- # copy Ruby, dylib, includes - have them in place before
- # we build exts (chipmunk).
- puts "Ruby at #{EXT_RUBY}"
- rbvt = RUBY_V
- rbvm = RUBY_V[/^\d+\.\d+/]
- mkdir_p "#{TGT_DIR}/lib"
- # clean out leftovers from last build
- rm_f "#{TGT_DIR}/libruby.dylib" if File.exist? "#{TGT_DIR}/libruby.dylib"
- rm_f "#{TGT_DIR}/libruby.#{rbvm}.dylib" if File.exist? "#{TGT_DIR}/libruby.#{rbvm}.dylib"
- rm_f "#{TGT_DIR}/libruby.#{rbvt}.dylib" if File.exist? "#{TGT_DIR}/libruby.#{rbvt}.dylib"
- mkdir_p "#{TGT_DIR}/lib/ruby/#{rbvm}.0/#{RUBY_PLATFORM}"
- cp_r "#{EXT_RUBY}/lib/ruby", "#{TGT_DIR}/lib"
- # copy and link libruby.dylib
- cp "#{EXT_RUBY}/lib/libruby.#{rbvt}.dylib", "#{TGT_DIR}"
- # copy include files - it might help build gems
- mkdir_p "#{TGT_DIR}/lib/ruby/include/ruby-#{rbvt}"
- cp_r "#{EXT_RUBY}/include/ruby-#{rbvt}/", "#{TGT_DIR}/lib/ruby/include"
- # build a hash of x.dylib > BrewLoc/**/*.dylib
- @brew_hsh = {}
- Dir.glob("#{BREWLOC}/lib/**/*.dylib").each do |path|
- key = File.basename(path)
- @brew_hsh[key] = path
- end
-
- # Find ruby's dependent libs
- cd "#{TGT_DIR}/lib/ruby/#{rbvm}.0/#{SHOES_TGT_ARCH}" do
- bundles = *Dir['*.bundle']
- puts "Bundles #{bundles}"
- cplibs = {}
- bundles.each do |bpath|
- `otool -L #{bpath}`.split.each do |lib|
- cplibs[lib] = lib if File.extname(lib)=='.dylib'
- end
- end
- cplibs.each_key do |k|
- cppath = @brew_hsh[File.basename(k)]
- if cppath
- cp cppath, "#{TGT_DIR}"
- chmod 0755, "#{TGT_DIR}/#{File.basename k}"
- puts "Copy #{cppath}"
- else
- puts "Missing Ruby: #{k}"
- end
- end
- # -id/-change the lib
- bundles.each do |f|
- dylibs = get_dylibs f
- dylibs.each do |dylib|
- if @brew_hsh[File.basename(dylib)]
- sh "install_name_tool -change #{dylib} @executable_path/../#{File.basename dylib} #{f}"
- else
- puts "Bundle lib missing #{dylib}"
- end
- end
- end
- #abort "Quitting"
- end
- end
-
def change_install_names
puts "Entering change_install_names"
cd "#{TGT_DIR}" do
@@ -144,17 +61,6 @@ def change_install_names
end
end
- def copy_pango_modules
- puts "Entering copy_pango_modules #{`pwd`}"
- mkdir_p "#{TGT_DIR}/pango/modules"
- puts "Leaving copy_pango_modules"
- end
-
- def copy_gem_deplibs
- puts "Entering copy_gem_deplibs"
- puts "leaving copy_gem_deplib"
- end
-
# Get a list of linked libraries for lib (discard the non-indented lines)
def get_dylibs lib
`otool -L #{lib}`.split("\n").inject([]) do |dylibs, line|
@@ -178,8 +84,6 @@ def dylibs_to_change lib
def copy_deps_to_dist
puts "Entering copy_deps_to_dist #{TGT_DIR}"
- copy_gem_deplibs
- #copy_pango_modules
# Generate a list of dependencies straight from the generated files.
# Start with dependencies of shoes-bin, and then add the dependencies
# of those dependencies. Finally, add any oddballs that must be
@@ -215,7 +119,7 @@ def copy_deps_to_dist
puts "Adding #{libn}"
@brew_hsh[keyf] = libn
#cp @brew_hsh[keyf], "#{TGT_DIR}/" unless File.exists? "#{TGT_DIR}/#{keyf}"
- cp "#{BREWLOC}/lib/#{keyf}", "#{TGT_DIR}/" unless File.exists? "#{TGT_DIR}/#{keyf}"
+ cp "#{ShoesDeps}/lib/#{keyf}", "#{TGT_DIR}/" unless File.exists? "#{TGT_DIR}/#{keyf}"
chmod 0755, "#{TGT_DIR}/#{keyf}" unless File.writable? "#{TGT_DIR}/#{keyf}"
else
puts "Missing #{libn}"
@@ -227,10 +131,79 @@ def copy_deps_to_dist
['libresolv.9.dylib', 'libicucore.A.dylib', 'libc++.1.dylib', 'libc++abi.dylib'].each do |lib|
rm "#{TGT_DIR}/#{lib}" if File.exists? "#{TGT_DIR}/#{lib}"
end
- end
-
+ end
+
def setup_system_resources
+ # called after the gems are copied into the above setup.
+ # build a hash of x.dylib > ShoesDeps/**/*.dylib
+ @brew_hsh = {}
+ Dir.glob("#{ShoesDeps}/lib/**/*.dylib").each do |path|
+ key = File.basename(path)
+ @brew_hsh[key] = path
+ end
+ rbvm = RUBY_V[/^\d+\.\d+/]
+ # Find ruby's + gems dependent libs
+ cd "#{TGT_DIR}/lib/ruby/#{rbvm}.0/#{SHOES_TGT_ARCH}" do
+ bundles = *Dir['*.bundle']
+ puts "Bundles #{bundles}"
+ cplibs = {}
+ bundles.each do |bpath|
+ `otool -L #{bpath}`.split.each do |lib|
+ cplibs[lib] = lib if File.extname(lib)=='.dylib'
+ end
+ end
+ cplibs.each_key do |k|
+ cppath = @brew_hsh[File.basename(k)]
+ if cppath
+ cp cppath, "#{TGT_DIR}"
+ chmod 0755, "#{TGT_DIR}/#{File.basename k}"
+ puts "Copy #{cppath}"
+ else
+ puts "Missing Ruby: #{k}"
+ end
+ end
+ # -id/-change the lib
+ bundles.each do |f|
+ dylibs = get_dylibs f
+ dylibs.each do |dylib|
+ if @brew_hsh[File.basename(dylib)]
+ sh "install_name_tool -change #{dylib} @executable_path/../#{File.basename dylib} #{f}"
+ else
+ puts "Bundle lib missing #{dylib}"
+ end
+ end
+ end
+ end
+ end
+
+ def postbuild_fix
+ # if this is called the only thing that has changed is libshoes.dylib
+ # and shoes-bin. This hasn't needed but might involve
+ #$stderr.puts "called postbuild_fix"
+=begin
+ install_name_tool -id @executable_path/shoes-bin shoes-bin
+ install_name_tool -change /usr/local/lib/libcairo.2.dylib @executable_path/libcairo.2.dylib shoes-bin
+ install_name_tool -change /usr/local/lib/libpangocairo-1.0.0.dylib @executable_path/libpangocairo-1.0.0.dylib shoes-bin
+ install_name_tool -change /usr/local/lib/libgif.4.dylib @executable_path/libgif.4.dylib shoes-bin
+ install_name_tool -change /usr/local/lib/libjpeg.8.dylib @executable_path/libjpeg.8.dylib shoes-bin
+ install_name_tool -change /usr/local/lib/libpango-1.0.0.dylib @executable_path/libpango-1.0.0.dylib shoes-bin
+ install_name_tool -change /usr/local/lib/libglib-2.0.0.dylib @executable_path/libglib-2.0.0.dylib shoes-bin
+ install_name_tool -change /usr/local/lib/libgobject-2.0.0.dylib @executable_path/libgobject-2.0.0.dylib shoes-bin
+ install_name_tool -change /usr/local/lib/libintl.8.dylib @executable_path/libintl.8.dylib shoes-bin
+ install_name_tool -change /usr/local/lib/librsvg-2.2.dylib @executable_path/librsvg-2.2.dylib shoes-bin
+=end
+ end
+
+ def osx_create_app
puts "Enter setup_system_resources"
+ # create plist version string
+ tf = File.open("VERSION.txt")
+ str = tf.readline
+ tf.close
+ flds = str.split(' ');
+ APP['plist_version_string'] = "#{flds[1]} #{flds[2]} #{flds[3]}"
+ puts "plist_version_string #{APP['plist_version_string']}"
+
tmpd = "/tmp"
rm_rf "#{tmpd}/#{APPNAME}.app"
mkdir "#{tmpd}/#{APPNAME}.app"
@@ -240,7 +213,12 @@ def setup_system_resources
mkdir "#{tmpd}/#{APPNAME}.app/Contents/Resources/English.lproj"
sh "ditto \"#{APP['icons']['osx']}\" \"#{tmpd}/#{APPNAME}.app/App.icns\""
sh "ditto \"#{APP['icons']['osx']}\" \"#{tmpd}/#{APPNAME}.app/Contents/Resources/App.icns\""
- rewrite "platform/mac/Info.plist", "#{tmpd}/#{APPNAME}.app/Contents/Info.plist"
+ #rewrite "platform/mac/Info.plist", "#{tmpd}/#{APPNAME}.app/Contents/Info.plist"
+ rewrite "platform/mac/Info.plist", "#{tmpd}/#{APPNAME}.app/Contents/Info.plist-1"
+ rewrite_ary "#{tmpd}/#{APPNAME}.app/Contents/Info.plist-1",
+ "#{tmpd}/#{APPNAME}.app/Contents/Info.plist"
+ rm "#{tmpd}/#{APPNAME}.app/Contents/Info.plist-1"
+
cp "platform/mac/version.plist", "#{tmpd}/#{APPNAME}.app/Contents/"
rewrite "platform/mac/pangorc", "#{tmpd}/#{APPNAME}.app/Contents/MacOS/pangorc"
cp "platform/mac/command-manual.rb", "#{tmpd}/#{APPNAME}.app/Contents/MacOS/"
@@ -251,6 +229,7 @@ def setup_system_resources
chmod 0755, "#{tmpd}/#{APPNAME}.app/Contents/MacOS/#{NAME}"
# cp InfoPlist.strings YourApp.app/Contents/Resources/English.lproj/
`echo -n 'APPL????' > "#{tmpd}/#{APPNAME}.app/Contents/PkgInfo"`
+ rm_rf "#{TGT_DIR}/#{APPNAME}.app"
mv "#{tmpd}/#{APPNAME}.app", "#{TGT_DIR}"
# create cshoes script /Users/ccoupe/build/mavericks/Shoes.app/Contents/MacOS
rewrite "platform/mac/cshoes.tmpl", "cshoes"
@@ -260,24 +239,42 @@ def setup_system_resources
def make_stub
sh "gcc -O -isysroot #{OSX_SDK} -framework Cocoa -o stub-osx platform/mac/stub.m -I."
end
-
- def make_app(name)
- puts "Enter make_app"
+
+ def new_so(name)
+ $stderr.puts "new__so #{name}"
+ objs = []
+ SubDirs.each do |f|
+ d = File.dirname(f)
+ objs = objs + FileList["#{d}/*.o"]
+ end
+ # TODO fix: gtk - needs to dig deeper vs osx
+ objs = objs + FileList["shoes/native/gtk/*.o"]
+ main_o = 'shoes/main.o'
+ objs = objs - [main_o]
+ #$stderr.puts "objs: #{objs}"
+ ldflags = LINUX_LDFLAGS.sub! /INSTALL_NAME/, "-install_name @executable_path/lib#{SONAME}.#{DLEXT}"
+ sh "#{CC} -o #{name} #{objs.join(' ')} #{LINUX_LDFLAGS} #{LINUX_LIBS}"
+ end
+
+ def new_link(name)
+ $stderr.puts "new_link #{name}"
bin = "#{name}-bin"
rm_f name
rm_f bin
- sh "#{CC} -L#{TGT_DIR} -o #{bin} bin/main.o #{LINUX_LIBS} -lshoes #{OSX_ARCH}"
- end
-
- def make_so(name)
- puts "Enter make_so"
- ldflags = LINUX_LDFLAGS.sub! /INSTALL_NAME/, "-install_name @executable_path/lib#{SONAME}.#{DLEXT}"
- sh "#{CC} -o #{name} #{OBJ.join(' ')} #{LINUX_LDFLAGS} #{LINUX_LIBS}"
+ tp = "#{TGT_DIR}/#{APP['Bld_Tmp']}"
+ sh "#{CC} -L#{TGT_DIR} -o #{bin} #{tp}/main.o #{LINUX_LIBS} -lshoes #{OSX_ARCH}"
+ if File.exist? "#{tp}/zzshoesbin.done"
+ postbuild_fix
+ else
+ copy_deps_to_dist
+ end
+ osx_create_app # generate plist and much copying/moving
+ touch "#{tp}/zzshoesbin.done"
end
def make_installer
puts "tbz_create from #{`pwd`}"
- nfs=ENV['NFS_ALTP']
+ nfs=APP['Bld_Pre']
mkdir_p "#{nfs}pkg"
#distfile = "#{nfs}pkg/#{PKG}#{TINYVER}-osx-10.9.tbz"
distfile = "#{nfs}pkg/#{APPNAME}-#{APP['VERSION']}-osx-10.9.tgz"
@@ -300,44 +297,7 @@ def make_installer
mkdir_p "pkg"
sh "cp #{distfile.downcase} pkg/"
end
- end
-
- # unused - was make_installer
- def make_dmg_installer
- dmg_ds, dmg_jpg = "platform/mac/dmg_ds_store", "static/shoes-dmg.jpg"
- if APP['dmg']
- dmg_ds, dmg_jpg = APP['dmg']['ds_store'], APP['dmg']['background']
- end
-
- mkdir_p "pkg"
- rm_rf "dmg"
- mkdir_p "dmg"
- cp_r "#{APPNAME}.app", "dmg"
- unless ENV['APP']
- mv "dmg/#{APPNAME}.app/Contents/MacOS/samples", "dmg/samples"
- end
- ln_s "/Applications", "dmg/Applications"
- sh "chmod +x dmg/\"#{APPNAME}.app\"/Contents/MacOS/#{NAME}"
- sh "chmod +x dmg/\"#{APPNAME}.app\"/Contents/MacOS/#{NAME}-bin"
- sh "chmod +x dmg/\"#{APPNAME}.app\"/Contents/MacOS/#{NAME}-launch"
- sh "DYLD_LIBRARY_PATH= platform/mac/pkg-dmg --target pkg/#{PKG}.dmg --source dmg --volname '#{APPNAME}' --copy #{dmg_ds}:/.DS_Store --mkdir /.background --copy #{dmg_jpg}:/.background" # --format UDRW"
- rm_rf "dmg"
- end
-
- def gems_build
- puts "Build gems #{TGT_DIR}"
- mkdir_p "#{TGT_DIR}/builtins"
- gdir = "#{TGT_DIR}/builtins"
- {}.each do |gemn, xdir|
- spec = eval(File.read("req/#{gemn}/gemspec"))
- mkdir_p "#{gdir}/specifications"
- mkdir_p "#{gdir}/gems/#{spec.full_name}/lib"
- FileList["req/#{gemn}/lib/*"].each { |rlib| cp_r rlib, "#{gdir}/gems/#{spec.full_name}/lib" }
- mkdir_p "#{gdir}/gems/#{spec.full_name}/#{xdir}"
- FileList["req/#{gemn}/ext/*"].each { |elib| copy_ext elib, "#{gdir}/gems/#{spec.full_name}/#{xdir}" }
- cp "req/#{gemn}/gemspec", "#{gdir}/specifications/#{spec.full_name}.gemspec"
- puts "Gems: #{gemn}"
- end
+ # restore tmp dir to the build
end
def make_smaller
diff --git a/make/gems.rb b/make/gems.rb
index bff95314..ee454742 100644
--- a/make/gems.rb
+++ b/make/gems.rb
@@ -107,7 +107,7 @@ def copy_files glob, dir
def copy_gems
puts "copy_gems dir=#{pwd} #{SHOES_TGT_ARCH}"
APP['EXTLIST'].each do |ext|
- puts "copy prebuild ext #{ext}"
+ $stderr.puts "copy prebuild ext #{ext}"
copy_files "#{APP['EXTLOC']}/built/#{TGT_ARCH}/#{ext}/ext/*.#{Lext}", "#{TGT_DIR}/lib/ruby/#{RUBY_V}/#{SHOES_TGT_ARCH}"
if File.exists? "#{APP['EXTLOC']}/built/#{TGT_ARCH}/#{ext}/lib"
Dir.glob("#{APP['EXTLOC']}/built/#{TGT_ARCH}/#{ext}/lib/*").each do |lib|
@@ -119,7 +119,7 @@ def copy_gems
# precompiled gems here - just copy
APP['INCLGEMS'].each do |gemn|
gemp = "#{APP['GEMLOC']}/built/#{TGT_ARCH}/#{gemn}"
- puts "Copying prebuilt gem #{gemp}"
+ $stderr.puts "Copying prebuilt gem #{gemp}"
spec = eval(File.read("#{gemp}/gemspec"))
mkdir_p "#{gdir}/specifications"
mkdir_p "#{gdir}/specifications/default"
@@ -135,12 +135,12 @@ def copy_gems
end
cp "#{gemp}/gemspec", "#{gdir}/specifications/#{spec.full_name}.gemspec"
if spec.require_paths.include? 'ext'
- puts "Ext weird copy = #{spec.require_paths}"
+ $stderr.puts "Ext weird copy = #{spec.require_paths}"
mkdir_p "#{gdir}/gems/#{spec.full_name}/ext"
cp_r "#{gemp}/ext", "#{gdir}/gems/#{spec.full_name}"
end
if spec.require_paths.include? 'lib'
- puts "Lib copy = #{spec.require_paths[-1]}"
+ $stderr.puts "Lib copy = #{spec.require_paths[-1]}"
mkdir_p "#{gdir}/gems/#{spec.full_name}/lib"
cp_r "#{gemp}/lib", "#{gdir}/gems/#{spec.full_name}"
end
@@ -154,7 +154,7 @@ def copy_gems
# do we need a rpath fixup? linux? probably not. OSX possibly
if false
FileList["#{gdir}/gems/#{spec.full_name}/**/*.so"].each do |so|
- puts "FIX rpath #{so}"
+ $stderr.puts "FIX rpath #{so}"
sh "chrpath #{so} -r '${ORIGIN}/../lib'"
end
end
@@ -164,7 +164,7 @@ def copy_gems
Dir.chdir("#{gdir}/gems/#{spec.full_name}/lib/nokogiri/") do
Dir.glob('*').each do |dirn|
if dirn =~ /\d.\d/ && dirn != grubyv
- puts "Noko delete: #{dirn}"
+ $stderr.puts "Noko delete: #{dirn}"
rm_r dirn
end
end
diff --git a/make/linux/i686-linux/env.rb b/make/linux/i686-linux/env.rb
index 2c0c575e..178027c2 100644
--- a/make/linux/i686-linux/env.rb
+++ b/make/linux/i686-linux/env.rb
@@ -6,40 +6,27 @@
custmz = YAML.load_file(cf)
ShoesDeps = custmz['Deps']
EXT_RUBY = custmz['Ruby']
- ENV['GDB'] = 'basic' if custmz['Debug'] == true
+ APP['GDB'] = 'basic' if custmz['Debug'] == true
APP['GEMLOC'] = custmz['Gemloc'] if custmz['Gemloc']
APP['EXTLOC'] = custmz['Extloc'] if custmz['Extloc']
APP['EXTLIST'] = custmz['Exts'] if custmz['Exts']
APP['GEMLIST'] = custmz['Gems'] if custmz['Gems']
APP['INCLGEMS'] = custmz['InclGems'] if custmz['InclGems']
- #APP['GTK'] = custmz['Gtk'] if custmz['Gtk']
else
abort "You need a custom.yaml"
end
APP['GTK'] = "gtk+-3.0"
-#ENV['DEBUG'] = "true" # turns on the tracing log
-CHROOT = ShoesDeps
SHOES_TGT_ARCH = 'i686-linux'
SHOES_GEM_ARCH = "#{Gem::Platform.local}"
-# Specify where the Target system binaries live.
-# Trailing slash is important.
-TGT_SYS_DIR = "#{CHROOT}/"
# Setup some shortcuts for the library locations
arch = 'i386-linux-gnu'
-uldir = "#{TGT_SYS_DIR}usr/lib"
-ularch = "#{TGT_SYS_DIR}usr/lib/#{arch}"
-larch = "#{TGT_SYS_DIR}lib/#{arch}"
+uldir = "#{ShoesDeps}/usr/lib"
+ularch = "#{ShoesDeps}/usr/lib/#{arch}"
+larch = "#{ShoesDeps}/lib/#{arch}"
# Set appropriately
CC = "gcc"
-pkgruby ="#{EXT_RUBY}/lib/pkgconfig/ruby-2.2.pc"
+pkgruby ="#{EXT_RUBY}/lib/pkgconfig/ruby-2.3.pc"
pkggtk ="#{ularch}/pkgconfig/gtk+-3.0.pc"
-file_list = ["shoes/console/*.c"] + ["shoes/native/*.c"] + ["shoes/http/rbload.c"] + ["shoes/*.c"] +
- ["shoes/plot/*.c"]
-file_list << "shoes/video/video.c"
-SRC = FileList[*file_list]
-OBJ = SRC.map do |x|
- x.gsub(/\.\w+$/, '.o')
-end
ADD_DLL = []
@@ -49,7 +36,7 @@
png_lib = 'png'
-if ENV['DEBUG'] || ENV['GDB']
+if APP['GDB']
LINUX_CFLAGS = " -g -O0"
else
LINUX_CFLAGS = " -O -Wall"
@@ -57,10 +44,10 @@
LINUX_CFLAGS << " -DSHOES_GTK -Wno-unused-but-set-variable -Wno-unused-variable"
LINUX_CFLAGS << " -DRUBY_HTTP"
-LINUX_CFLAGS << " -I#{TGT_SYS_DIR}usr/include "
+LINUX_CFLAGS << " -I#{ShoesDeps}/usr/include "
LINUX_CFLAGS << `pkg-config --cflags "#{pkgruby}"`.strip+" "
LINUX_CFLAGS << `pkg-config --cflags "#{pkggtk}"`.strip+" "
-LINUX_CFLAGS << " -I#{TGT_SYS_DIR}usr/include/ "
+LINUX_CFLAGS << " -I#{ShoesDeps}/usr/include/ "
LINUX_CFLAGS << "-I/usr/include/librsvg-2.0/librsvg "
MISC_LIB = ' /usr/lib/i386-linux-gnu/librsvg-2.so'
diff --git a/make/linux/i686-linux/setup.rb b/make/linux/i686-linux/setup.rb
new file mode 100644
index 00000000..6e68dbd3
--- /dev/null
+++ b/make/linux/i686-linux/setup.rb
@@ -0,0 +1,43 @@
+# This is a big gulp of copying.
+require 'fileutils'
+module Make
+ include FileUtils
+
+ # Windows cross compile. Copy the static stuff, Copy the ruby libs
+ # Then copy the deps.
+ def static_setup (so_list)
+ $stderr.puts "setup: dir=#{`pwd`}"
+ rbvt = RUBY_V
+ rbvm = RUBY_V[/^\d+\.\d+/]
+ mkdir_p "#{TGT_DIR}/lib"
+ mkdir_p "#{TGT_DIR}/fonts"
+ cp_r "fonts", "#{TGT_DIR}/fonts"
+ mkdir_p "#{TGT_DIR}/lib"
+ cp "lib/shoes.rb", "#{TGT_DIR}/lib"
+ cp_r "lib/shoes", "#{TGT_DIR}/lib"
+ cp_r "lib/exerb", "#{TGT_DIR}/lib"
+ cp_r "samples", "#{TGT_DIR}/samples"
+ cp_r "static", "#{TGT_DIR}/static"
+ cp "README.md", "#{TGT_DIR}/README.txt"
+ cp "CHANGELOG", "#{TGT_DIR}/CHANGELOG.txt"
+ cp "COPYING", "#{TGT_DIR}/COPYING.txt"
+ # clean out leftovers from last build
+ #rm_f "#{TGT_DIR}/libruby.so" if File.exist? "#{TGT_DIR}/libruby.so"
+ #rm_f "#{TGT_DIR}/libruby.so.#{rbvm}" if File.exist? "#{TGT_DIR}/libruby.so.#{rbvm}"
+ #rm_f "#{TGT_DIR}/libruby.so.#{rbvt}" if File.exist? "#{TGT_DIR}/libruby.so.#{rbvt}"
+ cp_r "#{EXT_RUBY}/lib/ruby", "#{TGT_DIR}/lib", remove_destination: true
+ # copy and link libruby.so
+ cp "#{EXT_RUBY}/lib/libruby.so.#{rbvm}", "#{TGT_DIR}"
+
+ # copy include files - it might help build gems
+ mkdir_p "#{TGT_DIR}/lib/ruby/include/ruby-#{rbvt}"
+ cp_r "#{EXT_RUBY}/include/ruby-#{rbvt}/", "#{TGT_DIR}/lib/ruby/include"
+ chdir TGT_DIR do
+ ln_s "libruby.so.#{rbvm}", "libruby.so"
+ end
+ SOLOCS.each_value do |path|
+ cp "#{path}", "#{TGT_DIR}"
+ end
+ end
+end
+
diff --git a/make/linux/i686-linux/tasks.rb b/make/linux/i686-linux/tasks.rb
index 7247a530..74eb6768 100644
--- a/make/linux/i686-linux/tasks.rb
+++ b/make/linux/i686-linux/tasks.rb
@@ -1,32 +1,6 @@
module Make
include FileUtils
- def copy_files_to_dist
- puts "copy_files_to_dist dir=#{pwd}"
- if ENV['APP']
- if APP['clone']
- sh APP['clone'].gsub(/^git /, "#{GIT} --git-dir=#{ENV['APP']}/.git ")
- else
- cp_r ENV['APP'], "#{TGT_DIR}/app"
- end
- if APP['ignore']
- APP['ignore'].each do |nn|
- rm_rf "dist/app/#{nn}"
- end
- end
- end
-
- cp_r "fonts", "#{TGT_DIR}/fonts"
- cp "lib/shoes.rb", "#{TGT_DIR}/lib"
- cp_r "lib/shoes", "#{TGT_DIR}/lib"
- cp_r "lib/exerb", "#{TGT_DIR}/lib"
- cp_r "samples", "#{TGT_DIR}/samples"
- cp_r "static", "#{TGT_DIR}/static"
- cp "README.md", "#{TGT_DIR}/README.txt"
- cp "CHANGELOG", "#{TGT_DIR}/CHANGELOG.txt"
- cp "COPYING", "#{TGT_DIR}/COPYING.txt"
- end
-
def cc(t)
sh "#{CC} -I. -c -o#{t.name} #{LINUX_CFLAGS} #{t.source}"
end
@@ -47,42 +21,6 @@ def rewrite before, after, reg = /\#\{(\w+)\}/, reg2 = '\1'
end
end
end
-
- def copy_files glob, dir
- FileList[glob].each { |f| cp_r f, dir }
- end
-
- # copy everything from the cross compiled Ruby libs as ruby wants it
- # copy any deps libraries that might ever be used in linking or when
- # building a static ar.
- def pre_build
- puts "pre_build dir=#{`pwd`}"
- rbvt = RUBY_V
- rbvm = RUBY_V[/^\d+\.\d+/]
- mkdir_p "#{TGT_DIR}/lib"
- # clean out leftovers from last build
- rm_f "#{TGT_DIR}/libruby.so" if File.exist? "#{TGT_DIR}/libruby.so"
- rm_f "#{TGT_DIR}/libruby.so.#{rbvm}" if File.exist? "#{TGT_DIR}/libruby.so.#{rbvm}"
- rm_f "#{TGT_DIR}/libruby.so.#{rbvt}" if File.exist? "#{TGT_DIR}/libruby.so.#{rbvt}"
- cp_r "#{EXT_RUBY}/lib/ruby", "#{TGT_DIR}/lib"
- # copy and link libruby.so
- cp "#{EXT_RUBY}/lib/libruby.so.#{rbvm}", "#{TGT_DIR}"
- # copy include files - it might help build gems
- mkdir_p "#{TGT_DIR}/lib/ruby/include/ruby-#{rbvt}"
- cp_r "#{EXT_RUBY}/include/ruby-#{rbvt}/", "#{TGT_DIR}/lib/ruby/include"
- chdir TGT_DIR do
- ln_s "libruby.so.#{rbvm}", "libruby.so"
- end
- SOLOCS.each_value do |path|
- cp "#{path}", "#{TGT_DIR}"
- end
- end
-
- # common_build is a misnomer. Build extentions, gems
- def common_build
- copy_gems
- end
-
end
@@ -92,62 +30,75 @@ class MakeLinux
extend Make
class << self
-
- def copy_deps_to_dist
- puts "copy_deps_to_dist dir=#{pwd}"
- unless ENV['GDB']
- sh "strip -x #{TGT_DIR}/*.so.*"
- sh "strip -x #{TGT_DIR}/*.so"
- end
- end
-
def setup_system_resources
cp APP['icons']['gtk'], "#{TGT_DIR}/static/app-icon.png"
end
-
- # name {TGT_DIR}/shoes
- def make_app(name)
- puts "make_app dir=#{pwd} arg=#{name}"
- bin = "#{name}-bin"
- rm_f name
- rm_f bin
- sh "#{CC} -o #{bin} bin/main.o -L#{TGT_DIR} -lshoes #{LINUX_LIBS}"
+
+
+ def new_so (name)
+ tgts = name.split('/')
+ tgtd = tgts[0]
+ $stderr.puts "new_so: #{tgtd}"
+ objs = []
+ SubDirs.each do |f|
+ d = File.dirname(f)
+ objs = objs + FileList["#{d}/*.o"]
+ end
+ objs = objs + FileList["shoes/native/gtk/*.o"]
+ main_o = 'shoes/main.o'
+ objs = objs - [main_o]
+ sh "#{CC} -o #{tgtd}/libshoes.#{DLEXT} #{objs.join(' ')} #{LINUX_LDFLAGS} #{LINUX_LIBS}"
+ end
+
+ def new_link(name)
+ #name is actually a file path
+ puts "new_link: arg=#{name}"
+ dpath = File.dirname(name)
+ fname = File.basename(name)
+ bin = "#{fname}-bin"
+ sh "#{CC} -o #{dpath}/#{bin} #{dpath}/tmp/main.o -L#{dpath} -lshoes -L#{TGT_DIR} #{LINUX_LIBS}"
rewrite "platform/nix/shoes.launch", name, %r!/shoes-bin!, "/#{NAME}-bin"
sh %{echo 'cd "$OLDPWD"\nLD_LIBRARY_PATH=$APPPATH $APPPATH/#{File.basename(bin)} "$@"' >> #{name}}
chmod 0755, "#{name}"
# write a gdb launched shoes
rewrite "platform/nix/shoes.launch", "#{TGT_DIR}/debug", %r!/shoes-bin!, "/#{NAME}-bin"
sh %{echo 'cd "$OLDPWD"\nLD_LIBRARY_PATH=$APPPATH gdb $APPPATH/#{File.basename(bin)} "$@"' >> #{TGT_DIR}/debug}
- chmod 0755, "#{TGT_DIR}/debug"
- end
-
- def make_so(name)
- puts "make_so dir=#{pwd} arg=#{name}"
- #ldflags = LINUX_LDFLAGS.sub! /INSTALL_NAME/, "-install_name @executable_path/lib#{SONAME}.#{DLEXT}"
- sh "#{CC} -o #{name} #{OBJ.join(' ')} #{LINUX_LDFLAGS} #{LINUX_LIBS}"
+ chmod 0755, "#{TGT_DIR}/debug"
end
- # make a .install with all the bits and peices.
+ # make a .install with all the bits and pieces.
def make_installer
- gtkv = APP['GTK']== 'gtk+-3.0' ? '3' : '2'
+ gtkv = '3'
arch = 'i686'
appname = "#{APP['name'].downcase}"
rlname = "#{appname}-#{APP['VERSION']}-gtk#{gtkv}-#{arch}"
#puts "Creating Pkg for #{rlname}"
- rm_r "pkg/#{rlname}" if File.exists? "pkg/#{rlname}"
+ pkg = ""
+ if APP['Bld_Pre']
+ pkg = "#{APP['Bld_Pre']}pkg"
+ mkdir_p pkg
+ else
+ pkg = 'pkg'
+ end
+ rm_r "#{pkg}/#{rlname}" if File.exists? "#{pkg}/#{rlname}"
cp_r "VERSION.txt", "#{TGT_DIR}"
- mkdir_p "pkg/#{rlname}"
- sh "cp -r #{TGT_DIR}/* pkg/#{rlname}"
- Dir.chdir "pkg/#{rlname}" do
+ mkdir_p "#{pkg}/#{rlname}"
+ sh "cp -r #{TGT_DIR}/* #{pkg}/#{rlname}"
+ Dir.chdir "#{pkg}/#{rlname}" do
+ rm_r "#{APP['Bld_Tmp']}"
+ rm_r "pkg" if File.exist? "pkg"
make_desktop
make_uninstall_script
make_install_script
- make_smaller unless ENV['GDB']
+ make_smaller unless APP['GDB']
end
- Dir.chdir "pkg" do
+ Dir.chdir "#{pkg}" do
puts `pwd`
- sh "makeself #{rlname} #{rlname}.install #{appname} \
-./shoes-install.sh "
+ sh "makeself #{rlname} #{rlname}.install #{appname} ./shoes-install.sh "
+ end
+ if APP['Bld_Pre']
+ # copy installer to the shoes3 source pkg/ dir (on an nfs server?)
+ cp "#{pkg}/#{rlname}.install", "pkg"
end
end
diff --git a/make/linux/loose/env.rb b/make/linux/minlin/env.rb
similarity index 74%
rename from make/linux/loose/env.rb
rename to make/linux/minlin/env.rb
index 412323b1..350cd2f5 100644
--- a/make/linux/loose/env.rb
+++ b/make/linux/minlin/env.rb
@@ -1,14 +1,11 @@
# This is for a Linux only build (loose shoes)
# It is safe and desireable to use RbConfig::CONFIG settings
-# Will not build gems and most extentions
-# Links against system (or rvm) ruby, and libraries. No LD_LIB_PATH
+# Will not build gems or copy gems - uses the host ruby.
+# Cannot be distributed.
require 'rbconfig'
-# manually set below to what you want to build with/for
-#ENV['DEBUG'] = "true" # turns on the call log
-
-ENV['GDB'] = "true" # true => compile -g, don't strip symbols
-if ENV['GDB']
+APP['GDB'] = "true" # true => compile -g, don't strip symbols
+if APP['GDB']
LINUX_CFLAGS = "-g -O0"
else
LINUX_CFLAGS = "-O -Wall"
@@ -20,25 +17,13 @@
LINUX_CFLAGS << " -DRUBY_HTTP"
LINUX_CFLAGS << " -DRUBY_1_9"
LINUX_CFLAGS << " -DDEBUG" if ENV['DEBUG']
-LINUX_CFLAGS << " -DSHOES_GTK -fPIC -shared"
+LINUX_CFLAGS << " -DSHOES_GTK -fPIC -shared -Wno-unused-but-set-variable"
# Following line may need handcrafting
LINUX_CFLAGS << " -I/usr/include/"
LINUX_CFLAGS << " #{`pkg-config --cflags gtk+-3.0`.strip}"
CC = "gcc"
-file_list = %w(shoes/native/gtk.c shoes/native/gtkfixedalt.c shoes/native/gtkentryalt.c
- shoes/native/gtkcomboboxtextalt.c shoes/native/gtkbuttonalt.c
- shoes/native/gtkscrolledwindowalt.c shoes/native/gtkprogressbaralt.c
- shoes/http/rbload.c) + ["shoes/*.c"] + ["shoes/console/*.c"] +
- ["shoes/plot/*.c"]
-file_list << "shoes/video/video.c"
-
-SRC = FileList[*file_list]
-OBJ = SRC.map do |x|
- x.gsub(/\.\w+$/, '.o')
-end
-
# Query pkg-config for cflags and link settings
EXT_RUBY = RbConfig::CONFIG['prefix']
RUBY_CFLAGS = " #{`pkg-config --cflags #{EXT_RUBY}/lib/pkgconfig/ruby-#{rv}.pc`.strip}"
@@ -91,3 +76,16 @@
# Main Rakefile and tasks.rb needs the below Constants
ADD_DLL = []
DLEXT = "so"
+SOLOCS = {} # needed to match Rakefile expectations.
+=begin
+# to save settings
+bld_args = {}
+bld_args['CC'] = CC
+bld_args['ADD_DLL'] = []
+bld_args['DLEXT'] = "so"
+bld_args['SOLOCS'] = {}
+bld_args['LINUX_CFLAGS'] = LINUX_CFLAGS
+bld_args['LINUX_LDFLAGS'] = LINUX_LDFLAGS
+bld_args['LINUX_LIBS'] = LINUX_LIBS
+File.open("#{TGT_DIR}/build.yaml", 'w') {|f| YAML.dump(bld_args, f)}
+=end
diff --git a/make/linux/minlin/setup.rb b/make/linux/minlin/setup.rb
new file mode 100644
index 00000000..846fa604
--- /dev/null
+++ b/make/linux/minlin/setup.rb
@@ -0,0 +1,54 @@
+module Make
+ include FileUtils
+
+
+ # Set up symlinks to lib/shoes and lib/shoes.rb so that they
+ # can be edited and tested without a rake clean/build every time we
+ # change a lib/shoes/*.rb
+ # They'll be copied (not linked) when rake install occurs. Be very
+ # careful. Only Link to FILES, not to directories. Fileutils.ln_s may
+ # not be the same as linux ln -s.
+ def static_setup (solocs)
+ srcloc= `pwd`.strip
+ puts "setup: #{srcloc}"
+=begin
+ mkdir_p "#{TGT_DIR}/lib/shoes"
+ Dir.chdir "#{TGT_DIR}/lib/shoes" do
+ Dir["../../../lib/shoes/*.rb"].each do |f|
+ #puts "SymLinking #{f}"
+ ln_s f, "." unless File.symlink? File.basename(f)
+ end
+ end
+ Dir.chdir "#{TGT_DIR}/lib" do
+ ln_s "../../lib/shoes.rb" , "shoes.rb" unless File.symlink? "shoes.rb"
+ # link to exerb
+ ln_s "../../lib/exerb", "exerb" unless File.symlink? "exerb"
+ end
+ cp_r "fonts", "#{TGT_DIR}/fonts"
+
+ #cp_r "samples", "#{TGT_DIR}/samples"
+ mkdir_p "#{TGT_DIR}/samples"
+ ['simple', 'good', 'expert'].each do |d|
+ mkdir_p "#{TGT_DIR}/samples/#{d}"
+ Dir.chdir "#{TGT_DIR}/samples/#{d}" do
+ Dir["../../../samples/#{d}/*"].each do |f|
+ ln_s f, '.' unless File.symlink? File.basename(f)
+ end
+ end
+ end
+ Dir.chdir "#{TGT_DIR}" do
+ ln_s "../static", "." unless File.symlink? 'static'
+ end
+ cp "README.md", "#{TGT_DIR}/README.txt"
+ cp "CHANGELOG", "#{TGT_DIR}/CHANGELOG.txt"
+ cp "COPYING", "#{TGT_DIR}/COPYING.txt"
+=end
+ ln_s "#{srcloc}/lib", TGT_DIR
+ ln_s "#{srcloc}/samples", TGT_DIR
+ ln_s "#{srcloc}/static", TGT_DIR
+ ln_s "#{srcloc}/fonts", TGT_DIR
+ cp "README.md", TGT_DIR
+ cp "CHANGELOG", TGT_DIR
+ cp "COPYING", TGT_DIR
+ end
+end
diff --git a/make/linux/loose/tasks.rb b/make/linux/minlin/tasks.rb
similarity index 59%
rename from make/linux/loose/tasks.rb
rename to make/linux/minlin/tasks.rb
index f1b8bb76..b8524458 100644
--- a/make/linux/loose/tasks.rb
+++ b/make/linux/minlin/tasks.rb
@@ -1,11 +1,6 @@
module Make
include FileUtils
- def copy_files_to_dist
- #cp "lib/shoes.rb", "dist/lib"
- #cp_r "lib/shoes", "dist/lib"
- end
-
def cc(t)
sh "#{CC} -I. -c -o#{t.name} #{LINUX_CFLAGS} #{t.source}"
end
@@ -30,61 +25,9 @@ def rewrite before, after, reg = /\#\{(\w+)\}/, reg2 = '\1'
def copy_files glob, dir
FileList[glob].each { |f| cp_r f, dir }
end
-
- # Set up symlinks to lib/shoes and lib/shoes.rb so that they
- # can be edited and tested without a rake clean/build every time we
- # change a lib/shoes/*.rb
- # They'll be copied (not linked) when rake install occurs. Be very
- # careful. Only Link to FILES, not to directories. Fileutils.ln_s may
- # not be the same as linux ln -s.
- def pre_build
- puts "Prebuild: #{pwd}"
- mkdir_p "dist/lib/shoes"
- Dir.chdir "dist/lib/shoes" do
- Dir["../../../lib/shoes/*.rb"].each do |f|
- #puts "SymLinking #{f}"
- ln_s f, "." unless File.symlink? File.basename(f)
- end
- end
- Dir.chdir "dist/lib" do
- ln_s "../../lib/shoes.rb" , "shoes.rb" unless File.symlink? "shoes.rb"
- # link to exerb
- ln_s "../../lib/exerb", "exerb" unless File.symlink? "exerb"
- end
- cp_r "fonts", "dist/fonts"
- cp_r "samples", "dist/samples"
- Dir.chdir "dist" do
- ln_s "../static", "." unless File.symlink? 'static'
- end
- #cp_r "static", "dist/static"
- cp "README.md", "dist/README.txt"
- cp "CHANGELOG", "dist/CHANGELOG.txt"
- cp "COPYING", "dist/COPYING.txt"
- end
-
- # Build the extensions, gems and copy to Shoes directories
- def common_build
- puts "common_build dir=#{pwd} #{SHOES_RUBY_ARCH}"
- mkdir_p "#{TGT_DIR}/lib/ruby/#{RUBY_V}/#{SHOES_RUBY_ARCH}"
- #cp_r "#{EXT_RUBY}/lib/ruby/#{RUBY_V}", "#{TGT_DIR}/ruby/lib"
- %w[req/rake/lib/*].each do |rdir|
- FileList[rdir].each { |rlib| cp_r rlib, "#{TGT_DIR}/lib/ruby/#{RUBY_V}" }
- end
- #%w[req/binject/ext/binject_c req/bloopsaphone/ext/bloops req/chipmunk/ext/chipmunk].
- %w[req/chipmunk/ext/chipmunk].
- each { |xdir| copy_ext xdir, "#{TGT_DIR}/lib/ruby/#{RUBY_V}/#{SHOES_RUBY_ARCH}" }
-
- gdir = "#{TGT_DIR}/lib/ruby/gems/#{RUBY_V}"
- # Loose shoes doesn't build gems
- {}.each do |gemn, xdir|
- spec = eval(File.read("req/#{gemn}/gemspec"))
- mkdir_p "#{gdir}/specifications"
- mkdir_p "#{gdir}/gems/#{spec.full_name}/lib"
- FileList["req/#{gemn}/lib/*"].each { |rlib| cp_r rlib, "#{gdir}/gems/#{spec.full_name}/lib" }
- mkdir_p "#{gdir}/gems/#{spec.full_name}/#{xdir}"
- FileList["req/#{gemn}/ext/*"].each { |elib| copy_ext elib, "#{gdir}/gems/#{spec.full_name}/#{xdir}" }
- cp "req/#{gemn}/gemspec", "#{gdir}/specifications/#{spec.full_name}.gemspec"
- end
+
+ # a stub, loose linux doesn't copy gems but the Builder will call it
+ def copy_gems
end
end
@@ -96,37 +39,44 @@ class MakeLinux
extend Make
class << self
- def copy_ext xdir, libdir
- Dir.chdir(xdir) do
- unless system "ruby", "extconf.rb" and system "make"
- raise "Extension build failed"
- end
- end
- copy_files "#{xdir}/*.so", libdir
- end
-
- # does nothing
- def copy_deps_to_dist
- end
def setup_system_resources
- cp APP['icons']['gtk'], "dist/static/app-icon.png"
+ cp APP['icons']['gtk'], "#{TGT_DIR}/static/app-icon.png"
end
-
- def make_app(name)
- # name is dist/shoes
- rm_f name
- sh "#{CC} -o #{name} bin/main.o dist/shoes.a #{LINUX_LDFLAGS} #{LINUX_LIBS}"
- # remove the static lib
- sh "rm -f #{TGT_DIR}/shoes.a"
- end
-
- # make a static library
- def make_so(name)
- puts "make_so: #{name}"
- name = 'dist/shoes.a'
- sh "ar rc #{name} #{OBJ.join(' ')}"
- sh "ranlib #{name}"
+
+ # this is called from the file task based new_builder
+ def new_so (name)
+=begin
+ tgts = name.split('/')
+ tgtd = tgts[0]
+ $stderr.puts "new_so: #{tgtd}"
+=end
+ tgts = File.expand_path(name)
+ tgtd = File.dirname(name)
+ $stderr.puts "new_so: #{tgtd} from #{tgts}"
+ objs = []
+ SubDirs.each do |f|
+ d = File.dirname(f)
+ objs = objs + FileList["#{d}/*.o"]
+ end
+ objs = objs + FileList["shoes/native/gtk/*.o"]
+ main_o = 'shoes/main.o'
+ objs = objs - [main_o]
+ sh "ar -rc #{tgtd}/shoes.lib #{objs.join(' ')}"
+ sh "ranlib #{tgtd}/shoes.lib"
+ end
+
+ def new_link name
+=begin
+ tgts = name.split('/')
+ tgtd = tgts[0]
+ $stderr.puts "new_link: #{tgtd}"
+ sh "#{CC} -o #{tgts[0]}/shoes #{TGT_DIR}/#{APP['Bld_Tmp']}/main.o #{tgtd}/shoes.lib #{LINUX_LDFLAGS} #{LINUX_LIBS}"
+=end
+ tgts = File.expand_path(name)
+ tgtd = File.dirname(name)
+ $stderr.puts "new_link: #{tgtd} from #{name}"
+ sh "#{CC} -o #{TGT_DIR}/shoes #{TGT_DIR}/#{APP['Bld_Tmp']}/main.o #{TGT_DIR}/shoes.lib #{LINUX_LDFLAGS} #{LINUX_LIBS}"
end
def make_installer
@@ -151,6 +101,7 @@ def make_userinstall
rm_r hdir
end
mkdir_p hdir
+=begin
cp_r "fonts", "#{hdir}/fonts"
cp_r "samples", "#{hdir}/samples"
cp_r "static", "#{hdir}/static"
@@ -166,6 +117,22 @@ def make_userinstall
sh "cp -r lib/shoes #{hdir}/lib"
sh "cp -r lib/shoes.rb #{hdir}/lib/"
sh "cp -r lib/exerb #{hdir}/lib"
+=end
+ cp_r "#{TGT_DIR}/fonts", "#{hdir}/fonts"
+ cp_r "#{TGT_DIR}/samples", "#{hdir}/samples"
+ cp_r "#{TGT_DIR}/static", "#{hdir}/static"
+ cp "#{TGT_DIR}/README.md", "#{hdir}/README.txt"
+ cp "#{TGT_DIR}/CHANGELOG", "#{hdir}/CHANGELOG.txt"
+ cp "#{TGT_DIR}/COPYING", "#{hdir}/COPYING.txt"
+ cp "#{TGT_DIR}/VERSION.txt", "#{hdir}"
+ cp "#{TGT_DIR}/shoes" , "#{hdir}"
+ cp "#{TGT_DIR}/shoes.lib",hdir
+ mkdir_p "#{hdir}/lib"
+ #sh "cp -r #{TGT_DIR}/lib/ruby #{hdir}/lib"
+ # bit of a hack here. Don't copy symlinks in dist/lib
+ sh "cp -r #{TGT_DIR}/lib/shoes #{hdir}/lib"
+ sh "cp -r #{TGT_DIR}/lib/shoes.rb #{hdir}/lib/"
+ sh "cp -r #{TGT_DIR}/lib/exerb #{hdir}/lib"
Dir.chdir hdir do
make_desktop
make_uninstall_script
diff --git a/make/linux/none/env.rb b/make/linux/none/env.rb
new file mode 100644
index 00000000..22212dbb
--- /dev/null
+++ b/make/linux/none/env.rb
@@ -0,0 +1,4 @@
+# just enough allow a rake -T
+CC = "gcc"
+DLEXT = "so"
+LINUX_CFLAGS = []
diff --git a/make/linux/none/tasks.rb b/make/linux/none/tasks.rb
new file mode 100644
index 00000000..5e80ab37
--- /dev/null
+++ b/make/linux/none/tasks.rb
@@ -0,0 +1,28 @@
+module Make
+ include FileUtils
+
+ def cc(t)
+ #sh "#{CC} -I. -c -o#{t.name} #{WINDOWS_CFLAGS} #{t.source}"
+ end
+
+ # Subs in special variables
+ def rewrite before, after, reg = /\#\{(\w+)\}/, reg2 = '\1'
+ File.open(after, 'w') do |a|
+ File.open(before) do |b|
+ b.each do |line|
+ a << line.gsub(reg) do
+ if reg2.include? '\1'
+ reg2.gsub(%r!\\1!, Object.const_get($1))
+ else
+ reg2
+ end
+ end
+ end
+ end
+ end
+ end
+
+end
+class MakeLinux
+ extend Make
+end
diff --git a/make/linux/pi2/env.rb b/make/linux/pi2/env.rb
index 35c14d29..1003c31d 100644
--- a/make/linux/pi2/env.rb
+++ b/make/linux/pi2/env.rb
@@ -4,43 +4,30 @@
custmz = YAML.load_file(cf)
ShoesDeps = custmz['Deps']
EXT_RUBY = custmz['Ruby']
- ENV['GDB'] = 'basic' if custmz['Debug'] == true
+ APP['GDB'] = 'basic' if custmz['Debug'] == true
APP['GEMLOC'] = custmz['Gemloc'] if custmz['Gemloc']
APP['EXTLOC'] = custmz['Extloc'] if custmz['Extloc']
APP['EXTLIST'] = custmz['Exts'] if custmz['Exts']
APP['GEMLIST'] = custmz['Gems'] if custmz['Gems']
APP['INCLGEMS'] = custmz['InclGems'] if custmz['InclGems']
- #APP['GTK'] = custmz['Gtk'] if custmz['Gtk']
else
abort "missing custom.yaml"
end
-#ENV['DEBUG'] = "true" # turns on the tracing log
-#ENV['GDB'] = "" # compile -g, strip symbols when not defined
+
APP['GTK'] = 'gtk+-3.0' # installer needs this to name the output
-CHROOT = ShoesDeps
SHOES_TGT_ARCH = 'armv7l-linux-eabihf'
SHOES_GEM_ARCH = "#{Gem::Platform.local}"
-# Specify where the Target system binaries live.
-# Trailing slash is important.
-TGT_SYS_DIR = "#{CHROOT}/"
# Setup some shortcuts for the library locations
arch = 'arm-linux-gnueabihf'
-uldir = "#{TGT_SYS_DIR}usr/lib"
-ularch = "#{TGT_SYS_DIR}usr/lib/#{arch}"
-larch = "#{TGT_SYS_DIR}lib/#{arch}"
+uldir = "#{ShoesDeps}/usr/lib"
+ularch = "#{ShoesDeps}/usr/lib/#{arch}"
+larch = "#{ShoesDeps}/lib/#{arch}"
# Set appropriately
CC = "gcc"
-pkgruby ="#{EXT_RUBY}/lib/pkgconfig/ruby-2.2.pc"
+pkgruby ="#{EXT_RUBY}/lib/pkgconfig/ruby-2.3.pc"
pkggtk ="#{ularch}/pkgconfig/gtk+-3.0.pc"
# Use Ruby or curl for downloads
RUBY_HTTP = true
-file_list = ["shoes/console/*.c"] + ["shoes/native/*.c"] + ["shoes/http/rbload.c"] + ["shoes/*.c"] +
- ["shoes/plot/*.c"]
-file_list << "shoes/video/video.c"
-SRC = FileList[*file_list]
-OBJ = SRC.map do |x|
- x.gsub(/\.\w+$/, '.o')
-end
ADD_DLL = []
@@ -52,17 +39,17 @@
png_lib = 'png'
-if ENV['DEBUG'] || ENV['GDB']
+if APP['GDB']
LINUX_CFLAGS = " -g -O0"
else
LINUX_CFLAGS = " -O -Wall"
end
-LINUX_CFLAGS << " -DRUBY_HTTP"
+LINUX_CFLAGS << " -DRUBY_HTTP -DGNOTE"
LINUX_CFLAGS << " -DSHOES_GTK -fPIC -Wno-unused-but-set-variable -Wno-unused-variable"
-LINUX_CFLAGS << " -I#{TGT_SYS_DIR}usr/include "
+LINUX_CFLAGS << " -I#{ShoesDeps}/usr/include "
LINUX_CFLAGS << `pkg-config --cflags "#{pkgruby}"`.strip+" "
LINUX_CFLAGS << `pkg-config --cflags "#{pkggtk}"`.strip+" "
-LINUX_CFLAGS << " -I#{TGT_SYS_DIR}usr/include/ "
+LINUX_CFLAGS << " -I#{ShoesDeps}/usr/include/ "
LINUX_CFLAGS << "-I/usr/include/librsvg-2.0/librsvg "
MISC_LIB = " #{ularch}/librsvg-2.so"
@@ -85,13 +72,18 @@
LINUX_LIBS << " #{CURL_LDFLAGS if !RUBY_HTTP} #{RUBY_LDFLAGS} #{CAIRO_LIB} #{PANGO_LIB} #{MISC_LIB}"
SOLOCS = {}
-SOLOCS['ungif'] = "#{uldir}/libungif.so.4" if !justgif
-SOLOCS['gif'] = "#{ularch}/libgif.so.4" if justgif
-SOLOCS['jpeg'] = "#{ularch}/libjpeg.so.8"
-SOLOCS['libyaml'] = "#{ularch}/libyaml-0.so.2"
-SOLOCS['pcre'] = "#{larch}/libpcre.so.3"
+SOLOCS['ungif'] = "#{uldir}/libgif.so.4.1.6" if !justgif
+SOLOCS['gif'] = "#{ularch}/libgif.so.4.1.6" if justgif
+SOLOCS['jpeg'] = "#{ularch}/libjpeg.so.8.4.0"
+SOLOCS['libyaml'] = "#{ularch}/libyaml-0.so.2.0.4"
+SOLOCS['pcre'] = "#{larch}/libpcre.so.3.13.1" # needed?
SOLOCS['crypto'] = "#{ularch}/libcrypto.so.1.0.0"
SOLOCS['ssl'] = "#{ularch}/libssl.so.1.0.0"
SOLOCS['sqlite'] = "#{ularch}/libsqlite3.so.0.8.6"
-SOLOCS['ffi'] = "#{ularch}/libffi.so"
-SOLOCS['rsvg2'] = "#{ularch}/librsvg-2.so"
+SOLOCS['ffi'] = "#{ularch}/libffi.so.5.0.10"
+SOLOCS['rsvg2'] = "#{ularch}/librsvg-2.so.2.40.5"
+SOLOCS['curl'] = "#{EXT_RUBY}/lib/libcurl.so.4.4.0"
+
+# sigh, curl and tyhpoeus - processed in setup.rb
+SYMLNK = {}
+SYMLNK['libcurl.so.4.4.0'] = ['libcurl.so', 'libcurl.so.4']
diff --git a/make/linux/pi2/setup.rb b/make/linux/pi2/setup.rb
new file mode 100644
index 00000000..b7ac17a8
--- /dev/null
+++ b/make/linux/pi2/setup.rb
@@ -0,0 +1,49 @@
+# This is a big gulp of copying.
+require 'fileutils'
+module Make
+ include FileUtils
+
+
+ def static_setup (so_list)
+ $stderr.puts "setup: dir=#{`pwd`}"
+ rbvt = RUBY_V
+ rbvm = RUBY_V[/^\d+\.\d+/]
+ mkdir_p "#{TGT_DIR}/lib"
+ mkdir_p "#{TGT_DIR}/fonts"
+ cp_r "fonts", "#{TGT_DIR}/fonts"
+ mkdir_p "#{TGT_DIR}/lib"
+ cp "lib/shoes.rb", "#{TGT_DIR}/lib"
+ cp_r "lib/shoes", "#{TGT_DIR}/lib"
+ cp_r "lib/exerb", "#{TGT_DIR}/lib"
+ cp_r "samples", "#{TGT_DIR}/samples"
+ cp_r "static", "#{TGT_DIR}/static"
+ cp "README.md", "#{TGT_DIR}/README.txt"
+ cp "CHANGELOG", "#{TGT_DIR}/CHANGELOG.txt"
+ cp "COPYING", "#{TGT_DIR}/COPYING.txt"
+ # clean out leftovers from last build
+ #rm_f "#{TGT_DIR}/libruby.so" if File.exist? "#{TGT_DIR}/libruby.so"
+ #rm_f "#{TGT_DIR}/libruby.so.#{rbvm}" if File.exist? "#{TGT_DIR}/libruby.so.#{rbvm}"
+ #rm_f "#{TGT_DIR}/libruby.so.#{rbvt}" if File.exist? "#{TGT_DIR}/libruby.so.#{rbvt}"
+ cp_r "#{EXT_RUBY}/lib/ruby", "#{TGT_DIR}/lib", remove_destination: true
+ # copy and link libruby.so
+ cp "#{EXT_RUBY}/lib/libruby.so.#{rbvm}", "#{TGT_DIR}"
+
+ # copy include files - it might help build gems
+ mkdir_p "#{TGT_DIR}/lib/ruby/include/ruby-#{rbvt}"
+ cp_r "#{EXT_RUBY}/include/ruby-#{rbvt}/", "#{TGT_DIR}/lib/ruby/include"
+ chdir TGT_DIR do
+ ln_s "libruby.so.#{rbvm}", "libruby.so"
+ end
+ SOLOCS.each_value do |path|
+ cp "#{path}", "#{TGT_DIR}"
+ end
+ chdir TGT_DIR do
+ SYMLNK.each do |k, v|
+ v.each do |syml|
+ ln_s k, syml
+ end
+ end
+ end
+ end
+end
+
diff --git a/make/linux/pi2/tasks.rb b/make/linux/pi2/tasks.rb
index 07af845c..5c6d4290 100644
--- a/make/linux/pi2/tasks.rb
+++ b/make/linux/pi2/tasks.rb
@@ -1,32 +1,6 @@
module Make
include FileUtils
- def copy_files_to_dist
- puts "copy_files_to_dist dir=#{pwd}"
- if ENV['APP']
- if APP['clone']
- sh APP['clone'].gsub(/^git /, "#{GIT} --git-dir=#{ENV['APP']}/.git ")
- else
- cp_r ENV['APP'], "#{TGT_DIR}/app"
- end
- if APP['ignore']
- APP['ignore'].each do |nn|
- rm_rf "dist/app/#{nn}"
- end
- end
- end
-
- cp_r "fonts", "#{TGT_DIR}/fonts"
- cp "lib/shoes.rb", "#{TGT_DIR}/lib"
- cp_r "lib/shoes", "#{TGT_DIR}/lib"
- cp_r "lib/exerb", "#{TGT_DIR}/lib"
- cp_r "samples", "#{TGT_DIR}/samples"
- cp_r "static", "#{TGT_DIR}/static"
- cp "README.md", "#{TGT_DIR}/README.txt"
- cp "CHANGELOG", "#{TGT_DIR}/CHANGELOG.txt"
- cp "COPYING", "#{TGT_DIR}/COPYING.txt"
- end
-
def cc(t)
sh "#{CC} -I. -c -o#{t.name} #{LINUX_CFLAGS} #{t.source}"
end
@@ -47,42 +21,6 @@ def rewrite before, after, reg = /\#\{(\w+)\}/, reg2 = '\1'
end
end
end
-
- def copy_files glob, dir
- FileList[glob].each { |f| cp_r f, dir }
- end
-
- # copy everything from the cross compiled Ruby libs as ruby wants it
- # copy any deps libraries that might ever be used in linking or when
- # building a static ar.
- def pre_build
- puts "pre_build dir=#{`pwd`}"
- rbvt = RUBY_V
- rbvm = RUBY_V[/^\d+\.\d+/]
- mkdir_p "#{TGT_DIR}/lib"
- # clean out leftovers from last build
- rm_f "#{TGT_DIR}/libruby.so" if File.exist? "#{TGT_DIR}/libruby.so"
- rm_f "#{TGT_DIR}/libruby.so.#{rbvm}" if File.exist? "#{TGT_DIR}/libruby.so.#{rbvm}"
- rm_f "#{TGT_DIR}/libruby.so.#{rbvt}" if File.exist? "#{TGT_DIR}/libruby.so.#{rbvt}"
- cp_r "#{EXT_RUBY}/lib/ruby", "#{TGT_DIR}/lib"
- # copy and link libruby.so
- cp "#{EXT_RUBY}/lib/libruby.so.#{rbvm}", "#{TGT_DIR}"
- # copy include files - it might help build gems
- mkdir_p "#{TGT_DIR}/lib/ruby/include/ruby-#{rbvt}"
- cp_r "#{EXT_RUBY}/include/ruby-#{rbvt}/", "#{TGT_DIR}/lib/ruby/include"
- chdir TGT_DIR do
- ln_s "libruby.so.#{rbvm}", "libruby.so"
- end
- SOLOCS.each_value do |path|
- cp "#{path}", "#{TGT_DIR}"
- end
- end
-
- # common_build is a misnomer. Build extentions, gems
- def common_build
- copy_gems
- end
-
end
@@ -92,26 +30,34 @@ class MakeLinux
extend Make
class << self
-
- def copy_deps_to_dist
- puts "copy_deps_to_dist dir=#{pwd}"
- unless ENV['GDB']
- sh "strip -x #{TGT_DIR}/*.so.*"
- sh "strip -x #{TGT_DIR}/*.so"
- end
- end
-
def setup_system_resources
cp APP['icons']['gtk'], "#{TGT_DIR}/static/app-icon.png"
end
-
- # name {TGT_DIR}/shoes
- def make_app(name)
- puts "make_app dir=#{pwd} arg=#{name}"
- bin = "#{name}-bin"
- rm_f name
- rm_f bin
- sh "#{CC} -o #{bin} bin/main.o -L#{TGT_DIR} -lshoes #{LINUX_LIBS}"
+
+ def new_so (name)
+ $stderr.puts "new_so: #{name}"
+ tgtd = File.dirname(name)
+ objs = []
+ SubDirs.each do |f|
+ d = File.dirname(f)
+ objs = objs + FileList["#{d}/*.o"]
+ end
+ objs = objs + FileList["shoes/native/gtk/*.o"]
+ main_o = 'shoes/main.o'
+ objs = objs - [main_o]
+ sh "#{CC} -o #{tgtd}/libshoes.#{DLEXT} #{objs.join(' ')} #{LINUX_LDFLAGS} #{LINUX_LIBS}"
+ end
+
+ def new_link(name)
+ #name is actually a file path
+ $stderr.puts "new_link: arg=#{name}"
+ dpath = File.dirname(name)
+ fname = File.basename(name)
+ bin = "#{fname}-bin"
+ #rm_f fname
+ #rm_f bin
+ #sh "#{CC} -o #{name} #{dpath}/tmp/main.o -L#{tgtd} -lshoes -L#{TGT_DIR} #{LINUX_LIBS}"
+ sh "#{CC} -o #{dpath}/#{bin} #{dpath}/tmp/main.o -L#{dpath} -lshoes -L#{TGT_DIR} #{LINUX_LIBS}"
rewrite "platform/nix/shoes.launch", name, %r!/shoes-bin!, "/#{NAME}-bin"
sh %{echo 'cd "$OLDPWD"\nLD_LIBRARY_PATH=$APPPATH $APPPATH/#{File.basename(bin)} "$@"' >> #{name}}
chmod 0755, "#{name}"
@@ -121,33 +67,39 @@ def make_app(name)
chmod 0755, "#{TGT_DIR}/debug"
end
- def make_so(name)
- puts "make_so dir=#{pwd} arg=#{name}"
- #ldflags = LINUX_LDFLAGS.sub! /INSTALL_NAME/, "-install_name @executable_path/lib#{SONAME}.#{DLEXT}"
- sh "#{CC} -o #{name} #{OBJ.join(' ')} #{LINUX_LDFLAGS} #{LINUX_LIBS}"
- end
-
# make a .install with all the bits and peices.
def make_installer
- gtkv = APP['GTK']== 'gtk+-3.0' ? '3' : '2'
+ gtkv = '3'
arch = 'armhf'
appname = "#{APP['name'].downcase}"
rlname = "#{appname}-#{APP['VERSION']}-gtk#{gtkv}-#{arch}"
#puts "Creating Pkg for #{rlname}"
- rm_r "pkg/#{rlname}" if File.exists? "pkg/#{rlname}"
+ pkg = ""
+ if APP['Bld_Pre']
+ pkg = "#{APP['Bld_Pre']}pkg"
+ mkdir_p pkg
+ else
+ pkg = 'pkg'
+ end
+ rm_r "#{pkg}/#{rlname}" if File.exists? "#{pkg}/#{rlname}"
cp_r "VERSION.txt", "#{TGT_DIR}"
- mkdir_p "pkg/#{rlname}"
- sh "cp -r #{TGT_DIR}/* pkg/#{rlname}"
- Dir.chdir "pkg/#{rlname}" do
+ mkdir_p "#{pkg}/#{rlname}"
+ sh "cp -r #{TGT_DIR}/* #{pkg}/#{rlname}"
+ Dir.chdir "#{pkg}/#{rlname}" do
+ rm_r "#{APP['Bld_Tmp']}"
+ rm_r "pkg" if File.exist? "pkg"
make_desktop
make_uninstall_script
make_install_script
- make_smaller unless ENV['GDB']
+ make_smaller unless APP['GDB']
end
- Dir.chdir "pkg" do
+ Dir.chdir "#{pkg}" do
puts `pwd`
- sh "makeself #{rlname} #{rlname}.install #{appname} \
-./shoes-install.sh "
+ sh "makeself #{rlname} #{rlname}.install #{appname} ./shoes-install.sh "
+ end
+ if APP['Bld_Pre']
+ # copy installer to the shoes3 source pkg/ dir (on an nfs server?)
+ cp "#{pkg}/#{rlname}.install", "pkg"
end
end
diff --git a/make/linux/x86_64-linux/env.rb b/make/linux/x86_64-linux/env.rb
index 2314b4de..b308cfae 100644
--- a/make/linux/x86_64-linux/env.rb
+++ b/make/linux/x86_64-linux/env.rb
@@ -6,43 +6,31 @@
custmz = YAML.load_file(cf)
ShoesDeps = custmz['Deps']
EXT_RUBY = custmz['Ruby']
- ENV['GDB'] = 'basic' if custmz['Debug'] == true
+ APP['GDB'] = 'basic' if custmz['Debug'] == true
APP['GEMLOC'] = custmz['Gemloc'] if custmz['Gemloc']
APP['EXTLOC'] = custmz['Extloc'] if custmz['Extloc']
APP['EXTLIST'] = custmz['Exts'] if custmz['Exts']
APP['GEMLIST'] = custmz['Gems'] if custmz['Gems']
APP['INCLGEMS'] = custmz['InclGems'] if custmz['InclGems']
- #APP['GTK'] = custmz['Gtk'] if custmz['Gtk']
else
abort "missing custom.yaml"
end
-#ENV['DEBUG'] = "true" # turns on the tracing log
-#ENV['GDB'] = "" # compile -g, strip symbols when not defined
+
APP['GTK'] = 'gtk+-3.0' # installer needs this to name the output
-CHROOT = ShoesDeps
SHOES_TGT_ARCH = 'x86_64-linux'
SHOES_GEM_ARCH = "#{Gem::Platform.local}"
-# Specify where the Target system binaries live.
-# Trailing slash is important.
-TGT_SYS_DIR = "#{CHROOT}/"
# Setup some shortcuts for the library locations
arch = 'x86_64-linux-gnu'
-uldir = "#{TGT_SYS_DIR}usr/lib"
-ularch = "#{TGT_SYS_DIR}usr/lib/#{arch}"
-larch = "#{TGT_SYS_DIR}lib/#{arch}"
+uldir = "#{ShoesDeps}/usr/lib"
+ularch = "#{ShoesDeps}/usr/lib/#{arch}"
+larch = "#{ShoesDeps}/lib/#{arch}"
+lcllib = "/usr/local/lib"
# Set appropriately
CC = "gcc"
-pkgruby ="#{EXT_RUBY}/lib/pkgconfig/ruby-2.2.pc"
+pkgruby ="#{EXT_RUBY}/lib/pkgconfig/ruby-2.3.pc"
pkggtk ="#{ularch}/pkgconfig/gtk+-3.0.pc"
# Use Ruby or curl for downloads
RUBY_HTTP = true
-file_list = ["shoes/console/*.c"] + ["shoes/native/*.c"] + ["shoes/http/rbload.c"] + ["shoes/*.c"] +
- ["shoes/plot/*.c"]
-file_list << "shoes/video/video.c"
-SRC = FileList[*file_list]
-OBJ = SRC.map do |x|
- x.gsub(/\.\w+$/, '.o')
-end
ADD_DLL = []
@@ -54,21 +42,20 @@
png_lib = 'png'
-if ENV['DEBUG'] || ENV['GDB']
+if APP['GDB']
LINUX_CFLAGS = " -g -O0"
else
LINUX_CFLAGS = " -O -Wall"
end
LINUX_CFLAGS << " -DRUBY_HTTP"
LINUX_CFLAGS << " -DSHOES_GTK -fPIC -Wno-unused-but-set-variable -Wno-unused-variable"
-LINUX_CFLAGS << " -I#{TGT_SYS_DIR}usr/include "
+LINUX_CFLAGS << " -I#{ShoesDeps}/usr/include "
LINUX_CFLAGS << `pkg-config --cflags "#{pkgruby}"`.strip+" "
LINUX_CFLAGS << `pkg-config --cflags "#{pkggtk}"`.strip+" "
-LINUX_CFLAGS << " -I#{TGT_SYS_DIR}usr/include/ "
+LINUX_CFLAGS << " -I#{ShoesDeps}/usr/include/ "
LINUX_CFLAGS << "-I/usr/include/librsvg-2.0/librsvg "
MISC_LIB = ' /usr/lib/x86_64-linux-gnu/librsvg-2.so'
-
LINUX_LIB_NAMES = %W[ungif jpeg]
DLEXT = "so"
@@ -84,13 +71,19 @@
LINUX_LIBS << " #{CURL_LDFLAGS if !RUBY_HTTP} #{RUBY_LDFLAGS} #{CAIRO_LIB} #{PANGO_LIB} #{MISC_LIB}"
SOLOCS = {}
-SOLOCS['ungif'] = "#{uldir}/libungif.so.4"
-SOLOCS['gif'] = "#{uldir}/libgif.so.4" # because Suse wants it
-SOLOCS['jpeg'] = "#{ularch}/libjpeg.so.8"
-SOLOCS['libyaml'] = "#{ularch}/libyaml-0.so.2"
+SOLOCS['ungif'] = "#{uldir}/libungif.so.4.1.6"
+SOLOCS['gif'] = "#{uldir}/libgif.so.4.1.6" # because Suse wants it
+SOLOCS['jpeg'] = "#{ularch}/libjpeg.so.8.4.0"
+SOLOCS['libyaml'] = "#{ularch}/libyaml-0.so.2.0.2"
SOLOCS['pcre'] = "#{larch}/libpcre.so.3"
SOLOCS['crypto'] = "#{ularch}/libcrypto.so.1.0.0"
SOLOCS['ssl'] = "#{ularch}/libssl.so.1.0.0"
SOLOCS['sqlite'] = "#{ularch}/libsqlite3.so.0.8.6"
-SOLOCS['ffi'] = "#{ularch}/libffi.so.5"
-SOLOCS['rsvg2'] = "#{ularch}/librsvg-2.so"
+SOLOCS['ffi'] = "#{ularch}/libffi.so.5.0.10"
+SOLOCS['rsvg2'] = "#{ularch}/librsvg-2.so.2.36.1"
+SOLOCS['curl'] = "#{lcllib}/libcurl.so.4.4.0"
+
+# sigh, curl and tyhpoeus - processed in setup.rb
+SYMLNK = {}
+SYMLNK['libcurl.so.4.4.0'] = ['libcurl.so', 'libcurl.so.4']
+
diff --git a/make/linux/x86_64-linux/setup.rb b/make/linux/x86_64-linux/setup.rb
new file mode 100644
index 00000000..0c5a86f1
--- /dev/null
+++ b/make/linux/x86_64-linux/setup.rb
@@ -0,0 +1,47 @@
+# This is a big gulp of copying.
+require 'fileutils'
+module Make
+ include FileUtils
+
+ def static_setup (so_list)
+ $stderr.puts "setup: dir=#{`pwd`}"
+ rbvt = RUBY_V
+ rbvm = RUBY_V[/^\d+\.\d+/]
+ mkdir_p "#{TGT_DIR}/lib"
+ mkdir_p "#{TGT_DIR}/fonts"
+ cp_r "fonts", "#{TGT_DIR}/fonts"
+ mkdir_p "#{TGT_DIR}/lib"
+ cp "lib/shoes.rb", "#{TGT_DIR}/lib"
+ cp_r "lib/shoes", "#{TGT_DIR}/lib"
+ cp_r "lib/exerb", "#{TGT_DIR}/lib"
+ cp_r "samples", "#{TGT_DIR}/samples"
+ cp_r "static", "#{TGT_DIR}/static"
+ cp "README.md", "#{TGT_DIR}/README.txt"
+ cp "CHANGELOG", "#{TGT_DIR}/CHANGELOG.txt"
+ cp "COPYING", "#{TGT_DIR}/COPYING.txt"
+ # clean out leftovers from last build
+ rm_f "#{TGT_DIR}/libruby.so" if File.exist? "#{TGT_DIR}/libruby.so"
+ rm_f "#{TGT_DIR}/libruby.so.#{rbvm}" if File.exist? "#{TGT_DIR}/libruby.so.#{rbvm}"
+ rm_f "#{TGT_DIR}/libruby.so.#{rbvt}" if File.exist? "#{TGT_DIR}/libruby.so.#{rbvt}"
+ cp_r "#{EXT_RUBY}/lib/ruby", "#{TGT_DIR}/lib", remove_destination: true
+ # copy and link libruby.so
+ cp "#{EXT_RUBY}/lib/libruby.so.#{rbvm}", "#{TGT_DIR}"
+ # copy include files - it might help build gems
+ mkdir_p "#{TGT_DIR}/lib/ruby/include/ruby-#{rbvt}"
+ cp_r "#{EXT_RUBY}/include/ruby-#{rbvt}/", "#{TGT_DIR}/lib/ruby/include"
+ chdir TGT_DIR do
+ ln_s "libruby.so.#{rbvm}", "libruby.so"
+ end
+ SOLOCS.each_value do |path|
+ cp "#{path}", "#{TGT_DIR}"
+ end
+ chdir TGT_DIR do
+ SYMLNK.each do |k, v|
+ v.each do |syml|
+ ln_s k, syml
+ end
+ end
+ end
+ end
+end
+
diff --git a/make/linux/x86_64-linux/tasks.rb b/make/linux/x86_64-linux/tasks.rb
index 7f6941be..57826a06 100644
--- a/make/linux/x86_64-linux/tasks.rb
+++ b/make/linux/x86_64-linux/tasks.rb
@@ -1,32 +1,6 @@
module Make
include FileUtils
- def copy_files_to_dist
- puts "copy_files_to_dist dir=#{pwd}"
- if ENV['APP']
- if APP['clone']
- sh APP['clone'].gsub(/^git /, "#{GIT} --git-dir=#{ENV['APP']}/.git ")
- else
- cp_r ENV['APP'], "#{TGT_DIR}/app"
- end
- if APP['ignore']
- APP['ignore'].each do |nn|
- rm_rf "dist/app/#{nn}"
- end
- end
- end
-
- cp_r "fonts", "#{TGT_DIR}/fonts"
- cp "lib/shoes.rb", "#{TGT_DIR}/lib"
- cp_r "lib/shoes", "#{TGT_DIR}/lib"
- cp_r "lib/exerb", "#{TGT_DIR}/lib"
- cp_r "samples", "#{TGT_DIR}/samples"
- cp_r "static", "#{TGT_DIR}/static"
- cp "README.md", "#{TGT_DIR}/README.txt"
- cp "CHANGELOG", "#{TGT_DIR}/CHANGELOG.txt"
- cp "COPYING", "#{TGT_DIR}/COPYING.txt"
- end
-
def cc(t)
sh "#{CC} -I. -c -o#{t.name} #{LINUX_CFLAGS} #{t.source}"
end
@@ -47,42 +21,6 @@ def rewrite before, after, reg = /\#\{(\w+)\}/, reg2 = '\1'
end
end
end
-
- def copy_files glob, dir
- FileList[glob].each { |f| cp_r f, dir }
- end
-
- # copy everything from the cross compiled Ruby libs as ruby wants it
- # copy any deps libraries that might ever be used in linking or when
- # building a static ar.
- def pre_build
- puts "pre_build dir=#{`pwd`}"
- rbvt = RUBY_V
- rbvm = RUBY_V[/^\d+\.\d+/]
- mkdir_p "#{TGT_DIR}/lib"
- # clean out leftovers from last build
- rm_f "#{TGT_DIR}/libruby.so" if File.exist? "#{TGT_DIR}/libruby.so"
- rm_f "#{TGT_DIR}/libruby.so.#{rbvm}" if File.exist? "#{TGT_DIR}/libruby.so.#{rbvm}"
- rm_f "#{TGT_DIR}/libruby.so.#{rbvt}" if File.exist? "#{TGT_DIR}/libruby.so.#{rbvt}"
- cp_r "#{EXT_RUBY}/lib/ruby", "#{TGT_DIR}/lib"
- # copy and link libruby.so
- cp "#{EXT_RUBY}/lib/libruby.so.#{rbvm}", "#{TGT_DIR}"
- # copy include files - it might help build gems
- mkdir_p "#{TGT_DIR}/lib/ruby/include/ruby-#{rbvt}"
- cp_r "#{EXT_RUBY}/include/ruby-#{rbvt}/", "#{TGT_DIR}/lib/ruby/include"
- chdir TGT_DIR do
- ln_s "libruby.so.#{rbvm}", "libruby.so"
- end
- SOLOCS.each_value do |path|
- cp "#{path}", "#{TGT_DIR}"
- end
- end
-
- # common_build is a misnomer. Build extentions, gems
- def common_build
- copy_gems
- end
-
end
@@ -92,62 +30,77 @@ class MakeLinux
extend Make
class << self
-
- def copy_deps_to_dist
- puts "copy_deps_to_dist dir=#{pwd}"
- unless ENV['GDB']
- sh "strip -x #{TGT_DIR}/*.so.*"
- sh "strip -x #{TGT_DIR}/*.so"
- end
- end
-
def setup_system_resources
cp APP['icons']['gtk'], "#{TGT_DIR}/static/app-icon.png"
end
-
- # name {TGT_DIR}/shoes
- def make_app(name)
- puts "make_app dir=#{pwd} arg=#{name}"
- bin = "#{name}-bin"
- rm_f name
- rm_f bin
- sh "#{CC} -o #{bin} bin/main.o -L#{TGT_DIR} -lshoes #{LINUX_LIBS}"
+
+
+ def new_so (name)
+ tgts = name.split('/')
+ tgtd = tgts[0]
+ $stderr.puts "new_so: #{tgtd}"
+ objs = []
+ SubDirs.each do |f|
+ d = File.dirname(f)
+ objs = objs + FileList["#{d}/*.o"]
+ end
+ # TODO fix: gtk - needs to dig deeper vs osx
+ objs = objs + FileList["shoes/native/gtk/*.o"]
+ main_o = 'shoes/main.o'
+ objs = objs - [main_o]
+ sh "#{CC} -o #{tgtd}/libshoes.#{DLEXT} #{objs.join(' ')} #{LINUX_LDFLAGS} #{LINUX_LIBS}"
+ end
+
+ def new_link(name)
+ #name is actually a file path
+ puts "new_link: arg=#{name}"
+ dpath = File.dirname(name)
+ fname = File.basename(name)
+ bin = "#{fname}-bin"
+ sh "#{CC} -o #{dpath}/#{bin} #{dpath}/tmp/main.o -L#{dpath} -lshoes -L#{TGT_DIR} #{LINUX_LIBS}"
rewrite "platform/nix/shoes.launch", name, %r!/shoes-bin!, "/#{NAME}-bin"
sh %{echo 'cd "$OLDPWD"\nLD_LIBRARY_PATH=$APPPATH $APPPATH/#{File.basename(bin)} "$@"' >> #{name}}
chmod 0755, "#{name}"
# write a gdb launched shoes
rewrite "platform/nix/shoes.launch", "#{TGT_DIR}/debug", %r!/shoes-bin!, "/#{NAME}-bin"
sh %{echo 'cd "$OLDPWD"\nLD_LIBRARY_PATH=$APPPATH gdb $APPPATH/#{File.basename(bin)} "$@"' >> #{TGT_DIR}/debug}
- chmod 0755, "#{TGT_DIR}/debug"
+ chmod 0755, "#{TGT_DIR}/debug"
end
- def make_so(name)
- puts "make_so dir=#{pwd} arg=#{name}"
- #ldflags = LINUX_LDFLAGS.sub! /INSTALL_NAME/, "-install_name @executable_path/lib#{SONAME}.#{DLEXT}"
- sh "#{CC} -o #{name} #{OBJ.join(' ')} #{LINUX_LDFLAGS} #{LINUX_LIBS}"
- end
- # make a .install with all the bits and peices.
+ # make a .install with all the bits and pieces.
def make_installer
- gtkv = APP['GTK']== 'gtk+-3.0' ? '3' : '2'
+ gtkv = '3'
arch = 'x86_64'
appname = "#{APP['name'].downcase}"
rlname = "#{appname}-#{APP['VERSION']}-gtk#{gtkv}-#{arch}"
#puts "Creating Pkg for #{rlname}"
- rm_r "pkg/#{rlname}" if File.exists? "pkg/#{rlname}"
+ pkg = ""
+ if APP['Bld_Pre']
+ pkg = "#{APP['Bld_Pre']}pkg"
+ mkdir_p pkg
+ else
+ pkg = 'pkg'
+ end
+ rm_r "#{pkg}/#{rlname}" if File.exists? "#{pkg}/#{rlname}"
cp_r "VERSION.txt", "#{TGT_DIR}"
- mkdir_p "pkg/#{rlname}"
- sh "cp -r #{TGT_DIR}/* pkg/#{rlname}"
- Dir.chdir "pkg/#{rlname}" do
+ mkdir_p "#{pkg}/#{rlname}"
+ sh "cp -r #{TGT_DIR}/* #{pkg}/#{rlname}"
+ Dir.chdir "#{pkg}/#{rlname}" do
+ rm_r "#{APP['Bld_Tmp']}"
+ rm_r "pkg" if File.exist? "pkg"
make_desktop
make_uninstall_script
make_install_script
- make_smaller unless ENV['GDB']
+ make_smaller unless APP['GDB']
end
- Dir.chdir "pkg" do
+ Dir.chdir "#{pkg}" do
puts `pwd`
- sh "makeself #{rlname} #{rlname}.install #{appname} \
-./shoes-install.sh "
+ sh "makeself #{rlname} #{rlname}.install #{appname} ./shoes-install.sh "
+ end
+ if APP['Bld_Pre']
+ # copy installer to the shoes3 source pkg/ dir (on an nfs server?)
+ cp "#{pkg}/#{rlname}.install", "pkg"
end
end
diff --git a/make/linux/xarm6hf/env.rb b/make/linux/xarm6hf/env.rb
index 21df91d7..58c75ee7 100644
--- a/make/linux/xarm6hf/env.rb
+++ b/make/linux/xarm6hf/env.rb
@@ -1,5 +1,6 @@
#
# Build shoes for Raspberry pi. Ruby is built in the chroot/qemu
+# no longer used but left for historical and how to reasons
#
cf =(ENV['ENV_CUSTOM'] || "#{TGT_ARCH}-custom.yaml")
if File.exists? cf
@@ -19,24 +20,21 @@
EXT_RUBY = "/srv/chroot/debrpi/usr/local"
APP['GTK'] = "gtk+-2.0"
end
-#ENV['DEBUG'] = "true" # turns on the tracing log
-#ENV['GDB'] = nil # compile -g, strip symbols when nil
-CHROOT = ShoesDeps
+
SHOES_TGT_ARCH = "armv7l-linux-eabihf"
SHOES_GEM_ARCH = "armv7l-linux"
# Specify where the Target system binaries live.
-# Trailing slash is important.
-TGT_SYS_DIR = "#{CHROOT}/"
# Setup some shortcuts for the library locations.
# These are not ruby paths but library paths
arch = 'arm-linux-gnueabihf'
-uldir = "#{TGT_SYS_DIR}usr/lib"
-ularch = "#{TGT_SYS_DIR}usr/lib/#{arch}"
-larch = "#{TGT_SYS_DIR}lib/#{arch}"
+uldir = "#{ShoesDeps}/usr/lib"
+ularch = "#{ShoesDeps}usr/lib/#{arch}"
+larch = "#{ShoesDeps}lib/#{arch}"
# Set appropriately (in my PATH), or use abs path)
CC = "arm-linux-gnueabihf-gcc"
# These ENV vars are used by the extconf.rb files (and tasks.rb)
-ENV['SYSROOT'] = CHROOT
+# should we have to build exts or gems
+ENV['SYSROOT'] = ShoesDeps
ENV['CC'] = CC
ENV['TGT_RUBY_PATH'] = EXT_RUBY
ENV['TGT_ARCH'] = SHOES_TGT_ARCH
@@ -61,14 +59,14 @@
# Hand code for your situation
def xfixip(path)
- path.gsub!(/-I\/usr\//, "-I#{TGT_SYS_DIR}usr/")
+ path.gsub!(/-I\/usr\//, "-I#{ShoesDeps}/usr/")
return path
end
def xfixrvmp(path)
#puts "path in: #{path}"
path.gsub!(/-I\/home\/ccoupe\/\.rvm/, "-I/home/cross/armv6-pi/rvm")
- path.gsub!(/-I\/usr\/local\//, "-I#{TGT_SYS_DIR}usr/local/")
+ path.gsub!(/-I\/usr\/local\//, "-I#{ShoesDeps}/usr/local/")
#puts "path out: #{path}"
return path
end
@@ -91,7 +89,7 @@ def xfixrvmp(path)
LINUX_CFLAGS << " -DSHOES_GTK "
LINUX_CFLAGS << " -DGTK3 " unless APP['GTK'] == 'gtk+-2.0'
LINUX_CFLAGS << xfixrvmp(`pkg-config --cflags "#{pkgruby}"`.strip)+" "
-LINUX_CFLAGS << " -I#{TGT_SYS_DIR}usr/include/#{arch} "
+LINUX_CFLAGS << " -I#{ShoesDeps}/usr/include/#{arch} "
LINUX_CFLAGS << xfixip("-I/usr/include")+" "
LINUX_CFLAGS << xfixip(`pkg-config --cflags "#{pkggtk}"`.strip)+" "
@@ -100,14 +98,14 @@ def xfixrvmp(path)
LINUX_LIB_NAMES = %W[ungif jpeg]
DLEXT = "so"
-LINUX_LDFLAGS = "-fPIC -shared --sysroot=#{CHROOT} -L#{ularch} "
+LINUX_LDFLAGS = "-fPIC -shared --sysroot=#{ShoesDeps} -L#{ularch} "
LINUX_LDFLAGS << `pkg-config --libs "#{pkggtk}"`.strip+" "
# dont use the ruby link info
RUBY_LDFLAGS = "-rdynamic -Wl,-export-dynamic "
RUBY_LDFLAGS << "-L#{EXT_RUBY}/lib -lruby "
-LINUX_LIBS = "--sysroot=#{CHROOT} -L/usr/lib "
+LINUX_LIBS = "--sysroot=#{ShoesDeps} -L/usr/lib "
LINUX_LIBS << LINUX_LIB_NAMES.map { |x| "-l#{x}" }.join(' ')
LINUX_LIBS << " #{RUBY_LDFLAGS} #{CAIRO_LIB} #{PANGO_LIB} #{MISC_LIB}"
diff --git a/make/linux/xmsys2/env.rb b/make/linux/xmsys2/env.rb
new file mode 100644
index 00000000..bbf11f61
--- /dev/null
+++ b/make/linux/xmsys2/env.rb
@@ -0,0 +1,157 @@
+# xmsys2 cross build
+cf =(ENV['ENV_CUSTOM'] || "xmsys2-custom.yaml")
+gtk_version = '3'
+if File.exists? cf
+ custmz = YAML.load_file(cf)
+ ShoesDeps = custmz['Deps']
+ EXT_RUBY = custmz['Ruby']
+ GtkDeps = custmz['GtkLoc'] ? custmz['GtkLoc'] : ShoesDeps
+ ENABLE_MS_THEME = custmz['MS-Theme'] == true
+ ENV['GDB'] = 'basic' if custmz['Debug'] == true
+ APP['GEMLOC'] = custmz['Gemloc'] if custmz['Gemloc']
+ APP['EXTLOC'] = custmz['Extloc'] if custmz['Extloc']
+ APP['EXTLIST'] = custmz['Exts'] if custmz['Exts']
+ APP['GEMLIST'] = custmz['Gems'] if custmz['Gems']
+ APP['INCLGEMS'] = custmz['InclGems'] if custmz['InclGems']
+ APP['VIDEO'] = true
+ APP['GTK'] = 'gtk+-3.0'
+ APP['INSTALLER'] = custmz['Installer'] == 'qtifw'? 'qtifw' : 'nsis'
+ APP['INSTALLER_LOC'] = custmz['InstallerLoc']
+else
+ # define where your deps are
+ #ShoesDeps = "E:/shoesdeps/mingw"
+ ShoesDeps = "C:/Users/Cecil/sandbox"
+ EXT_RUBY = RbConfig::CONFIG["prefix"]
+ ENABLE_MS_THEME = false
+end
+puts "Ruby = #{EXT_RUBY} Deps = #{ShoesDeps}, Gtk: #{GtkDeps}"
+SHOES_GEM_ARCH = "#{Gem::Platform.local}"
+SHOES_TGT_ARCH = 'i386-mingw32'
+WINVERSION = "#{APP['VERSION']}-gtk3-w32"
+WINFNAME = "#{APPNAME}-#{WINVERSION}"
+WIN32_CFLAGS = []
+WIN32_LDFLAGS = []
+WIN32_LIBS = []
+RUBY_HTTP = true
+
+file_list = []
+SRC = FileList[*file_list]
+OBJ = SRC.map do |x|
+ x.gsub(/\.\w+$/, '.o')
+end
+
+DLEXT = "dll"
+ADD_DLL = []
+
+CC = "i686-w64-mingw32-gcc"
+STRIP = "strip -x"
+WINDRES = "i686-w64-mingw32-windres"
+PKG_CONFIG = "pkg-config"
+
+# dance on ENV['PKG_CONFIG_PATH'] We want something pkg-config can use
+ENV['PKG_CONFIG_PATH'] = "#{ShoesDeps}/lib/pkgconfig"
+$stderr.puts "PKG PATH: #{ENV['PKG_CONFIG_PATH']}"
+if APP['GDB']
+ WIN32_CFLAGS << "-g3 -O0"
+else
+ WIN32_CFLAGS << "-O -Wall"
+end
+
+gtk_pkg_path = "#{GtkDeps}/lib/pkgconfig/gtk+-3.0.pc"
+
+GTK_CFLAGS = `#{PKG_CONFIG} --cflags gtk+-3.0 --define-variable=prefix=#{ShoesDeps}`.chomp
+GTK_LDFLAGS = `#{PKG_CONFIG} --libs gtk+-3.0 --define-variable=prefix=#{ShoesDeps}`.chomp
+CAIRO_CFLAGS = `#{PKG_CONFIG} --cflags glib-2.0 --define-variable=prefix=#{ShoesDeps}`.chomp +
+ `#{PKG_CONFIG} --cflags cairo --define-variable=prefix=#{ShoesDeps}`.chomp
+CAIRO_LDFLAGS = `#{PKG_CONFIG} --libs cairo --define-variable=prefix=#{ShoesDeps}`.chomp
+PANGO_CFLAGS = `#{PKG_CONFIG} --cflags pango --define-variable=prefix=#{ShoesDeps}`.chomp
+PANGO_LDFLAGS = `#{PKG_CONFIG} --libs pango --define-variable=prefix=#{ShoesDeps}`.chomp
+
+RUBY_LDFLAGS = " -Wl,-export-all-symbols -L#{EXT_RUBY}/lib -lmsvcrt-ruby220 "
+
+WIN32_CFLAGS << "-DSHOES_GTK -DSHOES_GTK_WIN32 -DRUBY_HTTP -DVIDEO"
+WIN32_CFLAGS << "-DGTK3 "
+WIN32_CFLAGS << "-Wno-unused-but-set-variable"
+WIN32_CFLAGS << "-D__MINGW_USE_VC2005_COMPAT -DXMD_H -D_WIN32_IE=0x0500 -D_WIN32_WINNT=0x0501 -DWINVER=0x0501 -DCOBJMACROS"
+WIN32_CFLAGS << GTK_CFLAGS
+WIN32_CFLAGS << CAIRO_CFLAGS
+WIN32_CFLAGS << PANGO_CFLAGS
+WIN32_CFLAGS << "-I#{ShoesDeps}/include/librsvg-2.0/librsvg "
+WIN32_CFLAGS << `pkg-config --cflags #{EXT_RUBY}/lib/pkgconfig/ruby-2.2.pc --define-variable=prefix=#{EXT_RUBY}`.chomp
+WIN32_CFLAGS << "-Ishoes"
+
+WIN32_LDFLAGS << "-lshell32 -lkernel32 -luser32 -lgdi32 -lcomdlg32 -lcomctl32"
+WIN32_LDFLAGS << "-lgif -ljpeg -lfontconfig"
+WIN32_LDFLAGS << "-L#{ENV['RI_DEVKIT']}/mingw/bin".gsub('\\','/').gsub(/^\//,'//')
+WIN32_LDFLAGS << "-fPIC -shared"
+WIN32_LDFLAGS << GTK_LDFLAGS
+WIN32_LDFLAGS << CAIRO_LDFLAGS
+WIN32_LDFLAGS << PANGO_LDFLAGS
+WIN32_LDFLAGS << RUBY_LDFLAGS
+
+WIN32_LIBS << RUBY_LDFLAGS
+WIN32_LIBS << CAIRO_LDFLAGS
+WIN32_LIBS << PANGO_LDFLAGS
+WIN32_LIBS << "-L#{ShoesDeps}/lib -lrsvg-2"
+
+# Cleaning up duplicates. Clunky? Hell yes!
+wIN32_CFLAGS = WIN32_CFLAGS.join(' ').split(' ').uniq
+wIN32_LDFLAGS = WIN32_LDFLAGS.join(' ').split(' ').uniq
+wIN32_LIBS = WIN32_LIBS.join(' ').split(' ').uniq
+
+LINUX_CFLAGS = wIN32_CFLAGS.join(' ')
+LINUX_LDFLAGS = wIN32_LDFLAGS.join(' ')
+LINUX_LIBS = wIN32_LIBS.join(' ')
+
+# hash of dlls to copy in tasks.rb pre_build - no particular order.
+bindll = "#{ShoesDeps}/bin"
+basedll = "#{ShoesDeps}/../basedll"
+gtkdll = "#{GtkDeps}/bin"
+SOLOCS = {
+ 'ruby' => "#{EXT_RUBY}/bin/msvcrt-ruby220.dll",
+ 'gif' => "#{bindll}/libgif-7.dll",
+ 'jpeg' => "#{bindll}/libjpeg-9.dll",
+ 'libyaml' => "#{bindll}/libyaml-0-2.dll",
+ 'iconv' => "#{bindll}/libiconv-2.dll",
+ 'eay' => "#{bindll}/libeay32.dll",
+ 'gdbm' => "#{bindll}/libgdbm-4.dll",
+ 'ssl' => "#{bindll}/ssleay32.dll",
+ 'gmp' => "#{basedll}/libgmp-10.dll", # ruby 2.2.6 needs this
+ 'gcc-dw' => "#{basedll}/libgcc_s_dw2-1.dll",
+ 'sqlite' => "#{bindll}/libsqlite3-0.dll"
+}
+
+
+SOLOCS.merge!(
+ {
+ 'atk' => "#{bindll}/libatk-1.0-0.dll",
+ 'cairo' => "#{bindll}/libcairo-2.dll",
+ 'cairo-gobj' => "#{bindll}/libcairo-gobject-2.dll",
+ 'ffi' => "#{bindll}/libffi-6.dll",
+ 'fontconfig' => "#{bindll}/libfontconfig-1.dll",
+ 'freetype' => "#{bindll}/libfreetype-6.dll",
+ 'gdkpixbuf' => "#{bindll}/libgdk_pixbuf-2.0-0.dll",
+ 'gio' => "#{bindll}/libgio-2.0-0.dll",
+ 'glib' => "#{bindll}/libglib-2.0-0.dll",
+ 'gmodule' => "#{bindll}/libgmodule-2.0-0.dll",
+ 'gobject' => "#{bindll}/libgobject-2.0-0.dll",
+ 'gdk3' => "#{gtkdll}/libgdk-3-0.dll",
+ 'gtk3' => "#{gtkdll}/libgtk-3-0.dll",
+ 'pixman' => "#{bindll}/libpixman-1-0.dll",
+ 'intl8' => "#{bindll}/libintl-8.dll",
+ 'pango' => "#{bindll}/libpango-1.0-0.dll",
+ 'pangocairo' => "#{bindll}/libpangocairo-1.0-0.dll",
+ 'pangoft' => "#{bindll}/libpangoft2-1.0-0.dll",
+ 'pango32' => "#{bindll}/libpangowin32-1.0-0.dll",
+ 'pixbuf' => "#{bindll}/libgdk_pixbuf-2.0-0.dll",
+ 'harfbuzz' => "#{bindll}/libharfbuzz-0.dll",
+ 'png16' => "#{bindll}/libpng16-16.dll",
+ 'croco' => "#{bindll}/libcroco-0.6-3.dll",
+ 'rsvg' => "#{bindll}/librsvg-2-2.dll",
+ 'xml2' => "#{bindll}/libxml2-2.dll",
+ 'thread' => "#{bindll}/libgthread-2.0-0.dll",
+ 'zlib1' => "#{bindll}/zlib1.dll",
+ 'pthread' => "#{basedll}/libwinpthread-1.dll",
+ }
+)
+
diff --git a/make/linux/xmsys2/packdeps.rb b/make/linux/xmsys2/packdeps.rb
new file mode 100644
index 00000000..24f35430
--- /dev/null
+++ b/make/linux/xmsys2/packdeps.rb
@@ -0,0 +1,33 @@
+# package ShoesDeps into just the minimum to upload
+# expect symlink trouble with include/x --> lib/x/include/ ?
+desc "package mingw dependencies"
+task :packdeps do
+ # ugly - build a ShoesDeps.zip in dist
+ rm_rf 'mingwdeps'
+ mkdir_p 'mingwdeps'
+ cp "#{ShoesDeps}/README.txt", 'mingwdeps'
+ bin = 'mingwdeps/bin'
+ mkdir_p bin
+ Dir.glob("#{ShoesDeps}/bin/*.dll") { |f|
+ cp f, bin
+ }
+ Dir.glob("#{ShoesDeps}/bin/fc*.exe") {|f|
+ cp f, bin
+ }
+ cp "#{ShoesDeps}/bin//gtk-update-icon-cache.exe", bin
+ cp "#{ShoesDeps}/bin/pkg-config.exe", bin
+ sh "cp -a #{ShoesDeps}/include mingwdeps"
+ cp_r "#{ShoesDeps}/etc", 'mingwdeps'
+ cp_r "#{ShoesDeps}/lib", 'mingwdeps'
+ mkdir_p 'mingwdeps/share'
+ cp_r "#{ShoesDeps}/share/fontconfig", 'mingwdeps/share'
+ cp_r "#{ShoesDeps}/share/glib-2.0", 'mingwdeps/share'
+ cp_r "#{ShoesDeps}/share/themes", 'mingwdeps/share'
+ cp_r "#{ShoesDeps}/share/xml", 'mingwdeps/share'
+ cp_r "#{ShoesDeps}/share/fontconfig", 'mingwdeps/share'
+ cp_r "#{ShoesDeps}/share/icons", 'mingwdeps/share'
+ Dir.chdir('mingwdeps') do
+ sh "zip -r ShoesDeps.zip README.txt etc lib share include bin"
+ end
+ puts "Done"
+end
diff --git a/make/linux/xmsys2/setup.rb b/make/linux/xmsys2/setup.rb
new file mode 100644
index 00000000..243b0e63
--- /dev/null
+++ b/make/linux/xmsys2/setup.rb
@@ -0,0 +1,66 @@
+# This is a big gulp of copying.
+require 'fileutils'
+module Make
+ include FileUtils
+
+ # Windows cross compile. Copy the static stuff, Copy the ruby libs
+ # Then copy the deps.
+ def static_setup (so_list)
+ $stderr.puts "setup: dir=#{`pwd`}"
+ rbvt = RUBY_V
+ rbvm = RUBY_V[/^\d+\.\d+/]
+ # remove leftovers from previous rake.
+ #rm_rf "#{TGT_DIR}/lib"
+ #rm_rf "#{TGT_DIR}/etc"
+ #rm_rf "#{TGT_DIR}/share"
+ #rm_rf "#{TGT_DIR}/conf.d"
+ mkdir_p "#{TGT_DIR}/fonts"
+ cp_r "fonts", "#{TGT_DIR}/fonts"
+ mkdir_p "#{TGT_DIR}/lib"
+ cp "lib/shoes.rb", "#{TGT_DIR}/lib"
+ cp_r "lib/shoes", "#{TGT_DIR}/lib"
+ cp_r "lib/exerb", "#{TGT_DIR}/lib"
+ cp_r "samples", "#{TGT_DIR}/samples"
+ cp_r "static", "#{TGT_DIR}/static"
+ cp "README.md", "#{TGT_DIR}/README.txt"
+ cp "CHANGELOG", "#{TGT_DIR}/CHANGELOG.txt"
+ cp "COPYING", "#{TGT_DIR}/COPYING.txt"
+ #mkdir_p "#{TGT_DIR}/lib"
+ cp_r "#{EXT_RUBY}/lib/ruby", "#{TGT_DIR}/lib", remove_destination: true
+ # copy include files
+ mkdir_p "#{TGT_DIR}/lib/ruby/include/ruby-#{rbvt}"
+ cp_r "#{EXT_RUBY}/include/ruby-#{rbvt}/", "#{TGT_DIR}/lib/ruby/include"
+ so_list.each_value do |path|
+ cp "#{path}", "#{TGT_DIR}"
+ end
+ # copy/setup etc/share
+ mkdir_p "#{TGT_DIR}/share/glib-2.0/schemas"
+ cp "#{ShoesDeps}/share/glib-2.0/schemas/gschemas.compiled" ,
+ "#{TGT_DIR}/share/glib-2.0/schemas"
+ cp_r "#{ShoesDeps}/share/fontconfig", "#{TGT_DIR}/share"
+ cp_r "#{ShoesDeps}/share/themes", "#{TGT_DIR}/share"
+ cp_r "#{ShoesDeps}/share/xml", "#{TGT_DIR}/share"
+ cp_r "#{ShoesDeps}/share/icons", "#{TGT_DIR}/share"
+
+ cp_r "#{ShoesDeps}/etc", TGT_DIR
+ if ENABLE_MS_THEME
+ ini_path = "#{TGT_DIR}/etc/gtk-3.0"
+ mkdir_p ini_path
+ File.open "#{ini_path}/settings.ini", mode: 'w' do |f|
+ f.write "[Settings]\n"
+ f.write "#gtk-theme-name=win32"
+ end
+ end
+ mkdir_p "#{ShoesDeps}/lib"
+ cp_r "#{ShoesDeps}/lib/gtk-3.0", "#{TGT_DIR}/lib"
+ bindir = "#{ShoesDeps}/bin"
+ if File.exist?("#{bindir}/gtk-update-icon-cache-3.0.exe")
+ cp "#{bindir}/gtk-update-icon-cache-3.0.exe",
+ "#{TGT_DIR}/gtk-update-icon-cache.exe"
+ else
+ cp "#{bindir}/gtk-update-icon-cache.exe", TGT_DIR
+ end
+ cp APP['icons']['win32'], "shoes/appwin32.ico"
+ end
+end
+
diff --git a/make/linux/xmsys2/stubs.rb b/make/linux/xmsys2/stubs.rb
new file mode 100644
index 00000000..0ea0790d
--- /dev/null
+++ b/make/linux/xmsys2/stubs.rb
@@ -0,0 +1,19 @@
+# build stubs - Much disappointment below.
+#
+desc "Build stubs (MinGW cross compile only)"
+task :stubs do
+ dbg = ENV['GDB']
+ #dbg = 'basic' # uncomment if needed
+ CPP = "i686-w64-mingw32-g++"
+ Dir.chdir("shoes/http") do
+ sh "#{CC} #{LINUX_CFLAGS} -I../../ -c winhttp.c"
+ end
+ Dir.chdir("platform/msw") do
+ sh "#{CC} #{dbg ? ' -DSTUB_DEBUG ' : ' '} #{LINUX_CFLAGS} -I../../ -c stub.c"
+ sh "i686-w64-mingw32-windres -o stub32.o -i stub32.rc"
+ sh "#{CC} -o shoes-stub.exe stub.o stub32.o ../../shoes/http/winhttp.o -lwinhttp -lcomctl32 #{dbg ? ' ' : '-mwindows'} "
+ sh "i686-w64-mingw32-strip -d shoes-stub.exe"
+ sh "cp shoes-stub.exe ../../static/stubs/"
+ end
+end
+
diff --git a/make/linux/xmsys2/tasks.rb b/make/linux/xmsys2/tasks.rb
new file mode 100644
index 00000000..bd5ab515
--- /dev/null
+++ b/make/linux/xmsys2/tasks.rb
@@ -0,0 +1,130 @@
+include FileUtils
+module Make
+ include FileUtils
+
+ def cc(t)
+ sh "#{CC} -I. -c -o#{t.name} #{LINUX_CFLAGS} #{t.source}"
+ end
+
+ # Subs in special variables
+ def rewrite before, after, reg = /\#\{(\w+)\}/, reg2 = '\1'
+ File.open(after, 'w') do |a|
+ File.open(before) do |b|
+ b.each do |line|
+ a << line.gsub(reg) do
+ if reg2.include? '\1'
+ reg2.gsub(%r!\\1!, Object.const_get($1))
+ else
+ reg2
+ end
+ end
+ end
+ end
+ end
+ end
+
+end
+
+class MakeLinux
+ extend Make
+
+ class << self
+
+ def setup_system_resources
+ cp APP['icons']['gtk'], "#{TGT_DIR}/static/app-icon.png"
+ end
+
+ def make_so(name)
+ if OBJ.empty?
+ puts "Called w/o need"
+ return
+ end
+ puts "make_so dir=#{pwd} arg=#{name}"
+ sh "#{CC} -o #{name} #{OBJ.join(' ')} #{LINUX_LDFLAGS} #{LINUX_LIBS}"
+ end
+
+ def new_link(name)
+=begin
+ tgts = name.split('/')
+ tgtd = tgts[0]
+ bin = "#{tgtd}/shoes.exe"
+ binc = "#{tgtd}/cshoes.exe"
+ #puts "binc = #{binc}"
+ #rm_f name
+ rm_f bin
+ rm_f binc
+ sh "#{WINDRES} -I. shoes/appwin32.rc shoes/appwin32.o"
+ missing = "-lgtk-3 -lgdk-3 -lfontconfig-1 -lpangocairo-1.0" # TODO: This is a bug in env.rb ?
+ sh "#{CC} -o #{bin} shoes/main.o shoes/appwin32.o -L#{TGT_DIR} -lshoes -mwindows #{LINUX_LIBS} #{missing}"
+ sh "#{STRIP} #{bin}" unless APP['GDB']
+ sh "#{CC} -o #{binc} shoes/main.o shoes/appwin32.o -L#{TGT_DIR} -lshoes #{LINUX_LIBS} #{missing}"
+ sh "#{STRIP} #{binc}" unless APP['GDB']
+=end
+ tgts = name.split('/')
+ tgtd = tgts[0]
+ bin = "#{tgtd}/shoes.exe"
+ binc = "#{tgtd}/cshoes.exe"
+ #puts "binc = #{binc}"
+ #rm_f name
+ rm_f bin
+ rm_f binc
+ tp = "#{TGT_DIR}/#{APP['Bld_Tmp']}"
+ sh "#{WINDRES} -I. shoes/appwin32.rc #{tp}/appwin32.o"
+ missing = "-lgtk-3 -lgdk-3 -lfontconfig-1 -lpangocairo-1.0" # TODO: This is a bug in env.rb ?
+ sh "#{CC} -o #{bin} #{tp}/main.o #{tp}/appwin32.o -L#{TGT_DIR} -lshoes -mwindows #{LINUX_LIBS} #{missing}"
+ sh "#{STRIP} #{bin}" unless APP['GDB']
+ sh "#{CC} -o #{binc} #{tp}/main.o #{tp}/appwin32.o -L#{TGT_DIR} -lshoes #{LINUX_LIBS} #{missing}"
+ sh "#{STRIP} #{binc}" unless APP['GDB']
+ end
+
+ # this is called from the file task based new_build
+ def new_so (name)
+ tgts = name.split('/')
+ tgtd = tgts[0]
+ $stderr.puts "new_so: #{tgtd}"
+ objs = []
+ SubDirs.each do |f|
+ d = File.dirname(f)
+ #$stderr.puts "collecting .o from #{d}"
+ objs = objs + FileList["#{d}/*.o"]
+ end
+ # TODO fix: gtk - needs to dig deeper vs osx
+ objs = objs + FileList["shoes/native/gtk/*.o"]
+ main_o = 'shoes/main.o'
+ objs = objs - [main_o]
+ sh "#{CC} -o #{tgtd}/libshoes.#{DLEXT} #{objs.join(' ')} #{LINUX_LDFLAGS} #{LINUX_LIBS}"
+ end
+
+ # does nothing
+ def make_userinstall
+ end
+
+ def make_resource(t)
+ puts "make resource"
+ end
+
+
+ def make_installer
+ # assumes you have NSIS installed on your box in the system PATH
+ # def sh(*args); super; end
+ puts "make_installer #{`pwd`}"
+ mkdir_p "pkg"
+ cp_r "VERSION.txt", "#{TGT_DIR}/VERSION.txt"
+ rm_rf "#{TGT_DIR}/nsis"
+ cp_r "platform/msw", "#{TGT_DIR}/nsis"
+ cp APP['icons']['win32'], "#{TGT_DIR}/nsis/setup.ico"
+ rewrite "#{TGT_DIR}/nsis/base.nsi", "#{TGT_DIR}/nsis/#{WINFNAME}.nsi"
+ Dir.chdir("#{TGT_DIR}/nsis") do
+ #sh "\"#{env('NSIS')}\\makensis.exe\" #{NAME}.nsi"
+ sh "makensis -V1 #{WINFNAME}.nsi"
+ end
+ mv "#{TGT_DIR}/nsis/#{WINFNAME}.exe", "pkg/"
+ Dir.chdir('pkg/') do
+ Dir.glob("Shoes*.exe").each do |f|
+ mv f, "#{f.downcase}"
+ end
+ end
+ end
+
+ end
+end
diff --git a/make/linux/xwin7/env.rb b/make/linux/xwin7/env.rb
index 4628ca49..2b402dd9 100644
--- a/make/linux/xwin7/env.rb
+++ b/make/linux/xwin7/env.rb
@@ -8,55 +8,46 @@
ShoesDeps = custmz['Deps']
EXT_RUBY = custmz['Ruby']
ENABLE_MS_THEME = custmz['MS-Theme'] == true
- ENV['GDB'] = 'basic' if custmz['Debug'] == true
+ APP['GDB'] = 'basic' if custmz['Debug'] == true
APP['GEMLOC'] = custmz['Gemloc'] if custmz['Gemloc']
APP['EXTLOC'] = custmz['Extloc'] if custmz['Extloc']
APP['EXTLIST'] = custmz['Exts'] if custmz['Exts']
APP['GEMLIST'] = custmz['Gems'] if custmz['Gems']
APP['INCLGEMS'] = custmz['InclGems'] if custmz['InclGems']
- #gtk_version = custmz['GtkVersion'].to_s if custmz['GtkVersion']
- #APP['VIDEO'] = true
else
- # define where your deps are
- ShoesDeps = "/home/ccoupe/Projects/shoesdeps/mingw"
- EXT_RUBY = "#{ShoesDeps}/usr/local"
- ENABLE_MS_THEME = false
+ abort "You must have an 'xwin7-custom.yaml' file!"
end
-puts "EXT_RUBY: #{EXT_RUBY}"
+#puts "EXT_RUBY: #{EXT_RUBY}"
APP['GTK'] = "gtk+-3.0" # needed in tasks.rb
#SHOES_GEM_ARCH = {Gem::Platform.local}
SHOES_GEM_ARCH = 'x86-mingw32'
-#ENV['DEBUG'] = "true" # turns on the tracing log
-#ENV['GDB'] = "basic" # 'basic' = keep symbols, or 'profile'
SHOES_TGT_ARCH = "i386-mingw32"
-# Specify where the Target system binaries live.
-# Trailing slash is important.
-TGT_SYS_DIR = "#{ShoesDeps}/"
-# Setup some shortcuts for the library locations. These are not ruby paths.
-# depends on what ruby was compiled to produce. Don't guess.
+
arch = 'i386-mingw32'
-uldir = "#{TGT_SYS_DIR}lib"
-ularch = "#{TGT_SYS_DIR}lib"
-larch = "#{TGT_SYS_DIR}lib/"
-bindll = "#{TGT_SYS_DIR}bin"
-ulbin = "#{TGT_SYS_DIR}usr/local/bin"
-# Set appropriately (in my PATH, or use abs)
+uldir = "#{ShoesDeps}/lib"
+ularch = "#{ShoesDeps}/lib"
+larch = "#{ShoesDeps}/lib/"
+bindll = "#{ShoesDeps}/bin"
+ulbin = "#{ShoesDeps}/usr/local/bin"
+
CC = "i686-w64-mingw32-gcc"
STRIP = "strip -x"
WINDRES = "i686-w64-mingw32-windres"
-# These ENV vars are used by the extconf.rb files
+
+# These ENV vars are used by the extconf.rb files should they
+# every appear again
ENV['SYSROOT']=ShoesDeps
ENV['CC']=CC
ENV['TGT_RUBY_PATH']=EXT_RUBY
ENV['TGT_ARCH'] = SHOES_TGT_ARCH
-ENV['TGT_RUBY_V'] = '2.2.0'
+ENV['TGT_RUBY_V'] = '2.3.0'
TGT_RUBY_V = ENV['TGT_RUBY_V']
-ENV['TGT_RUBY_SO'] = "msvcrt-ruby220"
+ENV['TGT_RUBY_SO'] = "msvcrt-ruby230"
EXT_RBCONFIG = "#{EXT_RUBY}/lib/ruby/#{TGT_RUBY_V}/#{SHOES_TGT_ARCH}/rbconfig.rb"
ENV['EXT_RBCONFIG'] = EXT_RBCONFIG
-pkgruby ="#{EXT_RUBY}/lib/pkgconfig/ruby-2.2.pc"
+pkgruby ="#{EXT_RUBY}/lib/pkgconfig/ruby-2.3.pc"
pkggtk ="#{uldir}/pkgconfig/gtk+-3.0.pc"
# winhttp or RUBY?
RUBY_HTTP = true
@@ -65,27 +56,16 @@
WINVERSION = "#{APP['VERSION']}-gtk3-32"
WINFNAME = "#{APPNAME}-#{WINVERSION}"
-gtk_extra_list = %w(shoes/native/gtkfixedalt.c shoes/native/gtkentryalt.c
- shoes/native/gtkcomboboxtextalt.c shoes/native/gtkbuttonalt.c
- shoes/native/gtkscrolledwindowalt.c shoes/native/gtkprogressbaralt.c)
-file_list = %w{shoes/native/gtk.c shoes/http/rbload.c} + gtk_extra_list + ["shoes/*.c"] +
- ["shoes/plot/*.c"]
-file_list << "shoes/video/video.c"
-SRC = FileList[*file_list]
-OBJ = SRC.map do |x|
- x.gsub(/\.\w+$/, '.o')
-end
-
ADD_DLL = []
-# Hand code for your situation
+# Hand code for your cross compie setup.
def xfixip(path)
- path.gsub!(/-I\/usr\//, "-I#{TGT_SYS_DIR}usr/")
+ path.gsub!(/-I\/usr\//, "-I#{ShoesDeps}/usr/")
return path
end
def xfixrvmp(path)
- path.gsub!(/-I\/usr\/local\//, "-I/#{TGT_SYS_DIR}usr/local/")
+ path.gsub!(/-I\/usr\/local\//, "-I/#{ShoesDeps}/usr/local/")
return path
end
@@ -98,7 +78,7 @@ def xfixrvmp(path)
png_lib = 'png'
-if ENV['DEBUG'] || ENV['GDB']
+if APP['GDB']
LINUX_CFLAGS = " -g3 -O0"
else
LINUX_CFLAGS = " -O -Wall"
@@ -107,22 +87,14 @@ def xfixrvmp(path)
LINUX_CFLAGS << " -DSHOES_GTK -DSHOES_GTK_WIN32 "
LINUX_CFLAGS << "-DRUBY_HTTP "
LINUX_CFLAGS << xfixrvmp(`pkg-config --cflags "#{pkgruby}"`.strip)+" "
-LINUX_CFLAGS << " -I#{TGT_SYS_DIR}usr/include/#{arch} "
+LINUX_CFLAGS << " -I#{ShoesDeps}/usr/include/#{arch} "
LINUX_CFLAGS << xfixip("-I/usr/include")+" "
LINUX_CFLAGS << xfixip(`pkg-config --cflags "#{pkggtk}"`.strip)+" "
LINUX_CFLAGS << "-I#{ShoesDeps}/include/librsvg-2.0/librsvg "
-LINUX_CFLAGS << " -I#{TGT_SYS_DIR}usr/local/include "
-if ENV['GDB']== 'profile'
- LINUX_CFLAGS << '-pg'
-end
+LINUX_CFLAGS << " -I#{ShoesDeps}/usr/local/include "
LINUX_CFLAGS << " -Wno-unused-but-set-variable -Wno-unused-variable -Wno-unused-function"
LINUX_CFLAGS << " -mms-bitfields -D__MINGW_USE_VC2005_COMPAT -DXMD_H -D_WIN32_IE=0x0500 -D_WIN32_WINNT=0x0501 -DWINVER=0x0501 -DCOBJMACROS "
-# I don't think the line below belongs in this file.
-# It should probably be in tasks/prebuild or tasks/package
-cp APP['icons']['win32'], "shoes/appwin32.ico"
-
-#LINUX_LIB_NAMES = %W[gif-4 jpeg librsvg-2 libffi]
LINUX_LIB_NAMES = %W[gif-7 jpeg librsvg-2 libffi]
DLEXT = "dll"
@@ -131,28 +103,24 @@ def xfixrvmp(path)
# dont use the ruby link info
RUBY_LDFLAGS = "-Wl,-export-all-symbols "
-RUBY_LDFLAGS << "-L#{EXT_RUBY}/lib -lmsvcrt-ruby220 "
+RUBY_LDFLAGS << "-L#{EXT_RUBY}/lib -lmsvcrt-ruby230 "
-LINUX_LDFLAGS << "#{ENV['GDB'] == 'profile' ? '-pg' : ' '} -lwinhttp -lshell32 -lkernel32 -luser32 -lgdi32 -lcomdlg32 -lcomctl32 "
+LINUX_LDFLAGS << "-lwinhttp -lshell32 -lkernel32 -luser32 -lgdi32 -lcomdlg32 -lcomctl32 "
LINUX_LIBS = " -L#{bindll} "
LINUX_LIBS << LINUX_LIB_NAMES.map { |x| "-l#{x}" }.join(' ')
LINUX_LIBS << " #{RUBY_LDFLAGS} #{CAIRO_LIB} #{PANGO_LIB} "
-# This should be used in pre_build instead of copy_deps_to_dist,
-# although either could work.
-# Reference: http://www.gtk.org/download/win32_contentlist.php
+# This is used in pre_build/setup
+
SOLOCS = {
- 'ruby' => "#{EXT_RUBY}/bin/msvcrt-ruby220.dll",
- #'ungif' => "#{uldir}/libungif.so.4",
- #'gif' => "#{bindll}/libgif-4.dll",
+ 'ruby' => "#{EXT_RUBY}/bin/msvcrt-ruby230.dll",
'gif' => "#{bindll}/libgif-7.dll",
'jpeg' => "#{bindll}/libjpeg-9.dll",
'libyaml' => "#{bindll}/libyaml-0-2.dll",
#'intl' => "#{bindll}/intl.dll",
'iconv' => "#{bindll}/libiconv-2.dll",
- #'ffi' => "#{bindll}/libffi-5.dll",
'eay' => "#{bindll}/libeay32.dll",
#'gdbm' => "#{bindll}/libgdbm-3.dll",
#'gdbmc' => "#{bindll}/libgdbm_compat-3.dll",
@@ -162,36 +130,40 @@ def xfixrvmp(path)
}
SOLOCS.merge!(
- {
- 'atk' => "#{bindll}/libatk-1.0-0.dll",
- 'cairo' => "#{bindll}/libcairo-2.dll",
- 'cairo-gobj' => "#{bindll}/libcairo-gobject-2.dll",
- 'ffi' => "#{bindll}/libffi-6.dll",
- 'fontconfig' => "#{bindll}/libfontconfig-1.dll",
- 'freetype' => "#{bindll}/libfreetype-6.dll",
- 'gdkpixbuf' => "#{bindll}/libgdk_pixbuf-2.0-0.dll",
- 'gdk3' => "#{bindll}/libgdk-3-0.dll",
- 'gio' => "#{bindll}/libgio-2.0-0.dll",
- 'glib' => "#{bindll}/libglib-2.0-0.dll",
- 'gmodule' => "#{bindll}/libgmodule-2.0-0.dll",
- 'gobject' => "#{bindll}/libgobject-2.0-0.dll",
- 'gtk3' => "#{bindll}/libgtk-3-0.dll",
- 'pixman' => "#{bindll}/libpixman-1-0.dll",
- 'intl8' => "#{bindll}/libintl-8.dll",
- 'pango' => "#{bindll}/libpango-1.0-0.dll",
- 'pangocairo' => "#{bindll}/libpangocairo-1.0-0.dll",
- 'pangoft' => "#{bindll}/libpangoft2-1.0-0.dll",
- 'pango32' => "#{bindll}/libpangowin32-1.0-0.dll",
- 'pixbuf' => "#{bindll}/libgdk_pixbuf-2.0-0.dll",
- 'harfbuzz' => "#{bindll}/libharfbuzz-0.dll",
- 'png16' => "#{bindll}/libpng16-16.dll",
- 'xml2' => "#{bindll}/libxml2-2.dll",
- 'croco' => "#{bindll}/libcroco-0.6-3.dll",
- 'rsvg' => "#{bindll}/librsvg-2-2.dll",
- 'thread' => "#{bindll}/libgthread-2.0-0.dll",
- 'zlib1' => "#{bindll}/zlib1.dll",
- 'siji' => "/usr/lib/gcc/i686-w64-mingw32/4.8/libgcc_s_sjlj-1.dll",
- 'pthread' => "/usr/i686-w64-mingw32/lib/libwinpthread-1.dll"
+ {
+ 'atk' => "#{bindll}/libatk-1.0-0.dll",
+ 'cairo' => "#{bindll}/libcairo-2.dll",
+ 'cairo-gobj' => "#{bindll}/libcairo-gobject-2.dll",
+ 'ffi' => "#{bindll}/libffi-6.dll",
+ 'fontconfig' => "#{bindll}/libfontconfig-1.dll",
+ 'freetype' => "#{bindll}/libfreetype-6.dll",
+ 'gdkpixbuf' => "#{bindll}/libgdk_pixbuf-2.0-0.dll",
+ 'gdk3' => "#{bindll}/libgdk-3-0.dll",
+ 'gio' => "#{bindll}/libgio-2.0-0.dll",
+ 'glib' => "#{bindll}/libglib-2.0-0.dll",
+ 'gmodule' => "#{bindll}/libgmodule-2.0-0.dll",
+ 'gobject' => "#{bindll}/libgobject-2.0-0.dll",
+ 'gtk3' => "#{bindll}/libgtk-3-0.dll",
+ 'pixman' => "#{bindll}/libpixman-1-0.dll",
+ 'intl8' => "#{bindll}/libintl-8.dll",
+ 'pango' => "#{bindll}/libpango-1.0-0.dll",
+ 'pangocairo' => "#{bindll}/libpangocairo-1.0-0.dll",
+ 'pangoft' => "#{bindll}/libpangoft2-1.0-0.dll",
+ 'pango32' => "#{bindll}/libpangowin32-1.0-0.dll",
+ 'pixbuf' => "#{bindll}/libgdk_pixbuf-2.0-0.dll",
+ 'harfbuzz' => "#{bindll}/libharfbuzz-0.dll",
+ 'png16' => "#{bindll}/libpng16-16.dll",
+ 'xml2' => "#{bindll}/libxml2-2.dll",
+ 'croco' => "#{bindll}/libcroco-0.6-3.dll",
+ 'rsvg' => "#{bindll}/librsvg-2-2.dll",
+ 'curl' => "#{bindll}/libcurl-4.dll",
+ 'thread' => "#{bindll}/libgthread-2.0-0.dll",
+ 'zlib1' => "#{bindll}/zlib1.dll",
+ 'siji' => "/usr/lib/gcc/i686-w64-mingw32/4.8/libgcc_s_sjlj-1.dll",
+ 'pthread' => "/usr/i686-w64-mingw32/lib/libwinpthread-1.dll"
}
- )
+)
+ReNames = {
+ "libcurl-4.dll" => "libcurl.dll"
+}
diff --git a/make/linux/xwin7/setup.rb b/make/linux/xwin7/setup.rb
new file mode 100644
index 00000000..5ac873fa
--- /dev/null
+++ b/make/linux/xwin7/setup.rb
@@ -0,0 +1,73 @@
+# This is a big gulp of copying.
+require 'fileutils'
+module Make
+ include FileUtils
+
+ # Windows cross compile. Copy the static stuff, Copy the ruby libs
+ # Then copy the deps.
+ def static_setup (so_list)
+ $stderr.puts "setup: dir=#{`pwd`}"
+ rbvt = RUBY_V
+ rbvm = RUBY_V[/^\d+\.\d+/]
+ # remove leftovers from previous rake.
+ rm_rf "#{TGT_DIR}/lib"
+ rm_rf "#{TGT_DIR}/etc"
+ rm_rf "#{TGT_DIR}/share"
+ rm_rf "#{TGT_DIR}/conf.d"
+ mkdir_p "#{TGT_DIR}/fonts"
+ cp_r "fonts", "#{TGT_DIR}/fonts"
+ mkdir_p "#{TGT_DIR}/lib"
+ cp "lib/shoes.rb", "#{TGT_DIR}/lib"
+ cp_r "lib/shoes", "#{TGT_DIR}/lib"
+ cp_r "lib/exerb", "#{TGT_DIR}/lib"
+ cp_r "samples", "#{TGT_DIR}/samples"
+ cp_r "static", "#{TGT_DIR}/static"
+ cp "README.md", "#{TGT_DIR}/README.txt"
+ cp "CHANGELOG", "#{TGT_DIR}/CHANGELOG.txt"
+ cp "COPYING", "#{TGT_DIR}/COPYING.txt"
+ #mkdir_p "#{TGT_DIR}/lib"
+ cp_r "#{EXT_RUBY}/lib/ruby", "#{TGT_DIR}/lib", remove_destination: true
+ # copy include files
+ mkdir_p "#{TGT_DIR}/lib/ruby/include/ruby-#{rbvt}"
+ cp_r "#{EXT_RUBY}/include/ruby-#{rbvt}/", "#{TGT_DIR}/lib/ruby/include"
+ so_list.each_value do |path|
+ cp "#{path}", "#{TGT_DIR}"
+ end
+ # the things we do for love...
+ ReNames.each_pair do |k, v|
+ if File.exist? "#{TGT_DIR}/#{k}"
+ mv "#{TGT_DIR}/#{k}", "#{TGT_DIR}/#{v}"
+ $stderr.puts "renamed #{k} to #{v}"
+ end
+ end
+ # copy/setup etc/share
+ mkdir_p "#{TGT_DIR}/share/glib-2.0/schemas"
+ cp "#{ShoesDeps}/share/glib-2.0/schemas/gschemas.compiled" ,
+ "#{TGT_DIR}/share/glib-2.0/schemas"
+ cp_r "#{ShoesDeps}/share/fontconfig", "#{TGT_DIR}/share"
+ cp_r "#{ShoesDeps}/share/themes", "#{TGT_DIR}/share"
+ cp_r "#{ShoesDeps}/share/xml", "#{TGT_DIR}/share"
+ cp_r "#{ShoesDeps}/share/icons", "#{TGT_DIR}/share"
+ sh "#{WINDRES} -I. shoes/appwin32.rc shoes/appwin32.o"
+ cp_r "#{ShoesDeps}/etc", TGT_DIR
+ if ENABLE_MS_THEME
+ ini_path = "#{TGT_DIR}/etc/gtk-3.0"
+ mkdir_p ini_path
+ File.open "#{ini_path}/settings.ini", mode: 'w' do |f|
+ f.write "[Settings]\n"
+ f.write "#gtk-theme-name=win32\n"
+ end
+ end
+ mkdir_p "#{ShoesDeps}/lib"
+ cp_r "#{ShoesDeps}/lib/gtk-3.0", "#{TGT_DIR}/lib"
+ bindir = "#{ShoesDeps}/bin"
+ if File.exist?("#{bindir}/gtk-update-icon-cache-3.0.exe")
+ cp "#{bindir}/gtk-update-icon-cache-3.0.exe",
+ "#{TGT_DIR}/gtk-update-icon-cache.exe"
+ else
+ cp "#{bindir}/gtk-update-icon-cache.exe", TGT_DIR
+ end
+ cp APP['icons']['win32'], "shoes/appwin32.ico"
+ end
+end
+
diff --git a/make/linux/xwin7/tasks.rb b/make/linux/xwin7/tasks.rb
index 8428c8f8..3b979ad0 100644
--- a/make/linux/xwin7/tasks.rb
+++ b/make/linux/xwin7/tasks.rb
@@ -2,32 +2,6 @@
module Make
include FileUtils
- def copy_files_to_dist
- puts "copy_files_to_dist dir=#{pwd}"
- if ENV['APP']
- if APP['clone']
- sh APP['clone'].gsub(/^git /, "#{GIT} --git-dir=#{ENV['APP']}/.git ")
- else
- cp_r ENV['APP'], "#{TGT_DIR}/app"
- end
- if APP['ignore']
- APP['ignore'].each do |nn|
- rm_rf "dist/app/#{nn}"
- end
- end
- end
-
- cp_r "fonts", "#{TGT_DIR}/fonts"
- cp "lib/shoes.rb", "#{TGT_DIR}/lib"
- cp_r "lib/shoes", "#{TGT_DIR}/lib"
- cp_r "lib/exerb", "#{TGT_DIR}/lib"
- cp_r "samples", "#{TGT_DIR}/samples"
- cp_r "static", "#{TGT_DIR}/static"
- cp "README.md", "#{TGT_DIR}/README.txt"
- cp "CHANGELOG", "#{TGT_DIR}/CHANGELOG.txt"
- cp "COPYING", "#{TGT_DIR}/COPYING.txt"
- end
-
def cc(t)
sh "#{CC} -I. -c -o#{t.name} #{LINUX_CFLAGS} #{t.source}"
end
@@ -47,142 +21,64 @@ def rewrite before, after, reg = /\#\{(\w+)\}/, reg2 = '\1'
end
end
end
- end
-
- def copy_files glob, dir
- FileList[glob].each { |f| cp_r f, dir }
- end
-
- # Windows cross compile. Copy the ruby libs
- # Then copy the deps.
- def pre_build
- puts "pre_build dir=#{`pwd`}"
- rbvt = RUBY_V
- rbvm = RUBY_V[/^\d+\.\d+/]
- # remove leftovers from previous rake.
- rm_rf "#{TGT_DIR}/lib"
- rm_rf "#{TGT_DIR}/etc"
- rm_rf "#{TGT_DIR}/share"
- rm_rf "#{TGT_DIR}/conf.d"
- mkdir_p "#{TGT_DIR}/lib"
- cp_r "#{EXT_RUBY}/lib/ruby", "#{TGT_DIR}/lib"
- # copy include files
- mkdir_p "#{TGT_DIR}/lib/ruby/include/ruby-#{rbvt}"
- cp_r "#{EXT_RUBY}/include/ruby-#{rbvt}/", "#{TGT_DIR}/lib/ruby/include"
- SOLOCS.each_value do |path|
- cp "#{path}", "#{TGT_DIR}"
- end
- # do some windows things
- mkdir_p "#{TGT_DIR}/share/glib-2.0/schemas"
- if APP['GTK'] == "gtk+-2.0"
- cp_r"#{TGT_SYS_DIR}/share/glib-2.0/schemas/gschema.dtd",
- "#{TGT_DIR}/share/glib-2.0/schemas"
- cp_r "#{ShoesDeps}/share/fontconfig", "#{TGT_DIR}/share"
- cp_r "#{ShoesDeps}/share/themes", "#{TGT_DIR}/share"
- cp_r "#{ShoesDeps}/share/xml", "#{TGT_DIR}/share"
- cp_r "#{ShoesDeps}/share/icons", "#{TGT_DIR}/share"
- elsif APP['GTK'] == "gtk+-3.0"
- cp "#{TGT_SYS_DIR}share/glib-2.0/schemas/gschemas.compiled" ,
- "#{TGT_DIR}/share/glib-2.0/schemas"
- cp_r "#{ShoesDeps}/share/fontconfig", "#{TGT_DIR}/share"
- cp_r "#{ShoesDeps}/share/themes", "#{TGT_DIR}/share"
- cp_r "#{ShoesDeps}/share/xml", "#{TGT_DIR}/share"
- cp_r "#{ShoesDeps}/share/icons", "#{TGT_DIR}/share"
- else
- cp "#{TGT_SYS_DIR}share/glib-2.0/schemas/gschemas.compiled" ,
- "#{TGT_DIR}/share/glib-2.0/schemas"
- end
- sh "#{WINDRES} -I. shoes/appwin32.rc shoes/appwin32.o"
- cp_r "#{ShoesDeps}/etc", TGT_DIR
- mkdir_p "#{ShoesDeps}/lib"
- if APP['GTK'] == "gtk+-3.0"
- cp_r "#{ShoesDeps}/lib/gtk-3.0", "#{TGT_DIR}/lib" # shoes, exerb, ruby here
- else
- cp_r "#{ShoesDeps}/lib/gtk-2.0", "#{TGT_DIR}/lib" # shoes, exerb, ruby here
- end
- bindir = "#{ShoesDeps}/bin"
- #cp_r "#{bindir}/fc-cache.exe", TGT_DIR
- cp_r "#{bindir}/gtk-update-icon-cache.exe", TGT_DIR
- # below for debugging purposes
- if ENV['GDB']
- cp "#{bindir}/fc-cat.exe", TGT_DIR
- cp "#{bindir}/fc-list.exe", TGT_DIR
- cp "#{bindir}/fc-match.exe", TGT_DIR
- cp "#{bindir}/fc-pattern.exe", TGT_DIR
- cp "#{bindir}/fc-query.exe", TGT_DIR
- cp "#{bindir}/fc-scan.exe", TGT_DIR
- cp "#{bindir}/fc-validate.exe", TGT_DIR
- end
- # disable MS Theme
- if !ENABLE_MS_THEME
- Dir.chdir("#{TGT_DIR}/share/themes/MS-Windows/gtk-2.0/") do
- mv 'gtkrc', 'disabled-gtkrc'
- end
- else
- # add our overrides to the MS-Windows theme
- cp "platform/msw/gtkrc", "#{TGT_DIR}/etc/gtk-2.0/"
- end
- end
+ end
- # common_build is a misnomer. copies prebuilt extentions & gems
- def common_build
- copy_gems
- end
-
end
class MakeLinux
extend Make
class << self
-
- def copy_deps_to_dist
- puts "copy_deps_to_dist dir=#{pwd}"
- unless ENV['GDB']
- sh "#{STRIP} #{TGT_DIR}/*.dll"
- Dir.glob("#{TGT_DIR}/lib/ruby/**/*.so").each {|lib| sh "#{STRIP} #{lib}"}
- end
- end
-
def setup_system_resources
cp APP['icons']['gtk'], "#{TGT_DIR}/static/app-icon.png"
- end
-
- # name {TGT_DIR}/shoes
- def make_app(name)
- puts "make_app dir=#{pwd} arg=#{name}"
- bin = "#{name}.exe"
- binc = bin.gsub(/shoes\.exe/, 'cshoes.exe')
- puts "binc = #{binc}"
- rm_f name
+ end
+
+ def new_link(name)
+ tgts = name.split('/')
+ tgtd = tgts[0]
+ bin = "#{tgtd}/shoes.exe"
+ binc = "#{tgtd}/cshoes.exe"
+ #puts "binc = #{binc}"
+ #rm_f name
rm_f bin
rm_f binc
- extra = ENV['GDB'] == 'profile' ? '-pg' : ''
- sh "#{CC} -o #{bin} bin/main.o shoes/appwin32.o -L#{TGT_DIR} -mwindows -lshoes #{LINUX_LIBS}"
- sh "#{STRIP} #{bin}" unless ENV['GDB']
- sh "#{CC} -o #{binc} bin/main.o shoes/appwin32.o -L#{TGT_DIR} #{extra} -lshoes #{LINUX_LIBS}"
- sh "#{STRIP} #{binc}" unless ENV['GDB']
+ tp = "#{TGT_DIR}/#{APP['Bld_Tmp']}"
+ sh "#{WINDRES} -I. shoes/appwin32.rc #{tp}/appwin32.o"
+ missing = "-lgtk-3 -lgdk-3 -lfontconfig-1 -lpangocairo-1.0" # TODO: This is a bug in env.rb ?
+ sh "#{CC} -o #{bin} #{tp}/main.o #{tp}/appwin32.o -L#{TGT_DIR} -lshoes -mwindows #{LINUX_LIBS} #{missing}"
+ sh "#{STRIP} #{bin}" unless APP['GDB']
+ sh "#{CC} -o #{binc} #{tp}/main.o #{tp}/appwin32.o -L#{TGT_DIR} -lshoes #{LINUX_LIBS} #{missing}"
+ sh "#{STRIP} #{binc}" unless APP['GDB']
end
- def make_so(name)
- puts "make_so dir=#{pwd} arg=#{name}"
- #ldflags = LINUX_LDFLAGS.sub! /INSTALL_NAME/, "-install_name @executable_path/lib#{SONAME}.#{DLEXT}"
- sh "#{CC} -o #{name} #{OBJ.join(' ')} #{LINUX_LDFLAGS} #{LINUX_LIBS}"
+ # this is called from the file task based new_builder
+ def new_so (name)
+ tgts = name.split('/')
+ tgtd = tgts[0]
+ $stderr.puts "new_so: #{tgtd}"
+ objs = []
+ SubDirs.each do |f|
+ d = File.dirname(f)
+ objs = objs + FileList["#{d}/*.o"]
+ end
+ # TODO fix: gtk - needs to dig deeper vs osx
+ objs = objs + FileList["shoes/native/gtk/*.o"]
+ main_o = 'shoes/main.o'
+ objs = objs - [main_o]
+ sh "#{CC} -o #{tgtd}/libshoes.#{DLEXT} #{objs.join(' ')} #{LINUX_LDFLAGS} #{LINUX_LIBS}"
end
# does nothing
def make_userinstall
end
-
- def make_resource(t)
- puts "make resource"
- end
-
def make_installer
# assumes you have NSIS installed on your box in the system PATH
# def sh(*args); super; end
- puts "make_installer #{`pwd`}"
+ $stderr.puts "make_installer #{`pwd`} moving tmp/"
+ tp = "#{TGT_DIR}/#{APP['Bld_Tmp']}"
+ mp = "#{TGT_DIR}-#{APP['Bld_Tmp']}"
+ mv tp, mp
mkdir_p "pkg"
cp_r "VERSION.txt", "#{TGT_DIR}/VERSION.txt"
rm_rf "#{TGT_DIR}/nsis"
@@ -191,7 +87,7 @@ def make_installer
rewrite "#{TGT_DIR}/nsis/base.nsi", "#{TGT_DIR}/nsis/#{WINFNAME}.nsi"
Dir.chdir("#{TGT_DIR}/nsis") do
#sh "\"#{env('NSIS')}\\makensis.exe\" #{NAME}.nsi"
- sh "makensis #{WINFNAME}.nsi"
+ sh "makensis -V1 #{WINFNAME}.nsi"
end
mv "#{TGT_DIR}/nsis/#{WINFNAME}.exe", "pkg/"
Dir.chdir('pkg/') do
@@ -199,7 +95,8 @@ def make_installer
mv f, "#{f.downcase}"
end
end
+ $stderr.puts "restore tmp/"
+ mv mp, tp
end
-
end
end
diff --git a/make/make.rb b/make/make.rb
deleted file mode 100644
index 1fa7108a..00000000
--- a/make/make.rb
+++ /dev/null
@@ -1,93 +0,0 @@
-module Make
- include FileUtils
-
- def copy_files_to_dist
- if ENV['APP']
- if APP['clone']
- sh APP['clone'].gsub(/^git /, "#{GIT} --git-dir=#{ENV['APP']}/.git ")
- else
- cp_r ENV['APP'], "dist/app"
- end
- if APP['ignore']
- APP['ignore'].each do |nn|
- rm_rf "dist/app/#{nn}"
- end
- end
- end
-
- cp_r "fonts", "dist/fonts"
- cp_r "lib", "dist/lib"
- cp_r "samples", "dist/samples"
- cp_r "static", "dist/static"
- cp "README.md", "dist/README.txt"
- cp "CHANGELOG", "dist/CHANGELOG.txt"
- cp "COPYING", "dist/COPYING.txt"
- end
-
- def cc(t)
- sh "#{CC} -I. -c -o#{t.name} #{LINUX_CFLAGS} #{t.source}"
- end
-
- # Subs in special variables
- def rewrite before, after, reg = /\#\{(\w+)\}/, reg2 = '\1'
- File.open(after, 'w') do |a|
- File.open(before) do |b|
- b.each do |line|
- a << line.gsub(reg) do
- if reg2.include? '\1'
- reg2.gsub(%r!\\1!, Object.const_get($1))
- else
- reg2
- end
- end
- end
- end
- end
- end
-
- def copy_files glob, dir
- FileList[glob].each { |f| cp_r f, dir }
- end
-
- # copy ruby libs to dist so we can link relative
- def pre_build
- $stderr.puts "Pre_build #{EXT_RUBY}"
- mkdir_p "dist/ruby"
- cp "#{::EXT_RUBY}/lib/lib#{::RUBY_SO}.so", "dist/lib#{::RUBY_SO}.so"
- end
-
- def common_build
- mkdir_p "dist/ruby"
- cp_r "#{EXT_RUBY}/lib/ruby/#{RUBY_V}", "dist/ruby/lib"
- unless ENV['STANDARD']
- %w[soap wsdl xsd].each do |libn|
- rm_rf "dist/ruby/lib/#{libn}"
- end
- end
- %w[req/rake/lib/*].each do |rdir|
- FileList[rdir].each { |rlib| cp_r rlib, "dist/ruby/lib" }
- end
- %w[req/binject/ext/binject_c req/bloopsaphone/ext/bloops req/chipmunk/ext/chipmunk].
- each { |xdir| copy_ext xdir, "dist/ruby/lib/#{SHOES_RUBY_ARCH}" }
-
- gdir = "dist/ruby/gems/#{RUBY_V}"
- #{}.each do |gemn, xdir|
- {'sqlite3' => 'lib'}.each do |gemn, xdir|
- spec = eval(File.read("req/#{gemn}/gemspec"))
- mkdir_p "#{gdir}/specifications"
- mkdir_p "#{gdir}/gems/#{spec.full_name}/lib"
- FileList["req/#{gemn}/lib/*"].each { |rlib| cp_r rlib, "#{gdir}/gems/#{spec.full_name}/lib" }
- mkdir_p "#{gdir}/gems/#{spec.full_name}/#{xdir}"
- FileList["req/#{gemn}/ext/*"].each { |elib| copy_ext elib, "#{gdir}/gems/#{spec.full_name}/#{xdir}" }
- cp "req/#{gemn}/gemspec", "#{gdir}/specifications/#{spec.full_name}.gemspec"
- end
- end
-
- # Check the environment
- def env(x)
- unless ENV[x]
- abort "Your #{x} environment variable is not set!"
- end
- ENV[x]
- end
-end
diff --git a/make/rakefile_common.rb b/make/rakefile_common.rb
deleted file mode 100644
index 6316f3d8..00000000
--- a/make/rakefile_common.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-task :build_os => [:buildenv_linux, :build_skel, "dist/#{NAME}"]
-
-task :buildenv_linux do
- unless ENV['VIDEO']
- rm_rf "dist"
- mkdir_p "dist"
- end
-end
diff --git a/make/subsys.rb b/make/subsys.rb
new file mode 100644
index 00000000..2e42ed6d
--- /dev/null
+++ b/make/subsys.rb
@@ -0,0 +1,216 @@
+# this is make _like_. very hand crafted. Modify with care and wisdom.
+# it creates the file tasks triggered at build time.
+Base_h = FileList["shoes/*.h"] - ["shoes/appwin32.h", "shoes/version.h"]
+# touching one of those could/should rebuild everything.
+#
+# Shoes shoes/base.lib (canvas, ruby, image....
+tp = "#{TGT_DIR}/#{APP['Bld_Tmp']}"
+mkdir_p tp, verbose: false
+base_src = FileList["shoes/*.c"]
+base_obj = []
+base_src.each do |c|
+ fnm = File.basename(c, ".*")
+ o = "#{tp}/#{fnm}.o"
+ base_obj << o
+ file o => [c] + Base_h do |t|
+ sh "#{CC} -o #{o} -I. -c #{LINUX_CFLAGS} #{c}"
+ end
+end
+file "#{tp}/zzbase.done" => base_obj do
+ touch "#{tp}/zzbase.done"
+end
+
+# Shoes/widget ruby interface (aka types/)
+mkdir_p "#{tp}/types", verbose: false
+rbwidget_src = FileList["shoes/types/*.c"]
+rbwidget_obj = []
+rbwidget_hdr = []
+rbwidget_src.each do |c|
+ fnm = File.basename(c, ".*")
+ o = "#{tp}/types/#{fnm}.o"
+ rbwidget_obj << o
+ h = c.gsub(/.c$/, '.h')
+ rbwidget_hdr << h
+ file o => [c] + [h] + Base_h do |t|
+ sh "#{CC} -o #{o} -I. -c #{LINUX_CFLAGS} #{c}"
+ end
+end
+file "#{tp}/types/zzwidgets.done" => rbwidget_obj do
+ touch "#{tp}/types/zzwidgets.done"
+end
+
+# Shoes Native
+nat_src = []
+nat_obj = []
+mkdir_p "#{tp}/native", verbose: false
+if RUBY_PLATFORM =~ /darwin/
+ file "#{tp}/native/cocoa.o" => ["shoes/native/cocoa.m", "shoes/native/cocoa.h"] + Base_h do
+ sh "#{CC} -o #{tp}/native/cocoa.o -I. -c #{LINUX_CFLAGS} shoes/native/cocoa.m"
+ end
+ file "#{tp}/native/zznative.done" => ["#{tp}/native/cocoa.o"] do
+ touch "#{tp}/native/zznative.done"
+ end
+else
+ nat_src = FileList['shoes/native/gtk/*.c']
+ nat_src.each do |c|
+ fnm = File.basename(c, ".*")
+ o = "#{tp}/native/#{fnm}.o"
+ nat_obj << o
+ h = c.gsub(/.c$/, '.h')
+ file o => [c] + [h] + ['shoes/native/native.h'] + Base_h do
+ sh "#{CC} -o #{o} -I. -c #{LINUX_CFLAGS} #{c}"
+ end
+ end
+ file "#{tp}/native/gtk.o" => ["shoes/native/gtk.c", "shoes/native/gtk.h", "shoes/native/native.h"] + Base_h do
+ sh "#{CC} -o #{tp}/native/gtk.o -I. -c #{LINUX_CFLAGS} shoes/native/gtk.c"
+ end
+ file "#{tp}/native/zznative.done" => ["#{tp}/native/gtk.o"] + nat_obj do
+ touch "#{tp}/native/zznative.done"
+ end
+end
+
+# Shoes/http
+dnl_src = []
+dnl_obj = []
+mkdir_p "#{tp}/http", verbose: false
+if RUBY_PLATFORM =~ /darwin/
+ dnl_src = ["shoes/http/nsurl.m"]
+else
+ dnl_src = ["shoes/http/rbload.c"]
+end
+dnl_src.each do |c|
+ fnm = File.basename(c, ".*")
+ o = "#{tp}/http/#{fnm}.o"
+ dnl_obj << o
+ file o => [c] + Base_h do |t|
+ cc t
+ end
+end
+file "#{tp}/http/zzdownload.done" => dnl_obj do
+ touch "#{tp}/http/zzdownload.done"
+end
+
+# Plot
+mkdir_p "#{tp}/plot", verbose: false
+plot_src = FileList['shoes/plot/*.c']
+plot_obj = []
+plot_src.each do |c|
+ fnm = File.basename(c, ".*")
+ o = "#{tp}/plot/#{fnm}.o"
+ plot_obj << o
+ file o => [c] + ["shoes/plot/plot.h", "shoes/plot/plot_util.c", "shoes/plot/chart_series.c"] do
+ sh "#{CC} -o #{o} -I. -c #{LINUX_CFLAGS} #{c}"
+ end
+end
+file "#{tp}/plot/zzplot.done" => plot_obj do
+ touch "#{tp}/plot/zzplot.done"
+end
+
+# Console
+mkdir_p "#{tp}/console", verbose: false
+if RUBY_PLATFORM =~ /darwin/
+ src = ["shoes/console/tesi.c", "shoes/console/colortab.c", "shoes/console/cocoa-term.m"]
+ obj =[]
+ src.each do |c|
+ fnm = File.basename(c, ".*")
+ o = "#{tp}/console/#{fnm}.o"
+ obj << o
+ file o => [c] + ["shoes/console/tesi.h"] do
+ sh "#{CC} -o #{o} -I. -c #{LINUX_CFLAGS} #{c}"
+ end
+ end
+ file "#{tp}/console/zzconsole.done" => obj do
+ touch "#{tp}/console/zzconsole.done"
+ end
+else
+ src = ["shoes/console/tesi.c", "shoes/console/colortab.c", "shoes/console/gtk-terminal.c"]
+ obj = []
+ src.each do |c|
+ fnm = File.basename(c, ".*")
+ o = "#{tp}/console/#{fnm}.o"
+ obj << o
+ file o => [c] + ["shoes/console/tesi.h"] do
+ sh "#{CC} -o #{o} -I. -c #{LINUX_CFLAGS} #{c}"
+ end
+ end
+ file "#{tp}/console/zzconsole.done" => obj do
+ touch "#{tp}/console/zzconsole.done"
+ end
+end
+
+# Too keep the main Rakefile almost legible, create some file tasks here for detecting
+# updates to static/manual-en.txt and lib/shoes.rb, lib/shoes/*.rb after shoes is 'setup'
+# but BEFORE new_so/new_link is called - an OSX requirement
+# Also handle sample/*/*.rb changes
+mkdir_p "#{tp}/copyonly", verbose: false
+file "#{tp}/copyonly/zzmanual.done" => ["#{tp}/zzsetup.done", "static/manual-en.txt"] do
+ if CROSS && (! TGT_DIR[/minlin/]) && (! TGT_DIR[/minbsd/])
+ cp "static/manual-en.txt", "#{TGT_DIR}/static/manual-en.txt"
+ end
+ touch "#{tp}/copyonly/zzmanual.done"
+end
+
+file "#{tp}/copyonly/zzshoesrb.done" => ["#{tp}/zzsetup.done", "lib/shoes.rb"] do
+ if CROSS && (! TGT_DIR[/minlin/]) && (! TGT_DIR[/minbsd/])
+ cp "lib/shoes.rb", "#{TGT_DIR}/lib/shoes.rb"
+ end
+ touch "#{tp}/copyonly/zzshoesrb.done"
+end
+
+# update lib/shoes/*.rb if changed. And ssl certs file.
+if CROSS && TGT_DIR != 'minlin' && TGT_DIR != 'minbsd'
+ shoesrblib = FileList["lib/shoes/*.rb"]
+ shoesrblib << "lib/shoes/cacert.pem"
+ taskl = []
+ shoesrblib.each do |fp|
+ taskl << "#{TGT_DIR}/#{fp}"
+ file "#{TGT_DIR}/#{fp}" => [fp] do |t|
+ cp "#{fp}", "#{TGT_DIR}/#{fp}"
+ end
+ end
+ file "#{tp}/copyonly/zzshoesrblib.done" => taskl do
+ touch "#{tp}/copyonly/zzshoesrblib.done", verbose: false
+ end
+else
+ # nothing to do because minlin uses symlinks
+ file "#{tp}/copyonly/zzshoesrblib.done" => ["#{tp}/zzsetup.done"] do
+ touch "#{tp}/copyonly/zzshoesrblib.done", verbose: false
+ end
+end
+
+# samples simple/ good/ expert/
+['simple', 'good', 'expert'].each do |sub|
+ if CROSS && TGT_DIR != 'minlin' && TGT_DIR != 'minbsd'
+ samples = FileList["samples/#{sub}/*.rb"]
+ sampl = []
+ samples.each do |fp|
+ sampl << "#{TGT_DIR}/#{fp}"
+ file "#{TGT_DIR}/#{fp}" => [fp] do
+ cp "#{fp}", "#{TGT_DIR}/#{fp}"
+ end
+ end
+ file "#{tp}/copyonly/zz#{sub}.done" => sampl do
+ touch "#{tp}/copyonly/zz#{sub}.done", verbose: false
+ end
+ else
+ file "#{tp}/copyonly/zz#{sub}.done" => ["#{tp}/zzsetup.done"] do
+ touch "#{tp}/copyonly/zz#{sub}.done", verbose: false
+ end
+ end
+end
+=begin
+if CROSS && TGT_DIR != 'minlin'
+ file "#{TGT_DIR}/lib/shoes.rb" => ["#{tp}/zzsetup.done", "lib/shoes.rb"] do
+ #$stderr.puts "Updating shoes.rb"
+ cp "lib/shoes.rb", "#{TGT_DIR}/lib/shoes.rb"
+ end
+ rbdeps = FileList["#{TGT_DIR}/lib/shoes/*.rb"]
+ rbdeps.each do |f|
+ #$stderr.puts "creating file task #{f} => lib/shoes/#{File.basename(f)}"
+ file f => ["lib/shoes/#{File.basename(f)}"] do |t|
+ #$stderr.puts "updated: #{f} from lib/shoes/#{File.basename(t.name)}"
+ cp "lib/shoes/#{File.basename(t.name)}", f
+ end
+ end
+end
+=end
diff --git a/make/win32/loose/env.rb b/make/win32/loose/env.rb
deleted file mode 100644
index 6d82115e..00000000
--- a/make/win32/loose/env.rb
+++ /dev/null
@@ -1,51 +0,0 @@
-require File.expand_path('make/make')
-extend Make
-
-EXT_RUBY = "../mingw"
-
-# use the platform Ruby claims
-require 'rbconfig'
-
-CC = ENV['CC'] ? ENV['CC'] : "gcc"
-file_list = ["shoes/*.c"] + %w{shoes/native/windows.c shoes/http/winhttp.c shoes/http/windownload.c}
-
-SRC = FileList[*file_list]
-OBJ = SRC.map do |x|
- x.gsub(/\.\w+$/, '.o')
-end
-
-ADD_DLL = ["shoes/appwin32.o"]
-
-# Linux build environment
-CAIRO_CFLAGS = '-I/mingw/include/glib-2.0 -I/mingw/lib/glib-2.0/include -I/mingw/include/cairo'
-CAIRO_LIB = '-lcairo'
-PANGO_CFLAGS = '-I/mingw/include/pango-1.0'
-PANGO_LIB = '-lpangocairo-1.0 -lpango-1.0 -lpangoft2-1.0 -lpangowin32-1.0'
-LINUX_CFLAGS = %[-Wall -I#{ENV['SHOES_DEPS_PATH'] || "/usr"}/include #{CAIRO_CFLAGS} #{PANGO_CFLAGS} -I#{RbConfig::CONFIG['archdir']}]
-if RbConfig::CONFIG['rubyhdrdir']
- LINUX_CFLAGS << " -I#{RbConfig::CONFIG['rubyhdrdir']} -I#{RbConfig::CONFIG['rubyhdrdir']}/#{SHOES_RUBY_ARCH}"
-end
-LINUX_LIB_NAMES = %W[#{RUBY_SO} cairo pangocairo-1.0 ungif]
-
-#FLAGS.each do |flag|
-# LINUX_CFLAGS << " -D#{flag}" if ENV[flag]
-#end
-if ENV['DEBUG']
- LINUX_CFLAGS << " -g -O0 "
-else
- LINUX_CFLAGS << " -O "
-end
-LINUX_CFLAGS << " -DRUBY_1_9"
-
-DLEXT = 'dll'
-LINUX_CFLAGS << ' -I. -I/mingw/include'
-LINUX_CFLAGS << ' -I/mingw/include/ruby-1.9.1/ruby'
-LINUX_CFLAGS << " -DXMD_H -DHAVE_BOOLEAN -DSHOES_WIN32 -D_WIN32_IE=0x0500 -D_WIN32_WINNT=0x0500 -DWINVER=0x0500 -DCOBJMACROS"
-LINUX_LDFLAGS = " -DBUILD_DLL -lungif -ljpeg -lglib-2.0 -lgobject-2.0 -lgio-2.0 -lgmodule-2.0 -lgthread-2.0 -fPIC -shared"
-LINUX_LDFLAGS << ' -lshell32 -lkernel32 -luser32 -lgdi32 -lcomdlg32 -lcomctl32 -lole32 -loleaut32 -ladvapi32 -loleacc -lwinhttp'
-
-cp APP['icons']['win32'], "shoes/appwin32.ico"
-
-LINUX_LIBS = LINUX_LIB_NAMES.map { |x| "-l#{x}" }.join(' ')
-
-LINUX_LIBS << " -L#{RbConfig::CONFIG['libdir']} #{CAIRO_LIB} #{PANGO_LIB}"
\ No newline at end of file
diff --git a/make/win32/loose/tasks.rb b/make/win32/loose/tasks.rb
deleted file mode 100644
index 6ed0eea8..00000000
--- a/make/win32/loose/tasks.rb
+++ /dev/null
@@ -1,69 +0,0 @@
-require File.expand_path('make/make')
-
-include FileUtils
-
-class MakeMinGW
- extend Make
-
- class << self
- # Execute shell calls through bash if we are compiling with mingw. This breaks us
- # out of the windows command shell if we are compiling from there.
- def sh(*args)
- cmd = args.join(' ')
- super "bash.exe --login -i -c \"#{cmd}\""
- end
-
- def copy_ext xdir, libdir
- Dir.chdir(xdir) do
- sh 'ruby extconf.rb; make'
- end
- copy_files "#{xdir}/*.so", libdir
- end
-
- def copy_deps_to_dist
- dlls = [RUBY_SO]
- dlls += IO.readlines("make/mingw/dlls").map{|dll| dll.chomp}
- dlls.each{|dll| cp "#{EXT_RUBY}/bin/#{dll}.dll", "dist/"}
- cp "dist/zlib1.dll", "dist/zlib.dll"
- Dir.glob("../deps_cairo*/*"){|file| cp file, "dist/"}
- sh "strip -x dist/*.dll" unless ENV['DEBUG']
- end
-
- def setup_system_resources
- cp APP['icons']['gtk'], "dist/static/app-icon.png"
- end
-
- def make_resource(t)
- sh "windres -I. #{t.source} #{t.name}"
- end
-
- def make_app(name)
- bin = name
- rm_f bin
- sh "#{CC} -Ldist -o #{bin} bin/main.o shoes/appwin32.o #{LINUX_LIBS} -lshoes #{Config::CONFIG['LDFLAGS']} -mwindows"
- rewrite "platform/nix/shoes.launch", name, %r!/shoes!, "/#{NAME}"
- sh %{echo 'cd "$OLDPWD"'}
- sh %{echo 'LD_LIBRARY_PATH=$APPPATH $APPPATH/#{File.basename(bin)} "$@"' >> #{name}}
- chmod 0755, name
- cp "platform/msw/shoes.exe.manifest", "dist/#{NAME}.exe.manifest"
- end
-
- def make_so(name)
- ldflags = LINUX_LDFLAGS.sub! /INSTALL_NAME/, "-install_name @executable_path/lib#{SONAME}.#{DLEXT}"
- sh "#{CC} -o #{name} #{OBJ.join(' ')} #{LINUX_LDFLAGS} #{LINUX_LIBS}"
- end
-
- def make_installer
- def sh(*args); super; end
- mkdir_p "pkg"
- rm_rf "dist/nsis"
- cp_r "platform/msw", "dist/nsis"
- cp APP['icons']['win32'], "dist/nsis/setup.ico"
- rewrite "dist/nsis/base.nsi", "dist/nsis/#{NAME}.nsi"
- Dir.chdir("dist/nsis") do
- sh "\"#{env('NSIS')}\\makensis.exe\" #{NAME}.nsi"
- end
- mv "dist/nsis/#{PKG}.exe", "pkg"
- end
- end
-end
\ No newline at end of file
diff --git a/make/win32/msys2/env.rb b/make/win32/msys2/env.rb
index 01c9e71e..50fe2649 100644
--- a/make/win32/msys2/env.rb
+++ b/make/win32/msys2/env.rb
@@ -9,7 +9,7 @@
EXT_RUBY = custmz['Ruby']
GtkDeps = custmz['GtkLoc'] ? custmz['GtkLoc'] : ShoesDeps
ENABLE_MS_THEME = custmz['MS-Theme'] == true
- ENV['GDB'] = 'basic' if custmz['Debug'] == true
+ APP['GDB'] = 'basic' if custmz['Debug'] == true
APP['GEMLOC'] = custmz['Gemloc'] if custmz['Gemloc']
APP['EXTLOC'] = custmz['Extloc'] if custmz['Extloc']
APP['EXTLIST'] = custmz['Exts'] if custmz['Exts']
@@ -17,6 +17,8 @@
APP['INCLGEMS'] = custmz['InclGems'] if custmz['InclGems']
APP['VIDEO'] = true
APP['GTK'] = 'gtk+-3.0'
+ APP['INSTALLER'] = custmz['Installer'] == 'qtifw'? 'qtifw' : 'nsis'
+ APP['INSTALLER_LOC'] = custmz['InstallerLoc']
else
# define where your deps are
#ShoesDeps = "E:/shoesdeps/mingw"
@@ -28,28 +30,15 @@
SHOES_GEM_ARCH = "#{Gem::Platform.local}"
SHOES_TGT_ARCH = 'i386-mingw32'
#APP['GTK'] = "gtk+-#{gtk_version}.0"
-#ENV['GDB'] = "basic" # 'basic' = keep symbols, or 'profile'
-WINVERSION = "#{APP['VERSION']}-#{APP['GTK']=='gtk+-3.0' ? 'gtk3' : 'gtk2'}-w32"
+
+WINVERSION = "#{APP['VERSION']}-gtk3-w32"
WINFNAME = "#{APPNAME}-#{WINVERSION}"
WIN32_CFLAGS = []
WIN32_LDFLAGS = []
WIN32_LIBS = []
RUBY_HTTP = true
-gtk_extra_list = []
-if APP['GTK'] == "gtk+-3.0"
- gtk_extra_list = %w(shoes/native/gtkfixedalt.c shoes/native/gtkentryalt.c
- shoes/native/gtkcomboboxtextalt.c shoes/native/gtkbuttonalt.c
- shoes/native/gtkscrolledwindowalt.c shoes/native/gtkprogressbaralt.c )
-end
-if RUBY_HTTP
- file_list = %w{shoes/native/gtk.c shoes/http/rbload.c} + gtk_extra_list + ["shoes/*.c"] +
- ["shoes/plot/*.c"]
-else
- file_list = %w{shoes/native/gtk.c shoes/http/winhttp.c shoes/http/windownload.c} + ["shoes/*.c"]
-end
-file_list << "shoes/video/video.c" if APP['VIDEO']
+file_list = []
SRC = FileList[*file_list]
-
OBJ = SRC.map do |x|
x.gsub(/\.\w+$/, '.o')
end
@@ -62,50 +51,27 @@
ENV['ShoesDeps'] = ShoesDeps # also for sqlite3 gem
STRIP = "strip -s"
WINDRES = "windres"
-#PKG_CONFIG = "C:/msys64/usr/bin/pkg-config.exe" # Has to be Ruby `path`
PKG_CONFIG = "pkg-config.exe"
-ENV['PKG_CONFIG_PATH'] = ENV['PKG_CONFIG_PATH'].split(";").collect { |n| `cygpath -u #{n}`.chomp }.join(":")
-#PKG_LOC = "C:/msys64/mingw32/lib/pkgconfig" # ditto
# dance on ENV['PKG_CONFIG_PATH'] We want something pkg-config can use
-#ENV['PKG_CONFIG_PATH'] = '/c/msys64/mingw32/lib/pkgconfig'+':'+ENV['PKG_CONFIG_PATH']
-#$stderr.puts "have #{ENV['PKG_CONFIG_PATH']}"
-if ENV['DEBUG'] || ENV['GDB']
+ENV['PKG_CONFIG_PATH'] = `cygpath -u #{ShoesDeps}/lib/pkgconfig`.chomp
+
+if APP['GDB']
WIN32_CFLAGS << "-g3 -O0"
else
WIN32_CFLAGS << "-O -Wall"
end
-# fixup include paths
-def xfixip(path)
- #path.gsub!(/-I\/mingw32\//, "-IC:/msys64/mingw32/")
- path.gsub!(/-I\/mingw32\//, "-I#{`cygpath -m /mingw32/`.chomp}")
- return path
-end
-# fixup link paths
-def xfixlp(path)
- #path.gsub!(/-L\/mingw32\//, "-LC:/msys64/mingw32/")
- path.gsub!(/-L\/mingw32\//, "-L#{`cygpath -m /mingw32/`.chomp}")
- return path
-end
-
-#fixup ruby includes
-def xfixri(path)
- #path.gsub!(/-I\/usr\/local\//, "-I/#{TGT_SYS_DIR}usr/local/")
- return path
-end
-
gtk_pkg_path = "#{GtkDeps}/lib/pkgconfig/gtk+-3.0.pc"
-GTK_CFLAGS = xfixip(`#{PKG_CONFIG} --cflags #{gtk_pkg_path}`.chomp)
-GTK_LDFLAGS = xfixlp(`#{PKG_CONFIG} --libs gtk+-3.0`.chomp)
-CAIRO_CFLAGS = xfixip(`#{PKG_CONFIG} --cflags glib-2.0`.chomp +
- `#{PKG_CONFIG} --cflags cairo`.chomp)
-CAIRO_LDFLAGS = xfixlp(`#{PKG_CONFIG} --libs cairo`.chomp)
-PANGO_CFLAGS = xfixip(`#{PKG_CONFIG} --cflags pango`.chomp)
-PANGO_LDFLAGS = xfixlp(`#{PKG_CONFIG} --libs pango`.chomp)
+GTK_CFLAGS = `#{PKG_CONFIG} --cflags gtk+-3.0 --define-variable=prefix=#{ShoesDeps}`.chomp
+GTK_LDFLAGS = `#{PKG_CONFIG} --libs gtk+-3.0 --define-variable=prefix=#{ShoesDeps}`.chomp
+CAIRO_CFLAGS = `#{PKG_CONFIG} --cflags glib-2.0 --define-variable=prefix=#{ShoesDeps}`.chomp +
+ `#{PKG_CONFIG} --cflags cairo --define-variable=prefix=#{ShoesDeps}`.chomp
+CAIRO_LDFLAGS = `#{PKG_CONFIG} --libs cairo --define-variable=prefix=#{ShoesDeps}`.chomp
+PANGO_CFLAGS = `#{PKG_CONFIG} --cflags pango --define-variable=prefix=#{ShoesDeps}`.chomp
+PANGO_LDFLAGS = `#{PKG_CONFIG} --libs pango --define-variable=prefix=#{ShoesDeps}`.chomp
RUBY_LDFLAGS = "-L#{RbConfig::CONFIG["bindir"]} #{RbConfig::CONFIG["LIBRUBYARG"]} "
RUBY_LDFLAGS << "-Wl,-export-all-symbols "
-#RUBY_LDFLAGS << "-L#{EXT_RUBY}/lib -lmsvcrt-ruby210 "
WIN32_CFLAGS << "-DSHOES_GTK -DSHOES_GTK_WIN32 -DRUBY_HTTP -DVIDEO"
WIN32_CFLAGS << "-DGTK3 "
@@ -118,25 +84,18 @@ def xfixri(path)
RbConfig::CONFIG.select { |k, _| k[/hdrdir/] }.each_key do |v|
WIN32_CFLAGS << "-I#{RbConfig::CONFIG[v]}"
end
-#["jpeg-6b-4-lib", "giflib-4.1.4-1-lib"].each { |n|
-# WIN32_CFLAGS << "-Isandbox/#{n}/include"
-# WIN32_LDFLAGS << "-Lsandbox/#{n}/lib"
-#}
WIN32_CFLAGS << "-Ishoes"
WIN32_LDFLAGS << "-lshell32 -lkernel32 -luser32 -lgdi32 -lcomdlg32 -lcomctl32"
WIN32_LDFLAGS << "-lgif -ljpeg -lfontconfig"
+# following line probably not needed.
WIN32_LDFLAGS << "-L#{ENV['RI_DEVKIT']}/mingw/bin".gsub('\\','/').gsub(/^\//,'//')
-#WIN32_LDFLAGS << "-lwinpthread-1 -fPIC -shared"
WIN32_LDFLAGS << "-fPIC -shared"
WIN32_LDFLAGS << GTK_LDFLAGS
WIN32_LDFLAGS << CAIRO_LDFLAGS
WIN32_LDFLAGS << PANGO_LDFLAGS
WIN32_LDFLAGS << RUBY_LDFLAGS
-#WIN32_LIBS = WIN32_LDFLAGS
-#WIN32_LIBS << "-L#{ENV['RI_DEVKIT']}/mingw/bin".gsub('\\','/').gsub(/^\//,'//')
-#WIN32_LIBS << "-lgif -ljpeg -Wl,-export-all-symbols -lmsvcrt-ruby210 -lcairo -lpango-1.0 -lgobject-2.0 -lgmodule-2.0 -lgthread-2.0 -lglib-2.0 -lintl "
WIN32_LIBS << RUBY_LDFLAGS
WIN32_LIBS << CAIRO_LDFLAGS
WIN32_LIBS << PANGO_LDFLAGS
@@ -151,32 +110,22 @@ def xfixri(path)
LINUX_LDFLAGS = wIN32_LDFLAGS.join(' ')
LINUX_LIBS = wIN32_LIBS.join(' ')
-# hash of dlls to copy in tasks.rb pre_build
+# hash of dlls to copy in setup.rb
bindll = "#{ShoesDeps}/bin"
-#rubydll = "#{EXT_RUBY}/bin"
-#devdll = "#{ENV['RI_DEVKIT']}/mingw/bin"
-#libdll = "#{ShoesDeps}/lib"
-# msys2 want's some things from or maybe its Ruby 2.2.6?
-#basedll = "C:/msys64/mingw32/bin"
basedll = `cygpath -m /mingw32/bin`.chomp
gtkdll = "#{GtkDeps}/bin"
SOLOCS = {
'ruby' => "#{EXT_RUBY}/bin/msvcrt-ruby220.dll",
- #'gif' => "#{bindll}/libgif-4.dll",
'gif' => "#{bindll}/libgif-7.dll",
- #'jpeg' => "#{bindll}/libjpeg-8.dll",
'jpeg' => "#{bindll}/libjpeg-9.dll",
'libyaml' => "#{bindll}/libyaml-0-2.dll",
'iconv' => "#{bindll}/libiconv-2.dll",
'eay' => "#{bindll}/libeay32.dll",
'gdbm' => "#{bindll}/libgdbm-4.dll",
- #'gdbm' => "#{basedll}/libgdbm-4.dll",
'ssl' => "#{bindll}/ssleay32.dll",
- 'gmp' => "#{basedll}/libgmp-10.dll", # ruby 2.2.6 needs this
-# 'gcc-dw' => "#{basedll}/libgcc_s_dw2-1.dll",
+ 'gmp' => "#{basedll}/libgmp-10.dll", # ruby 2.2.6+ needs this
'gcc-dw' => "#{basedll}/libgcc_s_dw2-1.dll",
- 'sqlite' => "#{bindll}/sqlite3.dll"
- #'sqlite' => "#{`cygpath -m /mingw32/lib`.chomp}/sqlite3.13.0/sqlite3130.dll"
+ 'sqlite' => "#{bindll}/libsqlite3-0.dll"
}
if APP['GTK'] == 'gtk+-3.0'
@@ -210,11 +159,9 @@ def xfixri(path)
'xml2' => "#{bindll}/libxml2-2.dll",
'thread' => "#{bindll}/libgthread-2.0-0.dll",
'zlib1' => "#{bindll}/zlib1.dll",
- 'pthread' => "#{bindll}/libwinpthread-1.dll",
- #'pthread' => "#{basedll}/libwinpthread-1.dll",
- 'sjlj' => "#{bindll}/libgcc_s_sjlj-1.dll"
+ #'pthread' => "#{bindll}/libwinpthread-1.dll",
+ 'pthread' => "#{basedll}/libwinpthread-1.dll",
+ #'sjlj' => "#{bindll}/libgcc_s_sjlj-1.dll"
}
)
end
-
-
diff --git a/make/win32/msys2/setup.rb b/make/win32/msys2/setup.rb
new file mode 100644
index 00000000..2fdc744d
--- /dev/null
+++ b/make/win32/msys2/setup.rb
@@ -0,0 +1,66 @@
+# This is a big gulp of copying.
+require 'fileutils'
+module Make
+ include FileUtils
+
+ # Windows compile. Copy the static stuff, Copy the ruby libs
+ # Then copy the deps.
+ def static_setup (so_list)
+ $stderr.puts "setup: dir=#{`pwd`}"
+ rbvt = RUBY_V
+ rbvm = RUBY_V[/^\d+\.\d+/]
+ # remove leftovers from previous rake.
+ rm_rf "#{TGT_DIR}/lib"
+ rm_rf "#{TGT_DIR}/etc"
+ rm_rf "#{TGT_DIR}/share"
+ rm_rf "#{TGT_DIR}/conf.d"
+ mkdir_p "#{TGT_DIR}/fonts"
+ cp_r "fonts", "#{TGT_DIR}/fonts"
+ mkdir_p "#{TGT_DIR}/lib"
+ cp "lib/shoes.rb", "#{TGT_DIR}/lib"
+ cp_r "lib/shoes", "#{TGT_DIR}/lib"
+ cp_r "lib/exerb", "#{TGT_DIR}/lib"
+ cp_r "samples", "#{TGT_DIR}/samples"
+ cp_r "static", "#{TGT_DIR}/static"
+ cp "README.md", "#{TGT_DIR}/README.txt"
+ cp "CHANGELOG", "#{TGT_DIR}/CHANGELOG.txt"
+ cp "COPYING", "#{TGT_DIR}/COPYING.txt"
+ #mkdir_p "#{TGT_DIR}/lib"
+ cp_r "#{EXT_RUBY}/lib/ruby", "#{TGT_DIR}/lib", remove_destination: true
+ # copy include files
+ mkdir_p "#{TGT_DIR}/lib/ruby/include/ruby-#{rbvt}"
+ cp_r "#{EXT_RUBY}/include/ruby-#{rbvt}/", "#{TGT_DIR}/lib/ruby/include"
+ so_list.each_value do |path|
+ cp "#{path}", "#{TGT_DIR}"
+ end
+ # copy/setup etc/share
+ mkdir_p "#{TGT_DIR}/share/glib-2.0/schemas"
+ cp "#{ShoesDeps}/share/glib-2.0/schemas/gschemas.compiled" ,
+ "#{TGT_DIR}/share/glib-2.0/schemas"
+ cp_r "#{ShoesDeps}/share/fontconfig", "#{TGT_DIR}/share"
+ cp_r "#{ShoesDeps}/share/themes", "#{TGT_DIR}/share"
+ cp_r "#{ShoesDeps}/share/xml", "#{TGT_DIR}/share"
+ cp_r "#{ShoesDeps}/share/icons", "#{TGT_DIR}/share"
+ sh "#{WINDRES} -I. shoes/appwin32.rc shoes/appwin32.o"
+ cp_r "#{ShoesDeps}/etc", TGT_DIR
+ if ENABLE_MS_THEME
+ ini_path = "#{TGT_DIR}/etc/gtk-3.0"
+ mkdir_p ini_path
+ File.open "#{ini_path}/settings.ini", mode: 'w' do |f|
+ f.write "[Settings]\n"
+ f.write "#gtk-theme-name=win32\n"
+ end
+ end
+ mkdir_p "#{ShoesDeps}/lib"
+ cp_r "#{ShoesDeps}/lib/gtk-3.0", "#{TGT_DIR}/lib"
+ bindir = "#{ShoesDeps}/bin"
+ if File.exist?("#{bindir}/gtk-update-icon-cache-3.0.exe")
+ cp "#{bindir}/gtk-update-icon-cache-3.0.exe",
+ "#{TGT_DIR}/gtk-update-icon-cache.exe"
+ else
+ cp "#{bindir}/gtk-update-icon-cache.exe", TGT_DIR
+ end
+ cp APP['icons']['win32'], "shoes/appwin32.ico"
+ end
+end
+
diff --git a/make/win32/msys2/tasks.rb b/make/win32/msys2/tasks.rb
index 0552b128..8927f4b2 100644
--- a/make/win32/msys2/tasks.rb
+++ b/make/win32/msys2/tasks.rb
@@ -1,32 +1,6 @@
module Make
include FileUtils
- def copy_files_to_dist
- puts "copy_files_to_dist dir=#{pwd}"
- if ENV['APP']
- if APP['clone']
- sh APP['clone'].gsub(/^git /, "#{GIT} --git-dir=#{ENV['APP']}/.git ")
- else
- cp_r ENV['APP'], "#{TGT_DIR}/app"
- end
- if APP['ignore']
- APP['ignore'].each do |nn|
- rm_rf "dist/app/#{nn}"
- end
- end
- end
-
- cp_r "fonts", "#{TGT_DIR}/fonts"
- cp "lib/shoes.rb", "#{TGT_DIR}/lib"
- cp_r "lib/shoes", "#{TGT_DIR}/lib"
- cp_r "lib/exerb", "#{TGT_DIR}/lib"
- cp_r "samples", "#{TGT_DIR}/samples"
- cp_r "static", "#{TGT_DIR}/static"
- cp "README.md", "#{TGT_DIR}/README.txt"
- cp "CHANGELOG", "#{TGT_DIR}/CHANGELOG.txt"
- cp "COPYING", "#{TGT_DIR}/COPYING.txt"
- end
-
def cc(t)
sh "#{CC} -I. -c -o#{t.name} #{WINDOWS_CFLAGS} #{t.source}"
end
@@ -46,126 +20,7 @@ def rewrite before, after, reg = /\#\{(\w+)\}/, reg2 = '\1'
end
end
end
- end
-
- def copy_files glob, dir
- FileList[glob].each { |f| cp_r f, dir }
- end
-
- # Copy the rubyinstaller libs - sigh - don't copy all of the gems.
- # Then copy the deps.
- def pre_build
- puts "pre_build dir=#{`pwd`}"
- rbvt = RUBY_V
- rbvm = RUBY_V[/^\d+\.\d+/]
- # remove leftovers from previous rake.
- rm_rf "#{TGT_DIR}/lib"
- rm_rf "#{TGT_DIR}/etc"
- rm_rf "#{TGT_DIR}/share"
- rm_rf "#{TGT_DIR}/conf.d"
- mkdir_p "#{TGT_DIR}/lib/ruby"
- cp_r "#{EXT_RUBY}/lib/ruby/#{rbvt}", "#{TGT_DIR}/lib/ruby"
- # copy include files
- mkdir_p "#{TGT_DIR}/lib/ruby/include/ruby-#{rbvt}"
- cp_r "#{EXT_RUBY}/include/ruby-#{rbvt}/", "#{TGT_DIR}/lib/ruby/include"
- # copy site_ruby (gems updates)
- cp_r "#{EXT_RUBY}/lib/ruby/site_ruby", "#{TGT_DIR}/lib/ruby"
- # copy vendor_ruby
- cp_r "#{EXT_RUBY}/lib/ruby/vendor_ruby", "#{TGT_DIR}/lib/ruby"
- # make empty gem libs
- mkdir_p "#{TGT_DIR}/lib/ruby/gems/#{rbvt}"
- ['build_info', 'cache', 'doc', 'extentions', 'gems', 'specifications' ].each do
- |d| mkdir_p "#{TGT_DIR}/lib/ruby/gems/#{rbvt}/#{d}"
- end
- # copy default gemspecs
- cp_r "#{EXT_RUBY}/lib/ruby/gems/#{rbvt}/specifications/default",
- "#{TGT_DIR}/lib/ruby/gems/#{rbvt}/specifications"
- # from default gemspecs , copy what's in gems (rake, rdoc, test-unit)
- # other defaults like bigdecimal are inside ruby. Grr.
- specs = Dir.glob("#{EXT_RUBY}/lib/ruby/gems/#{rbvt}/specifications/default/*.gemspec")
- specs.each do |spec|
- dirname = File.basename(spec, ".gemspec")
- next unless File.directory?("#{EXT_RUBY}/lib/ruby/gems/#{rbvt}/gems/#{dirname}")
- #puts "Copy #{dirname}"
- cp_r "#{EXT_RUBY}/lib/ruby/gems/#{rbvt}/gems/#{dirname}", "#{TGT_DIR}/lib/ruby/gems/#{rbvt}/gems"
- end
- # copy the deplibs (see env.rb)
- SOLOCS.each_value do |path|
- cp "#{path}", "#{TGT_DIR}"
- end
- # setup GTK stuff
- mkdir_p "#{TGT_DIR}/share/glib-2.0/schemas"
- if APP['GTK'] == "gtk+-2.0"
- cp_r"#{ShoesDeps}/share/glib-2.0/schemas/gschema.dtd",
- "#{TGT_DIR}/share/glib-2.0/schemas"
- cp_r "#{ShoesDeps}/share/fontconfig", "#{TGT_DIR}/share"
- cp_r "#{ShoesDeps}/share/themes", "#{TGT_DIR}/share"
- cp_r "#{ShoesDeps}/share/xml", "#{TGT_DIR}/share"
- cp_r "#{ShoesDeps}/share/icons", "#{TGT_DIR}/share"
- elsif APP['GTK'] == "gtk+-3.0"
- cp "#{ShoesDeps}/share/glib-2.0/schemas/gschemas.compiled" ,
- "#{TGT_DIR}/share/glib-2.0/schemas"
- cp_r "#{ShoesDeps}/share/fontconfig", "#{TGT_DIR}/share"
- cp_r "#{ShoesDeps}/share/themes", "#{TGT_DIR}/share"
- cp_r "#{ShoesDeps}/share/xml", "#{TGT_DIR}/share"
- cp_r "#{ShoesDeps}/share/icons", "#{TGT_DIR}/share"
- else
- cp "#{ShoesDeps}share/glib-2.0/schemas/gschemas.compiled" ,
- "#{TGT_DIR}/share/glib-2.0/schemas"
- end
- sh "#{WINDRES} -I. shoes/appwin32.rc shoes/appwin32.o"
- cp_r "#{ShoesDeps}/etc", TGT_DIR
- mkdir_p "#{ShoesDeps}/lib"
- if APP['GTK'] == "gtk+-3.0"
- cp_r "#{ShoesDeps}/lib/gtk-3.0", "#{TGT_DIR}/lib" # shoes, exerb, ruby here
- else
- cp_r "#{ShoesDeps}/lib/gtk-2.0", "#{TGT_DIR}/lib" # shoes, exerb, ruby here
- end
-
- bindir = "#{GtkDeps}/bin"
- # some gdk-pixbuf versions may need to execute some gtk setup apps - sigh
- gdkcache = "#{TGT_DIR}/lib/gdk-pixbuf-2.0/2.10.0/"
- $stderr.puts "create cache #{gdkcache}"
- mkdir_p gdkcache
- Dir.chdir(gdkcache) do
- `gdk-pixbuf-query-loaders > loaders.cache`
- end
-
- #cp_r "#{bindir}/fc-cache.exe", TGT_DIR
- # newer versions of gkt3 changed the name of an exe- grrr.
- if File.exist?("#{bindir}/gtk-update-icon-cache-3.0.exe")
- cp "#{bindir}/gtk-update-icon-cache-3.0.exe",
- "#{TGT_DIR}/gtk-update-icon-cache.exe"
- else
- cp "#{bindir}/gtk-update-icon-cache.exe", TGT_DIR
- end
-
- # below for debugging purposes
- if ENV['GDB']
- cp "#{bindir}/fc-cat.exe", TGT_DIR
- cp "#{bindir}/fc-list.exe", TGT_DIR
- cp "#{bindir}/fc-match.exe", TGT_DIR
- cp "#{bindir}/fc-pattern.exe", TGT_DIR
- cp "#{bindir}/fc-query.exe", TGT_DIR
- cp "#{bindir}/fc-scan.exe", TGT_DIR
- cp "#{bindir}/fc-validate.exe", TGT_DIR
- end
- # disable MS Theme
- if !ENABLE_MS_THEME
- Dir.chdir("#{TGT_DIR}/share/themes/MS-Windows/gtk-2.0/") do
- mv 'gtkrc', 'disabled-gtkrc'
- end
- else
- # add our overrides to the MS-Windows theme
- # TODO: cp "platform/msw/gtkrc", "#{TGT_DIR}/etc/gtk-2.0/"
- end
-end
-
- # common_build is a misnomer. copies prebuilt extentions & gems
- def common_build
- copy_gems
- end
-
+ end
end
@@ -175,52 +30,65 @@ class MakeMinGW
extend Make
class << self
-
- def copy_deps_to_dist
- puts "copy_deps_to_dist dir=#{pwd}"
- unless ENV['GDB']
- sh "#{STRIP} #{TGT_DIR}/*.dll"
- Dir.glob("#{TGT_DIR}/lib/ruby/**/*.so").each {|lib| sh "#{STRIP} #{lib}"}
- end
- end
-
def setup_system_resources
cp APP['icons']['gtk'], "#{TGT_DIR}/static/app-icon.png"
end
-
- # name {TGT_DIR}/shoes
- def make_app(name)
- puts "make_app dir=#{pwd} arg=#{name}"
- bin = "#{name}.exe"
- binc = bin.gsub(/shoes\.exe/, 'cshoes.exe')
- puts "binc = #{binc}"
- rm_f name
- rm_f bin
- rm_f binc
- extra = ENV['GDB'] == 'profile' ? '-pg' : ''
- sh "#{CC} -o #{bin} bin/main.o shoes/appwin32.o -L#{TGT_DIR} -mwindows -lshoes #{LINUX_LIBS}"
- sh "#{STRIP} #{bin}" unless ENV['GDB']
- sh "#{CC} -o #{binc} bin/main.o shoes/appwin32.o -L#{TGT_DIR} #{extra} -lshoes #{LINUX_LIBS}"
- sh "#{STRIP} #{binc}" unless ENV['GDB']
- end
def make_so(name)
- puts "make_so dir=#{pwd} arg=#{name}"
+ $stderr.puts "make_so dir=#{pwd} arg=#{name}"
+ if OBJ.empty?
+ $stderr.puts "make_so call not needed" #TODO: bug in Rakefile
+ return
+ end
#ldflags = LINUX_LDFLAGS.sub! /INSTALL_NAME/, "-install_name @executable_path/lib#{SONAME}.#{DLEXT}"
sh "#{CC} -o #{name} #{OBJ.join(' ')} #{LINUX_LDFLAGS} #{LINUX_LIBS}"
end
+
+ def new_so (name)
+ $stderr.puts "new so: #{name}"
+ tgtd = File.dirname(name)
+ #tgts = name.split('/')
+ #tgtd = tgts[0]
+ #$stderr.puts "new_so: #{tgtd}"
+ objs = []
+ SubDirs.each do |f|
+ d = File.dirname(f)
+ objs = objs + FileList["#{d}/*.o"]
+ end
+ objs = objs + FileList["shoes/native/gtk/*.o"]
+ main_o = 'shoes/main.o'
+ objs = objs - [main_o]
+ sh "#{CC} -o #{tgtd}/libshoes.#{DLEXT} #{objs.join(' ')} #{LINUX_LDFLAGS} #{LINUX_LIBS}"
+ end
+
+ def new_link(name)
+ dpath = File.dirname(name)
+ fname = File.basename(name)
+ tgts = name.split('/')
+ tgtd = tgts[0]
+ bin = "#{dpath}/shoes.exe"
+ binc = "#{dpath}/cshoes.exe"
+ rm_f bin
+ rm_f binc
+ sh "#{WINDRES} -I. shoes/appwin32.rc shoes/appwin32.o"
+ tp = "#{TGT_DIR}/#{APP['Bld_Tmp']}"
+ missing = "-lgtk-3 -lgdk-3 -lfontconfig-1 -lpangocairo-1.0" # TODO: a bug in env.rb?
+ sh "#{CC} -o #{bin} #{tp}/main.o shoes/appwin32.o -L#{TGT_DIR} -lshoes -mwindows #{LINUX_LIBS} #{missing}"
+ sh "#{STRIP} #{bin}" unless APP['GDB']
+ sh "#{CC} -o #{binc} #{tp}/main.o shoes/appwin32.o -L#{TGT_DIR} -lshoes #{LINUX_LIBS} #{missing}"
+ sh "#{STRIP} #{binc}" unless APP['GDB']
+ end
# does nothing
def make_userinstall
end
def make_resource(t)
- puts "make resource"
end
- Object::APPVERSION = APP['VERSION']
- Object::RELEASE_DATE = Date.parse(APP['DATE']).strftime("%Y-%m-%d")
- def make_installer
+ Object::APPVERSION = APP['VERSION']
+ Object::RELEASE_DATE = Date.parse(APP['DATE']).strftime("%Y-%m-%d")
+ def make_installer_gtifw exe_path
def sh(*args); super; end
rm_rf "qtifw"
mkdir_p "qtifw"
@@ -232,15 +100,18 @@ def sh(*args); super; end
Dir.chdir("qtifw") do
rewrite File.join("config", "config-template.xml"), File.join("config", "config.xml")
- rewrite File.join("packages", "com.shoesrb.shoes", "meta", "package-template.xml"), File.join("packages", "com.shoesrb.shoes", "meta", "package.xml")
- sh "E:/Programmes/Qt/QtIFW/bin/binarycreator -c config/config.xml -p packages #{WINFNAME}.exe"
+ rewrite File.join("packages", "com.shoesrb.shoes", "meta", "package-template.xml"),
+ File.join("packages", "com.shoesrb.shoes", "meta", "package.xml")
+ #sh "E:/Programmes/Qt/QtIFW/bin/binarycreator -c config/config.xml -p packages #{WINFNAME}.exe"
+ sh "#{exe_path} -c config/config.xml -p packages #{WINFNAME}.exe"
end
- end
+ mv "qtifw/#{WINFNAME}.exe", "pkg/qtifw-#{WINFNAME}.exe"
+ #rm_rf "qtifw"
+ end
- def make_installer_nsis
- # assumes you have NSIS installed on your box in the system PATH
+ def make_installer_nsis exe_path
def sh(*args); super; end
- puts "make_installer #{`pwd`}"
+ puts "make_installer #{`pwd`.chomp} using #{exe_path}"
mkdir_p "pkg"
cp_r "VERSION.txt", "#{TGT_DIR}/VERSION.txt"
rm_rf "#{TGT_DIR}/nsis"
@@ -248,11 +119,25 @@ def sh(*args); super; end
cp APP['icons']['win32'], "#{TGT_DIR}/nsis/setup.ico"
rewrite "#{TGT_DIR}/nsis/base.nsi", "#{TGT_DIR}/nsis/#{WINFNAME}.nsi"
Dir.chdir("#{TGT_DIR}/nsis") do
- sh "\"c:\\Program Files (x86)\\NSIS\\Unicode\\makensis.exe\" #{WINFNAME}.nsi"
- #sh "\"c:\\Program Files (x86)\\NSIS\\makensis.exe\" #{WINFNAME}.nsi"
+ #sh "\"c:\\Program Files (x86)\\NSIS\\Unicode\\makensis.exe\" #{WINFNAME}.nsi"
+ sh "#{exe_path} #{WINFNAME}.nsi"
end
mv "#{TGT_DIR}/nsis/#{WINFNAME}.exe", "pkg/"
end
-
+
+ #Allow diffrent installers
+ def make_installer
+ if APP['INSTALLER'] == 'qtifw'
+ installer = "C:/Qt/QtIFW2.0.5/bin/binarycreator"
+ installer = APP['INSTALLER_LOC'] if APP['INSTALLER_LOC']
+ make_installer_gtifw installer
+ elsif APP['INSTALLER'] == 'nsis'
+ installer = "\"c:\\Program Files (x86)\\NSIS\\Unicode\\makensis.exe\""
+ installer = APP['INSTALLER_LOC'] if APP['INSTALLER_LOC']
+ make_installer_nsis installer
+ else
+ puts "No Installer defined"
+ end
+ end
end
end
diff --git a/make/win32/loose/dlls b/make/win32/none/dlls
similarity index 100%
rename from make/win32/loose/dlls
rename to make/win32/none/dlls
diff --git a/make/win32/none/env.rb b/make/win32/none/env.rb
new file mode 100644
index 00000000..bdf96ab8
--- /dev/null
+++ b/make/win32/none/env.rb
@@ -0,0 +1,4 @@
+# just enough allow a rake -T
+CC = "gcc"
+DLEXT = "dll"
+LINUX_CFLAGS = []
diff --git a/make/win32/none/tasks.rb b/make/win32/none/tasks.rb
new file mode 100644
index 00000000..64ba63a6
--- /dev/null
+++ b/make/win32/none/tasks.rb
@@ -0,0 +1,28 @@
+module Make
+ include FileUtils
+
+ def cc(t)
+ #sh "#{CC} -I. -c -o#{t.name} #{WINDOWS_CFLAGS} #{t.source}"
+ end
+
+ # Subs in special variables
+ def rewrite before, after, reg = /\#\{(\w+)\}/, reg2 = '\1'
+ File.open(after, 'w') do |a|
+ File.open(before) do |b|
+ b.each do |line|
+ a << line.gsub(reg) do
+ if reg2.include? '\1'
+ reg2.gsub(%r!\\1!, Object.const_get($1))
+ else
+ reg2
+ end
+ end
+ end
+ end
+ end
+ end
+
+end
+class MakeMinGW
+ extend Make
+end
diff --git a/make/win32/win7/env.rb b/make/win32/win7/env.rb
index 2d1814bf..5e2a16b0 100644
--- a/make/win32/win7/env.rb
+++ b/make/win32/win7/env.rb
@@ -1,18 +1,18 @@
-require "devkit"
+#require "devkit" unless ENV['MINGW_PREFIX']
cf =(ENV['ENV_CUSTOM'] || "win7-custom.yaml")
-gtk_version = '2'
+gtk_version = '3'
if File.exists? cf
custmz = YAML.load_file(cf)
ShoesDeps = custmz['Deps']
EXT_RUBY = custmz['Ruby']
ENABLE_MS_THEME = custmz['MS-Theme'] == true
- ENV['GDB'] = 'basic' if custmz['Debug'] == true
+ APP['GDB'] = 'basic' if custmz['Debug'] == true
APP['GEMLOC'] = custmz['Gemloc'] if custmz['Gemloc']
APP['EXTLOC'] = custmz['Extloc'] if custmz['Extloc']
APP['EXTLIST'] = custmz['Exts'] if custmz['Exts']
APP['GEMLIST'] = custmz['Gems'] if custmz['Gems']
APP['INCLGEMS'] = custmz['InclGems'] if custmz['InclGems']
- gtk_version = custmz['GtkVersion'].to_s if custmz['GtkVersion']
+ #gtk_version = custmz['GtkVersion'].to_s if custmz['GtkVersion']
APP['VIDEO'] = true
else
# define where your deps are
@@ -26,30 +26,12 @@
SHOES_TGT_ARCH = 'i386-mingw32'
APP['GTK'] = "gtk+-#{gtk_version}.0"
#ENV['GDB'] = "basic" # 'basic' = keep symbols, or 'profile'
-WINVERSION = "#{APP['VERSION']}-#{APP['GTK']=='gtk+-3.0' ? 'gtk3' : 'gtk2'}-w32"
+WINVERSION = "#{APP['VERSION']}-gtk3-w32"
WINFNAME = "#{APPNAME}-#{WINVERSION}"
WIN32_CFLAGS = []
WIN32_LDFLAGS = []
WIN32_LIBS = []
RUBY_HTTP = true
-gtk_extra_list = []
-if APP['GTK'] == "gtk+-3.0"
- gtk_extra_list = %w(shoes/native/gtkfixedalt.c shoes/native/gtkentryalt.c
- shoes/native/gtkcomboboxtextalt.c shoes/native/gtkbuttonalt.c
- shoes/native/gtkscrolledwindowalt.c shoes/native/gtkprogressbaralt.c )
-end
-if RUBY_HTTP
- file_list = %w{shoes/native/gtk.c shoes/http/rbload.c} + gtk_extra_list + ["shoes/*.c"] +
- ["shoes/plot/*.c"]
-else
- file_list = %w{shoes/native/gtk.c shoes/http/winhttp.c shoes/http/windownload.c} + ["shoes/*.c"]
-end
-file_list << "shoes/video/video.c" if APP['VIDEO']
-SRC = FileList[*file_list]
-
-OBJ = SRC.map do |x|
- x.gsub(/\.\w+$/, '.o')
-end
DLEXT = "dll"
ADD_DLL = []
@@ -61,7 +43,7 @@
WINDRES = "windres"
PKG_CONFIG = "#{ShoesDeps}/bin/pkg-config" # the one from glib
-if ENV['DEBUG'] || ENV['GDB']
+if APP['GDB']
WIN32_CFLAGS << "-g3 -O0"
else
WIN32_CFLAGS << "-O -Wall"
@@ -77,10 +59,9 @@
RUBY_LDFLAGS = "-L#{RbConfig::CONFIG["bindir"]} #{RbConfig::CONFIG["LIBRUBYARG"]} "
RUBY_LDFLAGS << "-Wl,-export-all-symbols "
-#RUBY_LDFLAGS << "-L#{EXT_RUBY}/lib -lmsvcrt-ruby210 "
WIN32_CFLAGS << "-DSHOES_GTK -DSHOES_GTK_WIN32 -DRUBY_HTTP -DVIDEO"
-WIN32_CFLAGS << "-DGTK3 " unless APP['GTK'] == 'gtk+-2.0'
+WIN32_CFLAGS << "-DGTK3 "
WIN32_CFLAGS << "-Wno-unused-but-set-variable"
WIN32_CFLAGS << "-D__MINGW_USE_VC2005_COMPAT -DXMD_H -D_WIN32_IE=0x0500 -D_WIN32_WINNT=0x0501 -DWINVER=0x0501 -DCOBJMACROS"
WIN32_CFLAGS << GTK_CFLAGS
@@ -90,10 +71,7 @@
RbConfig::CONFIG.select { |k, _| k[/hdrdir/] }.each_key do |v|
WIN32_CFLAGS << "-I#{RbConfig::CONFIG[v]}"
end
-#["jpeg-6b-4-lib", "giflib-4.1.4-1-lib"].each { |n|
-# WIN32_CFLAGS << "-Isandbox/#{n}/include"
-# WIN32_LDFLAGS << "-Lsandbox/#{n}/lib"
-#}
+
WIN32_CFLAGS << "-Ishoes"
WIN32_LDFLAGS << "-lshell32 -lkernel32 -luser32 -lgdi32 -lcomdlg32 -lcomctl32"
@@ -105,9 +83,6 @@
WIN32_LDFLAGS << PANGO_LDFLAGS
WIN32_LDFLAGS << RUBY_LDFLAGS
-#WIN32_LIBS = WIN32_LDFLAGS
-#WIN32_LIBS << "-L#{ENV['RI_DEVKIT']}/mingw/bin".gsub('\\','/').gsub(/^\//,'//')
-#WIN32_LIBS << "-lgif -ljpeg -Wl,-export-all-symbols -lmsvcrt-ruby210 -lcairo -lpango-1.0 -lgobject-2.0 -lgmodule-2.0 -lgthread-2.0 -lglib-2.0 -lintl "
WIN32_LIBS << RUBY_LDFLAGS
WIN32_LIBS << CAIRO_LDFLAGS
WIN32_LIBS << PANGO_LDFLAGS
@@ -127,9 +102,7 @@
rubydll = "#{EXT_RUBY}/bin"
devdll = "#{ENV['RI_DEVKIT']}/mingw/bin"
SOLOCS = {
-# 'ruby' => "#{EXT_RUBY}/bin/msvcrt-ruby210.dll",
- 'ruby' => "#{EXT_RUBY}/bin/msvcrt-ruby220.dll",
- #'gif' => "#{bindll}/libgif-4.dll",
+ 'ruby' => "#{EXT_RUBY}/bin/msvcrt-ruby230.dll",
'gif' => "#{bindll}/libgif-7.dll",
'jpeg' => "#{bindll}/libjpeg-9.dll",
'libyaml' => "#{bindll}/libyaml-0-2.dll",
@@ -140,70 +113,38 @@
'sqlite' => "#{bindll}/sqlite3.dll"
}
-if APP['GTK'] == 'gtk+-3.0'
- SOLOCS.merge!(
- {
- 'atk' => "#{bindll}/libatk-1.0-0.dll",
- 'cairo' => "#{bindll}/libcairo-2.dll",
- 'cairo-gobj' => "#{bindll}/libcairo-gobject-2.dll",
- 'ffi' => "#{bindll}/libffi-6.dll",
- 'fontconfig' => "#{bindll}/libfontconfig-1.dll",
- 'freetype' => "#{bindll}/libfreetype-6.dll",
- 'gdkpixbuf' => "#{bindll}/libgdk_pixbuf-2.0-0.dll",
- 'gdk3' => "#{bindll}/libgdk-3-0.dll",
- 'gio' => "#{bindll}/libgio-2.0-0.dll",
- 'glib' => "#{bindll}/libglib-2.0-0.dll",
- 'gmodule' => "#{bindll}/libgmodule-2.0-0.dll",
- 'gobject' => "#{bindll}/libgobject-2.0-0.dll",
- 'gtk2' => "#{bindll}/libgtk-win32-2.0-0.dll", # something is wrong
- 'gtk3' => "#{bindll}/libgtk-3-0.dll",
- 'pixman' => "#{bindll}/libpixman-1-0.dll",
- 'intl8' => "#{bindll}/libintl-8.dll",
- 'pango' => "#{bindll}/libpango-1.0-0.dll",
- 'pangocairo' => "#{bindll}/libpangocairo-1.0-0.dll",
- 'pangoft' => "#{bindll}/libpangoft2-1.0-0.dll",
- 'pango32' => "#{bindll}/libpangowin32-1.0-0.dll",
- 'pixbuf' => "#{bindll}/libgdk_pixbuf-2.0-0.dll",
- 'harfbuzz' => "#{bindll}/libharfbuzz-0.dll",
- 'png16' => "#{bindll}/libpng16-16.dll",
- 'croco' => "#{bindll}/libcroco-0.6-3.dll",
- 'rsvg' => "#{bindll}/librsvg-2-2.dll",
- 'xml2' => "#{bindll}/libxml2-2.dll",
- 'thread' => "#{bindll}/libgthread-2.0-0.dll",
- 'zlib1' => "#{bindll}/zlib1.dll",
- 'pthread' => "#{devdll}/libwinpthread-1.dll",
- 'sjlj' => "#{devdll}/libgcc_s_sjlj-1.dll"
- }
- )
-end
-if APP['GTK'] == 'gtk+-2.0'
- SOLOCS.merge!(
+SOLOCS.merge!(
{
'atk' => "#{bindll}/libatk-1.0-0.dll",
'cairo' => "#{bindll}/libcairo-2.dll",
'cairo-gobj' => "#{bindll}/libcairo-gobject-2.dll",
+ 'ffi' => "#{bindll}/libffi-6.dll",
'fontconfig' => "#{bindll}/libfontconfig-1.dll",
'freetype' => "#{bindll}/libfreetype-6.dll",
'gdkpixbuf' => "#{bindll}/libgdk_pixbuf-2.0-0.dll",
- 'gdk2' => "#{bindll}/libgdk-win32-2.0-0.dll",
+ 'gdk3' => "#{bindll}/libgdk-3-0.dll",
'gio' => "#{bindll}/libgio-2.0-0.dll",
'glib' => "#{bindll}/libglib-2.0-0.dll",
'gmodule' => "#{bindll}/libgmodule-2.0-0.dll",
'gobject' => "#{bindll}/libgobject-2.0-0.dll",
- 'gtk2' => "#{bindll}/libgtk-win32-2.0-0.dll",
- 'intl8' => "#{bindll}/libintl-8.dll",
+ 'gtk2' => "#{bindll}/libgtk-win32-2.0-0.dll", # something is wrong
+ 'gtk3' => "#{bindll}/libgtk-3-0.dll",
+ 'pixman' => "#{bindll}/libpixman-1-0.dll",
+ 'intl8' => "#{bindll}/libintl-8.dll",
'pango' => "#{bindll}/libpango-1.0-0.dll",
'pangocairo' => "#{bindll}/libpangocairo-1.0-0.dll",
'pangoft' => "#{bindll}/libpangoft2-1.0-0.dll",
'pango32' => "#{bindll}/libpangowin32-1.0-0.dll",
+ 'pixbuf' => "#{bindll}/libgdk_pixbuf-2.0-0.dll",
'harfbuzz' => "#{bindll}/libharfbuzz-0.dll",
- 'pixman' => "#{bindll}/libpixman-1-0.dll",
'png16' => "#{bindll}/libpng16-16.dll",
+ 'croco' => "#{bindll}/libcroco-0.6-3.dll",
+ 'rsvg' => "#{bindll}/librsvg-2-2.dll",
'xml2' => "#{bindll}/libxml2-2.dll",
'thread' => "#{bindll}/libgthread-2.0-0.dll",
'zlib1' => "#{bindll}/zlib1.dll",
'pthread' => "#{devdll}/libwinpthread-1.dll",
- 'sjlj' => "#{devdll}/libgcc_s_sjlj-1.dll"
+ 'sjlj' => "#{devdll}/libgcc_s_sjlj-1.dll"
}
)
-end
+
diff --git a/make/win32/win7/setup.rb b/make/win32/win7/setup.rb
new file mode 100644
index 00000000..75e0bd33
--- /dev/null
+++ b/make/win32/win7/setup.rb
@@ -0,0 +1,66 @@
+# This is a big gulp of copying.
+require 'fileutils'
+module Make
+ include FileUtils
+
+ # Windows compile. Copy the static stuff, Copy the ruby libs
+ # Then copy the deps.
+ def static_setup (so_list)
+ $stderr.puts "setup: dir=#{Dir.pwd}"
+ rbvt = RUBY_V
+ rbvm = RUBY_V[/^\d+\.\d+/]
+ # remove leftovers from previous rake.
+ rm_rf "#{TGT_DIR}/lib"
+ rm_rf "#{TGT_DIR}/etc"
+ rm_rf "#{TGT_DIR}/share"
+ rm_rf "#{TGT_DIR}/conf.d"
+ mkdir_p "#{TGT_DIR}/fonts"
+ cp_r "fonts", "#{TGT_DIR}/fonts"
+ mkdir_p "#{TGT_DIR}/lib"
+ cp "lib/shoes.rb", "#{TGT_DIR}/lib"
+ cp_r "lib/shoes", "#{TGT_DIR}/lib"
+ cp_r "lib/exerb", "#{TGT_DIR}/lib"
+ cp_r "samples", "#{TGT_DIR}/samples"
+ cp_r "static", "#{TGT_DIR}/static"
+ cp "README.md", "#{TGT_DIR}/README.txt"
+ cp "CHANGELOG", "#{TGT_DIR}/CHANGELOG.txt"
+ cp "COPYING", "#{TGT_DIR}/COPYING.txt"
+ #mkdir_p "#{TGT_DIR}/lib"
+ cp_r "#{EXT_RUBY}/lib/ruby", "#{TGT_DIR}/lib", remove_destination: true
+ # copy include files
+ mkdir_p "#{TGT_DIR}/lib/ruby/include/ruby-#{rbvt}"
+ cp_r "#{EXT_RUBY}/include/ruby-#{rbvt}/", "#{TGT_DIR}/lib/ruby/include"
+ so_list.each_value do |path|
+ cp "#{path}", "#{TGT_DIR}"
+ end
+ # copy/setup etc/share
+ mkdir_p "#{TGT_DIR}/share/glib-2.0/schemas"
+ cp "#{ShoesDeps}/share/glib-2.0/schemas/gschemas.compiled" ,
+ "#{TGT_DIR}/share/glib-2.0/schemas"
+ cp_r "#{ShoesDeps}/share/fontconfig", "#{TGT_DIR}/share"
+ cp_r "#{ShoesDeps}/share/themes", "#{TGT_DIR}/share"
+ cp_r "#{ShoesDeps}/share/xml", "#{TGT_DIR}/share"
+ cp_r "#{ShoesDeps}/share/icons", "#{TGT_DIR}/share"
+ sh "#{WINDRES} -I. shoes/appwin32.rc shoes/appwin32.o"
+ cp_r "#{ShoesDeps}/etc", TGT_DIR
+ if ENABLE_MS_THEME
+ ini_path = "#{TGT_DIR}/etc/gtk-3.0"
+ mkdir_p ini_path
+ File.open "#{ini_path}/settings.ini", mode: 'w' do |f|
+ f.write "[Settings]\n"
+ f.write "#gtk-theme-name=win32\n"
+ end
+ end
+ mkdir_p "#{ShoesDeps}/lib"
+ cp_r "#{ShoesDeps}/lib/gtk-3.0", "#{TGT_DIR}/lib"
+ bindir = "#{ShoesDeps}/bin"
+ if File.exist?("#{bindir}/gtk-update-icon-cache-3.0.exe")
+ cp "#{bindir}/gtk-update-icon-cache-3.0.exe",
+ "#{TGT_DIR}/gtk-update-icon-cache.exe"
+ else
+ cp "#{bindir}/gtk-update-icon-cache.exe", TGT_DIR
+ end
+ cp APP['icons']['win32'], "shoes/appwin32.ico"
+ end
+end
+
diff --git a/make/win32/win7/tasks.rb b/make/win32/win7/tasks.rb
index c13fb3a5..9bd5dfb9 100644
--- a/make/win32/win7/tasks.rb
+++ b/make/win32/win7/tasks.rb
@@ -1,32 +1,6 @@
module Make
include FileUtils
-
- def copy_files_to_dist
- puts "copy_files_to_dist dir=#{pwd}"
- if ENV['APP']
- if APP['clone']
- sh APP['clone'].gsub(/^git /, "#{GIT} --git-dir=#{ENV['APP']}/.git ")
- else
- cp_r ENV['APP'], "#{TGT_DIR}/app"
- end
- if APP['ignore']
- APP['ignore'].each do |nn|
- rm_rf "dist/app/#{nn}"
- end
- end
- end
-
- cp_r "fonts", "#{TGT_DIR}/fonts"
- cp "lib/shoes.rb", "#{TGT_DIR}/lib"
- cp_r "lib/shoes", "#{TGT_DIR}/lib"
- cp_r "lib/exerb", "#{TGT_DIR}/lib"
- cp_r "samples", "#{TGT_DIR}/samples"
- cp_r "static", "#{TGT_DIR}/static"
- cp "README.md", "#{TGT_DIR}/README.txt"
- cp "CHANGELOG", "#{TGT_DIR}/CHANGELOG.txt"
- cp "COPYING", "#{TGT_DIR}/COPYING.txt"
- end
-
+
def cc(t)
sh "#{CC} -I. -c -o#{t.name} #{WINDOWS_CFLAGS} #{t.source}"
end
@@ -48,111 +22,8 @@ def rewrite before, after, reg = /\#\{(\w+)\}/, reg2 = '\1'
end
end
- def copy_files glob, dir
- FileList[glob].each { |f| cp_r f, dir }
- end
-
- # Copy the rubyinstaller libs - sigh - don't copy all of the gems.
- # Then copy the deps.
- def pre_build
- puts "pre_build dir=#{`pwd`}"
- rbvt = RUBY_V
- rbvm = RUBY_V[/^\d+\.\d+/]
- # remove leftovers from previous rake.
- rm_rf "#{TGT_DIR}/lib"
- rm_rf "#{TGT_DIR}/etc"
- rm_rf "#{TGT_DIR}/share"
- rm_rf "#{TGT_DIR}/conf.d"
- mkdir_p "#{TGT_DIR}/lib/ruby"
- cp_r "#{EXT_RUBY}/lib/ruby/#{rbvt}", "#{TGT_DIR}/lib/ruby"
- # copy include files
- mkdir_p "#{TGT_DIR}/lib/ruby/include/ruby-#{rbvt}"
- cp_r "#{EXT_RUBY}/include/ruby-#{rbvt}/", "#{TGT_DIR}/lib/ruby/include"
- # copy site_ruby (gems updates)
- cp_r "#{EXT_RUBY}/lib/ruby/site_ruby", "#{TGT_DIR}/lib/ruby"
- # copy vendor_ruby
- cp_r "#{EXT_RUBY}/lib/ruby/vendor_ruby", "#{TGT_DIR}/lib/ruby"
- # make empty gem libs
- mkdir_p "#{TGT_DIR}/lib/ruby/gems/#{rbvt}"
- ['build_info', 'cache', 'doc', 'extentions', 'gems', 'specifications' ].each do
- |d| mkdir_p "#{TGT_DIR}/lib/ruby/gems/#{rbvt}/#{d}"
- end
- # copy default gemspecs
- cp_r "#{EXT_RUBY}/lib/ruby/gems/#{rbvt}/specifications/default",
- "#{TGT_DIR}/lib/ruby/gems/#{rbvt}/specifications"
- # from default gemspecs , copy what's in gems (rake, rdoc, test-unit)
- # other defaults like bigdecimal are inside ruby. Grr.
- specs = Dir.glob("#{EXT_RUBY}/lib/ruby/gems/#{rbvt}/specifications/default/*.gemspec")
- specs.each do |spec|
- dirname = File.basename(spec, ".gemspec")
- next unless File.directory?("#{EXT_RUBY}/lib/ruby/gems/#{rbvt}/gems/#{dirname}")
- #puts "Copy #{dirname}"
- cp_r "#{EXT_RUBY}/lib/ruby/gems/#{rbvt}/gems/#{dirname}", "#{TGT_DIR}/lib/ruby/gems/#{rbvt}/gems"
- end
- # copy the deplibs (see env.rb)
- SOLOCS.each_value do |path|
- cp "#{path}", "#{TGT_DIR}"
- end
- # setup GTK stuff
- mkdir_p "#{TGT_DIR}/share/glib-2.0/schemas"
- if APP['GTK'] == "gtk+-2.0"
- cp_r"#{ShoesDeps}/share/glib-2.0/schemas/gschema.dtd",
- "#{TGT_DIR}/share/glib-2.0/schemas"
- cp_r "#{ShoesDeps}/share/fontconfig", "#{TGT_DIR}/share"
- cp_r "#{ShoesDeps}/share/themes", "#{TGT_DIR}/share"
- cp_r "#{ShoesDeps}/share/xml", "#{TGT_DIR}/share"
- cp_r "#{ShoesDeps}/share/icons", "#{TGT_DIR}/share"
- elsif APP['GTK'] == "gtk+-3.0"
- cp "#{ShoesDeps}/share/glib-2.0/schemas/gschemas.compiled" ,
- "#{TGT_DIR}/share/glib-2.0/schemas"
- cp_r "#{ShoesDeps}/share/fontconfig", "#{TGT_DIR}/share"
- cp_r "#{ShoesDeps}/share/themes", "#{TGT_DIR}/share"
- cp_r "#{ShoesDeps}/share/xml", "#{TGT_DIR}/share"
- cp_r "#{ShoesDeps}/share/icons", "#{TGT_DIR}/share"
- else
- cp "#{ShoesDeps}share/glib-2.0/schemas/gschemas.compiled" ,
- "#{TGT_DIR}/share/glib-2.0/schemas"
- end
- sh "#{WINDRES} -I. shoes/appwin32.rc shoes/appwin32.o"
- cp_r "#{ShoesDeps}/etc", TGT_DIR
- mkdir_p "#{ShoesDeps}/lib"
- if APP['GTK'] == "gtk+-3.0"
- cp_r "#{ShoesDeps}/lib/gtk-3.0", "#{TGT_DIR}/lib" # shoes, exerb, ruby here
- else
- cp_r "#{ShoesDeps}/lib/gtk-2.0", "#{TGT_DIR}/lib" # shoes, exerb, ruby here
- end
- bindir = "#{ShoesDeps}/bin"
- #cp_r "#{bindir}/fc-cache.exe", TGT_DIR
- cp_r "#{bindir}/gtk-update-icon-cache.exe", TGT_DIR
- # below for debugging purposes
- if ENV['GDB']
- cp "#{bindir}/fc-cat.exe", TGT_DIR
- cp "#{bindir}/fc-list.exe", TGT_DIR
- cp "#{bindir}/fc-match.exe", TGT_DIR
- cp "#{bindir}/fc-pattern.exe", TGT_DIR
- cp "#{bindir}/fc-query.exe", TGT_DIR
- cp "#{bindir}/fc-scan.exe", TGT_DIR
- cp "#{bindir}/fc-validate.exe", TGT_DIR
- end
- # disable MS Theme
- if !ENABLE_MS_THEME
- Dir.chdir("#{TGT_DIR}/share/themes/MS-Windows/gtk-2.0/") do
- mv 'gtkrc', 'disabled-gtkrc'
- end
- else
- # add our overrides to the MS-Windows theme
- cp "platform/msw/gtkrc", "#{TGT_DIR}/etc/gtk-2.0/"
- end
-end
-
- # common_build is a misnomer. copies prebuilt extentions & gems
- def common_build
- copy_gems
- end
-
end
-
include FileUtils
class MakeMinGW
@@ -162,8 +33,8 @@ class << self
def copy_deps_to_dist
puts "copy_deps_to_dist dir=#{pwd}"
- unless ENV['GDB']
- sh "#{STRIP} #{TGT_DIR}/*.dll"
+ unless APP['GDB']
+ sh "#{STRIP} #{TGT_DIR}/*.dll"
Dir.glob("#{TGT_DIR}/lib/ruby/**/*.so").each {|lib| sh "#{STRIP} #{lib}"}
end
end
@@ -171,42 +42,56 @@ def copy_deps_to_dist
def setup_system_resources
cp APP['icons']['gtk'], "#{TGT_DIR}/static/app-icon.png"
end
-
- # name {TGT_DIR}/shoes
- def make_app(name)
- puts "make_app dir=#{pwd} arg=#{name}"
- bin = "#{name}.exe"
- binc = bin.gsub(/shoes\.exe/, 'cshoes.exe')
- puts "binc = #{binc}"
- rm_f name
+
+ # this is called from the file task based new_builder
+ def new_so (name)
+ $stderr.puts "new so: #{name}"
+ #tgts = name.split('/')
+ #tgtd = tgts[0]
+ tgtd = File.dirname(name)
+ objs = []
+ SubDirs.each do |f|
+ d = File.dirname(f)
+ objs = objs + FileList["#{d}/*.o"]
+ end
+ # TODO fix: gtk - needs to dig deeper vs osx
+ objs = objs + FileList["shoes/native/gtk/*.o"]
+ main_o = 'shoes/main.o'
+ objs = objs - [main_o]
+ sh "#{CC} -o #{tgtd}/libshoes.#{DLEXT} #{objs.join(' ')} #{LINUX_LDFLAGS} #{LINUX_LIBS}"
+ end
+
+ def new_link(name)
+ $stderr.puts "new_link: #{name}"
+ dpath = File.dirname(name)
+ fname = File.basename(name)
+ tgts = name.split('/')
+ tgtd = tgts[0]
+ bin = "#{dpath}/shoes.exe"
+ binc = "#{dpath}/cshoes.exe"
rm_f bin
rm_f binc
- extra = ENV['GDB'] == 'profile' ? '-pg' : ''
- sh "#{CC} -o #{bin} bin/main.o shoes/appwin32.o -L#{TGT_DIR} -mwindows -lshoes #{LINUX_LIBS}"
- sh "#{STRIP} #{bin}" unless ENV['GDB']
- sh "#{CC} -o #{binc} bin/main.o shoes/appwin32.o -L#{TGT_DIR} #{extra} -lshoes #{LINUX_LIBS}"
- sh "#{STRIP} #{binc}" unless ENV['GDB']
- end
-
- def make_so(name)
- puts "make_so dir=#{pwd} arg=#{name}"
- #ldflags = LINUX_LDFLAGS.sub! /INSTALL_NAME/, "-install_name @executable_path/lib#{SONAME}.#{DLEXT}"
- sh "#{CC} -o #{name} #{OBJ.join(' ')} #{LINUX_LDFLAGS} #{LINUX_LIBS}"
- end
+ tp = "#{TGT_DIR}/#{APP['Bld_Tmp']}"
+ sh "#{WINDRES} -I. shoes/appwin32.rc shoes/appwin32.o"
+ missing = "-lgtk-3 -lgdk-3 -lfontconfig-1 -lpangocairo-1.0" # TODO: This is a bug in env.rb for
+ sh "#{CC} -o #{bin} #{tp}/main.o shoes/appwin32.o -L#{TGT_DIR} -lshoes -mwindows #{LINUX_LIBS} #{missing}"
+ sh "#{STRIP} #{bin}" unless APP['GDB']
+ sh "#{CC} -o #{binc} #{tp}/main.o shoes/appwin32.o -L#{TGT_DIR} -lshoes #{LINUX_LIBS} #{missing}"
+ sh "#{STRIP} #{binc}" unless APP['GDB']
+ end
# does nothing
def make_userinstall
end
- def make_resource(t)
- puts "make resource"
- end
-
def make_installer
# assumes you have NSIS installed on your box in the system PATH
def sh(*args); super; end
- puts "make_installer #{`pwd`}"
+ $stderr.puts "make_installer #{`pwd`} moving tmp/"
+ tp = "#{TGT_DIR}/#{APP['Bld_Tmp']}"
+ mp = "#{TGT_DIR}-#{APP['Bld_Tmp']}"
+ mv tp, mp
mkdir_p "pkg"
cp_r "VERSION.txt", "#{TGT_DIR}/VERSION.txt"
rm_rf "#{TGT_DIR}/nsis"
@@ -214,11 +99,11 @@ def sh(*args); super; end
cp APP['icons']['win32'], "#{TGT_DIR}/nsis/setup.ico"
rewrite "#{TGT_DIR}/nsis/base.nsi", "#{TGT_DIR}/nsis/#{WINFNAME}.nsi"
Dir.chdir("#{TGT_DIR}/nsis") do
- sh "\"c:\\Program Files (x86)\\NSIS\\Unicode\\makensis.exe\" #{WINFNAME}.nsi"
- #sh "\"c:\\Program Files (x86)\\NSIS\\makensis.exe\" #{WINFNAME}.nsi"
+ sh "\"c:\\Program Files (x86)\\NSIS\\Unicode\\makensis.exe\" #{WINFNAME}.nsi"
end
mv "#{TGT_DIR}/nsis/#{WINFNAME}.exe", "pkg/"
+ $stderr.puts "restore tmp/"
+ mv mp, tp
end
-
end
end
diff --git a/platform/mac/Info.plist b/platform/mac/Info.plist
index e11c8c0e..82617bf2 100644
--- a/platform/mac/Info.plist
+++ b/platform/mac/Info.plist
@@ -3,7 +3,7 @@
CFBundleGetInfoString
- #{APPNAME} #{APP['MAJOR']}.#{APP['MINOR']}
+ #{APPNAME} #{APP['plist_version_string']}
CFBundleExecutable
#{NAME}-launch
CFBundleIdentifier
@@ -13,16 +13,19 @@
CFBundleIconFile
App.icns
CFBundleShortVersionString
- #{APP['MAJOR']}.#{APP['MINOR']}
+ #{APP['plist_version_string']}
CFBundleInfoDictionaryVersion
6.0
CFBundlePackageType
APPL
IFMajorVersion
0
+ NSHighResolutionCapable
+ true
IFMinorVersion
1
- CFBundleDocumentTypes
+ NSHighResolutionCapable
+ true CFBundleDocumentTypes
CFBundleTypeExtensions
diff --git a/platform/msw/base.nsi b/platform/msw/base.nsi
index 815de042..6b487f99 100755
--- a/platform/msw/base.nsi
+++ b/platform/msw/base.nsi
@@ -86,6 +86,8 @@ Section "MainSection" SEC01
${EnvVarUpdate} $0 "PATH" "A" HKLM $INSTDIR
${registerExtension} "$INSTDIR\${SHOES_NAME}.exe" ".shy" "Shoes Application"
+ DetailPrint "Building Incon cache, this may take a while..."
+ ExecWait '"$INSTDIR\gtk-update-icon-cache.exe" "$INSTDIR\share\icons\Adwaita"'
SectionEnd
Section -AdditionalIcons
diff --git a/platform/nix/shoes.launch b/platform/nix/shoes.launch
index 132a3f7e..747670a6 100755
--- a/platform/nix/shoes.launch
+++ b/platform/nix/shoes.launch
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/usr/bin/env bash
REALPATH=`readlink -f $0`
@@ -18,3 +18,4 @@ if [ `pwd | awk '{ sub(/[0-9]+/, ""); print }'` = "/tmp/selfgz" ]; then
#ln -s libruby.so.2.1 libruby.so.2.1.0
cd "$OLDPWD"
fi
+export NO_AT_BRIDGE=1
diff --git a/platform/skel.rb b/platform/skel.rb
deleted file mode 100644
index 0c286e84..00000000
--- a/platform/skel.rb
+++ /dev/null
@@ -1,27 +0,0 @@
-def skel_replace(line)
- line.gsub! /\s+%DEFAULTS%/ do
- if APPARGS
- args = APPARGS.split(/\s+/)
- %{
- char *default_argv[] = {argv[0], #{args.inspect[1..-2]}};
- argv = default_argv;
- argc = #{args.length + 1};
- }
- end
- end
- line
-end
-
-# preprocess .skel
-task :build_skel do |t|
- Dir["bin/*.skel"].each do |src|
- name = src.gsub(/\.skel$/, '.c')
- File.open(src) do |skel|
- File.open(name, 'w') do |c|
- skel.each_line do |line|
- c << skel_replace(line)
- end
- end
- end
- end
-end
diff --git a/samples/expert/expert-colours.rb b/samples/expert/colours.rb
similarity index 100%
rename from samples/expert/expert-colours.rb
rename to samples/expert/colours.rb
diff --git a/samples/expert/expert-curve-animation.rb b/samples/expert/curve-animation.rb
similarity index 100%
rename from samples/expert/expert-curve-animation.rb
rename to samples/expert/curve-animation.rb
diff --git a/samples/expert/expert-curve-control-points.rb b/samples/expert/curve-control-point.rb
similarity index 100%
rename from samples/expert/expert-curve-control-points.rb
rename to samples/expert/curve-control-point.rb
diff --git a/samples/expert/expert-custom-list-box.rb b/samples/expert/custom-list-box.rb
similarity index 100%
rename from samples/expert/expert-custom-list-box.rb
rename to samples/expert/custom-list-box.rb
diff --git a/samples/expert/expert-definr.rb b/samples/expert/definr.rb
similarity index 100%
rename from samples/expert/expert-definr.rb
rename to samples/expert/definr.rb
diff --git a/samples/expert/expert-graph.rb b/samples/expert/expert-graph.rb
deleted file mode 100644
index c1895186..00000000
--- a/samples/expert/expert-graph.rb
+++ /dev/null
@@ -1,90 +0,0 @@
-# expert-graph.rb? draw timeseries data - using Shoes::Widget
-class Series
- attr_accessor :size, :minv, :maxv, :ary
-
- def initialize(opts = {})
- if opts[:values]
- @ary = opts[:values]
- @size = @ary.size
- else
- raise "must specifiy an :values array"
- end
- @size = opts[:num_obs] ? opts[:num_obs] : @ary.size
- @maxv = opts[:maxv] ? opts[:maxv] : @ary.max
- @minv = opts[:minv] ? opts[:minv] : @ary.min
- end
-
- def [] (idx)
- return @ary[idx]
- end
-
-end
-class Graph < Shoes::Widget
- @@series_collection = Array.new
- attr_accessor :width, :height, :canvas, :series_collection
-
- def initialize(opts = {})
- @widget_w = opts[:width] || 200
- @widget_h = opts[:height] || 200
- self.width = @widget_w
- self.height = @widget_h
- @canvas = flow height: @widget_h, width: @widget_w do
- background white
- end
- end
-
-
- def draw_all_series
- @@series_collection.each do |ser|
- @canvas.stroke blue
- #assume top left is 0,0 bottom right is 800,500
- wid = @widget_w
- hgt = @widget_h
- vscale = hgt / (ser.maxv - ser.minv)
- hscale = wid / ser.size
- oldx = 0
- oldy = 0
- (0..ser.size-1).each do |i|
- v = ser[i]
- x = (i * hscale).round.to_i
- y = (hgt - ((v - ser.minv) * vscale).round).to_i
- if i == 0
- @canvas.line(x, y, x, y)
- else
- @canvas.line(oldx, oldy, x, y)
- end
- oldx = x
- oldy = y
- end
- end
- end
-
- def add_series(series)
- @@series_collection << series
- draw_all_series
- end
-
- def remove_series(series)
- end
-end
-
-Shoes.app width: 620, height: 610 do
- @values1 = [24, 22, 10, 15, 12, 8, 22]
- @x_axis1 = ['a','b','c','d','e','f','g']
- stack do
- para "Just Art Graph Demo"
- widget_width = 600
- widget_height = 400
- @grf = graph width: widget_width, height: widget_height
- tseries = Series.new num_obs: @values1.size, values: @values1, xobs: @x_axis1,
- name: "foobar", minv: 6, maxv: 26 , long_name: "foobar values"
- @grf.add_series(tseries)
- flow do
- button "quit" do Shoes.quit end
- button "redraw" do
- @grf.draw_series(tseries)
- end
- end
- end
-end
-
diff --git a/samples/expert/expert-funnies.rb b/samples/expert/funnies.rb
similarity index 100%
rename from samples/expert/expert-funnies.rb
rename to samples/expert/funnies.rb
diff --git a/samples/expert/expert-minesweeper.rb b/samples/expert/minesweeper.rb
similarity index 100%
rename from samples/expert/expert-minesweeper.rb
rename to samples/expert/minesweeper.rb
diff --git a/samples/expert/expert-othello.rb b/samples/expert/othello.rb
similarity index 100%
rename from samples/expert/expert-othello.rb
rename to samples/expert/othello.rb
diff --git a/samples/expert/expert-pong.rb b/samples/expert/pong.rb
similarity index 100%
rename from samples/expert/expert-pong.rb
rename to samples/expert/pong.rb
diff --git a/samples/expert/expert-tankspank.rb b/samples/expert/tankspank.rb
similarity index 100%
rename from samples/expert/expert-tankspank.rb
rename to samples/expert/tankspank.rb
diff --git a/samples/expert/expert-tooltips.rb b/samples/expert/tooltips.rb
similarity index 100%
rename from samples/expert/expert-tooltips.rb
rename to samples/expert/tooltips.rb
diff --git a/samples/expert/expert-url.rb b/samples/expert/url.rb
similarity index 100%
rename from samples/expert/expert-url.rb
rename to samples/expert/url.rb
diff --git a/samples/expert/expert-video-player.rb b/samples/expert/video-player.rb
similarity index 100%
rename from samples/expert/expert-video-player.rb
rename to samples/expert/video-player.rb
diff --git a/samples/class-book.rb b/samples/good/_why-stories.rb
similarity index 88%
rename from samples/class-book.rb
rename to samples/good/_why-stories.rb
index 54b56ec7..16f888ec 100644
--- a/samples/class-book.rb
+++ b/samples/good/_why-stories.rb
@@ -8,7 +8,8 @@ def index
incident(0)
end
- INCIDENTS = YAML.load_file('class-book.yaml')
+ #INCIDENTS = YAML.load_file("good/good-stories.yaml")
+ INCIDENTS = YAML.load_file("#{DIR}/samples/good/_why-stories.yaml")
def table_of_contents
toc = []
diff --git a/samples/class-book.yaml b/samples/good/_why-stories.yaml
similarity index 100%
rename from samples/class-book.yaml
rename to samples/good/_why-stories.yaml
diff --git a/samples/good/good-arc.rb b/samples/good/arc.rb
similarity index 100%
rename from samples/good/good-arc.rb
rename to samples/good/arc.rb
diff --git a/samples/good/good-cardflip.rb b/samples/good/cardflip.rb
similarity index 93%
rename from samples/good/good-cardflip.rb
rename to samples/good/cardflip.rb
index bf3d85fe..2fe293bf 100644
--- a/samples/good/good-cardflip.rb
+++ b/samples/good/cardflip.rb
@@ -63,16 +63,19 @@ def tap
@top_card.handle = han
end
- # finding script resources is odd when developing a samples/myprogram.rb
+ # finding script resources is tricky when developing a samples/myprogram.rb
# particularly on osx when invoked with ./cshoes mydir/myprogram.rb
# DIR is not sufficient.
# its best to return a full path.
def find_paris
cdir = Dir.getwd
+ $stderr.puts "here: #{cdir}"
if File.exist? "paris.svg"
"#{cdir}/paris.svg"
- elsif File.exist? "#{DIR}/paris.svg"
- "#{DIR}/paris.svg"
+ elsif File.exist? "#{cdir}/good/paris.svg"
+ "#{cdir}/good/paris.svg"
+ elsif File.exist? "#{DIR}/good/paris.svg"
+ "#{DIR}/good/paris.svg"
else
ask_open_file title: "Locate paris.svg"
end
diff --git a/samples/good/good-clock.rb b/samples/good/clock.rb
similarity index 100%
rename from samples/good/good-clock.rb
rename to samples/good/clock.rb
diff --git a/samples/good/good-console.rb b/samples/good/console.rb
similarity index 100%
rename from samples/good/good-console.rb
rename to samples/good/console.rb
diff --git a/samples/good/good-follow.rb b/samples/good/follow.rb
similarity index 100%
rename from samples/good/good-follow.rb
rename to samples/good/follow.rb
diff --git a/samples/good/good-image-rotate.rb b/samples/good/image-rotate.rb
similarity index 100%
rename from samples/good/good-image-rotate.rb
rename to samples/good/image-rotate.rb
diff --git a/samples/paris.svg b/samples/good/paris.svg
similarity index 100%
rename from samples/paris.svg
rename to samples/good/paris.svg
diff --git a/samples/good/good-path-animation.rb b/samples/good/path-animation.rb
similarity index 100%
rename from samples/good/good-path-animation.rb
rename to samples/good/path-animation.rb
diff --git a/samples/good/good-plots.rb b/samples/good/plots.rb
similarity index 75%
rename from samples/good/good-plots.rb
rename to samples/good/plots.rb
index 5a75a1f2..b8b8b77f 100644
--- a/samples/good/good-plots.rb
+++ b/samples/good/plots.rb
@@ -70,6 +70,29 @@
@grf.add cs
end
end
+ button "Radar" do
+ @plot_area.clear do
+ @obs1 = ["internet", "television", "radio", "newspaper", "magazine"]
+ @values1 = [80, 160, 145, 75, 80]
+ @values2 = [180, 90, 95, 90, 90]
+ @columns = [ ["Internet", 0, 200, "%3.0f k"],
+ ["Television", 0, 250," %3.0f k" ],
+ {label: "Radio", min: 0, max: 200, format: "%3.0f k"},
+ ["Newspaper", 0, 200, "%3.0f k"],
+ ["Magazine", 0, 200, "%3.0f k"]
+ ]
+ @grf = plot 600, 400, title: "Advertising", caption:
+ "Budget Spend" , font: "Helvetica", auto_grid: true,
+ default: "skip", background: cornsilk, chart: "radar", column_settings: @columns
+ @grf.add values: @values1, labels: @xobs,
+ name: "Year 1", min: 0, max: 200, color: dodgerblue,
+ points: "dot", strokewidth: 3
+ cs = app.chart_series values: @values2, labels: @xobs,
+ name: "Year 2", min: 0, max: 200, color: coral,
+ points: "dot", strokewidth: 3
+ @grf.add cs
+ end
+ end
end
@plot_area = stack do
end
diff --git a/samples/good/good-reminder.rb b/samples/good/reminder.rb
similarity index 100%
rename from samples/good/good-reminder.rb
rename to samples/good/reminder.rb
diff --git a/samples/good/good-svgview.rb b/samples/good/svgview.rb
similarity index 98%
rename from samples/good/good-svgview.rb
rename to samples/good/svgview.rb
index deba83cb..aa0e14b9 100644
--- a/samples/good/good-svgview.rb
+++ b/samples/good/svgview.rb
@@ -49,7 +49,7 @@ def show_svg(fpath)
end
button "Paris Cards" do
- fpath = Shoes::RELEASE_TYPE =~ /TIGHT/ ? "#{DIR}/samples/paris.svg" : "#{DIR}/../samples/paris.svg"
+ fpath = Shoes::RELEASE_TYPE =~ /TIGHT/ ? "#{DIR}/samples/good/paris.svg" : "#{DIR}/samples/good/paris.svg"
if File.exist? fpath
show_svg(fpath)
diff --git a/samples/good/good-vjot.rb b/samples/good/vjot.rb
similarity index 100%
rename from samples/good/good-vjot.rb
rename to samples/good/vjot.rb
diff --git a/samples/simple/simple-accordion.rb b/samples/simple/accordion.rb
similarity index 100%
rename from samples/simple/simple-accordion.rb
rename to samples/simple/accordion.rb
diff --git a/samples/simple/simple-anim-shapes.rb b/samples/simple/anim-shapes.rb
similarity index 100%
rename from samples/simple/simple-anim-shapes.rb
rename to samples/simple/anim-shapes.rb
diff --git a/samples/simple/simple-anim-text.rb b/samples/simple/anim-text.rb
similarity index 100%
rename from samples/simple/simple-anim-text.rb
rename to samples/simple/anim-text.rb
diff --git a/samples/simple/simple-arc.rb b/samples/simple/arc.rb
similarity index 100%
rename from samples/simple/simple-arc.rb
rename to samples/simple/arc.rb
diff --git a/samples/simple/simple-bounce.rb b/samples/simple/bounce.rb
similarity index 100%
rename from samples/simple/simple-bounce.rb
rename to samples/simple/bounce.rb
diff --git a/samples/simple/simple-calc.rb b/samples/simple/calc.rb
similarity index 100%
rename from samples/simple/simple-calc.rb
rename to samples/simple/calc.rb
diff --git a/samples/simple/simple-chipmunk.rb b/samples/simple/chipmunk.rb
similarity index 100%
rename from samples/simple/simple-chipmunk.rb
rename to samples/simple/chipmunk.rb
diff --git a/samples/simple/simple-control-sizes.rb b/samples/simple/control-sizes.rb
similarity index 100%
rename from samples/simple/simple-control-sizes.rb
rename to samples/simple/control-sizes.rb
diff --git a/samples/simple/simple-curve-control-points.rb b/samples/simple/curve-control-points.rb
similarity index 100%
rename from samples/simple/simple-curve-control-points.rb
rename to samples/simple/curve-control-points.rb
diff --git a/samples/simple/simple-curve.rb b/samples/simple/curve.rb
similarity index 100%
rename from samples/simple/simple-curve.rb
rename to samples/simple/curve.rb
diff --git a/samples/simple/simple-dialogs.rb b/samples/simple/dialogs.rb
similarity index 100%
rename from samples/simple/simple-dialogs.rb
rename to samples/simple/dialogs.rb
diff --git a/samples/simple/simple-downloader.rb b/samples/simple/dowloader.rb
similarity index 100%
rename from samples/simple/simple-downloader.rb
rename to samples/simple/dowloader.rb
diff --git a/samples/simple/downloader.rb b/samples/simple/downloader.rb
new file mode 100644
index 00000000..350347c4
--- /dev/null
+++ b/samples/simple/downloader.rb
@@ -0,0 +1,40 @@
+Shoes.app do
+ background "#eee"
+ @list = stack do
+ para "Enter a URL to download:", :margin => [10, 8, 10, 0]
+ flow :margin => 10 do
+ @url = edit_line :width => -120
+ @url.text ='http://walkabout.mvmanila.com/public/share/Ytm-2.exe'
+ st_time = 0
+ end_time = 0
+ totalsz = 0
+ button "Download", :width => 120 do
+ st_time = Time.now
+ @list.append do
+ stack do
+ background "#eee".."#ccd"
+ stack :margin => 10 do
+ dld = nil
+ para @url.text, " [", link("cancel") { @dld.abort }, "]", :margin => 0
+ d = inscription "Beginning transfer.", :margin => 0
+ p = progress :width => 1.0, :height => 14
+ @dld = download @url.text, :save => File.basename(@url.text),
+ :pause => 0.02,
+ :progress => proc { |dl|
+ d.text = "Transferred #{dl.transferred} of #{dl.length} bytes (#{dl.percent.to_s[0..6]}%)"
+ p.fraction = dl.percent
+ },
+ :finish => proc { |dl|
+ end_time = Time.now
+ secs = (end_time.to_i - st_time.to_i)
+ kb = dl.length < 1024 ? 1: dl.length / 1024
+ d.text = "Download completed KB/s: #{kb/secs} seconds:#{secs}"
+ }
+ para "Should appear after button press"
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/samples/simple/simple-downloader1.rb b/samples/simple/downloader1.rb
similarity index 100%
rename from samples/simple/simple-downloader1.rb
rename to samples/simple/downloader1.rb
diff --git a/samples/simple/simple-draw.rb b/samples/simple/draw.rb
similarity index 100%
rename from samples/simple/simple-draw.rb
rename to samples/simple/draw.rb
diff --git a/samples/simple/simple-editor.rb b/samples/simple/editor.rb
similarity index 100%
rename from samples/simple/simple-editor.rb
rename to samples/simple/editor.rb
diff --git a/samples/simple/simple-form.rb b/samples/simple/form.rb
similarity index 100%
rename from samples/simple/simple-form.rb
rename to samples/simple/form.rb
diff --git a/samples/simple/simple-image.rb b/samples/simple/image.rb
similarity index 100%
rename from samples/simple/simple-image.rb
rename to samples/simple/image.rb
diff --git a/samples/simple/simple-info.rb b/samples/simple/info.rb
similarity index 100%
rename from samples/simple/simple-info.rb
rename to samples/simple/info.rb
diff --git a/samples/simple/simple-mask.rb b/samples/simple/mask.rb
similarity index 100%
rename from samples/simple/simple-mask.rb
rename to samples/simple/mask.rb
diff --git a/samples/simple/simple-mask2.rb b/samples/simple/mask2.rb
similarity index 100%
rename from samples/simple/simple-mask2.rb
rename to samples/simple/mask2.rb
diff --git a/samples/simple/simple-menu.rb b/samples/simple/menu.rb
similarity index 100%
rename from samples/simple/simple-menu.rb
rename to samples/simple/menu.rb
diff --git a/samples/simple/simple-menu1.rb b/samples/simple/menu1.rb
similarity index 100%
rename from samples/simple/simple-menu1.rb
rename to samples/simple/menu1.rb
diff --git a/samples/simple/simple-slide.rb b/samples/simple/slide.rb
similarity index 100%
rename from samples/simple/simple-slide.rb
rename to samples/simple/slide.rb
diff --git a/samples/simple/simple-sphere.rb b/samples/simple/sphere.rb
similarity index 100%
rename from samples/simple/simple-sphere.rb
rename to samples/simple/sphere.rb
diff --git a/samples/simple/simple-sqlite3.rb b/samples/simple/sqlite3.rb
similarity index 75%
rename from samples/simple/simple-sqlite3.rb
rename to samples/simple/sqlite3.rb
index e1cd1eb0..94f30be3 100644
--- a/samples/simple/simple-sqlite3.rb
+++ b/samples/simple/sqlite3.rb
@@ -1,6 +1,9 @@
+# encoding: utf-8
require 'sqlite3'
require 'fileutils'
+include FileUtils
tmpdir = File.join(LIB_DIR,"sample-data")
+#$stderr.puts "tmpdir #{tmpdir}"
mkdir_p tmpdir
dbfile = File.join(tmpdir, "simple-sqlite3.db")
if File.exists? dbfile
@@ -14,8 +17,8 @@
"TEXT,num double,timeEnter DATE)"
db.execute "insert into t1 (data,num) values ('This is sample data',3)"
db.execute "insert into t1 (data,num) values ('More sample data',6)"
- #db.execute "insert into t1 (data,num) values ('Aurélio, Küng, Stärk, Uña, Łuksza',6)"
- db.execute "insert into t1 (data,num) values ('Aurlio, Kng, Strk, Ua, uksza',6)"
+ db.execute "insert into t1 (data,num) values ('Aurélio, Küng, Stärk, Uña, Łuksza',6)"
+ #db.execute "insert into t1 (data,num) values ('Aurlio, Kng, Strk, Ua, uksza',6)"
db.execute "insert into t1 (data,num) values ('And a little more',9)"
rows = db.execute "select * from t1"
rows.each{|k, d, n| para "#{k} : #{d} : #{n}\n"}
diff --git a/samples/simple/simple-timer.rb b/samples/simple/timer.rb
similarity index 100%
rename from samples/simple/simple-timer.rb
rename to samples/simple/timer.rb
diff --git a/shoes/app.c b/shoes/app.c
index cd469bd3..561fb067 100644
--- a/shoes/app.c
+++ b/shoes/app.c
@@ -8,318 +8,322 @@
#include "shoes/ruby.h"
#include "shoes/canvas.h"
#include "shoes/world.h"
-#include "shoes/native.h"
-
-static void
-shoes_app_mark(shoes_app *app)
-{
- shoes_native_slot_mark(app->slot);
- rb_gc_mark_maybe(app->title);
- rb_gc_mark_maybe(app->location);
- rb_gc_mark_maybe(app->canvas);
- rb_gc_mark_maybe(app->keypresses);
- rb_gc_mark_maybe(app->nestslot);
- rb_gc_mark_maybe(app->nesting);
- rb_gc_mark_maybe(app->extras);
- rb_gc_mark_maybe(app->styles);
- rb_gc_mark_maybe(app->groups);
- rb_gc_mark_maybe(app->owner);
-}
-
-static void
-shoes_app_free(shoes_app *app)
-{
- SHOE_FREE(app->slot);
- cairo_destroy(app->scratch);
- RUBY_CRITICAL(free(app));
-}
-
-VALUE
-shoes_app_alloc(VALUE klass)
-{
- shoes_app *app = SHOE_ALLOC(shoes_app);
- SHOE_MEMZERO(app, shoes_app, 1);
- app->slot = SHOE_ALLOC(SHOES_SLOT_OS);
- SHOE_MEMZERO(app->slot, SHOES_SLOT_OS, 1);
- app->slot->owner = app;
- app->started = FALSE;
- app->owner = Qnil;
- app->location = Qnil;
- app->canvas = shoes_canvas_new(cShoes, app);
- app->keypresses = rb_hash_new();
- app->nestslot = Qnil;
- app->nesting = rb_ary_new();
- app->extras = rb_ary_new();
- app->groups = Qnil;
- app->styles = Qnil;
- app->title = Qnil;
- app->width = SHOES_APP_WIDTH;
- app->height = SHOES_APP_HEIGHT;
- app->minwidth = 0;
- app->minheight = 0;
- app->fullscreen = FALSE;
- app->resizable = TRUE;
- app->cursor = s_arrow;
- app->scratch = cairo_create(cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 1, 1));
- app->self = Data_Wrap_Struct(klass, shoes_app_mark, shoes_app_free, app);
- rb_extend_object(app->self, cTypes);
- return app->self;
-}
-
-VALUE
-shoes_app_new(VALUE klass)
-{
- VALUE app = shoes_app_alloc(klass);
- rb_ary_push(shoes_world->apps, app);
- return app;
-}
-
-VALUE
-shoes_apps_get(VALUE self)
-{
- return rb_ary_dup(shoes_world->apps);
-}
-
-static void
-shoes_app_clear(shoes_app *app)
-{
- shoes_ele_remove_all(app->extras);
+#include "shoes/native/native.h"
+#include "shoes/types/text.h"
+#include "shoes/types/text_link.h"
+#include "shoes/types/textblock.h"
+
+static void shoes_app_mark(shoes_app *app) {
+ shoes_native_slot_mark(app->slot);
+ rb_gc_mark_maybe(app->title);
+ rb_gc_mark_maybe(app->location);
+ rb_gc_mark_maybe(app->canvas);
+ rb_gc_mark_maybe(app->keypresses);
+ rb_gc_mark_maybe(app->nestslot);
+ rb_gc_mark_maybe(app->nesting);
+ rb_gc_mark_maybe(app->extras);
+ rb_gc_mark_maybe(app->styles);
+ rb_gc_mark_maybe(app->groups);
+ rb_gc_mark_maybe(app->owner);
+}
+
+static void shoes_app_free(shoes_app *app) {
+ SHOE_FREE(app->slot);
+ cairo_destroy(app->scratch);
+ RUBY_CRITICAL(free(app));
+}
+
+VALUE shoes_app_alloc(VALUE klass) {
+ shoes_app *app = SHOE_ALLOC(shoes_app);
+ SHOE_MEMZERO(app, shoes_app, 1);
+ app->slot = SHOE_ALLOC(SHOES_SLOT_OS);
+ SHOE_MEMZERO(app->slot, SHOES_SLOT_OS, 1);
+ app->slot->owner = app;
+ app->started = FALSE;
+ app->owner = Qnil;
+ app->location = Qnil;
+ app->canvas = shoes_canvas_new(cShoes, app);
+ app->keypresses = rb_hash_new();
+ app->nestslot = Qnil;
+ app->nesting = rb_ary_new();
+ app->extras = rb_ary_new();
+ app->groups = Qnil;
+ app->styles = Qnil;
+ app->title = Qnil;
+ app->width = SHOES_APP_WIDTH;
+ app->height = SHOES_APP_HEIGHT;
+ app->minwidth = 0;
+ app->minheight = 0;
+ app->fullscreen = FALSE;
+ app->resizable = TRUE;
+ app->decorated = TRUE;
+ app->opacity = 1.0;
+ app->cursor = s_arrow;
+ app->scratch = cairo_create(cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 1, 1));
+ app->self = Data_Wrap_Struct(klass, shoes_app_mark, shoes_app_free, app);
+ rb_extend_object(app->self, cTypes);
+ return app->self;
+}
+
+VALUE shoes_app_new(VALUE klass) {
+ VALUE app = shoes_app_alloc(klass);
+ rb_ary_push(shoes_world->apps, app);
+ return app;
+}
+
+VALUE shoes_apps_get(VALUE self) {
+ return rb_ary_dup(shoes_world->apps);
+}
+
+static void shoes_app_clear(shoes_app *app) {
+ shoes_ele_remove_all(app->extras);
// shoes_canvas *canvas;
// Data_Get_Struct(app->canvas, shoes_canvas, canvas);
// shoes_extras_remove_all(canvas);
- shoes_canvas_clear(app->canvas);
- app->nestslot = Qnil;
- app->groups = Qnil;
+ shoes_canvas_clear(app->canvas);
+ app->nestslot = Qnil;
+ app->groups = Qnil;
}
//
// When a window is finished, call this to delete it from the master
// list. Returns 1 if all windows are gone.
//
-int
-shoes_app_remove(shoes_app *app)
-{
- // gives a chance to cleanup before quit
- shoes_canvas_send_finish(app->canvas);
-
- shoes_app_clear(app);
- rb_ary_delete(shoes_world->apps, app->self);
- return (RARRAY_LEN(shoes_world->apps) == 0);
+int shoes_app_remove(shoes_app *app) {
+ // gives a chance to cleanup before quit
+ shoes_canvas_send_finish(app->canvas);
+
+ shoes_app_clear(app);
+ rb_ary_delete(shoes_world->apps, app->self);
+ return (RARRAY_LEN(shoes_world->apps) == 0);
}
-shoes_code
-shoes_app_resize(shoes_app *app, int width, int height)
-{
- app->width = width;
- app->height = height;
- shoes_native_app_resized(app);
- return SHOES_OK;
+
+shoes_code shoes_app_resize(shoes_app *app, int width, int height) {
+ app->width = width;
+ app->height = height;
+ //shoes_native_app_resized(app);
+ shoes_native_app_resize_window(app);
+ return SHOES_OK;
}
-VALUE
-shoes_app_window(int argc, VALUE *argv, VALUE self, VALUE owner)
-{
- rb_arg_list args;
- VALUE attr = Qnil;
- VALUE app = shoes_app_new(self == cDialog ? cDialog : cApp);
- shoes_app *app_t;
- char *url = "/";
- Data_Get_Struct(app, shoes_app, app_t);
-
- switch (rb_parse_args(argc, argv, "h,s|h,", &args))
- {
- case 1:
- attr = args.a[0];
- break;
-
- case 2:
- url = RSTRING_PTR(args.a[0]);
- attr = args.a[1];
- break;
- }
-
- if (rb_block_given_p()) rb_iv_set(app, "@main_app", rb_block_proc());
- app_t->owner = owner;
- app_t->title = ATTR(attr, title);
- app_t->fullscreen = RTEST(ATTR(attr, fullscreen));
- app_t->resizable = (ATTR(attr, resizable) != Qfalse);
- app_t->hidden = (ATTR(attr, hidden) == Qtrue);
- shoes_app_resize(app_t, ATTR2(int, attr, width, SHOES_APP_WIDTH), ATTR2(int, attr, height, SHOES_APP_HEIGHT));
- if (RTEST(ATTR(attr, minwidth)))
- //app_t->minwidth = (NUM2INT(ATTR(attr, minwidth)) - 1) / 2;
- app_t->minwidth = NUM2INT(ATTR(attr, minwidth));
- if (RTEST(ATTR(attr, minheight)))
- //app_t->minheight = (NUM2INT(ATTR(attr, minheight)) -1) / 2;
- app_t->minheight = NUM2INT(ATTR(attr, minheight));
- shoes_canvas_init(app_t->canvas, app_t->slot, attr, app_t->width, app_t->height);
- if (shoes_world->mainloop)
- shoes_app_open(app_t, url);
- return app;
-}
-
-VALUE
-shoes_app_main(int argc, VALUE *argv, VALUE self)
-{
- return shoes_app_window(argc, argv, self, Qnil);
+VALUE shoes_app_window(int argc, VALUE *argv, VALUE self, VALUE owner) {
+ rb_arg_list args;
+ VALUE attr = Qnil;
+ VALUE app = shoes_app_new(self == cDialog ? cDialog : cApp);
+ shoes_app *app_t;
+ char *url = "/";
+ Data_Get_Struct(app, shoes_app, app_t);
+
+ switch (rb_parse_args(argc, argv, "h,s|h,", &args)) {
+ case 1:
+ attr = args.a[0];
+ break;
+
+ case 2:
+ url = RSTRING_PTR(args.a[0]);
+ attr = args.a[1];
+ break;
+ }
+
+ if (rb_block_given_p()) rb_iv_set(app, "@main_app", rb_block_proc());
+ app_t->owner = owner;
+ app_t->title = ATTR(attr, title);
+ app_t->fullscreen = RTEST(ATTR(attr, fullscreen));
+ app_t->resizable = (ATTR(attr, resizable) != Qfalse);
+ app_t->decorated = (ATTR(attr, decorated) != Qfalse);
+ app_t->hidden = (ATTR(attr, hidden) == Qtrue);
+
+ if (RTEST(ATTR(attr, opacity)))
+ if ((0.0 <= NUM2DBL(ATTR(attr, opacity))) && (1.0 >= NUM2DBL(ATTR(attr, opacity))))
+ app_t->opacity = NUM2DBL(ATTR(attr, opacity));
+
+ shoes_app_resize(app_t, ATTR2(int, attr, width, SHOES_APP_WIDTH), ATTR2(int, attr, height, SHOES_APP_HEIGHT));
+ if (RTEST(ATTR(attr, minwidth)))
+ //app_t->minwidth = (NUM2INT(ATTR(attr, minwidth)) - 1) / 2;
+ app_t->minwidth = NUM2INT(ATTR(attr, minwidth));
+ if (RTEST(ATTR(attr, minheight)))
+ //app_t->minheight = (NUM2INT(ATTR(attr, minheight)) -1) / 2;
+ app_t->minheight = NUM2INT(ATTR(attr, minheight));
+ shoes_canvas_init(app_t->canvas, app_t->slot, attr, app_t->width, app_t->height);
+ if (shoes_world->mainloop)
+ shoes_app_open(app_t, url);
+ return app;
}
-VALUE
-shoes_app_slot(VALUE app)
-{
- shoes_app *app_t;
- Data_Get_Struct(app, shoes_app, app_t);
- return app_t->nestslot;
+VALUE shoes_app_main(int argc, VALUE *argv, VALUE self) {
+ return shoes_app_window(argc, argv, self, Qnil);
}
-VALUE
-shoes_app_get_width(VALUE app)
-{
- shoes_app *app_t;
- Data_Get_Struct(app, shoes_app, app_t);
- return INT2NUM(app_t->width);
+VALUE shoes_app_slot(VALUE app) {
+ shoes_app *app_t;
+ Data_Get_Struct(app, shoes_app, app_t);
+ return app_t->nestslot;
}
-VALUE
-shoes_app_get_height(VALUE app)
-{
- shoes_app *app_t;
- Data_Get_Struct(app, shoes_app, app_t);
- return INT2NUM(app_t->height);
+VALUE shoes_app_get_width(VALUE app) {
+ shoes_app *app_t;
+ Data_Get_Struct(app, shoes_app, app_t);
+ return INT2NUM(app_t->width);
}
-VALUE
-shoes_app_set_icon(VALUE app, VALUE icon_path)
-{
- shoes_app *app_t;
- char *path;
- Data_Get_Struct(app, shoes_app, app_t);
- path = RSTRING_PTR(icon_path);
- shoes_native_app_set_icon(app_t, path);
- return Qtrue;
+VALUE shoes_app_get_height(VALUE app) {
+ shoes_app *app_t;
+ Data_Get_Struct(app, shoes_app, app_t);
+ return INT2NUM(app_t->height);
}
-VALUE
-shoes_app_set_wtitle(VALUE app, VALUE title)
-{
- shoes_app *app_t;
- char *wtitle;
- Data_Get_Struct(app, shoes_app, app_t);
- app_t->title = title;
- wtitle = RSTRING_PTR(title);
- shoes_native_app_set_wtitle(app_t, wtitle);
- return Qtrue;
+VALUE shoes_app_set_icon(VALUE app, VALUE icon_path) {
+ shoes_app *app_t;
+ char *path;
+ Data_Get_Struct(app, shoes_app, app_t);
+ path = RSTRING_PTR(icon_path);
+ shoes_native_app_set_icon(app_t, path);
+ return Qtrue;
}
-VALUE
-shoes_app_get_title(VALUE app)
-{
- shoes_app *app_t;
- Data_Get_Struct(app, shoes_app, app_t);
- return app_t->title;
+VALUE shoes_app_resize_window(VALUE app, VALUE width, VALUE height) {
+ shoes_app *app_t;
+ Data_Get_Struct(app, shoes_app, app_t);
+ app_t->width = NUM2INT(width);
+ app_t->height = NUM2INT(height);
+ shoes_native_app_resize_window(app_t);
+ return Qtrue;
}
-VALUE
-shoes_app_set_title(VALUE app, VALUE title)
-{
- shoes_app *app_t;
- Data_Get_Struct(app, shoes_app, app_t);
- return app_t->title = title;
+VALUE shoes_app_set_wtitle(VALUE app, VALUE title) {
+ shoes_app *app_t;
+ char *wtitle;
+ Data_Get_Struct(app, shoes_app, app_t);
+ app_t->title = title;
+ wtitle = RSTRING_PTR(title);
+ shoes_native_app_set_wtitle(app_t, wtitle);
+ return Qtrue;
}
-VALUE
-shoes_app_get_fullscreen(VALUE app)
-{
- shoes_app *app_t;
- Data_Get_Struct(app, shoes_app, app_t);
- return app_t->fullscreen ? Qtrue : Qfalse;
+VALUE shoes_app_get_title(VALUE app) {
+ shoes_app *app_t;
+ Data_Get_Struct(app, shoes_app, app_t);
+ return app_t->title;
}
-VALUE
-shoes_app_set_fullscreen(VALUE app, VALUE yn)
-{
- shoes_app *app_t;
- Data_Get_Struct(app, shoes_app, app_t);
- shoes_native_app_fullscreen(app_t, app_t->fullscreen = RTEST(yn));
- return yn;
+VALUE shoes_app_set_title(VALUE app, VALUE title) {
+ shoes_app *app_t;
+ Data_Get_Struct(app, shoes_app, app_t);
+ return app_t->title = title;
}
-void
-shoes_app_title(shoes_app *app, VALUE title)
-{
- char *msg;
- if (!NIL_P(title))
- app->title = title;
- else
- app->title = rb_str_new2(SHOES_APPNAME);
- msg = RSTRING_PTR(app->title);
- shoes_native_app_title(app, msg);
+VALUE shoes_app_get_fullscreen(VALUE app) {
+ shoes_app *app_t;
+ Data_Get_Struct(app, shoes_app, app_t);
+ return app_t->fullscreen ? Qtrue : Qfalse;
}
-shoes_code
-shoes_app_start(VALUE allapps, char *uri)
-{
- int i;
- shoes_code code;
- shoes_app *app;
-
- for (i = 0; i < RARRAY_LEN(allapps); i++)
- {
- VALUE appobj2 = rb_ary_entry(allapps, i);
- Data_Get_Struct(appobj2, shoes_app, app);
- if (!app->started)
- {
- code = shoes_app_open(app, uri);
- app->started = TRUE;
- if (code != SHOES_OK)
- return code;
+VALUE shoes_app_set_fullscreen(VALUE app, VALUE yn) {
+ shoes_app *app_t;
+ Data_Get_Struct(app, shoes_app, app_t);
+ shoes_native_app_fullscreen(app_t, app_t->fullscreen = RTEST(yn));
+ return yn;
+}
+
+void shoes_app_title(shoes_app *app, VALUE title) {
+ char *msg;
+ if (!NIL_P(title))
+ app->title = title;
+ else
+ app->title = rb_str_new2(SHOES_APPNAME);
+ msg = RSTRING_PTR(app->title);
+ shoes_native_app_title(app, msg);
+}
+
+VALUE shoes_app_set_opacity(VALUE app, VALUE opacity) {
+ shoes_app *app_t;
+ Data_Get_Struct(app, shoes_app, app_t);
+ app_t->opacity = NUM2DBL(opacity);
+
+ if ((0.0 <= app_t->opacity) && (1.0 >= app_t->opacity))
+ shoes_native_app_set_opacity(app_t, app_t->opacity);
+
+ return Qtrue;
+}
+
+VALUE shoes_app_get_opacity(VALUE app) {
+ shoes_app *app_t;
+ Data_Get_Struct(app, shoes_app, app_t);
+ return DBL2NUM(shoes_native_app_get_opacity(app_t));
+}
+
+
+VALUE shoes_app_set_decoration(VALUE app, VALUE decorated) {
+ shoes_app *app_t;
+ Data_Get_Struct(app, shoes_app, app_t);
+ shoes_native_app_set_decoration(app_t, (decorated != Qfalse));
+ return Qtrue;
+}
+
+VALUE shoes_app_get_decoration(VALUE app) {
+ shoes_app *app_t;
+ Data_Get_Struct(app, shoes_app, app_t);
+ return (shoes_native_app_get_decoration(app_t) ? Qtrue : Qfalse);
+}
+
+
+shoes_code shoes_app_start(VALUE allapps, char *uri) {
+ int i;
+ shoes_code code;
+ shoes_app *app;
+
+ for (i = 0; i < RARRAY_LEN(allapps); i++) {
+ VALUE appobj2 = rb_ary_entry(allapps, i);
+ Data_Get_Struct(appobj2, shoes_app, app);
+ if (!app->started) {
+ code = shoes_app_open(app, uri);
+ app->started = TRUE;
+ if (code != SHOES_OK)
+ return code;
+ }
}
- }
- return shoes_app_loop();
+ return shoes_app_loop();
}
-shoes_code
-shoes_app_open(shoes_app *app, char *path)
-{
- shoes_code code = SHOES_OK;
- int dialog = (rb_obj_class(app->self) == cDialog);
+shoes_code shoes_app_open(shoes_app *app, char *path) {
+ shoes_code code = SHOES_OK;
+ int dialog = (rb_obj_class(app->self) == cDialog);
- code = shoes_native_app_open(app, path, dialog);
- if (code != SHOES_OK)
- return code;
+ code = shoes_native_app_open(app, path, dialog);
+ if (code != SHOES_OK)
+ return code;
- shoes_app_title(app, app->title);
- if (app->slot != NULL) shoes_native_slot_reset(app->slot);
- shoes_slot_init(app->canvas, app->slot, 0, 0, app->width, app->height, TRUE, TRUE);
- code = shoes_app_goto(app, path);
- if (code != SHOES_OK)
- return code;
+ shoes_app_title(app, app->title);
+ if (app->slot != NULL) shoes_native_slot_reset(app->slot);
+ shoes_slot_init(app->canvas, app->slot, 0, 0, app->width, app->height, TRUE, TRUE);
+ code = shoes_app_goto(app, path);
+ if (code != SHOES_OK)
+ return code;
- if (!app->hidden)
- shoes_native_app_show(app);
+ if (!app->hidden)
+ shoes_native_app_show(app);
- return code;
+ return code;
}
-shoes_code
-shoes_app_loop()
-{
- if (shoes_world->mainloop)
- return SHOES_OK;
+shoes_code shoes_app_loop() {
+ if (shoes_world->mainloop)
+ return SHOES_OK;
- shoes_world->mainloop = TRUE;
- INFO("RUNNING LOOP.\n");
- shoes_native_loop();
- return SHOES_OK;
+ shoes_world->mainloop = TRUE;
+ INFO("RUNNING LOOP.\n");
+ shoes_native_loop();
+ return SHOES_OK;
}
-typedef struct
-{
- shoes_app *app;
- VALUE canvas;
- VALUE block;
- char ieval;
- VALUE args;
+typedef struct {
+ shoes_app *app;
+ VALUE canvas;
+ VALUE block;
+ char ieval;
+ VALUE args;
} shoes_exec;
#ifndef RUBY_1_8
@@ -351,284 +355,235 @@ rb_unbound_get_class(VALUE method)
}
*/
-static VALUE
-shoes_app_run(VALUE rb_exec)
-{
- shoes_exec *exec = (shoes_exec *)rb_exec;
- rb_ary_push(exec->app->nesting, exec->canvas);
- if (exec->ieval)
- {
- VALUE obj;
- obj = mfp_instance_eval(exec->app->self, exec->block);
- return obj;
- }
- else
- {
- int i;
- VALUE vargs[10];
- for (i = 0; i < RARRAY_LEN(exec->args); i++)
- vargs[i] = rb_ary_entry(exec->args, i);
- return rb_funcall2(exec->block, s_call, (int)RARRAY_LEN(exec->args), vargs);
- }
+static VALUE shoes_app_run(VALUE rb_exec) {
+ shoes_exec *exec = (shoes_exec *)rb_exec;
+ rb_ary_push(exec->app->nesting, exec->canvas);
+ if (exec->ieval) {
+ VALUE obj;
+ obj = mfp_instance_eval(exec->app->self, exec->block);
+ return obj;
+ } else {
+ int i;
+ VALUE vargs[10];
+ for (i = 0; i < RARRAY_LEN(exec->args); i++)
+ vargs[i] = rb_ary_entry(exec->args, i);
+ return rb_funcall2(exec->block, s_call, (int)RARRAY_LEN(exec->args), vargs);
+ }
}
-static VALUE
-shoes_app_exception(VALUE rb_exec, VALUE e)
-{
- shoes_exec *exec = (shoes_exec *)rb_exec;
- rb_ary_clear(exec->app->nesting);
- shoes_canvas_error(exec->canvas, e);
- return Qnil;
+static VALUE shoes_app_exception(VALUE rb_exec, VALUE e) {
+ shoes_exec *exec = (shoes_exec *)rb_exec;
+ rb_ary_clear(exec->app->nesting);
+ shoes_canvas_error(exec->canvas, e);
+ return Qnil;
+}
+
+shoes_code shoes_app_visit(shoes_app *app, char *path) {
+ shoes_exec exec;
+ shoes_canvas *canvas;
+ VALUE meth;
+ Data_Get_Struct(app->canvas, shoes_canvas, canvas);
+
+ canvas->slot->scrolly = 0;
+ shoes_native_slot_clear(canvas);
+ shoes_app_clear(app);
+ shoes_app_reset_styles(app);
+ meth = rb_funcall(cShoes, s_run, 1, app->location = rb_str_new2(path));
+
+ VALUE app_block = rb_iv_get(app->self, "@main_app");
+ if (!NIL_P(app_block))
+ rb_ary_store(meth, 0, app_block);
+
+ exec.app = app;
+ exec.block = rb_ary_entry(meth, 0);
+ exec.args = rb_ary_entry(meth, 1);
+ if (rb_obj_is_kind_of(exec.block, rb_cUnboundMethod)) {
+ // VALUE klass = rb_unbound_get_class(exec.block);
+ VALUE klass = rb_ary_entry(meth, 2);
+ exec.canvas = app->nestslot = shoes_slot_new(klass, ssNestSlot, app->canvas);
+ exec.block = rb_funcall(exec.block, s_bind, 1, exec.canvas);
+ exec.ieval = 0;
+ rb_ary_push(canvas->contents, exec.canvas);
+ } else {
+ exec.canvas = app->nestslot = app->canvas;
+ exec.ieval = 1;
+ }
+
+ rb_rescue2(CASTHOOK(shoes_app_run), (VALUE)&exec, CASTHOOK(shoes_app_exception), (VALUE)&exec, rb_cObject, 0);
+
+ rb_ary_clear(exec.app->nesting);
+ return SHOES_OK;
}
-shoes_code
-shoes_app_visit(shoes_app *app, char *path)
-{
- shoes_exec exec;
- shoes_canvas *canvas;
- VALUE meth;
- Data_Get_Struct(app->canvas, shoes_canvas, canvas);
-
- canvas->slot->scrolly = 0;
- shoes_native_slot_clear(canvas);
- shoes_app_clear(app);
- shoes_app_reset_styles(app);
- meth = rb_funcall(cShoes, s_run, 1, app->location = rb_str_new2(path));
-
- VALUE app_block = rb_iv_get(app->self, "@main_app");
- if (!NIL_P(app_block))
- rb_ary_store(meth, 0, app_block);
-
- exec.app = app;
- exec.block = rb_ary_entry(meth, 0);
- exec.args = rb_ary_entry(meth, 1);
- if (rb_obj_is_kind_of(exec.block, rb_cUnboundMethod)) {
- // VALUE klass = rb_unbound_get_class(exec.block);
- VALUE klass = rb_ary_entry(meth, 2);
- exec.canvas = app->nestslot = shoes_slot_new(klass, ssNestSlot, app->canvas);
- exec.block = rb_funcall(exec.block, s_bind, 1, exec.canvas);
- exec.ieval = 0;
- rb_ary_push(canvas->contents, exec.canvas);
- } else {
- exec.canvas = app->nestslot = app->canvas;
- exec.ieval = 1;
- }
-
- rb_rescue2(CASTHOOK(shoes_app_run), (VALUE)&exec, CASTHOOK(shoes_app_exception), (VALUE)&exec, rb_cObject, 0);
-
- rb_ary_clear(exec.app->nesting);
- return SHOES_OK;
-}
-
-shoes_code
-shoes_app_paint(shoes_app *app)
-{
- shoes_canvas_paint(app->canvas);
- return SHOES_OK;
+shoes_code shoes_app_paint(shoes_app *app) {
+ shoes_canvas_paint(app->canvas);
+ return SHOES_OK;
}
-shoes_code
-shoes_app_motion(shoes_app *app, int x, int y)
-{
- app->mousex = x; app->mousey = y;
- shoes_canvas_send_motion(app->canvas, x, y, Qnil);
- return SHOES_OK;
+shoes_code shoes_app_motion(shoes_app *app, int x, int y) {
+ app->mousex = x;
+ app->mousey = y;
+ shoes_canvas_send_motion(app->canvas, x, y, Qnil);
+ return SHOES_OK;
}
-shoes_code
-shoes_app_click(shoes_app *app, int button, int x, int y)
-{
- app->mouseb = button;
- shoes_canvas_send_click(app->canvas, button, x, y);
- return SHOES_OK;
+shoes_code shoes_app_click(shoes_app *app, int button, int x, int y) {
+ app->mouseb = button;
+ shoes_canvas_send_click(app->canvas, button, x, y);
+ return SHOES_OK;
}
-shoes_code
-shoes_app_release(shoes_app *app, int button, int x, int y)
-{
- app->mouseb = 0;
- shoes_canvas_send_release(app->canvas, button, x, y);
- return SHOES_OK;
+shoes_code shoes_app_release(shoes_app *app, int button, int x, int y) {
+ app->mouseb = 0;
+ shoes_canvas_send_release(app->canvas, button, x, y);
+ return SHOES_OK;
}
-shoes_code
-shoes_app_wheel(shoes_app *app, ID dir, int x, int y)
-{
- shoes_canvas *canvas;
- Data_Get_Struct(app->canvas, shoes_canvas, canvas);
- if (canvas->slot->vscroll) shoes_canvas_wheel_way(canvas, dir);
+shoes_code shoes_app_wheel(shoes_app *app, ID dir, int x, int y) {
+ shoes_canvas *canvas;
+ Data_Get_Struct(app->canvas, shoes_canvas, canvas);
+ if (canvas->slot->vscroll) shoes_canvas_wheel_way(canvas, dir);
- shoes_canvas_send_wheel(app->canvas, dir, x, y);
- return SHOES_OK;
+ shoes_canvas_send_wheel(app->canvas, dir, x, y);
+ return SHOES_OK;
}
-shoes_code
-shoes_app_keydown(shoes_app *app, VALUE key)
-{
- if (!RTEST(rb_hash_aref(app->keypresses, key))) {
- rb_hash_aset(app->keypresses, key, Qtrue);
- shoes_canvas_send_keydown(app->canvas, key);
- }
- return SHOES_OK;
+shoes_code shoes_app_keydown(shoes_app *app, VALUE key) {
+ if (!RTEST(rb_hash_aref(app->keypresses, key))) {
+ rb_hash_aset(app->keypresses, key, Qtrue);
+ shoes_canvas_send_keydown(app->canvas, key);
+ }
+ return SHOES_OK;
}
-shoes_code
-shoes_app_keypress(shoes_app *app, VALUE key)
-{
- if (key == symAltSlash)
- rb_eval_string("Shoes.show_log");
- else if (key == symAltQuest)
- rb_eval_string("Shoes.show_manual");
- else if (key == symAltDot)
- rb_eval_string("Shoes.show_selector");
- else if (key == symAltEqual)
- rb_eval_string("Shoes.show_irb");
- else if (key == symAltSemiColon)
- rb_eval_string("Shoes.remote_debug");
- else
- shoes_canvas_send_keypress(app->canvas, key);
- return SHOES_OK;
-}
-
-shoes_code
-shoes_app_keyup(shoes_app *app, VALUE key)
-{
- rb_hash_aset(app->keypresses, key, Qfalse);
- shoes_canvas_send_keyup(app->canvas, key);
- return SHOES_OK;
+shoes_code shoes_app_keypress(shoes_app *app, VALUE key) {
+ if (key == symAltSlash)
+ rb_eval_string("Shoes.show_log");
+ else if (key == symAltQuest)
+ rb_eval_string("Shoes.show_manual");
+ else if (key == symAltDot)
+ rb_eval_string("Shoes.show_selector");
+ else if (key == symAltEqual)
+ rb_eval_string("Shoes.show_irb");
+ else if (key == symAltSemiColon)
+ rb_eval_string("Shoes.remote_debug");
+ else
+ shoes_canvas_send_keypress(app->canvas, key);
+ return SHOES_OK;
}
-VALUE
-shoes_sys(char *cmd, int detach)
-{
- if (detach)
- return rb_funcall(rb_mKernel, rb_intern("system"), 1, rb_str_new2(cmd));
- else
- return rb_funcall(rb_mKernel, '`', 1, rb_str_new2(cmd));
+shoes_code shoes_app_keyup(shoes_app *app, VALUE key) {
+ rb_hash_aset(app->keypresses, key, Qfalse);
+ shoes_canvas_send_keyup(app->canvas, key);
+ return SHOES_OK;
}
-shoes_code
-shoes_app_goto(shoes_app *app, char *path)
-{
- shoes_code code = SHOES_OK;
- const char http_scheme[] = "http://";
- if (strlen(path) > strlen(http_scheme) && strncmp(http_scheme, path, strlen(http_scheme)) == 0) {
- shoes_browser_open(path);
- } else {
- code = shoes_app_visit(app, path);
- if (code == SHOES_OK)
- {
- shoes_app_motion(app, app->mousex, app->mousey);
- shoes_slot_repaint(app->slot);
+VALUE shoes_sys(char *cmd, int detach) {
+ if (detach)
+ return rb_funcall(rb_mKernel, rb_intern("system"), 1, rb_str_new2(cmd));
+ else
+ return rb_funcall(rb_mKernel, '`', 1, rb_str_new2(cmd));
+}
+
+shoes_code shoes_app_goto(shoes_app *app, char *path) {
+ shoes_code code = SHOES_OK;
+ const char http_scheme[] = "http://";
+ if (strlen(path) > strlen(http_scheme) && strncmp(http_scheme, path, strlen(http_scheme)) == 0) {
+ shoes_browser_open(path);
+ } else {
+ code = shoes_app_visit(app, path);
+ if (code == SHOES_OK) {
+ shoes_app_motion(app, app->mousex, app->mousey);
+ shoes_slot_repaint(app->slot);
+ }
}
- }
- return code;
+ return code;
}
-shoes_code
-shoes_slot_repaint(SHOES_SLOT_OS *slot)
-{
- shoes_native_slot_paint(slot);
- return SHOES_OK;
+shoes_code shoes_slot_repaint(SHOES_SLOT_OS *slot) {
+ shoes_native_slot_paint(slot);
+ return SHOES_OK;
}
-static void
-shoes_style_set(VALUE styles, VALUE klass, VALUE k, VALUE v)
-{
- VALUE hsh = rb_hash_aref(styles, klass);
- if (NIL_P(hsh))
- rb_hash_aset(styles, klass, hsh = rb_hash_new());
- rb_hash_aset(hsh, k, v);
+static void shoes_style_set(VALUE styles, VALUE klass, VALUE k, VALUE v) {
+ VALUE hsh = rb_hash_aref(styles, klass);
+ if (NIL_P(hsh))
+ rb_hash_aset(styles, klass, hsh = rb_hash_new());
+ rb_hash_aset(hsh, k, v);
}
#define STYLE(klass, k, v) \
shoes_style_set(app->styles, klass, \
ID2SYM(rb_intern("" # k)), rb_str_new2("" # v))
-void
-shoes_app_reset_styles(shoes_app *app)
-{
- app->styles = rb_hash_new();
- STYLE(cBanner, size, 48);
- STYLE(cTitle, size, 34);
- STYLE(cSubtitle, size, 26);
- STYLE(cTagline, size, 18);
- STYLE(cCaption, size, 14);
- STYLE(cPara, size, 12);
- STYLE(cInscription, size, 10);
-
- STYLE(cCode, family, monospace);
- STYLE(cDel, strikethrough, single);
- STYLE(cEm, emphasis, italic);
- STYLE(cIns, underline, single);
- STYLE(cLink, underline, single);
- STYLE(cLink, stroke, #06E);
- STYLE(cLinkHover, underline, single);
- STYLE(cLinkHover, stroke, #039);
- STYLE(cStrong, weight, bold);
- STYLE(cSup, rise, 10);
- STYLE(cSup, size, x-small);
- STYLE(cSub, rise, -10);
- STYLE(cSub, size, x-small);
-}
-
-void
-shoes_app_style(shoes_app *app, VALUE klass, VALUE hsh)
-{
- long i;
- VALUE keys = rb_funcall(hsh, s_keys, 0);
- for ( i = 0; i < RARRAY_LEN(keys); i++ )
- {
- VALUE key = rb_ary_entry(keys, i);
- VALUE val = rb_hash_aref(hsh, key);
- if (!SYMBOL_P(key)) key = rb_str_intern(key);
- shoes_style_set(app->styles, klass, key, val);
- }
-}
-
-VALUE
-shoes_app_close_window(shoes_app *app)
-{
- shoes_native_app_close(app);
- return Qnil;
+void shoes_app_reset_styles(shoes_app *app) {
+ app->styles = rb_hash_new();
+ STYLE(cBanner, size, 48);
+ STYLE(cTitle, size, 34);
+ STYLE(cSubtitle, size, 26);
+ STYLE(cTagline, size, 18);
+ STYLE(cCaption, size, 14);
+ STYLE(cPara, size, 12);
+ STYLE(cInscription, size, 10);
+
+ STYLE(cCode, family, monospace);
+ STYLE(cDel, strikethrough, single);
+ STYLE(cEm, emphasis, italic);
+ STYLE(cIns, underline, single);
+ STYLE(cLink, underline, single);
+ STYLE(cLink, stroke, #06E);
+ STYLE(cLinkHover, underline, single);
+ STYLE(cLinkHover, stroke, #039);
+ STYLE(cStrong, weight, bold);
+ STYLE(cSup, rise, 10);
+ STYLE(cSup, size, x-small);
+ STYLE(cSub, rise, -10);
+ STYLE(cSub, size, x-small);
+}
+
+void shoes_app_style(shoes_app *app, VALUE klass, VALUE hsh) {
+ long i;
+ VALUE keys = rb_funcall(hsh, s_keys, 0);
+ for ( i = 0; i < RARRAY_LEN(keys); i++ ) {
+ VALUE key = rb_ary_entry(keys, i);
+ VALUE val = rb_hash_aref(hsh, key);
+ if (!SYMBOL_P(key)) key = rb_str_intern(key);
+ shoes_style_set(app->styles, klass, key, val);
+ }
}
-VALUE
-shoes_app_location(VALUE self)
-{
- shoes_app *app;
- Data_Get_Struct(self, shoes_app, app);
- return app->location;
+VALUE shoes_app_close_window(shoes_app *app) {
+ shoes_native_app_close(app);
+ return Qnil;
}
-VALUE
-shoes_app_is_started(VALUE self)
-{
- shoes_app *app;
- Data_Get_Struct(self, shoes_app, app);
- return app->started ? Qtrue : Qfalse;
+VALUE shoes_app_location(VALUE self) {
+ shoes_app *app;
+ Data_Get_Struct(self, shoes_app, app);
+ return app->location;
}
-VALUE
-shoes_app_contents(VALUE self)
-{
- shoes_app *app;
- Data_Get_Struct(self, shoes_app, app);
- return shoes_canvas_contents(app->canvas);
+VALUE shoes_app_is_started(VALUE self) {
+ shoes_app *app;
+ Data_Get_Struct(self, shoes_app, app);
+ return app->started ? Qtrue : Qfalse;
}
-VALUE
-shoes_app_quit(VALUE self)
-{
- shoes_native_quit();
- return self;
+VALUE shoes_app_contents(VALUE self) {
+ shoes_app *app;
+ Data_Get_Struct(self, shoes_app, app);
+ return shoes_canvas_contents(app->canvas);
}
+VALUE shoes_app_quit(VALUE self) {
+ shoes_native_quit();
+ return self;
+}
// Shoes doesn't know much about this - it's mostly C level window stuff
// to handle stdin/stdout and a native window for keypress and display
-//
-// Ugly: default font size
+//
+// Ugly: default font size
#ifdef SHOES_QUARTZ
#define TERM_FONT_SZ 12
#else
@@ -638,64 +593,63 @@ int shoes_global_terminal = 0;
// this called by the Shoes.show_console or using the -w flag on the
// command line. The next method is the preferred way.
-VALUE
-shoes_app_console(VALUE self)
-{
- if (!shoes_global_terminal) {
- // Dig out DIR constant
- VALUE dir_val;
- dir_val = rb_const_get(self, rb_intern("DIR"));
- char *dir_path = RSTRING_PTR(dir_val);
- //shoes_global_terminal = shoes_native_console(dir_path);
- shoes_native_terminal(dir_path, 1, 80, 24, TERM_FONT_SZ, "black", "white", "Shoes Terminal");
- shoes_global_terminal = 1;
- }
- return shoes_global_terminal ? Qtrue : Qfalse;
+VALUE shoes_app_console(VALUE self) {
+ if (!shoes_global_terminal) {
+ // Dig out DIR constant
+ VALUE dir_val;
+ dir_val = rb_const_get(self, rb_intern("DIR"));
+ char *dir_path = RSTRING_PTR(dir_val);
+ //shoes_global_terminal = shoes_native_console(dir_path);
+ shoes_native_terminal(dir_path, 1, 80, 24, TERM_FONT_SZ, "black", "white", "Shoes Terminal");
+ shoes_global_terminal = 1;
+ }
+ return shoes_global_terminal ? Qtrue : Qfalse;
}
// This is called from Shoes with a 'Shoes.terminal {hash of args values}'
-// THE prefered way to get a terminal/console. This parses the ruby hash in
+// THE prefered way to get a terminal/console. This parses the ruby hash in
// argv
-VALUE
-shoes_app_terminal(int argc, VALUE *argv, VALUE self) {
- if (!shoes_global_terminal) {
- // Dig out DIR constant
- VALUE dir_val;
- dir_val = rb_const_get(self, rb_intern("DIR"));
- // set sensible defaults to be replaced if specified
- int mode = 1, columns = 80, rows = 24, fontsize = TERM_FONT_SZ;
- char *fg = "black"; char* bg = "white"; char* title = "Shoes Terminal";
- char *dir_path = RSTRING_PTR(dir_val);
- if (argc == 1) {
- // parse the hash args
- VALUE argtitle = shoes_hash_get(argv[0], rb_intern("title"));
- if (!(NIL_P(argtitle)))
- title = RSTRING_PTR(argtitle);
- VALUE argcol = shoes_hash_get(argv[0], rb_intern("columns"));
- if (!(NIL_P(argcol)))
- columns = NUM2INT(argcol);
- VALUE argrow = shoes_hash_get(argv[0], rb_intern("rows"));
- if (!NIL_P(argrow))
- rows = NUM2INT(argrow);
- VALUE argfz = shoes_hash_get(argv[0], rb_intern("fontsize"));
- if (!NIL_P(argfz))
- fontsize = NUM2INT(argfz);
- VALUE argfg = shoes_hash_get(argv[0], rb_intern("fg"));
- if (!NIL_P(argfg))
- fg = RSTRING_PTR(argfg);
- VALUE argbg = shoes_hash_get(argv[0], rb_intern("bg"));
- if (!NIL_P(argbg))
- bg = RSTRING_PTR(argbg);
+VALUE shoes_app_terminal(int argc, VALUE *argv, VALUE self) {
+ if (!shoes_global_terminal) {
+ // Dig out DIR constant
+ VALUE dir_val;
+ dir_val = rb_const_get(self, rb_intern("DIR"));
+ // set sensible defaults to be replaced if specified
+ int mode = 1, columns = 80, rows = 24, fontsize = TERM_FONT_SZ;
+ char *fg = "black";
+ char* bg = "white";
+ char* title = "Shoes Terminal";
+ char *dir_path = RSTRING_PTR(dir_val);
+ if (argc == 1) {
+ // parse the hash args
+ VALUE argtitle = shoes_hash_get(argv[0], rb_intern("title"));
+ if (!(NIL_P(argtitle)))
+ title = RSTRING_PTR(argtitle);
+ VALUE argcol = shoes_hash_get(argv[0], rb_intern("columns"));
+ if (!(NIL_P(argcol)))
+ columns = NUM2INT(argcol);
+ VALUE argrow = shoes_hash_get(argv[0], rb_intern("rows"));
+ if (!NIL_P(argrow))
+ rows = NUM2INT(argrow);
+ VALUE argfz = shoes_hash_get(argv[0], rb_intern("fontsize"));
+ if (!NIL_P(argfz))
+ fontsize = NUM2INT(argfz);
+ VALUE argfg = shoes_hash_get(argv[0], rb_intern("fg"));
+ if (!NIL_P(argfg))
+ fg = RSTRING_PTR(argfg);
+ VALUE argbg = shoes_hash_get(argv[0], rb_intern("bg"));
+ if (!NIL_P(argbg))
+ bg = RSTRING_PTR(argbg);
#if 0
- VALUE modearg = shoes_hash_get(argv[0], rb_intern("mode"));
- if (!NIL_P(modearg)) {
- char *arg = RSTRING_PTR(modearg);
- if (strcmp(arg, "game") == 0)
- mode = 0;
- }
+ VALUE modearg = shoes_hash_get(argv[0], rb_intern("mode"));
+ if (!NIL_P(modearg)) {
+ char *arg = RSTRING_PTR(modearg);
+ if (strcmp(arg, "game") == 0)
+ mode = 0;
+ }
#endif
+ }
+ shoes_native_terminal(dir_path, mode, columns, rows, fontsize, fg, bg, title);
+ shoes_global_terminal = 1;
}
- shoes_native_terminal(dir_path, mode, columns, rows, fontsize, fg, bg, title);
- shoes_global_terminal = 1;
- }
- return shoes_global_terminal ? Qtrue : Qfalse;
+ return shoes_global_terminal ? Qtrue : Qfalse;
}
diff --git a/shoes/app.h b/shoes/app.h
index c1e80ca5..8664e1b6 100644
--- a/shoes/app.h
+++ b/shoes/app.h
@@ -17,8 +17,8 @@
#include "shoes/code.h"
#include "shoes/config.h"
-#define SHOES_APP_HEIGHT 500
#define SHOES_APP_WIDTH 600
+#define SHOES_APP_HEIGHT 500
#define SHOES_SHORTNAME "shoes"
#define SHOES_APPNAME "Shoes"
#define SHOES_VLCLASS "Shoes VLC"
@@ -29,24 +29,25 @@
// abstract window struct
//
typedef struct _shoes_app {
- SHOES_APP_OS os;
- SHOES_SLOT_OS *slot;
- cairo_t *scratch;
- int width, height, mouseb, mousex, mousey,
- resizable, hidden, started, fullscreen,
- minwidth, minheight;
- VALUE self;
- VALUE canvas;
- VALUE keypresses;
- VALUE nestslot;
- VALUE nesting;
- VALUE extras;
- VALUE styles;
- VALUE groups;
- ID cursor;
- VALUE title;
- VALUE location;
- VALUE owner;
+ SHOES_APP_OS os;
+ SHOES_SLOT_OS *slot;
+ cairo_t *scratch;
+ int width, height, mouseb, mousex, mousey,
+ resizable, hidden, started, fullscreen,
+ minwidth, minheight, decorated;
+ double opacity;
+ VALUE self;
+ VALUE canvas;
+ VALUE keypresses;
+ VALUE nestslot;
+ VALUE nesting;
+ VALUE extras;
+ VALUE styles;
+ VALUE groups;
+ ID cursor;
+ VALUE title;
+ VALUE location;
+ VALUE owner;
} shoes_app;
//
@@ -60,11 +61,15 @@ VALUE shoes_app_get_title(VALUE);
VALUE shoes_app_set_title(VALUE, VALUE);
VALUE shoes_app_get_fullscreen(VALUE);
VALUE shoes_app_set_fullscreen(VALUE, VALUE);
+VALUE shoes_app_set_opacity(VALUE app, VALUE opacity);
+VALUE shoes_app_get_opacity(VALUE app);
+VALUE shoes_app_set_decoration(VALUE app, VALUE decorated);
+VALUE shoes_app_get_decoration(VALUE app);
VALUE shoes_app_slot(VALUE);
VALUE shoes_app_set_icon(VALUE, VALUE); // New 3.2.19
VALUE shoes_app_set_wtitle(VALUE, VALUE); // New in 3.2.19
-VALUE shoes_app_console(VALUE); // New in 3.2.23 ?
-VALUE shoes_app_terminal(int, VALUE*, VALUE); //new in 3.3.2
+VALUE shoes_app_console(VALUE); // New in 3.2.23 ?
+VALUE shoes_app_terminal(int, VALUE*, VALUE); //new in 3.3.2
shoes_code shoes_app_start(VALUE, char *);
shoes_code shoes_app_open(shoes_app *, char *);
shoes_code shoes_app_loop(void);
@@ -86,6 +91,9 @@ void shoes_app_style(shoes_app *, VALUE, VALUE);
VALUE shoes_app_location(VALUE);
VALUE shoes_app_is_started(VALUE);
VALUE shoes_app_quit(VALUE);
+VALUE shoes_app_resize_window(VALUE, VALUE, VALUE);
+
+VALUE shoes_app_resize_window(VALUE, VALUE, VALUE);
// global var for console up and running
extern int shoes_global_terminal;
diff --git a/shoes/canvas.c b/shoes/canvas.c
index 8666a00d..f929d089 100644
--- a/shoes/canvas.c
+++ b/shoes/canvas.c
@@ -7,26 +7,15 @@
#include "shoes/canvas.h"
#include "shoes/ruby.h"
#include "shoes/world.h"
-#include "shoes/native.h"
+#include "shoes/native/native.h"
+#include "shoes/types/native.h"
+#include "shoes/types/color.h"
+#include "shoes/types/image.h"
+#include "shoes/types/pattern.h"
+#include "shoes/types/shape.h"
+#include "shoes/types/textblock.h"
#include "shoes/http.h"
-#define SETUP() \
- shoes_canvas *canvas; \
- cairo_t *cr; \
- Data_Get_Struct(self, shoes_canvas, canvas); \
- cr = CCR(canvas)
-#define SETUP_IMAGE() \
- shoes_place place; \
- GET_STRUCT(image, image); \
- shoes_image_ensure_dup(image); \
- shoes_place_exact(&place, attr, 0, 0); \
- if (NIL_P(attr)) attr = image->attr; \
- else if (!NIL_P(image->attr)) attr = rb_funcall(image->attr, s_merge, 1, attr);
-#define SETUP_SHAPE() \
- shoes_canvas *canvas = NULL; \
- VALUE c = shoes_find_canvas(self); \
- Data_Get_Struct(c, shoes_canvas, canvas)
-
const double SHOES_PIM2 = 6.28318530717958647693;
const double SHOES_PI = 3.14159265358979323846;
const double SHOES_HALFPI = 1.57079632679489661923;
@@ -39,1780 +28,906 @@ static void shoes_canvas_send_start(VALUE);
// made it public to hook to an app quit event
//static void shoes_canvas_send_finish(VALUE);
-shoes_transform *
-shoes_transform_new(shoes_transform *o)
-{
- shoes_transform *n = SHOE_ALLOC(shoes_transform);
- n->mode = s_center;
- n->refs = 1;
- cairo_matrix_init_identity(&n->tf);
- if (o != NULL)
- {
- cairo_matrix_multiply(&n->tf, &n->tf, &o->tf);
- n->mode = o->mode;
- }
- return n;
+shoes_transform *shoes_transform_new(shoes_transform *o) {
+ shoes_transform *n = SHOE_ALLOC(shoes_transform);
+ n->mode = s_center;
+ n->refs = 1;
+ cairo_matrix_init_identity(&n->tf);
+ if (o != NULL) {
+ cairo_matrix_multiply(&n->tf, &n->tf, &o->tf);
+ n->mode = o->mode;
+ }
+ return n;
}
-shoes_transform *
-shoes_transform_touch(shoes_transform *st)
-{
- if (st != NULL) st->refs++;
- return st;
+shoes_transform *shoes_transform_touch(shoes_transform *st) {
+ if (st != NULL) st->refs++;
+ return st;
}
-shoes_transform *
-shoes_transform_detach(shoes_transform *old)
-{
- if (old != NULL && old->refs == 1) return old;
- if (old != NULL) old->refs--;
- return shoes_transform_new(old);
+shoes_transform *shoes_transform_detach(shoes_transform *old) {
+ if (old != NULL && old->refs == 1) return old;
+ if (old != NULL) old->refs--;
+ return shoes_transform_new(old);
}
-void
-shoes_transform_release(shoes_transform *st)
-{
- if (st == NULL) return;
- if (--st->refs) return;
- SHOE_FREE(st);
+void shoes_transform_release(shoes_transform *st) {
+ if (st == NULL) return;
+ if (--st->refs) return;
+ SHOE_FREE(st);
}
-VALUE
-shoes_canvas_owner(VALUE self)
-{
- SETUP();
- return canvas->app->owner;
+VALUE shoes_canvas_owner(VALUE self) {
+ SETUP_CANVAS();
+ return canvas->app->owner;
}
-VALUE
-shoes_canvas_close(VALUE self)
-{
- SETUP();
- return shoes_app_close_window(canvas->app);
+VALUE shoes_canvas_close(VALUE self) {
+ SETUP_CANVAS();
+ return shoes_app_close_window(canvas->app);
}
-VALUE
-shoes_canvas_get_scroll_top(VALUE self)
-{
- GET_STRUCT(canvas, canvas);
- return INT2NUM(canvas->slot->scrolly);
+VALUE shoes_canvas_get_scroll_top(VALUE self) {
+ GET_STRUCT(canvas, canvas);
+ return INT2NUM(canvas->slot->scrolly);
}
-VALUE
-shoes_canvas_set_scroll_top(VALUE self, VALUE num)
-{
- SETUP();
- shoes_slot_scroll_to(canvas, NUM2INT(num), 0);
- return num;
+VALUE shoes_canvas_set_scroll_top(VALUE self, VALUE num) {
+ SETUP_CANVAS();
+ shoes_slot_scroll_to(canvas, NUM2INT(num), 0);
+ return num;
}
-VALUE
-shoes_canvas_get_scroll_max(VALUE self)
-{
- SETUP();
- return INT2NUM(max(0, canvas->fully - canvas->height));
+VALUE shoes_canvas_get_scroll_max(VALUE self) {
+ SETUP_CANVAS();
+ return INT2NUM(max(0, canvas->fully - canvas->height));
}
-VALUE
-shoes_canvas_get_scroll_height(VALUE self)
-{
- SETUP();
- return INT2NUM(canvas->fully);
+VALUE shoes_canvas_get_scroll_height(VALUE self) {
+ SETUP_CANVAS();
+ return INT2NUM(canvas->fully);
}
-VALUE
-shoes_canvas_get_gutter_width(VALUE self)
-{
- int scrollwidth = 0;
- GET_STRUCT(canvas, canvas);
- scrollwidth = shoes_native_slot_gutter(canvas->slot);
- return INT2NUM(scrollwidth);
+VALUE shoes_canvas_get_gutter_width(VALUE self) {
+ int scrollwidth = 0;
+ GET_STRUCT(canvas, canvas);
+ scrollwidth = shoes_native_slot_gutter(canvas->slot);
+ return INT2NUM(scrollwidth);
}
-VALUE
-shoes_canvas_displace(VALUE self, VALUE dx, VALUE dy)
-{
- SETUP();
- ATTRSET(canvas->attr, displace_left, dx);
- ATTRSET(canvas->attr, displace_top, dy);
- shoes_canvas_repaint_all(canvas->parent);
- return self;
+VALUE shoes_canvas_displace(VALUE self, VALUE dx, VALUE dy) {
+ SETUP_CANVAS();
+ ATTRSET(canvas->attr, displace_left, dx);
+ ATTRSET(canvas->attr, displace_top, dy);
+ shoes_canvas_repaint_all(canvas->parent);
+ return self;
}
-VALUE
-shoes_canvas_move(VALUE self, VALUE x, VALUE y)
-{
- SETUP();
- ATTRSET(canvas->attr, left, x);
- ATTRSET(canvas->attr, top, y);
- shoes_canvas_repaint_all(canvas->parent);
- return self;
+VALUE shoes_canvas_move(VALUE self, VALUE x, VALUE y) {
+ SETUP_CANVAS();
+ ATTRSET(canvas->attr, left, x);
+ ATTRSET(canvas->attr, top, y);
+ shoes_canvas_repaint_all(canvas->parent);
+ return self;
}
-VALUE
-shoes_canvas_style(int argc, VALUE *argv, VALUE self)
-{
- rb_arg_list args;
- SETUP();
-
- switch (rb_parse_args(argc, argv, "kh,h,", &args))
- {
- case 1:
- shoes_app_style(canvas->app, args.a[0], args.a[1]);
- break;
-
- case 2:
- if (NIL_P(canvas->attr)) canvas->attr = rb_hash_new();
- rb_funcall(canvas->attr, s_update, 1, args.a[0]);
- shoes_canvas_repaint_all(canvas->parent);
- break;
+VALUE shoes_canvas_style(int argc, VALUE *argv, VALUE self) {
+ rb_arg_list args;
+ SETUP_CANVAS();
- case 3: return rb_obj_freeze(rb_obj_dup(canvas->attr));
- }
+ switch (rb_parse_args(argc, argv, "kh,h,", &args)) {
+ case 1:
+ shoes_app_style(canvas->app, args.a[0], args.a[1]);
+ break;
+
+ case 2:
+ if (NIL_P(canvas->attr)) canvas->attr = rb_hash_new();
+ rb_funcall(canvas->attr, s_update, 1, args.a[0]);
+ shoes_canvas_repaint_all(canvas->parent);
+ break;
+
+ case 3:
+ return rb_obj_freeze(rb_obj_dup(canvas->attr));
+ }
- return self;
+ return self;
}
#define ELAPSED (shoes_diff_time(&start, &mid) * 0.001)
-static VALUE
-shoes_canvas_paint_call(VALUE self)
-{
- shoes_code code = SHOES_OK;
- SHOES_TIME start, mid;
- shoes_get_time(&start);
+static VALUE shoes_canvas_paint_call(VALUE self) {
+ shoes_code code = SHOES_OK;
+ SHOES_TIME start, mid;
+ shoes_get_time(&start);
- if (self == Qnil)
- return self;
+ if (self == Qnil)
+ return self;
- SETUP();
+ SETUP_CANVAS();
- if (canvas->cr != NULL)
- goto quit;
+ if (canvas->cr != NULL)
+ goto quit;
- canvas->cr = cr = shoes_cairo_create(canvas);
- if (cr == NULL)
- goto quit;
+ canvas->cr = cr = shoes_cairo_create(canvas);
+ if (cr == NULL)
+ goto quit;
- cairo_save(cr);
- shoes_canvas_draw(self, self, Qfalse);
- shoes_get_time(&mid);
- INFO("COMPUTE: %0.6f s\n", ELAPSED);
- cairo_restore(cr);
+ cairo_save(cr);
+ shoes_canvas_draw(self, self, Qfalse);
+ shoes_get_time(&mid);
+ INFO("COMPUTE: %0.6f s\n", ELAPSED);
+ cairo_restore(cr);
- canvas->cr = cr;
- cairo_save(cr);
- shoes_canvas_draw(self, self, Qtrue);
- shoes_get_time(&mid);
- INFO("DRAW: %0.6f s\n", ELAPSED);
- cairo_restore(cr);
+ canvas->cr = cr;
+ cairo_save(cr);
+ shoes_canvas_draw(self, self, Qtrue);
+ shoes_get_time(&mid);
+ INFO("DRAW: %0.6f s\n", ELAPSED);
+ cairo_restore(cr);
- if (cairo_status(cr)) {
- code = SHOES_FAIL;
- PUTS("Cairo is unhappy: %s\n", cairo_status_to_string (cairo_status (cr)));
- goto quit;
- }
+ if (cairo_status(cr)) {
+ code = SHOES_FAIL;
+ PUTS("Cairo is unhappy: %s\n", cairo_status_to_string (cairo_status (cr)));
+ goto quit;
+ }
- cairo_destroy(cr);
- cr = canvas->cr = NULL;
+ cairo_destroy(cr);
+ cr = canvas->cr = NULL;
- shoes_cairo_destroy(canvas);
- shoes_get_time(&mid);
- INFO("PAINT: %0.6f s\n", ELAPSED);
- shoes_canvas_send_start(self);
+ shoes_cairo_destroy(canvas);
+ shoes_get_time(&mid);
+ INFO("PAINT: %0.6f s\n", ELAPSED);
+ shoes_canvas_send_start(self);
quit:
- if (cr != NULL) cairo_destroy(cr);
- return self;
-}
-
-void
-shoes_canvas_paint(VALUE self)
-{
- rb_rescue2(CASTHOOK(shoes_canvas_paint_call), self,
- CASTHOOK(shoes_canvas_error), self, rb_cObject, 0);
- return;
-}
-
-void
-shoes_apply_transformation(cairo_t *cr, shoes_transform *st, shoes_place *place, unsigned char force)
-{
- cairo_save(cr);
-
- if (st != NULL) {
- double w = place->iw / 2.;
- double h = place->ih / 2.;
- double x = (place->ix + place->dx) + w;
- double y = (place->iy + place->dy) + h;
-
- if (st->mode == s_center) cairo_translate(cr, x, y);
- cairo_transform(cr, &st->tf);
- if (st->mode == s_center) cairo_translate(cr, -x, -y);
- }
+ if (cr != NULL) cairo_destroy(cr);
+ return self;
}
-void
-shoes_undo_transformation(cairo_t *cr, shoes_transform *st, shoes_place *place, unsigned char force)
-{
- cairo_restore(cr);
+void shoes_canvas_paint(VALUE self) {
+ rb_rescue2(CASTHOOK(shoes_canvas_paint_call), self,
+ CASTHOOK(shoes_canvas_error), self, rb_cObject, 0);
+ return;
}
-static VALUE
-shoes_add_ele(shoes_canvas *canvas, VALUE ele)
-{
- if (NIL_P(ele)) return ele;
- if (canvas->insertion <= -1)
- rb_ary_push(canvas->contents, ele);
- else
- {
- rb_ary_insert_at(canvas->contents, canvas->insertion, 0, ele);
- canvas->insertion++;
- }
- return ele;
-}
+void shoes_apply_transformation(cairo_t *cr, shoes_transform *st, shoes_place *place, unsigned char force) {
+ cairo_save(cr);
-void
-shoes_canvas_mark(shoes_canvas *canvas)
-{
- shoes_native_slot_mark(canvas->slot);
- rb_gc_mark_maybe(canvas->contents);
- rb_gc_mark_maybe(canvas->attr);
- rb_gc_mark_maybe(canvas->parent);
-}
-
-static void
-shoes_canvas_reset_transform(shoes_canvas *canvas)
-{
- if (canvas->sts != NULL)
- {
- int i;
- for (i = 0; i < canvas->stl; i++)
- shoes_transform_release(canvas->sts[i]);
- SHOE_FREE(canvas->sts);
- canvas->sts = NULL;
- }
- canvas->stl = 0;
- canvas->stt = 0;
+ if (st != NULL) {
+ double w = place->iw / 2.;
+ double h = place->ih / 2.;
+ double x = (place->ix + place->dx) + w;
+ double y = (place->iy + place->dy) + h;
- if (canvas->st != NULL)
- {
- shoes_transform_release(canvas->st);
- canvas->st = NULL;
- }
+ if (st->mode == s_center) cairo_translate(cr, x, y);
+ cairo_transform(cr, &st->tf);
+ if (st->mode == s_center) cairo_translate(cr, -x, -y);
+ }
}
-static void
-shoes_canvas_free(shoes_canvas *canvas)
-{
- if (canvas->slot != NULL && canvas->slot->owner == canvas)
- SHOE_FREE(canvas->slot);
- shoes_canvas_reset_transform(canvas);
- RUBY_CRITICAL(free(canvas));
-}
-
-VALUE
-shoes_canvas_alloc(VALUE klass)
-{
- shoes_canvas *canvas = SHOE_ALLOC(shoes_canvas);
- SHOE_MEMZERO(canvas, shoes_canvas, 1);
- canvas->app = NULL;
- canvas->stage = CANVAS_NADA;
- canvas->contents = Qnil;
- canvas->shape = NULL;
- canvas->insertion = -2;
- VALUE rb_canvas = Data_Wrap_Struct(klass, shoes_canvas_mark, shoes_canvas_free, canvas);
- return rb_canvas;
-}
-
-VALUE
-shoes_canvas_new(VALUE klass, shoes_app *app)
-{
- shoes_canvas *canvas;
- VALUE self = shoes_canvas_alloc(klass);
- Data_Get_Struct(self, shoes_canvas, canvas);
- canvas->app = app;
- return self;
-}
-
-static void
-shoes_canvas_empty(shoes_canvas *canvas, int extras)
-{
- unsigned char stage = canvas->stage;
- canvas->stage = CANVAS_EMPTY;
- shoes_ele_remove_all(canvas->contents);
- if (extras) shoes_extras_remove_all(canvas);
- canvas->stage = stage;
-}
-
-void
-shoes_canvas_clear(VALUE self)
-{
- shoes_canvas *canvas;
- Data_Get_Struct(self, shoes_canvas, canvas);
- canvas->cr = NULL;
- canvas->attr = rb_hash_new();
- ATTRSET(canvas->attr, cap, Qnil);
- ATTRSET(canvas->attr, strokewidth, rb_float_new(1.));
- ATTRSET(canvas->attr, stroke, shoes_color_new(0, 0, 0, 0xFF));
- ATTRSET(canvas->attr, fill, shoes_color_new(0, 0, 0, 0xFF));
- canvas->parent = Qnil;
- canvas->stl = 0;
- canvas->stt = 0;
- shoes_canvas_reset_transform(canvas);
- shoes_canvas_empty(canvas, TRUE);
- canvas->contents = rb_ary_new();
- canvas->place.x = canvas->place.y = 0;
- canvas->place.dx = canvas->place.dy = 0;
- canvas->place.ix = canvas->place.iy = 0;
- canvas->hover = 0;
- canvas->cx = 0;
- canvas->cy = 0;
- canvas->endy = 0;
- canvas->endx = 0;
- canvas->topy = 0;
- canvas->fully = 0;
- shoes_group_clear(&canvas->group);
-}
-
-shoes_canvas *
-shoes_canvas_init(VALUE self, SHOES_SLOT_OS *slot, VALUE attr, int width, int height)
-{
- shoes_canvas *canvas;
- Data_Get_Struct(self, shoes_canvas, canvas);
- canvas->attr = attr;
- canvas->place.iw = canvas->place.w = canvas->width = width;
- canvas->place.ih = canvas->place.h = canvas->height = height;
- return canvas;
-}
-
-void
-shoes_slot_scroll_to(shoes_canvas *canvas, int dy, int rel)
-{
- if (rel)
- canvas->slot->scrolly += dy;
- else
- canvas->slot->scrolly = dy;
-
- if (canvas->slot->scrolly > canvas->endy - canvas->height)
- canvas->slot->scrolly = canvas->endy - canvas->height;
- if (canvas->slot->scrolly < 0)
- canvas->slot->scrolly = 0;
- if (DC(canvas->app->slot) == DC(canvas->slot)) canvas->app->slot->scrolly = canvas->slot->scrolly;
- shoes_native_slot_scroll_top(canvas->slot);
- shoes_slot_repaint(canvas->slot);
-}
-
-VALUE
-shoes_canvas_nostroke(VALUE self)
-{
- SETUP_BASIC();
- ATTRSET(basic->attr, stroke, Qnil);
- return self;
-}
-
-VALUE
-shoes_canvas_stroke(int argc, VALUE *argv, VALUE self)
-{
- VALUE pat;
- SETUP_BASIC();
- if (argc == 1 && rb_respond_to(argv[0], s_to_pattern))
- pat = argv[0];
- else
- pat = shoes_pattern_args(argc, argv, self);
- if (!rb_obj_is_kind_of(pat, cColor))
- pat = rb_funcall(pat, s_to_pattern, 0);
- ATTRSET(basic->attr, stroke, pat);
- return pat;
-}
-
-VALUE
-shoes_canvas_strokewidth(VALUE self, VALUE w)
-{
- SETUP_BASIC();
- ATTRSET(basic->attr, strokewidth, w);
- return self;
-}
-
-VALUE
-shoes_canvas_dash(VALUE self, VALUE dash)
-{
- SETUP_BASIC();
- ATTRSET(basic->attr, dash, dash);
- return self;
-}
-
-VALUE
-shoes_canvas_cap(VALUE self, VALUE cap)
-{
- SETUP_BASIC();
- ATTRSET(basic->attr, cap, cap);
- return self;
-}
-
-VALUE
-shoes_canvas_nofill(VALUE self)
-{
- SETUP_BASIC();
- ATTRSET(basic->attr, fill, Qnil);
- return self;
-}
-
-VALUE
-shoes_canvas_fill(int argc, VALUE *argv, VALUE self)
-{
- VALUE pat;
- SETUP_BASIC();
- if (argc == 1 && rb_respond_to(argv[0], s_to_pattern))
- pat = argv[0];
- else
- pat = shoes_pattern_args(argc, argv, self);
- if (!rb_obj_is_kind_of(pat, cColor))
- pat = rb_funcall(pat, s_to_pattern, 0);
- ATTRSET(basic->attr, fill, pat);
- return pat;
-}
-
-VALUE
-shoes_add_shape(VALUE self, ID name, VALUE attr, cairo_path_t *line)
-{
- if (rb_obj_is_kind_of(self, cImage))
- {
- SETUP_IMAGE();
- shoes_shape_sketch(image->cr, name, &place, NULL, attr, line, 1);
- return self;
- }
-
- SETUP();
- if (canvas->shape != NULL)
- {
- shoes_place place;
- shoes_place_exact(&place, attr, 0, 0);
- cairo_new_sub_path(canvas->shape);
- shoes_shape_sketch(canvas->shape, name, &place, canvas->st, attr, line, 0);
- return self;
- }
-
- return shoes_add_ele(canvas, shoes_shape_new(self, name, attr, canvas->st, line));
+void shoes_undo_transformation(cairo_t *cr, shoes_transform *st, shoes_place *place, unsigned char force) {
+ cairo_restore(cr);
}
-VALUE
-shoes_canvas_arc(int argc, VALUE *argv, VALUE self)
-{
- VALUE attr = shoes_shape_attr(argc, argv, 6, s_left, s_top, s_width, s_height, s_angle1, s_angle2);
- return shoes_add_shape(self, s_arc, attr, NULL);
+VALUE shoes_add_ele(shoes_canvas *canvas, VALUE ele) {
+ if (NIL_P(ele)) return ele;
+ if (canvas->insertion <= -1)
+ rb_ary_push(canvas->contents, ele);
+ else {
+ rb_ary_insert_at(canvas->contents, canvas->insertion, 0, ele);
+ canvas->insertion++;
+ }
+ return ele;
}
-VALUE
-shoes_canvas_rect(int argc, VALUE *argv, VALUE self)
-{
- VALUE attr = shoes_shape_attr(argc, argv, 5, s_left, s_top, s_width, s_height, s_curve);
- return shoes_add_shape(self, s_rect, attr, NULL);
+void shoes_canvas_mark(shoes_canvas *canvas) {
+ shoes_native_slot_mark(canvas->slot);
+ rb_gc_mark_maybe(canvas->contents);
+ rb_gc_mark_maybe(canvas->attr);
+ rb_gc_mark_maybe(canvas->parent);
}
-VALUE
-shoes_canvas_oval(int argc, VALUE *argv, VALUE self)
-{
- VALUE attr = shoes_shape_attr(argc, argv, 4, s_left, s_top, s_width, s_height);
- //VALUE attr = shoes_shape_attr(argc, argv, 3, s_left, s_top, s_radius);
- //rb_warn("shoes_canvas_oval: %s\n", RSTRING_PTR(rb_inspect(attr)));
- return shoes_add_shape(self, s_oval, attr, NULL);
-}
+static void shoes_canvas_reset_transform(shoes_canvas *canvas) {
+ if (canvas->sts != NULL) {
+ int i;
+ for (i = 0; i < canvas->stl; i++)
+ shoes_transform_release(canvas->sts[i]);
+ SHOE_FREE(canvas->sts);
+ canvas->sts = NULL;
+ }
+ canvas->stl = 0;
+ canvas->stt = 0;
-VALUE
-shoes_canvas_line(int argc, VALUE *argv, VALUE self)
-{
- VALUE attr = shoes_shape_attr(argc, argv, 4, s_left, s_top, s_right, s_bottom);
- return shoes_add_shape(self, s_line, attr, NULL);
+ if (canvas->st != NULL) {
+ shoes_transform_release(canvas->st);
+ canvas->st = NULL;
+ }
}
-VALUE
-shoes_canvas_arrow(int argc, VALUE *argv, VALUE self)
-{
- VALUE attr = shoes_shape_attr(argc, argv, 3, s_left, s_top, s_width);
- return shoes_add_shape(self, s_arrow, attr, NULL);
+static void shoes_canvas_free(shoes_canvas *canvas) {
+ if (canvas->slot != NULL && canvas->slot->owner == canvas)
+ SHOE_FREE(canvas->slot);
+ shoes_canvas_reset_transform(canvas);
+ RUBY_CRITICAL(free(canvas));
}
-VALUE
-shoes_canvas_star(int argc, VALUE *argv, VALUE self)
-{
- VALUE attr = shoes_shape_attr(argc, argv, 5, s_left, s_top, s_points, s_outer, s_inner);
- return shoes_add_shape(self, s_star, attr, NULL);
+VALUE shoes_canvas_alloc(VALUE klass) {
+ shoes_canvas *canvas = SHOE_ALLOC(shoes_canvas);
+ SHOE_MEMZERO(canvas, shoes_canvas, 1);
+ canvas->app = NULL;
+ canvas->stage = CANVAS_NADA;
+ canvas->contents = Qnil;
+ canvas->shape = NULL;
+ canvas->insertion = -2;
+ VALUE rb_canvas = Data_Wrap_Struct(klass, shoes_canvas_mark, shoes_canvas_free, canvas);
+ return rb_canvas;
}
-VALUE
-shoes_add_effect(VALUE self, ID name, VALUE attr)
-{
- if (rb_obj_is_kind_of(self, cImage))
- {
- shoes_effect_filter filter = shoes_effect_for_type(name);
- SETUP_IMAGE();
- if (filter == NULL) return self;
- filter(image->cr, attr, &place);
+VALUE shoes_canvas_new(VALUE klass, shoes_app *app) {
+ shoes_canvas *canvas;
+ VALUE self = shoes_canvas_alloc(klass);
+ Data_Get_Struct(self, shoes_canvas, canvas);
+ canvas->app = app;
return self;
- }
-
- SETUP();
- return shoes_add_ele(canvas, shoes_effect_new(name, attr, self));
}
-VALUE
-shoes_canvas_blur(int argc, VALUE *argv, VALUE self)
-{
- VALUE attr = shoes_shape_attr(argc, argv, 1, s_radius);
- return shoes_add_effect(self, s_blur, attr);
+static void shoes_canvas_empty(shoes_canvas *canvas, int extras) {
+ unsigned char stage = canvas->stage;
+ canvas->stage = CANVAS_EMPTY;
+ shoes_ele_remove_all(canvas->contents);
+ if (extras) shoes_extras_remove_all(canvas);
+ canvas->stage = stage;
}
-VALUE
-shoes_canvas_glow(int argc, VALUE *argv, VALUE self)
-{
- VALUE attr = shoes_shape_attr(argc, argv, 1, s_radius);
- return shoes_add_effect(self, s_glow, attr);
+void shoes_canvas_clear(VALUE self) {
+ shoes_canvas *canvas;
+ Data_Get_Struct(self, shoes_canvas, canvas);
+ canvas->cr = NULL;
+ canvas->attr = rb_hash_new();
+ ATTRSET(canvas->attr, cap, Qnil);
+ ATTRSET(canvas->attr, strokewidth, rb_float_new(1.));
+ ATTRSET(canvas->attr, stroke, shoes_color_new(0, 0, 0, 0xFF));
+ ATTRSET(canvas->attr, fill, shoes_color_new(0, 0, 0, 0xFF));
+ canvas->parent = Qnil;
+ canvas->stl = 0;
+ canvas->stt = 0;
+ shoes_canvas_reset_transform(canvas);
+ shoes_canvas_empty(canvas, TRUE);
+ canvas->contents = rb_ary_new();
+ canvas->place.x = canvas->place.y = 0;
+ canvas->place.dx = canvas->place.dy = 0;
+ canvas->place.ix = canvas->place.iy = 0;
+ canvas->hover = 0;
+ canvas->cx = 0;
+ canvas->cy = 0;
+ canvas->endy = 0;
+ canvas->endx = 0;
+ canvas->topy = 0;
+ canvas->fully = 0;
+ shoes_group_clear(&canvas->group);
+}
+
+shoes_canvas *shoes_canvas_init(VALUE self, SHOES_SLOT_OS *slot, VALUE attr, int width, int height) {
+ shoes_canvas *canvas;
+ Data_Get_Struct(self, shoes_canvas, canvas);
+ canvas->attr = attr;
+ canvas->place.iw = canvas->place.w = canvas->width = width;
+ canvas->place.ih = canvas->place.h = canvas->height = height;
+ return canvas;
}
-VALUE
-shoes_canvas_shadow(int argc, VALUE *argv, VALUE self)
-{
- VALUE attr = shoes_shape_attr(argc, argv, 2, s_distance, s_radius);
- return shoes_add_effect(self, s_shadow, attr);
+void shoes_slot_scroll_to(shoes_canvas *canvas, int dy, int rel) {
+ if (rel)
+ canvas->slot->scrolly += dy;
+ else
+ canvas->slot->scrolly = dy;
+
+ if (canvas->slot->scrolly > canvas->endy - canvas->height)
+ canvas->slot->scrolly = canvas->endy - canvas->height;
+ if (canvas->slot->scrolly < 0)
+ canvas->slot->scrolly = 0;
+ if (DC(canvas->app->slot) == DC(canvas->slot)) canvas->app->slot->scrolly = canvas->slot->scrolly;
+ shoes_native_slot_scroll_top(canvas->slot);
+ shoes_slot_repaint(canvas->slot);
}
-#define MARKUP_BLOCK(klass) \
- text = shoes_textblock_new(klass, msgs, attr, self, canvas->st); \
- shoes_add_ele(canvas, text)
+VALUE shoes_canvas_move_to(VALUE self, VALUE _x, VALUE _y) {
+ double x, y;
+ SETUP_SHAPE();
-#define MARKUP_INLINE(klass) \
- text = shoes_text_new(klass, msgs, attr)
+ x = NUM2DBL(_x);
+ y = NUM2DBL(_y);
-#define MARKUP_DEF(mname, fname, klass) \
- VALUE \
- shoes_canvas_##mname(int argc, VALUE *argv, VALUE self) \
- { \
- long i; \
- VALUE msgs, attr, text; \
- SETUP(); \
- msgs = rb_ary_new(); \
- attr = Qnil; \
- for (i = 0; i < argc; i++) \
- { \
- if (rb_obj_is_kind_of(argv[i], rb_cHash)) \
- attr = argv[i]; \
- else \
- rb_ary_push(msgs, argv[i]); \
- } \
- MARKUP_##fname(klass); \
- return text; \
- }
+ if (canvas->shape != NULL) cairo_move_to(canvas->shape, x, y);
+ return self;
+}
-MARKUP_DEF(para, BLOCK, cPara);
-MARKUP_DEF(banner, BLOCK, cBanner);
-MARKUP_DEF(title, BLOCK, cTitle);
-MARKUP_DEF(subtitle, BLOCK, cSubtitle);
-MARKUP_DEF(tagline, BLOCK, cTagline);
-MARKUP_DEF(caption, BLOCK, cCaption);
-MARKUP_DEF(inscription, BLOCK, cInscription);
-
-MARKUP_DEF(code, INLINE, cCode);
-MARKUP_DEF(del, INLINE, cDel);
-MARKUP_DEF(em, INLINE, cEm);
-MARKUP_DEF(ins, INLINE, cIns);
-MARKUP_DEF(span, INLINE, cSpan);
-MARKUP_DEF(strong, INLINE, cStrong);
-MARKUP_DEF(sub, INLINE, cSub);
-MARKUP_DEF(sup, INLINE, cSup);
-
-VALUE
-shoes_canvas_link(int argc, VALUE *argv, VALUE self)
-{
- long i;
- VALUE msgs, attr, text;
- SETUP();
- msgs = rb_ary_new();
- attr = Qnil;
- for (i = 0; i < argc; i++)
- {
- if (rb_obj_is_kind_of(argv[i], rb_cHash))
- attr = argv[i];
- else
- rb_ary_push(msgs, argv[i]);
- }
+VALUE shoes_canvas_line_to(VALUE self, VALUE _x, VALUE _y) {
+ double x, y;
+ SETUP_SHAPE();
- if (rb_block_given_p())
- {
- if (NIL_P(attr)) attr = rb_hash_new();
- rb_hash_aset(attr, ID2SYM(s_click), rb_block_proc());
- }
+ x = NUM2DBL(_x);
+ y = NUM2DBL(_y);
- MARKUP_INLINE(cLink);
- return text;
-}
-
-VALUE
-shoes_canvas_imagesize(VALUE self, VALUE _path)
-{
- int w, h;
- if (shoes_load_imagesize(_path, &w, &h) == SHOES_OK)
- return rb_ary_new3(2, INT2NUM(w), INT2NUM(h));
- return Qnil;
-}
-
-VALUE
-shoes_canvas_background(int argc, VALUE *argv, VALUE self)
-{
- VALUE pat;
- SETUP();
- if (argc == 1 && rb_respond_to(argv[0], s_to_pattern))
- pat = argv[0];
- else
- pat = shoes_pattern_args(argc, argv, self);
- if (!NIL_P(pat))
- {
- pat = rb_funcall(pat, s_to_pattern, 0);
- pat = shoes_subpattern_new(cBackground, pat, self);
- shoes_add_ele(canvas, pat);
- }
- return pat;
-}
-
-VALUE
-shoes_canvas_border(int argc, VALUE *argv, VALUE self)
-{
- VALUE pat;
- SETUP();
- if (argc == 1 && rb_respond_to(argv[0], s_to_pattern))
- pat = argv[0];
- else
- pat = shoes_pattern_args(argc, argv, self);
- if (!NIL_P(pat))
- {
- pat = rb_funcall(pat, s_to_pattern, 0);
- pat = shoes_subpattern_new(cBorder, pat, self);
- shoes_add_ele(canvas, pat);
- }
- return pat;
-}
-
-VALUE
-shoes_canvas_image(int argc, VALUE *argv, VALUE self)
-{
- rb_arg_list args;
- VALUE path = Qnil, attr = Qnil, _w, _h, image;
-
- switch (rb_parse_args(argc, argv, "ii|h,s|h,|h", &args))
- {
- case 1:
- _w = args.a[0];
- _h = args.a[1];
- attr = args.a[2];
- ATTRSET(attr, width, _w);
- ATTRSET(attr, height, _h);
- if (rb_block_given_p()) ATTRSET(attr, draw, rb_block_proc());
- break;
-
- case 2:
- path = args.a[0];
- attr = args.a[1];
- if (rb_block_given_p()) ATTRSET(attr, click, rb_block_proc());
- break;
-
- case 3:
- attr = args.a[0];
- if (rb_block_given_p()) ATTRSET(attr, draw, rb_block_proc());
- break;
- }
-
- if (rb_obj_is_kind_of(self, cImage))
- {
- shoes_image_image(self, path, attr);
+ if (canvas->shape != NULL) cairo_line_to(canvas->shape, x, y);
return self;
- }
-
- SETUP();
- image = shoes_image_new(cImage, path, attr, self, canvas->st);
- shoes_add_ele(canvas, image);
-
- return image;
-}
-
-VALUE
-shoes_canvas_animate(int argc, VALUE *argv, VALUE self)
-{
- rb_arg_list args;
- VALUE anim;
- SETUP();
-
- rb_parse_args(argc, argv, "|I&", &args);
- anim = shoes_timer_new(cAnim, args.a[0], args.a[1], self);
- rb_ary_push(canvas->app->extras, anim);
- return anim;
-}
-
-VALUE
-shoes_canvas_every(int argc, VALUE *argv, VALUE self)
-{
- rb_arg_list args;
- VALUE ev;
- SETUP();
-
- rb_parse_args(argc, argv, "|F&", &args);
- ev = shoes_timer_new(cEvery, args.a[0], args.a[1], self);
- rb_ary_push(canvas->app->extras, ev);
- return ev;
-}
-
-VALUE
-shoes_canvas_timer(int argc, VALUE *argv, VALUE self)
-{
- rb_arg_list args;
- VALUE timer;
- SETUP();
-
- rb_parse_args(argc, argv, "|I&", &args);
- timer = shoes_timer_new(cTimer, args.a[0], args.a[1], self);
- rb_ary_push(canvas->app->extras, timer);
- return timer;
-}
-
-VALUE
-shoes_canvas_svg(int argc, VALUE *argv, VALUE self)
-{
- VALUE widget;
- SETUP();
- widget = shoes_svg_new(argc, argv, self);
- shoes_add_ele(canvas, widget);
- return widget;
-}
-
-VALUE
-shoes_canvas_svghandle(int argc, VALUE *argv, VALUE self)
-{
- VALUE han;
- SETUP();
- han = shoes_svghandle_new(argc, argv, self);
- return han;
-}
-
-
-VALUE
-shoes_canvas_plot(int argc, VALUE *argv, VALUE self)
-{
- VALUE widget;
- SETUP();
- widget = shoes_plot_new(argc, argv, self);
- shoes_add_ele(canvas, widget);
- return widget;
-}
-
-VALUE
-shoes_canvas_chart_series(int argc, VALUE *argv, VALUE self)
-{
- VALUE cs;
- SETUP();
- cs = shoes_chart_series_new(argc, argv, self);
- return cs;
-}
-
-
-VALUE
-shoes_canvas_shape(int argc, VALUE *argv, VALUE self)
-{
- int x;
- double x1, y1, x2, y2;
- cairo_t *shape = NULL;
- cairo_path_t *line = NULL;
- SETUP_SHAPE();
-
- shape = canvas->shape;
- VALUE attr = shoes_shape_attr(argc, argv, 2, s_left, s_top);
- canvas->shape = cairo_create(cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 1, 1));
- cairo_move_to(canvas->shape, 0, 0);
- if (rb_block_given_p()) rb_funcall(rb_block_proc(), s_call, 0);
-
-#if CAIRO_VERSION_MAJOR == 1 && CAIRO_VERSION_MINOR <= 4
- cairo_fill_extents(canvas->shape, &x1, &y1, &x2, &y2);
-#else
- cairo_path_extents(canvas->shape, &x1, &y1, &x2, &y2);
-#endif
- x = ROUND(x2 - x1);
- ATTRSET(attr, width, INT2NUM(x));
- x = ROUND(y2 - y1);
- ATTRSET(attr, height, INT2NUM(x));
- line = cairo_copy_path(canvas->shape);
- canvas->shape = shape;
- return shoes_add_shape(self, s_shape, attr, line);
-}
-
-VALUE
-shoes_canvas_move_to(VALUE self, VALUE _x, VALUE _y)
-{
- double x, y;
- SETUP_SHAPE();
-
- x = NUM2DBL(_x);
- y = NUM2DBL(_y);
-
- if (canvas->shape != NULL) cairo_move_to(canvas->shape, x, y);
- return self;
-}
-
-VALUE
-shoes_canvas_line_to(VALUE self, VALUE _x, VALUE _y)
-{
- double x, y;
- SETUP_SHAPE();
-
- x = NUM2DBL(_x);
- y = NUM2DBL(_y);
-
- if (canvas->shape != NULL) cairo_line_to(canvas->shape, x, y);
- return self;
-}
-
-VALUE
-shoes_canvas_curve_to(VALUE self, VALUE _x1, VALUE _y1, VALUE _x2, VALUE _y2, VALUE _x3, VALUE _y3)
-{
- double x1, y1, x2, y2, x3, y3;
- SETUP_SHAPE();
-
- x1 = NUM2DBL(_x1);
- y1 = NUM2DBL(_y1);
- x2 = NUM2DBL(_x2);
- y2 = NUM2DBL(_y2);
- x3 = NUM2DBL(_x3);
- y3 = NUM2DBL(_y3);
-
- if (canvas->shape != NULL) cairo_curve_to(canvas->shape, x1, y1, x2, y2, x3, y3);
- return self;
-}
-
-VALUE
-shoes_canvas_arc_to(VALUE self, VALUE _x, VALUE _y, VALUE _w, VALUE _h, VALUE _a1, VALUE _a2)
-{
- double x, y, w, h, a1, a2;
- SETUP_SHAPE();
-
- x = NUM2DBL(_x);
- y = NUM2DBL(_y);
- w = NUM2DBL(_w);
- h = NUM2DBL(_h);
- a1 = NUM2DBL(_a1);
- a2 = NUM2DBL(_a2);
-
- if (canvas->shape != NULL)
- {
- cairo_save(canvas->shape);
- shoes_cairo_arc(canvas->shape, x, y, w, h, a1, a2);
- cairo_restore(canvas->shape);
- }
- return self;
}
-VALUE
-shoes_canvas_push(VALUE self)
-{
- shoes_transform *m;
- SETUP();
-
- m = canvas->st;
- if (canvas->stl + 1 > canvas->stt)
- {
- canvas->stt += 8;
- SHOE_REALLOC_N(canvas->sts, shoes_transform *, canvas->stt);
- }
- canvas->st = shoes_transform_new(m);
- canvas->sts[canvas->stl++] = m;
- return self;
-}
+VALUE shoes_canvas_curve_to(VALUE self, VALUE _x1, VALUE _y1, VALUE _x2, VALUE _y2, VALUE _x3, VALUE _y3) {
+ double x1, y1, x2, y2, x3, y3;
+ SETUP_SHAPE();
-VALUE
-shoes_canvas_pop(VALUE self)
-{
- SETUP();
+ x1 = NUM2DBL(_x1);
+ y1 = NUM2DBL(_y1);
+ x2 = NUM2DBL(_x2);
+ y2 = NUM2DBL(_y2);
+ x3 = NUM2DBL(_x3);
+ y3 = NUM2DBL(_y3);
- if (canvas->stl >= 1)
- {
- shoes_transform_release(canvas->st);
- canvas->stl--;
- canvas->st = canvas->sts[canvas->stl];
- }
- return self;
-}
-
-VALUE
-shoes_canvas_reset(VALUE self)
-{
- SETUP();
- shoes_canvas_reset_transform(canvas);
- return self;
-}
-
-VALUE
-shoes_canvas_button(int argc, VALUE *argv, VALUE self)
-{
- rb_arg_list args;
- VALUE text = Qnil, attr = Qnil, button;
- SETUP();
-
- switch (rb_parse_args(argc, argv, "s|h,|h", &args))
- {
- case 1:
- text = args.a[0];
- attr = args.a[1];
- break;
-
- case 2:
- attr = args.a[0];
- break;
- }
+ if (canvas->shape != NULL) cairo_curve_to(canvas->shape, x1, y1, x2, y2, x3, y3);
+ return self;
+}
- if (!NIL_P(text))
- ATTRSET(attr, text, text);
+VALUE shoes_canvas_arc_to(VALUE self, VALUE _x, VALUE _y, VALUE _w, VALUE _h, VALUE _a1, VALUE _a2) {
+ double x, y, w, h, a1, a2;
+ SETUP_SHAPE();
- if (rb_block_given_p())
- ATTRSET(attr, click, rb_block_proc());
+ x = NUM2DBL(_x);
+ y = NUM2DBL(_y);
+ w = NUM2DBL(_w);
+ h = NUM2DBL(_h);
+ a1 = NUM2DBL(_a1);
+ a2 = NUM2DBL(_a2);
- button = shoes_control_new(cButton, attr, self);
- shoes_add_ele(canvas, button);
- return button;
+ if (canvas->shape != NULL) {
+ cairo_save(canvas->shape);
+ shoes_cairo_arc(canvas->shape, x, y, w, h, a1, a2);
+ cairo_restore(canvas->shape);
+ }
+ return self;
}
-VALUE
-shoes_canvas_edit_line(int argc, VALUE *argv, VALUE self)
-{
- rb_arg_list args;
- VALUE phrase = Qnil, attr = Qnil, edit_line;
- SETUP();
+VALUE shoes_canvas_push(VALUE self) {
+ shoes_transform *m;
+ SETUP_CANVAS();
- switch (rb_parse_args(argc, argv, "h,S|h,", &args))
- {
- case 1:
- attr = args.a[0];
- break;
+ m = canvas->st;
+ if (canvas->stl + 1 > canvas->stt) {
+ canvas->stt += 8;
+ SHOE_REALLOC_N(canvas->sts, shoes_transform *, canvas->stt);
+ }
+ canvas->st = shoes_transform_new(m);
+ canvas->sts[canvas->stl++] = m;
+ return self;
+}
- case 2:
- phrase = args.a[0];
- attr = args.a[1];
- break;
- }
+VALUE shoes_canvas_pop(VALUE self) {
+ SETUP_CANVAS();
- if (!NIL_P(phrase))
- ATTRSET(attr, text, phrase);
+ if (canvas->stl >= 1) {
+ shoes_transform_release(canvas->st);
+ canvas->stl--;
+ canvas->st = canvas->sts[canvas->stl];
+ }
+ return self;
+}
- if (rb_block_given_p())
- ATTRSET(attr, change, rb_block_proc());
+VALUE shoes_canvas_reset(VALUE self) {
+ SETUP_CANVAS();
+ shoes_canvas_reset_transform(canvas);
+ return self;
+}
- edit_line = shoes_control_new(cEditLine, attr, self);
- shoes_add_ele(canvas, edit_line);
- return edit_line;
+VALUE shoes_canvas_contents(VALUE self) {
+ GET_STRUCT(canvas, self_t);
+ return self_t->contents;
}
-VALUE
-shoes_canvas_edit_box(int argc, VALUE *argv, VALUE self)
-{
- rb_arg_list args;
- VALUE phrase = Qnil, attr = Qnil, edit_box;
- SETUP();
+VALUE shoes_canvas_children(VALUE self) {
+ GET_STRUCT(canvas, self_t);
+ return self_t->contents;
+}
- switch (rb_parse_args(argc, argv, "h,S|h,", &args))
- {
- case 1:
- attr = args.a[0];
- break;
+void shoes_canvas_remove_item(VALUE self, VALUE item, char c, char t) {
+ long i;
+ shoes_canvas *self_t;
+ Data_Get_Struct(self, shoes_canvas, self_t);
+ shoes_native_remove_item(self_t->slot, item, c);
+ if (t) {
+ i = rb_ary_index_of(self_t->app->extras, item);
+ if (i >= 0)
+ rb_ary_insert_at(self_t->app->extras, i, 1, Qnil);
+// rb_ary_delete(self_t->app->extras, item);
+ }
+ rb_ary_delete(self_t->contents, item);
+}
- case 2:
- phrase = args.a[0];
- attr = args.a[1];
- break;
- }
+static int shoes_canvas_inherits(VALUE ele, shoes_canvas *pc) {
+ if (rb_obj_is_kind_of(ele, cCanvas)) {
+ shoes_canvas *c;
+ Data_Get_Struct(ele, shoes_canvas, c);
+ return (pc == c || DC(c->slot) == DC(pc->slot));
+ }
- if (!NIL_P(phrase))
- ATTRSET(attr, text, phrase);
+ return TRUE;
+}
- if (rb_block_given_p())
- ATTRSET(attr, change, rb_block_proc());
+int shoes_canvas_independent(shoes_canvas *c) {
+ shoes_canvas *pc;
+ if (NIL_P(c->parent)) return TRUE;
+
+ Data_Get_Struct(c->parent, shoes_canvas, pc);
+ return !(pc == c || DC(c->slot) == DC(pc->slot));
+}
+
+static void shoes_canvas_reflow(shoes_canvas *self_t, VALUE c) {
+ shoes_canvas *parent;
+ Data_Get_Struct(c, shoes_canvas, parent);
+
+ self_t->cr = parent->cr;
+ shoes_place_decide(&self_t->place, c, self_t->attr, parent->place.iw, 0, REL_CANVAS, FALSE);
+ self_t->width = self_t->place.w;
+ self_t->height = self_t->place.h;
+
+ self_t->cx = self_t->place.ix;
+ self_t->cy = self_t->place.iy;
+ self_t->endx = self_t->place.ix;
+ self_t->endy = self_t->place.iy;
+ INFO("REFLOW: %d, %d (%d, %d) / %d, %d / %d, %d (%d, %d)\n", self_t->cx, self_t->cy,
+ self_t->endx, self_t->endy, self_t->place.x, self_t->place.y, self_t->width, self_t->height,
+ parent->cx, parent->cy);
+}
+
+VALUE shoes_canvas_remove(VALUE self) {
+ shoes_canvas *self_t;
+ Data_Get_Struct(self, shoes_canvas, self_t);
+ shoes_canvas_empty(self_t, TRUE);
+ self_t->stage = CANVAS_EMPTY; // to be able to remove everything in shoes_canvas_repaint_all
+ if (!NIL_P(self_t->parent)) {
+ shoes_canvas *pc;
+ shoes_canvas_remove_item(self_t->parent, self, 0, 0);
+ Data_Get_Struct(self_t->parent, shoes_canvas, pc);
+ if (pc != self_t && DC(self_t->slot) != DC(pc->slot))
+ shoes_slot_destroy(self_t, pc);
+ shoes_canvas_repaint_all(self);
+ }
+ shoes_canvas_send_finish(self);
+ return self;
+}
- edit_box = shoes_control_new(cEditBox, attr, self);
- shoes_add_ele(canvas, edit_box);
- return edit_box;
+VALUE shoes_canvas_refresh_slot(VALUE self) {
+ shoes_canvas_repaint_all(self);
+ return self;
}
-VALUE
-shoes_canvas_text_edit_box(int argc, VALUE *argv, VALUE self)
-{
- rb_arg_list args;
- VALUE phrase = Qnil, attr = Qnil, text_edit_box;
- SETUP();
+static void shoes_canvas_place(shoes_canvas *self_t) {
+ shoes_canvas *pc;
+ Data_Get_Struct(self_t->parent, shoes_canvas, pc);
+ shoes_native_canvas_place(self_t, pc);
+}
- switch (rb_parse_args(argc, argv, "h,S|h,", &args))
- {
- case 1:
- attr = args.a[0];
- break;
+VALUE shoes_canvas_draw(VALUE self, VALUE c, VALUE actual) {
+ long i;
+ shoes_canvas *self_t;
+ shoes_canvas *canvas;
+ VALUE ck = rb_obj_class(self);
+ Data_Get_Struct(self, shoes_canvas, self_t);
+ Data_Get_Struct(c, shoes_canvas, canvas);
+#ifdef SHOES_GTK
+ if (!RTEST(actual))
+ canvas->group.radios = NULL;
+#endif
- case 2:
- phrase = args.a[0];
- attr = args.a[1];
- break;
- }
+ if (self_t->height > self_t->fully)
+ self_t->fully = self_t->height;
+ if (self_t != canvas) {
+ shoes_canvas_reflow(self_t, c);
+ } else {
+ self_t->endx = self_t->cx = 0;
+ self_t->topy = self_t->endy = self_t->cy = 0;
+ }
- if (!NIL_P(phrase))
- ATTRSET(attr, text, phrase);
+ if (ATTR(self_t->attr, hidden) != Qtrue) {
+ VALUE masks = Qnil;
+ cairo_t *cr = NULL, *crc = NULL, *crm = NULL;
+ cairo_surface_t *surfc = NULL, *surfm = NULL;
- if (rb_block_given_p())
- ATTRSET(attr, change, rb_block_proc());
+ for (i = 0; i < RARRAY_LEN(self_t->contents); i++) {
+ VALUE ele = rb_ary_entry(self_t->contents, i);
+ if (rb_obj_class(ele) == cMask) {
+ if (NIL_P(masks)) masks = rb_ary_new();
+ rb_ary_push(masks, ele);
+ }
+ }
- text_edit_box = shoes_control_new(cTextEditBox, attr, self);
- shoes_add_ele(canvas, text_edit_box);
- return text_edit_box;
-}
+ if (!NIL_P(masks) && RTEST(actual)) {
+ cr = self_t->cr;
+ surfc = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, canvas->place.iw, canvas->place.ih);
+ surfm = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, canvas->place.iw, canvas->place.ih);
+ crc = cairo_create(surfc);
+ crm = cairo_create(surfm);
+ }
-VALUE
-shoes_canvas_list_box(int argc, VALUE *argv, VALUE self)
-{
- rb_arg_list args;
- VALUE list_box;
- SETUP();
+ self_t->topy = canvas->cy;
+
+ for (i = 0; i < RARRAY_LEN(self_t->contents); i++) {
+ shoes_canvas *c1;
+ VALUE ele = rb_ary_entry(self_t->contents, i);
+ Data_Get_Struct(ele, shoes_canvas, c1);
+
+ if (shoes_canvas_inherits(ele, self_t)) {
+ if (!NIL_P(masks) && RTEST(actual)) {
+ if (rb_obj_class(ele) == cMask)
+ self_t->cr = crm;
+ else
+ self_t->cr = crc;
+ }
+ rb_funcall(ele, s_draw, 2, self, actual);
+
+ if (rb_obj_is_kind_of(ele, cCanvas)) {
+ long j;
+ //
+ // update the height of all canvases in this row
+ //
+ for (j = i - 1; j >= 0; j--) {
+ shoes_canvas *c2;
+ VALUE ele2 = rb_ary_entry(self_t->contents, j);
+ if (rb_obj_is_kind_of(ele2, cCanvas)) {
+ Data_Get_Struct(ele2, shoes_canvas, c2);
+ if (c2->topy < c1->topy || ABSY(c2->place) || POS(c2->place) != REL_CANVAS)
+ break;
+ if (c1->fully > c2->fully)
+ c2->fully = c1->fully;
+ else
+ c1->fully = c2->fully;
+ }
+ }
+ }
+ } else {
+ shoes_place_decide(&c1->place, c1->parent, c1->attr, self_t->place.iw, 0, REL_CANVAS, FALSE);
+ c1->height = c1->place.ih;
+ c1->width = c1->place.iw;
+ c1->place.flags |= FLAG_ORIGIN;
+ if (!ABSY(c1->place)) {
+ self_t->cx = c1->place.x + c1->place.w;
+ self_t->cy = c1->place.y;
+ self_t->endx = self_t->cx;
+ self_t->endy = max(self_t->endy, c1->place.y + c1->place.h);
+ }
+ if (ck == cStack) {
+ self_t->cx = self_t->place.x;
+ self_t->cy = self_t->endy;
+ }
+ if (RTEST(actual)) {
+ shoes_canvas_place(c1);
+ }
+ }
+ }
- rb_parse_args(argc, argv, "|h&", &args);
+ if (!NIL_P(masks) && RTEST(actual)) {
+ cairo_set_source_surface(cr, surfc, 0., 0.);
+ cairo_mask_surface(cr, surfm, 0., 0.);
+ cairo_surface_destroy(surfm);
+ cairo_surface_destroy(surfc);
+ cairo_destroy(crc);
+ cairo_destroy(crm);
+ self_t->cr = cr;
+ }
+ }
- if (!NIL_P(args.a[1]))
- ATTRSET(args.a[0], change, args.a[1]);
+ if (self_t == canvas) {
+ for (i = 0; i < RARRAY_LEN(self_t->app->extras); i++) {
+ VALUE ele = rb_ary_entry(self_t->app->extras, i);
+ if (rb_respond_to(ele, s_draw))
+ rb_funcall(ele, s_draw, 2, self, actual);
+ }
+ }
+ canvas->endx = canvas->cx = self_t->place.x + self_t->width;
+ if (canvas->endy < self_t->endy)
+ canvas->endy = self_t->endy;
+
+ if (self_t == canvas || DC(self_t->slot) != DC(canvas->slot)) {
+ int endy = (int)self_t->endy;
+ if (endy < self_t->height) endy = self_t->height;
+ self_t->fully = endy;
+ if (RTEST(actual)) {
+ self_t->slot->scrolly = min(self_t->slot->scrolly, self_t->fully - self_t->height);
+ if (NIL_P(self_t->parent) || RTEST(ATTR(self_t->attr, scroll)))
+ shoes_native_slot_lengthen(self_t->slot, self_t->height, endy);
+ }
+ } else {
+ int bmargin = CPB(self_t);
+ self_t->fully = canvas->endy = max(canvas->endy, self_t->endy + bmargin);
+ self_t->place.ih = (canvas->endy - self_t->place.iy) - bmargin;
+ self_t->place.h = canvas->endy - self_t->place.y;
+ }
- list_box = shoes_control_new(cListBox, args.a[0], self);
- shoes_add_ele(canvas, list_box);
- return list_box;
+ if (self_t->cr == canvas->cr)
+ self_t->cr = NULL;
+ return self;
}
-VALUE
-shoes_canvas_progress(int argc, VALUE *argv, VALUE self)
-{
- rb_arg_list args;
- VALUE progress;
- SETUP();
-
- rb_parse_args(argc, argv, "|h", &args);
- progress = shoes_control_new(cProgress, args.a[0], self);
- shoes_add_ele(canvas, progress);
- return progress;
+static void shoes_canvas_memdraw(VALUE self, VALUE block) {
+ SETUP_CANVAS();
+ DRAW(self, canvas->app, rb_funcall(block, s_call, 0));
}
-VALUE
-shoes_canvas_slider(int argc, VALUE *argv, VALUE self)
-{
- rb_arg_list args;
- VALUE slider;
- SETUP();
+typedef cairo_public cairo_surface_t * (cairo_surface_function_t) (const char *filename, double width, double height);
- rb_parse_args(argc, argv, "|h&", &args);
+static cairo_surface_function_t * shoes_get_snapshot_surface(VALUE _format) {
+ ID format = SYM2ID (_format);
+ if (format == rb_intern ("pdf")) return & cairo_pdf_surface_create;
+ if (format == rb_intern ("ps")) return & cairo_ps_surface_create;
+ if (format == rb_intern ("svg")) return & cairo_svg_surface_create;
+ return NULL;
+}
+
+VALUE shoes_canvas_snapshot(int argc, VALUE *argv, VALUE self) {
+ SETUP_CANVAS();
+ rb_arg_list args;
+ ID s_filename = rb_intern ("filename");
+ ID s_format = rb_intern ("format");
+ VALUE _filename, _format;
+ rb_parse_args(argc, argv, "h&", &args);
+ //rb_parse_args(argc, argv, "h", &args);
+
+ _filename = ATTR(args.a[0], filename);
+ _format = ATTR(args.a[0], format);
+ if (NIL_P(args.a[1]) || NIL_P(_filename) || NIL_P(_format)) {
+ rb_raise(rb_eArgError, "wrong arguments for _snapshot({:filename=>'...',"
+ ":format=>:pdf|:ps|:svg}, &block)\n");
+ } else {
+ const char * filename = RSTRING_PTR(_filename);
+ cairo_surface_t * surface = shoes_get_snapshot_surface(_format)
+ (filename, canvas->width, canvas->height);
+ if (surface == NULL) {
+ rb_raise(rb_eArgError, "Failed to create %s surface for file %s\n",
+ RSTRING_PTR(rb_inspect(_format)),
+ RSTRING_PTR(rb_inspect(_filename)));
+ } else {
+ cairo_t * waz_cr = canvas->cr;
+ cairo_t * cr = canvas->cr = cairo_create(surface);
+ DRAW(self, canvas->app, rb_funcall(args.a[1], s_call, 0));
+ //shoes_canvas_draw (self, self, Qfalse);
+ shoes_canvas_draw(self, self, Qtrue);
+ canvas->cr = waz_cr;
+ cairo_show_page(cr);
+ cairo_destroy(cr);
+ cairo_surface_destroy(surface);
+ // TODO detect cairo outrages here
+ }
+ }
+ return Qnil;
+}
- if (!NIL_P(args.a[1]))
- ATTRSET(args.a[0], change, args.a[1]);
+void shoes_canvas_compute(VALUE self) {
+ SETUP_CANVAS();
+ if (!shoes_canvas_independent(canvas))
+ return shoes_canvas_compute(canvas->parent);
- slider = shoes_control_new(cSlider, args.a[0], self);
- shoes_add_ele(canvas, slider);
- return slider;
+ cairo_save(cr);
+ shoes_canvas_draw(self, self, Qfalse);
+ cairo_restore(cr);
}
-VALUE
-shoes_canvas_radio(int argc, VALUE *argv, VALUE self)
-{
- rb_arg_list args;
- VALUE group = Qnil, attr = Qnil, radio;
- SETUP();
-
- switch (rb_parse_args(argc, argv, "h,o|h,", &args))
- {
- case 1:
- attr = args.a[0];
- break;
+static void shoes_canvas_insert(VALUE self, long i, VALUE ele, VALUE block) {
+ SETUP_CANVAS();
- case 2:
- group = args.a[0];
- attr = args.a[1];
- break;
- }
+ if (canvas->insertion != -2)
+ rb_raise(eInvMode, "this slot is already being modified by an append, clear, etc.");
- if (!NIL_P(group))
- ATTRSET(attr, group, group);
- if (rb_block_given_p())
- ATTRSET(attr, click, rb_block_proc());
+ if (!NIL_P(ele))
+ i = rb_ary_index_of(canvas->contents, ele) - i;
- radio = shoes_control_new(cRadio, attr, self);
- shoes_add_ele(canvas, radio);
- return radio;
+ canvas->insertion = i;
+ if (rb_respond_to(block, s_widget))
+ rb_funcall(block, s_widget, 1, self);
+ else
+ shoes_canvas_memdraw(self, block);
+ canvas->insertion = -2;
+ shoes_canvas_repaint_all(self);
}
-VALUE
-shoes_canvas_check(int argc, VALUE *argv, VALUE self)
-{
- rb_arg_list args;
- VALUE check;
- SETUP();
-
- rb_parse_args(argc, argv, "|h", &args);
-
- if (rb_block_given_p())
- ATTRSET(args.a[0], click, rb_block_proc());
-
- check = shoes_control_new(cCheck, args.a[0], self);
- shoes_add_ele(canvas, check);
- return check;
+VALUE shoes_canvas_after(int argc, VALUE *argv, VALUE self) {
+ rb_arg_list args;
+ rb_parse_args(argc, argv, "eo,e&", &args);
+ shoes_canvas_insert(self, -1, args.a[0], args.a[1]);
+ return self;
}
-VALUE
-shoes_canvas_contents(VALUE self)
-{
- GET_STRUCT(canvas, self_t);
- return self_t->contents;
+VALUE shoes_canvas_before(int argc, VALUE *argv, VALUE self) {
+ rb_arg_list args;
+ rb_parse_args(argc, argv, "eo,e&", &args);
+ shoes_canvas_insert(self, 0, args.a[0], args.a[1]);
+ return self;
}
-VALUE
-shoes_canvas_children(VALUE self)
-{
- GET_STRUCT(canvas, self_t);
- return self_t->contents;
+VALUE shoes_canvas_append(int argc, VALUE *argv, VALUE self) {
+ rb_arg_list args;
+ rb_parse_args(argc, argv, "o,&", &args);
+ shoes_canvas_insert(self, -1, Qnil, args.a[0]);
+ return self;
}
-void
-shoes_canvas_remove_item(VALUE self, VALUE item, char c, char t)
-{
- long i;
- shoes_canvas *self_t;
- Data_Get_Struct(self, shoes_canvas, self_t);
- shoes_native_remove_item(self_t->slot, item, c);
- if (t)
- {
- i = rb_ary_index_of(self_t->app->extras, item);
- if (i >= 0)
- rb_ary_insert_at(self_t->app->extras, i, 1, Qnil);
-// rb_ary_delete(self_t->app->extras, item);
- }
- rb_ary_delete(self_t->contents, item);
+VALUE shoes_canvas_prepend(int argc, VALUE *argv, VALUE self) {
+ rb_arg_list args;
+ rb_parse_args(argc, argv, "o,&", &args);
+ shoes_canvas_insert(self, 0, Qnil, args.a[0]);
+ return self;
}
-static int
-shoes_canvas_inherits(VALUE ele, shoes_canvas *pc)
-{
- if (rb_obj_is_kind_of(ele, cCanvas))
- {
- shoes_canvas *c;
- Data_Get_Struct(ele, shoes_canvas, c);
- return (pc == c || DC(c->slot) == DC(pc->slot));
- }
+VALUE shoes_canvas_clear_contents(int argc, VALUE *argv, VALUE self) {
+ // VALUE block = Qnil;
+ SETUP_CANVAS();
- return TRUE;
-}
+ int i;
+ for (i = 0; i < RARRAY_LEN(canvas->contents); i++) {
+ VALUE ele = rb_ary_entry(canvas->contents, i);
+ if (rb_obj_class(ele) == cRadio) {
+ shoes_control *self_t;
+ Data_Get_Struct(ele, shoes_control, self_t);
+
+ VALUE group = ATTR(self_t->attr, group);
+ if (NIL_P(group)) group = self_t->parent;
+ // OSX clang compiler doesn't like that semicolon. it doesn't
+ // like the Qnill to boolean comparison either
+ //if (!shoes_hash_get(canvas->app->groups, group) == Qnil);
+ if (! NIL_P(shoes_hash_get(canvas->app->groups, group))) {
+ shoes_hash_set(canvas->app->groups, group, Qnil);
+ }
+ }
+ }
-int
-shoes_canvas_independent(shoes_canvas *c)
-{
- shoes_canvas *pc;
- if (NIL_P(c->parent)) return TRUE;
+ shoes_canvas_empty(canvas, FALSE);
+ if (rb_block_given_p()) {
+ shoes_canvas_memdraw(self, rb_block_proc());
+ }
- Data_Get_Struct(c->parent, shoes_canvas, pc);
- return !(pc == c || DC(c->slot) == DC(pc->slot));
+ shoes_canvas_repaint_all(self);
+ return self;
}
-static void
-shoes_canvas_reflow(shoes_canvas *self_t, VALUE c)
-{
- shoes_canvas *parent;
- Data_Get_Struct(c, shoes_canvas, parent);
+VALUE shoes_canvas_flow(int argc, VALUE *argv, VALUE self) {
+ rb_arg_list args;
+ VALUE flow;
+ SETUP_CANVAS();
- self_t->cr = parent->cr;
- shoes_place_decide(&self_t->place, c, self_t->attr, parent->place.iw, 0, REL_CANVAS, FALSE);
- self_t->width = self_t->place.w;
- self_t->height = self_t->place.h;
-
- self_t->cx = self_t->place.ix;
- self_t->cy = self_t->place.iy;
- self_t->endx = self_t->place.ix;
- self_t->endy = self_t->place.iy;
- INFO("REFLOW: %d, %d (%d, %d) / %d, %d / %d, %d (%d, %d)\n", self_t->cx, self_t->cy,
- self_t->endx, self_t->endy, self_t->place.x, self_t->place.y, self_t->width, self_t->height,
- parent->cx, parent->cy);
+ rb_parse_args(argc, argv, "|h&", &args);
+ flow = shoes_flow_new(args.a[0], self);
+ if (!NIL_P(args.a[1])) {
+ DRAW(flow, canvas->app, rb_funcall(args.a[1], s_call, 0));
+ }
+ shoes_add_ele(canvas, flow);
+ return flow;
}
-VALUE
-shoes_canvas_remove(VALUE self)
-{
- shoes_canvas *self_t;
- Data_Get_Struct(self, shoes_canvas, self_t);
- shoes_canvas_empty(self_t, TRUE);
- self_t->stage = CANVAS_EMPTY; // to be able to remove everything in shoes_canvas_repaint_all
- if (!NIL_P(self_t->parent))
- {
- shoes_canvas *pc;
- shoes_canvas_remove_item(self_t->parent, self, 0, 0);
- Data_Get_Struct(self_t->parent, shoes_canvas, pc);
- if (pc != self_t && DC(self_t->slot) != DC(pc->slot))
- shoes_slot_destroy(self_t, pc);
- shoes_canvas_repaint_all(self);
- }
- shoes_canvas_send_finish(self);
- return self;
-}
-
-VALUE
-shoes_canvas_refresh_slot(VALUE self)
-{
- shoes_canvas_repaint_all(self);
- return self;
-}
-
-static void
-shoes_canvas_place(shoes_canvas *self_t)
-{
- shoes_canvas *pc;
- Data_Get_Struct(self_t->parent, shoes_canvas, pc);
- shoes_native_canvas_place(self_t, pc);
-}
-
-VALUE
-shoes_canvas_draw(VALUE self, VALUE c, VALUE actual)
-{
- long i;
- shoes_canvas *self_t;
- shoes_canvas *canvas;
- VALUE ck = rb_obj_class(self);
- Data_Get_Struct(self, shoes_canvas, self_t);
- Data_Get_Struct(c, shoes_canvas, canvas);
-#ifdef SHOES_GTK
- if (!RTEST(actual))
- canvas->group.radios = NULL;
-#endif
+VALUE shoes_canvas_stack(int argc, VALUE *argv, VALUE self) {
+ rb_arg_list args;
+ VALUE stack;
+ SETUP_CANVAS();
- if (self_t->height > self_t->fully)
- self_t->fully = self_t->height;
- if (self_t != canvas)
- {
- shoes_canvas_reflow(self_t, c);
- }
- else
- {
- self_t->endx = self_t->cx = 0;
- self_t->topy = self_t->endy = self_t->cy = 0;
- }
-
- if (ATTR(self_t->attr, hidden) != Qtrue)
- {
- VALUE masks = Qnil;
- cairo_t *cr = NULL, *crc = NULL, *crm = NULL;
- cairo_surface_t *surfc = NULL, *surfm = NULL;
-
- for (i = 0; i < RARRAY_LEN(self_t->contents); i++)
- {
- VALUE ele = rb_ary_entry(self_t->contents, i);
- if (rb_obj_class(ele) == cMask)
- {
- if (NIL_P(masks)) masks = rb_ary_new();
- rb_ary_push(masks, ele);
- }
+ rb_parse_args(argc, argv, "|h&", &args);
+ stack = shoes_stack_new(args.a[0], self);
+ if (!NIL_P(args.a[1])) {
+ DRAW(stack, canvas->app, rb_funcall(args.a[1], s_call, 0));
}
+ shoes_add_ele(canvas, stack);
- if (!NIL_P(masks) && RTEST(actual))
- {
- cr = self_t->cr;
- surfc = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, canvas->place.iw, canvas->place.ih);
- surfm = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, canvas->place.iw, canvas->place.ih);
- crc = cairo_create(surfc);
- crm = cairo_create(surfm);
- }
-
- self_t->topy = canvas->cy;
-
- for (i = 0; i < RARRAY_LEN(self_t->contents); i++)
- {
- shoes_canvas *c1;
- VALUE ele = rb_ary_entry(self_t->contents, i);
- Data_Get_Struct(ele, shoes_canvas, c1);
-
- if (shoes_canvas_inherits(ele, self_t))
- {
- if (!NIL_P(masks) && RTEST(actual))
- {
- if (rb_obj_class(ele) == cMask)
- self_t->cr = crm;
- else
- self_t->cr = crc;
- }
- rb_funcall(ele, s_draw, 2, self, actual);
-
- if (rb_obj_is_kind_of(ele, cCanvas))
- {
- long j;
- //
- // update the height of all canvases in this row
- //
- for (j = i - 1; j >= 0; j--)
- {
- shoes_canvas *c2;
- VALUE ele2 = rb_ary_entry(self_t->contents, j);
- if (rb_obj_is_kind_of(ele2, cCanvas))
- {
- Data_Get_Struct(ele2, shoes_canvas, c2);
- if (c2->topy < c1->topy || ABSY(c2->place) || POS(c2->place) != REL_CANVAS)
- break;
- if (c1->fully > c2->fully)
- c2->fully = c1->fully;
- else
- c1->fully = c2->fully;
- }
- }
- }
- }
- else
- {
- shoes_place_decide(&c1->place, c1->parent, c1->attr, self_t->place.iw, 0, REL_CANVAS, FALSE);
- c1->height = c1->place.ih;
- c1->width = c1->place.iw;
- c1->place.flags |= FLAG_ORIGIN;
- if (!ABSY(c1->place)) {
- self_t->cx = c1->place.x + c1->place.w;
- self_t->cy = c1->place.y;
- self_t->endx = self_t->cx;
- self_t->endy = max(self_t->endy, c1->place.y + c1->place.h);
- }
- if (ck == cStack) {
- self_t->cx = self_t->place.x;
- self_t->cy = self_t->endy;
- }
- if (RTEST(actual))
- {
- shoes_canvas_place(c1);
- }
- }
- }
+ shoes_canvas *self_t;
+ Data_Get_Struct(stack, shoes_canvas, self_t);
+ return stack;
+}
- if (!NIL_P(masks) && RTEST(actual))
- {
- cairo_set_source_surface(cr, surfc, 0., 0.);
- cairo_mask_surface(cr, surfm, 0., 0.);
- cairo_surface_destroy(surfm);
- cairo_surface_destroy(surfc);
- cairo_destroy(crc);
- cairo_destroy(crm);
- self_t->cr = cr;
- }
- }
+VALUE shoes_canvas_mask(int argc, VALUE *argv, VALUE self) {
+ rb_arg_list args;
+ VALUE mask;
+ SETUP_CANVAS();
- if (self_t == canvas)
- {
- for (i = 0; i < RARRAY_LEN(self_t->app->extras); i++)
- {
- VALUE ele = rb_ary_entry(self_t->app->extras, i);
- if (rb_respond_to(ele, s_draw))
- rb_funcall(ele, s_draw, 2, self, actual);
- }
- }
- canvas->endx = canvas->cx = self_t->place.x + self_t->width;
- if (canvas->endy < self_t->endy)
- canvas->endy = self_t->endy;
-
- if (self_t == canvas || DC(self_t->slot) != DC(canvas->slot))
- {
- int endy = (int)self_t->endy;
- if (endy < self_t->height) endy = self_t->height;
- self_t->fully = endy;
- if (RTEST(actual))
- {
- self_t->slot->scrolly = min(self_t->slot->scrolly, self_t->fully - self_t->height);
- if (NIL_P(self_t->parent) || RTEST(ATTR(self_t->attr, scroll)))
- shoes_native_slot_lengthen(self_t->slot, self_t->height, endy);
+ rb_parse_args(argc, argv, "|h&", &args);
+ mask = shoes_mask_new(args.a[0], self);
+ if (!NIL_P(args.a[1])) {
+ DRAW(mask, canvas->app, rb_funcall(args.a[1], s_call, 0));
}
- }
- else
- {
- int bmargin = CPB(self_t);
- self_t->fully = canvas->endy = max(canvas->endy, self_t->endy + bmargin);
- self_t->place.ih = (canvas->endy - self_t->place.iy) - bmargin;
- self_t->place.h = canvas->endy - self_t->place.y;
- }
-
- if (self_t->cr == canvas->cr)
- self_t->cr = NULL;
- return self;
+ shoes_add_ele(canvas, mask);
+ return mask;
}
-static void
-shoes_canvas_memdraw(VALUE self, VALUE block)
-{
- SETUP();
- DRAW(self, canvas->app, rb_funcall(block, s_call, 0));
+VALUE shoes_canvas_widget(int argc, VALUE *argv, VALUE self) {
+ rb_arg_list args;
+ VALUE widget, attr = Qnil;
+ SETUP_CANVAS();
+
+ rb_parse_args(argc, argv, "k|", &args);
+ if (TYPE(argv[argc-1]) == T_HASH)
+ attr = argv[argc-1];
+ widget = shoes_widget_new(args.a[0], attr, self);
+ DRAW(widget, canvas->app, ts_funcall2(widget, rb_intern("initialize"), argc - 1, argv + 1));
+ shoes_add_ele(canvas, widget);
+ return widget;
}
-typedef cairo_public cairo_surface_t * (cairo_surface_function_t) (const char *filename, double width, double height);
+void shoes_canvas_size(VALUE self, int w, int h) {
+ SETUP_CANVAS();
+ canvas->place.iw = canvas->place.w = canvas->width = w;
+ canvas->place.ih = canvas->place.h = canvas->height = h;
+ shoes_native_canvas_resize(canvas);
+}
-static cairo_surface_function_t *
-shoes_get_snapshot_surface(VALUE _format)
-{
- ID format = SYM2ID (_format);
- if (format == rb_intern ("pdf")) return & cairo_pdf_surface_create;
- if (format == rb_intern ("ps")) return & cairo_ps_surface_create;
- if (format == rb_intern ("svg")) return & cairo_svg_surface_create;
- return NULL;
-}
-
-VALUE
-shoes_canvas_snapshot(int argc, VALUE *argv, VALUE self)
-{
- SETUP();
- rb_arg_list args;
- ID s_filename = rb_intern ("filename");
- ID s_format = rb_intern ("format");
- VALUE _filename, _format;
- rb_parse_args(argc, argv, "h&", &args);
- //rb_parse_args(argc, argv, "h", &args);
-
- _filename = ATTR(args.a[0], filename);
- _format = ATTR(args.a[0], format);
- if (NIL_P(args.a[1]) || NIL_P(_filename) || NIL_P(_format))
- {
- rb_raise(rb_eArgError, "wrong arguments for _snapshot({:filename=>'...',"
- ":format=>:pdf|:ps|:svg}, &block)\n");
- }
- else
- {
- const char * filename = RSTRING_PTR(_filename);
- cairo_surface_t * surface = shoes_get_snapshot_surface(_format)
- (filename, canvas->width, canvas->height);
- if (surface == NULL) {
- rb_raise(rb_eArgError, "Failed to create %s surface for file %s\n",
- RSTRING_PTR(rb_inspect(_format)),
- RSTRING_PTR(rb_inspect(_filename)));
- }
- else
- {
- cairo_t * waz_cr = canvas->cr;
- cairo_t * cr = canvas->cr = cairo_create(surface);
- DRAW(self, canvas->app, rb_funcall(args.a[1], s_call, 0));
- //shoes_canvas_draw (self, self, Qfalse);
- shoes_canvas_draw(self, self, Qtrue);
- canvas->cr = waz_cr;
- cairo_show_page(cr);
- cairo_destroy(cr);
- cairo_surface_destroy(surface);
- // TODO detect cairo outrages here
+VALUE shoes_find_canvas(VALUE self) {
+ while (!NIL_P(self) && !rb_obj_is_kind_of(self, cCanvas)) {
+ SETUP_BASIC();
+ self = basic->parent;
}
- }
- return Qnil;
-}
-
-void
-shoes_canvas_compute(VALUE self)
-{
- SETUP();
- if (!shoes_canvas_independent(canvas))
- return shoes_canvas_compute(canvas->parent);
-
- cairo_save(cr);
- shoes_canvas_draw(self, self, Qfalse);
- cairo_restore(cr);
-}
-
-static void
-shoes_canvas_insert(VALUE self, long i, VALUE ele, VALUE block)
-{
- SETUP();
-
- if (canvas->insertion != -2)
- rb_raise(eInvMode, "this slot is already being modified by an append, clear, etc.");
-
- if (!NIL_P(ele))
- i = rb_ary_index_of(canvas->contents, ele) - i;
-
- canvas->insertion = i;
- if (rb_respond_to(block, s_widget))
- rb_funcall(block, s_widget, 1, self);
- else
- shoes_canvas_memdraw(self, block);
- canvas->insertion = -2;
- shoes_canvas_repaint_all(self);
-}
-
-VALUE
-shoes_canvas_after(int argc, VALUE *argv, VALUE self)
-{
- rb_arg_list args;
- rb_parse_args(argc, argv, "eo,e&", &args);
- shoes_canvas_insert(self, -1, args.a[0], args.a[1]);
- return self;
-}
-
-VALUE
-shoes_canvas_before(int argc, VALUE *argv, VALUE self)
-{
- rb_arg_list args;
- rb_parse_args(argc, argv, "eo,e&", &args);
- shoes_canvas_insert(self, 0, args.a[0], args.a[1]);
- return self;
-}
-
-VALUE
-shoes_canvas_append(int argc, VALUE *argv, VALUE self)
-{
- rb_arg_list args;
- rb_parse_args(argc, argv, "o,&", &args);
- shoes_canvas_insert(self, -1, Qnil, args.a[0]);
- return self;
-}
-
-VALUE
-shoes_canvas_prepend(int argc, VALUE *argv, VALUE self)
-{
- rb_arg_list args;
- rb_parse_args(argc, argv, "o,&", &args);
- shoes_canvas_insert(self, 0, Qnil, args.a[0]);
- return self;
-}
-
-VALUE
-shoes_canvas_clear_contents(int argc, VALUE *argv, VALUE self)
-{
- // VALUE block = Qnil;
- SETUP();
-
- int i;
- for (i = 0; i < RARRAY_LEN(canvas->contents); i++)
- {
- VALUE ele = rb_ary_entry(canvas->contents, i);
- if (rb_obj_class(ele) == cRadio)
- {
- shoes_control *self_t;
- Data_Get_Struct(ele, shoes_control, self_t);
-
- VALUE group = ATTR(self_t->attr, group);
- if (NIL_P(group)) group = self_t->parent;
- // OSX clang compiler doesn't like that semicolon. it doesn't
- // like the Qnill to boolean comparison either
- //if (!shoes_hash_get(canvas->app->groups, group) == Qnil);
- if (! NIL_P(shoes_hash_get(canvas->app->groups, group)))
- {
- shoes_hash_set(canvas->app->groups, group, Qnil);
- }
+ return self;
+}
+
+VALUE shoes_canvas_get_app(VALUE self) {
+ VALUE app = Qnil, c = shoes_find_canvas(self);
+ if (rb_obj_is_kind_of(c, cCanvas)) {
+ shoes_canvas *canvas;
+ Data_Get_Struct(c, shoes_canvas, canvas);
+ app = canvas->app->self;
+ if (rb_block_given_p())
+ mfp_instance_eval(app, rb_block_proc());
}
- }
-
- shoes_canvas_empty(canvas, FALSE);
- if (rb_block_given_p()) {
- shoes_canvas_memdraw(self, rb_block_proc());
- }
-
- shoes_canvas_repaint_all(self);
- return self;
-}
-
-VALUE
-shoes_canvas_flow(int argc, VALUE *argv, VALUE self)
-{
- rb_arg_list args;
- VALUE flow;
- SETUP();
-
- rb_parse_args(argc, argv, "|h&", &args);
- flow = shoes_flow_new(args.a[0], self);
- if (!NIL_P(args.a[1]))
- {
- DRAW(flow, canvas->app, rb_funcall(args.a[1], s_call, 0));
- }
- shoes_add_ele(canvas, flow);
- return flow;
-}
-
-VALUE
-shoes_canvas_stack(int argc, VALUE *argv, VALUE self)
-{
- rb_arg_list args;
- VALUE stack;
- SETUP();
-
- rb_parse_args(argc, argv, "|h&", &args);
- stack = shoes_stack_new(args.a[0], self);
- if (!NIL_P(args.a[1]))
- {
- DRAW(stack, canvas->app, rb_funcall(args.a[1], s_call, 0));
- }
- shoes_add_ele(canvas, stack);
-
- shoes_canvas *self_t;
- Data_Get_Struct(stack, shoes_canvas, self_t);
- return stack;
-}
-
-VALUE
-shoes_canvas_mask(int argc, VALUE *argv, VALUE self)
-{
- rb_arg_list args;
- VALUE mask;
- SETUP();
-
- rb_parse_args(argc, argv, "|h&", &args);
- mask = shoes_mask_new(args.a[0], self);
- if (!NIL_P(args.a[1]))
- {
- DRAW(mask, canvas->app, rb_funcall(args.a[1], s_call, 0));
- }
- shoes_add_ele(canvas, mask);
- return mask;
-}
-
-VALUE
-shoes_canvas_widget(int argc, VALUE *argv, VALUE self)
-{
- rb_arg_list args;
- VALUE widget, attr = Qnil;
- SETUP();
-
- rb_parse_args(argc, argv, "k|", &args);
- if (TYPE(argv[argc-1]) == T_HASH)
- attr = argv[argc-1];
- widget = shoes_widget_new(args.a[0], attr, self);
- DRAW(widget, canvas->app, ts_funcall2(widget, rb_intern("initialize"), argc - 1, argv + 1));
- shoes_add_ele(canvas, widget);
- return widget;
-}
-
-VALUE
-shoes_canvas_download(int argc, VALUE *argv, VALUE self)
-{
- VALUE url, block, obj, attr = Qnil;
- SETUP();
-
- rb_scan_args(argc, argv, "11&", &url, &attr, &block);
- CHECK_HASH(attr);
- if (!NIL_P(block))
- ATTRSET(attr, finish, block);
- obj = shoes_http_threaded(self, url, attr);
- rb_ary_push(canvas->app->extras, obj);
- return obj;
-}
-
-void
-shoes_canvas_size(VALUE self, int w, int h)
-{
- SETUP();
- canvas->place.iw = canvas->place.w = canvas->width = w;
- canvas->place.ih = canvas->place.h = canvas->height = h;
- shoes_native_canvas_resize(canvas);
-}
-
-VALUE
-shoes_find_canvas(VALUE self)
-{
- while (!NIL_P(self) && !rb_obj_is_kind_of(self, cCanvas))
- {
- SETUP_BASIC();
- self = basic->parent;
- }
- return self;
+ return app;
}
-VALUE
-shoes_canvas_get_app(VALUE self)
-{
- VALUE app = Qnil, c = shoes_find_canvas(self);
- if (rb_obj_is_kind_of(c, cCanvas))
- {
+void shoes_canvas_repaint_all(VALUE self) {
shoes_canvas *canvas;
- Data_Get_Struct(c, shoes_canvas, canvas);
- app = canvas->app->self;
- if (rb_block_given_p())
- mfp_instance_eval(app, rb_block_proc());
- }
- return app;
-}
-
-void
-shoes_canvas_repaint_all(VALUE self)
-{
- shoes_canvas *canvas;
- self = shoes_find_canvas(self);
- Data_Get_Struct(self, shoes_canvas, canvas);
- if (canvas->stage == CANVAS_EMPTY) return;
- shoes_canvas_compute(self);
- shoes_slot_repaint(canvas->slot);
-}
-
-typedef VALUE (*ccallfunc)(VALUE);
-typedef void (*ccallfunc2)(SHOES_CONTROL_REF);
-
-static void
-shoes_canvas_ccall(VALUE self, ccallfunc func, ccallfunc2 func2, unsigned char check)
-{
- shoes_canvas *self_t, *pc;
- Data_Get_Struct(self, shoes_canvas, self_t);
-
- if (check) // check if already hidden by a parent canvas
- {
- pc = self_t;
- while (!NIL_P(pc->parent))
- {
- Data_Get_Struct(pc->parent, shoes_canvas, pc);
- if (RTEST(ATTR(pc->attr, hidden)))
- return;
+ self = shoes_find_canvas(self);
+ Data_Get_Struct(self, shoes_canvas, canvas);
+ if (canvas->stage == CANVAS_EMPTY) return;
+ shoes_canvas_compute(self);
+ shoes_slot_repaint(canvas->slot);
+}
+
+void shoes_canvas_ccall(VALUE self, ccallfunc func, ccallfunc2 func2, unsigned char check) {
+ shoes_canvas *self_t, *pc;
+ Data_Get_Struct(self, shoes_canvas, self_t);
+
+ if (check) { // check if already hidden by a parent canvas
+ pc = self_t;
+ while (!NIL_P(pc->parent)) {
+ Data_Get_Struct(pc->parent, shoes_canvas, pc);
+ if (RTEST(ATTR(pc->attr, hidden)))
+ return;
+ }
}
- }
- if (!NIL_P(self_t->parent))
- {
- Data_Get_Struct(self_t->parent, shoes_canvas, pc);
- if (DC(self_t->slot) != DC(pc->slot)) // if actual canvas native widget != parent canvas native widget
+ if (!NIL_P(self_t->parent)) {
+ Data_Get_Struct(self_t->parent, shoes_canvas, pc);
+ if (DC(self_t->slot) != DC(pc->slot)) // if actual canvas native widget != parent canvas native widget
#ifdef SHOES_QUARTZ
- func2(DC((NSControl *)self_t->slot));
+ func2(DC((NSControl *)self_t->slot));
#else
- func2(DC(self_t->slot));
+ func2(DC(self_t->slot));
#endif
- }
+ }
- if (!NIL_P(self_t->contents))
- {
- long i;
- for (i = 0; i < RARRAY_LEN(self_t->contents); i++)
- {
- shoes_basic *basic;
- VALUE ele = rb_ary_entry(self_t->contents, i);
- Data_Get_Struct(ele, shoes_basic, basic);
- if (!RTEST(ATTR(basic->attr, hidden)))
- {
- if (rb_obj_is_kind_of(ele, cNative))
- func(ele);
- else if (rb_obj_is_kind_of(ele, cCanvas))
- shoes_canvas_ccall(ele, func, func2, 0);
- }
+ if (!NIL_P(self_t->contents)) {
+ long i;
+ for (i = 0; i < RARRAY_LEN(self_t->contents); i++) {
+ shoes_basic *basic;
+ VALUE ele = rb_ary_entry(self_t->contents, i);
+ Data_Get_Struct(ele, shoes_basic, basic);
+ if (!RTEST(ATTR(basic->attr, hidden))) {
+ if (rb_obj_is_kind_of(ele, cNative))
+ func(ele);
+ else if (rb_obj_is_kind_of(ele, cCanvas))
+ shoes_canvas_ccall(ele, func, func2, 0);
+ }
+ }
}
- }
}
-VALUE
-shoes_canvas_hide(VALUE self)
-{
- shoes_canvas *self_t;
- Data_Get_Struct(self, shoes_canvas, self_t);
- ATTRSET(self_t->attr, hidden, Qtrue);
- shoes_canvas_ccall(self, shoes_control_temporary_hide, shoes_native_control_hide, 1);
- shoes_canvas_repaint_all(self);
- return self;
-}
-
-VALUE
-shoes_canvas_show(VALUE self)
-{
- shoes_canvas *self_t;
- Data_Get_Struct(self, shoes_canvas, self_t);
- ATTRSET(self_t->attr, hidden, Qfalse);
- shoes_canvas_ccall(self, shoes_control_temporary_show, shoes_native_control_show, 1);
- shoes_canvas_repaint_all(self);
- return self;
-}
-
-VALUE
-shoes_canvas_toggle(VALUE self)
-{
- shoes_canvas *self_t;
- Data_Get_Struct(self, shoes_canvas, self_t);
- if (RTEST(ATTR(self_t->attr, hidden)))
- shoes_canvas_show(self);
- else
- shoes_canvas_hide(self);
- return self;
+VALUE shoes_canvas_toggle(VALUE self) {
+ shoes_canvas *self_t;
+ Data_Get_Struct(self, shoes_canvas, self_t);
+ if (RTEST(ATTR(self_t->attr, hidden)))
+ shoes_canvas_show(self);
+ else
+ shoes_canvas_hide(self);
+ return self;
}
#define EVENT_HANDLER(x) \
@@ -1820,7 +935,7 @@ shoes_canvas_toggle(VALUE self)
shoes_canvas_##x(int argc, VALUE *argv, VALUE self) \
{ \
VALUE val, block; \
- SETUP(); \
+ SETUP_CANVAS(); \
rb_scan_args(argc, argv, "01&", &val, &block); \
ATTRSET(canvas->attr, x, NIL_P(block) ? val : block); \
return self; \
@@ -1837,364 +952,289 @@ EVENT_HANDLER(keyup);
//EVENT_HANDLER(start);
EVENT_HANDLER(finish);
-VALUE
-shoes_canvas_start(int argc, VALUE *argv, VALUE self)
- {
+VALUE shoes_canvas_start(int argc, VALUE *argv, VALUE self) {
VALUE val, block;
- SETUP();
+ SETUP_CANVAS();
rb_scan_args(argc, argv, "01&", &val, &block);
ATTRSET(canvas->attr, start, NIL_P(block) ? val : block);
-
+
// those two canvas are not necessarily the same !
- // they are the same when canvas has a :height
+ // they are the same when canvas has a :height
canvas->stage = CANVAS_PAINT;
((shoes_canvas *)canvas->slot->owner)->stage = CANVAS_PAINT;
// printf("app nesting size = : %ld\n", RARRAY_LEN(canvas->app->nesting));
// printf("same canvas ? : %s\n", (canvas == ((shoes_canvas *)canvas->slot->owner)) ? "yes" : "no");
-
+
return self;
- }
+}
-static void
-shoes_canvas_send_start(VALUE self)
-{
- shoes_canvas *canvas;
- Data_Get_Struct(self, shoes_canvas, canvas);
-
- if (canvas->stage == CANVAS_NADA || canvas->stage == CANVAS_PAINT) {
- int i;
- if (canvas->stage == CANVAS_NADA)
- canvas->stage = CANVAS_STARTED;
+static void shoes_canvas_send_start(VALUE self) {
+ shoes_canvas *canvas;
+ Data_Get_Struct(self, shoes_canvas, canvas);
- for (i = (int)RARRAY_LEN(canvas->contents) - 1; i >= 0; i--) {
- VALUE ele = rb_ary_entry(canvas->contents, i);
- if (rb_obj_is_kind_of(ele, cCanvas) && shoes_canvas_inherits(ele, canvas))
- shoes_canvas_send_start(ele);
- }
-
- /* This attribute is set
- * either explicitely with a :start style in the slot declaration
- * or later with the style method,
- * either by the 'start' method/event of a slot
- */
- VALUE start = ATTR(canvas->attr, start);
- if (!NIL_P(start)) {
- if (canvas->stage == CANVAS_PAINT) {
- canvas->stage = CANVAS_STARTED;
- ((shoes_canvas *)canvas->slot->owner)->stage = CANVAS_STARTED;
- shoes_native_canvas_oneshot(1, self);
- //g_timeout_add_full(G_PRIORITY_HIGH, 1, start_wait, (gpointer)self, NULL);
- } else {
+ if (canvas->stage == CANVAS_NADA || canvas->stage == CANVAS_PAINT) {
+ int i;
+ if (canvas->stage == CANVAS_NADA)
+ canvas->stage = CANVAS_STARTED;
+
+ for (i = (int)RARRAY_LEN(canvas->contents) - 1; i >= 0; i--) {
+ VALUE ele = rb_ary_entry(canvas->contents, i);
+ if (rb_obj_is_kind_of(ele, cCanvas) && shoes_canvas_inherits(ele, canvas))
+ shoes_canvas_send_start(ele);
+ }
+
+ /* This attribute is set
+ * either explicitely with a :start style in the slot declaration
+ * or later with the style method,
+ * either by the 'start' method/event of a slot
+ */
+ VALUE start = ATTR(canvas->attr, start);
+ if (!NIL_P(start)) {
+ if (canvas->stage == CANVAS_PAINT) {
+ canvas->stage = CANVAS_STARTED;
+ ((shoes_canvas *)canvas->slot->owner)->stage = CANVAS_STARTED;
+ shoes_native_canvas_oneshot(1, self);
+ //g_timeout_add_full(G_PRIORITY_HIGH, 1, start_wait, (gpointer)self, NULL);
+ } else {
// canvas->stage = CANVAS_STARTED;
// ((shoes_canvas *)canvas->slot->owner)->stage = CANVAS_STARTED;
- shoes_safe_block(self, start, rb_ary_new3(1, self));
- }
- } else if (NIL_P(start) && canvas->stage == CANVAS_PAINT) {
+ shoes_safe_block(self, start, rb_ary_new3(1, self));
+ }
+ } else if (NIL_P(start) && canvas->stage == CANVAS_PAINT) {
// printf("no start attr !! canvas->stage : %d\n", canvas->stage );
- canvas->stage = CANVAS_STARTED;
- ((shoes_canvas *)canvas->slot->owner)->stage = CANVAS_STARTED;
+ canvas->stage = CANVAS_STARTED;
+ ((shoes_canvas *)canvas->slot->owner)->stage = CANVAS_STARTED;
+ }
}
- }
}
-void
-shoes_canvas_send_finish(VALUE self)
-{
- shoes_canvas *canvas;
- Data_Get_Struct(self, shoes_canvas, canvas);
- VALUE finish = ATTR(canvas->attr, finish);
- if (!NIL_P(finish))
- shoes_safe_block(self, finish, rb_ary_new3(1, self));
-}
-
-static VALUE
-shoes_canvas_send_click2(VALUE self, int button, int x, int y, VALUE *clicked)
-{
- long i;
- int ox = x, oy = y;
- VALUE v = Qnil;
- shoes_canvas *self_t;
- Data_Get_Struct(self, shoes_canvas, self_t);
-
- if (ORIGIN(self_t->place))
- {
- oy = y + self_t->slot->scrolly;
- ox = x - self_t->place.ix + self_t->place.dx;
- oy = oy - (self_t->place.iy + self_t->place.dy);
- if (oy < self_t->slot->scrolly || ox < 0 || oy > self_t->slot->scrolly + self_t->place.ih || ox > self_t->place.iw)
- return Qnil;
- }
- if (ATTR(self_t->attr, hidden) != Qtrue)
- {
- if (self_t->app->canvas == self) // when we are the app's slot
- y -= self_t->slot->scrolly;
-
- if (IS_INSIDE(self_t, x, y))
- {
- VALUE click = ATTR(self_t->attr, click);
- if (!NIL_P(click))
- {
- if (ORIGIN(self_t->place))
- y += self_t->slot->scrolly;
- shoes_safe_block(self, click, rb_ary_new3(3, INT2NUM(button), INT2NUM(x), INT2NUM(y)));
- }
- }
+void shoes_canvas_send_finish(VALUE self) {
+ shoes_canvas *canvas;
+ Data_Get_Struct(self, shoes_canvas, canvas);
+ VALUE finish = ATTR(canvas->attr, finish);
+ if (!NIL_P(finish))
+ shoes_safe_block(self, finish, rb_ary_new3(1, self));
+}
- for (i = RARRAY_LEN(self_t->contents) - 1; i >= 0; i--)
- {
- VALUE ele = rb_ary_entry(self_t->contents, i);
- if (rb_obj_is_kind_of(ele, cCanvas))
- {
- v = shoes_canvas_send_click(ele, button, ox, oy);
- *clicked = ele;
- }
- else if (rb_obj_is_kind_of(ele, cTextBlock))
- {
- v = shoes_textblock_send_click(ele, button, ox, oy, clicked);
- }
- else if (rb_obj_is_kind_of(ele, cImage))
- {
- v = shoes_image_send_click(ele, button, ox, oy);
- *clicked = ele;
- }
- else if (rb_obj_is_kind_of(ele, cSvg))
- {
- v = shoes_svg_send_click(ele, button, ox, oy);
- *clicked = ele;
- }
- else if (rb_obj_is_kind_of(ele, cPlot))
- {
- v = shoes_plot_send_click(ele, button, ox, oy);
- *clicked = ele;
- }
- else if (rb_obj_is_kind_of(ele, cShape))
- {
- v = shoes_shape_send_click(ele, button, ox, oy);
- *clicked = ele;
- }
-
- if (!NIL_P(v))
- return v;
+VALUE shoes_canvas_send_click2(VALUE self, int button, int x, int y, VALUE *clicked) {
+ long i;
+ int ox = x, oy = y;
+ VALUE v = Qnil;
+ shoes_canvas *self_t;
+ Data_Get_Struct(self, shoes_canvas, self_t);
+
+ if (ORIGIN(self_t->place)) {
+ oy = y + self_t->slot->scrolly;
+ ox = x - self_t->place.ix + self_t->place.dx;
+ oy = oy - (self_t->place.iy + self_t->place.dy);
+ if (oy < self_t->slot->scrolly || ox < 0 || oy > self_t->slot->scrolly + self_t->place.ih || ox > self_t->place.iw)
+ return Qnil;
}
- }
+ if (ATTR(self_t->attr, hidden) != Qtrue) {
+ if (self_t->app->canvas == self) // when we are the app's slot
+ y -= self_t->slot->scrolly;
+
+ if (IS_INSIDE(self_t, x, y)) {
+ VALUE click = ATTR(self_t->attr, click);
+ if (!NIL_P(click)) {
+ if (ORIGIN(self_t->place))
+ y += self_t->slot->scrolly;
+ shoes_safe_block(self, click, rb_ary_new3(3, INT2NUM(button), INT2NUM(x), INT2NUM(y)));
+ }
+ }
- return Qnil;
-}
-
-VALUE
-shoes_canvas_mouse(VALUE self)
-{
- shoes_canvas *self_t;
- Data_Get_Struct(self, shoes_canvas, self_t);
- return rb_ary_new3(3, INT2NUM(self_t->app->mouseb),
- INT2NUM(self_t->app->mousex), INT2NUM(self_t->app->mousey));
-}
-
-VALUE
-shoes_canvas_goto(VALUE self, VALUE url)
-{
- shoes_canvas *self_t;
- Data_Get_Struct(self, shoes_canvas, self_t);
- shoes_app_goto(self_t->app, RSTRING_PTR(url));
- return self;
-}
-
-VALUE
-shoes_canvas_send_click(VALUE self, int button, int x, int y)
-{
- // INFO("click(%d, %d, %d)\n", button, x, y);
- VALUE clicked = Qnil;
- VALUE url = shoes_canvas_send_click2(self, button, x, y, &clicked);
- if (!NIL_P(url))
- {
- if (rb_obj_is_kind_of(url, rb_cProc))
- //shoes_safe_block(self, url, rb_ary_new3(1, clicked));
- shoes_safe_block(self, url, rb_ary_new3(3, INT2NUM(button), INT2NUM(x), INT2NUM(y)));
- else
- {
- shoes_canvas *self_t;
- Data_Get_Struct(self, shoes_canvas, self_t);
- shoes_app_goto(self_t->app, RSTRING_PTR(url));
- }
- }
- return Qnil;
-}
-
-void
-shoes_canvas_send_release(VALUE self, int button, int x, int y)
-{
- long i;
- int ox = x, oy = y;
- shoes_canvas *self_t;
- Data_Get_Struct(self, shoes_canvas, self_t);
-
- if (ORIGIN(self_t->place))
- {
- oy = y + self_t->slot->scrolly;
- ox = x - self_t->place.ix + self_t->place.dx;
- oy = oy - (self_t->place.iy + self_t->place.dy);
- if (oy < self_t->slot->scrolly || ox < 0 || oy > self_t->slot->scrolly + self_t->place.ih || ox > self_t->place.iw)
- return;
- }
+ for (i = RARRAY_LEN(self_t->contents) - 1; i >= 0; i--) {
+ VALUE ele = rb_ary_entry(self_t->contents, i);
+ if (rb_obj_is_kind_of(ele, cCanvas)) {
+ v = shoes_canvas_send_click(ele, button, ox, oy);
+ *clicked = ele;
+ } else if (rb_obj_is_kind_of(ele, cTextBlock)) {
+ v = shoes_textblock_send_click(ele, button, ox, oy, clicked);
+ } else if (rb_obj_is_kind_of(ele, cImage)) {
+ v = shoes_image_send_click(ele, button, ox, oy);
+ *clicked = ele;
+ } else if (rb_obj_is_kind_of(ele, cSvg)) {
+ v = shoes_svg_send_click(ele, button, ox, oy);
+ *clicked = ele;
+ } else if (rb_obj_is_kind_of(ele, cPlot)) {
+ v = shoes_plot_send_click(ele, button, ox, oy);
+ *clicked = ele;
+ } else if (rb_obj_is_kind_of(ele, cShape)) {
+ v = shoes_shape_send_click(ele, button, ox, oy);
+ *clicked = ele;
+ }
- // INFO("release(%d, %d, %d)\n", button, x, y);
-
- if (ATTR(self_t->attr, hidden) != Qtrue)
- {
- if (IS_INSIDE(self_t, x, y))
- {
- VALUE release = ATTR(self_t->attr, release);
- if (!NIL_P(release))
- {
- if (ORIGIN(self_t->place))
- y += self_t->slot->scrolly;
- shoes_safe_block(self, release, rb_ary_new3(3, INT2NUM(button), INT2NUM(x), INT2NUM(y)));
- }
+ if (!NIL_P(v))
+ return v;
+ }
}
- for (i = RARRAY_LEN(self_t->contents) - 1; i >= 0; i--)
- {
- VALUE ele = rb_ary_entry(self_t->contents, i);
- if (rb_obj_is_kind_of(ele, cCanvas))
- {
- shoes_canvas_send_release(ele, button, ox, oy);
- }
- else if (rb_obj_is_kind_of(ele, cTextBlock))
- {
- shoes_textblock_send_release(ele, button, ox, oy);
- }
- else if (rb_obj_is_kind_of(ele, cImage))
- {
- shoes_image_send_release(ele, button, ox, oy);
- }
- else if (rb_obj_is_kind_of(ele, cSvg))
- {
- shoes_svg_send_release(ele, button, ox, oy);
- }
- else if (rb_obj_is_kind_of(ele, cPlot))
- {
- shoes_plot_send_release(ele, button, ox, oy);
- }
- else if (rb_obj_is_kind_of(ele, cShape))
- {
- shoes_shape_send_release(ele, button, ox, oy);
- }
+ return Qnil;
+}
+
+VALUE shoes_canvas_mouse(VALUE self) {
+ shoes_canvas *self_t;
+ Data_Get_Struct(self, shoes_canvas, self_t);
+ return rb_ary_new3(3, INT2NUM(self_t->app->mouseb),
+ INT2NUM(self_t->app->mousex), INT2NUM(self_t->app->mousey));
+}
+
+VALUE shoes_canvas_goto(VALUE self, VALUE url) {
+ shoes_canvas *self_t;
+ Data_Get_Struct(self, shoes_canvas, self_t);
+ shoes_app_goto(self_t->app, RSTRING_PTR(url));
+ return self;
+}
+
+VALUE shoes_canvas_send_click(VALUE self, int button, int x, int y) {
+ // INFO("click(%d, %d, %d)\n", button, x, y);
+ VALUE clicked = Qnil;
+ VALUE url = shoes_canvas_send_click2(self, button, x, y, &clicked);
+ if (!NIL_P(url)) {
+ if (rb_obj_is_kind_of(url, rb_cProc))
+ //shoes_safe_block(self, url, rb_ary_new3(1, clicked));
+ shoes_safe_block(self, url, rb_ary_new3(3, INT2NUM(button), INT2NUM(x), INT2NUM(y)));
+ else {
+ shoes_canvas *self_t;
+ Data_Get_Struct(self, shoes_canvas, self_t);
+ shoes_app_goto(self_t->app, RSTRING_PTR(url));
+ }
}
- }
+ return Qnil;
}
-VALUE
-shoes_canvas_send_motion(VALUE self, int x, int y, VALUE url)
-{
- char oh, ch = 0, h = 0, *n = 0;
- long i;
- int ox = x, oy = y;
- shoes_canvas *self_t;
- Data_Get_Struct(self, shoes_canvas, self_t);
-
- oh = self_t->hover;
- ch = h = IS_INSIDE(self_t, x, y);
- CHECK_HOVER(self_t, h, n);
-
- if (ORIGIN(self_t->place))
- {
- y += self_t->slot->scrolly;
- ox = x - self_t->place.ix + self_t->place.dx;
- oy = y - (self_t->place.iy + self_t->place.dy);
- if (!oh && (oy < self_t->slot->scrolly || ox < 0 || oy > self_t->slot->scrolly + self_t->place.ih || ox > self_t->place.iw))
- return Qnil;
- }
+void shoes_canvas_send_release(VALUE self, int button, int x, int y) {
+ long i;
+ int ox = x, oy = y;
+ shoes_canvas *self_t;
+ Data_Get_Struct(self, shoes_canvas, self_t);
+
+ if (ORIGIN(self_t->place)) {
+ oy = y + self_t->slot->scrolly;
+ ox = x - self_t->place.ix + self_t->place.dx;
+ oy = oy - (self_t->place.iy + self_t->place.dy);
+ if (oy < self_t->slot->scrolly || ox < 0 || oy > self_t->slot->scrolly + self_t->place.ih || ox > self_t->place.iw)
+ return;
+ }
+
+ // INFO("release(%d, %d, %d)\n", button, x, y);
- h = 0;
- if (ATTR(self_t->attr, hidden) != Qtrue)
- {
- VALUE motion = ATTR(self_t->attr, motion);
- if (!NIL_P(motion))
- {
- shoes_safe_block(self, motion, rb_ary_new3(2, INT2NUM(x), INT2NUM(y)));
+ if (ATTR(self_t->attr, hidden) != Qtrue) {
+ if (IS_INSIDE(self_t, x, y)) {
+ VALUE release = ATTR(self_t->attr, release);
+ if (!NIL_P(release)) {
+ if (ORIGIN(self_t->place))
+ y += self_t->slot->scrolly;
+ shoes_safe_block(self, release, rb_ary_new3(3, INT2NUM(button), INT2NUM(x), INT2NUM(y)));
+ }
+ }
+
+ for (i = RARRAY_LEN(self_t->contents) - 1; i >= 0; i--) {
+ VALUE ele = rb_ary_entry(self_t->contents, i);
+ if (rb_obj_is_kind_of(ele, cCanvas)) {
+ shoes_canvas_send_release(ele, button, ox, oy);
+ } else if (rb_obj_is_kind_of(ele, cTextBlock)) {
+ shoes_textblock_send_release(ele, button, ox, oy);
+ } else if (rb_obj_is_kind_of(ele, cImage)) {
+ shoes_image_send_release(ele, button, ox, oy);
+ } else if (rb_obj_is_kind_of(ele, cSvg)) {
+ shoes_svg_send_release(ele, button, ox, oy);
+ } else if (rb_obj_is_kind_of(ele, cPlot)) {
+ shoes_plot_send_release(ele, button, ox, oy);
+ } else if (rb_obj_is_kind_of(ele, cShape)) {
+ shoes_shape_send_release(ele, button, ox, oy);
+ }
+ }
}
+}
- for (i = RARRAY_LEN(self_t->contents) - 1; i >= 0; i--)
- {
- VALUE urll = Qnil;
- VALUE ele = rb_ary_entry(self_t->contents, i);
- if (rb_obj_is_kind_of(ele, cCanvas))
- {
- urll = shoes_canvas_send_motion(ele, ox, oy, url);
- }
- else if (rb_obj_is_kind_of(ele, cTextBlock))
- {
- urll = shoes_textblock_motion(ele, ox, oy, &h);
- }
- else if (rb_obj_is_kind_of(ele, cImage))
- {
- urll = shoes_image_motion(ele, ox, oy, NULL);
- }
- else if (rb_obj_is_kind_of(ele, cSvg))
- {
- urll = shoes_svg_motion(ele, ox, oy, NULL);
- }
- else if (rb_obj_is_kind_of(ele, cPlot))
- {
- urll = shoes_plot_motion(ele, ox, oy, NULL);
- }
-
- else if (rb_obj_is_kind_of(ele, cShape))
- {
- urll = shoes_shape_motion(ele, ox, oy, NULL);
- }
-
- if (NIL_P(url)) url = urll;
+VALUE shoes_canvas_send_motion(VALUE self, int x, int y, VALUE url) {
+ char oh, ch = 0, h = 0, *n = 0;
+ long i;
+ int ox = x, oy = y;
+ shoes_canvas *self_t;
+ Data_Get_Struct(self, shoes_canvas, self_t);
+
+ oh = self_t->hover;
+ ch = h = IS_INSIDE(self_t, x, y);
+ CHECK_HOVER(self_t, h, n);
+
+ if (ORIGIN(self_t->place)) {
+ y += self_t->slot->scrolly;
+ ox = x - self_t->place.ix + self_t->place.dx;
+ oy = y - (self_t->place.iy + self_t->place.dy);
+ if (!oh && (oy < self_t->slot->scrolly || ox < 0 || oy > self_t->slot->scrolly + self_t->place.ih || ox > self_t->place.iw))
+ return Qnil;
}
- if (ch && NIL_P(url))
- {
- shoes_canvas *self_t;
- Data_Get_Struct(self, shoes_canvas, self_t);
- if (self_t->app->cursor == s_link)
- shoes_app_cursor(self_t->app, s_arrow);
+ h = 0;
+ if (ATTR(self_t->attr, hidden) != Qtrue) {
+ VALUE motion = ATTR(self_t->attr, motion);
+ if (!NIL_P(motion)) {
+ shoes_safe_block(self, motion, rb_ary_new3(2, INT2NUM(x), INT2NUM(y)));
+ }
+
+ for (i = RARRAY_LEN(self_t->contents) - 1; i >= 0; i--) {
+ VALUE urll = Qnil;
+ VALUE ele = rb_ary_entry(self_t->contents, i);
+ if (rb_obj_is_kind_of(ele, cCanvas)) {
+ urll = shoes_canvas_send_motion(ele, ox, oy, url);
+ } else if (rb_obj_is_kind_of(ele, cTextBlock)) {
+ urll = shoes_textblock_motion(ele, ox, oy, &h);
+ } else if (rb_obj_is_kind_of(ele, cImage)) {
+ urll = shoes_image_motion(ele, ox, oy, NULL);
+ } else if (rb_obj_is_kind_of(ele, cSvg)) {
+ urll = shoes_svg_motion(ele, ox, oy, NULL);
+ } else if (rb_obj_is_kind_of(ele, cPlot)) {
+ urll = shoes_plot_motion(ele, ox, oy, NULL);
+ }
+
+ else if (rb_obj_is_kind_of(ele, cShape)) {
+ urll = shoes_shape_motion(ele, ox, oy, NULL);
+ }
+
+ if (NIL_P(url)) url = urll;
+ }
+
+ if (ch && NIL_P(url)) {
+ shoes_canvas *self_t;
+ Data_Get_Struct(self, shoes_canvas, self_t);
+ if (self_t->app->cursor == s_link)
+ shoes_app_cursor(self_t->app, s_arrow);
+ }
}
- }
- if (h) shoes_canvas_repaint_all(self);
+ if (h) shoes_canvas_repaint_all(self);
- return url;
+ return url;
}
-void
-shoes_canvas_wheel_way(shoes_canvas *self_t, ID dir)
-{
+void shoes_canvas_wheel_way(shoes_canvas *self_t, ID dir) {
if (dir == s_up)
shoes_slot_scroll_to(self_t, -32, 1);
else if (dir == s_down)
shoes_slot_scroll_to(self_t, 32, 1);
}
-void
-shoes_canvas_send_wheel(VALUE self, ID dir, int x, int y)
-{
- long i;
- shoes_canvas *self_t;
- Data_Get_Struct(self, shoes_canvas, self_t);
-
- if (ATTR(self_t->attr, hidden) != Qtrue)
- {
- VALUE wheel = ATTR(self_t->attr, wheel);
- if (!NIL_P(wheel))
- {
- if (IS_INSIDE(self_t, x, y))
- shoes_canvas_wheel_way(self_t, dir);
- }
+void shoes_canvas_send_wheel(VALUE self, ID dir, int x, int y) {
+ long i;
+ shoes_canvas *self_t;
+ Data_Get_Struct(self, shoes_canvas, self_t);
+
+ if (ATTR(self_t->attr, hidden) != Qtrue) {
+ VALUE wheel = ATTR(self_t->attr, wheel);
+ if (!NIL_P(wheel)) {
+ if (IS_INSIDE(self_t, x, y))
+ shoes_canvas_wheel_way(self_t, dir);
+ }
- for (i = RARRAY_LEN(self_t->contents) - 1; i >= 0; i--)
- {
- VALUE ele = rb_ary_entry(self_t->contents, i);
- if (rb_obj_is_kind_of(ele, cCanvas))
- {
- shoes_canvas_send_wheel(ele, dir, x, y);
- }
+ for (i = RARRAY_LEN(self_t->contents) - 1; i >= 0; i--) {
+ VALUE ele = rb_ary_entry(self_t->contents, i);
+ if (rb_obj_is_kind_of(ele, cCanvas)) {
+ shoes_canvas_send_wheel(ele, dir, x, y);
+ }
+ }
}
- }
}
#define DEF_SEND_KEY_EVENT(event_name) \
@@ -2227,140 +1267,112 @@ DEF_SEND_KEY_EVENT(keydown)
DEF_SEND_KEY_EVENT(keypress)
DEF_SEND_KEY_EVENT(keyup)
-SHOES_SLOT_OS *
-shoes_slot_alloc(shoes_canvas *canvas, SHOES_SLOT_OS *parent, int toplevel)
-{
- canvas->slot = SHOE_ALLOC(SHOES_SLOT_OS);
- SHOE_MEMZERO(canvas->slot, SHOES_SLOT_OS, 1);
- canvas->slot->owner = canvas;
- return canvas->slot;
-}
-
-VALUE
-shoes_slot_new(VALUE klass, VALUE attr, VALUE parent)
-{
- shoes_canvas *self_t, *pc;
- VALUE self = shoes_canvas_alloc(klass);
- shoes_canvas_clear(self);
- Data_Get_Struct(parent, shoes_canvas, pc);
- Data_Get_Struct(self, shoes_canvas, self_t);
- self_t->cr = pc->cr;
- self_t->slot = pc->slot;
- self_t->parent = parent;
- self_t->app = pc->app;
- self_t->attr = attr;
- COPY_PENS(self_t->attr, pc->attr);
- int scrolls = RTEST(ATTR(self_t->attr, scroll));
- if ((attr != ssNestSlot && RTEST(ATTR(self_t->attr, height))) || scrolls) {
- //
- // create the slot off-screen until it can be properly placed
- //
- shoes_slot_init(self, pc->slot, -99, -99, 100, 100, scrolls, FALSE);
- self_t->place.x = self_t->place.y = 0;
- self_t->place.ix = self_t->place.iy = 0;
- }
- return self;
+SHOES_SLOT_OS *shoes_slot_alloc(shoes_canvas *canvas, SHOES_SLOT_OS *parent, int toplevel) {
+ canvas->slot = SHOE_ALLOC(SHOES_SLOT_OS);
+ SHOE_MEMZERO(canvas->slot, SHOES_SLOT_OS, 1);
+ canvas->slot->owner = canvas;
+ return canvas->slot;
+}
+
+VALUE shoes_slot_new(VALUE klass, VALUE attr, VALUE parent) {
+ shoes_canvas *self_t, *pc;
+ VALUE self = shoes_canvas_alloc(klass);
+ shoes_canvas_clear(self);
+ Data_Get_Struct(parent, shoes_canvas, pc);
+ Data_Get_Struct(self, shoes_canvas, self_t);
+ self_t->cr = pc->cr;
+ self_t->slot = pc->slot;
+ self_t->parent = parent;
+ self_t->app = pc->app;
+ self_t->attr = attr;
+ COPY_PENS(self_t->attr, pc->attr);
+ int scrolls = RTEST(ATTR(self_t->attr, scroll));
+ if ((attr != ssNestSlot && RTEST(ATTR(self_t->attr, height))) || scrolls) {
+ //
+ // create the slot off-screen until it can be properly placed
+ //
+ shoes_slot_init(self, pc->slot, -99, -99, 100, 100, scrolls, FALSE);
+ self_t->place.x = self_t->place.y = 0;
+ self_t->place.ix = self_t->place.iy = 0;
+ }
+ return self;
}
//
// Shoes::Flow
//
-VALUE
-shoes_flow_new(VALUE attr, VALUE parent)
-{
- return shoes_slot_new(cFlow, attr, parent);
+VALUE shoes_flow_new(VALUE attr, VALUE parent) {
+ return shoes_slot_new(cFlow, attr, parent);
}
//
// Shoes::Stack
//
-VALUE
-shoes_stack_new(VALUE attr, VALUE parent)
-{
- return shoes_slot_new(cStack, attr, parent);
+VALUE shoes_stack_new(VALUE attr, VALUE parent) {
+ return shoes_slot_new(cStack, attr, parent);
}
//
// Shoes::Mask
//
-VALUE
-shoes_mask_new(VALUE attr, VALUE parent)
-{
- return shoes_slot_new(cMask, attr, parent);
+VALUE shoes_mask_new(VALUE attr, VALUE parent) {
+ return shoes_slot_new(cMask, attr, parent);
}
//
// Shoes::Widget
//
-VALUE
-shoes_widget_new(VALUE klass, VALUE attr, VALUE parent)
-{
- return shoes_slot_new(klass, attr, parent);
+VALUE shoes_widget_new(VALUE klass, VALUE attr, VALUE parent) {
+ return shoes_slot_new(klass, attr, parent);
}
-VALUE
-shoes_canvas_get_cursor(VALUE self)
-{
- SETUP();
- return ID2SYM(canvas->app->cursor);
+VALUE shoes_canvas_get_cursor(VALUE self) {
+ SETUP_CANVAS();
+ return ID2SYM(canvas->app->cursor);
}
-VALUE
-shoes_canvas_set_cursor(VALUE self, VALUE name)
-{
- SETUP();
- shoes_app_cursor(canvas->app, SYM2ID(name));
- return name;
+VALUE shoes_canvas_set_cursor(VALUE self, VALUE name) {
+ SETUP_CANVAS();
+ shoes_app_cursor(canvas->app, SYM2ID(name));
+ return name;
}
//
// Global clipboard getter and setter
//
-VALUE
-shoes_canvas_get_clipboard(VALUE self)
-{
- shoes_canvas *self_t;
- Data_Get_Struct(self, shoes_canvas, self_t);
- return shoes_native_clipboard_get(self_t->app);
+VALUE shoes_canvas_get_clipboard(VALUE self) {
+ shoes_canvas *self_t;
+ Data_Get_Struct(self, shoes_canvas, self_t);
+ return shoes_native_clipboard_get(self_t->app);
}
-VALUE
-shoes_canvas_set_clipboard(VALUE self, VALUE string)
-{
- shoes_canvas *self_t;
- Data_Get_Struct(self, shoes_canvas, self_t);
- string = shoes_native_to_s(string);
- shoes_native_clipboard_set(self_t->app, string);
- return string;
+VALUE shoes_canvas_set_clipboard(VALUE self, VALUE string) {
+ shoes_canvas *self_t;
+ Data_Get_Struct(self, shoes_canvas, self_t);
+ string = shoes_native_to_s(string);
+ shoes_native_clipboard_set(self_t->app, string);
+ return string;
}
//
// Window creation
//
-VALUE
-shoes_canvas_window(int argc, VALUE *argv, VALUE self)
-{
- SETUP();
- return shoes_app_window(argc, argv, cApp, canvas->app->self);
+VALUE shoes_canvas_window(int argc, VALUE *argv, VALUE self) {
+ SETUP_CANVAS();
+ return shoes_app_window(argc, argv, cApp, canvas->app->self);
}
-VALUE
-shoes_canvas_dialog(int argc, VALUE *argv, VALUE self)
-{
- return shoes_app_window(argc, argv, cDialog, self);
+VALUE shoes_canvas_dialog(int argc, VALUE *argv, VALUE self) {
+ return shoes_app_window(argc, argv, cDialog, self);
}
-VALUE
-shoes_canvas_window_plain(VALUE self)
-{
- SETUP();
- return shoes_native_window_color(canvas->app);
+VALUE shoes_canvas_window_plain(VALUE self) {
+ SETUP_CANVAS();
+ return shoes_native_window_color(canvas->app);
}
-VALUE
-shoes_canvas_dialog_plain(VALUE self)
-{
- SETUP();
- return shoes_native_dialog_color(canvas->app);
+VALUE shoes_canvas_dialog_plain(VALUE self) {
+ SETUP_CANVAS();
+ return shoes_native_dialog_color(canvas->app);
}
diff --git a/shoes/canvas.h b/shoes/canvas.h
index af1ef422..38141af1 100644
--- a/shoes/canvas.h
+++ b/shoes/canvas.h
@@ -17,7 +17,6 @@
#include "shoes/code.h"
#include
-
struct _shoes_app;
typedef unsigned int PIXEL;
@@ -47,9 +46,9 @@ extern const char *dialog_title, *dialog_title_says;
// affine transforms, to avoid littering these structs everywhere
//
typedef struct {
- cairo_matrix_t tf;
- ID mode;
- int refs;
+ cairo_matrix_t tf;
+ ID mode;
+ int refs;
} shoes_transform;
//
@@ -57,9 +56,9 @@ typedef struct {
// (outlines the area where a control has been placed)
//
typedef struct {
- int x, y, w, h, dx, dy;
- int ix, iy, iw, ih;
- unsigned char flags;
+ int x, y, w, h, dx, dy;
+ int ix, iy, iw, ih;
+ unsigned char flags;
} shoes_place;
#define SETUP_BASIC() \
@@ -76,8 +75,6 @@ typedef struct {
blk; \
rb_ary_pop(app->nesting); \
}
-#define PATTERN_DIM(self_t, x) (self_t->cached != NULL ? self_t->cached->x : 1)
-#define PATTERN(self_t) (self_t->cached != NULL ? self_t->cached->pattern : self_t->pattern)
#define ABSX(place) ((place).flags & FLAG_ABSX)
#define ABSY(place) ((place).flags & FLAG_ABSY)
#define POS(place) ((place).flags & FLAG_POSITION)
@@ -90,113 +87,57 @@ typedef struct {
#define CCR(c) (c->cr == NULL ? c->app->scratch : c->cr)
#define SWPOS(x) ((int)sw % 2 == 0 ? x * 1. : x + .5)
-//
-// color struct
-//
-typedef struct {
- unsigned char r, g, b, a, on;
-} shoes_color;
-
-#define SHOES_COLOR_OPAQUE 0xFF
-#define SHOES_COLOR_TRANSPARENT 0x0
-#define SHOES_COLOR_DARK (0x55 * 3)
-#define SHOES_COLOR_LIGHT (0xAA * 3)
+#define SETUP_CANVAS() \
+ shoes_canvas *canvas; \
+ cairo_t *cr; \
+ Data_Get_Struct(self, shoes_canvas, canvas); \
+ cr = CCR(canvas)
+#define SETUP_IMAGE() \
+ shoes_place place; \
+ GET_STRUCT(image, image); \
+ shoes_image_ensure_dup(image); \
+ shoes_place_exact(&place, attr, 0, 0); \
+ if (NIL_P(attr)) attr = image->attr; \
+ else if (!NIL_P(image->attr)) attr = rb_funcall(image->attr, s_merge, 1, attr);
//
// basic struct
//
typedef struct {
- VALUE parent;
- VALUE attr;
+ VALUE parent;
+ VALUE attr;
} shoes_basic;
typedef struct {
- VALUE parent;
- VALUE attr;
- shoes_place place;
+ VALUE parent;
+ VALUE attr;
+ shoes_place place;
} shoes_element;
-//
-// shape struct
-//
-typedef struct {
- VALUE parent;
- VALUE attr;
- shoes_place place;
- ID name;
- char hover;
- cairo_path_t *line;
- shoes_transform *st;
-} shoes_shape;
-
//
// flow struct
//
typedef struct {
- VALUE parent;
- VALUE attr;
- VALUE contents;
+ VALUE parent;
+ VALUE attr;
+ VALUE contents;
} shoes_flow;
-//
-// link struct
-//
-typedef struct {
- int start;
- int end;
- VALUE ele;
-} shoes_link;
-
-//
-// text cursor
-//
-typedef struct {
- int pos, x, y, hi;
-} shoes_textcursor;
-
-//
-// text block struct
-//
-typedef struct {
- VALUE parent;
- VALUE attr;
- shoes_place place;
- VALUE texts;
- VALUE links;
- shoes_textcursor *cursor;
- PangoLayout *layout;
- PangoAttrList *pattr;
- GString *text;
- guint len;
- char cached, hover;
- shoes_transform *st;
-} shoes_textblock;
-
-//
-// text struct
-//
-typedef struct {
- VALUE parent;
- VALUE attr;
- VALUE texts;
- char hover;
-} shoes_text;
-
//
// cached image
//
typedef enum {
- SHOES_IMAGE_NONE,
- SHOES_IMAGE_PNG,
- SHOES_IMAGE_JPEG,
- SHOES_IMAGE_GIF
+ SHOES_IMAGE_NONE,
+ SHOES_IMAGE_PNG,
+ SHOES_IMAGE_JPEG,
+ SHOES_IMAGE_GIF
} shoes_image_format;
typedef struct {
- cairo_surface_t *surface;
- cairo_pattern_t *pattern;
- int width, height, mtime;
- shoes_image_format format;
+ cairo_surface_t *surface;
+ cairo_pattern_t *pattern;
+ int width, height, mtime;
+ shoes_image_format format;
} shoes_cached_image;
#define SHOES_CACHE_FILE 0
@@ -204,8 +145,8 @@ typedef struct {
#define SHOES_CACHE_MEM 2
typedef struct {
- unsigned char type;
- shoes_cached_image *image;
+ unsigned char type;
+ shoes_cached_image *image;
} shoes_cache_entry;
//
@@ -213,78 +154,25 @@ typedef struct {
//
#define SHOES_IMAGE_EXPIRE (60 * 60)
typedef struct {
- VALUE parent;
- VALUE attr;
- shoes_place place;
- unsigned char type;
- shoes_cached_image *cached;
- shoes_transform *st;
- cairo_t *cr;
- VALUE path;
- char hover;
+ VALUE parent;
+ VALUE attr;
+ shoes_place place;
+ unsigned char type;
+ shoes_cached_image *cached;
+ shoes_transform *st;
+ cairo_t *cr;
+ VALUE path;
+ char hover;
} shoes_image;
-
-//
-// pattern struct
-//
-typedef struct {
- VALUE parent;
- VALUE attr;
- shoes_place place;
- VALUE source;
- char hover;
- shoes_cached_image *cached;
- cairo_pattern_t *pattern;
-} shoes_pattern;
-
-//
-// native controls struct
-//
-#define CONTROL_NORMAL 0
-#define CONTROL_READONLY 1
-#define CONTROL_DISABLED 2
-
-typedef struct {
- VALUE parent;
- VALUE attr;
- shoes_place place;
- SHOES_CONTROL_REF ref;
-} shoes_control;
-
-#define ANIM_NADA 0
-#define ANIM_STARTED 1
-#define ANIM_PAUSED 2
-#define ANIM_STOPPED 3
-
-//
-// animation struct
-//
-typedef struct {
- VALUE parent;
- VALUE block;
- unsigned int rate, frame;
- char started;
- SHOES_TIMER_REF ref;
-} shoes_timer;
-
-typedef void (*shoes_effect_filter)(cairo_t *, VALUE attr, shoes_place *);
-
-typedef struct {
- VALUE parent;
- VALUE attr;
- shoes_place place;
- shoes_effect_filter filter;
-} shoes_effect;
-
typedef struct {
- VALUE parent;
- VALUE attr;
- VALUE response;
- unsigned char state;
- unsigned LONG_LONG total;
- unsigned LONG_LONG transferred;
- unsigned long percent;
+ VALUE parent;
+ VALUE attr;
+ VALUE response;
+ unsigned char state;
+ unsigned LONG_LONG total;
+ unsigned LONG_LONG transferred;
+ unsigned long percent;
} shoes_http_klass;
#define CANVAS_NADA 0
@@ -293,115 +181,85 @@ typedef struct {
#define CANVAS_EMPTY 3
#define CANVAS_REMOVED 4
-// SvgHandle struct - not a graphical widget
-// new in 3.3.0
-typedef struct _svghandle {
- RsvgHandle *handle;
- RsvgDimensionData svghdim;
- RsvgPositionData svghpos;
- char *path;
- char *data;
- char *subid;
- double aspect;
-} shoes_svghandle;
-
-//
-// SVG struct
-//
-typedef struct {
- VALUE parent;
- VALUE attr;
- shoes_place place;
- double scalew;
- double scaleh;
- VALUE svghandle;
- char hover;
- shoes_transform *st;
-} shoes_svg;
-
-
// ChartSeries struct
typedef struct {
- VALUE maxv;
- VALUE minv;
- VALUE values;
- VALUE name;
- VALUE desc;
- VALUE labels;
- VALUE strokes;
- VALUE point_type;
- VALUE color;
+ VALUE maxv;
+ VALUE minv;
+ VALUE values;
+ VALUE name;
+ VALUE desc;
+ VALUE labels;
+ VALUE strokes;
+ VALUE point_type;
+ VALUE color;
} shoes_chart_series;
//
// Plot struct - It's HUGE!
//
typedef struct {
- VALUE parent;
- VALUE attr;
- shoes_place place;
- int chart_type;
- int seriescnt;
- VALUE series;
- int auto_grid;
- int boundbox;
- int missing; // repurposed in pie_charts so beware
- VALUE background;
- VALUE title;
- VALUE legend;
- VALUE caption;
- VALUE default_colors;
- VALUE column_opts;
- void *c_things;
- int x_ticks; // number of x_axis (which means a vertical grid line draw)
- int y_ticks; // number of (left side) y axis horizontial grid lines)
- double radar_label_mult; // radius multipler (1.1 ex)
- char *fontname; // not a Shoes name, cairo "toy" name - might be the same
- int beg_idx; //used for zooming in
- int end_idx; // and zooming out
- int title_h;
- PangoFontDescription *title_pfd;
- int caption_h;
- PangoFontDescription *caption_pfd;
- int legend_h;
- PangoFontDescription *legend_pfd;
- PangoFontDescription *label_pfd;
- PangoFontDescription *tiny_pfd;
- int yaxis_offset; // don't like
- int graph_h; // to where the dots are drawn
- int graph_w;
- int graph_x;
- int graph_y;
- char hover;
- shoes_transform *st;
+ VALUE parent;
+ VALUE attr;
+ shoes_place place;
+ int chart_type;
+ int seriescnt;
+ VALUE series;
+ int auto_grid;
+ int boundbox;
+ int missing; // repurposed in pie_charts so beware
+ VALUE background;
+ VALUE title;
+ VALUE legend;
+ VALUE caption;
+ VALUE default_colors;
+ VALUE column_opts;
+ void *c_things;
+ int x_ticks; // number of x_axis (which means a vertical grid line draw)
+ int y_ticks; // number of (left side) y axis horizontial grid lines)
+ double radar_label_mult; // radius multipler (1.1 ex)
+ char *fontname; // not a Shoes name, cairo "toy" name - might be the same
+ int beg_idx; //used for zooming in
+ int end_idx; // and zooming out
+ int title_h;
+ PangoFontDescription *title_pfd;
+ int caption_h;
+ PangoFontDescription *caption_pfd;
+ int legend_h;
+ PangoFontDescription *legend_pfd;
+ PangoFontDescription *label_pfd;
+ PangoFontDescription *tiny_pfd;
+ int yaxis_offset; // don't like
+ int graph_h; // to where the dots are drawn
+ int graph_w;
+ int graph_x;
+ int graph_y;
+ char hover;
+ shoes_transform *st;
} shoes_plot;
//
// not very temporary canvas (used internally for painting)
//
typedef struct {
- VALUE parent;
- VALUE attr;
- shoes_place place;
- cairo_t *cr, *shape;
- shoes_transform *st, **sts;
- int stl, stt;
- VALUE contents;
- unsigned char stage;
- long insertion;
- int cx, cy; // cursor x and y (stored in absolute coords)
- int endx, endy; // jump points if the cursor spills over
- int topy, fully; // since we often stack vertically
- int width, height; // the full height and width used by this box
- char hover;
- struct _shoes_app *app;
- SHOES_SLOT_OS *slot;
- SHOES_GROUP_OS group;
+ VALUE parent;
+ VALUE attr;
+ shoes_place place;
+ cairo_t *cr, *shape;
+ shoes_transform *st, **sts;
+ int stl, stt;
+ VALUE contents;
+ unsigned char stage;
+ long insertion;
+ int cx, cy; // cursor x and y (stored in absolute coords)
+ int endx, endy; // jump points if the cursor spills over
+ int topy, fully; // since we often stack vertically
+ int width, height; // the full height and width used by this box
+ char hover;
+ struct _shoes_app *app;
+ SHOES_SLOT_OS *slot;
+ SHOES_GROUP_OS group;
} shoes_canvas;
-void shoes_control_hide_ref(SHOES_CONTROL_REF);
-void shoes_control_show_ref(SHOES_CONTROL_REF);
-
VALUE shoes_app_main(int, VALUE *, VALUE);
VALUE shoes_app_window(int, VALUE *, VALUE, VALUE);
VALUE shoes_app_contents(VALUE);
@@ -433,7 +291,7 @@ void shoes_slot_scroll_to(shoes_canvas *, int, int);
void shoes_canvas_paint(VALUE);
void shoes_apply_transformation(cairo_t *, shoes_transform *, shoes_place *, unsigned char);
void shoes_undo_transformation(cairo_t *, shoes_transform *, shoes_place *, unsigned char);
-void shoes_canvas_shape_do(shoes_canvas *, double, double, double, double, unsigned char);
+//void shoes_canvas_shape_do(shoes_canvas *, double, double, double, double, unsigned char);
VALUE shoes_canvas_style(int, VALUE *, VALUE);
VALUE shoes_canvas_owner(VALUE);
VALUE shoes_canvas_close(VALUE);
@@ -448,75 +306,14 @@ VALUE shoes_canvas_set_scroll_top(VALUE, VALUE);
VALUE shoes_canvas_get_gutter_width(VALUE);
VALUE shoes_canvas_displace(VALUE, VALUE, VALUE);
VALUE shoes_canvas_move(VALUE, VALUE, VALUE);
-VALUE shoes_canvas_nostroke(VALUE);
-VALUE shoes_canvas_stroke(int, VALUE *, VALUE);
-VALUE shoes_canvas_strokewidth(VALUE, VALUE);
-VALUE shoes_canvas_dash(VALUE, VALUE);
-VALUE shoes_canvas_cap(VALUE, VALUE);
-VALUE shoes_canvas_nofill(VALUE);
-VALUE shoes_canvas_fill(int, VALUE *, VALUE);
VALUE shoes_canvas_rgb(int, VALUE *, VALUE);
VALUE shoes_canvas_gray(int, VALUE *, VALUE);
-VALUE shoes_canvas_rect(int, VALUE *, VALUE);
-VALUE shoes_canvas_arc(int, VALUE *, VALUE);
-VALUE shoes_canvas_oval(int, VALUE *, VALUE);
-VALUE shoes_canvas_line(int, VALUE *, VALUE);
-VALUE shoes_canvas_arrow(int, VALUE *, VALUE);
-VALUE shoes_canvas_star(int, VALUE *, VALUE);
-VALUE shoes_canvas_para(int argc, VALUE *argv, VALUE self);
-VALUE shoes_canvas_banner(int argc, VALUE *argv, VALUE self);
-VALUE shoes_canvas_title(int argc, VALUE *argv, VALUE self);
-VALUE shoes_canvas_subtitle(int argc, VALUE *argv, VALUE self);
-VALUE shoes_canvas_tagline(int argc, VALUE *argv, VALUE self);
-VALUE shoes_canvas_caption(int argc, VALUE *argv, VALUE self);
-VALUE shoes_canvas_inscription(int argc, VALUE *argv, VALUE self);
-VALUE shoes_canvas_code(int argc, VALUE *argv, VALUE self);
-VALUE shoes_canvas_del(int argc, VALUE *argv, VALUE self);
-VALUE shoes_canvas_em(int argc, VALUE *argv, VALUE self);
-VALUE shoes_canvas_ins(int argc, VALUE *argv, VALUE self);
-VALUE shoes_canvas_link(int argc, VALUE *argv, VALUE self);
-VALUE shoes_canvas_span(int argc, VALUE *argv, VALUE self);
-VALUE shoes_canvas_strong(int argc, VALUE *argv, VALUE self);
-VALUE shoes_canvas_sub(int argc, VALUE *argv, VALUE self);
-VALUE shoes_canvas_sup(int argc, VALUE *argv, VALUE self);
-VALUE shoes_canvas_background(int, VALUE *, VALUE);
-VALUE shoes_canvas_border(int, VALUE *, VALUE);
-VALUE shoes_canvas_video(int, VALUE *, VALUE);
-VALUE shoes_canvas_blur(int, VALUE *, VALUE);
-VALUE shoes_canvas_glow(int, VALUE *, VALUE);
-VALUE shoes_canvas_shadow(int, VALUE *, VALUE);
-VALUE shoes_canvas_image(int, VALUE *, VALUE);
-VALUE shoes_canvas_animate(int, VALUE *, VALUE);
-VALUE shoes_canvas_every(int, VALUE *, VALUE);
-VALUE shoes_canvas_timer(int, VALUE *, VALUE);
-VALUE shoes_canvas_svg(int, VALUE *, VALUE);
-VALUE shoes_canvas_svghandle(int, VALUE *, VALUE);
VALUE shoes_canvas_plot(int, VALUE *, VALUE);
VALUE shoes_canvas_chart_series(int, VALUE *, VALUE);
-VALUE shoes_canvas_imagesize(VALUE, VALUE);
-VALUE shoes_canvas_shape(int, VALUE *, VALUE);
void shoes_canvas_remove_item(VALUE, VALUE, char, char);
-VALUE shoes_canvas_move_to(VALUE, VALUE, VALUE);
-VALUE shoes_canvas_line_to(VALUE, VALUE, VALUE);
-VALUE shoes_canvas_curve_to(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE);
-VALUE shoes_canvas_arc_to(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE);
-VALUE shoes_canvas_transform(VALUE, VALUE);
-VALUE shoes_canvas_translate(VALUE, VALUE, VALUE);
-VALUE shoes_canvas_rotate(VALUE, VALUE);
-VALUE shoes_canvas_scale(int, VALUE *, VALUE);
-VALUE shoes_canvas_skew(int, VALUE *, VALUE);
VALUE shoes_canvas_push(VALUE);
VALUE shoes_canvas_pop(VALUE);
VALUE shoes_canvas_reset(VALUE);
-VALUE shoes_canvas_button(int, VALUE *, VALUE);
-VALUE shoes_canvas_list_box(int, VALUE *, VALUE);
-VALUE shoes_canvas_edit_line(int, VALUE *, VALUE);
-VALUE shoes_canvas_edit_box(int, VALUE *, VALUE);
-VALUE shoes_canvas_text_edit_box(int, VALUE *, VALUE);
-VALUE shoes_canvas_progress(int, VALUE *, VALUE);
-VALUE shoes_canvas_slider(int, VALUE *, VALUE);
-VALUE shoes_canvas_check(int, VALUE *, VALUE);
-VALUE shoes_canvas_radio(int, VALUE *, VALUE);
VALUE shoes_canvas_contents(VALUE);
VALUE shoes_canvas_children(VALUE);
void shoes_canvas_size(VALUE, int, int);
@@ -553,6 +350,7 @@ void shoes_canvas_repaint_all(VALUE);
void shoes_canvas_compute(VALUE);
VALUE shoes_canvas_goto(VALUE, VALUE);
VALUE shoes_canvas_send_click(VALUE, int, int, int);
+VALUE shoes_canvas_send_click2(VALUE self, int button, int x, int y, VALUE *clicked);
void shoes_canvas_send_release(VALUE, int, int, int);
VALUE shoes_canvas_send_motion(VALUE, int, int, VALUE);
void shoes_canvas_send_wheel(VALUE, ID, int, int);
@@ -570,8 +368,13 @@ VALUE shoes_canvas_dialog(int, VALUE *, VALUE);
VALUE shoes_canvas_window_plain(VALUE);
VALUE shoes_canvas_dialog_plain(VALUE);
VALUE shoes_canvas_snapshot(int, VALUE *, VALUE);
-VALUE shoes_canvas_download(int, VALUE *, VALUE);
+typedef VALUE (*ccallfunc)(VALUE);
+typedef void (*ccallfunc2)(SHOES_CONTROL_REF);
+
+void shoes_canvas_ccall(VALUE, ccallfunc, ccallfunc2, unsigned char);
+
+VALUE shoes_add_ele(shoes_canvas *canvas, VALUE ele);
SHOES_SLOT_OS *shoes_slot_alloc(shoes_canvas *, SHOES_SLOT_OS *, int);
VALUE shoes_slot_new(VALUE, VALUE, VALUE);
@@ -580,38 +383,6 @@ VALUE shoes_stack_new(VALUE, VALUE);
VALUE shoes_mask_new(VALUE, VALUE);
VALUE shoes_widget_new(VALUE, VALUE, VALUE);
-VALUE shoes_svghandle_new(int argc, VALUE *argv, VALUE self);
-VALUE shoes_svghandle_alloc(VALUE);
-VALUE shoes_svghandle_get_width(VALUE);
-VALUE shoes_svghandle_get_height(VALUE);
-VALUE shoes_svghandle_has_group(VALUE, VALUE);
-
-VALUE shoes_svg_new(int, VALUE *, VALUE);
-VALUE shoes_svg_alloc(VALUE);
-VALUE shoes_svg_draw(VALUE, VALUE, VALUE);
-VALUE shoes_svg_get_handle(VALUE);
-VALUE shoes_svg_set_handle(VALUE, VALUE);
-VALUE shoes_svg_get_dpi(VALUE);
-VALUE shoes_svg_set_dpi(VALUE, VALUE);
-VALUE shoes_svg_export(VALUE, VALUE);
-VALUE shoes_svg_save(VALUE, VALUE);
-VALUE shoes_svg_show(VALUE);
-VALUE shoes_svg_hide(VALUE);
-VALUE shoes_svg_get_actual_width(VALUE);
-VALUE shoes_svg_get_actual_height(VALUE);
-VALUE shoes_svg_get_actual_left(VALUE);
-VALUE shoes_svg_get_actual_top(VALUE);
-VALUE shoes_svg_get_parent(VALUE);
-VALUE shoes_svg_get_offsetX(VALUE);
-VALUE shoes_svg_get_offsetY(VALUE);
-VALUE shoes_svg_preferred_height(VALUE);
-VALUE shoes_svg_preferred_width(VALUE);
-VALUE shoes_svg_remove(VALUE);
-VALUE shoes_svg_has_group(VALUE, VALUE);
-VALUE shoes_svg_motion(VALUE, int, int, char *);
-VALUE shoes_svg_send_click(VALUE, int, int, int);
-void shoes_svg_send_release(VALUE, int, int, int);
-
VALUE shoes_chart_series_new(int, VALUE *, VALUE);
VALUE shoes_chart_series_alloc(VALUE);
VALUE shoes_chart_series_values(VALUE);
@@ -661,50 +432,6 @@ VALUE shoes_plot_motion(VALUE, int, int, char *);
VALUE shoes_plot_send_click(VALUE, int, int, int);
void shoes_plot_send_release(VALUE, int, int, int);
-void shoes_control_mark(shoes_control *);
-VALUE shoes_control_new(VALUE, VALUE, VALUE);
-VALUE shoes_control_alloc(VALUE);
-void shoes_control_send(VALUE, ID);
-VALUE shoes_control_get_top(VALUE);
-VALUE shoes_control_get_left(VALUE);
-VALUE shoes_control_get_width(VALUE);
-VALUE shoes_control_get_height(VALUE);
-VALUE shoes_control_remove(VALUE);
-VALUE shoes_control_show(VALUE);
-VALUE shoes_control_temporary_show(VALUE);
-VALUE shoes_control_hide(VALUE);
-VALUE shoes_control_temporary_hide(VALUE);
-VALUE shoes_control_focus(VALUE);
-VALUE shoes_control_get_state(VALUE);
-VALUE shoes_control_set_state(VALUE, VALUE);
-
-VALUE shoes_button_draw(VALUE, VALUE, VALUE);
-void shoes_button_send_click(VALUE);
-VALUE shoes_edit_line_draw(VALUE, VALUE, VALUE);
-VALUE shoes_edit_line_get_text(VALUE);
-VALUE shoes_edit_line_set_text(VALUE, VALUE);
-VALUE shoes_edit_box_draw(VALUE, VALUE, VALUE);
-VALUE shoes_edit_box_get_text(VALUE);
-VALUE shoes_edit_box_set_text(VALUE, VALUE);
-VALUE shoes_list_box_text(VALUE);
-VALUE shoes_list_box_draw(VALUE, VALUE, VALUE);
-VALUE shoes_progress_draw(VALUE, VALUE, VALUE);
-
-void shoes_shape_mark(shoes_shape *);
-VALUE shoes_shape_attr(int, VALUE *, int, ...);
-void shoes_shape_sketch(cairo_t *, ID, shoes_place *, shoes_transform *, VALUE, cairo_path_t *, unsigned char);
-VALUE shoes_shape_new(VALUE, ID, VALUE, shoes_transform *, cairo_path_t *);
-VALUE shoes_shape_alloc(VALUE);
-VALUE shoes_shape_draw(VALUE, VALUE, VALUE);
-VALUE shoes_shape_move(VALUE, VALUE, VALUE);
-VALUE shoes_shape_get_top(VALUE);
-VALUE shoes_shape_get_left(VALUE);
-VALUE shoes_shape_get_width(VALUE);
-VALUE shoes_shape_get_height(VALUE);
-VALUE shoes_shape_motion(VALUE, int, int, char *);
-VALUE shoes_shape_send_click(VALUE, int, int, int);
-void shoes_shape_send_release(VALUE, int, int, int);
-
void shoes_image_ensure_dup(shoes_image *);
void shoes_image_mark(shoes_image *);
VALUE shoes_image_new(VALUE, VALUE, VALUE, VALUE, shoes_transform *);
@@ -719,83 +446,6 @@ VALUE shoes_image_motion(VALUE, int, int, char *);
VALUE shoes_image_send_click(VALUE, int, int, int);
void shoes_image_send_release(VALUE, int, int, int);
-shoes_effect_filter shoes_effect_for_type(ID);
-void shoes_effect_mark(shoes_effect *);
-VALUE shoes_effect_new(ID, VALUE, VALUE);
-VALUE shoes_effect_alloc(VALUE);
-VALUE shoes_effect_draw(VALUE, VALUE, VALUE);
-
-VALUE shoes_pattern_self(VALUE);
-VALUE shoes_pattern_method(VALUE, VALUE);
-VALUE shoes_pattern_args(int, VALUE *, VALUE);
-void shoes_pattern_mark(shoes_pattern *);
-VALUE shoes_pattern_new(VALUE, VALUE, VALUE, VALUE);
-VALUE shoes_pattern_alloc(VALUE);
-VALUE shoes_pattern_motion(VALUE, int, int, char *);
-VALUE shoes_background_draw(VALUE, VALUE, VALUE);
-VALUE shoes_border_draw(VALUE, VALUE, VALUE);
-VALUE shoes_subpattern_new(VALUE, VALUE, VALUE);
-
-void shoes_timer_mark(shoes_timer *);
-VALUE shoes_timer_new(VALUE, VALUE, VALUE, VALUE);
-VALUE shoes_timer_alloc(VALUE);
-VALUE shoes_timer_init(VALUE, VALUE);
-VALUE shoes_timer_remove(VALUE);
-VALUE shoes_timer_start(VALUE);
-VALUE shoes_timer_stop(VALUE);
-void shoes_timer_call(VALUE);
-
-void shoes_color_mark(shoes_color *);
-VALUE shoes_color_new(int, int, int, int);
-VALUE shoes_color_alloc(VALUE);
-VALUE shoes_color_rgb(int, VALUE *, VALUE);
-VALUE shoes_color_gray(int, VALUE *, VALUE);
-cairo_pattern_t *shoes_color_pattern(VALUE);
-void shoes_color_grad_stop(cairo_pattern_t *, double, VALUE);
-VALUE shoes_color_args(int, VALUE *, VALUE);
-VALUE shoes_color_parse(VALUE, VALUE);
-VALUE shoes_color_is_black(VALUE);
-VALUE shoes_color_is_dark(VALUE);
-VALUE shoes_color_is_light(VALUE);
-VALUE shoes_color_is_white(VALUE);
-VALUE shoes_color_invert(VALUE);
-VALUE shoes_color_to_s(VALUE);
-VALUE shoes_color_to_pattern(VALUE);
-VALUE shoes_color_gradient(int, VALUE *, VALUE);
-
-void shoes_link_mark(shoes_link *);
-VALUE shoes_link_new(VALUE, int, int);
-VALUE shoes_link_alloc(VALUE);
-VALUE shoes_text_new(VALUE, VALUE, VALUE);
-VALUE shoes_text_alloc(VALUE);
-
-void shoes_text_mark(shoes_text *);
-void shoes_textblock_mark(shoes_textblock *);
-VALUE shoes_textblock_new(VALUE, VALUE, VALUE, VALUE, shoes_transform *);
-VALUE shoes_textblock_alloc(VALUE);
-VALUE shoes_textblock_get_top(VALUE);
-VALUE shoes_textblock_get_left(VALUE);
-VALUE shoes_textblock_get_width(VALUE);
-VALUE shoes_textblock_get_height(VALUE);
-VALUE shoes_textblock_set_cursor(VALUE, VALUE);
-VALUE shoes_textblock_get_cursor(VALUE);
-VALUE shoes_textblock_draw(VALUE, VALUE, VALUE);
-VALUE shoes_textblock_motion(VALUE, int, int, char *);
-VALUE shoes_textblock_send_click(VALUE, int, int, int, VALUE *);
-void shoes_textblock_send_release(VALUE, int, int, int);
-
-void shoes_http_mark(shoes_http_klass *);
-VALUE shoes_http_new(VALUE, VALUE, VALUE);
-VALUE shoes_http_alloc(VALUE);
-VALUE shoes_http_threaded(VALUE, VALUE, VALUE);
-int shoes_message_download(VALUE, void *);
-int shoes_catch_message(unsigned int name, VALUE obj, void *data);
-
-VALUE shoes_response_new(VALUE, int);
-VALUE shoes_response_body(VALUE);
-VALUE shoes_response_headers(VALUE);
-VALUE shoes_response_status(VALUE);
-
VALUE shoes_p(VALUE, VALUE);
extern const double SHOES_PIM2, SHOES_PI, SHOES_RAD2PI, SHOES_HALFPI;
@@ -804,10 +454,10 @@ extern const double SHOES_PIM2, SHOES_PI, SHOES_RAD2PI, SHOES_HALFPI;
// shoes/image.c
//
typedef struct {
- unsigned long status;
- char *cachepath, *filepath, *uripath, *etag;
- char hexdigest[42];
- VALUE slot;
+ unsigned long status;
+ char *cachepath, *filepath, *uripath, *etag;
+ char hexdigest[42];
+ VALUE slot;
} shoes_image_download_event;
shoes_code shoes_load_imagesize(VALUE, int *, int *);
@@ -815,4 +465,50 @@ shoes_cached_image *shoes_cached_image_new(int, int, cairo_surface_t *);
shoes_cached_image *shoes_load_image(VALUE, VALUE);
unsigned char shoes_image_downloaded(shoes_image_download_event *);
+// Canvas needs cSvg to create snapshots and send events
+extern VALUE cSvg;
+
+extern VALUE shoes_svg_motion(VALUE, int, int, char *);
+extern VALUE shoes_svg_send_click(VALUE, int, int, int);
+extern void shoes_svg_send_release(VALUE, int, int, int);
+
+// TODO: to be removed during refactoring
+extern VALUE shoes_text_new(VALUE klass, VALUE texts, VALUE attr);
+
+extern VALUE cNative, cPlot, cRadio;
+
+
+// TODO: MARKUP_* macro belongs to either TextBlock or Text?
+#define MARKUP_BLOCK(klass) \
+ text = shoes_textblock_new(klass, msgs, attr, self, canvas->st); \
+ shoes_add_ele(canvas, text)
+
+#define MARKUP_INLINE(klass) \
+ text = shoes_text_new(klass, msgs, attr)
+
+#define MARKUP_DEF(mname, fname, klass) \
+ VALUE \
+ shoes_canvas_##mname(int argc, VALUE *argv, VALUE self) \
+ { \
+ long i; \
+ VALUE msgs, attr, text; \
+ SETUP_CANVAS(); \
+ msgs = rb_ary_new(); \
+ attr = Qnil; \
+ for (i = 0; i < argc; i++) \
+ { \
+ if (rb_obj_is_kind_of(argv[i], rb_cHash)) \
+ attr = argv[i]; \
+ else \
+ rb_ary_push(msgs, argv[i]); \
+ } \
+ MARKUP_##fname(klass); \
+ return text; \
+ }
+
+#define SETUP_SHAPE() \
+ shoes_canvas *canvas = NULL; \
+ VALUE c = shoes_find_canvas(self); \
+ Data_Get_Struct(c, shoes_canvas, canvas)
+
#endif
diff --git a/shoes/config.h b/shoes/config.h
index 45085f5d..52ae620a 100644
--- a/shoes/config.h
+++ b/shoes/config.h
@@ -42,7 +42,7 @@
#include
#include
// choose gdk
-#if defined(SHOES_GTK_WIN32)
+#if defined(SHOES_GTK_WIN32)
#include
#else
#include
@@ -63,31 +63,31 @@
typedef struct {
#ifdef GTK3
- GtkWidget *vscroll, *oscanvas;
- cairo_t *drawevent;
+ GtkWidget *vscroll, *oscanvas;
+ cairo_t *drawevent;
#else
- GtkWidget *vscroll, *oscanvas;
- GdkEventExpose *expose;
+ GtkWidget *vscroll, *oscanvas;
+ GdkEventExpose *expose;
#endif
- int scrolly, scrollh, scrollw;
- void *owner;
+ int scrolly, scrollh, scrollw;
+ void *owner;
} shoes_slot_gtk, SHOES_SLOT_OS;
typedef struct {
- GtkWidget *layout;
- GtkWidget *radios;
+ GtkWidget *layout;
+ GtkWidget *radios;
} shoes_group_gtk, SHOES_GROUP_OS;
typedef struct {
- GtkWidget *window;
+ GtkWidget *window;
} shoes_app_gtk, SHOES_APP_OS;
typedef struct {
#ifdef SHOES_GTK_WIN32
- HINSTANCE instance;
- int style;
+ HINSTANCE instance;
+ int style;
#endif
- int nada;
+ int nada;
} shoes_world_gtk, SHOES_WORLD_OS;
#define USTR(str) str
@@ -147,27 +147,27 @@ typedef struct {
#define SHOES_EXTERN
typedef struct {
- NSView *view;
- NSScroller *vscroll;
- CGContextRef context;
- cairo_surface_t *surface;
- VALUE controls;
- int scrolly;
- void *owner;
+ NSView *view;
+ NSScroller *vscroll;
+ CGContextRef context;
+ cairo_surface_t *surface;
+ VALUE controls;
+ int scrolly;
+ void *owner;
} shoes_slot_quartz, SHOES_SLOT_OS;
typedef struct {
- char none;
+ char none;
} shoes_group_quartz, SHOES_GROUP_OS;
typedef struct {
- ShoesWindow *window;
- NSView *view;
- NSRect normal;
+ ShoesWindow *window;
+ NSView *view;
+ NSRect normal;
} shoes_app_quartz, SHOES_APP_OS;
typedef struct {
- ShoesEvents *events;
+ ShoesEvents *events;
} shoes_world_quartz, SHOES_WORLD_OS;
#define kShoesViewClassID CFSTR("org.hackety.ShoesView")
@@ -219,36 +219,36 @@ typedef struct {
#define SHOES_EXTERN __declspec(dllexport)
typedef struct {
- PAINTSTRUCT ps;
- HDC dc, dc2;
- HWND window;
- VALUE focus;
- VALUE controls;
- cairo_surface_t *surface;
- int scrolly;
- char vscroll;
- void *owner;
- void *parent;
+ PAINTSTRUCT ps;
+ HDC dc, dc2;
+ HWND window;
+ VALUE focus;
+ VALUE controls;
+ cairo_surface_t *surface;
+ int scrolly;
+ char vscroll;
+ void *owner;
+ void *parent;
} shoes_slot_win32, SHOES_SLOT_OS;
typedef struct {
- char none;
+ char none;
} shoes_group_win32, SHOES_GROUP_OS;
typedef struct {
- LONG style;
- RECT normal;
- BOOL ctrlkey, altkey, shiftkey;
- HWND window;
+ LONG style;
+ RECT normal;
+ BOOL ctrlkey, altkey, shiftkey;
+ HWND window;
} shoes_app_win32, SHOES_APP_OS;
typedef struct {
- HINSTANCE instance;
- int style;
- HWND hidden;
- WNDCLASSEX classex, slotex, vlclassex, hiddenex;
- ATOM classatom;
- BOOL doublebuffer;
+ HINSTANCE instance;
+ int style;
+ HWND hidden;
+ WNDCLASSEX classex, slotex, vlclassex, hiddenex;
+ ATOM classatom;
+ BOOL doublebuffer;
} shoes_world_win32, SHOES_WORLD_OS;
#define USTR(str) (const char *)L##str
diff --git a/shoes/console/colortab.c b/shoes/console/colortab.c
index 2c8a0cad..5fc58768 100644
--- a/shoes/console/colortab.c
+++ b/shoes/console/colortab.c
@@ -1,259 +1,259 @@
// generated from gtk-rgb.py
char *colorstrings[256] = {
- "@00-#000000",
- "@01-#800000",
- "@02-#008000",
- "@03-#808000",
- "@04-#000080",
- "@05-#800080",
- "@06-#008080",
- "@07-#c0c0c0",
- "@08-#808080",
- "@09-#ff0000",
- "@10-#00ff00",
- "@11-#ffff00",
- "@12-#0000ff",
- "@13-#ff00ff",
- "@14-#00ffff",
- "@15-#ffffff",
- "@16-#000000",
- "@17-#00005f",
- "@18-#000087",
- "@19-#0000af",
- "@20-#0000d7",
- "@21-#0000ff",
- "@22-#005f00",
- "@23-#005f5f",
- "@24-#005f87",
- "@25-#005faf",
- "@26-#005fd7",
- "@27-#005fff",
- "@28-#008700",
- "@29-#00875f",
- "@30-#008787",
- "@31-#0087af",
- "@32-#0087d7",
- "@33-#0087ff",
- "@34-#00af00",
- "@35-#00af5f",
- "@36-#00af87",
- "@37-#00afaf",
- "@38-#00afd7",
- "@39-#00afff",
- "@40-#00d700",
- "@41-#00d75f",
- "@42-#00d787",
- "@43-#00d7af",
- "@44-#00d7d7",
- "@45-#00d7ff",
- "@46-#00ff00",
- "@47-#00ff5f",
- "@48-#00ff87",
- "@49-#00ffaf",
- "@50-#00ffd7",
- "@51-#00ffff",
- "@52-#5f0000",
- "@53-#5f005f",
- "@54-#5f0087",
- "@55-#5f00af",
- "@56-#5f00d7",
- "@57-#5f00ff",
- "@58-#5f5f00",
- "@59-#5f5f5f",
- "@60-#5f5f87",
- "@61-#5f5faf",
- "@62-#5f5fd7",
- "@63-#5f5fff",
- "@64-#5f8700",
- "@65-#5f875f",
- "@66-#5f8787",
- "@67-#5f87af",
- "@68-#5f87d7",
- "@69-#5f87ff",
- "@70-#5faf00",
- "@71-#5faf5f",
- "@72-#5faf87",
- "@73-#5fafaf",
- "@74-#5fafd7",
- "@75-#5fafff",
- "@76-#5fd700",
- "@77-#5fd75f",
- "@78-#5fd787",
- "@79-#5fd7af",
- "@80-#5fd7d7",
- "@81-#5fd7ff",
- "@82-#5fff00",
- "@83-#5fff5f",
- "@84-#5fff87",
- "@85-#5fffaf",
- "@86-#5fffd7",
- "@87-#5fffff",
- "@88-#870000",
- "@89-#87005f",
- "@90-#870087",
- "@91-#8700af",
- "@92-#8700d7",
- "@93-#8700ff",
- "@94-#875f00",
- "@95-#875f5f",
- "@96-#875f87",
- "@97-#875faf",
- "@98-#875fd7",
- "@99-#875fff",
- "@100-#878700",
- "@101-#87875f",
- "@102-#878787",
- "@103-#8787af",
- "@104-#8787d7",
- "@105-#8787ff",
- "@106-#87af00",
- "@107-#87af5f",
- "@108-#87af87",
- "@109-#87afaf",
- "@110-#87afd7",
- "@111-#87afff",
- "@112-#87d700",
- "@113-#87d75f",
- "@114-#87d787",
- "@115-#87d7af",
- "@116-#87d7d7",
- "@117-#87d7ff",
- "@118-#87ff00",
- "@119-#87ff5f",
- "@120-#87ff87",
- "@121-#87ffaf",
- "@122-#87ffd7",
- "@123-#87ffff",
- "@124-#af0000",
- "@125-#af005f",
- "@126-#af0087",
- "@127-#af00af",
- "@128-#af00d7",
- "@129-#af00ff",
- "@130-#af5f00",
- "@131-#af5f5f",
- "@132-#af5f87",
- "@133-#af5faf",
- "@134-#af5fd7",
- "@135-#af5fff",
- "@136-#af8700",
- "@137-#af875f",
- "@138-#af8787",
- "@139-#af87af",
- "@140-#af87d7",
- "@141-#af87ff",
- "@142-#afaf00",
- "@143-#afaf5f",
- "@144-#afaf87",
- "@145-#afafaf",
- "@146-#afafd7",
- "@147-#afafff",
- "@148-#afd700",
- "@149-#afd75f",
- "@150-#afd787",
- "@151-#afd7af",
- "@152-#afd7d7",
- "@153-#afd7ff",
- "@154-#afff00",
- "@155-#afff5f",
- "@156-#afff87",
- "@157-#afffaf",
- "@158-#afffd7",
- "@159-#afffff",
- "@160-#d70000",
- "@161-#d7005f",
- "@162-#d70087",
- "@163-#d700af",
- "@164-#d700d7",
- "@165-#d700ff",
- "@166-#d75f00",
- "@167-#d75f5f",
- "@168-#d75f87",
- "@169-#d75faf",
- "@170-#d75fd7",
- "@171-#d75fff",
- "@172-#d78700",
- "@173-#d7875f",
- "@174-#d78787",
- "@175-#d787af",
- "@176-#d787d7",
- "@177-#d787ff",
- "@178-#d7af00",
- "@179-#d7af5f",
- "@180-#d7af87",
- "@181-#d7afaf",
- "@182-#d7afd7",
- "@183-#d7afff",
- "@184-#d7d700",
- "@185-#d7d75f",
- "@186-#d7d787",
- "@187-#d7d7af",
- "@188-#d7d7d7",
- "@189-#d7d7ff",
- "@190-#d7ff00",
- "@191-#d7ff5f",
- "@192-#d7ff87",
- "@193-#d7ffaf",
- "@194-#d7ffd7",
- "@195-#d7ffff",
- "@196-#ff0000",
- "@197-#ff005f",
- "@198-#ff0087",
- "@199-#ff00af",
- "@200-#ff00d7",
- "@201-#ff00ff",
- "@202-#ff5f00",
- "@203-#ff5f5f",
- "@204-#ff5f87",
- "@205-#ff5faf",
- "@206-#ff5fd7",
- "@207-#ff5fff",
- "@208-#ff8700",
- "@209-#ff875f",
- "@210-#ff8787",
- "@211-#ff87af",
- "@212-#ff87d7",
- "@213-#ff87ff",
- "@214-#ffaf00",
- "@215-#ffaf5f",
- "@216-#ffaf87",
- "@217-#ffafaf",
- "@218-#ffafd7",
- "@219-#ffafff",
- "@220-#ffd700",
- "@221-#ffd75f",
- "@222-#ffd787",
- "@223-#ffd7af",
- "@224-#ffd7d7",
- "@225-#ffd7ff",
- "@226-#ffff00",
- "@227-#ffff5f",
- "@228-#ffff87",
- "@229-#ffffaf",
- "@230-#ffffd7",
- "@231-#ffffff",
- "@232-#080808",
- "@233-#121212",
- "@234-#1c1c1c",
- "@235-#262626",
- "@236-#303030",
- "@237-#3a3a3a",
- "@238-#444444",
- "@239-#4e4e4e",
- "@240-#585858",
- "@241-#626262",
- "@242-#6c6c6c",
- "@243-#767676",
- "@244-#808080",
- "@245-#8a8a8a",
- "@246-#949494",
- "@247-#9e9e9e",
- "@248-#a8a8a8",
- "@249-#b2b2b2",
- "@250-#bcbcbc",
- "@251-#c6c6c6",
- "@252-#d0d0d0",
- "@253-#dadada",
- "@254-#e4e4e4",
- "@255-#eeeeee",
+ "@00-#000000",
+ "@01-#800000",
+ "@02-#008000",
+ "@03-#808000",
+ "@04-#000080",
+ "@05-#800080",
+ "@06-#008080",
+ "@07-#c0c0c0",
+ "@08-#808080",
+ "@09-#ff0000",
+ "@10-#00ff00",
+ "@11-#ffff00",
+ "@12-#0000ff",
+ "@13-#ff00ff",
+ "@14-#00ffff",
+ "@15-#ffffff",
+ "@16-#000000",
+ "@17-#00005f",
+ "@18-#000087",
+ "@19-#0000af",
+ "@20-#0000d7",
+ "@21-#0000ff",
+ "@22-#005f00",
+ "@23-#005f5f",
+ "@24-#005f87",
+ "@25-#005faf",
+ "@26-#005fd7",
+ "@27-#005fff",
+ "@28-#008700",
+ "@29-#00875f",
+ "@30-#008787",
+ "@31-#0087af",
+ "@32-#0087d7",
+ "@33-#0087ff",
+ "@34-#00af00",
+ "@35-#00af5f",
+ "@36-#00af87",
+ "@37-#00afaf",
+ "@38-#00afd7",
+ "@39-#00afff",
+ "@40-#00d700",
+ "@41-#00d75f",
+ "@42-#00d787",
+ "@43-#00d7af",
+ "@44-#00d7d7",
+ "@45-#00d7ff",
+ "@46-#00ff00",
+ "@47-#00ff5f",
+ "@48-#00ff87",
+ "@49-#00ffaf",
+ "@50-#00ffd7",
+ "@51-#00ffff",
+ "@52-#5f0000",
+ "@53-#5f005f",
+ "@54-#5f0087",
+ "@55-#5f00af",
+ "@56-#5f00d7",
+ "@57-#5f00ff",
+ "@58-#5f5f00",
+ "@59-#5f5f5f",
+ "@60-#5f5f87",
+ "@61-#5f5faf",
+ "@62-#5f5fd7",
+ "@63-#5f5fff",
+ "@64-#5f8700",
+ "@65-#5f875f",
+ "@66-#5f8787",
+ "@67-#5f87af",
+ "@68-#5f87d7",
+ "@69-#5f87ff",
+ "@70-#5faf00",
+ "@71-#5faf5f",
+ "@72-#5faf87",
+ "@73-#5fafaf",
+ "@74-#5fafd7",
+ "@75-#5fafff",
+ "@76-#5fd700",
+ "@77-#5fd75f",
+ "@78-#5fd787",
+ "@79-#5fd7af",
+ "@80-#5fd7d7",
+ "@81-#5fd7ff",
+ "@82-#5fff00",
+ "@83-#5fff5f",
+ "@84-#5fff87",
+ "@85-#5fffaf",
+ "@86-#5fffd7",
+ "@87-#5fffff",
+ "@88-#870000",
+ "@89-#87005f",
+ "@90-#870087",
+ "@91-#8700af",
+ "@92-#8700d7",
+ "@93-#8700ff",
+ "@94-#875f00",
+ "@95-#875f5f",
+ "@96-#875f87",
+ "@97-#875faf",
+ "@98-#875fd7",
+ "@99-#875fff",
+ "@100-#878700",
+ "@101-#87875f",
+ "@102-#878787",
+ "@103-#8787af",
+ "@104-#8787d7",
+ "@105-#8787ff",
+ "@106-#87af00",
+ "@107-#87af5f",
+ "@108-#87af87",
+ "@109-#87afaf",
+ "@110-#87afd7",
+ "@111-#87afff",
+ "@112-#87d700",
+ "@113-#87d75f",
+ "@114-#87d787",
+ "@115-#87d7af",
+ "@116-#87d7d7",
+ "@117-#87d7ff",
+ "@118-#87ff00",
+ "@119-#87ff5f",
+ "@120-#87ff87",
+ "@121-#87ffaf",
+ "@122-#87ffd7",
+ "@123-#87ffff",
+ "@124-#af0000",
+ "@125-#af005f",
+ "@126-#af0087",
+ "@127-#af00af",
+ "@128-#af00d7",
+ "@129-#af00ff",
+ "@130-#af5f00",
+ "@131-#af5f5f",
+ "@132-#af5f87",
+ "@133-#af5faf",
+ "@134-#af5fd7",
+ "@135-#af5fff",
+ "@136-#af8700",
+ "@137-#af875f",
+ "@138-#af8787",
+ "@139-#af87af",
+ "@140-#af87d7",
+ "@141-#af87ff",
+ "@142-#afaf00",
+ "@143-#afaf5f",
+ "@144-#afaf87",
+ "@145-#afafaf",
+ "@146-#afafd7",
+ "@147-#afafff",
+ "@148-#afd700",
+ "@149-#afd75f",
+ "@150-#afd787",
+ "@151-#afd7af",
+ "@152-#afd7d7",
+ "@153-#afd7ff",
+ "@154-#afff00",
+ "@155-#afff5f",
+ "@156-#afff87",
+ "@157-#afffaf",
+ "@158-#afffd7",
+ "@159-#afffff",
+ "@160-#d70000",
+ "@161-#d7005f",
+ "@162-#d70087",
+ "@163-#d700af",
+ "@164-#d700d7",
+ "@165-#d700ff",
+ "@166-#d75f00",
+ "@167-#d75f5f",
+ "@168-#d75f87",
+ "@169-#d75faf",
+ "@170-#d75fd7",
+ "@171-#d75fff",
+ "@172-#d78700",
+ "@173-#d7875f",
+ "@174-#d78787",
+ "@175-#d787af",
+ "@176-#d787d7",
+ "@177-#d787ff",
+ "@178-#d7af00",
+ "@179-#d7af5f",
+ "@180-#d7af87",
+ "@181-#d7afaf",
+ "@182-#d7afd7",
+ "@183-#d7afff",
+ "@184-#d7d700",
+ "@185-#d7d75f",
+ "@186-#d7d787",
+ "@187-#d7d7af",
+ "@188-#d7d7d7",
+ "@189-#d7d7ff",
+ "@190-#d7ff00",
+ "@191-#d7ff5f",
+ "@192-#d7ff87",
+ "@193-#d7ffaf",
+ "@194-#d7ffd7",
+ "@195-#d7ffff",
+ "@196-#ff0000",
+ "@197-#ff005f",
+ "@198-#ff0087",
+ "@199-#ff00af",
+ "@200-#ff00d7",
+ "@201-#ff00ff",
+ "@202-#ff5f00",
+ "@203-#ff5f5f",
+ "@204-#ff5f87",
+ "@205-#ff5faf",
+ "@206-#ff5fd7",
+ "@207-#ff5fff",
+ "@208-#ff8700",
+ "@209-#ff875f",
+ "@210-#ff8787",
+ "@211-#ff87af",
+ "@212-#ff87d7",
+ "@213-#ff87ff",
+ "@214-#ffaf00",
+ "@215-#ffaf5f",
+ "@216-#ffaf87",
+ "@217-#ffafaf",
+ "@218-#ffafd7",
+ "@219-#ffafff",
+ "@220-#ffd700",
+ "@221-#ffd75f",
+ "@222-#ffd787",
+ "@223-#ffd7af",
+ "@224-#ffd7d7",
+ "@225-#ffd7ff",
+ "@226-#ffff00",
+ "@227-#ffff5f",
+ "@228-#ffff87",
+ "@229-#ffffaf",
+ "@230-#ffffd7",
+ "@231-#ffffff",
+ "@232-#080808",
+ "@233-#121212",
+ "@234-#1c1c1c",
+ "@235-#262626",
+ "@236-#303030",
+ "@237-#3a3a3a",
+ "@238-#444444",
+ "@239-#4e4e4e",
+ "@240-#585858",
+ "@241-#626262",
+ "@242-#6c6c6c",
+ "@243-#767676",
+ "@244-#808080",
+ "@245-#8a8a8a",
+ "@246-#949494",
+ "@247-#9e9e9e",
+ "@248-#a8a8a8",
+ "@249-#b2b2b2",
+ "@250-#bcbcbc",
+ "@251-#c6c6c6",
+ "@252-#d0d0d0",
+ "@253-#dadada",
+ "@254-#e4e4e4",
+ "@255-#eeeeee",
};
diff --git a/shoes/console/gtk-terminal.c b/shoes/console/gtk-terminal.c
index 4deb317d..b38b3a9e 100644
--- a/shoes/console/gtk-terminal.c
+++ b/shoes/console/gtk-terminal.c
@@ -10,10 +10,10 @@ extern char *colorstrings[];
/*
* heavily modified from https://github.com/alanszlosek/tesi/
* for use in Shoes/Linux
- *
+ *
* There are some restrictions - there is only one tesiObject because
- * it hooks to stdin/out/err and there's only one of those in a Shoes/Ruby/C
- * process.
+ * it hooks to stdin/out/err and there's only one of those in a Shoes/Ruby/C
+ * process.
* *
* We can also switch the gtk_text_view buffer from log like/readline buffer
* to a legacy buffer (with 80 * 24/25 lines of characters)
@@ -22,666 +22,671 @@ static struct tesiObject *tobj;
static GtkWidget *terminal_window;
static GtkTextView *view;
static GtkTextBuffer *buffer;
-static gboolean log_mode = TRUE;
+static gboolean log_mode = TRUE;
static GtkTextBuffer *log_buffer = NULL;
static GtkTextBuffer *game_buffer = NULL;
static char *blank_line; // has columns number of spaces + nl & null
static GtkTextMark **begline;
static GtkTextMark **endline;
static gboolean saveRaw = FALSE;
-static GString *rawBuffer;
+static GString *rawBuffer;
static gboolean keypress_event(GtkWidget *widget, GdkEventKey *event, gpointer data) {
- struct tesiObject *tobj = (struct tesiObject*)data;
- char *c = ((GdkEventKey*)event)->string;
- char s = *c;
- if (event->keyval == GDK_KEY_BackSpace) {
- s = 010;
- }
- write(tobj->fd_input, &s, 1);
- return TRUE;
+ struct tesiObject *tobj = (struct tesiObject*)data;
+ char *c = ((GdkEventKey*)event)->string;
+ char s = *c;
+ if (event->keyval == GDK_KEY_BackSpace) {
+ s = 010;
+ }
+ write(tobj->fd_input, &s, 1);
+ return TRUE;
}
static gboolean clear_console(GtkWidget *widget, GdkEvent *event, gpointer data) {
- struct tesiObject *tobj = (struct tesiObject*) data;
- GtkTextView *view = GTK_TEXT_VIEW(tobj->pointer);
- GtkTextBuffer *newbuf = gtk_text_buffer_new(NULL);
- gtk_text_view_set_buffer(view, newbuf);
- // set a mark to the end? get focus
- gtk_widget_grab_focus(GTK_WIDGET(view));
- // clean out rawBuffer
- g_string_free (rawBuffer,TRUE);
- rawBuffer = g_string_sized_new(4096);
- return TRUE;
+ struct tesiObject *tobj = (struct tesiObject*) data;
+ GtkTextView *view = GTK_TEXT_VIEW(tobj->pointer);
+ GtkTextBuffer *newbuf = gtk_text_buffer_new(NULL);
+ gtk_text_view_set_buffer(view, newbuf);
+ // set a mark to the end? get focus
+ gtk_widget_grab_focus(GTK_WIDGET(view));
+ // clean out rawBuffer
+ g_string_free (rawBuffer,TRUE);
+ rawBuffer = g_string_sized_new(4096);
+ return TRUE;
}
static gboolean copy_console(GtkWidget *widget, GdkEvent *event, gpointer data) {
- struct tesiObject *tobj = (struct tesiObject*) data;
-
- GtkTextView *view = GTK_TEXT_VIEW(tobj->pointer);
- GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(view));
- GtkTextIter iter_s, iter_e;
- gtk_text_buffer_get_bounds(buffer, &iter_s, &iter_e);
- gchar *bigstr = gtk_text_buffer_get_slice(buffer, &iter_s, &iter_e, TRUE);
- GtkClipboard *primary = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
- gtk_clipboard_set_text(primary, bigstr, strlen(bigstr));
- return TRUE;
+ struct tesiObject *tobj = (struct tesiObject*) data;
+
+ GtkTextView *view = GTK_TEXT_VIEW(tobj->pointer);
+ GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(view));
+ GtkTextIter iter_s, iter_e;
+ gtk_text_buffer_get_bounds(buffer, &iter_s, &iter_e);
+ gchar *bigstr = gtk_text_buffer_get_slice(buffer, &iter_s, &iter_e, TRUE);
+ GtkClipboard *primary = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
+ gtk_clipboard_set_text(primary, bigstr, strlen(bigstr));
+ return TRUE;
}
static gboolean raw_copy(GtkWidget *widget, GdkEvent *event, gpointer data) {
- struct tesiObject *tobj = (struct tesiObject*) data;
- GtkClipboard *primary = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
- gtk_clipboard_set_text(primary, rawBuffer->str, rawBuffer->len );
- return TRUE;
+ struct tesiObject *tobj = (struct tesiObject*) data;
+ GtkClipboard *primary = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
+ gtk_clipboard_set_text(primary, rawBuffer->str, rawBuffer->len );
+ return TRUE;
}
/*
* This is called to handle characters received from the pty
* in response to a puts/printf/write from Shoes,Ruby, & C
* It does't manage escape seq, x,y or deal with width and height.
* Just write to the end of the buffer and let the gtk_text_view manage it.
- *
+ *
* In 3.3.2 this won't be used.
*/
void console_haveChar(void *p, char c) {
- struct tesiObject *tobj = (struct tesiObject*)p;
- GtkTextView *view = GTK_TEXT_VIEW(tobj->pointer);
- GtkTextBuffer *buffer = gtk_text_view_get_buffer(view);
- GtkTextIter iter_e;
- GtkTextMark *insert_mark;
- char in[8];
-
- snprintf(in, 7, "%c", c);
- if (c >= 32 && c != 127) {
- buffer = gtk_text_view_get_buffer(view);
- gtk_text_buffer_insert_at_cursor(buffer, in, 1);
- return;
+ struct tesiObject *tobj = (struct tesiObject*)p;
+ GtkTextView *view = GTK_TEXT_VIEW(tobj->pointer);
+ GtkTextBuffer *buffer = gtk_text_view_get_buffer(view);
+ GtkTextIter iter_e;
+ GtkTextMark *insert_mark;
+ char in[8];
+
+ snprintf(in, 7, "%c", c);
+ if (c >= 32 && c != 127) {
+ buffer = gtk_text_view_get_buffer(view);
+ gtk_text_buffer_insert_at_cursor(buffer, in, 1);
+ return;
}
- switch (c) {
- case '\x1B': // begin escape sequence (aborting previous one if any)
- //tobj->partialSequence = 1;
- // possibly flush buffer
- break;
-
- case '\r': // carriage return ('M' - '@'). Move cursor to first column.
- // odds are high this preceeds a \n. Move to the begining of
- // last line in buffer line. What happens if we insert
- break;
-
- case '\n': // line feed ('J' - '@'). Move cursor down line and to first column.
- // just insert '\n' into the buffer.
- gtk_text_buffer_insert_at_cursor(buffer, in, 1);
- break;
-
- case '\t': // ht - horizontal tab, ('I' - '@')
- // textview can handle tabs - it claims.
- gtk_text_buffer_insert_at_cursor(buffer, in, 1);
- break;
-
- case '\a': // bell ('G' - '@')
- // do nothing for now... maybe a visual bell would be nice?
- break;
-
- case 8: // backspace cub1 cursor back 1 ('H' - '@')
+ switch (c) {
+ case '\x1B': // begin escape sequence (aborting previous one if any)
+ //tobj->partialSequence = 1;
+ // possibly flush buffer
+ break;
+
+ case '\r': // carriage return ('M' - '@'). Move cursor to first column.
+ // odds are high this preceeds a \n. Move to the begining of
+ // last line in buffer line. What happens if we insert
+ break;
+
+ case '\n': // line feed ('J' - '@'). Move cursor down line and to first column.
+ // just insert '\n' into the buffer.
+ gtk_text_buffer_insert_at_cursor(buffer, in, 1);
+ break;
+
+ case '\t': // ht - horizontal tab, ('I' - '@')
+ // textview can handle tabs - it claims.
+ gtk_text_buffer_insert_at_cursor(buffer, in, 1);
+ break;
+
+ case '\a': // bell ('G' - '@')
+ // do nothing for now... maybe a visual bell would be nice?
+ break;
+
+ case 8: // backspace cub1 cursor back 1 ('H' - '@')
gtk_text_buffer_get_end_iter (buffer, &iter_e);
gtk_text_buffer_backspace(buffer, &iter_e, 1, 1);
- break;
+ break;
- default:
+ default:
#ifdef DEBUG
- fprintf(stderr, "Unrecognized control char: %d (^%c)\n", c, c + '@');
+ fprintf(stderr, "Unrecognized control char: %d (^%c)\n", c, c + '@');
#endif
- break;
- }
- // tell the view to show the newest position
- // from http://www.gtkforums.com/viewtopic.php?t=1307
- gtk_text_buffer_get_end_iter (buffer, &iter_e);
- insert_mark = gtk_text_buffer_get_insert (buffer);
- gtk_text_buffer_place_cursor(buffer, &iter_e);
- gtk_text_view_scroll_to_mark( GTK_TEXT_VIEW (view),
- insert_mark, 0.0, TRUE, 0.0, 1.0);
+ break;
+ }
+ // tell the view to show the newest position
+ // from http://www.gtkforums.com/viewtopic.php?t=1307
+ gtk_text_buffer_get_end_iter (buffer, &iter_e);
+ insert_mark = gtk_text_buffer_get_insert (buffer);
+ gtk_text_buffer_place_cursor(buffer, &iter_e);
+ gtk_text_view_scroll_to_mark( GTK_TEXT_VIEW (view),
+ insert_mark, 0.0, TRUE, 0.0, 1.0);
}
// for more control, we implemented these callbacks in 3.3.2
void terminal_visAscii(struct tesiObject *tobj, char c, int x, int y) {
- char in[8];
- //GtkTextView *view = GTK_TEXT_VIEW(tobj->pointer);
- //GtkTextBuffer *buffer = gtk_text_view_get_buffer(view);
- GtkTextIter iter_e;
- GtkTextMark *insert_mark;
-
- snprintf(in, 7, "%c", c);
- if (log_mode) {
- gtk_text_buffer_insert_at_cursor(buffer, in, 1);
- } else {
- // FIXME: so horribly inefficient and it doesn't work.
- // constrain x to avoid GTK wrap. does'nt always do that
- if (x >= tobj->width) {
- x = tobj->width = (tobj->width -1);
+ char in[8];
+ //GtkTextView *view = GTK_TEXT_VIEW(tobj->pointer);
+ //GtkTextBuffer *buffer = gtk_text_view_get_buffer(view);
+ GtkTextIter iter_e;
+ GtkTextMark *insert_mark;
+
+ snprintf(in, 7, "%c", c);
+ if (log_mode) {
+ gtk_text_buffer_insert_at_cursor(buffer, in, 1);
+ } else {
+ // FIXME: so horribly inefficient and it doesn't work.
+ // constrain x to avoid GTK wrap. does'nt always do that
+ if (x >= tobj->width) {
+ x = tobj->width = (tobj->width -1);
+ }
+ GtkTextIter iter_s;
+ gtk_text_buffer_get_iter_at_line_offset(buffer, &iter_s, y, x);
+ gtk_text_buffer_get_iter_at_line_offset(buffer, &iter_e, y, x+1);
+ gtk_text_buffer_delete(buffer, &iter_s, &iter_e); // invalidates iters maybe
+ gtk_text_buffer_get_iter_at_line_offset(buffer, &iter_s, y, x);
+ gtk_text_buffer_place_cursor(buffer, &iter_s);
+ gtk_text_buffer_insert_at_cursor(buffer, in, 1);
+ return; // don't scroll
}
- GtkTextIter iter_s;
- gtk_text_buffer_get_iter_at_line_offset(buffer, &iter_s, y, x);
- gtk_text_buffer_get_iter_at_line_offset(buffer, &iter_e, y, x+1);
- gtk_text_buffer_delete(buffer, &iter_s, &iter_e); // invalidates iters maybe
- gtk_text_buffer_get_iter_at_line_offset(buffer, &iter_s, y, x);
- gtk_text_buffer_place_cursor(buffer, &iter_s);
- gtk_text_buffer_insert_at_cursor(buffer, in, 1);
- return; // don't scroll
- }
- // update on screen
- gtk_text_buffer_get_end_iter (buffer, &iter_e);
- insert_mark = gtk_text_buffer_get_insert (buffer);
- gtk_text_buffer_place_cursor(buffer, &iter_e);
- gtk_text_view_scroll_to_mark( GTK_TEXT_VIEW (view),
- insert_mark, 0.0, TRUE, 0.0, 1.0);
+ // update on screen
+ gtk_text_buffer_get_end_iter (buffer, &iter_e);
+ insert_mark = gtk_text_buffer_get_insert (buffer);
+ gtk_text_buffer_place_cursor(buffer, &iter_e);
+ gtk_text_view_scroll_to_mark( GTK_TEXT_VIEW (view),
+ insert_mark, 0.0, TRUE, 0.0, 1.0);
}
void terminal_return(struct tesiObject *tobj, int x, int y) {
- GtkTextIter iter;
-
- if (!log_mode) {
- gtk_text_buffer_get_iter_at_mark (buffer, &iter, begline[y]);
- //gtk_text_buffer_get_iter_at_line_index(buffer, &iter, y, 0);
- gtk_text_buffer_place_cursor(buffer, &iter);
- }
+ GtkTextIter iter;
+
+ if (!log_mode) {
+ gtk_text_buffer_get_iter_at_mark (buffer, &iter, begline[y]);
+ //gtk_text_buffer_get_iter_at_line_index(buffer, &iter, y, 0);
+ gtk_text_buffer_place_cursor(buffer, &iter);
+ }
}
void terminal_newline(struct tesiObject *tobj, int x, int y) {
- //GtkTextView *view = GTK_TEXT_VIEW(tobj->pointer);
- //GtkTextBuffer *buffer = gtk_text_view_get_buffer(view);
- GtkTextIter iter_e;
- GtkTextMark *insert_mark;
-
- if (log_mode) {
- gtk_text_buffer_insert_at_cursor(buffer, "\n", 1);
- } else {
- // tesi moved y for us. double check it's in Gtk range
- if (y >= tobj->height) {
- tobj->y = y = (tobj->height - 1);
- // real terminals did this
+ //GtkTextView *view = GTK_TEXT_VIEW(tobj->pointer);
+ //GtkTextBuffer *buffer = gtk_text_view_get_buffer(view);
+ GtkTextIter iter_e;
+ GtkTextMark *insert_mark;
+
+ if (log_mode) {
+ gtk_text_buffer_insert_at_cursor(buffer, "\n", 1);
+ } else {
+ // tesi moved y for us. double check it's in Gtk range
+ if (y >= tobj->height) {
+ tobj->y = y = (tobj->height - 1);
+ // real terminals did this
+ }
+ gtk_text_buffer_get_iter_at_mark (buffer, &iter_e, begline[y]);
+ //gtk_text_buffer_get_iter_at_line(buffer, &iter_e, buf_y);
+ gtk_text_buffer_place_cursor(buffer, &iter_e);
+ return; // don't scroll
}
- gtk_text_buffer_get_iter_at_mark (buffer, &iter_e, begline[y]);
- //gtk_text_buffer_get_iter_at_line(buffer, &iter_e, buf_y);
+ // update on screen
+ gtk_text_buffer_get_end_iter (buffer, &iter_e);
+ insert_mark = gtk_text_buffer_get_insert (buffer);
gtk_text_buffer_place_cursor(buffer, &iter_e);
- return; // don't scroll
- }
- // update on screen
- gtk_text_buffer_get_end_iter (buffer, &iter_e);
- insert_mark = gtk_text_buffer_get_insert (buffer);
- gtk_text_buffer_place_cursor(buffer, &iter_e);
- gtk_text_view_scroll_to_mark( GTK_TEXT_VIEW (view),
- insert_mark, 0.0, TRUE, 0.0, 1.0);
+ gtk_text_view_scroll_to_mark( GTK_TEXT_VIEW (view),
+ insert_mark, 0.0, TRUE, 0.0, 1.0);
}
void terminal_backspace(struct tesiObject *tobj, int x, int y) {
// GtkTextView *view = GTK_TEXT_VIEW(tobj->pointer);
// GtkTextBuffer *buffer = gtk_text_view_get_buffer(view);
- GtkTextIter iter_e;
- GtkTextMark *insert_mark;
-
- gtk_text_buffer_get_end_iter (buffer, &iter_e);
- gtk_text_buffer_backspace(buffer, &iter_e, 1, 1);
-
- // update on screen
- gtk_text_buffer_get_end_iter (buffer, &iter_e);
- insert_mark = gtk_text_buffer_get_insert (buffer);
- gtk_text_buffer_place_cursor(buffer, &iter_e);
- gtk_text_view_scroll_to_mark( GTK_TEXT_VIEW (view),
- insert_mark, 0.0, TRUE, 0.0, 1.0);
+ GtkTextIter iter_e;
+ GtkTextMark *insert_mark;
+
+ gtk_text_buffer_get_end_iter (buffer, &iter_e);
+ gtk_text_buffer_backspace(buffer, &iter_e, 1, 1);
+
+ // update on screen
+ gtk_text_buffer_get_end_iter (buffer, &iter_e);
+ insert_mark = gtk_text_buffer_get_insert (buffer);
+ gtk_text_buffer_place_cursor(buffer, &iter_e);
+ gtk_text_view_scroll_to_mark( GTK_TEXT_VIEW (view),
+ insert_mark, 0.0, TRUE, 0.0, 1.0);
}
void terminal_tab(struct tesiObject *tobj, int x, int y) {
- return terminal_visAscii(tobj, '\t', x, y);
+ return terminal_visAscii(tobj, '\t', x, y);
}
-/*
+/*
* Handle terminal attributes to Gtk Textview/buffer settings
- *
+ *
*/
struct tagcapture {
- int open;
- GtkTextTag *tag[8]; // this many tags in a Esc [ 1;2; 8m
- int begpos; // buffer offsets - marks and iters are troublesome
- int endpos; // Be wery, wery careful -- Elmer Fudd
+ int open;
+ GtkTextTag *tag[8]; // this many tags in a Esc [ 1;2; 8m
+ int begpos; // buffer offsets - marks and iters are troublesome
+ int endpos; // Be wery, wery careful -- Elmer Fudd
} capture;
static GtkTextTag *fgcolortag[256];
static GtkTextTag *bgcolortag[256];
static GtkTextTag *chartags[4];
-static GdkRGBA colortable[256];
+static GdkRGBA colortable[256];
static void initattr(GtkTextBuffer *buffer) {
#if 1
- int i;
- for (i = 0; i < 256; i++) {
- char *cstr = strdup(colorstrings[i]); // can't write into code sections
- char *hyphen = strchr(cstr, '-');
- *hyphen = '\0';
- char *name = cstr;
- char *rgbstr = ++hyphen;
- gdk_rgba_parse(&colortable[i], rgbstr);
- char bgname[8], fgname[8];
- sprintf(fgname, "%s-fg", name);
- sprintf(bgname, "%s-bg", name);
- fgcolortag[i] = gtk_text_buffer_create_tag(buffer, fgname,"foreground-rgba", &colortable[i], NULL);
- bgcolortag[i] = gtk_text_buffer_create_tag(buffer, bgname,"background-rgba", &colortable[i], NULL);
- free(cstr);
- }
-#else
- fgcolortag[0] = gtk_text_buffer_create_tag(buffer, "blackfb","foreground", "black", NULL);
- //fgcolortag[1] = gtk_text_buffer_create_tag(buffer, "redfb","foreground", "red", NULL);
- GdkRGBA temp; temp.red = 0.5; temp.green = 0.0; temp.blue =0.0; temp.alpha = 1.0;
- colortable[1] = temp;
- colortable[2].red = 0.0; colortable[2].green = 0.5; colortable[2].blue = 0.0; colortable[2].alpha = 1.0;
- fgcolortag[1] = gtk_text_buffer_create_tag(buffer, "redfg","foreground-rgba", &colortable[1], NULL);
- //fgcolortag[2] = gtk_text_buffer_create_tag(buffer, "greenfb","foreground", "green", NULL);
- fgcolortag[2] = gtk_text_buffer_create_tag(buffer, "greenfb","foreground-rgba", &colortable[2], NULL);
- fgcolortag[3] = gtk_text_buffer_create_tag(buffer, "brownfb","foreground", "brown", NULL);
- fgcolortag[4] = gtk_text_buffer_create_tag(buffer, "bluefb","foreground", "blue", NULL);
- //fgcolortag[5] = gtk_text_buffer_create_tag(buffer, "magentafb","foreground", "magenta", NULL);
- char *tstr = "#800080";
- gdk_rgba_parse(&colortable[5], tstr);
- fgcolortag[5] = gtk_text_buffer_create_tag(buffer, tstr,"foreground-rgba", &colortable[5], NULL);
- fgcolortag[6] = gtk_text_buffer_create_tag(buffer, "cyanfb","foreground", "cyan", NULL);
- fgcolortag[7] = gtk_text_buffer_create_tag(buffer, "white","foreground", "white", NULL);
-
- bgcolortag[0] = gtk_text_buffer_create_tag(buffer, "blackbg","background", "black", NULL);
- bgcolortag[1] = gtk_text_buffer_create_tag(buffer, "redbg","background", "red", NULL);
- //bgcolortag[1] = gtk_text_buffer_create_tag(buffer, "redbg", "background-rgba", colortable[1], NULL);
- bgcolortag[2] = gtk_text_buffer_create_tag(buffer, "greenbg","background", "green", NULL);
- bgcolortag[3] = gtk_text_buffer_create_tag(buffer, "brownbg","background", "brown", NULL);
- bgcolortag[4] = gtk_text_buffer_create_tag(buffer, "bluebg","background", "blue", NULL);
- bgcolortag[5] = gtk_text_buffer_create_tag(buffer, "magentabg","background", "magenta", NULL);
- bgcolortag[6] = gtk_text_buffer_create_tag(buffer, "cyanbg","background", "cyan", NULL);
- bgcolortag[7] = gtk_text_buffer_create_tag(buffer, "whitebg","background", "white", NULL);
-#endif
- chartags[0] = gtk_text_buffer_create_tag(buffer, "boldtag","weight", PANGO_WEIGHT_BOLD, NULL);
- chartags[1] = gtk_text_buffer_create_tag(buffer, "underlinetag","underline", PANGO_UNDERLINE_SINGLE, NULL);
- capture.open = 0;
+ int i;
+ for (i = 0; i < 256; i++) {
+ char *cstr = strdup(colorstrings[i]); // can't write into code sections
+ char *hyphen = strchr(cstr, '-');
+ *hyphen = '\0';
+ char *name = cstr;
+ char *rgbstr = ++hyphen;
+ gdk_rgba_parse(&colortable[i], rgbstr);
+ char bgname[8], fgname[8];
+ sprintf(fgname, "%s-fg", name);
+ sprintf(bgname, "%s-bg", name);
+ fgcolortag[i] = gtk_text_buffer_create_tag(buffer, fgname,"foreground-rgba", &colortable[i], NULL);
+ bgcolortag[i] = gtk_text_buffer_create_tag(buffer, bgname,"background-rgba", &colortable[i], NULL);
+ free(cstr);
+ }
+#else
+ fgcolortag[0] = gtk_text_buffer_create_tag(buffer, "blackfb","foreground", "black", NULL);
+ //fgcolortag[1] = gtk_text_buffer_create_tag(buffer, "redfb","foreground", "red", NULL);
+ GdkRGBA temp;
+ temp.red = 0.5;
+ temp.green = 0.0;
+ temp.blue =0.0;
+ temp.alpha = 1.0;
+ colortable[1] = temp;
+ colortable[2].red = 0.0;
+ colortable[2].green = 0.5;
+ colortable[2].blue = 0.0;
+ colortable[2].alpha = 1.0;
+ fgcolortag[1] = gtk_text_buffer_create_tag(buffer, "redfg","foreground-rgba", &colortable[1], NULL);
+ //fgcolortag[2] = gtk_text_buffer_create_tag(buffer, "greenfb","foreground", "green", NULL);
+ fgcolortag[2] = gtk_text_buffer_create_tag(buffer, "greenfb","foreground-rgba", &colortable[2], NULL);
+ fgcolortag[3] = gtk_text_buffer_create_tag(buffer, "brownfb","foreground", "brown", NULL);
+ fgcolortag[4] = gtk_text_buffer_create_tag(buffer, "bluefb","foreground", "blue", NULL);
+ //fgcolortag[5] = gtk_text_buffer_create_tag(buffer, "magentafb","foreground", "magenta", NULL);
+ char *tstr = "#800080";
+ gdk_rgba_parse(&colortable[5], tstr);
+ fgcolortag[5] = gtk_text_buffer_create_tag(buffer, tstr,"foreground-rgba", &colortable[5], NULL);
+ fgcolortag[6] = gtk_text_buffer_create_tag(buffer, "cyanfb","foreground", "cyan", NULL);
+ fgcolortag[7] = gtk_text_buffer_create_tag(buffer, "white","foreground", "white", NULL);
+
+ bgcolortag[0] = gtk_text_buffer_create_tag(buffer, "blackbg","background", "black", NULL);
+ bgcolortag[1] = gtk_text_buffer_create_tag(buffer, "redbg","background", "red", NULL);
+ //bgcolortag[1] = gtk_text_buffer_create_tag(buffer, "redbg", "background-rgba", colortable[1], NULL);
+ bgcolortag[2] = gtk_text_buffer_create_tag(buffer, "greenbg","background", "green", NULL);
+ bgcolortag[3] = gtk_text_buffer_create_tag(buffer, "brownbg","background", "brown", NULL);
+ bgcolortag[4] = gtk_text_buffer_create_tag(buffer, "bluebg","background", "blue", NULL);
+ bgcolortag[5] = gtk_text_buffer_create_tag(buffer, "magentabg","background", "magenta", NULL);
+ bgcolortag[6] = gtk_text_buffer_create_tag(buffer, "cyanbg","background", "cyan", NULL);
+ bgcolortag[7] = gtk_text_buffer_create_tag(buffer, "whitebg","background", "white", NULL);
+#endif
+ chartags[0] = gtk_text_buffer_create_tag(buffer, "boldtag","weight", PANGO_WEIGHT_BOLD, NULL);
+ chartags[1] = gtk_text_buffer_create_tag(buffer, "underlinetag","underline", PANGO_UNDERLINE_SINGLE, NULL);
+ capture.open = 0;
}
static void initgame(columns, rows) {
- blank_line = malloc(columns+2);
- int i;
- for (i = 0; i < columns; i++) blank_line[i] = ' ';
- blank_line[i++] = '\n';
- blank_line[i] = 0;
- int len = strlen(blank_line);
- GtkTextIter iter;
- gtk_text_view_set_wrap_mode(view, GTK_WRAP_NONE);
- //gtk_text_view_set_overwrite (view, TRUE);
- begline = malloc(sizeof (GtkTextMark*) * rows);
- endline = malloc(sizeof (GtkTextMark*) * rows);
- gtk_text_buffer_get_iter_at_line_index(buffer, &iter, 0, 0);
- gtk_text_buffer_place_cursor (buffer, &iter);
- for (i = 0; i < rows; i++) {
- gtk_text_buffer_get_iter_at_line (buffer, &iter, i);
- begline[i] = gtk_text_buffer_create_mark(buffer, NULL, &iter, TRUE);
- gtk_text_buffer_insert (buffer, &iter, blank_line, len);
- // endline[] May not be needed
- //gtk_text_buffer_get_iter_at_line_offset(buffer, &iter, i, columns -1);
- //endline[i] = gtk_text_buffer_create_mark(buffer, NULL, &iter, TRUE);
- }
- gtk_text_buffer_get_iter_at_line_index(buffer, &iter, 0, 0);
- gtk_text_buffer_place_cursor (buffer, &iter);
- // below returns 1 line more than I inserted. Documented behaviour.
- //int nlines = gtk_text_buffer_get_line_count(buffer);
+ blank_line = malloc(columns+2);
+ int i;
+ for (i = 0; i < columns; i++) blank_line[i] = ' ';
+ blank_line[i++] = '\n';
+ blank_line[i] = 0;
+ int len = strlen(blank_line);
+ GtkTextIter iter;
+ gtk_text_view_set_wrap_mode(view, GTK_WRAP_NONE);
+ //gtk_text_view_set_overwrite (view, TRUE);
+ begline = malloc(sizeof (GtkTextMark*) * rows);
+ endline = malloc(sizeof (GtkTextMark*) * rows);
+ gtk_text_buffer_get_iter_at_line_index(buffer, &iter, 0, 0);
+ gtk_text_buffer_place_cursor (buffer, &iter);
+ for (i = 0; i < rows; i++) {
+ gtk_text_buffer_get_iter_at_line (buffer, &iter, i);
+ begline[i] = gtk_text_buffer_create_mark(buffer, NULL, &iter, TRUE);
+ gtk_text_buffer_insert (buffer, &iter, blank_line, len);
+ // endline[] May not be needed
+ //gtk_text_buffer_get_iter_at_line_offset(buffer, &iter, i, columns -1);
+ //endline[i] = gtk_text_buffer_create_mark(buffer, NULL, &iter, TRUE);
+ }
+ gtk_text_buffer_get_iter_at_line_index(buffer, &iter, 0, 0);
+ gtk_text_buffer_place_cursor (buffer, &iter);
+ // below returns 1 line more than I inserted. Documented behaviour.
+ //int nlines = gtk_text_buffer_get_line_count(buffer);
}
void terminal_attreset(struct tesiObject *tobj) {
- // reset all attibutes (color, bold,...)
- // close the tagcapture - apply the save color from saved pt to where
- // the cursor is now. These are buffer offsets converted to iters.
- if (capture.open > 0) {
- GtkTextIter start;
- GtkTextIter end;
- GtkTextMark *endmark;
- endmark = gtk_text_buffer_get_insert(buffer); // cursor 'insert' mark
- gtk_text_buffer_get_iter_at_mark(buffer, &end, endmark);
- // convert begpos (correct offset) to start iter;
- gtk_text_buffer_get_iter_at_offset(buffer, &start, capture.begpos);
- int j;
- for (j = 0; j < capture.open; j++) {
- gtk_text_buffer_apply_tag(buffer, capture.tag[j], &start, &end);
+ // reset all attibutes (color, bold,...)
+ // close the tagcapture - apply the save color from saved pt to where
+ // the cursor is now. These are buffer offsets converted to iters.
+ if (capture.open > 0) {
+ GtkTextIter start;
+ GtkTextIter end;
+ GtkTextMark *endmark;
+ endmark = gtk_text_buffer_get_insert(buffer); // cursor 'insert' mark
+ gtk_text_buffer_get_iter_at_mark(buffer, &end, endmark);
+ // convert begpos (correct offset) to start iter;
+ gtk_text_buffer_get_iter_at_offset(buffer, &start, capture.begpos);
+ int j;
+ for (j = 0; j < capture.open; j++) {
+ gtk_text_buffer_apply_tag(buffer, capture.tag[j], &start, &end);
+ }
+ capture.open = 0;
+ // should delete or unref marks and otherwise clean up memory? TODO
}
- capture.open = 0;
- // should delete or unref marks and otherwise clean up memory? TODO
- }
-}
+}
void terminal_setfgcolor(struct tesiObject *tobj, int fg) {
- capture.tag[capture.open] = fgcolortag[(fg - 30)+8]; // go for the bright colors
- GtkTextMark *mark = gtk_text_buffer_get_insert(buffer); // cursor mark named 'insert'
- GtkTextIter start;
- // convert mark to iter to pos
- gtk_text_buffer_get_iter_at_mark(buffer, &start, mark);
- capture.begpos = gtk_text_iter_get_offset(&start);
- capture.open++; // make room for the next tag
+ capture.tag[capture.open] = fgcolortag[(fg - 30)+8]; // go for the bright colors
+ GtkTextMark *mark = gtk_text_buffer_get_insert(buffer); // cursor mark named 'insert'
+ GtkTextIter start;
+ // convert mark to iter to pos
+ gtk_text_buffer_get_iter_at_mark(buffer, &start, mark);
+ capture.begpos = gtk_text_iter_get_offset(&start);
+ capture.open++; // make room for the next tag
}
void terminal_setbgcolor(struct tesiObject *tobj, int bg) {
- capture.tag[capture.open] = bgcolortag[(bg - 40)];
- GtkTextMark *mark = gtk_text_buffer_get_insert(buffer); // cursor mark named 'insert'
- GtkTextIter start;
- // convert mark to iter to pos
- gtk_text_buffer_get_iter_at_mark(buffer, &start, mark);
- capture.begpos = gtk_text_iter_get_offset(&start);
- capture.open++; // make room for the next tag
+ capture.tag[capture.open] = bgcolortag[(bg - 40)];
+ GtkTextMark *mark = gtk_text_buffer_get_insert(buffer); // cursor mark named 'insert'
+ GtkTextIter start;
+ // convert mark to iter to pos
+ gtk_text_buffer_get_iter_at_mark(buffer, &start, mark);
+ capture.begpos = gtk_text_iter_get_offset(&start);
+ capture.open++; // make room for the next tag
}
void terminal_setfg256(struct tesiObject *tobj, int fg) {
- capture.tag[capture.open] = fgcolortag[fg]; // go for the bright colors
- GtkTextMark *mark = gtk_text_buffer_get_insert(buffer); // cursor mark named 'insert'
- GtkTextIter start;
- // convert mark to iter to pos
- gtk_text_buffer_get_iter_at_mark(buffer, &start, mark);
- capture.begpos = gtk_text_iter_get_offset(&start);
- capture.open++; // make room for the next tag
+ capture.tag[capture.open] = fgcolortag[fg]; // go for the bright colors
+ GtkTextMark *mark = gtk_text_buffer_get_insert(buffer); // cursor mark named 'insert'
+ GtkTextIter start;
+ // convert mark to iter to pos
+ gtk_text_buffer_get_iter_at_mark(buffer, &start, mark);
+ capture.begpos = gtk_text_iter_get_offset(&start);
+ capture.open++; // make room for the next tag
}
void terminal_setbg256(struct tesiObject *tobj, int bg) {
- capture.tag[capture.open] = bgcolortag[bg];
- GtkTextMark *mark = gtk_text_buffer_get_insert(buffer); // cursor mark named 'insert'
- GtkTextIter start;
- // convert mark to iter to pos
- gtk_text_buffer_get_iter_at_mark(buffer, &start, mark);
- capture.begpos = gtk_text_iter_get_offset(&start);
- capture.open++; // make room for the next tag
-}
-
-void terminal_charattr(struct tesiObject *tobj, int attr) {
- GtkTextTag *tag = NULL;
- if (attr == 1) {
- tag = chartags[0];
- } else if (attr == 4) {
- tag = chartags[1];
- }
- if (tag != NULL) {
- //GtkWidget *view = GTK_WIDGET(tobj->pointer);
- //GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW (view));
- capture.tag[capture.open] = tag;
+ capture.tag[capture.open] = bgcolortag[bg];
GtkTextMark *mark = gtk_text_buffer_get_insert(buffer); // cursor mark named 'insert'
GtkTextIter start;
// convert mark to iter to pos
gtk_text_buffer_get_iter_at_mark(buffer, &start, mark);
- capture.begpos = gtk_text_iter_get_offset(&start);
- capture.open++; // make room for the next tag
- }
+ capture.begpos = gtk_text_iter_get_offset(&start);
+ capture.open++; // make room for the next tag
}
-/*
+void terminal_charattr(struct tesiObject *tobj, int attr) {
+ GtkTextTag *tag = NULL;
+ if (attr == 1) {
+ tag = chartags[0];
+ } else if (attr == 4) {
+ tag = chartags[1];
+ }
+ if (tag != NULL) {
+ //GtkWidget *view = GTK_WIDGET(tobj->pointer);
+ //GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW (view));
+ capture.tag[capture.open] = tag;
+ GtkTextMark *mark = gtk_text_buffer_get_insert(buffer); // cursor mark named 'insert'
+ GtkTextIter start;
+ // convert mark to iter to pos
+ gtk_text_buffer_get_iter_at_mark(buffer, &start, mark);
+ capture.begpos = gtk_text_iter_get_offset(&start);
+ capture.open++; // make room for the next tag
+ }
+}
+
+/*
* NOTE - cursor based drawing is discouraged - assume it doesn't work
* because if it does work, it won't be what you want in the scrollback
- * buffer.
- *
+ * buffer.
+ *
* When a cursor based callback is called it will check the log_mode
* and if true, call start_cursor_mode. No return to log mode is possible
* Brutal, unholy things happen when switching to this mode.
- *
+ *
* Very UTF-8 unfriendly. Have I mentioned that you shouldn't do this?
*/
void start_cursor_mode(struct tesiObject *tobj) {
- if (log_mode == FALSE) return; // was called before
- log_mode = FALSE;
+ if (log_mode == FALSE) return; // was called before
+ log_mode = FALSE;
}
void terminal_clearscreen(struct tesiObject *tobj, int scrollback) {
- // if (scrollback) then clear it too.
- GtkTextView *view = GTK_TEXT_VIEW(tobj->pointer);
- GtkTextBuffer *buffer = gtk_text_view_get_buffer(view);
+ // if (scrollback) then clear it too.
+ GtkTextView *view = GTK_TEXT_VIEW(tobj->pointer);
+ GtkTextBuffer *buffer = gtk_text_view_get_buffer(view);
}
void console_eraseCharacter(struct tesiObject *tobj, int x, int y) {
- GtkTextView *view = GTK_TEXT_VIEW(tobj->pointer);
- GtkTextBuffer *buffer = gtk_text_view_get_buffer(view);
- GtkTextIter iter_e;
-
- //buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(p)); ?
- gtk_text_buffer_get_iter_at_line_index(buffer, &iter_e, y, x);
- gtk_text_buffer_backspace(buffer, &iter_e, 1, 1);
+ GtkTextView *view = GTK_TEXT_VIEW(tobj->pointer);
+ GtkTextBuffer *buffer = gtk_text_view_get_buffer(view);
+ GtkTextIter iter_e;
+
+ //buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(p)); ?
+ gtk_text_buffer_get_iter_at_line_index(buffer, &iter_e, y, x);
+ gtk_text_buffer_backspace(buffer, &iter_e, 1, 1);
}
void console_scrollUp(struct tesiObject *tobj) {
- // add line to buffer, scroll up
- GtkTextBuffer *buffer;
- GtkTextIter iter;
- gint lcnt;
- buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(tobj->pointer));
- lcnt = gtk_text_buffer_get_line_count(buffer);
- gtk_text_buffer_get_iter_at_line_index(buffer, &iter, lcnt+1, 0);
- gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(tobj->pointer), &iter, 0.0, false, 0.0, 0.0);
+ // add line to buffer, scroll up
+ GtkTextBuffer *buffer;
+ GtkTextIter iter;
+ gint lcnt;
+ buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(tobj->pointer));
+ lcnt = gtk_text_buffer_get_line_count(buffer);
+ gtk_text_buffer_get_iter_at_line_index(buffer, &iter, lcnt+1, 0);
+ gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(tobj->pointer), &iter, 0.0, false, 0.0, 0.0);
}
void terminal_moveCursor(struct tesiObject *tobj, int x, int y) {
- GtkTextIter iter;
- gtk_text_buffer_get_iter_at_line_offset(buffer, &iter, y, x);
- gtk_text_buffer_place_cursor (buffer, &iter);
+ GtkTextIter iter;
+ gtk_text_buffer_get_iter_at_line_offset(buffer, &iter, y, x);
+ gtk_text_buffer_place_cursor (buffer, &iter);
}
void console_insertLine(struct tesiObject *tobj, int y) {
- printf("Insert Line\n");
+ printf("Insert Line\n");
}
void terminal_eraseLine(struct tesiObject *tobj, int startx, int endx, int y) {
- // we can ignore this in log mode - readline will do this for a \b
- if (!log_mode) {
- GtkTextIter iter, s, e;
- int len = endx - startx;
- gtk_text_buffer_get_iter_at_line_offset(buffer, &s, y, startx);
- gtk_text_buffer_get_iter_at_line_offset(buffer, &e, y, endx);
- gtk_text_buffer_delete (buffer, &s, &e);
- gtk_text_buffer_get_iter_at_line_offset(buffer, &s, y, startx);
- gtk_text_buffer_insert(buffer, &s, blank_line, len);
- }
+ // we can ignore this in log mode - readline will do this for a \b
+ if (!log_mode) {
+ GtkTextIter iter, s, e;
+ int len = endx - startx;
+ gtk_text_buffer_get_iter_at_line_offset(buffer, &s, y, startx);
+ gtk_text_buffer_get_iter_at_line_offset(buffer, &e, y, endx);
+ gtk_text_buffer_delete (buffer, &s, &e);
+ gtk_text_buffer_get_iter_at_line_offset(buffer, &s, y, startx);
+ gtk_text_buffer_insert(buffer, &s, blank_line, len);
+ }
}
-// end of incomplete/untested functions
+// end of incomplete/untested functions
gboolean g_tesi_handleInput(gpointer data) {
- tesi_handleInput( (struct tesiObject*) data);
- return TRUE;
+ tesi_handleInput( (struct tesiObject*) data);
+ return TRUE;
}
// access to shoes_global_console
#include "shoes/app.h"
static gboolean clean(GtkWidget *widget, GdkEvent *event, gpointer data) {
- struct tesiObject *to = (struct tesiObject*)data;
- g_source_remove(to->ides); // remove g_timeout_add
- g_source_destroy(g_main_context_find_source_by_id(NULL, to->ides));
-
- deleteTesiObject(data); // FIXME see deleteTesiObject
-
- shoes_global_terminal = 0;
- // closing the console window does not restore stdin/stdout/stderr
- return FALSE;
+ struct tesiObject *to = (struct tesiObject*)data;
+ g_source_remove(to->ides); // remove g_timeout_add
+ g_source_destroy(g_main_context_find_source_by_id(NULL, to->ides));
+
+ deleteTesiObject(data); // FIXME see deleteTesiObject
+
+ shoes_global_terminal = 0;
+ // closing the console window does not restore stdin/stdout/stderr
+ return FALSE;
}
#ifdef USE_PTY // Linux only. Debug only. TODO !!
// callback for raw capture
-static void terminal_raw (struct tesiObject *tobj, char *raw, int len)
-{
- int i;
- for (i = 0; i < len; i++) {
- g_string_append_c(rawBuffer, (gchar) raw[i]);
- }
+static void terminal_raw (struct tesiObject *tobj, char *raw, int len) {
+ int i;
+ for (i = 0; i < len; i++) {
+ g_string_append_c(rawBuffer, (gchar) raw[i]);
+ }
}
#endif
void shoes_native_terminal(char *app_dir, int mode, int columns, int rows,
- int fontsize, char* fg, char *bg, char* title)
-{
- GtkWidget *window;
- GtkWidget *canvas;
- GtkWidget *vbox;
- GtkScrolledWindow *sw;
- PangoFontDescription *pfd; // for terminal
- PangoFontDescription *bpfd; // for Label in button panel
-
- struct tesiObject *t;
- // create the debugging capture buffer. expands as needed.
- // Not a lot of memory all things considered.
- rawBuffer = g_string_sized_new (4096);
-
- terminal_window = window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- // size set below based on font (rows*columns)
- //gtk_window_set_resizable(GTK_WINDOW(window), TRUE);
- gtk_window_set_resizable(GTK_WINDOW(window), FALSE);
- gtk_window_set_title (GTK_WINDOW (window), title);
-
- // like a Shoes stack at the top.
- vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);
- gtk_container_add (GTK_CONTAINER (window), vbox);
-
- // need a panel with a string (icon?), copy button and clear button
- GtkWidget *btnpnl = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 2); // think flow layout
- // create widgets for btnpnl - icon, title, clear, copy, copy-raw
- // icon is wicked
- char icon_path[256];
- sprintf(icon_path, "%s/static/app-icon.png", app_dir);
- GdkPixbuf *icon_pix = gdk_pixbuf_new_from_file_at_size(icon_path, 32, 32, NULL);
- GtkWidget *icon = gtk_image_new_from_pixbuf(icon_pix);
- gtk_box_pack_start (GTK_BOX(btnpnl), icon, 1, 0, 0);
-
- GtkWidget *announce = gtk_label_new(title? title : "Shoes Terminal");
- bpfd = pango_font_description_from_string ("Sans-Serif Italic 14");
- gtk_widget_override_font (announce, bpfd);
- gtk_box_pack_start(GTK_BOX(btnpnl), announce, 1, 0, 0);
-
- GtkWidget *clrbtn = gtk_button_new_with_label ("Clear");
- gtk_box_pack_start (GTK_BOX(btnpnl), clrbtn, 1, 0, 0);
-
- GtkWidget *cpybtn = gtk_button_new_with_label ("Copy");
- gtk_box_pack_start (GTK_BOX(btnpnl), cpybtn, 1, 0, 0);
-
- GtkWidget *rawbtn = gtk_button_new_with_label ("copy raw");
- gtk_box_pack_start (GTK_BOX(btnpnl), rawbtn, 1, 0, 0);
-
- gtk_box_pack_start (GTK_BOX(vbox), GTK_WIDGET(btnpnl), 0, 0, 0);
-
-
- // then a widget/panel for the terminal
- sw = GTK_SCROLLED_WINDOW(gtk_scrolled_window_new(NULL, NULL));
- gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW(sw),
- GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
- gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET(sw), 1, 1, 0);
-
- canvas = gtk_text_view_new();
- view = GTK_TEXT_VIEW(canvas);
- gtk_container_add (GTK_CONTAINER (sw), canvas);
- gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(canvas), TRUE);
- gtk_text_view_set_left_margin(GTK_TEXT_VIEW(canvas), 4);
- gtk_text_view_set_right_margin(GTK_TEXT_VIEW(canvas), 4);
- gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(canvas), GTK_WRAP_CHAR);
- //gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(canvas), GTK_WRAP_NONE);
-
- // Deal with the colors of the terminal widget. Note: these functions
- // are deprecated at gtk 3.16
- GdkRGBA bg_color, fg_color;
- if (fg)
- gdk_rgba_parse(&fg_color, fg);
- else
- gdk_rgba_parse(&fg_color, "black");
- gtk_widget_override_color(canvas, GTK_STATE_FLAG_NORMAL, &fg_color);
- if (bg)
- gdk_rgba_parse(&bg_color, bg);
- else
- gdk_rgba_parse(&bg_color, "white");
- gtk_widget_override_background_color(canvas, GTK_STATE_FLAG_NORMAL, &bg_color);
-
- // set font for scrollable window
- char fontnm[64];
- sprintf(fontnm,"monospace %d", fontsize);
- pfd = pango_font_description_from_string (fontnm);
- //pfd = pango_font_description_from_string ("monospace 12");
- gtk_widget_override_font (canvas, pfd);
-
- // compute 'char' width, and tab settings.
- PangoLayout *playout;
- PangoTabArray *tab_array;
- gint charwidth, charheight, tabwidth;
- playout = gtk_widget_create_pango_layout(canvas, "M");
- pango_layout_set_font_description(playout, pfd);
- pango_layout_get_pixel_size(playout, &charwidth, &charheight);
- tabwidth = charwidth * 8;
- tab_array = pango_tab_array_new(1, TRUE);
- pango_tab_array_set_tab( tab_array, 0, PANGO_TAB_LEFT, tabwidth);
- gtk_text_view_set_tabs(GTK_TEXT_VIEW(canvas), tab_array);
-
- // init buffers base on mode.
- if (mode == 0) {
- log_mode = 0;
- game_buffer = buffer = gtk_text_view_get_buffer(view);
- initattr(game_buffer);
- initgame(columns, rows);
- } else { // default
- log_buffer = buffer = gtk_text_view_get_buffer(view);
- initattr(log_buffer);
- }
-
- //gtk_widget_set_size_request (GTK_WIDGET (sw), 80*charwidth, 24*charheight);
- int slop = charwidth * 3; // probably the 4 pixel margins.
- gtk_widget_set_size_request (GTK_WIDGET (sw), (columns*charwidth)+slop, rows*charheight);
-
- t = newTesiObject("/bin/bash", columns, rows); // first arg not used
- tobj = t;
- t->pointer = canvas;
- //t->callback_haveCharacter = &console_haveChar;
- // cjc - haveCharacter short circuts all? of the callbacks below:
- t->callback_handleNL = &terminal_newline;
- t->callback_handleRTN = &terminal_return;
- t->callback_handleBS = &terminal_backspace;
- t->callback_handleTAB = &terminal_tab;
- t->callback_handleBEL = NULL;
- t->callback_printCharacter = &terminal_visAscii;
- t->callback_attreset = &terminal_attreset;
- t->callback_charattr = terminal_charattr;
- t->callback_setfgcolor= &terminal_setfgcolor;
- t->callback_setbgcolor = &terminal_setbgcolor;
- t->callback_setfg256 = &terminal_setfg256;
- t->callback_setbg256 = &terminal_setbg256;
- // that's the minimum set of call backs;
- t->callback_setdefcolor = NULL;
- t->callback_deleteLines = NULL;
- t->callback_insertLines = NULL;
- t->callback_attributes = NULL; // old tesi - not used?
-
- t->callback_clearScreen = NULL; //&terminal_clearscreen;
- t->callback_eraseCharacter = NULL; // &console_eraseCharacter;
- t->callback_moveCursor = &terminal_moveCursor;
- t->callback_insertLines = NULL; //&console_insertLine;
- t->callback_eraseLine = &terminal_eraseLine;
- t->callback_scrollUp = NULL; // &console_scrollUp;
+ int fontsize, char* fg, char *bg, char* title) {
+ GtkWidget *window;
+ GtkWidget *canvas;
+ GtkWidget *vbox;
+ GtkScrolledWindow *sw;
+ PangoFontDescription *pfd; // for terminal
+ PangoFontDescription *bpfd; // for Label in button panel
+
+ struct tesiObject *t;
+ // create the debugging capture buffer. expands as needed.
+ // Not a lot of memory all things considered.
+ rawBuffer = g_string_sized_new (4096);
+
+ terminal_window = window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ // size set below based on font (rows*columns)
+ //gtk_window_set_resizable(GTK_WINDOW(window), TRUE);
+ gtk_window_set_resizable(GTK_WINDOW(window), FALSE);
+ gtk_window_set_title (GTK_WINDOW (window), title);
+
+ // like a Shoes stack at the top.
+ vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);
+ gtk_container_add (GTK_CONTAINER (window), vbox);
+
+ // need a panel with a string (icon?), copy button and clear button
+ GtkWidget *btnpnl = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 2); // think flow layout
+ // create widgets for btnpnl - icon, title, clear, copy, copy-raw
+ // icon is wicked
+ char icon_path[256];
+ sprintf(icon_path, "%s/static/app-icon.png", app_dir);
+ GdkPixbuf *icon_pix = gdk_pixbuf_new_from_file_at_size(icon_path, 32, 32, NULL);
+ GtkWidget *icon = gtk_image_new_from_pixbuf(icon_pix);
+ gtk_box_pack_start (GTK_BOX(btnpnl), icon, 1, 0, 0);
+
+ GtkWidget *announce = gtk_label_new(title? title : "Shoes Terminal");
+ bpfd = pango_font_description_from_string ("Sans-Serif Italic 14");
+ gtk_widget_override_font (announce, bpfd);
+ gtk_box_pack_start(GTK_BOX(btnpnl), announce, 1, 0, 0);
+
+ GtkWidget *clrbtn = gtk_button_new_with_label ("Clear");
+ gtk_box_pack_start (GTK_BOX(btnpnl), clrbtn, 1, 0, 0);
+
+ GtkWidget *cpybtn = gtk_button_new_with_label ("Copy");
+ gtk_box_pack_start (GTK_BOX(btnpnl), cpybtn, 1, 0, 0);
+
+ GtkWidget *rawbtn = gtk_button_new_with_label ("copy raw");
+ gtk_box_pack_start (GTK_BOX(btnpnl), rawbtn, 1, 0, 0);
+
+ gtk_box_pack_start (GTK_BOX(vbox), GTK_WIDGET(btnpnl), 0, 0, 0);
+
+
+ // then a widget/panel for the terminal
+ sw = GTK_SCROLLED_WINDOW(gtk_scrolled_window_new(NULL, NULL));
+ gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW(sw),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
+ gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET(sw), 1, 1, 0);
+
+ canvas = gtk_text_view_new();
+ view = GTK_TEXT_VIEW(canvas);
+ gtk_container_add (GTK_CONTAINER (sw), canvas);
+ gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(canvas), TRUE);
+ gtk_text_view_set_left_margin(GTK_TEXT_VIEW(canvas), 4);
+ gtk_text_view_set_right_margin(GTK_TEXT_VIEW(canvas), 4);
+ gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(canvas), GTK_WRAP_CHAR);
+ //gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(canvas), GTK_WRAP_NONE);
+
+ // Deal with the colors of the terminal widget. Note: these functions
+ // are deprecated at gtk 3.16
+ GdkRGBA bg_color, fg_color;
+ if (fg)
+ gdk_rgba_parse(&fg_color, fg);
+ else
+ gdk_rgba_parse(&fg_color, "black");
+ gtk_widget_override_color(canvas, GTK_STATE_FLAG_NORMAL, &fg_color);
+ if (bg)
+ gdk_rgba_parse(&bg_color, bg);
+ else
+ gdk_rgba_parse(&bg_color, "white");
+ gtk_widget_override_background_color(canvas, GTK_STATE_FLAG_NORMAL, &bg_color);
+
+ // set font for scrollable window
+ char fontnm[64];
+ sprintf(fontnm,"monospace %d", fontsize);
+ pfd = pango_font_description_from_string (fontnm);
+ //pfd = pango_font_description_from_string ("monospace 12");
+ gtk_widget_override_font (canvas, pfd);
+
+ // compute 'char' width, and tab settings.
+ PangoLayout *playout;
+ PangoTabArray *tab_array;
+ gint charwidth, charheight, tabwidth;
+ playout = gtk_widget_create_pango_layout(canvas, "M");
+ pango_layout_set_font_description(playout, pfd);
+ pango_layout_get_pixel_size(playout, &charwidth, &charheight);
+ tabwidth = charwidth * 8;
+ tab_array = pango_tab_array_new(1, TRUE);
+ pango_tab_array_set_tab( tab_array, 0, PANGO_TAB_LEFT, tabwidth);
+ gtk_text_view_set_tabs(GTK_TEXT_VIEW(canvas), tab_array);
+
+ // init buffers base on mode.
+ if (mode == 0) {
+ log_mode = 0;
+ game_buffer = buffer = gtk_text_view_get_buffer(view);
+ initattr(game_buffer);
+ initgame(columns, rows);
+ } else { // default
+ log_buffer = buffer = gtk_text_view_get_buffer(view);
+ initattr(log_buffer);
+ }
+
+ //gtk_widget_set_size_request (GTK_WIDGET (sw), 80*charwidth, 24*charheight);
+ int slop = charwidth * 3; // probably the 4 pixel margins.
+ gtk_widget_set_size_request (GTK_WIDGET (sw), (columns*charwidth)+slop, rows*charheight);
+
+ t = newTesiObject("/bin/bash", columns, rows); // first arg not used
+ tobj = t;
+ t->pointer = canvas;
+ //t->callback_haveCharacter = &console_haveChar;
+ // cjc - haveCharacter short circuts all? of the callbacks below:
+ t->callback_handleNL = &terminal_newline;
+ t->callback_handleRTN = &terminal_return;
+ t->callback_handleBS = &terminal_backspace;
+ t->callback_handleTAB = &terminal_tab;
+ t->callback_handleBEL = NULL;
+ t->callback_printCharacter = &terminal_visAscii;
+ t->callback_attreset = &terminal_attreset;
+ t->callback_charattr = terminal_charattr;
+ t->callback_setfgcolor= &terminal_setfgcolor;
+ t->callback_setbgcolor = &terminal_setbgcolor;
+ t->callback_setfg256 = &terminal_setfg256;
+ t->callback_setbg256 = &terminal_setbg256;
+ // that's the minimum set of call backs;
+ t->callback_setdefcolor = NULL;
+ t->callback_deleteLines = NULL;
+ t->callback_insertLines = NULL;
+ t->callback_attributes = NULL; // old tesi - not used?
+
+ t->callback_clearScreen = NULL; //&terminal_clearscreen;
+ t->callback_eraseCharacter = NULL; // &console_eraseCharacter;
+ t->callback_moveCursor = &terminal_moveCursor;
+ t->callback_insertLines = NULL; //&console_insertLine;
+ t->callback_eraseLine = &terminal_eraseLine;
+ t->callback_scrollUp = NULL; // &console_scrollUp;
#ifdef USE_PTY // Linux only
- t->callback_rawCapture = &terminal_raw; //debugging -remove it later!!
+ t->callback_rawCapture = &terminal_raw; //debugging -remove it later!!
#endif
-
- g_signal_connect(G_OBJECT(window), "delete_event", G_CALLBACK(clean), t);
-
- g_signal_connect (G_OBJECT (canvas), "key-press-event", G_CALLBACK (keypress_event), t);
- g_signal_connect (G_OBJECT (clrbtn), "clicked", G_CALLBACK (clear_console), t);
- g_signal_connect (G_OBJECT (cpybtn), "clicked", G_CALLBACK (copy_console), t);
- g_signal_connect (G_OBJECT (rawbtn), "clicked", G_CALLBACK (raw_copy), t);
-
- gtk_widget_grab_focus(canvas);
- //unsigned int ides = g_timeout_add(100, &g_tesi_handleInput, t);
- unsigned int ides = g_timeout_add(20, &g_tesi_handleInput, t);
- t->ides = ides;
-
- gtk_widget_show_all (window);
-
- // TODO: some clean up here. Complete ?
- pango_font_description_free(pfd);
- pango_font_description_free(bpfd);
- pango_tab_array_free(tab_array);
- g_object_unref(playout);
- return;
+
+ g_signal_connect(G_OBJECT(window), "delete_event", G_CALLBACK(clean), t);
+
+ g_signal_connect (G_OBJECT (canvas), "key-press-event", G_CALLBACK (keypress_event), t);
+ g_signal_connect (G_OBJECT (clrbtn), "clicked", G_CALLBACK (clear_console), t);
+ g_signal_connect (G_OBJECT (cpybtn), "clicked", G_CALLBACK (copy_console), t);
+ g_signal_connect (G_OBJECT (rawbtn), "clicked", G_CALLBACK (raw_copy), t);
+
+ gtk_widget_grab_focus(canvas);
+ //unsigned int ides = g_timeout_add(100, &g_tesi_handleInput, t);
+ unsigned int ides = g_timeout_add(20, &g_tesi_handleInput, t);
+ t->ides = ides;
+
+ gtk_widget_show_all (window);
+
+ // TODO: some clean up here. Complete ?
+ pango_font_description_free(pfd);
+ pango_font_description_free(bpfd);
+ pango_tab_array_free(tab_array);
+ g_object_unref(playout);
+ return;
}
diff --git a/shoes/console/tesi.c b/shoes/console/tesi.c
index e04fd737..2aa4a641 100644
--- a/shoes/console/tesi.c
+++ b/shoes/console/tesi.c
@@ -1,23 +1,23 @@
#include "tesi.h"
-/*
- * This is a state machine to parse a subset of xterm[-256] escape sequences
+/*
+ * This is a state machine to parse a subset of xterm[-256] escape sequences
* that arrive on a pty (slave side) and call back into gtk/cocoa functions
* to implement that sequence 'clear_screen' or 'setcolor' or ...
- *
+ *
* Those call back functions have nothing to do with Shoes. The window they
- * draw to is invisible to Shoes scripts and we won't call any Shoes or Ruby
- * internal code
- *
- * The code expects row & colunm numbers in escape sequences (1,1) is the
+ * draw to is invisible to Shoes scripts and we won't call any Shoes or Ruby
+ * internal code
+ *
+ * The code expects row & colunm numbers in escape sequences (1,1) is the
* top left for escape sequences and width and height of 80 and 24 or 25
* are common. The gtk/cocoa backends expect (0,0) so this code is a fine
* source of 'off by one' errors and confusion. Internally, the main struct
* tesiObject is 0,0 based for x,y
- *
+ *
* If you don't setup a console_haveChar() callback (the short-circuit)
* then you need to implement the following call backs in gtk & cocoa
- *
- * Required
+ *
+ * Required
* callback_printChar Required
* callback_handleNL Required for Shoes
* callback_handleBS Required for Shoes
@@ -31,13 +31,13 @@
* callback_scrollUp Dragons Here!
* callback_scrollDown Dragons Here!
* callback_bell Dragons Here!
- * callback_invertColors God Forbid.
- *
+ * callback_invertColors God Forbid.
+ *
*/
//#define DEBUG 1
// forward declares - these are private to tesi.c - they may simulate behaviour
-// or do nothing at all.
+// or do nothing at all.
static void tesi_seqED(struct tesiObject *to); // Erase Display
static void tesi_seqEL(struct tesiObject *to); // Erase Line
/*
@@ -46,81 +46,81 @@ handleInput
*/
#ifdef USE_PTY // aka Linux, not osx, not windows
int tesi_handleInput(struct tesiObject *to) {
- char input[128];
- char *pointer, c;
- long lengthRead;
- int i; //, j, sequenceLength;
- //FILE *f;
- struct pollfd fds[1];
-
- // use sequenceLength as a local cache for faster ops?
- // avoid premature optimization ... wait until find bottlenecks
-
- // use poll for it's speed, allows us to call this function at regular intervals without first checking for input
- fds[0].fd = to->fd_activity;
- fds[0].events = POLLIN | POLLPRI;
- poll(fds, 1, 0);
- if((fds[0].revents & (POLLIN | POLLPRI)) == 0) {
- return 0;
- }
-
- lengthRead = read(to->ptyMaster, input, 128);
- if (to->callback_rawCapture) {
- to->callback_rawCapture(to, input, lengthRead);
- }
+ char input[128];
+ char *pointer, c;
+ long lengthRead;
+ int i; //, j, sequenceLength;
+ //FILE *f;
+ struct pollfd fds[1];
+
+ // use sequenceLength as a local cache for faster ops?
+ // avoid premature optimization ... wait until find bottlenecks
+
+ // use poll for it's speed, allows us to call this function at regular intervals without first checking for input
+ fds[0].fd = to->fd_activity;
+ fds[0].events = POLLIN | POLLPRI;
+ poll(fds, 1, 0);
+ if((fds[0].revents & (POLLIN | POLLPRI)) == 0) {
+ return 0;
+ }
+
+ lengthRead = read(to->ptyMaster, input, 128);
+ if (to->callback_rawCapture) {
+ to->callback_rawCapture(to, input, lengthRead);
+ }
#else
int tesi_handleInput(struct tesiObject *to, char *input, int lengthRead) {
- char *pointer, c;
- int i;
+ char *pointer, c;
+ int i;
#endif
- pointer = input;
- for(i = 0; i < lengthRead; i++, pointer++) {
- c = *pointer;
- if(c == 0) { // skip NULL for unicode?
- continue;
- }
- // has Shoes put a short circuit in? Call it
- if (to->callback_haveCharacter) {
- to->callback_haveCharacter(to, c);
- continue;
- }
+ pointer = input;
+ for(i = 0; i < lengthRead; i++, pointer++) {
+ c = *pointer;
+ if(c == 0) { // skip NULL for unicode?
+ continue;
+ }
+ // has Shoes put a short circuit in? Call it
+ if (to->callback_haveCharacter) {
+ to->callback_haveCharacter(to, c);
+ continue;
+ }
+
+ if((c >= 1 && c <= 31) || c == 127) {
+ tesi_handleControlCharacter(to, c);
+ continue;
+ }
- if((c >= 1 && c <= 31) || c == 127) {
- tesi_handleControlCharacter(to, c);
- continue;
- }
-
- if(to->partialSequence) { // was set in tesi_handleControlCharacter()
- // keep track of the sequence type. some
- to->sequence[ to->sequenceLength++ ] = c;
- to->sequence[ to->sequenceLength ] = 0;
- if(
- (c >= 'a' && c <= 'z') ||
- (c >= 'A' && c <= 'Z')
- ) // done with sequence
- to->partialSequence = 0;
-
- if(to->partialSequence == 0) {
- tesi_interpretSequence(to); // we've got everything in the esc sequence
- to->sequenceLength = 0;
- to->parametersLength = 0;
- }
- } else { // standard text, not part of any escape sequence
- if(to->partialSequence == 0) {
- // newlines aren't in visible range, so they shouldn't be a problem
- if(to->insertMode == 0 && to->callback_printCharacter) {
- to->callback_printCharacter(to, c, to->x, to->y);
- to->x++;
- //tesi_limitCursor(to, 1);
- }
- // cjc: we don't do insert mode
- if(to->insertMode == 1 && to->callback_insertCharacter) {
- to->callback_insertCharacter(to, c, to->x, to->y);
- }
- }
- }
- }
- return 1;
+ if(to->partialSequence) { // was set in tesi_handleControlCharacter()
+ // keep track of the sequence type. some
+ to->sequence[ to->sequenceLength++ ] = c;
+ to->sequence[ to->sequenceLength ] = 0;
+ if(
+ (c >= 'a' && c <= 'z') ||
+ (c >= 'A' && c <= 'Z')
+ ) // done with sequence
+ to->partialSequence = 0;
+
+ if(to->partialSequence == 0) {
+ tesi_interpretSequence(to); // we've got everything in the esc sequence
+ to->sequenceLength = 0;
+ to->parametersLength = 0;
+ }
+ } else { // standard text, not part of any escape sequence
+ if(to->partialSequence == 0) {
+ // newlines aren't in visible range, so they shouldn't be a problem
+ if(to->insertMode == 0 && to->callback_printCharacter) {
+ to->callback_printCharacter(to, c, to->x, to->y);
+ to->x++;
+ //tesi_limitCursor(to, 1);
+ }
+ // cjc: we don't do insert mode
+ if(to->insertMode == 1 && to->callback_insertCharacter) {
+ to->callback_insertCharacter(to, c, to->x, to->y);
+ }
+ }
+ }
+ }
+ return 1;
}
/*
@@ -129,72 +129,72 @@ int tesi_handleInput(struct tesiObject *to, char *input, int lengthRead) {
* Also starts a new escape sequence when ASCII 27 is read
* */
int tesi_handleControlCharacter(struct tesiObject *to, char c) {
- int i, j;
- // entire switch from Rote
- switch (c) {
- case '\x1B': // begin escape sequence (aborting previous one if any)
- to->partialSequence = 1;
- // possibly flush buffer
- break;
-
- case '\r': // carriage return ('M' - '@'). Move cursor to first column.
- to->x = 0;
- if(to->callback_handleRTN)
- to->callback_handleRTN(to, to->x, to->y);
- break;
-
- case '\n': // line feed ('J' - '@'). Move cursor down line and to first column.
- to->y++;
- //if(to->insertMode == 0 && to->linefeedMode == 1)
- to->x = 0;
-
- //if(i == 1 && to->callback_scrollUp)
- // to->callback_scrollUp(to->pointer);
- //tesi_limitCursor(to, 1);
- if (to->callback_handleNL)
- to->callback_handleNL(to, to->x, to->y);
- break;
-
- case '\t': // ht - horizontal tab, ('I' - '@')
- if (to->callback_handleTAB) {
- to->callback_handleTAB(to, to->x, to->y);
- break; // This prevents tesi from writing spaces it's way
- }
- j = 8 - (to->x % 8);
- if(j == 0)
- j = 8;
- for(i = 0; i < j; i++, to->x++) {
- if(tesi_limitCursor(to, 1))
- break;
- if(to->callback_moveCursor)
- to->callback_moveCursor(to , to->x, to->y);
- if(to->callback_printCharacter)
- to->callback_printCharacter(to , ' ', to->x, to->y);
- }
- break;
-
- case '\a': // bell ('G' - '@')
- // do nothing for now... maybe a visual bell would be nice?
- if(to->callback_handleBEL)
- to->callback_handleBEL(to, to->x, to->y);
- break;
-
- case 8: // backspace cub1 cursor back 1 ('H' - '@')
- // what do i do about wrapping back up to previous line?
- // where should that be handled
- // just move cursor, don't print space
- //tesi_limitCursor(to, 1);
- if(to->callback_handleBS)
- to->callback_handleBS(to, to->x, to->y);
- if (to->x > 0)
- to->x--;
- break;
-
- default:
- return false;
- break;
- }
- return true;
+ int i, j;
+ // entire switch from Rote
+ switch (c) {
+ case '\x1B': // begin escape sequence (aborting previous one if any)
+ to->partialSequence = 1;
+ // possibly flush buffer
+ break;
+
+ case '\r': // carriage return ('M' - '@'). Move cursor to first column.
+ to->x = 0;
+ if(to->callback_handleRTN)
+ to->callback_handleRTN(to, to->x, to->y);
+ break;
+
+ case '\n': // line feed ('J' - '@'). Move cursor down line and to first column.
+ to->y++;
+ //if(to->insertMode == 0 && to->linefeedMode == 1)
+ to->x = 0;
+
+ //if(i == 1 && to->callback_scrollUp)
+ // to->callback_scrollUp(to->pointer);
+ //tesi_limitCursor(to, 1);
+ if (to->callback_handleNL)
+ to->callback_handleNL(to, to->x, to->y);
+ break;
+
+ case '\t': // ht - horizontal tab, ('I' - '@')
+ if (to->callback_handleTAB) {
+ to->callback_handleTAB(to, to->x, to->y);
+ break; // This prevents tesi from writing spaces it's way
+ }
+ j = 8 - (to->x % 8);
+ if(j == 0)
+ j = 8;
+ for(i = 0; i < j; i++, to->x++) {
+ if(tesi_limitCursor(to, 1))
+ break;
+ if(to->callback_moveCursor)
+ to->callback_moveCursor(to, to->x, to->y);
+ if(to->callback_printCharacter)
+ to->callback_printCharacter(to, ' ', to->x, to->y);
+ }
+ break;
+
+ case '\a': // bell ('G' - '@')
+ // do nothing for now... maybe a visual bell would be nice?
+ if(to->callback_handleBEL)
+ to->callback_handleBEL(to, to->x, to->y);
+ break;
+
+ case 8: // backspace cub1 cursor back 1 ('H' - '@')
+ // what do i do about wrapping back up to previous line?
+ // where should that be handled
+ // just move cursor, don't print space
+ //tesi_limitCursor(to, 1);
+ if(to->callback_handleBS)
+ to->callback_handleBS(to, to->x, to->y);
+ if (to->x > 0)
+ to->x--;
+ break;
+
+ default:
+ return false;
+ break;
+ }
+ return true;
}
/*
@@ -204,207 +204,207 @@ int tesi_handleControlCharacter(struct tesiObject *to, char c) {
* parameters (ascii decimal characters), separated by ';' if more than one
*/
void tesi_interpretSequence(struct tesiObject *to) {
- char *p = to->sequence;
- char *q; // another pointer
- char c;
- char *secondChar = to->sequence; // used to test for ? after [
- char operation = to->sequence[to->sequenceLength - 1];
- int i,j;
-
- // init parameters to zero
- for(i=0; i<6; i++)
- to->parameters[i] = 0;
- to->parametersLength = 0;
-
- if(*secondChar == '?') //ignore it
- p++;
- // parse numeric parameters
- q = p++; // move past esc [
- c = *p;
-
- while ((c >= '0' && c <= '9') || c == ';') {
- if (c == ';') {
- if (to->parametersLength > 6)
- return; // too many - best to ignore.
- to->parametersLength++;
- } else {
- j = to->parameters[ to->parametersLength ];
- j = j * 10;
- j += c - '0';
- to->parameters[ to->parametersLength ] = j;
- }
- p++;
- c = *p;
- }
- if(p != q)
- to->parametersLength++;
-
- if( (operation >= 'A' && operation <= 'Z') || (operation >= 'a' && operation <= 'z')) {
- int j;
- switch(operation) {
- // RESET INITIALIZATIONS
- case 'l': // defaults
- to->parameters[0] = 0;
- tesi_processAttributes(to, to->parameters[0], 0) ; // FIXME:
- to->parameters[0] = 1;
- tesi_processAttributes(to, to->parameters[0], 0); // FIXME:
- // scroll regions, colors, etc.
- break;
- case 'J': // ED erase display
- tesi_seqED(to);
- break;
-
- // LINE-RELATED
- case 'K': // clear line --
- tesi_seqEL(to);
- break;
- case 'L': // insert line(s)
- if(to->callback_insertLines)
- to->callback_insertLines(to, to->parameters[0]);
- break;
- case 'M': // delelete line(s)
- if (to->callback_deleteLines)
- to->callback_deleteLines(to, to->parameters[0]);
- break;
-
- // ATTRIBUTES AND MODES
- case 'm': // SGR attributes
- for (i = 0; i < to->parametersLength; i++)
- tesi_processAttributes(to, to->parameters[i], i);
- break;
- case 'h': // enter/exit insert mode
- break;
-
- // CURSOR RELATED
- case 'A': // CUU Move cursor up the indicated # of rows.
- j = to->parameters[0];
- if (j == 0) j = 1;
- to->y -= j;
- tesi_limitCursor(to, 1);
- break;
- case 'B': // CUD Move cursor down the indicated # of rows.
- j = to->parameters[0];
- if (j == 0) j = 1;
- to->y += j;
- tesi_limitCursor(to, 1);
- break;
- case 'C': // CUF Move cursor right the indicated # of columns.
- j = to->parameters[0];
- if (j == 0) j = 1;
- to->x += j;
- tesi_limitCursor(to, 1);
- break;
- case 'D': // CUB Move cursor left the indicated # of columns.
- j = to->parameters[0];
- if (j == 0) j = 1;
- to->x -= j;
- tesi_limitCursor(to, 1);
- break;
- case 'E': // CNL Move cursor down the indicated # of rows, to column 1.
- j = to->parameters[0];
- if (j == 0) j = 1;
- to->y += j;
- to->x = 0;
- tesi_limitCursor(to, 1);
- break;
- case 'F': // CPL Move cursor up the indicated # of rows, to column 1.
- j = to->parameters[0];
- if (j == 0) j = 1;
- to->y -= j;
- to->x = 0;
- tesi_limitCursor(to, 1);
- break;
- case 'G': // CHA Move cursor to indicated column in current row.
- j = to->parameters[0];
- to->y = j - 1; // escape cursor address is 1..80, not 0..79
- tesi_limitCursor(to, 1);
- break;
- case 'f': // HVP
- case 'H': // CUP. move cursor to row, column
- // parameters should be 1 more than the real value
- if(to->parametersLength == 0)
- to->x = to->y = 0;
- else {
- to->x = to->parameters[1] - 1;
- to->y = to->parameters[0] - 1;
- }
- // limit cursor to boundaries
- tesi_limitCursor(to, 1);
- break;
-
- // SCROLLING RELATED
- case 'r': // change scrolling region
+ char *p = to->sequence;
+ char *q; // another pointer
+ char c;
+ char *secondChar = to->sequence; // used to test for ? after [
+ char operation = to->sequence[to->sequenceLength - 1];
+ int i,j;
+
+ // init parameters to zero
+ for(i=0; i<6; i++)
+ to->parameters[i] = 0;
+ to->parametersLength = 0;
+
+ if(*secondChar == '?') //ignore it
+ p++;
+ // parse numeric parameters
+ q = p++; // move past esc [
+ c = *p;
+
+ while ((c >= '0' && c <= '9') || c == ';') {
+ if (c == ';') {
+ if (to->parametersLength > 6)
+ return; // too many - best to ignore.
+ to->parametersLength++;
+ } else {
+ j = to->parameters[ to->parametersLength ];
+ j = j * 10;
+ j += c - '0';
+ to->parameters[ to->parametersLength ] = j;
+ }
+ p++;
+ c = *p;
+ }
+ if(p != q)
+ to->parametersLength++;
+
+ if( (operation >= 'A' && operation <= 'Z') || (operation >= 'a' && operation <= 'z')) {
+ int j;
+ switch(operation) {
+ // RESET INITIALIZATIONS
+ case 'l': // defaults
+ to->parameters[0] = 0;
+ tesi_processAttributes(to, to->parameters[0], 0) ; // FIXME:
+ to->parameters[0] = 1;
+ tesi_processAttributes(to, to->parameters[0], 0); // FIXME:
+ // scroll regions, colors, etc.
+ break;
+ case 'J': // ED erase display
+ tesi_seqED(to);
+ break;
+
+ // LINE-RELATED
+ case 'K': // clear line --
+ tesi_seqEL(to);
+ break;
+ case 'L': // insert line(s)
+ if(to->callback_insertLines)
+ to->callback_insertLines(to, to->parameters[0]);
+ break;
+ case 'M': // delelete line(s)
+ if (to->callback_deleteLines)
+ to->callback_deleteLines(to, to->parameters[0]);
+ break;
+
+ // ATTRIBUTES AND MODES
+ case 'm': // SGR attributes
+ for (i = 0; i < to->parametersLength; i++)
+ tesi_processAttributes(to, to->parameters[i], i);
+ break;
+ case 'h': // enter/exit insert mode
+ break;
+
+ // CURSOR RELATED
+ case 'A': // CUU Move cursor up the indicated # of rows.
+ j = to->parameters[0];
+ if (j == 0) j = 1;
+ to->y -= j;
+ tesi_limitCursor(to, 1);
+ break;
+ case 'B': // CUD Move cursor down the indicated # of rows.
+ j = to->parameters[0];
+ if (j == 0) j = 1;
+ to->y += j;
+ tesi_limitCursor(to, 1);
+ break;
+ case 'C': // CUF Move cursor right the indicated # of columns.
+ j = to->parameters[0];
+ if (j == 0) j = 1;
+ to->x += j;
+ tesi_limitCursor(to, 1);
+ break;
+ case 'D': // CUB Move cursor left the indicated # of columns.
+ j = to->parameters[0];
+ if (j == 0) j = 1;
+ to->x -= j;
+ tesi_limitCursor(to, 1);
+ break;
+ case 'E': // CNL Move cursor down the indicated # of rows, to column 1.
+ j = to->parameters[0];
+ if (j == 0) j = 1;
+ to->y += j;
+ to->x = 0;
+ tesi_limitCursor(to, 1);
+ break;
+ case 'F': // CPL Move cursor up the indicated # of rows, to column 1.
+ j = to->parameters[0];
+ if (j == 0) j = 1;
+ to->y -= j;
+ to->x = 0;
+ tesi_limitCursor(to, 1);
+ break;
+ case 'G': // CHA Move cursor to indicated column in current row.
+ j = to->parameters[0];
+ to->y = j - 1; // escape cursor address is 1..80, not 0..79
+ tesi_limitCursor(to, 1);
+ break;
+ case 'f': // HVP
+ case 'H': // CUP. move cursor to row, column
+ // parameters should be 1 more than the real value
+ if(to->parametersLength == 0)
+ to->x = to->y = 0;
+ else {
+ to->x = to->parameters[1] - 1;
+ to->y = to->parameters[0] - 1;
+ }
+ // limit cursor to boundaries
+ tesi_limitCursor(to, 1);
+ break;
+
+ // SCROLLING RELATED
+ case 'r': // change scrolling region
#ifdef DEBUG
- fprintf(stderr, "Change scrolling region from line %d to %d\n", i, j);
+ fprintf(stderr, "Change scrolling region from line %d to %d\n", i, j);
#endif
- if(to->parametersLength == 2) {
- i = to->parameters[0];
- j = to->parameters[1];
- to->scrollBegin = i;
- to->scrollEnd = j;
- if(to->callback_scrollRegion)
- to->callback_scrollRegion(to, i,j);
- } else {
- //0, 0
- }
- break;
- case 'c': // Identify your self. Ick!
- fprintf(stderr, "recevied ESC [ c\n");
- break;
+ if(to->parametersLength == 2) {
+ i = to->parameters[0];
+ j = to->parameters[1];
+ to->scrollBegin = i;
+ to->scrollEnd = j;
+ if(to->callback_scrollRegion)
+ to->callback_scrollRegion(to, i,j);
+ } else {
+ //0, 0
+ }
+ break;
+ case 'c': // Identify your self. Ick!
+ fprintf(stderr, "recevied ESC [ c\n");
+ break;
#if 0 // no such thing in xterm
- case 'D': // scroll down
- if(to->callback_scrollDown)
- to->callback_scrollDown(to);
- break;
- case 'U': // scroll up
- if(to->callback_scrollUp)
- to->callback_scrollUp(to);
- // cursor shouldn't change positions after a scroll
- // but this means the next output line (like a new prompt invoked after Enter on last line)
- // will be indented
- break;
+ case 'D': // scroll down
+ if(to->callback_scrollDown)
+ to->callback_scrollDown(to);
+ break;
+ case 'U': // scroll up
+ if(to->callback_scrollUp)
+ to->callback_scrollUp(to);
+ // cursor shouldn't change positions after a scroll
+ // but this means the next output line (like a new prompt invoked after Enter on last line)
+ // will be indented
+ break;
#endif
- }
- }
+ }
+ }
}
void tesi_processAttributes(struct tesiObject *to, int attr, int idx) {
- // cjc: modify for ECMA 48 SGR terminals. attributes in tesi
- // are tricky. Particularly 38 and 48
- // http://man7.org/linux/man-pages/man4/console_codes.4.html
- // idx is current point in to->parameters[], attr is the value there.
- if (attr == 0) {
- if (to->callback_attreset)
- to->callback_attreset(to);
- } else if (attr > 0 && attr <= 27) { // 1..27
- if (to->callback_charattr)
- to->callback_charattr(to, attr);
- } else if (attr >= 30 && attr <= 37) { // 30..37
- if (to->callback_setfgcolor)
- to->callback_setfgcolor(to, attr);
- } else if (attr == 38) {
- if (to->callback_setfg256) {
- to->parameters[++idx] = 255; // skip 5; 2;
- int c8 = to->parameters[++idx];
- to->parameters[idx] = 255; // nullify the color
- to->callback_setfg256(to, c8);
- }
- } else if (attr >= 40 && attr <= 47) {
- if (to->callback_setbgcolor)
- to->callback_setbgcolor(to, attr);
- } else if (attr == 48) { // Hack ahead
- if (to->callback_setbg256) {
- to->parameters[++idx] = 255; // skip 5; 2; could be worse so don't look
- int c8 = to->parameters[++idx];
- to->parameters[idx] = 255;
- to->callback_setbg256(to, c8);
+ // cjc: modify for ECMA 48 SGR terminals. attributes in tesi
+ // are tricky. Particularly 38 and 48
+ // http://man7.org/linux/man-pages/man4/console_codes.4.html
+ // idx is current point in to->parameters[], attr is the value there.
+ if (attr == 0) {
+ if (to->callback_attreset)
+ to->callback_attreset(to);
+ } else if (attr > 0 && attr <= 27) { // 1..27
+ if (to->callback_charattr)
+ to->callback_charattr(to, attr);
+ } else if (attr >= 30 && attr <= 37) { // 30..37
+ if (to->callback_setfgcolor)
+ to->callback_setfgcolor(to, attr);
+ } else if (attr == 38) {
+ if (to->callback_setfg256) {
+ to->parameters[++idx] = 255; // skip 5; 2;
+ int c8 = to->parameters[++idx];
+ to->parameters[idx] = 255; // nullify the color
+ to->callback_setfg256(to, c8);
+ }
+ } else if (attr >= 40 && attr <= 47) {
+ if (to->callback_setbgcolor)
+ to->callback_setbgcolor(to, attr);
+ } else if (attr == 48) { // Hack ahead
+ if (to->callback_setbg256) {
+ to->parameters[++idx] = 255; // skip 5; 2; could be worse so don't look
+ int c8 = to->parameters[++idx];
+ to->parameters[idx] = 255;
+ to->callback_setbg256(to, c8);
+ }
+ } else if ((attr == 39) || (attr = 49)) {
+ if (to->callback_setdefcolor)
+ to->callback_setdefcolor(to, attr);
+ } else {
+ // ignored. This behaviour is needed for those 255 above
}
- } else if ((attr == 39) || (attr = 49)) {
- if (to->callback_setdefcolor)
- to->callback_setdefcolor(to, attr);
- } else {
- // ignored. This behaviour is needed for those 255 above
- }
}
// Returns 1 if cursor was out of bounds
@@ -412,208 +412,208 @@ void tesi_processAttributes(struct tesiObject *to, int attr, int idx) {
// so the parameter is probably not necessary
// x, y are 0 based. height and width are 1 based
int tesi_limitCursor(struct tesiObject *tobj, int moveCursorRegardless) {
- int oldx = tobj->x;
- int oldy = tobj->y;
-
- // auto wrap - cjc: do not like
- if(tobj->x >= tobj->width) {
- tobj->x = 0;
- tobj->y = tobj->y + 1;
- }
- if(tobj->x < 0)
- tobj->x = 0;
-
- if(tobj->y >= tobj->height) {
- tobj->y = tobj->height - 1; //width,height are 1 based, x,y 0 based
- // tobj->height++; //wacky but Shoes likes it.
- if(tobj->callback_scrollUp) {
- tobj->callback_scrollUp(tobj);
- tobj->x = 0;
- }
- }
-
- if(tobj->y < 0)
- tobj->y = 0;
-
- if(moveCursorRegardless || oldx != tobj->x || oldy != tobj->y) {
- if(tobj->callback_moveCursor)
- tobj->callback_moveCursor(tobj, tobj->x, tobj->y);
- return 1;
- }
- return 0;
+ int oldx = tobj->x;
+ int oldy = tobj->y;
+
+ // auto wrap - cjc: do not like
+ if(tobj->x >= tobj->width) {
+ tobj->x = 0;
+ tobj->y = tobj->y + 1;
+ }
+ if(tobj->x < 0)
+ tobj->x = 0;
+
+ if(tobj->y >= tobj->height) {
+ tobj->y = tobj->height - 1; //width,height are 1 based, x,y 0 based
+ // tobj->height++; //wacky but Shoes likes it.
+ if(tobj->callback_scrollUp) {
+ tobj->callback_scrollUp(tobj);
+ tobj->x = 0;
+ }
+ }
+
+ if(tobj->y < 0)
+ tobj->y = 0;
+
+ if(moveCursorRegardless || oldx != tobj->x || oldy != tobj->y) {
+ if(tobj->callback_moveCursor)
+ tobj->callback_moveCursor(tobj, tobj->x, tobj->y);
+ return 1;
+ }
+ return 0;
}
-/*
- * Process those xterm sequences - each is quirky
+/*
+ * Process those xterm sequences - each is quirky
* They could be implemented differently (conditional compile) for
* Linux and osx or NOT IMPLEMENTED.
-*/
+*/
// various forms of Erase Display
static void tesi_seqED(struct tesiObject *to) {
- int i;
- if ((! to->callback_eraseLine) || (! to->callback_moveCursor)) return;
- switch(to->parameters[0]) {
- case 0: // from cursor to end of display
- to->callback_eraseLine(to, to->x, to->width, to->y);
- for (i = to->y+1; i < to->height; i++) {
- to->callback_eraseLine(to, 0, to->width, i);
- }
- // cursor doesn't change
- break;
- case 1: // from start (1,1) to cursor
- for (i = 0; i < to->y; i++) {
- to->callback_eraseLine(to, 0, to->width, i);
- }
- to->callback_eraseLine(to, 0, to->x, to->y);
- break;
- case 2: // whole display
- case 3: // whole display and scrollback buffer (linux only?)
- if (to->callback_clearScreen) {
- to->callback_clearScreen(to, to->parameters[0] == 3);
- } else {
- for(i = 0; i < to->height; i++) {
- if(to->callback_moveCursor)
- to->callback_moveCursor(to, 0, i);
- if(to->callback_eraseLine)
- to->callback_eraseLine(to, 0, to->width, i);
- }
- }
- to->x = to->y = 0;
- if(to->callback_moveCursor)
- to->callback_moveCursor(to, to->x, to->y);
- break;
- default:
- break;
- }
+ int i;
+ if ((! to->callback_eraseLine) || (! to->callback_moveCursor)) return;
+ switch(to->parameters[0]) {
+ case 0: // from cursor to end of display
+ to->callback_eraseLine(to, to->x, to->width, to->y);
+ for (i = to->y+1; i < to->height; i++) {
+ to->callback_eraseLine(to, 0, to->width, i);
+ }
+ // cursor doesn't change
+ break;
+ case 1: // from start (1,1) to cursor
+ for (i = 0; i < to->y; i++) {
+ to->callback_eraseLine(to, 0, to->width, i);
+ }
+ to->callback_eraseLine(to, 0, to->x, to->y);
+ break;
+ case 2: // whole display
+ case 3: // whole display and scrollback buffer (linux only?)
+ if (to->callback_clearScreen) {
+ to->callback_clearScreen(to, to->parameters[0] == 3);
+ } else {
+ for(i = 0; i < to->height; i++) {
+ if(to->callback_moveCursor)
+ to->callback_moveCursor(to, 0, i);
+ if(to->callback_eraseLine)
+ to->callback_eraseLine(to, 0, to->width, i);
+ }
+ }
+ to->x = to->y = 0;
+ if(to->callback_moveCursor)
+ to->callback_moveCursor(to, to->x, to->y);
+ break;
+ default:
+ break;
+ }
}
// various forms of Erase Line (EL)
// you would expect that ' ' would replace the backing buffer and
// reflected visually
static void tesi_seqEL(struct tesiObject *to) {
- switch(to->parameters[0]) {
- case 0: // erase line from cursor to end of line
- if(to->callback_eraseLine)
- to->callback_eraseLine(to, to->x, to->width, to->y);
- break;
- case 1: // erase line from start to cursor
- if(to->callback_eraseLine)
- to->callback_eraseLine(to, 0, to->x , to->y);
- break;
- case 2: // erase whole line
- if(to->callback_eraseLine)
- to->callback_eraseLine(to, 0, to->width, to->y);
- break;
- }
+ switch(to->parameters[0]) {
+ case 0: // erase line from cursor to end of line
+ if(to->callback_eraseLine)
+ to->callback_eraseLine(to, to->x, to->width, to->y);
+ break;
+ case 1: // erase line from start to cursor
+ if(to->callback_eraseLine)
+ to->callback_eraseLine(to, 0, to->x, to->y);
+ break;
+ case 2: // erase whole line
+ if(to->callback_eraseLine)
+ to->callback_eraseLine(to, 0, to->width, to->y);
+ break;
+ }
}
-// ---- initialize
+// ---- initialize
struct tesiObject* newTesiObject(char *command, int width, int height) {
- struct tesiObject *to;
- //struct winsize ws;
- char message[32]; // really just a temp
+ struct tesiObject *to;
+ //struct winsize ws;
+ char message[32]; // really just a temp
#if defined(USE_PTY) || defined(HALF_PTY)
- char *ptySlave;
+ char *ptySlave;
#endif
- to = malloc(sizeof(struct tesiObject));
- if(to == NULL)
- return NULL;
-
- to->partialSequence = 0;
- to->sequence = malloc(sizeof(char) * 40); // escape sequence buffer
- to->sequence[0] = 0;
- to->sequenceLength = 0;
- //to->outputBuffer[0] = 0;
- //to->outputBufferLength = 0;
- to->parametersLength = 0;
-
- to->x = to->y = to->x2 = to->y2 = 0; // cursor x,y and window width,height
- to->width = width;
- to->height = height;
- to->scrollBegin = 0;
- to->scrollEnd = height - 1;
- to->insertMode = 0;
- // simple callbacks
+ to = malloc(sizeof(struct tesiObject));
+ if(to == NULL)
+ return NULL;
+
+ to->partialSequence = 0;
+ to->sequence = malloc(sizeof(char) * 40); // escape sequence buffer
+ to->sequence[0] = 0;
+ to->sequenceLength = 0;
+ //to->outputBuffer[0] = 0;
+ //to->outputBufferLength = 0;
+ to->parametersLength = 0;
+
+ to->x = to->y = to->x2 = to->y2 = 0; // cursor x,y and window width,height
+ to->width = width;
+ to->height = height;
+ to->scrollBegin = 0;
+ to->scrollEnd = height - 1;
+ to->insertMode = 0;
+ // simple callbacks
to->callback_haveCharacter = NULL; // The shortcircuit to be replaced
to->callback_handleRTN = NULL;
to->callback_handleNL = NULL;
to->callback_handleBS = NULL;
to->callback_handleTAB = NULL;
- to->callback_handleBEL = NULL;
- to->callback_printCharacter = NULL;
+ to->callback_handleBEL = NULL;
+ to->callback_printCharacter = NULL;
to->callback_printString = NULL;
// more complex processing
to->callback_attributes = NULL;
to->callback_clearScreen = NULL;
- to->callback_insertCharacter = NULL;
- to->callback_eraseLine = NULL;
- to->callback_eraseCharacter = NULL;
- to->callback_moveCursor = NULL;
- to->callback_attributes = NULL;
- to->callback_scrollUp = NULL;
- to->callback_scrollDown = NULL;
- to->callback_invertColors = NULL;
-
- to->command[0] = to->command[1] = to->command[2] = NULL;
- to->pid = 0;
+ to->callback_insertCharacter = NULL;
+ to->callback_eraseLine = NULL;
+ to->callback_eraseCharacter = NULL;
+ to->callback_moveCursor = NULL;
+ to->callback_attributes = NULL;
+ to->callback_scrollUp = NULL;
+ to->callback_scrollDown = NULL;
+ to->callback_invertColors = NULL;
+
+ to->command[0] = to->command[1] = to->command[2] = NULL;
+ to->pid = 0;
#if defined(USE_PTY) || defined(HALF_PTY)
- to->ptyMaster = posix_openpt(O_RDWR|O_NOCTTY);
-
- to->fd_activity = to->ptyMaster; // descriptor to check whether the process has sent output
- to->fd_input = to->ptyMaster; // descriptor for sending input to child process
-
- grantpt(to->ptyMaster);
- unlockpt(to->ptyMaster);
- /* for shoes we don't fork. pty slave will be used for this process
- * stdin/out/err which replaces what was there in this process.
- * This may be a bad idea or not work or leave zombie processses
- */
- ptySlave = ptsname(to->ptyMaster);
- to->ptySlave = open(ptySlave, O_RDWR);
- // need to setup the terminal stuff for the slave side of the pty.
- struct termios slave_orig_term_settings; // Saved terminal settings
- struct termios new_term_settings; // Current terminal settings
- tcgetattr(to->ptySlave, &slave_orig_term_settings);
- new_term_settings = slave_orig_term_settings;
+ to->ptyMaster = posix_openpt(O_RDWR|O_NOCTTY);
+
+ to->fd_activity = to->ptyMaster; // descriptor to check whether the process has sent output
+ to->fd_input = to->ptyMaster; // descriptor for sending input to child process
+
+ grantpt(to->ptyMaster);
+ unlockpt(to->ptyMaster);
+ /* for shoes we don't fork. pty slave will be used for this process
+ * stdin/out/err which replaces what was there in this process.
+ * This may be a bad idea or not work or leave zombie processses
+ */
+ ptySlave = ptsname(to->ptyMaster);
+ to->ptySlave = open(ptySlave, O_RDWR);
+ // need to setup the terminal stuff for the slave side of the pty.
+ struct termios slave_orig_term_settings; // Saved terminal settings
+ struct termios new_term_settings; // Current terminal settings
+ tcgetattr(to->ptySlave, &slave_orig_term_settings);
+ new_term_settings = slave_orig_term_settings;
#if defined(SHOES_QUARTZ) || defined(SHOES_GTK_OSX)
- cfmakeraw (&new_term_settings);
+ cfmakeraw (&new_term_settings);
#endif
- tcsetattr (to->ptySlave, TCSANOW, &new_term_settings);
- dup2(to->ptySlave, fileno(stdin));
+ tcsetattr (to->ptySlave, TCSANOW, &new_term_settings);
+ dup2(to->ptySlave, fileno(stdin));
#ifndef HALF_PTY
- dup2(to->ptySlave, fileno(stdout));
- dup2(to->ptySlave, fileno(stderr));
+ dup2(to->ptySlave, fileno(stdout));
+ dup2(to->ptySlave, fileno(stderr));
#endif
#endif // USE_PTY
#ifdef SHOES_QUARTZ
- setenv("TERM","xterm-256color",1);
- //setenv("TERM","xterm",1);
+ setenv("TERM","xterm-256color",1);
+ //setenv("TERM","xterm",1);
#else
- setenv("TERM","xterm",1);
+ setenv("TERM","xterm",1);
#endif
- sprintf(message, "%d", width);
- setenv("COLUMNS", message, 1);
- sprintf(message, "%d", height);
- setenv("LINES", message, 1);
- return to;
+ sprintf(message, "%d", width);
+ setenv("COLUMNS", message, 1);
+ sprintf(message, "%d", height);
+ setenv("LINES", message, 1);
+ return to;
}
/*
* Why does this take a void pointer?
* So that you don't have to cast before you pass the parameter
* */
void deleteTesiObject(void *p) {
- struct tesiObject *to = (struct tesiObject*) p;
- close(to->ptyMaster);
- free(to->sequence);
- free(to->command[0]);
- if(to->command[1])
- free(to->command[1]);
- free(to);
+ struct tesiObject *to = (struct tesiObject*) p;
+ close(to->ptyMaster);
+ free(to->sequence);
+ free(to->command[0]);
+ if(to->command[1])
+ free(to->command[1]);
+ free(to);
// FIXME Is all ?
}
-/*
+/*
* stuff that may never be called or work
-*/
+*/
diff --git a/shoes/console/tesi.h b/shoes/console/tesi.h
index e150564d..0c9745d7 100644
--- a/shoes/console/tesi.h
+++ b/shoes/console/tesi.h
@@ -11,17 +11,23 @@
#if !defined(SHOES_QUARTZ)
#define USE_PTY
#else
-#define HALF_PTY
+#define HALF_PTY
#endif
#if defined(SHOES_QUARTZ) || defined(SHOES_GTK_OSX)
#include
#else
+#if !defined(BSD)
#include
+#endif
extern int posix_openpt(int); // shut warnings off
extern int setenv(const char*, const char*, int); // shut warnings off
#endif
+#if !defined(BSD)
#include
+#else
+#include
+#endif
#include
#include
#include
@@ -40,35 +46,35 @@ extern int setenv(const char*, const char*, int); // shut warnings off
struct tesiObject; // forward declare for C compilier
struct tesiObject {
- // file descriptor for "select"ing whether there are terminal sequences to be processed
- int fd_activity;
- int fd_input;
- int partialSequence; // whether we've begun buffering an escape sequence
- char *sequence; // escape sequence buffer
- int sequenceLength;
- //char outputBuffer[129];
- //int outputBufferLength;
- void *pointer; // *gtk_text_view or *NSTextView
-
- int parameters[32];
- int parametersLength;
- char attributes[8]; // display attributes: bold, foreground, etc
- int insertMode;
-
- pid_t pid;
- int ptyMaster;
- int ptySlave;
- char *command[3];
-
- void (*callback_haveCharacter)(struct tesiObject *, char); // No longer used???
- void (*callback_printCharacter)(struct tesiObject *, char, int, int); // print character at x, y
- void (*callback_handleRTN)(struct tesiObject *, int, int);
+ // file descriptor for "select"ing whether there are terminal sequences to be processed
+ int fd_activity;
+ int fd_input;
+ int partialSequence; // whether we've begun buffering an escape sequence
+ char *sequence; // escape sequence buffer
+ int sequenceLength;
+ //char outputBuffer[129];
+ //int outputBufferLength;
+ void *pointer; // *gtk_text_view or *NSTextView
+
+ int parameters[32];
+ int parametersLength;
+ char attributes[8]; // display attributes: bold, foreground, etc
+ int insertMode;
+
+ pid_t pid;
+ int ptyMaster;
+ int ptySlave;
+ char *command[3];
+
+ void (*callback_haveCharacter)(struct tesiObject *, char); // No longer used???
+ void (*callback_printCharacter)(struct tesiObject *, char, int, int); // print character at x, y
+ void (*callback_handleRTN)(struct tesiObject *, int, int);
void (*callback_handleNL)(struct tesiObject *, int, int);
void (*callback_handleBS)(struct tesiObject *, int, int);
void (*callback_handleBEL)(struct tesiObject *, int, int);
void (*callback_handleTAB)(struct tesiObject *, int, int);
- void (*callback_printString)(void*, char*, int, int, int); // print string of length at x, y
-
+ void (*callback_printString)(void*, char*, int, int, int); // print string of length at x, y
+
void (*callback_attreset)(struct tesiObject *); // reset all attributes
void (*callback_charattr)(struct tesiObject *, int); // char based attributes 1..27
void (*callback_setbgcolor)(struct tesiObject *, int); // attr 40..47
@@ -76,29 +82,29 @@ struct tesiObject {
void (*callback_setfg256)(struct tesiObject *, int); // 38;5;x
void (*callback_setbg256)(struct tesiObject *, int); // 48;5;x
void (*callback_setdefcolor)(struct tesiObject *, int); // 39,49 set default color
- // cursor based callbacks - caution - maybe not be implemented
+ // cursor based callbacks - caution - maybe not be implemented
// and probably don't do what you think should be done.
- void (*callback_eraseLine)(struct tesiObject *, int, int, int); // erase line at from_x, to_x, line y
- void (*callback_moveCursor)(struct tesiObject *, int, int); // move to x, y
+ void (*callback_eraseLine)(struct tesiObject *, int, int, int); // erase line at from_x, to_x, line y
+ void (*callback_moveCursor)(struct tesiObject *, int, int); // move to x, y
void (*callback_deleteLines) (struct tesiObject *, int); // delete is not erase
- void (*callback_insertLines)(struct tesiObject *, int); // insert lines at lines
-
- void (*callback_clearScreen)(struct tesiObject *, int scrollback); //
-
- void (*callback_insertCharacter)(struct tesiObject *, char, int, int); // insert character at x, y
-
- void (*callback_eraseCharacter)(struct tesiObject *, int, int); // erase character at x, y
- void (*callback_attributes)(struct tesiObject *, short, short, short, short, short, short, short); // bold, blink, inverse, underline, foreground, background, charset
- void (*callback_scrollRegion)(struct tesiObject *,int,int);
- void (*callback_scrollUp)(struct tesiObject *);
- void (*callback_scrollDown)(struct tesiObject *);
- void (*callback_invertColors)(struct tesiObject *);
+ void (*callback_insertLines)(struct tesiObject *, int); // insert lines at lines
+
+ void (*callback_clearScreen)(struct tesiObject *, int scrollback); //
+
+ void (*callback_insertCharacter)(struct tesiObject *, char, int, int); // insert character at x, y
+
+ void (*callback_eraseCharacter)(struct tesiObject *, int, int); // erase character at x, y
+ void (*callback_attributes)(struct tesiObject *, short, short, short, short, short, short, short); // bold, blink, inverse, underline, foreground, background, charset
+ void (*callback_scrollRegion)(struct tesiObject *,int,int);
+ void (*callback_scrollUp)(struct tesiObject *);
+ void (*callback_scrollDown)(struct tesiObject *);
+ void (*callback_invertColors)(struct tesiObject *);
#ifdef USE_PTY // Linux only
- void (*callback_rawCapture) (struct tesiObject *, char *, int);
+ void (*callback_rawCapture) (struct tesiObject *, char *, int);
#endif
unsigned int ides; // event source id from g_timeout_add
- int x, y, x2, y2, width, height, scrollBegin, scrollEnd; // cursor x,y and window width,height
- //int alternativeChar;
+ int x, y, x2, y2, width, height, scrollBegin, scrollEnd; // cursor x,y and window width,height
+ //int alternativeChar;
};
// PRIVATE: as if C has that ability! Illusions will continue
diff --git a/shoes/effects.c b/shoes/effects.c
deleted file mode 100644
index 18167a66..00000000
--- a/shoes/effects.c
+++ /dev/null
@@ -1,268 +0,0 @@
-//
-// shoes/effects.c
-// The blurring and shadowing effects.
-//
-#include "shoes/internal.h"
-#include "shoes/app.h"
-#include "shoes/canvas.h"
-#include "shoes/effects.h"
-#include "shoes/ruby.h"
-#include
-
-static unsigned char *
-box_run(unsigned int size)
-{
- int i;
- unsigned char *tmp = SHOE_ALLOC_N(unsigned char, size * 256);
- for (i = 0; i < 256; i++)
- memset(tmp + i * size, i, size);
- return tmp;
-}
-
-#define BOX_H 1
-#define BOX_V 2
-
-static void
-box_blur(unsigned char *in, unsigned char *out,
- int stride, shoes_place *place,
- unsigned int edge1, unsigned int edge2,
- const unsigned char *run, int dir)
-{
- int i, j1, j2, l = 0, l2, l3, l4, lx = 0, c1, c2, c3, c4, start;
- int boxSize = edge1 + edge2 + 1;
- if (dir == BOX_H)
- {
- c1 = place->y;
- c2 = place->y + place->h;
- c3 = place->x;
- c4 = place->x + place->w;
- }
- else
- {
- c1 = place->x;
- c2 = place->x + place->w;
- c3 = place->y;
- c4 = place->y + place->h;
- }
-
- start = c3 - edge1;
- for (j1 = c1; j1 < c2; j1++) {
- unsigned int sums[4] = {0, 0, 0, 0};
- if (dir == BOX_H)
- l = stride * j1;
- else
- lx = j1 << 2;
- for (i = 0; i < boxSize; i++) {
- int pos = start + i;
- pos = max(pos, c3);
- pos = min(pos, c4 - 1);
- if (dir == BOX_V)
- l = stride * pos + lx;
- sums[0] += in[l];
- sums[1] += in[l + 1];
- sums[2] += in[l + 2];
- sums[3] += in[l + 3];
- }
- for (j2 = c3; j2 < c4; j2++) {
- if (dir == BOX_H)
- l2 = l + (j2 << 2);
- else
- l2 = stride * j2 + lx;
- out[l2] = run[(int)sums[0]];
- out[l2 + 1] = run[(int)sums[1]];
- out[l2 + 2] = run[(int)sums[2]];
- out[l2 + 3] = run[(int)sums[3]];
-
- int tmp = j2 - edge1;
- int last = max(tmp, c3);
- int next = min(tmp + boxSize, c4 - 1);
- if (dir == BOX_H)
- {
- l3 = l + (next << 2);
- l4 = l + (last << 2);
- }
- else
- {
- l3 = stride * next + lx;
- l4 = stride * last + lx;
- }
-
- sums[0] += in[l3] - in[l4];
- sums[1] += in[l3 + 1] - in[l4 + 1];
- sums[2] += in[l3 + 2] - in[l4 + 2];
- sums[3] += in[l3 + 3] - in[l4 + 3];
- }
- }
-}
-#ifdef GTK3
-#define RAW_FILTER_START(place) \
- int width, height, stride; \
- guchar *out; \
- static const cairo_user_data_key_t key; \
- cairo_surface_t *source = cairo_get_target(cr); \
- cairo_surface_t *target; \
- unsigned char *in = cairo_image_surface_get_data(source); \
- \
- place->x = place->y = 0; \
- place->w = width = cairo_image_surface_get_width(source); \
- place->h = height = cairo_image_surface_get_height(source); \
- stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width); \
- \
- out = (guchar *)g_malloc(4 * width * height); \
- target = cairo_image_surface_create_for_data((unsigned char *)out, \
- CAIRO_FORMAT_ARGB32, \
- width, height, stride); \
- cairo_surface_set_user_data(target, &key, out, (cairo_destroy_func_t)g_free); \
- unsigned int len = 4 * width * height
-#else
-#define RAW_FILTER_START(place) \
- int width, height, stride; \
- guchar *out; \
- static const cairo_user_data_key_t key; \
- cairo_surface_t *source = cairo_get_target(cr); \
- cairo_surface_t *target; \
- unsigned char *in = cairo_image_surface_get_data(source); \
- \
- place->x = place->y = 0; \
- place->w = width = cairo_image_surface_get_width(source); \
- place->h = height = cairo_image_surface_get_height(source); \
- stride = cairo_image_surface_get_stride(source); \
- \
- out = (guchar *)g_malloc(4 * width * height); \
- target = cairo_image_surface_create_for_data((unsigned char *)out, \
- CAIRO_FORMAT_ARGB32, \
- width, height, 4 * width); \
- cairo_surface_set_user_data(target, &key, out, (cairo_destroy_func_t)g_free); \
- unsigned int len = 4 * width * height
-#endif
-
-#define RAW_FILTER_END() \
- cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR); \
- cairo_paint(cr); \
- cairo_set_operator(cr, CAIRO_OPERATOR_OVER); \
- cairo_set_source_surface(cr, target, 0, 0); \
- cairo_paint(cr); \
- cairo_surface_destroy(target);
-
-void
-shoes_gaussian_blur_filter(cairo_t *cr, VALUE attr, shoes_place *place)
-{
- double blur_d = ATTR2(dbl, attr, radius, 2.);
- double blur_x = blur_d, blur_y = blur_d;
-
- RAW_FILTER_START(place);
- if (blur_x < 0 || blur_y < 0)
- return;
- if (blur_x == 0 || blur_y == 0)
- memset(out, 0, len);
- unsigned int dX, dY;
- dX = (unsigned int) floor(blur_x * 3*sqrt(2*SHOES_PI)/4 + 0.5);
- dY = (unsigned int) floor((blur_y * 3*sqrt(2*SHOES_PI)/4) + 0.5);
-
- unsigned char *tmp = SHOE_ALLOC_N(unsigned char, len);
-
- if (dX & 1) { // odd dX
- unsigned char *run = box_run(2 * (dX / 2) + 1);
- box_blur(in, tmp, stride, place, dX/2, dX/2, run, BOX_H);
- box_blur(tmp, out, stride, place, dX/2, dX/2, run, BOX_H);
- box_blur(out, tmp, stride, place, dX/2, dX/2, run, BOX_H);
- SHOE_FREE(run);
- } else { // even dX
- if (dX == 0) {
- memcpy(tmp, in, len);
- } else {
- unsigned char *run1 = box_run(2 * (dX / 2) + 1);
- unsigned char *run2 = box_run(2 * (dX / 2));
- box_blur(in, tmp, stride, place, dX/2, dX/2 - 1, run2, BOX_H);
- box_blur(tmp, out, stride, place, dX/2 - 1, dX/2, run2, BOX_H);
- box_blur(out, tmp, stride, place, dX/2, dX/2, run1, BOX_H);
- SHOE_FREE(run1);
- SHOE_FREE(run2);
- }
- }
- if (dY & 1) {
- unsigned char *run = box_run(2 * (dY / 2) + 1);
- box_blur(tmp, out, stride, place, dY/2, dY/2, run, BOX_V);
- box_blur(out, tmp, stride, place, dY/2, dY/2, run, BOX_V);
- box_blur(tmp, out, stride, place, dY/2, dY/2, run, BOX_V);
- SHOE_FREE(run);
- } else {
- if (dY == 0) {
- memcpy(out, tmp, len);
- } else {
- unsigned char *run1 = box_run(2 * (dY / 2) + 1);
- unsigned char *run2 = box_run(2 * (dY / 2));
- box_blur(tmp, out, stride, place, dY/2, dY/2 - 1, run2, BOX_V);
- box_blur(out, tmp, stride, place, dY/2 - 1, dY/2, run2, BOX_V);
- box_blur(tmp, out, stride, place, dY/2, dY/2, run1, BOX_V);
- SHOE_FREE(run1);
- SHOE_FREE(run2);
- }
- }
-
- SHOE_FREE(tmp);
- RAW_FILTER_END();
-}
-
-static void
-shoes_layer_blur_filter(cairo_t *cr, VALUE attr, shoes_place *place,
- cairo_operator_t blur_op, cairo_operator_t merge_op, int distance)
-{
- cairo_surface_t *source = cairo_get_target(cr);
- int width = cairo_image_surface_get_width(source);
- int height = cairo_image_surface_get_height(source);
- VALUE fill = ATTR(attr, fill);
- int dx = ATTR2(int, attr, displace_left, 0);
- int dy = ATTR2(int, attr, displace_top, 0);
-
- cairo_surface_t *target = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
- cairo_t *cr2 = cairo_create(target);
- if (dx != 0 || dy != 0)
- cairo_set_source_surface(cr2, source, dx, dy);
- else
- cairo_set_source_surface(cr2, source, distance, distance);
- cairo_paint(cr2);
- cairo_set_operator(cr2, blur_op);
- if (NIL_P(fill))
- cairo_set_source_rgb(cr2, 0., 0., 0.);
- else if (rb_obj_is_kind_of(fill, cColor))
- {
- shoes_color *color;
- Data_Get_Struct(fill, shoes_color, color);
- cairo_set_source_rgba(cr2, color->r / 255., color->g / 255., color->b / 255., color->a / 255.);
- }
- else
- {
- shoes_pattern *pattern;
- Data_Get_Struct(fill, shoes_pattern, pattern);
- cairo_set_source(cr2, PATTERN(pattern));
- }
- cairo_rectangle(cr2, 0, 0, width, height);
- cairo_paint(cr2);
- shoes_gaussian_blur_filter(cr2, attr, place);
- cairo_set_operator(cr, merge_op);
- cairo_set_source_surface(cr, target, 0, 0);
- cairo_paint(cr);
- cairo_destroy(cr2);
-}
-
-void
-shoes_shadow_filter(cairo_t *cr, VALUE attr, shoes_place *place)
-{
- int distance = ATTR2(int, attr, distance, 4);
- shoes_layer_blur_filter(cr, attr, place, CAIRO_OPERATOR_IN, CAIRO_OPERATOR_DEST_OVER, distance);
-}
-
-void
-shoes_glow_filter(cairo_t *cr, VALUE attr, shoes_place *place)
-{
- cairo_operator_t blur_op = CAIRO_OPERATOR_IN;
- cairo_operator_t merge_op = CAIRO_OPERATOR_DEST_OVER;
- if (RTEST(ATTR(attr, inner)))
- {
- blur_op = CAIRO_OPERATOR_OUT;
- merge_op = CAIRO_OPERATOR_ATOP;
- }
- shoes_layer_blur_filter(cr, attr, place, blur_op, merge_op, 0);
-}
-
diff --git a/shoes/effects.h b/shoes/effects.h
deleted file mode 100644
index 00f22d8c..00000000
--- a/shoes/effects.h
+++ /dev/null
@@ -1,7 +0,0 @@
-//
-// shoes/effects.h
-// The presently meager effects API.
-//
-void shoes_gaussian_blur_filter(cairo_t *, VALUE, shoes_place *);
-void shoes_shadow_filter(cairo_t *, VALUE, shoes_place *);
-void shoes_glow_filter(cairo_t *, VALUE, shoes_place *);
diff --git a/shoes/http.h b/shoes/http.h
index c2590da1..8e718ef2 100644
--- a/shoes/http.h
+++ b/shoes/http.h
@@ -9,23 +9,23 @@
#include "shoes/http/common.h"
typedef struct {
- char *url;
- char *scheme;
- char *host;
- int port;
- char *path;
+ char *url;
+ char *scheme;
+ char *host;
+ int port;
+ char *path;
- char *method, *body;
- unsigned long bodylen;
- SHOES_DOWNLOAD_HEADERS headers;
+ char *method, *body;
+ unsigned long bodylen;
+ SHOES_DOWNLOAD_HEADERS headers;
- char *mem;
- unsigned long memlen;
- char *filepath;
- unsigned LONG_LONG size;
- shoes_http_handler handler;
- void *data;
- unsigned char flags;
+ char *mem;
+ unsigned long memlen;
+ char *filepath;
+ unsigned LONG_LONG size;
+ shoes_http_handler handler;
+ void *data;
+ unsigned char flags;
} shoes_http_request;
void shoes_download(shoes_http_request *req);
diff --git a/shoes/http/nsurl.m b/shoes/http/nsurl.m
index c70adca6..c2f67866 100644
--- a/shoes/http/nsurl.m
+++ b/shoes/http/nsurl.m
@@ -9,7 +9,7 @@
#include "shoes/http.h"
#include "shoes/version.h"
#include "shoes/world.h"
-#include "shoes/native.h"
+#include "shoes/native/native.h"
#import
diff --git a/shoes/http/rbload.c b/shoes/http/rbload.c
index 42ebb7e8..73428b80 100644
--- a/shoes/http/rbload.c
+++ b/shoes/http/rbload.c
@@ -1,8 +1,8 @@
//
// shoes/http/rbload
-// the downloader routines using ruby's open_uri
+// the downloader routines using ruby's open_uri
// Might still have some nsurl.m stuff for comments
-// Cecil Coupe screwed this together.
+// Cecil Coupe screwed this together.
//
#include "shoes/app.h"
#include "shoes/ruby.h"
@@ -11,87 +11,77 @@
#include "shoes/http.h"
#include "shoes/version.h"
#include "shoes/world.h"
-#include "shoes/native.h"
+#include "shoes/native/native.h"
+#include "shoes/types/download.h"
#include "shoes/canvas.h"
-void
-shoes_download(shoes_http_request *req)
-{
- /* monkey patched out in download.rb - need function for linking */
- printf("monkey patch failed\n");
+void shoes_download(shoes_http_request *req) {
+ /* monkey patched out in download.rb - need function for linking */
+ printf("monkey patch failed\n");
}
-void
-shoes_queue_download(shoes_http_request *req)
-{
- //printf("shoes_queue_download called: %s -> %s\n",req->url,req->filepath);
- VALUE path, url, opts, svsym, dnobj, stvar;
- // convert req->url, req->filepath to ruby strings
- path = rb_str_new2(req->filepath);
- url = rb_str_new2(req->url);
- // make a hash
- opts = rb_hash_new();
- // make a :save symbol
- svsym = ID2SYM(rb_intern("save"));
- // add :save and filepath to hash
- rb_hash_aset(opts, svsym, path);
- // Call Shoes::image_download_sync - defined in image.rb
- dnobj = rb_funcall(cShoes,
- rb_intern("image_download_sync"), 2, url, opts);
- // convert the status var of dnobj to a C int and save it in req->idat
- stvar = rb_funcall(dnobj, rb_intern("status"), 0);
- int st = NUM2INT(stvar);
- // dig the etag field out of headers.
- VALUE hdrs = rb_funcall(dnobj, rb_intern("headers"), 0);
- //printf("returned from image_download_sync %i\n", st);
- // shoes_image_download_event *idat
- // shoes_image_download_event in req->data
- shoes_image_download_event *side = req->data;
- side->status = st;
- VALUE etag = Qnil;
- VALUE keys = rb_funcall(hdrs, s_keys, 0);
- int i;
- for (i = 0; i < RARRAY_LEN(keys); i++ )
- {
- VALUE key = rb_ary_entry(keys, i);
- if (strcmp("etag", RSTRING_PTR(key)) == 0) {
- etag = key;
- break;
+void shoes_queue_download(shoes_http_request *req) {
+ //printf("shoes_queue_download called: %s -> %s\n",req->url,req->filepath);
+ VALUE path, url, opts, svsym, dnobj, stvar;
+ // convert req->url, req->filepath to ruby strings
+ path = rb_str_new2(req->filepath);
+ url = rb_str_new2(req->url);
+ // make a hash
+ opts = rb_hash_new();
+ // make a :save symbol
+ svsym = ID2SYM(rb_intern("save"));
+ // add :save and filepath to hash
+ rb_hash_aset(opts, svsym, path);
+ // Call Shoes::image_download_sync - defined in image.rb
+ dnobj = rb_funcall(cShoes,
+ rb_intern("image_download_sync"), 2, url, opts);
+ // convert the status var of dnobj to a C int and save it in req->idat
+ stvar = rb_funcall(dnobj, rb_intern("status"), 0);
+ int st = NUM2INT(stvar);
+ // dig the etag field out of headers.
+ VALUE hdrs = rb_funcall(dnobj, rb_intern("headers"), 0);
+ //printf("returned from image_download_sync %i\n", st);
+ // shoes_image_download_event *idat
+ // shoes_image_download_event in req->data
+ shoes_image_download_event *side = req->data;
+ side->status = st;
+ VALUE etag = Qnil;
+ VALUE keys = rb_funcall(hdrs, s_keys, 0);
+ int i;
+ for (i = 0; i < RARRAY_LEN(keys); i++ ) {
+ VALUE key = rb_ary_entry(keys, i);
+ if (strcmp("etag", RSTRING_PTR(key)) == 0) {
+ etag = key;
+ break;
+ }
+ //printf("key=%s\n",RSTRING_PTR(key));
}
- //printf("key=%s\n",RSTRING_PTR(key));
- }
- side->etag = RSTRING_PTR(rb_hash_aref(hdrs, etag));
- //VALUE rbetag = rb_hash_aref(hdrs, rb_intern("etag"));
- //printf("%s\n",RSTRING_PTR(rbetag));
- shoes_catch_message(SHOES_IMAGE_DOWNLOAD, Qnil, side);
- shoes_http_request_free(req);
- free(req);
- // assume Ruby will garbage collect all the VALUE var's.
- // after this stack frame pops there's nothing holding them.
+ side->etag = RSTRING_PTR(rb_hash_aref(hdrs, etag));
+ //VALUE rbetag = rb_hash_aref(hdrs, rb_intern("etag"));
+ //printf("%s\n",RSTRING_PTR(rbetag));
+ shoes_catch_message(SHOES_IMAGE_DOWNLOAD, Qnil, side);
+ shoes_http_request_free(req);
+ free(req);
+ // assume Ruby will garbage collect all the VALUE var's.
+ // after this stack frame pops there's nothing holding them.
}
-VALUE
-shoes_http_err(SHOES_DOWNLOAD_ERROR code)
-{
- /* a little unclear what this does or what it returns
- I think it converts the platform 'code' to a Shoes string
- */
- char errorString[10];
- sprintf(errorString, "%i", code);
- //printf("shoes_http_err called%s\n",errorString);
- return rb_str_new2(errorString);
+VALUE shoes_http_err(SHOES_DOWNLOAD_ERROR code) {
+ /* a little unclear what this does or what it returns
+ I think it converts the platform 'code' to a Shoes string
+ */
+ char errorString[10];
+ sprintf(errorString, "%i", code);
+ //printf("shoes_http_err called%s\n",errorString);
+ return rb_str_new2(errorString);
}
-SHOES_DOWNLOAD_HEADERS
-shoes_http_headers(VALUE hsh)
-{
-
- //printf("shoes_http_headers called\n");
- return (SHOES_DOWNLOAD_HEADERS)hsh;
+SHOES_DOWNLOAD_HEADERS shoes_http_headers(VALUE hsh) {
+
+ //printf("shoes_http_headers called\n");
+ return (SHOES_DOWNLOAD_HEADERS)hsh;
}
-void
-shoes_http_headers_free(SHOES_DOWNLOAD_HEADERS headers)
-{
- // printf("shoes_headers_free called\n");
+void shoes_http_headers_free(SHOES_DOWNLOAD_HEADERS headers) {
+// printf("shoes_headers_free called\n");
}
diff --git a/shoes/http/windownload.c b/shoes/http/windownload.c
index df5154d4..ae0256e4 100644
--- a/shoes/http/windownload.c
+++ b/shoes/http/windownload.c
@@ -9,7 +9,7 @@
#include "shoes/http.h"
#include "shoes/version.h"
#include "shoes/world.h"
-#include "shoes/native.h"
+#include "shoes/native/native.h"
#include
#include
#include
diff --git a/shoes/image.c b/shoes/image.c
index cccab601..24eecf0a 100644
--- a/shoes/image.c
+++ b/shoes/image.c
@@ -1,7 +1,7 @@
//
// shoes/image.c
-// Loading image formats in Cairo. I've already tried gdk-pixbuf and imlib2, but
-// the idea here is to cut down dependencies, since I only really need reading of
+// Loading image formats in Cairo. I've already tried gdk-pixbuf and imlib2, but
+// the idea here is to cut down dependencies, since I only really need reading of
// the basics: GIF and JPEG.
//
#include
@@ -12,7 +12,7 @@
#include "shoes/ruby.h"
#include "shoes/internal.h"
#include "shoes/world.h"
-#include "shoes/native.h"
+#include "shoes/native/native.h"
#include "shoes/version.h"
#include "shoes/http.h"
@@ -40,9 +40,9 @@ shoes_image_format shoes_image_detect(VALUE, int *, int *);
#define SIZE_SURFACE ((cairo_surface_t *)1)
typedef struct {
- unsigned int state[5];
- unsigned int count[2];
- unsigned char buffer[64];
+ unsigned int state[5];
+ unsigned int count[2];
+ unsigned char buffer[64];
} SHA1_CTX;
void SHA1Transform(unsigned int state[5], unsigned char buffer[64]);
@@ -71,379 +71,409 @@ void SHA1Final(unsigned char digest[20], SHA1_CTX* context);
#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
/* Hash a single 512-bit block. This is the core of the algorithm. */
-void SHA1Transform(unsigned int state[5], unsigned char buffer[64])
-{
-unsigned int a, b, c, d, e;
-typedef union {
- unsigned char c[64];
- unsigned int l[16];
-} CHAR64LONG16;
-CHAR64LONG16* block;
+void SHA1Transform(unsigned int state[5], unsigned char buffer[64]) {
+ unsigned int a, b, c, d, e;
+ typedef union {
+ unsigned char c[64];
+ unsigned int l[16];
+ } CHAR64LONG16;
+ CHAR64LONG16* block;
#ifdef SHA1HANDSOFF
-static unsigned char workspace[64];
- block = (CHAR64LONG16*)workspace;
- memcpy(block, buffer, 64);
+ static unsigned char workspace[64];
+ block = (CHAR64LONG16*)workspace;
+ memcpy(block, buffer, 64);
#else
- block = (CHAR64LONG16*)buffer;
+ block = (CHAR64LONG16*)buffer;
#endif
- /* Copy context->state[] to working vars */
- a = state[0];
- b = state[1];
- c = state[2];
- d = state[3];
- e = state[4];
- /* 4 rounds of 20 operations each. Loop unrolled. */
- R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
- R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
- R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
- R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
- R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
- R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
- R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
- R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
- R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
- R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
- R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
- R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
- R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
- R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
- R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
- R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
- R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
- R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
- R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
- R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
- /* Add the working vars back into context.state[] */
- state[0] += a;
- state[1] += b;
- state[2] += c;
- state[3] += d;
- state[4] += e;
- /* Wipe variables */
- a = b = c = d = e = 0;
+ /* Copy context->state[] to working vars */
+ a = state[0];
+ b = state[1];
+ c = state[2];
+ d = state[3];
+ e = state[4];
+ /* 4 rounds of 20 operations each. Loop unrolled. */
+ R0(a,b,c,d,e, 0);
+ R0(e,a,b,c,d, 1);
+ R0(d,e,a,b,c, 2);
+ R0(c,d,e,a,b, 3);
+ R0(b,c,d,e,a, 4);
+ R0(a,b,c,d,e, 5);
+ R0(e,a,b,c,d, 6);
+ R0(d,e,a,b,c, 7);
+ R0(c,d,e,a,b, 8);
+ R0(b,c,d,e,a, 9);
+ R0(a,b,c,d,e,10);
+ R0(e,a,b,c,d,11);
+ R0(d,e,a,b,c,12);
+ R0(c,d,e,a,b,13);
+ R0(b,c,d,e,a,14);
+ R0(a,b,c,d,e,15);
+ R1(e,a,b,c,d,16);
+ R1(d,e,a,b,c,17);
+ R1(c,d,e,a,b,18);
+ R1(b,c,d,e,a,19);
+ R2(a,b,c,d,e,20);
+ R2(e,a,b,c,d,21);
+ R2(d,e,a,b,c,22);
+ R2(c,d,e,a,b,23);
+ R2(b,c,d,e,a,24);
+ R2(a,b,c,d,e,25);
+ R2(e,a,b,c,d,26);
+ R2(d,e,a,b,c,27);
+ R2(c,d,e,a,b,28);
+ R2(b,c,d,e,a,29);
+ R2(a,b,c,d,e,30);
+ R2(e,a,b,c,d,31);
+ R2(d,e,a,b,c,32);
+ R2(c,d,e,a,b,33);
+ R2(b,c,d,e,a,34);
+ R2(a,b,c,d,e,35);
+ R2(e,a,b,c,d,36);
+ R2(d,e,a,b,c,37);
+ R2(c,d,e,a,b,38);
+ R2(b,c,d,e,a,39);
+ R3(a,b,c,d,e,40);
+ R3(e,a,b,c,d,41);
+ R3(d,e,a,b,c,42);
+ R3(c,d,e,a,b,43);
+ R3(b,c,d,e,a,44);
+ R3(a,b,c,d,e,45);
+ R3(e,a,b,c,d,46);
+ R3(d,e,a,b,c,47);
+ R3(c,d,e,a,b,48);
+ R3(b,c,d,e,a,49);
+ R3(a,b,c,d,e,50);
+ R3(e,a,b,c,d,51);
+ R3(d,e,a,b,c,52);
+ R3(c,d,e,a,b,53);
+ R3(b,c,d,e,a,54);
+ R3(a,b,c,d,e,55);
+ R3(e,a,b,c,d,56);
+ R3(d,e,a,b,c,57);
+ R3(c,d,e,a,b,58);
+ R3(b,c,d,e,a,59);
+ R4(a,b,c,d,e,60);
+ R4(e,a,b,c,d,61);
+ R4(d,e,a,b,c,62);
+ R4(c,d,e,a,b,63);
+ R4(b,c,d,e,a,64);
+ R4(a,b,c,d,e,65);
+ R4(e,a,b,c,d,66);
+ R4(d,e,a,b,c,67);
+ R4(c,d,e,a,b,68);
+ R4(b,c,d,e,a,69);
+ R4(a,b,c,d,e,70);
+ R4(e,a,b,c,d,71);
+ R4(d,e,a,b,c,72);
+ R4(c,d,e,a,b,73);
+ R4(b,c,d,e,a,74);
+ R4(a,b,c,d,e,75);
+ R4(e,a,b,c,d,76);
+ R4(d,e,a,b,c,77);
+ R4(c,d,e,a,b,78);
+ R4(b,c,d,e,a,79);
+ /* Add the working vars back into context.state[] */
+ state[0] += a;
+ state[1] += b;
+ state[2] += c;
+ state[3] += d;
+ state[4] += e;
+ /* Wipe variables */
+ a = b = c = d = e = 0;
}
/* SHA1Init - Initialize new context */
-void SHA1Init(SHA1_CTX* context)
-{
- /* SHA1 initialization constants */
- context->state[0] = 0x67452301;
- context->state[1] = 0xEFCDAB89;
- context->state[2] = 0x98BADCFE;
- context->state[3] = 0x10325476;
- context->state[4] = 0xC3D2E1F0;
- context->count[0] = context->count[1] = 0;
+void SHA1Init(SHA1_CTX* context) {
+ /* SHA1 initialization constants */
+ context->state[0] = 0x67452301;
+ context->state[1] = 0xEFCDAB89;
+ context->state[2] = 0x98BADCFE;
+ context->state[3] = 0x10325476;
+ context->state[4] = 0xC3D2E1F0;
+ context->count[0] = context->count[1] = 0;
}
/* Run your data through this. */
-void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int len)
-{
-unsigned int i, j;
-
- j = (context->count[0] >> 3) & 63;
- if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++;
- context->count[1] += (len >> 29);
- if ((j + len) > 63) {
- memcpy(&context->buffer[j], data, (i = 64-j));
- SHA1Transform(context->state, context->buffer);
- for ( ; i + 63 < len; i += 64) {
- SHA1Transform(context->state, &data[i]);
- }
- j = 0;
- }
- else i = 0;
- memcpy(&context->buffer[j], &data[i], len - i);
+void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int len) {
+ unsigned int i, j;
+
+ j = (context->count[0] >> 3) & 63;
+ if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++;
+ context->count[1] += (len >> 29);
+ if ((j + len) > 63) {
+ memcpy(&context->buffer[j], data, (i = 64-j));
+ SHA1Transform(context->state, context->buffer);
+ for ( ; i + 63 < len; i += 64) {
+ SHA1Transform(context->state, &data[i]);
+ }
+ j = 0;
+ } else i = 0;
+ memcpy(&context->buffer[j], &data[i], len - i);
}
/* Add padding and return the message digest. */
-void SHA1Final(unsigned char digest[20], SHA1_CTX* context)
-{
-unsigned int i, j;
-unsigned char finalcount[8];
-
- for (i = 0; i < 8; i++) {
- finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
- >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */
- }
- SHA1Update(context, (unsigned char *)"\200", 1);
- while ((context->count[0] & 504) != 448) {
- SHA1Update(context, (unsigned char *)"\0", 1);
- }
- SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */
- for (i = 0; i < 20; i++) {
- digest[i] = (unsigned char)
- ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
- }
- /* Wipe variables */
- i = j = 0;
- memset(context->buffer, 0, 64);
- memset(context->state, 0, 20);
- memset(context->count, 0, 8);
- memset(&finalcount, 0, 8);
+void SHA1Final(unsigned char digest[20], SHA1_CTX* context) {
+ unsigned int i, j;
+ unsigned char finalcount[8];
+
+ for (i = 0; i < 8; i++) {
+ finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
+ >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */
+ }
+ SHA1Update(context, (unsigned char *)"\200", 1);
+ while ((context->count[0] & 504) != 448) {
+ SHA1Update(context, (unsigned char *)"\0", 1);
+ }
+ SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */
+ for (i = 0; i < 20; i++) {
+ digest[i] = (unsigned char)
+ ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
+ }
+ /* Wipe variables */
+ i = j = 0;
+ memset(context->buffer, 0, 64);
+ memset(context->state, 0, 20);
+ memset(context->count, 0, 8);
+ memset(&finalcount, 0, 8);
#ifdef SHA1HANDSOFF /* make SHA1Transform overwrite it's own static vars */
- SHA1Transform(context->state, context->buffer);
+ SHA1Transform(context->state, context->buffer);
#endif
}
-cairo_surface_t *
-shoes_surface_create_from_pixels(PIXEL *pixels, int width, int height)
-{
- guchar *cairo_pixels;
- cairo_surface_t *surface;
- cairo_user_data_key_t key;
- int j;
-
- cairo_pixels = (guchar *)g_malloc(4 * width * height);
- surface = cairo_image_surface_create_for_data((unsigned char *)cairo_pixels,
- CAIRO_FORMAT_ARGB32,
- width, height, 4 * width);
- cairo_surface_set_user_data(surface, &key,
- cairo_pixels, (cairo_destroy_func_t)g_free);
-
- for (j = height; j; j--)
- {
- guchar *p = (guchar *)pixels;
- guchar *q = cairo_pixels;
-
- guchar *end = p + 4 * width;
- guint t1,t2,t3;
-
+cairo_surface_t *shoes_surface_create_from_pixels(PIXEL *pixels, int width, int height) {
+ guchar *cairo_pixels;
+ cairo_surface_t *surface;
+ cairo_user_data_key_t key;
+ int j;
+
+ cairo_pixels = (guchar *)g_malloc(4 * width * height);
+ surface = cairo_image_surface_create_for_data((unsigned char *)cairo_pixels,
+ CAIRO_FORMAT_ARGB32,
+ width, height, 4 * width);
+ cairo_surface_set_user_data(surface, &key,
+ cairo_pixels, (cairo_destroy_func_t)g_free);
+
+ for (j = height; j; j--) {
+ guchar *p = (guchar *)pixels;
+ guchar *q = cairo_pixels;
+
+ guchar *end = p + 4 * width;
+ guint t1,t2,t3;
+
#define MULT(d,c,a,t) G_STMT_START { t = c * a; d = ((t >> 8) + t) >> 8; } G_STMT_END
-
- while (p < end)
- {
+
+ while (p < end) {
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
- MULT(q[2], p[2], p[3], t1);
- MULT(q[1], p[1], p[3], t2);
- MULT(q[0], p[0], p[3], t3);
- q[3] = p[3];
+ MULT(q[2], p[2], p[3], t1);
+ MULT(q[1], p[1], p[3], t2);
+ MULT(q[0], p[0], p[3], t3);
+ q[3] = p[3];
#else
- q[0] = p[3];
- MULT(q[3], p[0], p[3], t1);
- MULT(q[2], p[1], p[3], t2);
- MULT(q[1], p[2], p[3], t3);
+ q[0] = p[3];
+ MULT(q[3], p[0], p[3], t1);
+ MULT(q[2], p[1], p[3], t2);
+ MULT(q[1], p[2], p[3], t3);
#endif
-
- p += 4;
- q += 4;
- }
-
+
+ p += 4;
+ q += 4;
+ }
+
#undef MULT
-
- pixels += width;
- cairo_pixels += 4 * width;
- }
-
- return surface;
+
+ pixels += width;
+ cairo_pixels += 4 * width;
+ }
+
+ return surface;
}
#define PNG_SIG "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A"
-cairo_surface_t *
-shoes_png_size(char *filename, int *width, int *height)
-{
- unsigned char *sig = SHOE_ALLOC_N(unsigned char, 32);
- cairo_surface_t *surface = NULL;
-
+cairo_surface_t *shoes_png_size(char *filename, int *width, int *height) {
+ unsigned char *sig = SHOE_ALLOC_N(unsigned char, 32);
+ cairo_surface_t *surface = NULL;
+
#ifdef SHOES_WIN32
- HANDLE hFile;
- hFile = CreateFile( filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
- if ( hFile == INVALID_HANDLE_VALUE ) return NULL;
- DWORD readsize;
- ReadFile( hFile, sig, 32, &readsize, NULL );
- if (readsize < 8)
- goto done;
+ HANDLE hFile;
+ hFile = CreateFile( filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
+ if ( hFile == INVALID_HANDLE_VALUE ) return NULL;
+ DWORD readsize;
+ ReadFile( hFile, sig, 32, &readsize, NULL );
+ if (readsize < 8)
+ goto done;
#else
- FILE *image = fopen(filename, "rb");
- if (image == NULL) return NULL;
+ FILE *image = fopen(filename, "rb");
+ if (image == NULL) return NULL;
- if (fread(sig, 1, 32, image) < 8)
- goto done;
+ if (fread(sig, 1, 32, image) < 8)
+ goto done;
#endif
-
- if (memcmp(sig, PNG_SIG, 8) != 0)
- goto done;
- *width = *((int *)(sig + 0x10));
- BE_CPU(*width);
- *height = *((int *)(sig + 0x14));
- BE_CPU(*height);
+ if (memcmp(sig, PNG_SIG, 8) != 0)
+ goto done;
+
+ *width = *((int *)(sig + 0x10));
+ BE_CPU(*width);
+ *height = *((int *)(sig + 0x14));
+ BE_CPU(*height);
- surface = SIZE_SURFACE;
+ surface = SIZE_SURFACE;
done:
#ifdef SHOES_WIN32
- CloseHandle( hFile );
+ CloseHandle( hFile );
#else
- fclose(image);
+ fclose(image);
#endif
- return surface;
+ return surface;
}
-cairo_surface_t *
-shoes_surface_create_from_gif(char *filename, int *width, int *height, unsigned char load)
-{
- cairo_surface_t *surface = NULL;
- GifFileType *gif;
- PIXEL *ptr = NULL, *pixels = NULL;
- GifPixelType **rows = NULL;
- GifRecordType rec;
- ColorMapObject *cmap;
- int i, j, bg, r, g, b, w = 0, h = 0, done = 0, transp = -1;
- float per = 0.0f, per_inc;
- int intoffset[] = { 0, 4, 2, 1 };
- int intjump[] = { 8, 8, 4, 2 };
-
- transp = -1;
+cairo_surface_t *shoes_surface_create_from_gif(char *filename, int *width, int *height, unsigned char load) {
+ cairo_surface_t *surface = NULL;
+ GifFileType *gif;
+ PIXEL *ptr = NULL, *pixels = NULL;
+ GifPixelType **rows = NULL;
+ GifRecordType rec;
+ ColorMapObject *cmap;
+ int i, j, bg, r, g, b, w = 0, h = 0, done = 0, transp = -1;
+ float per = 0.0f, per_inc;
+ int intoffset[] = { 0, 4, 2, 1 };
+ int intjump[] = { 8, 8, 4, 2 };
+
+ transp = -1;
#if !defined(GIFLIB_MAJOR) || (GIFLIB_MAJOR <= 4)
- gif = DGifOpenFileName(filename);
+ gif = DGifOpenFileName(filename);
#else
- int gif_err;
- gif = DGifOpenFileName(filename, &gif_err);
+ int gif_err;
+ gif = DGifOpenFileName(filename, &gif_err);
#endif
- if (gif == NULL)
- goto done;
-
- do
- {
- if (DGifGetRecordType(gif, &rec) == GIF_ERROR)
- rec = TERMINATE_RECORD_TYPE;
- if ((rec == IMAGE_DESC_RECORD_TYPE) && (!done))
- {
- if (DGifGetImageDesc(gif) == GIF_ERROR)
- {
- /* PrintGifError(); */
- rec = TERMINATE_RECORD_TYPE;
- }
- w = gif->Image.Width;
- if (width != NULL) *width = w;
- h = gif->Image.Height;
- if (height != NULL) *height = h;
- if ((w < 1) || (h < 1) || (w > 8192) || (h > 8192))
+ if (gif == NULL)
goto done;
- if (!load)
- {
- surface = SIZE_SURFACE;
- goto done;
- }
+ do {
+ if (DGifGetRecordType(gif, &rec) == GIF_ERROR)
+ rec = TERMINATE_RECORD_TYPE;
+ if ((rec == IMAGE_DESC_RECORD_TYPE) && (!done)) {
+ if (DGifGetImageDesc(gif) == GIF_ERROR) {
+ /* PrintGifError(); */
+ rec = TERMINATE_RECORD_TYPE;
+ }
+ w = gif->Image.Width;
+ if (width != NULL) *width = w;
+ h = gif->Image.Height;
+ if (height != NULL) *height = h;
+ if ((w < 1) || (h < 1) || (w > 8192) || (h > 8192))
+ goto done;
+
+ if (!load) {
+ surface = SIZE_SURFACE;
+ goto done;
+ }
+
+ rows = SHOE_ALLOC_N(GifPixelType *, h);
+ if (rows == NULL)
+ goto done;
+
+ SHOE_MEMZERO(rows, GifPixelType *, h);
+
+ for (i = 0; i < h; i++) {
+ rows[i] = SHOE_ALLOC_N(GifPixelType, w);
+ if (rows[i] == NULL)
+ goto done;
+ }
+
+ if (gif->Image.Interlace) {
+ for (i = 0; i < 4; i++) {
+ for (j = intoffset[i]; j < h; j += intjump[i])
+ DGifGetLine(gif, rows[j], w);
+ }
+ } else {
+ for (i = 0; i < h; i++)
+ DGifGetLine(gif, rows[i], w);
+ }
+ done = 1;
+ } else if (rec == EXTENSION_RECORD_TYPE) {
+ int ext_code;
+ GifByteType *ext = NULL;
+ DGifGetExtension(gif, &ext_code, &ext);
+ while (ext) {
+ if ((ext_code == 0xf9) && (ext[1] & 1) && (transp < 0))
+ transp = (int)ext[4];
+ ext = NULL;
+ DGifGetExtensionNext(gif, &ext);
+ }
+ }
+ } while (rec != TERMINATE_RECORD_TYPE);
- rows = SHOE_ALLOC_N(GifPixelType *, h);
- if (rows == NULL)
+ bg = gif->SBackGroundColor;
+ cmap = (gif->Image.ColorMap ? gif->Image.ColorMap : gif->SColorMap);
+ pixels = SHOE_ALLOC_N(PIXEL, w * h);
+ if (pixels == NULL)
goto done;
- SHOE_MEMZERO(rows, GifPixelType *, h);
-
- for (i = 0; i < h; i++)
- {
- rows[i] = SHOE_ALLOC_N(GifPixelType, w);
- if (rows[i] == NULL)
- goto done;
- }
-
- if (gif->Image.Interlace)
- {
- for (i = 0; i < 4; i++)
- {
- for (j = intoffset[i]; j < h; j += intjump[i])
- DGifGetLine(gif, rows[j], w);
+ ptr = pixels;
+ per_inc = 100.0f / (((float)w) * h);
+ for (i = 0; i < h; i++) {
+ for (j = 0; j < w; j++) {
+ if (rows[i][j] == transp) {
+ r = cmap->Colors[bg].Red;
+ g = cmap->Colors[bg].Green;
+ b = cmap->Colors[bg].Blue;
+ *ptr = 0x00ffffff & ((r << 16) | (g << 8) | b);
+ LE_CPU(*ptr);
+ ptr++;
+ } else {
+ r = cmap->Colors[rows[i][j]].Red;
+ g = cmap->Colors[rows[i][j]].Green;
+ b = cmap->Colors[rows[i][j]].Blue;
+ *ptr = (0xff << 24) | (r << 16) | (g << 8) | b;
+ LE_CPU(*ptr);
+ ptr++;
+ }
+ per += per_inc;
}
- }
- else
- {
- for (i = 0; i < h; i++)
- DGifGetLine(gif, rows[i], w);
- }
- done = 1;
- }
- else if (rec == EXTENSION_RECORD_TYPE)
- {
- int ext_code;
- GifByteType *ext = NULL;
- DGifGetExtension(gif, &ext_code, &ext);
- while (ext)
- {
- if ((ext_code == 0xf9) && (ext[1] & 1) && (transp < 0))
- transp = (int)ext[4];
- ext = NULL;
- DGifGetExtensionNext(gif, &ext);
- }
}
- } while (rec != TERMINATE_RECORD_TYPE);
-
- bg = gif->SBackGroundColor;
- cmap = (gif->Image.ColorMap ? gif->Image.ColorMap : gif->SColorMap);
- pixels = SHOE_ALLOC_N(PIXEL, w * h);
- if (pixels == NULL)
- goto done;
-
- ptr = pixels;
- per_inc = 100.0f / (((float)w) * h);
- for (i = 0; i < h; i++)
- {
- for (j = 0; j < w; j++)
- {
- if (rows[i][j] == transp)
- {
- r = cmap->Colors[bg].Red;
- g = cmap->Colors[bg].Green;
- b = cmap->Colors[bg].Blue;
- *ptr = 0x00ffffff & ((r << 16) | (g << 8) | b);
- LE_CPU(*ptr);
- ptr++;
- }
- else
- {
- r = cmap->Colors[rows[i][j]].Red;
- g = cmap->Colors[rows[i][j]].Green;
- b = cmap->Colors[rows[i][j]].Blue;
- *ptr = (0xff << 24) | (r << 16) | (g << 8) | b;
- LE_CPU(*ptr);
- ptr++;
- }
- per += per_inc;
- }
- }
- if ((w < 1) || (h < 1) || (w > 8192) || (h > 8192))
- goto done;
+ if ((w < 1) || (h < 1) || (w > 8192) || (h > 8192))
+ goto done;
- surface = shoes_surface_create_from_pixels(pixels, w, h);
+ surface = shoes_surface_create_from_pixels(pixels, w, h);
done:
#if !defined(GIFLIB_MAJOR) || (GIFLIB_MAJOR <= 4)
- if (gif != NULL) DGifCloseFile(gif);
+ if (gif != NULL) DGifCloseFile(gif);
#else
- if (gif != NULL) DGifCloseFile(gif, &gif_err);
+ if (gif != NULL) DGifCloseFile(gif, &gif_err);
#endif
- if (pixels != NULL) SHOE_FREE(pixels);
- if (rows != NULL) {
- for (i = 0; i < h; i++)
- if (rows[i] != NULL)
- SHOE_FREE(rows[i]);
- SHOE_FREE(rows);
- }
- return surface;
+ if (pixels != NULL) SHOE_FREE(pixels);
+ if (rows != NULL) {
+ for (i = 0; i < h; i++)
+ if (rows[i] != NULL)
+ SHOE_FREE(rows[i]);
+ SHOE_FREE(rows);
+ }
+ return surface;
}
//
// JPEG handling code
//
struct shoes_jpeg_file_src {
- struct jpeg_source_mgr pub; /* public fields */
-
+ struct jpeg_source_mgr pub; /* public fields */
+
#ifdef SHOES_WIN32
- HANDLE infile; /* source stream */
+ HANDLE infile; /* source stream */
#else
- FILE *infile; /* source stream */
+ FILE *infile; /* source stream */
#endif
-
- JOCTET *buffer; /* start of buffer */
- boolean start_of_file; /* have we gotten any data yet? */
+
+ JOCTET *buffer; /* start of buffer */
+ boolean start_of_file; /* have we gotten any data yet? */
};
struct shoes_jpeg_error_mgr {
- struct jpeg_error_mgr pub; /* public fields */
- jmp_buf setjmp_buffer; /* for return to caller */
+ struct jpeg_error_mgr pub; /* public fields */
+ jmp_buf setjmp_buffer; /* for return to caller */
};
typedef struct shoes_jpeg_file_src *shoes_jpeg_file;
@@ -451,584 +481,502 @@ typedef struct shoes_jpeg_error_mgr *shoes_jpeg_err;
#define JPEG_INPUT_BUF_SIZE 4096
-void
-shoes_jpeg_term_source(j_decompress_ptr cinfo)
-{
+void shoes_jpeg_term_source(j_decompress_ptr cinfo) {
}
-void
-shoes_jpeg_init_source(j_decompress_ptr cinfo)
-{
- shoes_jpeg_file src = (shoes_jpeg_file) cinfo->src;
- src->start_of_file = 1;
+void shoes_jpeg_init_source(j_decompress_ptr cinfo) {
+ shoes_jpeg_file src = (shoes_jpeg_file) cinfo->src;
+ src->start_of_file = 1;
}
-
-boolean
-shoes_jpeg_fill_input_buffer(j_decompress_ptr cinfo)
-{
- shoes_jpeg_file src = (shoes_jpeg_file)cinfo->src;
- size_t nbytes;
+boolean shoes_jpeg_fill_input_buffer(j_decompress_ptr cinfo) {
+ shoes_jpeg_file src = (shoes_jpeg_file)cinfo->src;
+ size_t nbytes;
#ifdef SHOES_WIN32
- DWORD readsize;
- ReadFile( src->infile, src->buffer, JPEG_INPUT_BUF_SIZE, &readsize, NULL );
- nbytes = readsize;
+ DWORD readsize;
+ ReadFile( src->infile, src->buffer, JPEG_INPUT_BUF_SIZE, &readsize, NULL );
+ nbytes = readsize;
#else
- nbytes = fread(src->buffer, 1, JPEG_INPUT_BUF_SIZE, src->infile);
+ nbytes = fread(src->buffer, 1, JPEG_INPUT_BUF_SIZE, src->infile);
#endif
- if (nbytes <= 0) {
- if (src->start_of_file) /* Treat empty input file as fatal error */
- ERREXIT(cinfo, JERR_INPUT_EMPTY);
- WARNMS(cinfo, JWRN_JPEG_EOF);
- src->buffer[0] = (JOCTET) 0xFF;
- src->buffer[1] = (JOCTET) JPEG_EOI;
- nbytes = 2;
- }
+ if (nbytes <= 0) {
+ if (src->start_of_file) /* Treat empty input file as fatal error */
+ ERREXIT(cinfo, JERR_INPUT_EMPTY);
+ WARNMS(cinfo, JWRN_JPEG_EOF);
+ src->buffer[0] = (JOCTET) 0xFF;
+ src->buffer[1] = (JOCTET) JPEG_EOI;
+ nbytes = 2;
+ }
- src->pub.next_input_byte = src->buffer;
- src->pub.bytes_in_buffer = nbytes;
- src->start_of_file = 0;
+ src->pub.next_input_byte = src->buffer;
+ src->pub.bytes_in_buffer = nbytes;
+ src->start_of_file = 0;
- return 1;
+ return 1;
}
-void
-shoes_jpeg_skip_input_data(j_decompress_ptr cinfo, long num_bytes)
-{
- shoes_jpeg_file src = (shoes_jpeg_file)cinfo->src;
-
- if (num_bytes > 0)
- {
- while (num_bytes > (long)src->pub.bytes_in_buffer)
- {
- num_bytes -= (long)src->pub.bytes_in_buffer;
- (void)shoes_jpeg_fill_input_buffer(cinfo);
+void shoes_jpeg_skip_input_data(j_decompress_ptr cinfo, long num_bytes) {
+ shoes_jpeg_file src = (shoes_jpeg_file)cinfo->src;
+
+ if (num_bytes > 0) {
+ while (num_bytes > (long)src->pub.bytes_in_buffer) {
+ num_bytes -= (long)src->pub.bytes_in_buffer;
+ (void)shoes_jpeg_fill_input_buffer(cinfo);
+ }
+ src->pub.next_input_byte += (size_t)num_bytes;
+ src->pub.bytes_in_buffer -= (size_t)num_bytes;
}
- src->pub.next_input_byte += (size_t)num_bytes;
- src->pub.bytes_in_buffer -= (size_t)num_bytes;
- }
}
-void
+void jpeg_file_src(j_decompress_ptr cinfo,
#ifdef SHOES_WIN32
-jpeg_file_src(j_decompress_ptr cinfo, HANDLE infile)
+ HANDLE infile
#else
-jpeg_file_src(j_decompress_ptr cinfo, FILE *infile)
+ FILE *infile
#endif
-{
- shoes_jpeg_file src;
-
- if (cinfo->src == NULL)
- {
- /* first time for this JPEG object? */
- cinfo->src = (struct jpeg_source_mgr *)
- (*cinfo->mem->alloc_small)((j_common_ptr) cinfo, JPOOL_PERMANENT,
- sizeof(struct shoes_jpeg_file_src));
- src = (shoes_jpeg_file) cinfo->src;
- src->buffer = (JOCTET *)
- (*cinfo->mem->alloc_small)((j_common_ptr) cinfo, JPOOL_PERMANENT,
- JPEG_INPUT_BUF_SIZE * sizeof(JOCTET));
- }
-
- src = (shoes_jpeg_file)cinfo->src;
- src->pub.init_source = shoes_jpeg_init_source;
- src->pub.fill_input_buffer = shoes_jpeg_fill_input_buffer;
- src->pub.skip_input_data = shoes_jpeg_skip_input_data;
- src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */
- src->pub.term_source = shoes_jpeg_term_source;
- src->infile = infile;
- src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */
- src->pub.next_input_byte = NULL; /* until buffer loaded */
+ ) {
+ shoes_jpeg_file src;
+
+ if (cinfo->src == NULL) {
+ /* first time for this JPEG object? */
+ cinfo->src = (struct jpeg_source_mgr *)
+ (*cinfo->mem->alloc_small)((j_common_ptr) cinfo, JPOOL_PERMANENT,
+ sizeof(struct shoes_jpeg_file_src));
+ src = (shoes_jpeg_file) cinfo->src;
+ src->buffer = (JOCTET *)
+ (*cinfo->mem->alloc_small)((j_common_ptr) cinfo, JPOOL_PERMANENT,
+ JPEG_INPUT_BUF_SIZE * sizeof(JOCTET));
+ }
+
+ src = (shoes_jpeg_file)cinfo->src;
+ src->pub.init_source = shoes_jpeg_init_source;
+ src->pub.fill_input_buffer = shoes_jpeg_fill_input_buffer;
+ src->pub.skip_input_data = shoes_jpeg_skip_input_data;
+ src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */
+ src->pub.term_source = shoes_jpeg_term_source;
+ src->infile = infile;
+ src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */
+ src->pub.next_input_byte = NULL; /* until buffer loaded */
}
-
-void
-shoes_jpeg_fatal(j_common_ptr cinfo)
-{
- shoes_jpeg_err jpgerr = (shoes_jpeg_err)cinfo->err;
- longjmp(jpgerr->setjmp_buffer, 1);
+
+void shoes_jpeg_fatal(j_common_ptr cinfo) {
+ shoes_jpeg_err jpgerr = (shoes_jpeg_err)cinfo->err;
+ longjmp(jpgerr->setjmp_buffer, 1);
}
-cairo_surface_t *
-shoes_surface_create_from_jpeg(char *filename, int *width, int *height, unsigned char load)
-{
- int x, y, w, h, l, i, scans, count, prevy;
- unsigned char *ptr, *rgb = NULL, **line = NULL;
- PIXEL *pixels = NULL, *ptr2;
- cairo_surface_t *surface = NULL;
- struct jpeg_decompress_struct cinfo;
- struct shoes_jpeg_error_mgr jerr;
-
+cairo_surface_t *shoes_surface_create_from_jpeg(char *filename, int *width, int *height, unsigned char load) {
+ int x, y, w, h, l, i, scans, count, prevy;
+ unsigned char *ptr, *rgb = NULL, **line = NULL;
+ PIXEL *pixels = NULL, *ptr2;
+ cairo_surface_t *surface = NULL;
+ struct jpeg_decompress_struct cinfo;
+ struct shoes_jpeg_error_mgr jerr;
+
#ifdef SHOES_WIN32
- HANDLE hFile;
- hFile = CreateFile( filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
- if ( hFile == INVALID_HANDLE_VALUE ) return NULL;
+ HANDLE hFile;
+ hFile = CreateFile( filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
+ if ( hFile == INVALID_HANDLE_VALUE ) return NULL;
#else
- FILE *f = fopen(filename, "rb");
- if (!f) return NULL;
+ FILE *f = fopen(filename, "rb");
+ if (!f) return NULL;
#endif
-
- // TODO: error handling
- cinfo.err = jpeg_std_error(&jerr.pub);
- jerr.pub.error_exit = shoes_jpeg_fatal;
- // jerr.pub.emit_message = shoes_jpeg_error;
- // jerr.pub.output_message = shoes_jpeg_error2;
- if (setjmp(jerr.setjmp_buffer)) {
- // append_jpeg_message(interp, (j_common_ptr) &cinfo);
- jpeg_destroy_decompress(&cinfo);
- return NULL;
- }
- jpeg_create_decompress(&cinfo);
+ // TODO: error handling
+ cinfo.err = jpeg_std_error(&jerr.pub);
+ jerr.pub.error_exit = shoes_jpeg_fatal;
+ // jerr.pub.emit_message = shoes_jpeg_error;
+ // jerr.pub.output_message = shoes_jpeg_error2;
+ if (setjmp(jerr.setjmp_buffer)) {
+ // append_jpeg_message(interp, (j_common_ptr) &cinfo);
+ jpeg_destroy_decompress(&cinfo);
+ return NULL;
+ }
+
+ jpeg_create_decompress(&cinfo);
#ifdef SHOES_WIN32
- jpeg_file_src(&cinfo, hFile);
+ jpeg_file_src(&cinfo, hFile);
#else
- jpeg_file_src(&cinfo, f);
+ jpeg_file_src(&cinfo, f);
#endif
- jpeg_read_header(&cinfo, TRUE);
- cinfo.do_fancy_upsampling = FALSE;
- cinfo.do_block_smoothing = FALSE;
-
- line = SHOE_ALLOC_N(unsigned char *, JPEG_LINES);
- jpeg_start_decompress(&cinfo);
- w = cinfo.output_width;
- if (width != NULL) *width = w;
- h = cinfo.output_height;
- if (height != NULL) *height = h;
-
- if ((w < 1) || (h < 1) || (w > 8192) || (h > 8192))
- goto done;
-
- if (!load)
- {
- surface = SIZE_SURFACE;
- goto done;
- }
-
- if (cinfo.rec_outbuf_height > JPEG_LINES)
- goto done;
-
- rgb = SHOE_ALLOC_N(unsigned char, w * JPEG_LINES * 3);
- ptr2 = pixels = SHOE_ALLOC_N(PIXEL, w * h);
- if (rgb == NULL || pixels == NULL)
- goto done;
-
- count = 0;
- prevy = 0;
- if (cinfo.output_components == 3 || cinfo.output_components == 1)
- {
- int c = cinfo.output_components;
- for (i = 0; i < cinfo.rec_outbuf_height; i++)
- line[i] = rgb + (i * w * c);
- for (l = 0; l < h; l += cinfo.rec_outbuf_height)
- {
- jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
- scans = cinfo.rec_outbuf_height;
- if ((h - l) < scans) scans = h - l;
- ptr = rgb;
- for (y = 0; y < scans; y++)
- {
- for (x = 0; x < w; x++)
- {
- if (c == 3)
- *ptr2 = (0xff000000) | ((ptr[0]) << 16) | ((ptr[1]) << 8) | (ptr[2]);
- else if (c == 1)
- *ptr2 = (0xff000000) | ((ptr[0]) << 16) | ((ptr[0]) << 8) | (ptr[0]);
- LE_CPU(*ptr2);
- ptr += c;
- ptr2++;
+ jpeg_read_header(&cinfo, TRUE);
+ cinfo.do_fancy_upsampling = FALSE;
+ cinfo.do_block_smoothing = FALSE;
+
+ line = SHOE_ALLOC_N(unsigned char *, JPEG_LINES);
+ jpeg_start_decompress(&cinfo);
+ w = cinfo.output_width;
+ if (width != NULL) *width = w;
+ h = cinfo.output_height;
+ if (height != NULL) *height = h;
+
+ if ((w < 1) || (h < 1) || (w > 8192) || (h > 8192))
+ goto done;
+
+ if (!load) {
+ surface = SIZE_SURFACE;
+ goto done;
+ }
+
+ if (cinfo.rec_outbuf_height > JPEG_LINES)
+ goto done;
+
+ rgb = SHOE_ALLOC_N(unsigned char, w * JPEG_LINES * 3);
+ ptr2 = pixels = SHOE_ALLOC_N(PIXEL, w * h);
+ if (rgb == NULL || pixels == NULL)
+ goto done;
+
+ count = 0;
+ prevy = 0;
+ if (cinfo.output_components == 3 || cinfo.output_components == 1) {
+ int c = cinfo.output_components;
+ for (i = 0; i < cinfo.rec_outbuf_height; i++)
+ line[i] = rgb + (i * w * c);
+ for (l = 0; l < h; l += cinfo.rec_outbuf_height) {
+ jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
+ scans = cinfo.rec_outbuf_height;
+ if ((h - l) < scans) scans = h - l;
+ ptr = rgb;
+ for (y = 0; y < scans; y++) {
+ for (x = 0; x < w; x++) {
+ if (c == 3)
+ *ptr2 = (0xff000000) | ((ptr[0]) << 16) | ((ptr[1]) << 8) | (ptr[2]);
+ else if (c == 1)
+ *ptr2 = (0xff000000) | ((ptr[0]) << 16) | ((ptr[0]) << 8) | (ptr[0]);
+ LE_CPU(*ptr2);
+ ptr += c;
+ ptr2++;
+ }
+ }
}
- }
}
- }
- surface = shoes_surface_create_from_pixels(pixels, w, h);
- jpeg_finish_decompress(&cinfo);
+ surface = shoes_surface_create_from_pixels(pixels, w, h);
+ jpeg_finish_decompress(&cinfo);
done:
- free(line);
- if (pixels != NULL) free(pixels);
- if (rgb != NULL) free(rgb);
- jpeg_destroy_decompress(&cinfo);
+ free(line);
+ if (pixels != NULL) free(pixels);
+ if (rgb != NULL) free(rgb);
+ jpeg_destroy_decompress(&cinfo);
#ifdef SHOES_WIN32
- CloseHandle( hFile );
+ CloseHandle( hFile );
#else
- fclose(f);
+ fclose(f);
#endif
- return surface;
+ return surface;
}
-char
-shoes_has_ext(char *fname, int len, const char *ext)
-{
- return strncmp(fname + (len - strlen(ext)), ext, strlen(ext)) == 0;
+char shoes_has_ext(char *fname, int len, const char *ext) {
+ return strncmp(fname + (len - strlen(ext)), ext, strlen(ext)) == 0;
}
-unsigned char
-shoes_check_file_exists(VALUE path)
-{
- if (!RTEST(rb_funcall(rb_cFile, rb_intern("exists?"), 1, path)))
- {
- StringValue(path);
- shoes_error("Shoes could not find the file %s.", RSTRING_PTR(path));
- return FALSE;
- }
- return TRUE;
+unsigned char shoes_check_file_exists(VALUE path) {
+ if (!RTEST(rb_funcall(rb_cFile, rb_intern("exists?"), 1, path))) {
+ StringValue(path);
+ shoes_error("Shoes could not find the file %s.", RSTRING_PTR(path));
+ return FALSE;
+ }
+ return TRUE;
}
-void
-shoes_unsupported_image(VALUE path)
-{
- VALUE ext = rb_funcall(rb_cFile, rb_intern("extname"), 1, path);
- StringValue(path);
- StringValue(ext);
- shoes_error("Couldn't load %s. Shoes does not support images with the %s extension.",
- RSTRING_PTR(path), RSTRING_PTR(ext));
+void shoes_unsupported_image(VALUE path) {
+ VALUE ext = rb_funcall(rb_cFile, rb_intern("extname"), 1, path);
+ StringValue(path);
+ StringValue(ext);
+ shoes_error("Couldn't load %s. Shoes does not support images with the %s extension.",
+ RSTRING_PTR(path), RSTRING_PTR(ext));
}
-void
-shoes_failed_image(VALUE path)
-{
- VALUE ext = rb_funcall(rb_cFile, rb_intern("extname"), 1, path);
- StringValue(path);
- StringValue(ext);
- shoes_error("Couldn't load %s. Is the file a valid %s?",
- RSTRING_PTR(path), RSTRING_PTR(ext));
+void shoes_failed_image(VALUE path) {
+ VALUE ext = rb_funcall(rb_cFile, rb_intern("extname"), 1, path);
+ StringValue(path);
+ StringValue(ext);
+ shoes_error("Couldn't load %s. Is the file a valid %s?",
+ RSTRING_PTR(path), RSTRING_PTR(ext));
}
-cairo_surface_t *
-shoes_surface_create_from_file(VALUE imgpath, int *width, int *height)
-{
- cairo_surface_t *img = NULL;
- shoes_image_format format = shoes_image_detect(imgpath, width, height);
- if (format == SHOES_IMAGE_PNG)
- {
- img = cairo_image_surface_create_from_png(RSTRING_PTR(imgpath));
- if (cairo_surface_status(img) != CAIRO_STATUS_SUCCESS)
- img = NULL;
- }
- else if (format == SHOES_IMAGE_JPEG)
- img = shoes_surface_create_from_jpeg(RSTRING_PTR(imgpath), width, height, TRUE);
- else if (format == SHOES_IMAGE_GIF)
- img = shoes_surface_create_from_gif(RSTRING_PTR(imgpath), width, height, TRUE);
- else
- return shoes_world->blank_image;
-
- if (img == NULL)
- {
- shoes_failed_image(imgpath);
- img = shoes_world->blank_image;
- }
-
- return img;
+cairo_surface_t *shoes_surface_create_from_file(VALUE imgpath, int *width, int *height) {
+ cairo_surface_t *img = NULL;
+ shoes_image_format format = shoes_image_detect(imgpath, width, height);
+ if (format == SHOES_IMAGE_PNG) {
+ img = cairo_image_surface_create_from_png(RSTRING_PTR(imgpath));
+ if (cairo_surface_status(img) != CAIRO_STATUS_SUCCESS)
+ img = NULL;
+ } else if (format == SHOES_IMAGE_JPEG)
+ img = shoes_surface_create_from_jpeg(RSTRING_PTR(imgpath), width, height, TRUE);
+ else if (format == SHOES_IMAGE_GIF)
+ img = shoes_surface_create_from_gif(RSTRING_PTR(imgpath), width, height, TRUE);
+ else
+ return shoes_world->blank_image;
+
+ if (img == NULL) {
+ shoes_failed_image(imgpath);
+ img = shoes_world->blank_image;
+ }
+
+ return img;
}
-int
-shoes_file_mtime(char *path)
-{
- int mtime = 0;
- struct stat *s = SHOE_ALLOC(struct stat);
- stat(path, s);
- mtime = (int)s->st_mtime;
- SHOE_FREE(s);
- return mtime;
+int shoes_file_mtime(char *path) {
+ int mtime = 0;
+ struct stat *s = SHOE_ALLOC(struct stat);
+ stat(path, s);
+ mtime = (int)s->st_mtime;
+ SHOE_FREE(s);
+ return mtime;
}
-shoes_cached_image *
-shoes_cached_image_new(int width, int height, cairo_surface_t *surface)
-{
- shoes_cached_image *cached = SHOE_ALLOC(shoes_cached_image);
- if (surface == NULL)
- surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
- cached->surface = surface;
- cached->pattern = NULL;
- cached->width = width;
- cached->height = height;
- cached->mtime = 0;
- return cached;
+shoes_cached_image *shoes_cached_image_new(int width, int height, cairo_surface_t *surface) {
+ shoes_cached_image *cached = SHOE_ALLOC(shoes_cached_image);
+ if (surface == NULL)
+ surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
+ cached->surface = surface;
+ cached->pattern = NULL;
+ cached->width = width;
+ cached->height = height;
+ cached->mtime = 0;
+ return cached;
}
-int
-shoes_cache_lookup(char *imgpath, shoes_cached_image **image)
-{
- shoes_cache_entry *cached = NULL;
- int ret = st_lookup(shoes_world->image_cache, (st_data_t)imgpath, (st_data_t *)&cached);
- // if (ret && shoes_file_mtime(imgpath) == cached->image->mtime) {
- // st_delete(shoes_world->image_cache, (st_data_t *)&imgpath, 0);
- // // TODO: memory leak if an image's mtime changes (it's overwritten)
- // // need to free this struct, but only after the surface is out of play
- // // shoes_world_free_image_cache(imgpath, cached, NULL);
- // ret = 0;
- // }
- if (ret) *image = cached->image;
- return ret;
+int shoes_cache_lookup(char *imgpath, shoes_cached_image **image) {
+ shoes_cache_entry *cached = NULL;
+ int ret = st_lookup(shoes_world->image_cache, (st_data_t)imgpath, (st_data_t *)&cached);
+ // if (ret && shoes_file_mtime(imgpath) == cached->image->mtime) {
+ // st_delete(shoes_world->image_cache, (st_data_t *)&imgpath, 0);
+ // // TODO: memory leak if an image's mtime changes (it's overwritten)
+ // // need to free this struct, but only after the surface is out of play
+ // // shoes_world_free_image_cache(imgpath, cached, NULL);
+ // ret = 0;
+ // }
+ if (ret) *image = cached->image;
+ return ret;
}
-void
-shoes_cache_insert(unsigned char type, VALUE imgpath, shoes_cached_image *image)
-{
- char *path = strdup(RSTRING_PTR(imgpath));
- shoes_cache_entry *cached = SHOE_ALLOC(shoes_cache_entry);
- cached->type = type;
- cached->image = image;
- if (type == SHOES_CACHE_FILE) image->mtime = shoes_file_mtime(path);
- st_insert(shoes_world->image_cache, (st_data_t)path, (st_data_t)cached);
+void shoes_cache_insert(unsigned char type, VALUE imgpath, shoes_cached_image *image) {
+ char *path = strdup(RSTRING_PTR(imgpath));
+ shoes_cache_entry *cached = SHOE_ALLOC(shoes_cache_entry);
+ cached->type = type;
+ cached->image = image;
+ if (type == SHOES_CACHE_FILE) image->mtime = shoes_file_mtime(path);
+ st_insert(shoes_world->image_cache, (st_data_t)path, (st_data_t)cached);
}
-shoes_image_format
-shoes_image_detect(VALUE imgpath, int *width, int *height)
-{
- shoes_image_format format = SHOES_IMAGE_NONE;
- shoes_cached_image *cached = NULL;
- cairo_surface_t *img = NULL;
- VALUE filename = rb_funcall(imgpath, s_downcase, 0);
- char *fname = RSTRING_PTR(filename);
- int len = (int)RSTRING_LEN(filename);
-
- if (shoes_cache_lookup(RSTRING_PTR(imgpath), &cached))
- {
- *width = cached->width;
- *height = cached->height;
- return cached->format;
- }
-
- if (!shoes_check_file_exists(imgpath))
- return SHOES_IMAGE_NONE;
- else if (shoes_has_ext(fname, len, ".png"))
- {
- img = shoes_png_size(RSTRING_PTR(imgpath), width, height);
- format = SHOES_IMAGE_PNG;
- }
- else if (shoes_has_ext(fname, len, ".jpg") || shoes_has_ext(fname, len, ".jpeg"))
- {
- img = shoes_surface_create_from_jpeg(RSTRING_PTR(imgpath), width, height, FALSE);
- format = SHOES_IMAGE_JPEG;
- }
- else if (shoes_has_ext(fname, len, ".gif"))
- {
- img = shoes_surface_create_from_gif(RSTRING_PTR(imgpath), width, height, FALSE);
- format = SHOES_IMAGE_GIF;
- }
-
- if (img != SIZE_SURFACE)
- {
- if (format != SHOES_IMAGE_PNG &&
- (img = shoes_png_size(RSTRING_PTR(imgpath), width, height)) == SIZE_SURFACE)
- format = SHOES_IMAGE_PNG;
- else if (format != SHOES_IMAGE_JPEG &&
- (img = shoes_surface_create_from_jpeg(RSTRING_PTR(imgpath), width, height, FALSE)) == SIZE_SURFACE)
- format = SHOES_IMAGE_JPEG;
- else if (format != SHOES_IMAGE_GIF &&
- (img = shoes_surface_create_from_gif(RSTRING_PTR(imgpath), width, height, FALSE)) == SIZE_SURFACE)
- format = SHOES_IMAGE_GIF;
- }
-
- if (format == SHOES_IMAGE_NONE)
- {
- shoes_unsupported_image(imgpath);
- return format;
- }
+shoes_image_format shoes_image_detect(VALUE imgpath, int *width, int *height) {
+ shoes_image_format format = SHOES_IMAGE_NONE;
+ shoes_cached_image *cached = NULL;
+ cairo_surface_t *img = NULL;
+ VALUE filename = rb_funcall(imgpath, s_downcase, 0);
+ char *fname = RSTRING_PTR(filename);
+ int len = (int)RSTRING_LEN(filename);
+
+ if (shoes_cache_lookup(RSTRING_PTR(imgpath), &cached)) {
+ *width = cached->width;
+ *height = cached->height;
+ return cached->format;
+ }
- if (img != SIZE_SURFACE)
- shoes_failed_image(imgpath);
+ if (!shoes_check_file_exists(imgpath))
+ return SHOES_IMAGE_NONE;
+ else if (shoes_has_ext(fname, len, ".png")) {
+ img = shoes_png_size(RSTRING_PTR(imgpath), width, height);
+ format = SHOES_IMAGE_PNG;
+ } else if (shoes_has_ext(fname, len, ".jpg") || shoes_has_ext(fname, len, ".jpeg")) {
+ img = shoes_surface_create_from_jpeg(RSTRING_PTR(imgpath), width, height, FALSE);
+ format = SHOES_IMAGE_JPEG;
+ } else if (shoes_has_ext(fname, len, ".gif")) {
+ img = shoes_surface_create_from_gif(RSTRING_PTR(imgpath), width, height, FALSE);
+ format = SHOES_IMAGE_GIF;
+ }
+
+ if (img != SIZE_SURFACE) {
+ if (format != SHOES_IMAGE_PNG &&
+ (img = shoes_png_size(RSTRING_PTR(imgpath), width, height)) == SIZE_SURFACE)
+ format = SHOES_IMAGE_PNG;
+ else if (format != SHOES_IMAGE_JPEG &&
+ (img = shoes_surface_create_from_jpeg(RSTRING_PTR(imgpath), width, height, FALSE)) == SIZE_SURFACE)
+ format = SHOES_IMAGE_JPEG;
+ else if (format != SHOES_IMAGE_GIF &&
+ (img = shoes_surface_create_from_gif(RSTRING_PTR(imgpath), width, height, FALSE)) == SIZE_SURFACE)
+ format = SHOES_IMAGE_GIF;
+ }
+
+ if (format == SHOES_IMAGE_NONE) {
+ shoes_unsupported_image(imgpath);
+ return format;
+ }
+
+ if (img != SIZE_SURFACE)
+ shoes_failed_image(imgpath);
- return format;
+ return format;
}
-shoes_code
-shoes_load_imagesize(VALUE imgpath, int *width, int *height)
-{
- if (shoes_image_detect(imgpath, width, height) == SHOES_IMAGE_NONE)
- return SHOES_FAIL;
- return SHOES_OK;
+shoes_code shoes_load_imagesize(VALUE imgpath, int *width, int *height) {
+ if (shoes_image_detect(imgpath, width, height) == SHOES_IMAGE_NONE)
+ return SHOES_FAIL;
+ return SHOES_OK;
}
-unsigned char
-shoes_image_downloaded(shoes_image_download_event *idat)
-{
- int i, j, width, height;
- SHA1_CTX context;
- unsigned char *digest = SHOE_ALLOC_N(unsigned char, 20),
- *buffer = SHOE_ALLOC_N(unsigned char, 16384);
-
- if (idat->status == 304)
- {
- idat->filepath = idat->cachepath;
- idat->cachepath = NULL;
- }
- else if (idat->status != 200)
- {
- shoes_error("Shoes could not load the file at %s. [%lu]", idat->uripath, idat->status);
- return 0;
- }
-
- cairo_surface_t *img = shoes_surface_create_from_file(rb_str_new2(idat->filepath), &width, &height);
- if (img != NULL)
- {
- shoes_cached_image *cached;
- if (shoes_cache_lookup(idat->uripath, &cached) && cached->surface == shoes_world->blank_image)
- {
- cached->surface = img;
- cached->width = width;
- cached->height = height;
- cached->mtime = shoes_file_mtime(idat->filepath);
-
- if (idat->status != 304)
- {
+unsigned char shoes_image_downloaded(shoes_image_download_event *idat) {
+ int i, j, width, height;
+ SHA1_CTX context;
+ unsigned char *digest = SHOE_ALLOC_N(unsigned char, 20),
+ *buffer = SHOE_ALLOC_N(unsigned char, 16384);
+
+ if (idat->status == 304) {
+ idat->filepath = idat->cachepath;
+ idat->cachepath = NULL;
+ } else if (idat->status != 200) {
+ shoes_error("Shoes could not load the file at %s. [%lu]", idat->uripath, idat->status);
+ return 0;
+ }
+
+ cairo_surface_t *img = shoes_surface_create_from_file(rb_str_new2(idat->filepath), &width, &height);
+ if (img != NULL) {
+ shoes_cached_image *cached;
+ if (shoes_cache_lookup(idat->uripath, &cached) && cached->surface == shoes_world->blank_image) {
+ cached->surface = img;
+ cached->width = width;
+ cached->height = height;
+ cached->mtime = shoes_file_mtime(idat->filepath);
+
+ if (idat->status != 304) {
#ifdef SHOES_WIN32
- HANDLE hFile;
- hFile = CreateFile( idat->filepath, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
- SHA1Init(&context);
- DWORD readsize;
- while (1)
- {
- ReadFile( hFile, buffer, 16384, &readsize, NULL );
- if (readsize != 16384) break;
- SHA1Update(&context, buffer, readsize);
- }
- SHA1Final(digest, &context);
- CloseHandle( hFile );
+ HANDLE hFile;
+ hFile = CreateFile( idat->filepath, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
+ SHA1Init(&context);
+ DWORD readsize;
+ while (1) {
+ ReadFile( hFile, buffer, 16384, &readsize, NULL );
+ if (readsize != 16384) break;
+ SHA1Update(&context, buffer, readsize);
+ }
+ SHA1Final(digest, &context);
+ CloseHandle( hFile );
#else
- FILE* fp = fopen(idat->filepath, "rb");
- if (fp == NULL)
- {
- shoes_error("Shoes was unable to open the cached file at %s.", idat->filepath);
- return 0;
- }
- SHA1Init(&context);
- while (!feof(fp))
- {
- i = (int)fread(buffer, 1, 16384, fp);
- SHA1Update(&context, buffer, i);
- }
- SHA1Final(digest, &context);
- fclose(fp);
+ FILE* fp = fopen(idat->filepath, "rb");
+ if (fp == NULL) {
+ shoes_error("Shoes was unable to open the cached file at %s.", idat->filepath);
+ return 0;
+ }
+ SHA1Init(&context);
+ while (!feof(fp)) {
+ i = (int)fread(buffer, 1, 16384, fp);
+ SHA1Update(&context, buffer, i);
+ }
+ SHA1Final(digest, &context);
+ fclose(fp);
#endif
-
- for (i = 0; i < 5; i++)
- for (j = 0; j < 4; j++)
- sprintf(&idat->hexdigest[(i*8)+(j*2)], "%02x", digest[i*4+j]);
- idat->hexdigest[41] = '\0';
- }
+
+ for (i = 0; i < 5; i++)
+ for (j = 0; j < 4; j++)
+ sprintf(&idat->hexdigest[(i*8)+(j*2)], "%02x", digest[i*4+j]);
+ idat->hexdigest[41] = '\0';
+ }
+ }
}
- }
- SHOE_FREE(digest);
- SHOE_FREE(buffer);
- return 1;
+ SHOE_FREE(digest);
+ SHOE_FREE(buffer);
+ return 1;
}
-int
-shoes_http_image_handler(shoes_http_event *de, void *data)
-{
- shoes_image_download_event *idat = (shoes_image_download_event *)data;
- if (de->stage == SHOES_HTTP_STATUS)
- {
- idat->status = de->status;
- }
- else if (de->stage == SHOES_HTTP_HEADER)
- {
- if (de->hkeylen == 4 && strncmp(de->hkey, "ETag", 4) == 0 && de->hvallen > 0)
- {
- idat->etag = SHOE_ALLOC_N(char, de->hvallen + 1);
- SHOE_MEMCPY(idat->etag, de->hval, char, de->hvallen);
- idat->etag[de->hvallen] = '\0';
+int shoes_http_image_handler(shoes_http_event *de, void *data) {
+ shoes_image_download_event *idat = (shoes_image_download_event *)data;
+ if (de->stage == SHOES_HTTP_STATUS) {
+ idat->status = de->status;
+ } else if (de->stage == SHOES_HTTP_HEADER) {
+ if (de->hkeylen == 4 && strncmp(de->hkey, "ETag", 4) == 0 && de->hvallen > 0) {
+ idat->etag = SHOE_ALLOC_N(char, de->hvallen + 1);
+ SHOE_MEMCPY(idat->etag, de->hval, char, de->hvallen);
+ idat->etag[de->hvallen] = '\0';
+ }
+ } else if (de->stage == SHOES_HTTP_COMPLETED) {
+ shoes_image_download_event *side = SHOE_ALLOC(shoes_image_download_event);
+ SHOE_MEMCPY(side, idat, shoes_image_download_event, 1);
+ return shoes_throw_message(SHOES_IMAGE_DOWNLOAD, idat->slot, side);
}
- }
- else if (de->stage == SHOES_HTTP_COMPLETED)
- {
- shoes_image_download_event *side = SHOE_ALLOC(shoes_image_download_event);
- SHOE_MEMCPY(side, idat, shoes_image_download_event, 1);
- return shoes_throw_message(SHOES_IMAGE_DOWNLOAD, idat->slot, side);
- }
- return SHOES_DOWNLOAD_CONTINUE;
+ return SHOES_DOWNLOAD_CONTINUE;
}
-shoes_cached_image *
-shoes_load_image(VALUE slot, VALUE imgpath)
-{
- shoes_cached_image *cached = NULL;
- cairo_surface_t *img = NULL;
- VALUE filename = rb_funcall(imgpath, s_downcase, 0);
- StringValue(filename);
- char *fname = RSTRING_PTR(filename);
- int width = 1, height = 1;
-
- if (shoes_cache_lookup(RSTRING_PTR(imgpath), &cached))
- goto done;
-
- if (strlen(fname) > 7 && (strncmp(fname, "http://", 7) == 0 || strncmp(fname, "https://", 8) == 0))
- {
- struct timeval tv;
- VALUE cache, uext, hdrs, tmppath, uri, scheme, host, port, requ, path, cachepath = Qnil, hash = Qnil;
- rb_require("shoes/data");
- uri = rb_funcall(cShoes, rb_intern("uri"), 1, imgpath);
- scheme = rb_funcall(uri, s_scheme, 0);
- host = rb_funcall(uri, s_host, 0);
- port = rb_funcall(uri, s_port, 0);
- requ = rb_funcall(uri, s_request_uri, 0);
- path = rb_funcall(uri, s_path, 0);
- path = rb_funcall(path, s_downcase, 0);
-
- cache = rb_funcall(rb_const_get(rb_cObject, rb_intern("DATABASE")), rb_intern("check_cache_for"), 1, imgpath);
- uext = rb_funcall(rb_cFile, rb_intern("extname"), 1, path);
- hdrs = Qnil;
- if (!NIL_P(cache))
- {
- VALUE etag = rb_hash_aref(cache, ID2SYM(rb_intern("etag")));
- hash = rb_hash_aref(cache, ID2SYM(rb_intern("hash")));
- if (!NIL_P(hash)) cachepath = rb_funcall(cShoes, rb_intern("image_cache_path"), 2, hash, uext);
- int saved = NUM2INT(rb_hash_aref(cache, ID2SYM(rb_intern("saved"))));
- gettimeofday(&tv, 0);
- if (tv.tv_sec - saved < SHOES_IMAGE_EXPIRE)
- {
- cached = shoes_load_image(slot, cachepath);
- if (cached != NULL)
- {
- shoes_cache_insert(SHOES_CACHE_ALIAS, imgpath, cached);
- goto done;
+shoes_cached_image *shoes_load_image(VALUE slot, VALUE imgpath) {
+ shoes_cached_image *cached = NULL;
+ cairo_surface_t *img = NULL;
+ VALUE filename = rb_funcall(imgpath, s_downcase, 0);
+ StringValue(filename);
+ char *fname = RSTRING_PTR(filename);
+ int width = 1, height = 1;
+
+ if (shoes_cache_lookup(RSTRING_PTR(imgpath), &cached))
+ goto done;
+
+ if (strlen(fname) > 7 && (strncmp(fname, "http://", 7) == 0 || strncmp(fname, "https://", 8) == 0)) {
+ struct timeval tv;
+ VALUE cache, uext, hdrs, tmppath, uri, scheme, host, port, requ, path, cachepath = Qnil, hash = Qnil;
+ rb_require("shoes/data");
+ uri = rb_funcall(cShoes, rb_intern("uri"), 1, imgpath);
+ scheme = rb_funcall(uri, s_scheme, 0);
+ host = rb_funcall(uri, s_host, 0);
+ port = rb_funcall(uri, s_port, 0);
+ requ = rb_funcall(uri, s_request_uri, 0);
+ path = rb_funcall(uri, s_path, 0);
+ path = rb_funcall(path, s_downcase, 0);
+
+ cache = rb_funcall(rb_const_get(rb_cObject, rb_intern("DATABASE")), rb_intern("check_cache_for"), 1, imgpath);
+ uext = rb_funcall(rb_cFile, rb_intern("extname"), 1, path);
+ hdrs = Qnil;
+ if (!NIL_P(cache)) {
+ VALUE etag = rb_hash_aref(cache, ID2SYM(rb_intern("etag")));
+ hash = rb_hash_aref(cache, ID2SYM(rb_intern("hash")));
+ if (!NIL_P(hash)) cachepath = rb_funcall(cShoes, rb_intern("image_cache_path"), 2, hash, uext);
+ int saved = NUM2INT(rb_hash_aref(cache, ID2SYM(rb_intern("saved"))));
+ gettimeofday(&tv, 0);
+ if (tv.tv_sec - saved < SHOES_IMAGE_EXPIRE) {
+ cached = shoes_load_image(slot, cachepath);
+ if (cached != NULL) {
+ shoes_cache_insert(SHOES_CACHE_ALIAS, imgpath, cached);
+ goto done;
+ }
+ } else if (!NIL_P(etag))
+ rb_hash_aset(hdrs = rb_hash_new(), rb_str_new2("If-None-Match"), etag);
}
- }
- else if (!NIL_P(etag))
- rb_hash_aset(hdrs = rb_hash_new(), rb_str_new2("If-None-Match"), etag);
+
+ cached = shoes_cached_image_new(1, 1, shoes_world->blank_image);
+ shoes_cache_insert(SHOES_CACHE_FILE, imgpath, cached);
+ tmppath = rb_funcall(cShoes, rb_intern("image_temp_path"), 2, uri, uext);
+
+ shoes_http_request *req = SHOE_ALLOC(shoes_http_request);
+ SHOE_MEMZERO(req, shoes_http_request, 1);
+ shoes_image_download_event *idat = SHOE_ALLOC(shoes_image_download_event);
+ SHOE_MEMZERO(idat, shoes_image_download_event, 1);
+ req->url = strdup(RSTRING_PTR(imgpath));
+ req->scheme = strdup(RSTRING_PTR(scheme));
+ req->host = strdup(RSTRING_PTR(host));
+ req->port = NUM2INT(port);
+ req->path = strdup(RSTRING_PTR(requ));
+ req->handler = shoes_http_image_handler;
+ req->filepath = strdup(RSTRING_PTR(tmppath));
+ idat->filepath = strdup(RSTRING_PTR(tmppath));
+ idat->uripath = strdup(RSTRING_PTR(imgpath));
+ idat->slot = slot;
+ if (!NIL_P(cachepath)) idat->cachepath = strdup(RSTRING_PTR(cachepath));
+ if (!NIL_P(hash)) SHOE_MEMCPY(idat->hexdigest, RSTRING_PTR(hash), char, min(42, RSTRING_LEN(hash)));
+ if (!NIL_P(hdrs)) req->headers = shoes_http_headers(hdrs);
+ req->data = idat;
+ shoes_queue_download(req);
+ goto done;
}
- cached = shoes_cached_image_new(1, 1, shoes_world->blank_image);
- shoes_cache_insert(SHOES_CACHE_FILE, imgpath, cached);
- tmppath = rb_funcall(cShoes, rb_intern("image_temp_path"), 2, uri, uext);
-
- shoes_http_request *req = SHOE_ALLOC(shoes_http_request);
- SHOE_MEMZERO(req, shoes_http_request, 1);
- shoes_image_download_event *idat = SHOE_ALLOC(shoes_image_download_event);
- SHOE_MEMZERO(idat, shoes_image_download_event, 1);
- req->url = strdup(RSTRING_PTR(imgpath));
- req->scheme = strdup(RSTRING_PTR(scheme));
- req->host = strdup(RSTRING_PTR(host));
- req->port = NUM2INT(port);
- req->path = strdup(RSTRING_PTR(requ));
- req->handler = shoes_http_image_handler;
- req->filepath = strdup(RSTRING_PTR(tmppath));
- idat->filepath = strdup(RSTRING_PTR(tmppath));
- idat->uripath = strdup(RSTRING_PTR(imgpath));
- idat->slot = slot;
- if (!NIL_P(cachepath)) idat->cachepath = strdup(RSTRING_PTR(cachepath));
- if (!NIL_P(hash)) SHOE_MEMCPY(idat->hexdigest, RSTRING_PTR(hash), char, min(42, RSTRING_LEN(hash)));
- if (!NIL_P(hdrs)) req->headers = shoes_http_headers(hdrs);
- req->data = idat;
- shoes_queue_download(req);
- goto done;
- }
-
- img = shoes_surface_create_from_file(imgpath, &width, &height);
- if (img != shoes_world->blank_image)
- {
- cached = shoes_cached_image_new(width, height, img);
- shoes_cache_insert(SHOES_CACHE_FILE, imgpath, cached);
- }
+ img = shoes_surface_create_from_file(imgpath, &width, &height);
+ if (img != shoes_world->blank_image) {
+ cached = shoes_cached_image_new(width, height, img);
+ shoes_cache_insert(SHOES_CACHE_FILE, imgpath, cached);
+ }
done:
- if (cached == NULL)
- cached = shoes_world->blank_cache;
- return cached;
+ if (cached == NULL)
+ cached = shoes_world->blank_cache;
+ return cached;
}
diff --git a/shoes/internal.c b/shoes/internal.c
index 3615913d..fb788a13 100644
--- a/shoes/internal.c
+++ b/shoes/internal.c
@@ -8,39 +8,36 @@
#include
#include
-void odprintf(const char *format, ...)
-{
- char buf[4096], *p = buf;
- va_list args;
- int n;
+void odprintf(const char *format, ...) {
+ char buf[4096], *p = buf;
+ va_list args;
+ int n;
- va_start(args, format);
- n = _vsnprintf(p, sizeof buf - 3, format, args); // buf-3 is room for CR/LF/NUL
- va_end(args);
+ va_start(args, format);
+ n = _vsnprintf(p, sizeof buf - 3, format, args); // buf-3 is room for CR/LF/NUL
+ va_end(args);
- p += (n < 0) ? sizeof buf - 3 : n;
+ p += (n < 0) ? sizeof buf - 3 : n;
- while(p > buf && isspace(p[-1]))
- *--p = '\0';
+ while(p > buf && isspace(p[-1]))
+ *--p = '\0';
- *p++ = '\r';
- *p++ = '\n';
- *p = '\0';
+ *p++ = '\r';
+ *p++ = '\n';
+ *p = '\0';
- OutputDebugString(buf);
+ OutputDebugString(buf);
}
-int
-shoes_snprintf(char* str, size_t size, const char* format, ...)
-{
- size_t count;
- va_list args;
+int shoes_snprintf(char* str, size_t size, const char* format, ...) {
+ size_t count;
+ va_list args;
- va_start(args, format);
- count = _vscprintf(format, args);
- _vsnprintf(str, size, format, args);
- va_end(args);
+ va_start(args, format);
+ count = _vscprintf(format, args);
+ _vsnprintf(str, size, format, args);
+ va_end(args);
- return count;
+ return count;
}
#endif
diff --git a/shoes/internal.h b/shoes/internal.h
index 7fd6c902..1995b3fa 100644
--- a/shoes/internal.h
+++ b/shoes/internal.h
@@ -29,7 +29,7 @@
void odprintf(const char *format, ...);
static inline void odignore(const char *format, ...) {}
int shoes_snprintf(char* str, size_t size, const char* format, ...);
-#define PUTS odprintf
+#define PUTS odprintf
#ifdef DEBUG
#define INFO PUTS
diff --git a/bin/main.skel b/shoes/main.c
similarity index 98%
rename from bin/main.skel
rename to shoes/main.c
index dfd1cc92..8d33cfb3 100644
--- a/bin/main.skel
+++ b/shoes/main.c
@@ -3,7 +3,6 @@
// The generic launcher for Shoes.
//
#include
-#include "shoes/app.h"
#include "shoes/ruby.h"
#include "shoes/config.h"
#include "shoes/world.h"
@@ -44,7 +43,7 @@ main(argc, argv)
//char *cmdline = GetCommandLine();
//argv = CommandLineToArgvW(cmdline, &argc);
#endif
- %DEFAULTS%
+
#ifdef SHOES_WIN32
path = SHOE_ALLOC_N(char, SHOES_BUFSIZE);
@@ -99,6 +98,7 @@ main(argc, argv)
}
#endif
#ifdef SHOES_QUARTZ
+ int osx_cshoes_launch = 0;
if (argc > 1 && strcmp(argv[1], "--osx") == 0)
{
// only the cshoes script sets this flag. An open -a launch will not.
diff --git a/shoes/native/cocoa.h b/shoes/native/cocoa.h
index 90fe2931..09bee432 100644
--- a/shoes/native/cocoa.h
+++ b/shoes/native/cocoa.h
@@ -86,6 +86,20 @@
}
@end
+@interface ShoesSwitch : NSButton
+{
+ VALUE object;
+}
+@end
+
+@interface ShoesSpinner : NSProgressIndicator
+{
+ VALUE object;
+@public
+ BOOL state;
+}
+@end
+
@interface ShoesDialogAsk : NSWindow
{
NSWindow *win;
@@ -107,6 +121,8 @@
NSTimer *timer;
}
@end
+@interface ShoesNotifyDelegate : NSObject
+@end
// declares to stop compiler whining
void add_to_menubar(NSMenu *main, NSMenu *menu);
diff --git a/shoes/native/cocoa.m b/shoes/native/cocoa.m
index c5f2c8f8..08da111c 100644
--- a/shoes/native/cocoa.m
+++ b/shoes/native/cocoa.m
@@ -6,9 +6,9 @@
#include "shoes/ruby.h"
#include "shoes/config.h"
#include "shoes/world.h"
-#include "shoes/native.h"
-#include "shoes/internal.h"
-#include "shoes/http.h"
+#include "shoes/native/native.h"
+#include "shoes/types/types.h"
+extern VALUE cTimer;
#import
@@ -593,6 +593,17 @@ -(IBAction)handleChange: (id)sender
}
@end
+@implementation ShoesNotifyDelegate
+- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
+{
+ [[NSUserNotificationCenter defaultUserNotificationCenter] setDelegate:self];
+}
+
+- (BOOL)userNotificationCenter:(NSUserNotificationCenter *)center shouldPresentNotification:(NSUserNotification *)notification{
+ return YES;
+}
+@end
+
@implementation ShoesDialogAsk
- (id)init
{
@@ -1018,7 +1029,7 @@ void shoes_native_remove_item(SHOES_SLOT_OS *slot, VALUE item, char c)
}
void
-shoes_native_app_resized(shoes_app *app)
+shoes_native_app_resize_window(shoes_app *app)
{
NSRect rect = [app->os.window frame];
rect.size.width = app->width;
@@ -1288,6 +1299,7 @@ - (void)invalidate
@end
+
void
shoes_native_canvas_oneshot(int ms, VALUE canvas)
{
@@ -1364,6 +1376,8 @@ - (void)invalidate
ShoesTextView *sv = (ShoesTextView *)ref;
NSTextView *tv = sv->textView;
[tv setEditable: setting];
+ } else if ([ref isKindOfClass: [NSProgressIndicator class]]) {
+ // not really a control
} else {
fprintf(stderr, "control is unknown type\n");
}
@@ -1437,8 +1451,7 @@ - (void)invalidate
}
-SHOES_CONTROL_REF
-shoes_native_button(VALUE self, shoes_canvas *canvas, shoes_place *place, char *msg)
+SHOES_CONTROL_REF shoes_native_button(VALUE self, shoes_canvas *canvas, shoes_place *place, VALUE attr, char *msg)
{
INIT;
ShoesButton *button = [[ShoesButton alloc] initWithType: NSMomentaryPushInButton
@@ -1492,6 +1505,11 @@ - (void)invalidate
return Qnil;
}
+void
+shoes_native_edit_box_set_text(SHOES_CONTROL_REF ref, char *msg)
+{
+ COCOA_DO([[[(ShoesTextView *)ref textStorage] mutableString] setString: [NSString stringWithUTF8String: msg]]);
+}
SHOES_CONTROL_REF
shoes_native_edit_box(VALUE self, shoes_canvas *canvas, shoes_place *place, VALUE attr, char *msg)
@@ -1501,7 +1519,8 @@ - (void)invalidate
NSMakeRect(place->ix + place->dx, place->iy + place->dy,
place->ix + place->dx + place->iw, place->iy + place->dy + place->ih)
andObject: self];
- shoes_native_edit_box_set_text((NSControl *)tv, msg);
+ //shoes_native_edit_box_set_text((NSControl *)tv, msg);
+ shoes_native_edit_box_set_text((SHOES_CONTROL_REF )tv, msg);
RELEASE;
return (NSControl *)tv;
}
@@ -1516,11 +1535,6 @@ - (void)invalidate
return text;
}
-void
-shoes_native_edit_box_set_text(SHOES_CONTROL_REF ref, char *msg)
-{
- COCOA_DO([[[(ShoesTextView *)ref textStorage] mutableString] setString: [NSString stringWithUTF8String: msg]]);
-}
void
shoes_native_edit_box_append(SHOES_CONTROL_REF ref, char *msg)
@@ -1537,21 +1551,28 @@ - (void)invalidate
}
// text_edit_box is new in 3.2.25
+void
+shoes_native_text_view_set_text(SHOES_CONTROL_REF ref, char *msg)
+{
+ COCOA_DO([[[(ShoesTextEditView *)ref textStorage] mutableString] setString: [NSString stringWithUTF8String: msg]]);
+}
+
SHOES_CONTROL_REF
-shoes_native_text_edit_box(VALUE self, shoes_canvas *canvas, shoes_place *place, VALUE attr, char *msg)
+shoes_native_text_view(VALUE self, shoes_canvas *canvas, shoes_place *place, VALUE attr, char *msg)
{
INIT;
ShoesTextEditView *tv = [[ShoesTextEditView alloc] initWithFrame:
NSMakeRect(place->ix + place->dx, place->iy + place->dy,
place->ix + place->dx + place->iw, place->iy + place->dy + place->ih)
andObject: self];
- shoes_native_text_edit_box_set_text((NSControl *)tv, msg);
+ //shoes_native_text_view_set_text((NSControl *)tv, msg);
+ shoes_native_text_view_set_text((SHOES_CONTROL_REF)tv, msg);
RELEASE;
return (NSControl *)tv;
}
VALUE
-shoes_native_text_edit_box_get_text(SHOES_CONTROL_REF ref)
+shoes_native_text_view_get_text(SHOES_CONTROL_REF ref)
{
VALUE text = Qnil;
INIT;
@@ -1560,14 +1581,9 @@ - (void)invalidate
return text;
}
-void
-shoes_native_text_edit_box_set_text(SHOES_CONTROL_REF ref, char *msg)
-{
- COCOA_DO([[[(ShoesTextEditView *)ref textStorage] mutableString] setString: [NSString stringWithUTF8String: msg]]);
-}
VALUE
-shoes_native_text_edit_box_append(SHOES_CONTROL_REF ref, char *msg)
+shoes_native_text_view_append(SHOES_CONTROL_REF ref, char *msg)
{
COCOA_DO([[[(ShoesTextEditView *)ref textStorage] mutableString] appendString: [NSString stringWithUTF8String: msg]]);
#ifdef dontwant
@@ -1781,6 +1797,18 @@ - (void)invalidate
return shoes_color_new(255, 255, 255, 255);
}
+
+void shoes_native_systray(char *title, char *message, char *path)
+{
+ NSUserNotification *notification = [[NSUserNotification alloc] init];
+ notification.title = [NSString stringWithUTF8String: title];
+ notification.informativeText = [NSString stringWithUTF8String: message];
+ notification.soundName = NSUserNotificationDefaultSoundName;
+ notification.contentImage = [[NSImage alloc] initWithContentsOfFile: [NSString stringWithUTF8String: path]];
+ [[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:notification];
+}
+
+
VALUE
shoes_native_dialog_color(shoes_app *app)
{
@@ -2171,3 +2199,171 @@ - (BOOL)accepted
});
return path;
}
+
+/*
+ New with 3.3.3: switch, spinner widgets, opacity, decoraation and tooltips.
+ TODO: Fix No-op - they can crash
+*/
+
+/*
+ * ---- tooltips ----
+ * are a property of NSView - damn near everything in osx but we might
+ * want to make sure it's a SHOES_CONTROL_REF/shoes-widget.
+*/
+void shoes_native_control_set_tooltip(SHOES_CONTROL_REF ref, VALUE tooltip)
+{
+ NSView *view = (NSView *)ref;
+ view.toolTip = [NSString stringWithUTF8String: RSTRING_PTR(tooltip)];
+
+}
+
+VALUE shoes_native_control_get_tooltip(SHOES_CONTROL_REF ref) {
+ NSView *view = (NSView *)ref;
+ return rb_str_new2((char *)view.toolTip);
+}
+
+/*
+ * ---- spinner ----
+ * subclass NSProgressIndicator for better control. Sadly, this is not a cocoa control
+ * so it can't be first class Shoes control
+*/
+
+@implementation ShoesSpinner
+- (id)initWithAnObject: (VALUE)o
+{
+ if ((self = [super init]))
+ {
+ object = o;
+ self.indeterminate = true;
+ [self setStyle: NSProgressIndicatorSpinningStyle];
+ [self setBezeled: true];
+ }
+ return self;
+}
+
+@end
+
+void shoes_native_spinner_start(SHOES_CONTROL_REF ref)
+{
+ ShoesSpinner *spin = (ShoesSpinner *)ref;
+ spin->state = true;
+ [spin startAnimation: (id)ref];
+}
+void shoes_native_spinner_stop(SHOES_CONTROL_REF ref)
+{
+ ShoesSpinner *spin = (ShoesSpinner *)ref;
+ spin->state = false;
+ [spin stopAnimation: (id)ref];
+}
+
+int shoes_native_spinner_started(SHOES_CONTROL_REF ref)
+{
+ ShoesSpinner *spin = (ShoesSpinner *)ref;
+ return spin->state;
+}
+
+
+SHOES_CONTROL_REF shoes_native_spinner(VALUE self, shoes_canvas *canvas, shoes_place *place, VALUE attr, char *msg)
+{
+ ShoesSpinner *spin = [[ShoesSpinner alloc] initWithAnObject: self];
+ spin->state = false;
+ if (!NIL_P(shoes_hash_get(attr, rb_intern("start")))) {
+ spin->state = (Qtrue == shoes_hash_get(attr, rb_intern("start"))) ? true: false;
+ }
+ if (spin->state == true)
+ shoes_native_spinner_start((SHOES_CONTROL_REF)spin);
+ else
+ shoes_native_spinner_stop((SHOES_CONTROL_REF)spin);
+ return (SHOES_CONTROL_REF) spin;
+}
+
+
+
+/*
+ * ---- switch ----
+ * subclass NSButton and see what it looks like as ToggleButton
+ * needs it own action handlers
+*/
+@implementation ShoesSwitch
+- (id)initWithType: (NSButtonType)t andObject: (VALUE)o
+{
+ if ((self = [super init]))
+ {
+ object = o;
+ [self setButtonType: t];
+ [self setBezelStyle: NSRoundedBezelStyle];
+ [self setTarget: self];
+ [self setAction: @selector(handleClick:)];
+ [self setState: NSOffState];
+ //sw_state = 0;
+ }
+ return self;
+}
+-(IBAction)handleClick: (id)sender
+{
+ //fprintf(stderr, "handler: %li\n", [self state]);
+ //sw_state = sw_state ^ 1;
+ //fprintf(stderr, "h after: %li\n", [self state]);
+ shoes_control_send(object, s_active);
+}
+@end
+
+SHOES_CONTROL_REF
+shoes_native_switch(VALUE self, shoes_canvas *canvas, shoes_place *place, VALUE attr, char *msg)
+{
+ INIT;
+ ShoesSwitch *button = [[ShoesSwitch alloc] initWithType: NSToggleButton
+ andObject: self];
+ [button setTitle: @"Off"];
+ [button setAlternateTitle: @"On"];
+ if (!NIL_P(shoes_hash_get(attr, rb_intern("active")))) {
+ VALUE bstv = shoes_hash_get(attr, rb_intern("active"));
+ button.state = !NIL_P(bstv) ? NSOnState : NSOffState;
+ //fprintf(stderr, "have a initial active %li\n",button.state);
+ }
+ //button->sw_state = button.state; //property -> instance_var
+ RELEASE;
+ return (SHOES_CONTROL_REF) button;
+}
+
+void shoes_native_switch_set_active(SHOES_CONTROL_REF ref, int activate)
+{
+ ShoesSwitch *button = (ShoesSwitch *)ref;
+ //fprintf(stderr, "Set_active = %i\n", activate);
+ NSInteger bst = activate ? NSOnState : NSOffState;
+ [button setState: bst];
+}
+
+VALUE
+shoes_native_switch_get_active(SHOES_CONTROL_REF ref)
+{
+ ShoesSwitch *button = (ShoesSwitch *)ref;
+ //fprintf(stderr, "get_active -> %li\n", [button state]);
+ return [button state] ? Qtrue : Qfalse;
+}
+
+// ---- opacity ----
+double shoes_native_app_get_opacity(shoes_app *app)
+{
+ NSWindow *win = (NSWindow *)app->os.window;
+ return [win alphaValue];
+}
+
+void shoes_native_app_set_opacity(shoes_app *app, double opacity)
+{
+ NSWindow *win = (NSWindow *)app->os.window;
+ [win setAlphaValue: opacity];
+}
+
+
+
+// ---- decoration remove title bar, resize controls ----
+void shoes_native_app_set_decoration(shoes_app *app, gboolean decorated)
+{
+}
+
+int shoes_native_app_get_decoration(shoes_app *app)
+{
+ return true;
+}
+
diff --git a/shoes/native/gtk.c b/shoes/native/gtk.c
index bafe0400..75ff8ed7 100644
--- a/shoes/native/gtk.c
+++ b/shoes/native/gtk.c
@@ -4,14 +4,19 @@
// Modified for Gtk-3.0 by Cecil Coupe (cjc)
//
#ifndef GTK3
-// fail only used for shoes_native_window_color will be deleted
-#define GTK3
-#endif
+// fail only used for shoes_native_window_color will be deleted
+#define GTK3
+#endif
#include "shoes/app.h"
#include "shoes/ruby.h"
#include "shoes/config.h"
#include "shoes/world.h"
-#include "shoes/native.h"
+#include "shoes/native/native.h"
+#include "shoes/types/native.h"
+#include "shoes/types/color.h"
+#include "shoes/types/text.h"
+#include "shoes/types/text_link.h"
+#include "shoes/types/download.h"
#include "shoes/internal.h"
#include
@@ -23,604 +28,531 @@
#include
#include
-#include "gtkfixedalt.h"
-#include "gtkentryalt.h"
-#include "gtkcomboboxtextalt.h"
-#include "gtkbuttonalt.h"
-#include "gtkscrolledwindowalt.h"
-#include "gtkprogressbaralt.h"
-#include "shoes/video/video.h"
-
-#define GTK_CHILD(child, ptr) \
- GList *children = gtk_container_get_children(GTK_CONTAINER(ptr)); \
- child = children->data
+#include "gtk.h"
+#include "shoes/native/gtk/gtkfixedalt.h"
+#include "shoes/native/gtk/gtkentryalt.h"
+#include "shoes/native/gtk/gtkcomboboxtextalt.h"
+#include "shoes/native/gtk/gtkbuttonalt.h"
+#include "shoes/native/gtk/gtkscrolledwindowalt.h"
+#include "shoes/native/gtk/gtkprogressbaralt.h"
#define HEIGHT_PAD 0
#define SHOES_GTK_INVISIBLE_CHAR (gunichar)0x2022
#ifndef SHOES_GTK_WIN32
-static VALUE
-shoes_make_font_list(FcFontSet *fonts, VALUE ary)
-{
- int i = 0;
- for (i = 0; i < fonts->nfont; i++)
- {
- FcValue val;
- FcPattern *p = fonts->fonts[i];
- if (FcPatternGet(p, FC_FAMILY, 0, &val) == FcResultMatch)
- rb_ary_push(ary, rb_str_new2((char *)val.u.s));
- }
- rb_funcall(ary, rb_intern("uniq!"), 0);
- rb_funcall(ary, rb_intern("sort!"), 0);
- return ary;
-}
-
-VALUE
-shoes_font_list()
-{
- VALUE ary = rb_ary_new();
- FcConfig *fc = FcConfigGetCurrent();
- FcFontSet *fonts = FcConfigGetFonts(fc, FcSetApplication);
- if (fonts) shoes_make_font_list(fonts, ary);
- fonts = FcConfigGetFonts(fc, FcSetSystem);
- if (fonts) shoes_make_font_list(fonts, ary);
- return ary;
+static VALUE shoes_make_font_list(FcFontSet *fonts, VALUE ary) {
+ int i = 0;
+ for (i = 0; i < fonts->nfont; i++) {
+ FcValue val;
+ FcPattern *p = fonts->fonts[i];
+ if (FcPatternGet(p, FC_FAMILY, 0, &val) == FcResultMatch)
+ rb_ary_push(ary, rb_str_new2((char *)val.u.s));
+ }
+ rb_funcall(ary, rb_intern("uniq!"), 0);
+ rb_funcall(ary, rb_intern("sort!"), 0);
+ return ary;
}
-VALUE
-shoes_load_font(const char *filename)
-{
- FcConfig *fc = FcConfigGetCurrent();
- FcFontSet *fonts = FcFontSetCreate();
- if (!FcFileScan(fonts, NULL, NULL, NULL, (const FcChar8 *)filename, FcTrue))
- return Qnil;
-
- VALUE ary = rb_ary_new();
- shoes_make_font_list(fonts, ary);
- FcFontSetDestroy(fonts);
-
- if (!FcConfigAppFontAddFile(fc, (const FcChar8 *)filename))
- return Qnil;
-
- // refresh the FONTS list
- shoes_update_fonts(shoes_font_list());
- return ary;
+VALUE shoes_font_list() {
+ VALUE ary = rb_ary_new();
+ FcConfig *fc = FcConfigGetCurrent();
+ FcFontSet *fonts = FcConfigGetFonts(fc, FcSetApplication);
+ if (fonts) shoes_make_font_list(fonts, ary);
+ fonts = FcConfigGetFonts(fc, FcSetSystem);
+ if (fonts) shoes_make_font_list(fonts, ary);
+ return ary;
}
-#endif
-
-#if 0
-// FIXME: experiment with font settings
-// Borrowed from http://ricardo.ecn.wfu.edu/~cottrell/gtk_win32/
-#ifdef G_OS_WIN32
-static char appfontname[128] = "sans-serif 12"; /* fallback value */
-#else
-static char appfontname[128] = "Sans-Serif 10"; // gtk doc says 'Sans 10'
-#endif
-
-void set_app_font (const char *fontname)
-{
- GtkSettings *settings;
- gchar *themedir;
- gchar *themename;
- if (fontname != NULL && *fontname == 0) return;
+VALUE shoes_load_font(const char *filename) {
+ FcConfig *fc = FcConfigGetCurrent();
+ FcFontSet *fonts = FcFontSetCreate();
+ if (!FcFileScan(fonts, NULL, NULL, NULL, (const FcChar8 *)filename, FcTrue))
+ return Qnil;
- settings = gtk_settings_get_default();
- themedir = gtk_rc_get_theme_dir ();
- g_object_get(settings, "gtk-theme-name", &themename, NULL);
- printf("dir=%s, name: %s\n", themedir,themename);
+ VALUE ary = rb_ary_new();
+ shoes_make_font_list(fonts, ary);
+ FcFontSetDestroy(fonts);
+ if (!FcConfigAppFontAddFile(fc, (const FcChar8 *)filename))
+ return Qnil;
- if (fontname == NULL) {
- g_object_set(G_OBJECT(settings), "gtk-font-name", appfontname, NULL);
- } else {
- GtkWidget *w;
- PangoFontDescription *pfd;
- PangoContext *pc;
- PangoFont *pfont;
+ // refresh the FONTS list
+ shoes_update_fonts(shoes_font_list());
+ return ary;
+}
+#endif
- w = gtk_label_new(NULL);
- pfd = pango_font_description_from_string(fontname);
- pc = gtk_widget_get_pango_context(w);
- pfont = pango_context_load_font(pc, pfd);
+/*
+ * Shoes 3.3.4 uses gtk_application_new (aka GApplication) instead of gtk_init
+*/
- if (pfont != NULL) {
- strcpy(appfontname, fontname);
- g_object_set(G_OBJECT(settings), "gtk-font-name", appfontname, NULL);
- }
+#if 0 // not used
+void
+shoes_gtk_app_activate (GApplication *app, gpointer user_data) {
+ fprintf(stderr, "shoes_gtk_app_activate called\n");
+}
- gtk_widget_destroy(w);
- pango_font_description_free(pfd);
- }
+void shoes_gtk_app_open (GApplication *app, GFile **files,
+ gint n_files, gchar *hint) {
+ fprintf(stderr, "shoes_gtk_app_open called\n");
}
+#endif
-void shoes_native_print_env()
+gboolean
+shoes_gtk_app_cmdline (GApplication *application, gchar ***arguments,
+ gint *exit_status)
{
- GtkSettings *settings;
- gchar *themedir;
- gchar *themename;
-
- gchar *rcfile = "shoesgtk.rc";
- //gchar *rcfiles[] = {rcfile, NULL};
- gchar **defs;
- //gtk_rc_set_default_files(rcfiles);
- //gtk_rc_parse(rcfile);
- //printf("ask theme = %s\n", rcfile);
- defs = gtk_rc_get_default_files ();
- int i = 0;
- while ((rcfile = defs[i]) != NULL) {
- printf("%d: %s\n", i+1, rcfile);
- i++;
- }
- settings = gtk_settings_get_default();
- themedir = gtk_rc_get_theme_dir ();
- g_object_get(settings, "gtk-theme-name", &themename, NULL);
- printf("dir=%s, name: %s\n", themedir,themename);
+ /* This doesn't seem to work as documented.
+ * *exit_status is 0x0 instead of a real pointer, arguments don't seem
+ * correct either. For Shoes it doesn't matter. Just tell gtk we processed
+ * them so it doesn't have too. Need to do this for Gtk/Windows which has the
+ * documented habit of reading the commandline twice
+ */
+ return TRUE;
}
-#endif
-void shoes_native_init()
-{
+void shoes_native_init() {
#if !defined(RUBY_HTTP) && !defined(SHOES_GTK_WIN32)
- curl_global_init(CURL_GLOBAL_ALL);
+ curl_global_init(CURL_GLOBAL_ALL);
#endif
- gtk_init(NULL, NULL);
- //set_app_font(NULL); // experiment failed
- //shoes_native_print_env();
+ /* using linux gtk_application_new() instead of
+ * // Shoes <= 3.3.3
+ * gtk_init(NULL, NULL);
+ */
+ int status;
+ GtkApplication *shoes_GtkApp;
+ shoes_GtkApp = gtk_application_new ("com.mvmanila.shoes", G_APPLICATION_HANDLES_COMMAND_LINE);
+
+ g_signal_connect (shoes_GtkApp, "command-line", G_CALLBACK (shoes_gtk_app_cmdline), NULL);
+ status = g_application_run (G_APPLICATION (shoes_GtkApp), NULL, NULL);
}
-void shoes_native_cleanup(shoes_world_t *world)
-{
+/* end of GApplication init */
+
+void shoes_native_cleanup(shoes_world_t *world) {
#if !defined(RUBY_HTTP) && !defined(SHOES_GTK_WIN32)
- curl_global_cleanup();
+ curl_global_cleanup();
#endif
}
-void shoes_native_quit()
-{
- gtk_main_quit();
+void shoes_native_quit() {
+ gtk_main_quit();
}
#ifdef SHOES_GTK_WIN32
-int
-shoes_win32_cmdvector(const char *cmdline, char ***argv)
-{
+int shoes_win32_cmdvector(const char *cmdline, char ***argv) {
// return rb_w32_cmdvector(cmdline, argv);
- return 0; // TODO: delete this function.
+ return 0; // TODO: delete this function.
}
-void shoes_get_time(SHOES_TIME *ts)
-{
- *ts = g_get_monotonic_time(); // Should work for GTK3 w/o win32
+void shoes_get_time(SHOES_TIME *ts) {
+ *ts = g_get_monotonic_time(); // Should work for GTK3 w/o win32
}
-unsigned long shoes_diff_time(SHOES_TIME *start, SHOES_TIME *end)
-{
- return *end - *start;
+unsigned long shoes_diff_time(SHOES_TIME *start, SHOES_TIME *end) {
+ return *end - *start;
}
#else
-void shoes_get_time(SHOES_TIME *ts)
-{
+void shoes_get_time(SHOES_TIME *ts) {
#ifdef SHOES_GTK_OSX
- gettimeofday(ts, NULL);
+ gettimeofday(ts, NULL);
#else
- clock_gettime(CLOCK_REALTIME, ts);
+ clock_gettime(CLOCK_REALTIME, ts);
#endif
}
-unsigned long shoes_diff_time(SHOES_TIME *start, SHOES_TIME *end)
-{
- unsigned long usec;
- if ((end->tv_nsec-start->tv_nsec)<0) {
- usec = (end->tv_sec-start->tv_sec - 1) * 1000;
- usec += (1000000000 + end->tv_nsec - start->tv_nsec) / 1000000;
- } else {
- usec = (end->tv_sec - start->tv_sec) * 1000;
- usec += (end->tv_nsec - start->tv_nsec) / 1000000;
- }
- return usec;
+unsigned long shoes_diff_time(SHOES_TIME *start, SHOES_TIME *end) {
+ unsigned long usec;
+ if ((end->tv_nsec-start->tv_nsec)<0) {
+ usec = (end->tv_sec-start->tv_sec - 1) * 1000;
+ usec += (1000000000 + end->tv_nsec - start->tv_nsec) / 1000000;
+ } else {
+ usec = (end->tv_sec - start->tv_sec) * 1000;
+ usec += (end->tv_nsec - start->tv_nsec) / 1000000;
+ }
+ return usec;
}
#endif
typedef struct {
- unsigned int name;
- VALUE obj;
- void *data;
- pthread_mutex_t mutex;
- pthread_cond_t cond;
- int ret;
+ unsigned int name;
+ VALUE obj;
+ void *data;
+ pthread_mutex_t mutex;
+ pthread_cond_t cond;
+ int ret;
} shoes_gtk_msg;
-static gboolean
-shoes_gtk_catch_message(gpointer user) {
- shoes_gtk_msg *msg = (shoes_gtk_msg *)user;
- pthread_mutex_lock(&msg->mutex);
- msg->ret = shoes_catch_message(msg->name, msg->obj, msg->data);
- pthread_cond_signal(&msg->cond);
- pthread_mutex_unlock(&msg->mutex);
- return FALSE;
+static gboolean shoes_gtk_catch_message(gpointer user) {
+ shoes_gtk_msg *msg = (shoes_gtk_msg *)user;
+ pthread_mutex_lock(&msg->mutex);
+ msg->ret = shoes_catch_message(msg->name, msg->obj, msg->data);
+ pthread_cond_signal(&msg->cond);
+ pthread_mutex_unlock(&msg->mutex);
+ return FALSE;
}
// Only called by image.c
-int shoes_throw_message(unsigned int name, VALUE obj, void *data)
-{
- int ret;
- shoes_gtk_msg *msg = SHOE_ALLOC(shoes_gtk_msg);
- msg->name = name;
- msg->obj = obj;
- msg->data = data;
- pthread_mutex_init(&msg->mutex, NULL);
- pthread_cond_init(&msg->cond, NULL);
- msg->ret = 0;
-
- pthread_mutex_lock(&msg->mutex);
- g_idle_add_full(G_PRIORITY_DEFAULT, shoes_gtk_catch_message, msg, NULL);
- pthread_cond_wait(&msg->cond, &msg->mutex);
- ret = msg->ret;
- pthread_mutex_unlock(&msg->mutex);
-
- free(msg);
- return ret;
+int shoes_throw_message(unsigned int name, VALUE obj, void *data) {
+ int ret;
+ shoes_gtk_msg *msg = SHOE_ALLOC(shoes_gtk_msg);
+ msg->name = name;
+ msg->obj = obj;
+ msg->data = data;
+ pthread_mutex_init(&msg->mutex, NULL);
+ pthread_cond_init(&msg->cond, NULL);
+ msg->ret = 0;
+
+ pthread_mutex_lock(&msg->mutex);
+ g_idle_add_full(G_PRIORITY_DEFAULT, shoes_gtk_catch_message, msg, NULL);
+ pthread_cond_wait(&msg->cond, &msg->mutex);
+ ret = msg->ret;
+ pthread_mutex_unlock(&msg->mutex);
+
+ free(msg);
+ return ret;
}
void shoes_native_slot_mark(SHOES_SLOT_OS *slot) {}
void shoes_native_slot_reset(SHOES_SLOT_OS *slot) {}
-void shoes_native_slot_clear(shoes_canvas *canvas)
-{
- if (canvas->slot->vscroll)
- {
- GtkAdjustment *adj = gtk_range_get_adjustment(GTK_RANGE(canvas->slot->vscroll));
- gtk_adjustment_set_value(adj, gtk_adjustment_get_lower(adj));
- }
+void shoes_native_slot_clear(shoes_canvas *canvas) {
+ if (canvas->slot->vscroll) {
+ GtkAdjustment *adj = gtk_range_get_adjustment(GTK_RANGE(canvas->slot->vscroll));
+ gtk_adjustment_set_value(adj, gtk_adjustment_get_lower(adj));
+ }
}
-void shoes_native_slot_paint(SHOES_SLOT_OS *slot)
-{
- gtk_widget_queue_draw(slot->oscanvas);
+void shoes_native_slot_paint(SHOES_SLOT_OS *slot) {
+ gtk_widget_queue_draw(slot->oscanvas);
}
-void shoes_native_slot_lengthen(SHOES_SLOT_OS *slot, int height, int endy)
-{
- if (slot->vscroll)
- {
- GtkAdjustment *adj = gtk_range_get_adjustment(GTK_RANGE(slot->vscroll));
- if (gtk_adjustment_get_upper(adj) != (gdouble)endy)
- {
- gtk_range_set_range(GTK_RANGE(slot->vscroll), 0., (gdouble)endy);
-
- if (gtk_adjustment_get_page_size(adj) >= gtk_adjustment_get_upper(adj))
- gtk_widget_hide(slot->vscroll);
- else
- gtk_widget_show(slot->vscroll);
+void shoes_native_slot_lengthen(SHOES_SLOT_OS *slot, int height, int endy) {
+ if (slot->vscroll) {
+ GtkAdjustment *adj = gtk_range_get_adjustment(GTK_RANGE(slot->vscroll));
+ if (gtk_adjustment_get_upper(adj) != (gdouble)endy) {
+ gtk_range_set_range(GTK_RANGE(slot->vscroll), 0., (gdouble)endy);
+
+ if (gtk_adjustment_get_page_size(adj) >= gtk_adjustment_get_upper(adj))
+ gtk_widget_hide(slot->vscroll);
+ else
+ gtk_widget_show(slot->vscroll);
+ }
}
- }
}
-void shoes_native_slot_scroll_top(SHOES_SLOT_OS *slot)
-{
- if (slot->vscroll)
- gtk_range_set_value(GTK_RANGE(slot->vscroll), slot->scrolly);
+void shoes_native_slot_scroll_top(SHOES_SLOT_OS *slot) {
+ if (slot->vscroll)
+ gtk_range_set_value(GTK_RANGE(slot->vscroll), slot->scrolly);
}
-int shoes_native_slot_gutter(SHOES_SLOT_OS *slot)
-{
- if (slot->vscroll)
- {
- GtkRequisition rnat;
- gtk_widget_get_preferred_size(slot->vscroll, NULL, &rnat);
- return rnat.width;
- }
- return 0;
+int shoes_native_slot_gutter(SHOES_SLOT_OS *slot) {
+ if (slot->vscroll) {
+ GtkRequisition rnat;
+ gtk_widget_get_preferred_size(slot->vscroll, NULL, &rnat);
+ return rnat.width;
+ }
+ return 0;
}
-void shoes_native_remove_item(SHOES_SLOT_OS *slot, VALUE item, char c)
-{
+void shoes_native_remove_item(SHOES_SLOT_OS *slot, VALUE item, char c) {
}
//
// Window-level events
//
-static gboolean
-shoes_app_gtk_motion(GtkWidget *widget, GdkEventMotion *event, gpointer data)
-{
- GdkModifierType state;
- shoes_app *app = (shoes_app *)data;
- if (!event->is_hint)
- {
+static gboolean shoes_app_gtk_motion(GtkWidget *widget, GdkEventMotion *event, gpointer data) {
+ GdkModifierType state;
+ shoes_app *app = (shoes_app *)data;
+ if (!event->is_hint) {
+ shoes_canvas *canvas;
+ Data_Get_Struct(app->canvas, shoes_canvas, canvas);
+ state = (GdkModifierType)event->state;
+ shoes_app_motion(app, (int)event->x, (int)event->y + canvas->slot->scrolly);
+ }
+ return TRUE;
+}
+#ifdef NEWCLICK
+static gboolean shoes_app_gtk_button(GtkWidget *widget, GdkEventButton *event, gpointer data) {
+ shoes_app *app = (shoes_app *)data;
shoes_canvas *canvas;
Data_Get_Struct(app->canvas, shoes_canvas, canvas);
- state = (GdkModifierType)event->state;
- shoes_app_motion(app, (int)event->x, (int)event->y + canvas->slot->scrolly);
- }
- return TRUE;
+
+ int x, y;
+ GdkModifierType state;
+
+ gdk_window_get_device_position(gtk_widget_get_window(widget), event->device, &x, &y, &state);
+
+ if (event->type == GDK_BUTTON_PRESS) {
+ shoes_app_click(app, event->button, x, y);
+ } else if (event->type == GDK_BUTTON_RELEASE) {
+ shoes_app_release(app, event->button, x, y);
+ }
+ return TRUE;
}
-
-static gboolean
-shoes_app_gtk_button(GtkWidget *widget, GdkEventButton *event, gpointer data)
-{
- shoes_app *app = (shoes_app *)data;
- shoes_canvas *canvas;
- Data_Get_Struct(app->canvas, shoes_canvas, canvas);
- if (event->type == GDK_BUTTON_PRESS)
- {
- shoes_app_click(app, event->button, event->x, event->y + canvas->slot->scrolly);
- }
- else if (event->type == GDK_BUTTON_RELEASE)
- {
- shoes_app_release(app, event->button, event->x, event->y + canvas->slot->scrolly);
- }
- return TRUE;
+#else
+static gboolean shoes_app_gtk_button(GtkWidget *widget, GdkEventButton *event, gpointer data) {
+ shoes_app *app = (shoes_app *)data;
+ shoes_canvas *canvas;
+ Data_Get_Struct(app->canvas, shoes_canvas, canvas);
+ if (event->type == GDK_BUTTON_PRESS) {
+ shoes_app_click(app, event->button, event->x, event->y + canvas->slot->scrolly);
+ } else if (event->type == GDK_BUTTON_RELEASE) {
+ shoes_app_release(app, event->button, event->x, event->y + canvas->slot->scrolly);
+ }
+ return TRUE;
}
+#endif
-static gboolean
-shoes_app_gtk_wheel(GtkWidget *widget, GdkEventScroll *event, gpointer data)
-{
- ID wheel;
- shoes_app *app = (shoes_app *)data;
-
- switch (event->direction)
- {
- case GDK_SCROLL_UP: wheel = s_up; break;
- case GDK_SCROLL_DOWN: wheel = s_down; break;
- case GDK_SCROLL_LEFT: wheel = s_left; break;
- case GDK_SCROLL_RIGHT: wheel = s_right; break;
- default: return TRUE;
- }
-
- shoes_app_wheel(app, wheel, event->x, event->y);
- return TRUE;
+static gboolean shoes_app_gtk_wheel(GtkWidget *widget, GdkEventScroll *event, gpointer data) {
+ ID wheel;
+ shoes_app *app = (shoes_app *)data;
+
+ switch (event->direction) {
+ case GDK_SCROLL_UP:
+ wheel = s_up;
+ break;
+ case GDK_SCROLL_DOWN:
+ wheel = s_down;
+ break;
+ case GDK_SCROLL_LEFT:
+ wheel = s_left;
+ break;
+ case GDK_SCROLL_RIGHT:
+ wheel = s_right;
+ break;
+ default:
+ return TRUE;
+ }
+
+ shoes_app_wheel(app, wheel, event->x, event->y);
+ return TRUE;
}
-static void
-shoes_app_gtk_paint(GtkWidget *widget, cairo_t *cr, gpointer data)
-{
- shoes_app *app = (shoes_app *)data;
- gtk_window_get_size(GTK_WINDOW(app->os.window), &app->width, &app->height);
- shoes_canvas_size(app->canvas, app->width, app->height);
+static void shoes_app_gtk_paint(GtkWidget *widget, cairo_t *cr, gpointer data) {
+ shoes_app *app = (shoes_app *)data;
+ gtk_window_get_size(GTK_WINDOW(app->os.window), &app->width, &app->height);
+ shoes_canvas_size(app->canvas, app->width, app->height);
}
#define KEY_SYM(name, sym) \
else if (event->keyval == GDK_KEY_##name) \
v = ID2SYM(rb_intern("" # sym))
-static gboolean
-shoes_app_gtk_keypress(GtkWidget *widget, GdkEventKey *event, gpointer data)
-{
- VALUE v = Qnil;
- guint modifiers = event->state;
- shoes_app *app = (shoes_app *)data;
- if (event->keyval == GDK_KEY_Return)
- {
- v = rb_str_new2("\n");
- }
- KEY_SYM(BackSpace, backspace); // GTK3 has length of 1. Go figure.
- KEY_SYM(Escape, escape);
- else if (event->length > 0)
- {
- if ((event->state & GDK_CONTROL_MASK) || (event->state & GDK_MOD1_MASK))
- {
- gint len;
- gunichar ch;
- char chbuf[7] = {0};
-
- ch = gdk_keyval_to_unicode(event->keyval);
- len = g_unichar_to_utf8(ch, chbuf);
- chbuf[len] = '\0';
-
- v = ID2SYM(rb_intern(chbuf));
- if (modifiers & GDK_SHIFT_MASK) modifiers ^= GDK_SHIFT_MASK;
- }
- else
- {
- if (event->string[0] == '\r' && event->length == 1)
+static gboolean shoes_app_gtk_keypress(GtkWidget *widget, GdkEventKey *event, gpointer data) {
+ VALUE v = Qnil;
+ guint modifiers = event->state;
+ shoes_app *app = (shoes_app *)data;
+ if (event->keyval == GDK_KEY_Return) {
v = rb_str_new2("\n");
- else
- v = rb_str_new(event->string, event->length);
}
- }
- KEY_SYM(Insert, insert);
- KEY_SYM(Delete, delete);
- KEY_SYM(Tab, tab);
- KEY_SYM(ISO_Left_Tab, tab);
- KEY_SYM(Page_Up, page_up);
- KEY_SYM(Page_Down, page_down);
- KEY_SYM(Home, home);
- KEY_SYM(End, end);
- KEY_SYM(Left, left);
- KEY_SYM(Up, up);
- KEY_SYM(Right, right);
- KEY_SYM(Down, down);
- KEY_SYM(F1, f1);
- KEY_SYM(F2, f2);
- KEY_SYM(F3, f3);
- KEY_SYM(F4, f4);
- KEY_SYM(F5, f5);
- KEY_SYM(F6, f6);
- KEY_SYM(F7, f7);
- KEY_SYM(F8, f8);
- KEY_SYM(F9, f9);
- KEY_SYM(F10, f10);
- KEY_SYM(F11, f11);
- KEY_SYM(F12, f12);
-
- if (v != Qnil) {
- if (event->type == GDK_KEY_PRESS) {
- shoes_app_keydown(app, v);
-
- if (event->keyval == GDK_KEY_Return)
- if ((event->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK | GDK_MOD1_MASK)) != 0)
- v = ID2SYM(rb_intern("enter"));
-
- if (SYMBOL_P(v))
- {
- if (modifiers & GDK_MOD1_MASK)
- KEY_STATE(alt);
- if (modifiers & GDK_SHIFT_MASK)
- KEY_STATE(shift);
- if (modifiers & GDK_CONTROL_MASK)
- KEY_STATE(control);
- }
-
- shoes_app_keypress(app, v);
- } else {
- shoes_app_keyup(app, v);
+ KEY_SYM(BackSpace, backspace); // GTK3 has length of 1. Go figure.
+ KEY_SYM(Escape, escape);
+ else if (event->length > 0) {
+ if ((event->state & GDK_CONTROL_MASK) || (event->state & GDK_MOD1_MASK)) {
+ gint len;
+ gunichar ch;
+ char chbuf[7] = {0};
+
+ ch = gdk_keyval_to_unicode(event->keyval);
+ len = g_unichar_to_utf8(ch, chbuf);
+ chbuf[len] = '\0';
+
+ v = ID2SYM(rb_intern(chbuf));
+ if (modifiers & GDK_SHIFT_MASK) modifiers ^= GDK_SHIFT_MASK;
+ } else {
+ if (event->string[0] == '\r' && event->length == 1)
+ v = rb_str_new2("\n");
+ else
+ v = rb_str_new(event->string, event->length);
+ }
+ }
+ KEY_SYM(Insert, insert);
+ KEY_SYM(Delete, delete);
+ KEY_SYM(Tab, tab);
+ KEY_SYM(ISO_Left_Tab, tab);
+ KEY_SYM(Page_Up, page_up);
+ KEY_SYM(Page_Down, page_down);
+ KEY_SYM(Home, home);
+ KEY_SYM(End, end);
+ KEY_SYM(Left, left);
+ KEY_SYM(Up, up);
+ KEY_SYM(Right, right);
+ KEY_SYM(Down, down);
+ KEY_SYM(F1, f1);
+ KEY_SYM(F2, f2);
+ KEY_SYM(F3, f3);
+ KEY_SYM(F4, f4);
+ KEY_SYM(F5, f5);
+ KEY_SYM(F6, f6);
+ KEY_SYM(F7, f7);
+ KEY_SYM(F8, f8);
+ KEY_SYM(F9, f9);
+ KEY_SYM(F10, f10);
+ KEY_SYM(F11, f11);
+ KEY_SYM(F12, f12);
+
+ if (v != Qnil) {
+ if (event->type == GDK_KEY_PRESS) {
+ shoes_app_keydown(app, v);
+
+ if (event->keyval == GDK_KEY_Return)
+ if ((event->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK | GDK_MOD1_MASK)) != 0)
+ v = ID2SYM(rb_intern("enter"));
+
+ if (SYMBOL_P(v)) {
+ if (modifiers & GDK_MOD1_MASK)
+ KEY_STATE(alt);
+ if (modifiers & GDK_SHIFT_MASK)
+ KEY_STATE(shift);
+ if (modifiers & GDK_CONTROL_MASK)
+ KEY_STATE(control);
+ }
+
+ shoes_app_keypress(app, v);
+ } else {
+ shoes_app_keyup(app, v);
+ }
}
- }
- return FALSE;
+ return FALSE;
}
-static gboolean
-shoes_app_gtk_quit(GtkWidget *widget, GdkEvent *event, gpointer data)
-{
- shoes_app *app = (shoes_app *)data;
- if (shoes_app_remove(app))
- gtk_main_quit();
- return FALSE;
+static gboolean shoes_app_gtk_quit(GtkWidget *widget, GdkEvent *event, gpointer data) {
+ shoes_app *app = (shoes_app *)data;
+ if (shoes_app_remove(app))
+ gtk_main_quit();
+ return FALSE;
}
-static void
-shoes_canvas_gtk_paint_children(GtkWidget *widget, gpointer data)
-{
- shoes_canvas *canvas = (shoes_canvas *)data;
- gtk_container_propagate_draw(GTK_CONTAINER(canvas->slot->oscanvas), widget,
- canvas->slot->drawevent);
+static void shoes_canvas_gtk_paint_children(GtkWidget *widget, gpointer data) {
+ shoes_canvas *canvas = (shoes_canvas *)data;
+ gtk_container_propagate_draw(GTK_CONTAINER(canvas->slot->oscanvas), widget,
+ canvas->slot->drawevent);
}
-static void
-shoes_canvas_gtk_paint(GtkWidget *widget, cairo_t *cr, gpointer data)
-{
- VALUE c = (VALUE)data;
- shoes_canvas *canvas;
- Data_Get_Struct(c, shoes_canvas, canvas);
- canvas->slot->drawevent = cr; // stash it for the children
-
- // getting widget dirty area, already clipped
- cairo_rectangle_int_t rect;
- gdk_cairo_get_clip_rectangle(cr, &rect);
-
- shoes_canvas_paint(c);
- // Gtk3 doc says gtk_container_foreach is preferable over gtk_container_forall
- gtk_container_foreach(GTK_CONTAINER(widget), shoes_canvas_gtk_paint_children, canvas);
-
- canvas->slot->drawevent = NULL;
-}
-
-static void
-shoes_canvas_gtk_size(GtkWidget *widget, GtkAllocation *size, gpointer data)
-{
- VALUE c = (VALUE)data;
- shoes_canvas *canvas;
- Data_Get_Struct(c, shoes_canvas, canvas);
- if (canvas->slot->vscroll &&
- (size->height != canvas->slot->scrollh || size->width != canvas->slot->scrollw))
- {
- GtkAdjustment *adj = gtk_range_get_adjustment(GTK_RANGE(canvas->slot->vscroll));
- gtk_widget_set_size_request(canvas->slot->vscroll, -1, size->height);
-
- //gtk_widget_set_size_request(GTK_CONTAINER(widget), canvas->app->width, size->height);
-
- GtkAllocation alloc;
- gtk_widget_get_allocation((GtkWidget *)canvas->slot->vscroll, &alloc);
- gtk_fixed_move(GTK_FIXED(canvas->slot->oscanvas), canvas->slot->vscroll,
- size->width - alloc.width, 0);
- gtk_adjustment_set_page_size(adj, size->height);
- gtk_adjustment_set_page_increment(adj, size->height - 32);
-
- if (gtk_adjustment_get_page_size(adj) >= gtk_adjustment_get_upper(adj))
- gtk_widget_hide(canvas->slot->vscroll);
- else
- gtk_widget_show(canvas->slot->vscroll);
+static void shoes_canvas_gtk_paint(GtkWidget *widget, cairo_t *cr, gpointer data) {
+ VALUE c = (VALUE)data;
+ shoes_canvas *canvas;
+ Data_Get_Struct(c, shoes_canvas, canvas);
+ canvas->slot->drawevent = cr; // stash it for the children
+
+ // getting widget dirty area, already clipped
+ cairo_rectangle_int_t rect;
+ gdk_cairo_get_clip_rectangle(cr, &rect);
- canvas->slot->scrollh = size->height;
- canvas->slot->scrollw = size->width;
- }
+ shoes_canvas_paint(c);
+ // Gtk3 doc says gtk_container_foreach is preferable over gtk_container_forall
+ gtk_container_foreach(GTK_CONTAINER(widget), shoes_canvas_gtk_paint_children, canvas);
+
+ canvas->slot->drawevent = NULL;
}
-static void
-shoes_canvas_gtk_scroll(GtkRange *r, gpointer data)
-{
- VALUE c = (VALUE)data;
- shoes_canvas *canvas;
- Data_Get_Struct(c, shoes_canvas, canvas);
- canvas->slot->scrolly = (int)gtk_range_get_value(r);
- shoes_slot_repaint(canvas->app->slot);
+static void shoes_canvas_gtk_size(GtkWidget *widget, GtkAllocation *size, gpointer data) {
+ VALUE c = (VALUE)data;
+ shoes_canvas *canvas;
+ Data_Get_Struct(c, shoes_canvas, canvas);
+ if (canvas->slot->vscroll &&
+ (size->height != canvas->slot->scrollh || size->width != canvas->slot->scrollw)) {
+ GtkAdjustment *adj = gtk_range_get_adjustment(GTK_RANGE(canvas->slot->vscroll));
+ gtk_widget_set_size_request(canvas->slot->vscroll, -1, size->height);
+
+ //gtk_widget_set_size_request(GTK_CONTAINER(widget), canvas->app->width, size->height);
+
+ GtkAllocation alloc;
+ gtk_widget_get_allocation((GtkWidget *)canvas->slot->vscroll, &alloc);
+ gtk_fixed_move(GTK_FIXED(canvas->slot->oscanvas), canvas->slot->vscroll,
+ size->width - alloc.width, 0);
+ gtk_adjustment_set_page_size(adj, size->height);
+ gtk_adjustment_set_page_increment(adj, size->height - 32);
+
+ if (gtk_adjustment_get_page_size(adj) >= gtk_adjustment_get_upper(adj))
+ gtk_widget_hide(canvas->slot->vscroll);
+ else
+ gtk_widget_show(canvas->slot->vscroll);
+
+ canvas->slot->scrollh = size->height;
+ canvas->slot->scrollw = size->width;
+ }
+}
+
+static void shoes_canvas_gtk_scroll(GtkRange *r, gpointer data) {
+ VALUE c = (VALUE)data;
+ shoes_canvas *canvas;
+ Data_Get_Struct(c, shoes_canvas, canvas);
+ canvas->slot->scrolly = (int)gtk_range_get_value(r);
+ shoes_slot_repaint(canvas->app->slot);
}
+// TODO: remove dead code? warning: 'shoes_app_g_poll' defined but not used
#ifndef SHOES_GTK_WIN32
-static gint
-shoes_app_g_poll(GPollFD *fds, guint nfds, gint timeout)
-{
- struct timeval tv;
-
- rb_fdset_t rset, wset, xset;
- GPollFD *f;
- int ready;
- int maxfd = 0;
-
- rb_fd_init(&rset); // was FD_ZERO()
- rb_fd_init(&wset);
- rb_fd_init(&xset);
-
- for (f = fds; f < &fds[nfds]; ++f)
- if (f->fd >= 0)
- {
- if (f->events & G_IO_IN)
- //FD_SET (f->fd, &rset);
- rb_fd_set(f->fd, &rset);
- if (f->events & G_IO_OUT)
- //FD_SET (f->fd, &wset);
- rb_fd_set(f->fd, &wset);
- if (f->events & G_IO_PRI)
- //FD_SET (f->fd, &xset);
- rb_fd_set(f->fd, &xset);
- if (f->fd > maxfd && (f->events & (G_IO_IN|G_IO_OUT|G_IO_PRI)))
- maxfd = f->fd;
- }
-
- //
- // If we poll indefinitely, then the window updates will
- // pile up for as long as Ruby is churning away.
- //
- // Give Ruby half-seconds in which to work, in order to
- // keep it from completely blocking the GUI.
- //
- // cjc: timeout appears to be in millisecs.
- if (timeout == -1 || timeout > 500)
- timeout = 500;
-
- tv.tv_sec = timeout / 1000;
- tv.tv_usec = (timeout % 1000) * 1000;
-
- ready = rb_thread_fd_select (maxfd + 1, &rset, &wset, &xset, &tv);
- if (ready > 0)
- // I think the idea here is that the Ruby threads might cause Gtk events
- // and that's supposed to pass back in the f->revents
- // Does Ruby/Windows execute this code more often or incorrectly?
- for (f = fds; f < &fds[nfds]; ++f)
- {
- f->revents = 0;
- if (f->fd >= 0)
- {
- //if (FD_ISSET (f->fd, &rset))
- if (rb_fd_isset (f->fd, &rset))
- f->revents |= G_IO_IN;
- //if (FD_ISSET (f->fd, &wset))
- if (rb_fd_isset (f->fd, &wset))
- f->revents |= G_IO_OUT;
- //if (FD_ISSET (f->fd, &xset))
- if (rb_fd_isset (f->fd, &xset))
- f->revents |= G_IO_PRI;
- }
- }
- // Free the allocated storage from rb_fd_init
- rb_fd_term(&rset);
- rb_fd_term(&wset);
- rb_fd_term(&xset);
- return ready;
+static gint shoes_app_g_poll(GPollFD *fds, guint nfds, gint timeout) {
+ struct timeval tv;
+
+ rb_fdset_t rset, wset, xset;
+ GPollFD *f;
+ int ready;
+ int maxfd = 0;
+
+ rb_fd_init(&rset); // was FD_ZERO()
+ rb_fd_init(&wset);
+ rb_fd_init(&xset);
+
+ for (f = fds; f < &fds[nfds]; ++f)
+ if (f->fd >= 0) {
+ if (f->events & G_IO_IN)
+ //FD_SET (f->fd, &rset);
+ rb_fd_set(f->fd, &rset);
+ if (f->events & G_IO_OUT)
+ //FD_SET (f->fd, &wset);
+ rb_fd_set(f->fd, &wset);
+ if (f->events & G_IO_PRI)
+ //FD_SET (f->fd, &xset);
+ rb_fd_set(f->fd, &xset);
+ if (f->fd > maxfd && (f->events & (G_IO_IN|G_IO_OUT|G_IO_PRI)))
+ maxfd = f->fd;
+ }
+
+ //
+ // If we poll indefinitely, then the window updates will
+ // pile up for as long as Ruby is churning away.
+ //
+ // Give Ruby half-seconds in which to work, in order to
+ // keep it from completely blocking the GUI.
+ //
+ // cjc: timeout appears to be in millisecs.
+ if (timeout == -1 || timeout > 500)
+ timeout = 500;
+
+ tv.tv_sec = timeout / 1000;
+ tv.tv_usec = (timeout % 1000) * 1000;
+
+ ready = rb_thread_fd_select (maxfd + 1, &rset, &wset, &xset, &tv);
+ if (ready > 0)
+ // I think the idea here is that the Ruby threads might cause Gtk events
+ // and that's supposed to pass back in the f->revents
+ // Does Ruby/Windows execute this code more often or incorrectly?
+ for (f = fds; f < &fds[nfds]; ++f) {
+ f->revents = 0;
+ if (f->fd >= 0) {
+ //if (FD_ISSET (f->fd, &rset))
+ if (rb_fd_isset (f->fd, &rset))
+ f->revents |= G_IO_IN;
+ //if (FD_ISSET (f->fd, &wset))
+ if (rb_fd_isset (f->fd, &wset))
+ f->revents |= G_IO_OUT;
+ //if (FD_ISSET (f->fd, &xset))
+ if (rb_fd_isset (f->fd, &xset))
+ f->revents |= G_IO_PRI;
+ }
+ }
+ // Free the allocated storage from rb_fd_init
+ rb_fd_term(&rset);
+ rb_fd_term(&wset);
+ rb_fd_term(&xset);
+ return ready;
}
#else
/*
@@ -630,222 +562,219 @@ shoes_app_g_poll(GPollFD *fds, guint nfds, gint timeout)
* run a poll/select on the Gtk fds
* and return that number.
*/
+/*
+static gint shoes_app_g_poll(GPollFD *fds, guint nfds, gint timeout) {
+ struct timeval tv;
+ rb_fdset_t rset, wset, xset; //ruby
+ GPollFD *f;
+ int ready;
+ int maxfd = 0;
-static gint
-shoes_app_g_poll(GPollFD *fds, guint nfds, gint timeout)
-{
- struct timeval tv;
- rb_fdset_t rset, wset, xset; //ruby
- GPollFD *f;
- int ready;
- int maxfd = 0;
-
-
-
- rb_fd_init(&rset); // These are ruby rd (sets
- rb_fd_init(&wset);
- rb_fd_init(&xset);
-
- int i;
- // On Windows GTK GPollFD.fd could be a handle, not a small int.
- for (i = 0; i < nfds; i++)
- {
- f = &fds[i];
- if (f->fd >= 0)
- {
- if (f->events & G_IO_IN)
- rb_fd_set(f->fd, &rset);
- if (f->events & G_IO_OUT)
- rb_fd_set (f->fd, &wset);
- if (f->events & G_IO_PRI)
- rb_fd_set (f->fd, &xset);
- // if (f->fd > maxfd && (f->events & (G_IO_IN|G_IO_OUT|G_IO_PRI)))
- // maxfd = f->fd;
- if (i > maxfd && (f->events & (G_IO_IN|G_IO_OUT|G_IO_PRI)))
- maxfd = i;
+ rb_fd_init(&rset); // These are ruby rd (sets
+ rb_fd_init(&wset);
+ rb_fd_init(&xset);
+
+ int i;
+ // On Windows GTK GPollFD.fd could be a handle, not a small int.
+ for (i = 0; i < nfds; i++) {
+ f = &fds[i];
+ if (f->fd >= 0) {
+ if (f->events & G_IO_IN)
+ rb_fd_set(f->fd, &rset);
+ if (f->events & G_IO_OUT)
+ rb_fd_set (f->fd, &wset);
+ if (f->events & G_IO_PRI)
+ rb_fd_set (f->fd, &xset);
+ // if (f->fd > maxfd && (f->events & (G_IO_IN|G_IO_OUT|G_IO_PRI)))
+ // maxfd = f->fd;
+ if (i > maxfd && (f->events & (G_IO_IN|G_IO_OUT|G_IO_PRI)))
+ maxfd = i;
+ }
+ }
+ //
+ // If we poll indefinitely, then the window updates will
+ // pile up for as long as Ruby is churning away.
+ //
+ // Give Ruby half-seconds in which to work, in order to
+ // keep it from completely blocking the GUI.
+ //
+ if (timeout == -1 || timeout > 500)
+ timeout = 500;
+
+ tv.tv_sec = timeout / 1000;
+ tv.tv_usec = (timeout % 1000) * 1000;
+
+ ready = rb_fd_select (maxfd + 1, &rset, &wset, &xset, &tv); // NOT deprecated in 2.1.0
+ int really_ready = 0;
+ if (ready == 0) {
+ for (f = fds; f < &fds[nfds]; ++f) {
+ f->revents = 0;
+ if (f->fd >= 0) {
+ if (rb_fd_isset (f->fd, &rset))
+ f->revents |= G_IO_IN;
+ if (rb_fd_isset (f->fd, &wset))
+ f->revents |= G_IO_OUT;
+ if (rb_fd_isset (f->fd, &xset))
+ f->revents |= G_IO_PRI;
+ if (f->revents > 0) really_ready++;
+ }
+ }
+ }
+
+ rb_fd_term(&rset);
+ rb_fd_term(&wset);
+ rb_fd_term(&xset);
+ if (ready < 0) {
+ printf("Poll fail %d\n", errno);
+ ready = 0;
+ }
+ if (ready != really_ready) {
+ printf("R %d. RR %d\n", ready, really_ready);
+ ready = really_ready;
}
- }
- //
- // If we poll indefinitely, then the window updates will
- // pile up for as long as Ruby is churning away.
- //
- // Give Ruby half-seconds in which to work, in order to
- // keep it from completely blocking the GUI.
- //
- if (timeout == -1 || timeout > 500)
- timeout = 500;
-
- tv.tv_sec = timeout / 1000;
- tv.tv_usec = (timeout % 1000) * 1000;
-
- ready = rb_fd_select (maxfd + 1, &rset, &wset, &xset, &tv); // NOT deprecated in 2.1.0
- int really_ready = 0;
- if (ready == 0)
- {
- for (f = fds; f < &fds[nfds]; ++f)
- {
- f->revents = 0;
- if (f->fd >= 0)
- {
- if (rb_fd_isset (f->fd, &rset))
- f->revents |= G_IO_IN;
- if (rb_fd_isset (f->fd, &wset))
- f->revents |= G_IO_OUT;
- if (rb_fd_isset (f->fd, &xset))
- f->revents |= G_IO_PRI;
- if (f->revents > 0) really_ready++;
- }
- }
- }
-
- rb_fd_term(&rset);
- rb_fd_term(&wset);
- rb_fd_term(&xset);
- if (ready < 0)
- {
- printf("Poll fail %d\n", errno);
- ready = 0;
- }
- if (ready != really_ready)
- {
- printf("R %d. RR %d\n", ready, really_ready);
- ready = really_ready;
- }
- return ready;
+ return ready;
}
+*/
#endif
-shoes_code
-shoes_app_cursor(shoes_app *app, ID cursor)
-{
- if (app->os.window == NULL || gtk_widget_get_window(app->os.window)== NULL || app->cursor == cursor)
- goto done;
-
- GdkCursor *c;
- if (cursor == s_hand || cursor == s_link)
- {
- c = gdk_cursor_new(GDK_HAND2);
- }
- else if (cursor == s_arrow)
- {
- c = gdk_cursor_new(GDK_ARROW);
- }
- else if (cursor == s_text)
- {
- c = gdk_cursor_new(GDK_XTERM);
- }
- else
- goto done;
-
- gdk_window_set_cursor(gtk_widget_get_window(app->os.window), c);
- app->cursor = cursor;
+shoes_code shoes_app_cursor(shoes_app *app, ID cursor) {
+ if (app->os.window == NULL || gtk_widget_get_window(app->os.window)== NULL || app->cursor == cursor)
+ goto done;
+
+ GdkCursor *c;
+ if (cursor == s_hand || cursor == s_link) {
+ c = gdk_cursor_new(GDK_HAND2);
+ } else if (cursor == s_arrow) {
+ c = gdk_cursor_new(GDK_ARROW);
+ } else if (cursor == s_text) {
+ c = gdk_cursor_new(GDK_XTERM);
+ } else
+ goto done;
+
+ gdk_window_set_cursor(gtk_widget_get_window(app->os.window), c);
+ app->cursor = cursor;
done:
- return SHOES_OK;
+ return SHOES_OK;
}
-void
-shoes_native_app_resized(shoes_app *app)
-{
- // Not needed anymore ?
- // if (app->os.window != NULL)
- // gtk_widget_set_size_request(app->os.window, app->width, app->height);
+void shoes_native_app_title(shoes_app *app, char *msg) {
+ gtk_window_set_title(GTK_WINDOW(app->os.window), _(msg));
}
-void
-shoes_native_app_title(shoes_app *app, char *msg)
-{
- gtk_window_set_title(GTK_WINDOW(app->os.window), _(msg));
+void shoes_native_app_resize_window(shoes_app *app) {
+ if ((app->os.window != NULL) && (app->width > 0 && app->height > 0)) {
+ gtk_widget_set_size_request(GTK_WINDOW(app->os.window), app->width, app->height);
+ }
}
-void
-shoes_native_app_fullscreen(shoes_app *app, char yn)
-{
- gtk_window_set_keep_above(GTK_WINDOW(app->os.window), (gboolean)yn);
- if (yn)
- gtk_window_fullscreen(GTK_WINDOW(app->os.window));
- else
- gtk_window_unfullscreen(GTK_WINDOW(app->os.window));
+void shoes_native_app_fullscreen(shoes_app *app, char yn) {
+ gtk_window_set_keep_above(GTK_WINDOW(app->os.window), (gboolean)yn);
+ if (yn)
+ gtk_window_fullscreen(GTK_WINDOW(app->os.window));
+ else
+ gtk_window_unfullscreen(GTK_WINDOW(app->os.window));
}
// new in 3.2.19
-void
-shoes_native_app_set_icon(shoes_app *app, char *icon_path)
-{
- // replace default icon
- gboolean err;
- err = gtk_window_set_icon_from_file((GtkWindow *) app->slot->oscanvas, icon_path, NULL);
- err = gtk_window_set_default_icon_from_file(icon_path, NULL);
+void shoes_native_app_set_icon(shoes_app *app, char *icon_path) {
+ // replace default icon
+ gboolean err;
+ err = gtk_window_set_icon_from_file((GtkWindow *) app->slot->oscanvas, icon_path, NULL);
+ err = gtk_window_set_default_icon_from_file(icon_path, NULL);
}
// new in 3.2.19
-void shoes_native_app_set_wtitle(shoes_app *app, char *wtitle)
-{
- gtk_window_set_title(GTK_WINDOW(app->slot->oscanvas), _(wtitle));
+void shoes_native_app_set_wtitle(shoes_app *app, char *wtitle) {
+ gtk_window_set_title(GTK_WINDOW(app->slot->oscanvas), _(wtitle));
}
-shoes_code
-shoes_native_app_open(shoes_app *app, char *path, int dialog)
-{
- char icon_path[SHOES_BUFSIZE];
- shoes_app_gtk *gk = &app->os;
+// new in 3.3.3 - opacity -uses the deprecated
+void shoes_native_app_set_opacity(shoes_app *app, double opacity) {
+// if (gtk_get_minor_version() >= 8)
+// gtk_widget_set_opacity(GTK_WIDGET(app->os.window), opacity);
+// else
+ gtk_window_set_opacity(GTK_WINDOW(app->os.window), opacity);
+}
+
+double shoes_native_app_get_opacity(shoes_app *app) {
+// if (gtk_get_minor_version() >= 8)
+// return gtk_widget_get_opacity(GTK_WIDGET(app->os.window));
+// else
+ return gtk_window_get_opacity(GTK_WINDOW(app->os.window));
+}
+
+void shoes_native_app_set_decoration(shoes_app *app, gboolean decorated) {
+ gtk_window_set_decorated(GTK_WINDOW(app->os.window), decorated);
+}
+
+int shoes_native_app_get_decoration(shoes_app *app) {
+ return gtk_window_get_decorated(GTK_WINDOW(app->os.window)) == TRUE;
+}
+
+shoes_code shoes_native_app_open(shoes_app *app, char *path, int dialog) {
#if !defined(SHOES_GTK_WIN32)
- sprintf(icon_path, "%s/static/app-icon.png", shoes_world->path);
- gtk_window_set_default_icon_from_file(icon_path, NULL);
+ char icon_path[SHOES_BUFSIZE];
#endif
- gk->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
- gtk_window_set_position(GTK_WINDOW(gk->window), GTK_WIN_POS_CENTER);
- // commit https://github.com/shoes/shoes/commit/4e7982ddcc8713298b6959804dab8d20111c0038
- if (!app->resizable)
- {
- gtk_widget_set_size_request(gk->window, app->width, app->height);
- gtk_window_set_resizable(GTK_WINDOW(gk->window), FALSE);
- }
- else if (app->minwidth < app->width || app->minheight < app->height)
- {
- GdkGeometry hints;
- hints.min_width = app->minwidth;
- hints.min_height = app->minheight;
- gtk_window_set_geometry_hints(GTK_WINDOW(gk->window), gk->window,
- &hints, GDK_HINT_MIN_SIZE);
- }
- gtk_window_set_default_size(GTK_WINDOW(gk->window), app->width, app->height);
-
- if (app->fullscreen) shoes_native_app_fullscreen(app, 1);
-
- gtk_widget_set_events(gk->window, GDK_POINTER_MOTION_MASK | GDK_SCROLL_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
- g_signal_connect(G_OBJECT(gk->window), "size-allocate",
- G_CALLBACK(shoes_app_gtk_paint), app);
- g_signal_connect(G_OBJECT(gk->window), "motion-notify-event",
- G_CALLBACK(shoes_app_gtk_motion), app);
- g_signal_connect(G_OBJECT(gk->window), "button-press-event",
- G_CALLBACK(shoes_app_gtk_button), app);
- g_signal_connect(G_OBJECT(gk->window), "button-release-event",
- G_CALLBACK(shoes_app_gtk_button), app);
- g_signal_connect(G_OBJECT(gk->window), "scroll-event",
- G_CALLBACK(shoes_app_gtk_wheel), app);
- g_signal_connect(G_OBJECT(gk->window), "key-press-event",
- G_CALLBACK(shoes_app_gtk_keypress), app);
- g_signal_connect(G_OBJECT(gk->window), "key-release-event",
- G_CALLBACK(shoes_app_gtk_keypress), app);
- g_signal_connect(G_OBJECT(gk->window), "delete-event",
- G_CALLBACK(shoes_app_gtk_quit), app);
-
- app->slot->oscanvas = gk->window;
- return SHOES_OK;
-}
-void
-shoes_native_app_show(shoes_app *app)
-{
- gtk_widget_show_all(app->os.window);
+ shoes_app_gtk *gk = &app->os;
+
+#if !defined(SHOES_GTK_WIN32)
+ sprintf(icon_path, "%s/static/app-icon.png", shoes_world->path);
+ gtk_window_set_default_icon_from_file(icon_path, NULL);
+#endif
+ gk->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_position(GTK_WINDOW(gk->window), GTK_WIN_POS_CENTER);
+ // commit https://github.com/shoes/shoes/commit/4e7982ddcc8713298b6959804dab8d20111c0038
+ if (!app->resizable) {
+ gtk_widget_set_size_request(gk->window, app->width, app->height);
+ gtk_window_set_resizable(GTK_WINDOW(gk->window), FALSE);
+ } else if (app->minwidth < app->width || app->minheight < app->height) {
+ GdkGeometry hints;
+ hints.min_width = app->minwidth;
+ hints.min_height = app->minheight;
+ gtk_window_set_geometry_hints(GTK_WINDOW(gk->window), gk->window,
+ &hints, GDK_HINT_MIN_SIZE);
+ }
+ gtk_window_set_default_size(GTK_WINDOW(gk->window), app->width, app->height);
+
+ if (app->fullscreen) shoes_native_app_fullscreen(app, 1);
+
+ gtk_window_set_decorated(GTK_WINDOW(gk->window), app->decorated);
+#if GTK_CHECK_VERSION(3,8,0)
+ gtk_widget_set_opacity(GTK_WIDGET(gk->window), app->opacity);
+#endif
+ gtk_widget_set_events(gk->window, GDK_POINTER_MOTION_MASK | GDK_SCROLL_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
+ g_signal_connect(G_OBJECT(gk->window), "size-allocate",
+ G_CALLBACK(shoes_app_gtk_paint), app);
+ g_signal_connect(G_OBJECT(gk->window), "motion-notify-event",
+ G_CALLBACK(shoes_app_gtk_motion), app);
+ g_signal_connect(G_OBJECT(gk->window), "button-press-event",
+ G_CALLBACK(shoes_app_gtk_button), app);
+ g_signal_connect(G_OBJECT(gk->window), "button-release-event",
+ G_CALLBACK(shoes_app_gtk_button), app);
+ g_signal_connect(G_OBJECT(gk->window), "scroll-event",
+ G_CALLBACK(shoes_app_gtk_wheel), app);
+ g_signal_connect(G_OBJECT(gk->window), "key-press-event",
+ G_CALLBACK(shoes_app_gtk_keypress), app);
+ g_signal_connect(G_OBJECT(gk->window), "key-release-event",
+ G_CALLBACK(shoes_app_gtk_keypress), app);
+ g_signal_connect(G_OBJECT(gk->window), "delete-event",
+ G_CALLBACK(shoes_app_gtk_quit), app);
+
+ app->slot->oscanvas = gk->window;
+ return SHOES_OK;
+}
+
+void shoes_native_app_show(shoes_app *app) {
+ gtk_widget_show_all(app->os.window);
}
#ifdef SHOES_GTK_WIN32
-static GSource *gtkrb_source;
+/*static GSource *gtkrb_source;
static GSource *gtkrb_init_source();
-static GSourceFuncs gtkrb_func_tbl;
+static GSourceFuncs gtkrb_func_tbl;*/
/*
static GSource *gtkrb_init_source()
{
@@ -854,767 +783,391 @@ static GSource *gtkrb_init_source()
}
*/
-static gboolean gtkrb_idle()
-{ rb_thread_schedule();
- return 1; // keep timeout
+static gboolean gtkrb_idle() {
+ rb_thread_schedule();
+ return 1; // keep timeout
}
#endif
-void
-shoes_native_loop()
-{
+void shoes_native_loop() {
#ifndef SHOES_GTK_WIN32
- g_main_context_set_poll_func(g_main_context_default(), shoes_app_g_poll);
+ g_main_context_set_poll_func(g_main_context_default(), shoes_app_g_poll);
#else
- /* Win32 (should work for Linux too when finished)
- * Build: struct GSourceFuncs
- * Call: g_source_new() with that struct
- * Call: g_source_attach() with that
- */
- //gtkrb_source = gtkrb_init_source();
- //g_source_attach(gtkrb_source, (gpointer) NULL);
- //g_idle_add(gtkrb_idle, NULL);
- g_timeout_add(100, gtkrb_idle, NULL);
+ /* Win32 (should work for Linux too when finished)
+ * Build: struct GSourceFuncs
+ * Call: g_source_new() with that struct
+ * Call: g_source_attach() with that
+ */
+ //gtkrb_source = gtkrb_init_source();
+ //g_source_attach(gtkrb_source, (gpointer) NULL);
+ //g_idle_add(gtkrb_idle, NULL);
+ g_timeout_add(2, gtkrb_idle, NULL);
#endif
- GLOBAL_APP(app);
- if (APP_WINDOW(app)) gtk_main();
-}
-
-void
-shoes_native_app_close(shoes_app *app)
-{
- shoes_app_gtk_quit(app->os.window, NULL, (gpointer)app);
- gtk_widget_destroy(app->os.window);
- app->os.window = NULL;
+ GLOBAL_APP(app);
+ if (APP_WINDOW(app)) gtk_main();
}
-void
-shoes_browser_open(char *url)
-{
- VALUE browser = rb_str_new2("/etc/alternatives/x-www-browser '");
- rb_str_cat2(browser, url);
- rb_str_cat2(browser, "' 2>/dev/null &");
- shoes_sys(RSTRING_PTR(browser), 1);
-}
-
-void
-shoes_slot_init(VALUE c, SHOES_SLOT_OS *parent, int x, int y, int width, int height, int scrolls, int toplevel)
-{
- shoes_canvas *canvas;
- SHOES_SLOT_OS *slot;
- Data_Get_Struct(c, shoes_canvas, canvas);
-
- slot = shoes_slot_alloc(canvas, parent, toplevel);
-
- /* Subclassing GtkFixed so we can override gtk3 size management which creates
- problems with slot height being always tied to inside widgets cumulative heights
- creating heights overflow with no scrollbar !
- */
- slot->oscanvas = gtkfixed_alt_new();
-
- g_signal_connect(G_OBJECT(slot->oscanvas), "draw",
- G_CALLBACK(shoes_canvas_gtk_paint), (gpointer)c);
-
- g_signal_connect(G_OBJECT(slot->oscanvas), "size-allocate",
- G_CALLBACK(shoes_canvas_gtk_size), (gpointer)c);
- INFO("shoes_slot_init(%lu)\n", c);
-
- if (toplevel)
- gtk_container_add(GTK_CONTAINER(parent->oscanvas), slot->oscanvas);
- else
- gtk_fixed_put(GTK_FIXED(parent->oscanvas), slot->oscanvas, x, y);
-
- slot->scrollh = slot->scrollw = 0;
- slot->vscroll = NULL;
- if (scrolls)
- {
- slot->vscroll = gtk_scrollbar_new(GTK_ORIENTATION_VERTICAL,NULL);
- GtkAdjustment *adj;
- adj = gtk_range_get_adjustment(GTK_RANGE(slot->vscroll));
- gtk_adjustment_set_step_increment(adj, 16);
- gtk_adjustment_set_page_increment(adj, height - 32);
- slot->drawevent = NULL;
-
- g_signal_connect(G_OBJECT(slot->vscroll), "value-changed",
- G_CALLBACK(shoes_canvas_gtk_scroll), (gpointer)c);
- gtk_fixed_put(GTK_FIXED(slot->oscanvas), slot->vscroll, -100, -100);
-
- gtk_widget_set_size_request(slot->oscanvas, width, height);
- //gtk_widget_set_size_request(slot->oscanvas, canvas->app->minwidth, canvas->app->minheight);
-
- if (!toplevel) ATTRSET(canvas->attr, wheel, scrolls);
- }
-
- if (toplevel) shoes_canvas_size(c, width, height);
- else
- {
- gtk_widget_show_all(slot->oscanvas);
- canvas->width = 100;
- canvas->height = 100;
- }
+void shoes_native_app_close(shoes_app *app) {
+ shoes_app_gtk_quit(app->os.window, NULL, (gpointer)app);
+ gtk_widget_destroy(app->os.window);
+ app->os.window = NULL;
}
-void
-shoes_slot_destroy(shoes_canvas *canvas, shoes_canvas *pc)
-{
- if (canvas->slot->vscroll)
- gtk_container_remove(GTK_CONTAINER(canvas->slot->oscanvas), canvas->slot->vscroll);
- gtk_container_remove(GTK_CONTAINER(pc->slot->oscanvas), canvas->slot->oscanvas);
+// Below function doesn't work - /etc/alternatives doesn't exist.
+// TODO: Appears to not be used at Shoe/ruby level
+void shoes_browser_open(char *url) {
+ VALUE browser = rb_str_new2("/etc/alternatives/x-www-browser '");
+ rb_str_cat2(browser, url);
+ rb_str_cat2(browser, "' 2>/dev/null &");
+ shoes_sys(RSTRING_PTR(browser), 1);
}
-cairo_t *
-shoes_cairo_create(shoes_canvas *canvas)
-{
- GdkWindow *win = gtk_widget_get_window(canvas->slot->oscanvas);
- cairo_t *cr = gdk_cairo_create(win);
- if (canvas->slot->drawevent != NULL &&
- gtk_cairo_should_draw_window(canvas->slot->drawevent, win))
- {
- cairo_rectangle_int_t alloc;
- gtk_widget_get_allocation((GtkWidget *)canvas->slot->oscanvas, &alloc);
- cairo_region_t *region = cairo_region_create_rectangle(&alloc);
-// cairo_rectangle_int_t w_rect = {canvas->place.ix, canvas->place.iy, canvas->place.w, canvas->place.h};
- cairo_rectangle_int_t w_rect;
- gdk_cairo_get_clip_rectangle(cr, &w_rect);
- cairo_region_intersect_rectangle(region, &w_rect);
- gdk_cairo_region(cr, region);
- cairo_clip(cr);
- cairo_region_destroy(region);
-
- cairo_translate(cr, alloc.x, alloc.y - canvas->slot->scrolly);
- }
- return cr;
-}
-
-void
-shoes_cairo_destroy(shoes_canvas *canvas)
-{
-}
+void shoes_slot_init(VALUE c, SHOES_SLOT_OS *parent, int x, int y, int width, int height, int scrolls, int toplevel) {
+ shoes_canvas *canvas;
+ SHOES_SLOT_OS *slot;
+ Data_Get_Struct(c, shoes_canvas, canvas);
-void
-shoes_group_clear(SHOES_GROUP_OS *group)
-{
- group->radios = NULL;
- group->layout = NULL;
-}
+ slot = shoes_slot_alloc(canvas, parent, toplevel);
-void
-shoes_native_canvas_place(shoes_canvas *self_t, shoes_canvas *pc)
-{
- int x, y, newy;
+ /* Subclassing GtkFixed so we can override gtk3 size management which creates
+ problems with slot height being always tied to inside widgets cumulative heights
+ creating heights overflow with no scrollbar !
+ */
+ slot->oscanvas = gtkfixed_alt_new();
- GtkAllocation a;
- gtk_widget_get_allocation(self_t->slot->oscanvas, &a);
- gtk_widget_translate_coordinates(self_t->slot->oscanvas, pc->slot->oscanvas, 0, 0, &x, &y);
- newy = (self_t->place.iy + self_t->place.dy) - pc->slot->scrolly;
+ g_signal_connect(G_OBJECT(slot->oscanvas), "draw",
+ G_CALLBACK(shoes_canvas_gtk_paint), (gpointer)c);
- if (x != self_t->place.ix + self_t->place.dx || y != newy)
- gtk_fixed_move(GTK_FIXED(pc->slot->oscanvas), self_t->slot->oscanvas,
- self_t->place.ix + self_t->place.dx, newy);
- if (a.width != self_t->place.iw || a.height != self_t->place.ih)
- gtk_widget_set_size_request(self_t->slot->oscanvas, self_t->place.iw, self_t->place.ih);
-}
+ g_signal_connect(G_OBJECT(slot->oscanvas), "size-allocate",
+ G_CALLBACK(shoes_canvas_gtk_size), (gpointer)c);
+ INFO("shoes_slot_init(%lu)\n", c);
-void
-shoes_native_canvas_resize(shoes_canvas *canvas)
-{
-}
-
-/*
- * one shot timer for start{} on slot. Canvas internal use.
-*/
-static gboolean
-start_wait(gpointer data) {
- VALUE rbcanvas = (VALUE)data;
- shoes_canvas *canvas;
- Data_Get_Struct(rbcanvas, shoes_canvas, canvas);
-
- shoes_safe_block(rbcanvas, ATTR(canvas->attr, start), rb_ary_new3(1, rbcanvas));
- return FALSE; // timeout will be stopped and destroyed
-}
-
-void shoes_native_canvas_oneshot(int ms, VALUE canvas) {
- g_timeout_add_full(G_PRIORITY_HIGH, 1, start_wait, (gpointer)canvas, NULL);
-}
+ if (toplevel)
+ gtk_container_add(GTK_CONTAINER(parent->oscanvas), slot->oscanvas);
+ else
+ gtk_fixed_put(GTK_FIXED(parent->oscanvas), slot->oscanvas, x, y);
+
+ slot->scrollh = slot->scrollw = 0;
+ slot->vscroll = NULL;
+ if (scrolls) {
+ slot->vscroll = gtk_scrollbar_new(GTK_ORIENTATION_VERTICAL,NULL);
+ GtkAdjustment *adj;
+ adj = gtk_range_get_adjustment(GTK_RANGE(slot->vscroll));
+ gtk_adjustment_set_step_increment(adj, 16);
+ gtk_adjustment_set_page_increment(adj, height - 32);
+ slot->drawevent = NULL;
+
+ g_signal_connect(G_OBJECT(slot->vscroll), "value-changed",
+ G_CALLBACK(shoes_canvas_gtk_scroll), (gpointer)c);
+ gtk_fixed_put(GTK_FIXED(slot->oscanvas), slot->vscroll, -100, -100);
+
+ gtk_widget_set_size_request(slot->oscanvas, width, height);
+ //gtk_widget_set_size_request(slot->oscanvas, canvas->app->minwidth, canvas->app->minheight);
+
+ if (!toplevel) ATTRSET(canvas->attr, wheel, scrolls);
+ }
-static void
-shoes_widget_changed(GtkWidget *ref, gpointer data)
-{
- VALUE self = (VALUE)data;
- shoes_control_send(self, s_change);
+ if (toplevel) shoes_canvas_size(c, width, height);
+ else {
+ gtk_widget_show_all(slot->oscanvas);
+ canvas->width = 100;
+ canvas->height = 100;
+ }
}
-void
-shoes_native_control_hide(SHOES_CONTROL_REF ref)
-{
- gtk_widget_hide(ref);
+void shoes_slot_destroy(shoes_canvas *canvas, shoes_canvas *pc) {
+ if (canvas->slot->vscroll)
+ gtk_container_remove(GTK_CONTAINER(canvas->slot->oscanvas), canvas->slot->vscroll);
+ gtk_container_remove(GTK_CONTAINER(pc->slot->oscanvas), canvas->slot->oscanvas);
}
-void
-shoes_native_control_show(SHOES_CONTROL_REF ref)
-{
- gtk_widget_show(ref);
+cairo_t *shoes_cairo_create(shoes_canvas *canvas) {
+ GdkWindow *win = gtk_widget_get_window(canvas->slot->oscanvas);
+ cairo_t *cr = gdk_cairo_create(win);
+ if (canvas->slot->drawevent != NULL &&
+ gtk_cairo_should_draw_window(canvas->slot->drawevent, win)) {
+ cairo_rectangle_int_t alloc;
+ gtk_widget_get_allocation((GtkWidget *)canvas->slot->oscanvas, &alloc);
+ cairo_region_t *region = cairo_region_create_rectangle(&alloc);
+// cairo_rectangle_int_t w_rect = {canvas->place.ix, canvas->place.iy, canvas->place.w, canvas->place.h};
+ cairo_rectangle_int_t w_rect;
+ gdk_cairo_get_clip_rectangle(cr, &w_rect);
+ cairo_region_intersect_rectangle(region, &w_rect);
+ gdk_cairo_region(cr, region);
+ cairo_clip(cr);
+ cairo_region_destroy(region);
+
+ cairo_translate(cr, alloc.x, alloc.y - canvas->slot->scrolly);
+ }
+ return cr;
}
-void
-shoes_native_control_position(SHOES_CONTROL_REF ref, shoes_place *p1, VALUE self,
- shoes_canvas *canvas, shoes_place *p2)
-{
- PLACE_COORDS();
- gtk_widget_set_size_request(ref, p2->iw, p2->ih);
- gtk_fixed_put(GTK_FIXED(canvas->slot->oscanvas), ref, p2->ix + p2->dx, p2->iy + p2->dy);
- gtk_widget_show_all(ref);
+void shoes_cairo_destroy(shoes_canvas *canvas) {
}
-void
-shoes_native_control_repaint(SHOES_CONTROL_REF ref, shoes_place *p1,
- shoes_canvas *canvas, shoes_place *p2)
-{
- p2->iy -= canvas->slot->scrolly;
- if (CHANGED_COORDS()) {
- PLACE_COORDS();
- gtk_fixed_move(GTK_FIXED(canvas->slot->oscanvas),
- ref, p2->ix + p2->dx, p2->iy + p2->dy);
- gtk_widget_set_size_request(ref, p2->iw, p2->ih);
- }
- p2->iy += canvas->slot->scrolly;
+void shoes_group_clear(SHOES_GROUP_OS *group) {
+ group->radios = NULL;
+ group->layout = NULL;
}
-void
-shoes_native_control_focus(SHOES_CONTROL_REF ref)
-{
- if (gtk_widget_get_can_focus(ref)) gtk_widget_grab_focus(ref);
-}
+void shoes_native_canvas_place(shoes_canvas *self_t, shoes_canvas *pc) {
+ int x, y, newy;
-void
-shoes_native_control_state(SHOES_CONTROL_REF ref, gboolean sensitive, gboolean setting)
-{
- gtk_widget_set_sensitive(ref, sensitive);
- if (GTK_IS_EDITABLE(ref))
- gtk_editable_set_editable(GTK_EDITABLE(ref), setting);
- else if (GTK_IS_SCROLLED_WINDOW(ref))
- {
- GtkWidget *textview;
- GTK_CHILD(textview, ref);
- gtk_text_view_set_editable(GTK_TEXT_VIEW(textview), setting);
- }
-}
+ GtkAllocation a;
+ gtk_widget_get_allocation(self_t->slot->oscanvas, &a);
+ gtk_widget_translate_coordinates(self_t->slot->oscanvas, pc->slot->oscanvas, 0, 0, &x, &y);
+ newy = (self_t->place.iy + self_t->place.dy) - pc->slot->scrolly;
-void
-shoes_native_control_remove(SHOES_CONTROL_REF ref, shoes_canvas *canvas)
-{
- gtk_container_remove(GTK_CONTAINER(canvas->slot->oscanvas), ref);
+ if (x != self_t->place.ix + self_t->place.dx || y != newy)
+ gtk_fixed_move(GTK_FIXED(pc->slot->oscanvas), self_t->slot->oscanvas,
+ self_t->place.ix + self_t->place.dx, newy);
+ if (a.width != self_t->place.iw || a.height != self_t->place.ih)
+ gtk_widget_set_size_request(self_t->slot->oscanvas, self_t->place.iw, self_t->place.ih);
}
-void
-shoes_native_control_free(SHOES_CONTROL_REF ref)
-{
- //
- // no need to free gtk widgets, since gtk seems
- // to garbage collect them fine. and memory
- // addresses often get reused.
- //
+void shoes_native_canvas_resize(shoes_canvas *canvas) {
}
-
/*
- * video support
- */
+ * one shot timer for start{} on slot. Canvas internal use.
+*/
+static gboolean start_wait(gpointer data) {
+ VALUE rbcanvas = (VALUE)data;
+ shoes_canvas *canvas;
+ Data_Get_Struct(rbcanvas, shoes_canvas, canvas);
-void
-surface_on_realize(SHOES_CONTROL_REF ref, gpointer data) {
- VALUE rbvideo = (VALUE)data;
- shoes_video *video;
- Data_Get_Struct(rbvideo, shoes_video, video);
- video->realized = 1;
+ shoes_safe_block(rbcanvas, ATTR(canvas->attr, start), rb_ary_new3(1, rbcanvas));
+ return FALSE; // timeout will be stopped and destroyed
}
-// SHOES_SURFACE_REF and SHOES_CONTROL_REF expands the same : GtkWidget *
-// ref in shoes_video struct was a SHOES_CONTROL_REF anyway
-SHOES_CONTROL_REF
-shoes_native_surface_new(VALUE attr, VALUE video)
-{
- SHOES_CONTROL_REF da = gtk_drawing_area_new();
- gtk_widget_set_size_request(da, NUM2INT(ATTR(attr, width)), NUM2INT(ATTR(attr, height)));
-
- VALUE uc = Qnil;
- if (!NIL_P(attr)) uc = ATTR(attr, bg_color);
-
- // TODO (better with GtkStyleProvider)
- GdkRGBA color = {.0, .0, .0, 1.0};
- if (!NIL_P(uc)) {
- shoes_color *col;
- Data_Get_Struct(uc, shoes_color, col);
- color.red = col->r/255.0; color.green = col->g/255.0; color.blue = col->b/255.0;
- }
- gtk_widget_override_background_color(GTK_WIDGET(da), 0, &color);
-
- g_signal_connect(G_OBJECT(da), "realize",
- G_CALLBACK(surface_on_realize),
- (gpointer)video);
-
- return da;
+void shoes_native_canvas_oneshot(int ms, VALUE canvas) {
+ g_timeout_add_full(G_PRIORITY_HIGH, 1, start_wait, (gpointer)canvas, NULL);
}
-void
-shoes_native_surface_remove(SHOES_CONTROL_REF ref)
-{
- gtk_widget_destroy(ref);
+void shoes_widget_changed(GtkWidget *ref, gpointer data) {
+ VALUE self = (VALUE)data;
+ shoes_control_send(self, s_change);
}
-/* doing this directly on control now
- *
-void
-shoes_native_surface_position(SHOES_SURFACE_REF ref, shoes_place *p1,
- VALUE self, shoes_canvas *canvas, shoes_place *p2)
-{
- shoes_native_control_position((SHOES_CONTROL_REF)ref, p1, self, canvas, p2);
+void shoes_native_control_hide(SHOES_CONTROL_REF ref) {
+ gtk_widget_hide(ref);
}
-void
-//shoes_native_surface_hide(SHOES_SURFACE_REF ref)
-shoes_native_surface_hide(SHOES_CONTROL_REF ref)
-{
- shoes_native_control_hide(ref);
+void shoes_native_control_show(SHOES_CONTROL_REF ref) {
+ gtk_widget_show(ref);
}
-void
-//shoes_native_surface_show(SHOES_SURFACE_REF ref)
-shoes_native_surface_show(SHOES_CONTROL_REF ref)
-{
- shoes_native_control_show(ref);
+void shoes_native_control_position(SHOES_CONTROL_REF ref, shoes_place *p1, VALUE self,
+ shoes_canvas *canvas, shoes_place *p2) {
+ PLACE_COORDS();
+ gtk_widget_set_size_request(ref, p2->iw, p2->ih);
+ gtk_fixed_put(GTK_FIXED(canvas->slot->oscanvas), ref, p2->ix + p2->dx, p2->iy + p2->dy);
+ gtk_widget_show_all(ref);
+}
+
+void shoes_native_control_repaint(SHOES_CONTROL_REF ref, shoes_place *p1,
+ shoes_canvas *canvas, shoes_place *p2) {
+ p2->iy -= canvas->slot->scrolly;
+ if (CHANGED_COORDS()) {
+ PLACE_COORDS();
+ gtk_fixed_move(GTK_FIXED(canvas->slot->oscanvas),
+ ref, p2->ix + p2->dx, p2->iy + p2->dy);
+ gtk_widget_set_size_request(ref, p2->iw, p2->ih);
+ }
+ p2->iy += canvas->slot->scrolly;
}
-*/
-
-
-static gboolean
-shoes_button_gtk_clicked(GtkButton *button, gpointer data)
-{
- VALUE self = (VALUE)data;
- shoes_control_send(self, s_click);
- return TRUE;
+void shoes_native_control_focus(SHOES_CONTROL_REF ref) {
+ if (gtk_widget_get_can_focus(ref)) gtk_widget_grab_focus(ref);
}
-SHOES_CONTROL_REF
-shoes_native_button(VALUE self, shoes_canvas *canvas, shoes_place *place, char *msg)
-{
- SHOES_CONTROL_REF ref = gtk_button_alt_new_with_label(_(msg));
-
- g_signal_connect(G_OBJECT(ref), "clicked",
- G_CALLBACK(shoes_button_gtk_clicked),
- (gpointer)self);
- return ref;
+void shoes_native_control_state(SHOES_CONTROL_REF ref, gboolean sensitive, gboolean setting) {
+ gtk_widget_set_sensitive(ref, sensitive);
+ if (GTK_IS_EDITABLE(ref))
+ gtk_editable_set_editable(GTK_EDITABLE(ref), setting);
+ else if (GTK_IS_SCROLLED_WINDOW(ref)) {
+ GtkWidget *textview;
+ GTK_CHILD(textview, ref);
+ gtk_text_view_set_editable(GTK_TEXT_VIEW(textview), setting);
+ }
}
-void
-shoes_native_secrecy(SHOES_CONTROL_REF ref)
-{
- gtk_entry_set_visibility(GTK_ENTRY(ref), FALSE);
- gtk_entry_set_invisible_char(GTK_ENTRY(ref), SHOES_GTK_INVISIBLE_CHAR);
+void shoes_native_control_remove(SHOES_CONTROL_REF ref, shoes_canvas *canvas) {
+ gtk_container_remove(GTK_CONTAINER(canvas->slot->oscanvas), ref);
}
-void
-shoes_native_enterkey(GtkWidget *ref, gpointer data)
-{
- VALUE self = (VALUE)data;
- GET_STRUCT(control, self_t);
- VALUE click = ATTR(self_t->attr, donekey);
- if (!NIL_P(click))
- {
- shoes_safe_block(self_t->parent, click, rb_ary_new3(1, self));
- }
+void shoes_native_control_free(SHOES_CONTROL_REF ref) {
+ //
+ // no need to free gtk widgets, since gtk seems
+ // to garbage collect them fine. and memory
+ // addresses often get reused.
+ //
}
-SHOES_CONTROL_REF
-shoes_native_edit_line(VALUE self, shoes_canvas *canvas, shoes_place *place, VALUE attr, char *msg)
-{
- SHOES_CONTROL_REF ref = gtk_entry_alt_new();
- if (RTEST(ATTR(attr, secret))) shoes_native_secrecy(ref);
- gtk_entry_set_text(GTK_ENTRY(ref), _(msg));
- g_signal_connect(G_OBJECT(ref), "changed",
- G_CALLBACK(shoes_widget_changed),
- (gpointer)self);
- // cjc: try to intercept \n bug 860 @ shoes4
- g_signal_connect(G_OBJECT(ref), "activate",
- G_CALLBACK(shoes_native_enterkey), // fix name?
- (gpointer)self);
-
- return ref;
-}
-
-VALUE
-shoes_native_edit_line_get_text(SHOES_CONTROL_REF ref)
-{
- return rb_str_new2(gtk_entry_get_text(GTK_ENTRY(ref)));
+void shoes_native_control_set_tooltip(SHOES_CONTROL_REF ref, VALUE tooltip) {
+ gtk_widget_set_tooltip_text(GTK_WIDGET(ref), RSTRING_PTR(shoes_native_to_s(tooltip)));
}
-void
-shoes_native_edit_line_set_text(SHOES_CONTROL_REF ref, char *msg)
-{
- gtk_entry_set_text(GTK_ENTRY(ref), _(msg));
+VALUE shoes_native_control_get_tooltip(SHOES_CONTROL_REF ref) {
+ return rb_str_new2(gtk_widget_get_tooltip_text(GTK_WIDGET(ref)));
}
-VALUE
-shoes_native_edit_line_cursor_to_end(SHOES_CONTROL_REF ref)
-{
- gtk_editable_set_position(GTK_EDITABLE(ref), -1);
- return Qnil;
+gboolean shoes_button_gtk_clicked(GtkButton *button, gpointer data) {
+ VALUE self = (VALUE)data;
+ shoes_control_send(self, s_click);
+ return TRUE;
}
-SHOES_CONTROL_REF
-shoes_native_edit_box(VALUE self, shoes_canvas *canvas, shoes_place *place, VALUE attr, char *msg)
-{
- GtkTextBuffer *buffer;
- GtkWidget* textview = gtk_text_view_new();
- SHOES_CONTROL_REF ref = gtk_scrolled_window_alt_new(NULL, NULL);
- gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(textview), GTK_WRAP_WORD);
- buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview));
- gtk_text_buffer_set_text(buffer, _(msg), -1);
- gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(ref),
- GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
- gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(ref), GTK_SHADOW_IN);
- gtk_container_add(GTK_CONTAINER(ref), textview);
- g_signal_connect(G_OBJECT(buffer), "changed",
- G_CALLBACK(shoes_widget_changed),
- (gpointer)self);
- return ref;
-}
-
-VALUE
-shoes_native_edit_box_get_text(SHOES_CONTROL_REF ref)
-{
- GtkWidget *textview;
- GTK_CHILD(textview, ref);
- GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview));
- GtkTextIter begin, end;
- gtk_text_buffer_get_bounds(buffer, &begin, &end);
- return rb_str_new2(gtk_text_buffer_get_text(buffer, &begin, &end, TRUE));
-}
+SHOES_CONTROL_REF shoes_native_button(VALUE self, shoes_canvas *canvas, shoes_place *place, VALUE attr, char *msg) {
+ SHOES_CONTROL_REF ref = gtk_button_alt_new_with_label(_(msg));
-void
-shoes_native_edit_box_set_text(SHOES_CONTROL_REF ref, char *msg)
-{
- GtkWidget *textview;
- GTK_CHILD(textview, ref);
- GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview));
- gtk_text_buffer_set_text(buffer, _(msg), -1);
-}
+ if (!NIL_P(shoes_hash_get(attr, rb_intern("tooltip")))) {
+ gtk_widget_set_tooltip_text(GTK_WIDGET(ref), RSTRING_PTR(shoes_hash_get(attr, rb_intern("tooltip"))));
+ }
-void
-shoes_native_edit_box_append(SHOES_CONTROL_REF ref, char *msg)
-{
- GtkWidget *textview;
- GTK_CHILD(textview, ref);
- GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview));
- GtkTextIter begin, end;
- gtk_text_buffer_get_bounds(buffer, &begin, &end);
- gtk_text_buffer_insert(buffer, &end, msg, strlen(msg));
- gtk_text_buffer_get_bounds(buffer, &begin, &end);
+ g_signal_connect(G_OBJECT(ref), "clicked",
+ G_CALLBACK(shoes_button_gtk_clicked),
+ (gpointer)self);
+ return ref;
}
-void
-shoes_native_edit_box_scroll_to_end(SHOES_CONTROL_REF ref)
-{
- GtkWidget *textview;
- GTK_CHILD(textview, ref);
- GtkTextIter end;
- GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview));
- gtk_text_buffer_get_end_iter (buffer, &end);
- /* get the current ( cursor )mark name */
- GtkTextMark *insert_mark = gtk_text_buffer_get_insert (buffer);
-
- /* move mark and selection bound to the end */
- gtk_text_buffer_place_cursor(buffer, &end);
-
- /* scroll to the end view */
- gtk_text_view_scroll_to_mark( GTK_TEXT_VIEW (textview),
- insert_mark, 0.0, TRUE, 0.0, 1.0);
+void shoes_native_secrecy(SHOES_CONTROL_REF ref) {
+ gtk_entry_set_visibility(GTK_ENTRY(ref), FALSE);
+ gtk_entry_set_invisible_char(GTK_ENTRY(ref), SHOES_GTK_INVISIBLE_CHAR);
}
+SHOES_CONTROL_REF shoes_native_list_box(VALUE self, shoes_canvas *canvas, shoes_place *place, VALUE attr, char *msg) {
+ /*get bottom margin : following macro gives us bmargin (also lmargin,tmargin,rmargin)*/
+ ATTR_MARGINS(attr, 0, canvas);
-SHOES_CONTROL_REF
-shoes_native_text_edit_box(VALUE self, shoes_canvas *canvas, shoes_place *place, VALUE attr, char *msg)
-{
- GtkTextBuffer *buffer;
- GtkWidget* textview = gtk_text_view_new();
- SHOES_CONTROL_REF ref = gtk_scrolled_window_alt_new(NULL, NULL);
- gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(textview), GTK_WRAP_WORD);
- buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview));
- gtk_text_buffer_set_text(buffer, _(msg), -1);
- gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(ref),
- GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
- gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(ref), GTK_SHADOW_IN);
- gtk_container_add(GTK_CONTAINER(ref), textview);
- g_signal_connect(G_OBJECT(buffer), "changed",
- G_CALLBACK(shoes_widget_changed),
- (gpointer)self);
- return ref;
-}
-
-VALUE
-shoes_native_text_edit_box_get_text(SHOES_CONTROL_REF ref)
-{
- GtkWidget *textview;
- GTK_CHILD(textview, ref);
- GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview));
- GtkTextIter begin, end;
- gtk_text_buffer_get_bounds(buffer, &begin, &end);
- return rb_str_new2(gtk_text_buffer_get_text(buffer, &begin, &end, TRUE));
-}
+ SHOES_CONTROL_REF ref = gtk_combo_box_text_alt_new(attr, bmargin);
-void
-shoes_native_text_edit_box_set_text(SHOES_CONTROL_REF ref, char *msg)
-{
- GtkWidget *textview;
- GTK_CHILD(textview, ref);
- GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview));
- gtk_text_buffer_set_text(buffer, _(msg), -1);
-}
+ if (!NIL_P(shoes_hash_get(attr, rb_intern("tooltip")))) {
+ gtk_widget_set_tooltip_text(GTK_WIDGET(ref), RSTRING_PTR(shoes_hash_get(attr, rb_intern("tooltip"))));
+ }
-VALUE
-shoes_native_text_edit_box_append(SHOES_CONTROL_REF ref, char *msg)
-{
- GtkWidget *textview;
- GTK_CHILD(textview, ref);
- GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview));
- GtkTextIter begin, end;
- gtk_text_buffer_get_bounds(buffer, &begin, &end);
- gtk_text_buffer_insert(buffer, &end, msg, strlen(msg));
- gtk_text_buffer_get_bounds(buffer, &begin, &end);
- // TODO: return something useful
- return Qnil;
- //return rb_str_new2(gtk_text_buffer_get_text(buffer, &begin, &end, TRUE));
-}
-// -- end of shoes_native_text_edit_box methods
-
-SHOES_CONTROL_REF
-shoes_native_list_box(VALUE self, shoes_canvas *canvas, shoes_place *place, VALUE attr, char *msg)
-{
- /*get bottom margin : following macro gives us bmargin (also lmargin,tmargin,rmargin)*/
- ATTR_MARGINS(attr, 0, canvas);
-
- SHOES_CONTROL_REF ref = gtk_combo_box_text_alt_new(attr, bmargin);
- g_signal_connect(G_OBJECT(ref), "changed",
- G_CALLBACK(shoes_widget_changed),
- (gpointer)self);
- return ref;
+ g_signal_connect(G_OBJECT(ref), "changed",
+ G_CALLBACK(shoes_widget_changed),
+ (gpointer)self);
+ return ref;
}
-void
-shoes_native_list_box_update(SHOES_CONTROL_REF combo, VALUE ary)
-{
- long i;
- gtk_list_store_clear(GTK_LIST_STORE(gtk_combo_box_get_model(GTK_COMBO_BOX(combo))));
- for (i = 0; i < RARRAY_LEN(ary); i++)
- {
- VALUE msg = shoes_native_to_s(rb_ary_entry(ary, i));
- gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(combo), NULL, _(RSTRING_PTR(msg)));
- }
-}
-
-VALUE
-shoes_native_list_box_get_active(SHOES_CONTROL_REF ref, VALUE items)
-{
- int sel = gtk_combo_box_get_active(GTK_COMBO_BOX(ref));
- if (sel >= 0)
- return rb_ary_entry(items, sel);
- return Qnil;
+void shoes_native_list_box_update(SHOES_CONTROL_REF combo, VALUE ary) {
+ long i;
+ gtk_list_store_clear(GTK_LIST_STORE(gtk_combo_box_get_model(GTK_COMBO_BOX(combo))));
+ for (i = 0; i < RARRAY_LEN(ary); i++) {
+ VALUE msg = shoes_native_to_s(rb_ary_entry(ary, i));
+ gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(combo), NULL, _(RSTRING_PTR(msg)));
+ }
}
-void
-shoes_native_list_box_set_active(SHOES_CONTROL_REF combo, VALUE ary, VALUE item)
-{
- int idx = rb_ary_index_of(ary, item);
- if (idx < 0) return;
- gtk_combo_box_set_active(GTK_COMBO_BOX(combo), idx);
+VALUE shoes_native_list_box_get_active(SHOES_CONTROL_REF ref, VALUE items) {
+ int sel = gtk_combo_box_get_active(GTK_COMBO_BOX(ref));
+ if (sel >= 0)
+ return rb_ary_entry(items, sel);
+ return Qnil;
}
-SHOES_CONTROL_REF
-shoes_native_progress(VALUE self, shoes_canvas *canvas, shoes_place *place, VALUE attr, char *msg)
-{
- SHOES_CONTROL_REF ref = gtk_progress_bar_alt_new();
- gtk_progress_bar_set_text(GTK_PROGRESS_BAR(ref), _(msg));
- return ref;
+void shoes_native_list_box_set_active(SHOES_CONTROL_REF combo, VALUE ary, VALUE item) {
+ int idx = rb_ary_index_of(ary, item);
+ if (idx < 0) return;
+ gtk_combo_box_set_active(GTK_COMBO_BOX(combo), idx);
}
-double
-shoes_native_progress_get_fraction(SHOES_CONTROL_REF ref)
-{
- return gtk_progress_bar_get_fraction(GTK_PROGRESS_BAR(ref));
-}
+// TODO: should be moved into gtkprogress.c (or gtkprogressbaralt.c)
+SHOES_CONTROL_REF shoes_native_progress(VALUE self, shoes_canvas *canvas, shoes_place *place, VALUE attr, char *msg) {
+ SHOES_CONTROL_REF ref = gtk_progress_bar_alt_new();
-void
-shoes_native_progress_set_fraction(SHOES_CONTROL_REF ref, double perc)
-{
- gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(ref), perc);
-}
+ if (!NIL_P(shoes_hash_get(attr, rb_intern("tooltip")))) {
+ gtk_widget_set_tooltip_text(GTK_WIDGET(ref), RSTRING_PTR(shoes_hash_get(attr, rb_intern("tooltip"))));
+ }
-SHOES_CONTROL_REF
-shoes_native_slider(VALUE self, shoes_canvas *canvas, shoes_place *place, VALUE attr, char *msg)
-{
- SHOES_CONTROL_REF ref = gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL, 0., 1., 0.01);
- gtk_scale_set_draw_value(GTK_SCALE(ref), FALSE);
- g_signal_connect(G_OBJECT(ref), "value-changed",
- G_CALLBACK(shoes_widget_changed), (gpointer)self);
- return ref;
+ gtk_progress_bar_set_text(GTK_PROGRESS_BAR(ref), _(msg));
+ return ref;
}
-double
-shoes_native_slider_get_fraction(SHOES_CONTROL_REF ref)
-{
- return gtk_range_get_value(GTK_RANGE(ref));
+double shoes_native_progress_get_fraction(SHOES_CONTROL_REF ref) {
+ return gtk_progress_bar_get_fraction(GTK_PROGRESS_BAR(ref));
}
-void
-shoes_native_slider_set_fraction(SHOES_CONTROL_REF ref, double perc)
-{
- gtk_range_set_value(GTK_RANGE(ref), perc);
+void shoes_native_progress_set_fraction(SHOES_CONTROL_REF ref, double perc) {
+ gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(ref), perc);
}
-SHOES_CONTROL_REF
-shoes_native_check(VALUE self, shoes_canvas *canvas, shoes_place *place, VALUE attr, char *msg)
-{
- SHOES_CONTROL_REF ref = gtk_check_button_new();
- // set visual state before connecting signal
- if (RTEST(ATTR(attr, checked)))
- {
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ref), TRUE);
- }
- g_signal_connect(G_OBJECT(ref), "clicked",
- G_CALLBACK(shoes_button_gtk_clicked),
- (gpointer)self);
- return ref;
-}
-
-VALUE
-shoes_native_check_get(SHOES_CONTROL_REF ref)
-{
- return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ref)) ? Qtrue : Qfalse;
-}
+SHOES_CONTROL_REF shoes_native_slider(VALUE self, shoes_canvas *canvas, shoes_place *place, VALUE attr, char *msg) {
+ SHOES_CONTROL_REF ref = gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL, 0., 1., 0.01);
-void
-shoes_native_check_set(SHOES_CONTROL_REF ref, int on)
-{
- // bug264 - don't toggle if already set to desired state.
- gboolean new_state;
- new_state = on ? TRUE : FALSE;
- if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ref)) != new_state)
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ref), new_state);
-}
+ if (!NIL_P(shoes_hash_get(attr, rb_intern("tooltip")))) {
+ gtk_widget_set_tooltip_text(GTK_WIDGET(ref), RSTRING_PTR(shoes_hash_get(attr, rb_intern("tooltip"))));
+ }
-SHOES_CONTROL_REF
-shoes_native_radio(VALUE self, shoes_canvas *canvas, shoes_place *place, VALUE attr, VALUE group)
-{
- SHOES_CONTROL_REF ref;
- GSList *list = NULL;
- if (!NIL_P(group))
- {
- shoes_control *lctrl;
- VALUE leader = rb_ary_entry(group, 0);
- Data_Get_Struct(leader, shoes_control, lctrl);
- list = gtk_radio_button_get_group(GTK_RADIO_BUTTON(lctrl->ref));
- }
- ref = gtk_radio_button_new(list);
- g_signal_connect(G_OBJECT(ref), "clicked",
- G_CALLBACK(shoes_button_gtk_clicked),
- (gpointer)self);
- return ref;
-}
-
-static gboolean
-shoes_gtk_animate(gpointer data)
-{
- VALUE timer = (VALUE)data;
- shoes_timer *self_t;
- Data_Get_Struct(timer, shoes_timer, self_t);
- if (self_t->started == ANIM_STARTED)
- shoes_timer_call(timer);
- return self_t->started == ANIM_STARTED;
+ gtk_scale_set_draw_value(GTK_SCALE(ref), FALSE);
+ g_signal_connect(G_OBJECT(ref), "value-changed",
+ G_CALLBACK(shoes_widget_changed), (gpointer)self);
+ return ref;
}
-void
-shoes_native_timer_remove(shoes_canvas *canvas, SHOES_TIMER_REF ref)
-{
- g_source_remove(ref);
+double shoes_native_slider_get_fraction(SHOES_CONTROL_REF ref) {
+ return gtk_range_get_value(GTK_RANGE(ref));
}
-SHOES_TIMER_REF
-shoes_native_timer_start(VALUE self, shoes_canvas *canvas, unsigned int interval)
-{
- return g_timeout_add(interval, shoes_gtk_animate, (gpointer)self);
+void shoes_native_slider_set_fraction(SHOES_CONTROL_REF ref, double perc) {
+ gtk_range_set_value(GTK_RANGE(ref), perc);
}
-VALUE
-shoes_native_clipboard_get(shoes_app *app)
-{
- //GtkClipboard *primary = gtk_clipboard_get(GDK_SELECTION_PRIMARY);
- GtkClipboard *primary = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
- if (gtk_clipboard_wait_is_text_available(primary))
- {
- gchar *string = gtk_clipboard_wait_for_text(primary);
- return rb_str_new2(string);
- }
- return Qnil;
+VALUE shoes_native_clipboard_get(shoes_app *app) {
+ //GtkClipboard *primary = gtk_clipboard_get(GDK_SELECTION_PRIMARY);
+ GtkClipboard *primary = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
+ if (gtk_clipboard_wait_is_text_available(primary)) {
+ gchar *string = gtk_clipboard_wait_for_text(primary);
+ return rb_str_new2(string);
+ }
+ return Qnil;
}
-void
-shoes_native_clipboard_set(shoes_app *app, VALUE string)
-{
- //GtkClipboard *primary = gtk_clipboard_get(GDK_SELECTION_PRIMARY);
- GtkClipboard *primary = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
- gtk_clipboard_set_text(primary, RSTRING_PTR(string), RSTRING_LEN(string));
+void shoes_native_clipboard_set(shoes_app *app, VALUE string) {
+ //GtkClipboard *primary = gtk_clipboard_get(GDK_SELECTION_PRIMARY);
+ GtkClipboard *primary = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
+ gtk_clipboard_set_text(primary, RSTRING_PTR(string), RSTRING_LEN(string));
}
-VALUE
-shoes_native_to_s(VALUE text)
-{
- text = rb_funcall(text, s_to_s, 0);
- return text;
+VALUE shoes_native_to_s(VALUE text) {
+ text = rb_funcall(text, s_to_s, 0);
+ return text;
}
#if defined(GTK3) // && !defined(SHOES_GTK_WIN32)
-VALUE
-shoes_native_window_color(shoes_app *app)
-{
- GtkStyleContext *style = gtk_widget_get_style_context(GTK_WIDGET(APP_WINDOW(app)));
- GdkRGBA bg;
- gtk_style_context_lookup_color(style, GTK_STATE_NORMAL, &bg);
- return shoes_color_new((int)(bg.red * 255), (int)(bg.green * 255),
- (int)(bg.blue * 255) , SHOES_COLOR_OPAQUE);
+VALUE shoes_native_window_color(shoes_app *app) {
+ GtkStyleContext *style = gtk_widget_get_style_context(GTK_WIDGET(APP_WINDOW(app)));
+ GdkRGBA bg;
+ gtk_style_context_lookup_color(style, GTK_STATE_NORMAL, &bg);
+ return shoes_color_new((int)(bg.red * 255), (int)(bg.green * 255),
+ (int)(bg.blue * 255), SHOES_COLOR_OPAQUE);
}
-VALUE
-shoes_native_dialog_color(shoes_app *app)
-{
- GdkRGBA bg;
- GtkStyleContext *style = gtk_widget_get_style_context(GTK_WIDGET(APP_WINDOW(app)));
- gtk_style_context_lookup_color(style, GTK_STATE_NORMAL, &bg);
- return shoes_color_new((int)(bg.red * 255), (int)(bg.green * 255),
- (int)(bg.blue * 255) , SHOES_COLOR_OPAQUE);
+VALUE shoes_native_dialog_color(shoes_app *app) {
+ GdkRGBA bg;
+ GtkStyleContext *style = gtk_widget_get_style_context(GTK_WIDGET(APP_WINDOW(app)));
+ gtk_style_context_lookup_color(style, GTK_STATE_NORMAL, &bg);
+ return shoes_color_new((int)(bg.red * 255), (int)(bg.green * 255),
+ (int)(bg.blue * 255), SHOES_COLOR_OPAQUE);
}
#else
-VALUE
-shoes_native_window_color(shoes_app *app)
-{
- GtkStyle *style = gtk_widget_get_style(GTK_WIDGET(APP_WINDOW(app)));
- GdkColor bg = style->bg[GTK_STATE_NORMAL];
- return shoes_color_new(bg.red / 257, bg.green / 257, bg.blue / 257 , SHOES_COLOR_OPAQUE);
+VALUE shoes_native_window_color(shoes_app *app) {
+ GtkStyle *style = gtk_widget_get_style(GTK_WIDGET(APP_WINDOW(app)));
+ GdkColor bg = style->bg[GTK_STATE_NORMAL];
+ return shoes_color_new(bg.red / 257, bg.green / 257, bg.blue / 257, SHOES_COLOR_OPAQUE);
}
-VALUE
-shoes_native_dialog_color(shoes_app *app)
-{
- GtkStyle *style = gtk_widget_get_style(GTK_WIDGET(APP_WINDOW(app)));
- GdkColor bg = style->bg[GTK_STATE_NORMAL];
- return shoes_color_new(bg.red / 257, bg.green / 257, bg.blue / 257 , SHOES_COLOR_OPAQUE);
+VALUE shoes_native_dialog_color(shoes_app *app) {
+ GtkStyle *style = gtk_widget_get_style(GTK_WIDGET(APP_WINDOW(app)));
+ GdkColor bg = style->bg[GTK_STATE_NORMAL];
+ return shoes_color_new(bg.red / 257, bg.green / 257, bg.blue / 257, SHOES_COLOR_OPAQUE);
}
#endif
-VALUE
-shoes_dialog_alert(int argc, VALUE *argv, VALUE self)
-{
+VALUE shoes_dialog_alert(int argc, VALUE *argv, VALUE self) {
GTK_APP_VAR(app);
char atitle[50];
g_sprintf(atitle, "%s says", title_app);
@@ -1623,251 +1176,219 @@ shoes_dialog_alert(int argc, VALUE *argv, VALUE self)
char *msg = RSTRING_PTR(shoes_native_to_s(args.a[0]));
gchar *format_string = "%s\n\n%s";
- if (argc == 2)
- {
- if (RTEST(ATTR(args.a[1], title)))
- {
- VALUE tmpstr = ATTR(args.a[1], title);
+ if (argc == 2) {
+ if (RTEST(ATTR(args.a[1], title))) {
+ VALUE tmpstr = ATTR(args.a[1], title);
strcpy(atitle,RSTRING_PTR(shoes_native_to_s(tmpstr)));
- }
- else
- {
+ } else {
g_stpcpy(atitle," ");
}
}
GtkWidget *dialog = gtk_message_dialog_new_with_markup(
- window_app, GTK_DIALOG_MODAL, GTK_MESSAGE_INFO, GTK_BUTTONS_OK,
- format_string, atitle, msg );
+ window_app, GTK_DIALOG_MODAL, GTK_MESSAGE_INFO, GTK_BUTTONS_OK,
+ format_string, atitle, msg );
gtk_dialog_run(GTK_DIALOG(dialog));
gtk_widget_destroy(dialog);
return Qnil;
}
-VALUE
-shoes_dialog_ask(int argc, VALUE *argv, VALUE self)
-{
- char atitle[50];
- GTK_APP_VAR(app);
-
- VALUE answer = Qnil;
- rb_arg_list args;
- rb_parse_args(argc, argv, "S|h", &args);
-
- switch(argc)
- {
- case 1:
- sprintf(atitle, "%s asks", title_app);
- break;
- case 2:
- if (RTEST(ATTR(args.a[1], title)))
- {
- VALUE tmpstr = ATTR(args.a[1], title);
- strcpy(atitle, RSTRING_PTR(shoes_native_to_s(tmpstr)));
- }
- else
- {
- g_stpcpy(atitle," ");
- }
- break;
+VALUE shoes_dialog_ask(int argc, VALUE *argv, VALUE self) {
+ char atitle[50];
+ GTK_APP_VAR(app);
+
+ VALUE answer = Qnil;
+ rb_arg_list args;
+ rb_parse_args(argc, argv, "S|h", &args);
+
+ switch(argc) {
+ case 1:
+ sprintf(atitle, "%s asks", title_app);
+ break;
+ case 2:
+ if (RTEST(ATTR(args.a[1], title))) {
+ VALUE tmpstr = ATTR(args.a[1], title);
+ strcpy(atitle, RSTRING_PTR(shoes_native_to_s(tmpstr)));
+ } else {
+ g_stpcpy(atitle," ");
+ }
+ break;
}
- //GtkWidget *dialog = gtk_dialog_new_with_buttons(atitle, APP_WINDOW(app), GTK_DIALOG_MODAL,
- // _("_Cancel"), GTK_RESPONSE_CANCEL, _("_OK"), GTK_RESPONSE_OK, NULL);
- GtkWidget *dialog = gtk_dialog_new_with_buttons(atitle, window_app, GTK_DIALOG_MODAL,
- _("_Cancel"), GTK_RESPONSE_CANCEL, _("_OK"), GTK_RESPONSE_OK, NULL);
-
- gtk_container_set_border_width(GTK_CONTAINER(dialog), 6);
- gtk_container_set_border_width(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), 6);
- GtkWidget *question = gtk_label_new(RSTRING_PTR(shoes_native_to_s(args.a[0])));
- gtk_misc_set_alignment(GTK_MISC(question), 0, 0);
- GtkWidget *_answer = gtk_entry_new();
- if (RTEST(ATTR(args.a[1], secret))) shoes_native_secrecy(_answer);
- gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), question, FALSE, FALSE, 3);
- gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), _answer, FALSE, TRUE, 3);
-
- gtk_widget_show_all(dialog);
- gint result = gtk_dialog_run(GTK_DIALOG(dialog));
- if (result == GTK_RESPONSE_OK)
- {
- const gchar *txt = gtk_entry_get_text(GTK_ENTRY(_answer));
- answer = rb_str_new2(txt);
- }
- gtk_widget_destroy(dialog);
- return answer;
-}
-
-
-VALUE
-shoes_dialog_confirm(int argc, VALUE *argv, VALUE self)
-{
- VALUE answer = Qfalse;
- char atitle[50];
- GTK_APP_VAR(app);
- //char *apptitle = RSTRING_PTR(app->title);
- rb_arg_list args;
- rb_parse_args(argc, argv, "S|h", &args);
- VALUE quiz = shoes_native_to_s(args.a[0]);
-
- switch(argc)
- {
- case 1:
- sprintf(atitle, "%s asks", title_app);
- break;
- case 2:
- if (RTEST(ATTR(args.a[1], title)))
- {
- VALUE tmpstr = ATTR(args.a[1], title);
- strcpy(atitle, RSTRING_PTR(shoes_native_to_s(tmpstr)));
- }
- else
- {
- g_stpcpy(atitle," ");
- }
- break;
+ //GtkWidget *dialog = gtk_dialog_new_with_buttons(atitle, APP_WINDOW(app), GTK_DIALOG_MODAL,
+ // _("_Cancel"), GTK_RESPONSE_CANCEL, _("_OK"), GTK_RESPONSE_OK, NULL);
+ GtkWidget *dialog = gtk_dialog_new_with_buttons(atitle, window_app, GTK_DIALOG_MODAL,
+ _("_Cancel"), GTK_RESPONSE_CANCEL, _("_OK"), GTK_RESPONSE_OK, NULL);
+
+ gtk_container_set_border_width(GTK_CONTAINER(dialog), 6);
+ gtk_container_set_border_width(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), 6);
+ GtkWidget *question = gtk_label_new(RSTRING_PTR(shoes_native_to_s(args.a[0])));
+ gtk_misc_set_alignment(GTK_MISC(question), 0, 0);
+ GtkWidget *_answer = gtk_entry_new();
+ if (RTEST(ATTR(args.a[1], secret))) shoes_native_secrecy(_answer);
+ gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), question, FALSE, FALSE, 3);
+ gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), _answer, FALSE, TRUE, 3);
+
+ gtk_widget_show_all(dialog);
+ gint result = gtk_dialog_run(GTK_DIALOG(dialog));
+ if (result == GTK_RESPONSE_OK) {
+ const gchar *txt = gtk_entry_get_text(GTK_ENTRY(_answer));
+ answer = rb_str_new2(txt);
+ }
+ gtk_widget_destroy(dialog);
+ return answer;
+}
+
+
+VALUE shoes_dialog_confirm(int argc, VALUE *argv, VALUE self) {
+ VALUE answer = Qfalse;
+ char atitle[50];
+ GTK_APP_VAR(app);
+ //char *apptitle = RSTRING_PTR(app->title);
+ rb_arg_list args;
+ rb_parse_args(argc, argv, "S|h", &args);
+ VALUE quiz = shoes_native_to_s(args.a[0]);
+
+ switch(argc) {
+ case 1:
+ sprintf(atitle, "%s asks", title_app);
+ break;
+ case 2:
+ if (RTEST(ATTR(args.a[1], title))) {
+ VALUE tmpstr = ATTR(args.a[1], title);
+ strcpy(atitle, RSTRING_PTR(shoes_native_to_s(tmpstr)));
+ } else {
+ g_stpcpy(atitle," ");
+ }
+ break;
}
- //GtkWidget *dialog = gtk_dialog_new_with_buttons(atitle, APP_WINDOW(app), GTK_DIALOG_MODAL,
- // _("_Cancel"), GTK_RESPONSE_CANCEL, _("_OK"), GTK_RESPONSE_OK, NULL);
- GtkWidget *dialog = gtk_dialog_new_with_buttons(atitle, window_app, GTK_DIALOG_MODAL,
- _("_Cancel"), GTK_RESPONSE_CANCEL, _("_OK"), GTK_RESPONSE_OK, NULL);
+ //GtkWidget *dialog = gtk_dialog_new_with_buttons(atitle, APP_WINDOW(app), GTK_DIALOG_MODAL,
+ // _("_Cancel"), GTK_RESPONSE_CANCEL, _("_OK"), GTK_RESPONSE_OK, NULL);
+ GtkWidget *dialog = gtk_dialog_new_with_buttons(atitle, window_app, GTK_DIALOG_MODAL,
+ _("_Cancel"), GTK_RESPONSE_CANCEL, _("_OK"), GTK_RESPONSE_OK, NULL);
- gtk_container_set_border_width(GTK_CONTAINER(dialog), 6);
- gtk_container_set_border_width(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), 6);
+ gtk_container_set_border_width(GTK_CONTAINER(dialog), 6);
+ gtk_container_set_border_width(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), 6);
- GtkWidget *question = gtk_label_new(RSTRING_PTR(quiz));
- gtk_misc_set_alignment(GTK_MISC(question), 0, 0);
+ GtkWidget *question = gtk_label_new(RSTRING_PTR(quiz));
+ gtk_misc_set_alignment(GTK_MISC(question), 0, 0);
- gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), question, FALSE, FALSE, 3);
+ gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), question, FALSE, FALSE, 3);
- gtk_widget_show_all(dialog);
- gint result = gtk_dialog_run(GTK_DIALOG(dialog));
- if (result == GTK_RESPONSE_OK)
- answer = Qtrue;
- gtk_widget_destroy(dialog);
- return answer;
+ gtk_widget_show_all(dialog);
+ gint result = gtk_dialog_run(GTK_DIALOG(dialog));
+ if (result == GTK_RESPONSE_OK)
+ answer = Qtrue;
+ gtk_widget_destroy(dialog);
+ return answer;
}
-VALUE
-shoes_dialog_color(VALUE self, VALUE title)
-{
- VALUE color = Qnil;
- GTK_APP_VAR(app);
- title = shoes_native_to_s(title);
- GtkWidget *dialog = gtk_color_chooser_dialog_new(RSTRING_PTR(title), NULL);
- gint result = gtk_dialog_run(GTK_DIALOG(dialog));
- if (result == GTK_RESPONSE_OK)
- {
- GdkRGBA _color;
- gtk_color_chooser_get_rgba((GtkColorChooser *)dialog, &_color);
- color = shoes_color_new((int)(_color.red*255), (int)(_color.green*255),
- (int)(_color.blue*255), (int)(_color.alpha*255));
- }
-
- gtk_widget_destroy(dialog);
- return color;
-}
-
-
-VALUE
-shoes_dialog_chooser(VALUE self, char *title, GtkFileChooserAction act, const gchar *button, VALUE attr)
-{
- VALUE path = Qnil;
- GTK_APP_VAR(app);
- if (!NIL_P(attr) && !NIL_P(shoes_hash_get(attr, rb_intern("title"))))
- title = strdup(RSTRING_PTR(shoes_hash_get(attr, rb_intern("title"))));
- //GtkWidget *dialog = gtk_file_chooser_dialog_new(title, APP_WINDOW(app), act,
- // _("_Cancel"), GTK_RESPONSE_CANCEL, button, GTK_RESPONSE_ACCEPT, NULL);
- GtkWidget *dialog = gtk_file_chooser_dialog_new(title, window_app, act,
- _("_Cancel"), GTK_RESPONSE_CANCEL, button, GTK_RESPONSE_ACCEPT, NULL);
- if (act == GTK_FILE_CHOOSER_ACTION_SAVE)
- gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), TRUE);
- if(RTEST(shoes_hash_get(attr, rb_intern("save"))))
- gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog),
- RSTRING_PTR(shoes_hash_get(attr, rb_intern("save"))));
- if(RTEST(shoes_hash_get(attr, rb_intern("types"))) && TYPE(shoes_hash_get(attr, rb_intern("types"))) == T_HASH) {
- VALUE hsh = shoes_hash_get(attr, rb_intern("types"));
- VALUE keys = rb_funcall(hsh, s_keys, 0);
- int i;
- for(i = 0; i < RARRAY_LEN(keys); i++) {
- VALUE key = rb_ary_entry(keys, i);
- VALUE val = rb_hash_aref(hsh, key);
- GtkFileFilter *ff = gtk_file_filter_new();
- gtk_file_filter_set_name(ff, RSTRING_PTR(key));
- gtk_file_filter_add_pattern(ff, RSTRING_PTR(val));
- gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), ff);
+VALUE shoes_dialog_color(VALUE self, VALUE title) {
+ VALUE color = Qnil;
+ GTK_APP_VAR(app);
+ title = shoes_native_to_s(title);
+ GtkWidget *dialog = gtk_color_chooser_dialog_new(RSTRING_PTR(title), NULL);
+ gint result = gtk_dialog_run(GTK_DIALOG(dialog));
+ if (result == GTK_RESPONSE_OK) {
+ GdkRGBA _color;
+ gtk_color_chooser_get_rgba((GtkColorChooser *)dialog, &_color);
+ color = shoes_color_new((int)(_color.red*255), (int)(_color.green*255),
+ (int)(_color.blue*255), (int)(_color.alpha*255));
}
- }
- gint result = gtk_dialog_run(GTK_DIALOG(dialog));
- if (result == GTK_RESPONSE_ACCEPT)
- {
- char *filename;
- filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
- path = rb_str_new2(filename);
- }
- if (!NIL_P(attr) && !NIL_P(shoes_hash_get(attr, rb_intern("title"))))
- SHOE_FREE(title);
- gtk_widget_destroy(dialog);
- return path;
-}
-
-VALUE
-shoes_dialog_open(int argc, VALUE *argv, VALUE self)
-{
- rb_arg_list args;
+
+ gtk_widget_destroy(dialog);
+ return color;
+}
+
+VALUE shoes_dialog_chooser(VALUE self, char *title, GtkFileChooserAction act, const gchar *button, VALUE attr) {
+ VALUE path = Qnil;
+ GTK_APP_VAR(app);
+ if (!NIL_P(attr) && !NIL_P(shoes_hash_get(attr, rb_intern("title"))))
+ title = strdup(RSTRING_PTR(shoes_hash_get(attr, rb_intern("title"))));
+ //GtkWidget *dialog = gtk_file_chooser_dialog_new(title, APP_WINDOW(app), act,
+ // _("_Cancel"), GTK_RESPONSE_CANCEL, button, GTK_RESPONSE_ACCEPT, NULL);
+ GtkWidget *dialog = gtk_file_chooser_dialog_new(title, window_app, act,
+ _("_Cancel"), GTK_RESPONSE_CANCEL, button, GTK_RESPONSE_ACCEPT, NULL);
+ if (act == GTK_FILE_CHOOSER_ACTION_SAVE)
+ gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), TRUE);
+ if(RTEST(shoes_hash_get(attr, rb_intern("save"))))
+ gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog),
+ RSTRING_PTR(shoes_hash_get(attr, rb_intern("save"))));
+ if(RTEST(shoes_hash_get(attr, rb_intern("types"))) && TYPE(shoes_hash_get(attr, rb_intern("types"))) == T_HASH) {
+ VALUE hsh = shoes_hash_get(attr, rb_intern("types"));
+ VALUE keys = rb_funcall(hsh, s_keys, 0);
+ int i;
+ for(i = 0; i < RARRAY_LEN(keys); i++) {
+ VALUE key = rb_ary_entry(keys, i);
+ VALUE val = rb_hash_aref(hsh, key);
+ GtkFileFilter *ff = gtk_file_filter_new();
+ gtk_file_filter_set_name(ff, RSTRING_PTR(key));
+ gtk_file_filter_add_pattern(ff, RSTRING_PTR(val));
+ gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), ff);
+ }
+ }
+ gint result = gtk_dialog_run(GTK_DIALOG(dialog));
+ if (result == GTK_RESPONSE_ACCEPT) {
+ char *filename;
+ filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
+ path = rb_str_new2(filename);
+ }
+ if (!NIL_P(attr) && !NIL_P(shoes_hash_get(attr, rb_intern("title"))))
+ SHOE_FREE(title);
+ gtk_widget_destroy(dialog);
+ return path;
+}
+
+VALUE shoes_dialog_open(int argc, VALUE *argv, VALUE self) {
+ rb_arg_list args;
#if 0
- VALUE attr = Qnil;
- char *title;
- switch (rb_parse_args(argc, argv, "|h", &args)) {
- case 0:
- title = strdup("Open file...");
- break;
- case 1:
- attr = args.a[0];
- title = strdup(RSTRING_PTR(shoes_hash_get(attr, rb_intern("title"))));
- break;
- }
- shoes_dialog_chooser(self, title, GTK_FILE_CHOOSER_ACTION_OPEN,
- _("_Open"), args.a[0]);
- free(title);
- return;
+ VALUE attr = Qnil;
+ char *title;
+ switch (rb_parse_args(argc, argv, "|h", &args)) {
+ case 0:
+ title = strdup("Open file...");
+ break;
+ case 1:
+ attr = args.a[0];
+ title = strdup(RSTRING_PTR(shoes_hash_get(attr, rb_intern("title"))));
+ break;
+ }
+ shoes_dialog_chooser(self, title, GTK_FILE_CHOOSER_ACTION_OPEN,
+ _("_Open"), args.a[0]);
+ free(title);
+ return;
#else
- rb_parse_args(argc, argv, "|h", &args);
- return shoes_dialog_chooser(self, "Open file...", GTK_FILE_CHOOSER_ACTION_OPEN,
- _("_Open"), args.a[0]);
+ rb_parse_args(argc, argv, "|h", &args);
+ return shoes_dialog_chooser(self, "Open file...", GTK_FILE_CHOOSER_ACTION_OPEN,
+ _("_Open"), args.a[0]);
#endif
}
-VALUE
-shoes_dialog_save(int argc, VALUE *argv, VALUE self)
-{
- rb_arg_list args;
- rb_parse_args(argc, argv, "|h", &args);
- return shoes_dialog_chooser(self, "Save file...", GTK_FILE_CHOOSER_ACTION_SAVE,
- _("_Save"), args.a[0]);
+VALUE shoes_dialog_save(int argc, VALUE *argv, VALUE self) {
+ rb_arg_list args;
+ rb_parse_args(argc, argv, "|h", &args);
+ return shoes_dialog_chooser(self, "Save file...", GTK_FILE_CHOOSER_ACTION_SAVE,
+ _("_Save"), args.a[0]);
}
-VALUE
-shoes_dialog_open_folder(int argc, VALUE *argv, VALUE self)
-{
- rb_arg_list args;
- rb_parse_args(argc, argv, "|h", &args);
- return shoes_dialog_chooser(self, "Open folder...", GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
- _("_Open"), args.a[0]);
+VALUE shoes_dialog_open_folder(int argc, VALUE *argv, VALUE self) {
+ rb_arg_list args;
+ rb_parse_args(argc, argv, "|h", &args);
+ return shoes_dialog_chooser(self, "Open folder...", GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
+ _("_Open"), args.a[0]);
}
-VALUE
-shoes_dialog_save_folder(int argc, VALUE *argv, VALUE self)
-{
- rb_arg_list args;
- rb_parse_args(argc, argv, "|h", &args);
- return shoes_dialog_chooser(self, "Save folder...", GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER,
- _("_Save"), args.a[0]);
+VALUE shoes_dialog_save_folder(int argc, VALUE *argv, VALUE self) {
+ rb_arg_list args;
+ rb_parse_args(argc, argv, "|h", &args);
+ return shoes_dialog_chooser(self, "Save folder...", GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER,
+ _("_Save"), args.a[0]);
}
// July 2016 - Windows Fun!
@@ -1875,49 +1396,43 @@ shoes_dialog_save_folder(int argc, VALUE *argv, VALUE self)
/*
* This is only called when a shoe script uses the font(filename) command
* so the file name is lacuna.ttf, coolvetica.ttf (Shoes splash or the
- * Shoes manual) or a user supplied font
+ * Shoes manual) or a user supplied font
*/
-VALUE
-shoes_load_font(const char *filename)
-{
- VALUE allfonts, newfonts, oldfonts;
- // get current fconfig. Add the font to it so pango can find it.
- FcConfig *fc = FcConfigGetCurrent();
- FcBool yay = FcConfigAppFontAddFile(fc, (const FcChar8 *)filename);
- if (yay == FcFalse) {
- printf("failed to add font %s ?\n", filename);
- }
- // the Shoes api says an array of all fonts is returned. After a
- // font load, the Shoes fontlist must be updated. Use the much faster
- // Windows api. First, make sure Windows knows about the new one.
- int fonts = AddFontResourceEx(filename, FR_PRIVATE, 0);
- if (!fonts) return Qnil;
- allfonts = shoes_font_list();
- oldfonts = rb_const_get(cShoes, rb_intern("FONTS"));
- newfonts = rb_funcall(allfonts, rb_intern("-"), 1, oldfonts);
- shoes_update_fonts(allfonts);
- return newfonts;
-}
-
-static int CALLBACK
-shoes_font_list_iter(const ENUMLOGFONTEX *font, const NEWTEXTMETRICA *pfont, DWORD type, LPARAM l)
-{
- VALUE ary = (VALUE)l;
- rb_ary_push(l, rb_str_new2(font->elfLogFont.lfFaceName));
- return TRUE;
-}
-
-VALUE
-shoes_font_list()
-{
- LOGFONT font = {0, 0, 0, 0, 0, 0, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, ""};
- VALUE ary = rb_ary_new();
- HDC dc = GetDC(NULL);
- EnumFontFamiliesEx(dc, &font, (FONTENUMPROC)shoes_font_list_iter, (LPARAM)ary, 0);
- ReleaseDC(NULL, dc);
- rb_funcall(ary, rb_intern("uniq!"), 0);
- rb_funcall(ary, rb_intern("sort!"), 0);
- return ary;
+VALUE shoes_load_font(const char *filename) {
+ VALUE allfonts, newfonts, oldfonts;
+ // get current fconfig. Add the font to it so pango can find it.
+ FcConfig *fc = FcConfigGetCurrent();
+ FcBool yay = FcConfigAppFontAddFile(fc, (const FcChar8 *)filename);
+ if (yay == FcFalse) {
+ printf("failed to add font %s ?\n", filename);
+ }
+ // the Shoes api says an array of all fonts is returned. After a
+ // font load, the Shoes fontlist must be updated. Use the much faster
+ // Windows api. First, make sure Windows knows about the new one.
+ int fonts = AddFontResourceEx(filename, FR_PRIVATE, 0);
+ if (!fonts) return Qnil;
+ allfonts = shoes_font_list();
+ oldfonts = rb_const_get(cShoes, rb_intern("FONTS"));
+ newfonts = rb_funcall(allfonts, rb_intern("-"), 1, oldfonts);
+ shoes_update_fonts(allfonts);
+ return newfonts;
+}
+
+static int CALLBACK shoes_font_list_iter(const ENUMLOGFONTEX *font, const NEWTEXTMETRICA *pfont, DWORD type, LPARAM l) {
+ //VALUE ary = (VALUE)l; // TODO: compiler warning, remove because unused
+ rb_ary_push(l, rb_str_new2(font->elfLogFont.lfFaceName));
+ return TRUE;
+}
+
+VALUE shoes_font_list() {
+ LOGFONT font = {0, 0, 0, 0, 0, 0, 0, 0, DEFAULT_CHARSET, 0, 0, 0, 0, ""};
+ VALUE ary = rb_ary_new();
+ HDC dc = GetDC(NULL);
+ EnumFontFamiliesEx(dc, &font, (FONTENUMPROC)shoes_font_list_iter, (LPARAM)ary, 0);
+ ReleaseDC(NULL, dc);
+ rb_funcall(ary, rb_intern("uniq!"), 0);
+ rb_funcall(ary, rb_intern("sort!"), 0);
+ return ary;
}
// hat tip: https://justcheckingonall.wordpress.com/2008/08/29/console-window-win32-app/
@@ -1929,13 +1444,12 @@ shoes_font_list()
static FILE* shoes_console_out = NULL;
static FILE* shoes_console_in = NULL;
-int shoes_win32_console()
-{
-
+int shoes_win32_console() {
+
if (AllocConsole() == 0) {
- // cshoes.exe can get here
- printf("Already have console\n");
- return 0;
+ // cshoes.exe can get here
+ printf("Already have console\n");
+ return 0;
}
HANDLE handle_out = GetStdHandle(STD_OUTPUT_HANDLE);
@@ -1948,28 +1462,27 @@ int shoes_win32_console()
FILE* hf_in = _fdopen(hCrt, "r");
setvbuf(hf_in, NULL, _IONBF, 128);
*stdin = *hf_in;
-
- //* stash handles
+
+ //* stash handles
shoes_console_out = hf_out;
shoes_console_in = hf_in;
return 1;
}
// Called by Shoes after ruby/gtk/shoes is initialized and running
-int shoes_native_terminal()
-{
- // has a console been setup by --console flag?
- if (shoes_console_out == NULL) {
- if (shoes_win32_console() == 0) // cshoes.exe can do this
- return 1;
- }
- // convert the (cached) FILE * for what ruby wants for fd[0], [1]...
+int shoes_native_terminal() {
+ // has a console been setup by --console flag?
+ if (shoes_console_out == NULL) {
+ if (shoes_win32_console() == 0) // cshoes.exe can do this
+ return 1;
+ }
+ // convert the (cached) FILE * for what ruby wants for fd[0], [1]...
if (dup2(_fileno(shoes_console_out), 1) == -1)
- printf("failed dup2 of stdout\n");
+ printf("failed dup2 of stdout\n");
if (dup2(_fileno(shoes_console_out), 2) == -1)
- printf("failed dup2 of stderr\n");
+ printf("failed dup2 of stderr\n");
if (dup2(_fileno(shoes_console_in), 0) == -1)
- printf("failed dup2 of stdin\n");
+ printf("failed dup2 of stdin\n");
printf("created win32 console\n");
return 1;
}
@@ -1982,5 +1495,5 @@ int shoes_native_console(char *app_path)
printf("gtk\010k\t console \t\tcreated\n"); //test \b \t in string
return 1;
}
-*/
+*/
#endif
diff --git a/shoes/native/gtk.h b/shoes/native/gtk.h
new file mode 100644
index 00000000..560f90ba
--- /dev/null
+++ b/shoes/native/gtk.h
@@ -0,0 +1,3 @@
+#define GTK_CHILD(child, ptr) \
+ GList *children = gtk_container_get_children(GTK_CONTAINER(ptr)); \
+ child = children->data
diff --git a/shoes/native/gtk/gtkbuttonalt.c b/shoes/native/gtk/gtkbuttonalt.c
new file mode 100644
index 00000000..e18871bc
--- /dev/null
+++ b/shoes/native/gtk/gtkbuttonalt.c
@@ -0,0 +1,78 @@
+#include "shoes/app.h"
+#include "shoes/ruby.h"
+#include "shoes/config.h"
+#include "shoes/world.h"
+#include "shoes/native/native.h"
+#include "shoes/internal.h"
+
+#include "gtkbuttonalt.h"
+
+/* Private class member */
+#define GTK_BUTTON_ALT_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), \
+ GTK_TYPE_BUTTON_ALT, GtkButton_AltPrivate))
+
+typedef struct _GtkButton_AltPrivate GtkButton_AltPrivate;
+
+struct _GtkButton_AltPrivate {
+ /* to avoid warnings (g_type_class_add_private: assertion `private_size > 0' failed) */
+ gchar dummy;
+};
+
+/* Forward declarations */
+static void gtk_button_alt_get_preferred_width(GtkWidget *widget,
+ int *minimal, int *natural);
+static void gtk_button_alt_get_preferred_height(GtkWidget *widget,
+ int *minimal, int *natural);
+
+/* Define the GtkButton_Alt type and inherit from GtkButton */
+G_DEFINE_TYPE(GtkButton_Alt, gtk_button_alt, GTK_TYPE_BUTTON);
+
+/* Initialize the GtkButton_Alt class */
+static void gtk_button_alt_class_init(GtkButton_AltClass *klass) {
+ /* Override GtkWidget methods */
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
+ widget_class->get_preferred_width = gtk_button_alt_get_preferred_width;
+ widget_class->get_preferred_height = gtk_button_alt_get_preferred_height;
+
+ /* Override GtkButton methods */
+ // TODO: determine whether gobject_class has any use.
+ //GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ // ...
+
+ /* Add private indirection member */
+ g_type_class_add_private(klass, sizeof(GtkButton_AltPrivate));
+}
+
+/* Initialize a new GtkButton_Alt instance */
+static void gtk_button_alt_init(GtkButton_Alt *buttontAlt) {
+ /* This means that GtkButton_Alt doesn't supply its own GdkWindow */
+ gtk_widget_set_has_window(GTK_WIDGET(buttontAlt), FALSE);
+
+ /* Initialize private members */
+ // TODO: determine whether priv has any use.
+ //GtkButton_AltPrivate *priv = GTK_BUTTON_ALT_PRIVATE(buttontAlt);
+
+}
+
+/* Return a new GtkButton_Alt cast to a GtkWidget */
+GtkWidget *gtk_button_alt_new() {
+ return GTK_WIDGET(g_object_new(gtk_button_alt_get_type(), NULL));
+}
+
+GtkWidget *gtk_button_alt_new_with_label(const gchar *label) {
+ return GTK_WIDGET(g_object_new (gtk_button_alt_get_type(), "label", label, NULL));
+}
+
+static void gtk_button_alt_get_preferred_width(GtkWidget *widget, int *minimal, int *natural) {
+ g_return_if_fail(widget != NULL);
+
+ *minimal = 1;
+ *natural = 1;
+}
+
+static void gtk_button_alt_get_preferred_height(GtkWidget *widget, int *minimal, int *natural) {
+ g_return_if_fail(widget != NULL);
+
+ *minimal = 1;
+ *natural = 1;
+}
diff --git a/shoes/native/gtkbuttonalt.h b/shoes/native/gtk/gtkbuttonalt.h
similarity index 100%
rename from shoes/native/gtkbuttonalt.h
rename to shoes/native/gtk/gtkbuttonalt.h
diff --git a/shoes/native/gtk/gtkcheck.c b/shoes/native/gtk/gtkcheck.c
new file mode 100644
index 00000000..42520ba4
--- /dev/null
+++ b/shoes/native/gtk/gtkcheck.c
@@ -0,0 +1,40 @@
+#include "shoes/app.h"
+#include "shoes/ruby.h"
+#include "shoes/config.h"
+#include "shoes/world.h"
+#include "shoes/native/native.h"
+#include "shoes/internal.h"
+#include "shoes/native/gtk/gtkcheck.h"
+
+SHOES_CONTROL_REF shoes_native_check(VALUE self, shoes_canvas *canvas, shoes_place *place, VALUE attr, char *msg) {
+ SHOES_CONTROL_REF ref = gtk_check_button_new();
+ // set visual state before connecting signal
+ if (RTEST(ATTR(attr, checked))) {
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ref), TRUE);
+ }
+
+ if (!NIL_P(shoes_hash_get(attr, rb_intern("checked")))) {
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ref), shoes_hash_get(attr, rb_intern("checked")) == Qtrue);
+ }
+
+ if (!NIL_P(shoes_hash_get(attr, rb_intern("tooltip")))) {
+ gtk_widget_set_tooltip_text(GTK_WIDGET(ref), RSTRING_PTR(shoes_hash_get(attr, rb_intern("tooltip"))));
+ }
+
+ g_signal_connect(G_OBJECT(ref), "clicked",
+ G_CALLBACK(shoes_button_gtk_clicked),
+ (gpointer)self);
+ return ref;
+}
+
+VALUE shoes_native_check_get(SHOES_CONTROL_REF ref) {
+ return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ref)) ? Qtrue : Qfalse;
+}
+
+void shoes_native_check_set(SHOES_CONTROL_REF ref, int on) {
+ // bug264 - don't toggle if already set to desired state.
+ gboolean new_state;
+ new_state = on ? TRUE : FALSE;
+ if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ref)) != new_state)
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ref), new_state);
+}
diff --git a/shoes/native/gtk/gtkcheck.h b/shoes/native/gtk/gtkcheck.h
new file mode 100644
index 00000000..649d5bb7
--- /dev/null
+++ b/shoes/native/gtk/gtkcheck.h
@@ -0,0 +1,13 @@
+#ifndef SHOES_GTK_CHECK_H
+#define SHOES_GTK_CHECK_H
+
+SHOES_CONTROL_REF shoes_native_check(VALUE self, shoes_canvas *canvas, shoes_place *place, VALUE attr, char *msg);
+VALUE shoes_native_check_get(SHOES_CONTROL_REF ref);
+void shoes_native_check_set(SHOES_CONTROL_REF ref, int on);
+
+SYMBOL_EXTERN(checked);
+
+// gtk forward declaration
+extern gboolean shoes_button_gtk_clicked(GtkButton *button, gpointer data);
+
+#endif
diff --git a/shoes/native/gtk/gtkcomboboxtextalt.c b/shoes/native/gtk/gtkcomboboxtextalt.c
new file mode 100644
index 00000000..3488fe0a
--- /dev/null
+++ b/shoes/native/gtk/gtkcomboboxtextalt.c
@@ -0,0 +1,227 @@
+#include "shoes/app.h"
+#include "shoes/ruby.h"
+#include "shoes/config.h"
+#include "shoes/world.h"
+#include "shoes/native/native.h"
+#include "shoes/internal.h"
+
+#include "gtkcomboboxtextalt.h"
+//#include
+
+
+struct _GtkComboBoxPrivate {
+ GtkTreeModel *model;
+
+ GtkCellArea *area;
+
+ gint col_column;
+ gint row_column;
+
+ gint wrap_width;
+ GtkShadowType shadow_type;
+
+ gint active; /* Only temporary */
+ GtkTreeRowReference *active_row;
+
+ GtkWidget *tree_view;
+
+ GtkWidget *cell_view;
+ GtkWidget *cell_view_frame;
+
+ GtkWidget *button;
+ GtkWidget *box;
+ GtkWidget *arrow;
+ GtkWidget *separator;
+
+ GtkWidget *popup_widget;
+ GtkWidget *popup_window;
+ GtkWidget *scrolled_window;
+
+ gulong inserted_id;
+ gulong deleted_id;
+ gulong reordered_id;
+ gulong changed_id;
+ guint popup_idle_id;
+ guint activate_button;
+ guint32 activate_time;
+ guint scroll_timer;
+ guint resize_idle_id;
+
+ /* For "has-entry" specific behavior we track
+ * an automated cell renderer and text column
+ */
+ gint text_column;
+ GtkCellRenderer *text_renderer;
+
+ gint id_column;
+
+ guint popup_in_progress : 1;
+ guint popup_shown : 1;
+ guint add_tearoffs : 1;
+ guint has_frame : 1;
+ guint is_cell_renderer : 1;
+ guint editing_canceled : 1;
+ guint auto_scroll : 1;
+ guint focus_on_click : 1;
+ guint button_sensitivity : 2;
+ guint has_entry : 1;
+ guint popup_fixed_width : 1;
+
+ GtkTreeViewRowSeparatorFunc row_separator_func;
+ gpointer row_separator_data;
+ GDestroyNotify row_separator_destroy;
+
+ GdkDevice *grab_pointer;
+ GdkDevice *grab_keyboard;
+
+ gchar *tearoff_title;
+};
+
+/* Private class member */
+#define GTK_COMBOBOXTEXT_ALT_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), \
+ GTK_TYPE_COMBO_BOX_TEXT_ALT, GtkComboBoxText_AltPrivate))
+
+typedef struct _GtkComboBoxText_AltPrivate GtkComboBoxText_AltPrivate;
+
+struct _GtkComboBoxText_AltPrivate {
+ /* to avoid warnings (g_type_class_add_private: assertion `private_size > 0' failed) */
+ gchar dummy;
+};
+
+/* Forward declarations */
+static void gtk_combo_box_text_alt_get_preferred_width(GtkWidget *widget,
+ int *minimal, int *natural);
+static void gtk_combo_box_text_alt_get_preferred_height(GtkWidget *widget,
+ int *minimal, int *natural);
+static void gtk_combo_box_text_alt_get_preferred_height_for_width(GtkWidget *widget,
+ gint avail_size, gint *minimum_size, gint *natural_size);
+static void gtk_combo_box_text_alt_get_preferred_width_for_height(GtkWidget *widget,
+ gint avail_size, gint *minimum_size, gint *natural_size);
+
+/* Define the GtkComboBoxText_Alt type and inherit from GtkComboBoxText */
+G_DEFINE_TYPE(GtkComboBoxText_Alt, gtk_combo_box_text_alt, GTK_TYPE_COMBO_BOX_TEXT);
+
+/* Initialize the GtkComboBoxText_Alt class */
+static void gtk_combo_box_text_alt_class_init(GtkComboBoxText_AltClass *klass) {
+ /* Override GtkWidget methods */
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
+ widget_class->get_preferred_width = gtk_combo_box_text_alt_get_preferred_width;
+ widget_class->get_preferred_height = gtk_combo_box_text_alt_get_preferred_height;
+ widget_class->get_preferred_height_for_width = gtk_combo_box_text_alt_get_preferred_height_for_width;
+ widget_class->get_preferred_width_for_height = gtk_combo_box_text_alt_get_preferred_width_for_height;
+
+ /* Override GtkComboBoxText methods */
+ // TODO: determine whether gobject_class has any use.
+ // GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+ // ...
+
+ /* Add private indirection member */
+ g_type_class_add_private(klass, sizeof(GtkComboBoxText_AltPrivate));
+}
+
+/* Initialize a new GtkComboBoxText_Alt instance */
+static void gtk_combo_box_text_alt_init(GtkComboBoxText_Alt *comboboxtextAlt) {
+ /* This means that GtkComboBoxText_Alt doesn't supply its own GdkWindow */
+ gtk_widget_set_has_window(GTK_WIDGET(comboboxtextAlt), FALSE);
+
+ /* Initialize private members */
+ // TODO: determine whether priv has any use.
+ //GtkComboBoxText_AltPrivate *priv = GTK_COMBOBOXTEXT_ALT_PRIVATE(comboboxtextAlt);
+}
+
+/* Return a new GtkComboBoxText_Alt cast to a GtkWidget */
+GtkWidget *gtk_combo_box_text_alt_new(VALUE attribs, int bottom_margin) {
+ GtkWidget *ref;
+ ref = GTK_WIDGET(g_object_new(gtk_combo_box_text_alt_get_type(), NULL));
+
+ /* emulating gtk2 defaults*/
+ int w = 160, h = 30;
+ if (RTEST(ATTR(attribs, width))) w = NUM2INT(ATTR(attribs, width));
+ if (RTEST(ATTR(attribs, height))) h = NUM2INT(ATTR(attribs, height));
+
+ //GtkCellArea *area = gtk_cell_layout_get_area((GtkCellLayout *)ref);
+ GList *renderers = gtk_cell_layout_get_cells((GtkCellLayout *)ref);
+ GtkCellRendererText *cell = g_list_first(renderers)->data; //only one renderer
+ g_list_free(renderers);
+ gtk_cell_renderer_set_fixed_size((GtkCellRenderer *)cell, w, h-bottom_margin*2);
+ if (RTEST(ATTR(attribs, font))) {
+ char *fontnm = RSTRING_PTR(ATTR(attribs, font));
+ g_object_set((GtkCellRenderer *)cell, "font", fontnm, NULL);
+ }
+ if (RTEST(ATTR(attribs, wrap))) {
+ g_object_set((GtkCellRenderer *)cell, "wrap-width", w, NULL);
+ char *wrapstr = RSTRING_PTR(ATTR(attribs, wrap));
+ if (strcmp(wrapstr, "char") == 0)
+ g_object_set((GtkCellRenderer *)cell, "wrap-mode", PANGO_WRAP_CHAR, NULL);
+ else if (strcmp(wrapstr, "word") == 0)
+ g_object_set((GtkCellRenderer *)cell, "wrap-mode", PANGO_WRAP_WORD, NULL);
+ else if (strcmp(wrapstr, "trim") == 0)
+ g_object_set((GtkCellRenderer *)cell, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
+ } else {
+ g_object_set((GtkCellRenderer *)cell, "ellipsize", PANGO_ELLIPSIZE_MIDDLE, NULL);
+ }
+ return ref;
+}
+
+static void gtk_combo_box_text_alt_get_preferred_width(GtkWidget *widget, int *minimal, int *natural) {
+ g_return_if_fail(widget != NULL);
+
+ /* This is how we can access private data from parent Widget
+ GtkComboBox *combo_box = GTK_COMBO_BOX(widget);
+ GtkComboBoxPrivate *priv = G_TYPE_INSTANCE_GET_PRIVATE(combo_box,
+ GTK_TYPE_COMBO_BOX,
+ GtkComboBoxPrivate);
+ gint box_width;
+ gtk_widget_get_preferred_width(priv->box, &box_width, NULL);
+ */
+
+ GList *renderers = gtk_cell_layout_get_cells((GtkCellLayout *)widget);
+ GtkCellRenderer *cell = g_list_first(renderers)->data; //only one renderer
+ g_list_free(renderers);
+ gint cell_width, cell_height;
+ gtk_cell_renderer_get_fixed_size(cell, &cell_width, &cell_height);
+
+ *minimal = cell_width;
+ *natural = cell_width;
+}
+
+static void gtk_combo_box_text_alt_get_preferred_height(GtkWidget *widget, int *minimal, int *natural) {
+ g_return_if_fail(widget != NULL);
+
+ /* Combo box is height-for-width only
+ * (so we always just reserve enough height for the minimum width) */
+ gint min_width, nat_width;
+ GTK_WIDGET_GET_CLASS(widget)->get_preferred_width(widget, &min_width, &nat_width);
+ GTK_WIDGET_GET_CLASS(widget)->get_preferred_height_for_width(widget, min_width, minimal, natural);
+
+}
+
+static void gtk_combo_box_text_alt_get_preferred_width_for_height(GtkWidget *widget,
+ gint avail_size,
+ gint *minimum_size,
+ gint *natural_size) {
+ /* Combo box is height-for-width only
+ * (so we assume we always reserved enough height for the minimum width) */
+ GTK_WIDGET_GET_CLASS(widget)->get_preferred_width(widget, minimum_size, natural_size);
+}
+
+static void gtk_combo_box_text_alt_get_preferred_height_for_width(GtkWidget *widget,
+ gint avail_size,
+ gint *minimum_size,
+ gint *natural_size) {
+ GList *renderers = gtk_cell_layout_get_cells((GtkCellLayout *)widget);
+ GtkCellRenderer *cell = g_list_first(renderers)->data; //only one renderer
+ g_list_free(renderers);
+
+ GtkRequisition min_size, nat_size;
+ gtk_cell_renderer_get_preferred_size(cell, widget, &min_size, &nat_size);
+
+ gint xpad, ypad;
+ gtk_cell_renderer_get_padding(cell, &xpad, &ypad);
+ gtk_cell_renderer_set_padding(cell, xpad, 0);
+
+ *minimum_size = min_size.height;
+ *natural_size = nat_size.height;
+
+}
+
diff --git a/shoes/native/gtkcomboboxtextalt.h b/shoes/native/gtk/gtkcomboboxtextalt.h
similarity index 100%
rename from shoes/native/gtkcomboboxtextalt.h
rename to shoes/native/gtk/gtkcomboboxtextalt.h
diff --git a/shoes/native/gtk/gtkeditbox.c b/shoes/native/gtk/gtkeditbox.c
new file mode 100644
index 00000000..05b1b7fc
--- /dev/null
+++ b/shoes/native/gtk/gtkeditbox.c
@@ -0,0 +1,78 @@
+#include "shoes/app.h"
+#include "shoes/ruby.h"
+#include "shoes/config.h"
+#include "shoes/world.h"
+#include "shoes/native/native.h"
+#include "shoes/internal.h"
+
+#include "shoes/native/gtk.h"
+#include "shoes/native/gtk/gtkscrolledwindowalt.h"
+#include "shoes/native/gtk/gtkeditbox.h"
+
+SHOES_CONTROL_REF shoes_native_edit_box(VALUE self, shoes_canvas *canvas, shoes_place *place, VALUE attr, char *msg) {
+ GtkTextBuffer *buffer;
+ GtkWidget* textview = gtk_text_view_new();
+ SHOES_CONTROL_REF ref = gtk_scrolled_window_alt_new(NULL, NULL);
+
+ if (!NIL_P(shoes_hash_get(attr, rb_intern("tooltip")))) {
+ gtk_widget_set_tooltip_text(GTK_WIDGET(ref), RSTRING_PTR(shoes_hash_get(attr, rb_intern("tooltip"))));
+ }
+
+ gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(textview), GTK_WRAP_WORD);
+ buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview));
+ gtk_text_buffer_set_text(buffer, _(msg), -1);
+ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(ref),
+ GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(ref), GTK_SHADOW_IN);
+ gtk_container_add(GTK_CONTAINER(ref), textview);
+
+ g_signal_connect(G_OBJECT(buffer), "changed",
+ G_CALLBACK(shoes_widget_changed),
+ (gpointer)self);
+
+ return ref;
+}
+
+VALUE shoes_native_edit_box_get_text(SHOES_CONTROL_REF ref) {
+ GtkWidget *textview;
+ GTK_CHILD(textview, ref);
+ GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview));
+ GtkTextIter begin, end;
+ gtk_text_buffer_get_bounds(buffer, &begin, &end);
+ return rb_str_new2(gtk_text_buffer_get_text(buffer, &begin, &end, TRUE));
+}
+
+void shoes_native_edit_box_set_text(SHOES_CONTROL_REF ref, char *msg) {
+ GtkWidget *textview;
+ GTK_CHILD(textview, ref);
+ GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview));
+ gtk_text_buffer_set_text(buffer, _(msg), -1);
+}
+
+void shoes_native_edit_box_append(SHOES_CONTROL_REF ref, char *msg) {
+ GtkWidget *textview;
+ GTK_CHILD(textview, ref);
+ GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview));
+ GtkTextIter begin, end;
+ gtk_text_buffer_get_bounds(buffer, &begin, &end);
+ gtk_text_buffer_insert(buffer, &end, msg, strlen(msg));
+ gtk_text_buffer_get_bounds(buffer, &begin, &end);
+
+}
+
+void shoes_native_edit_box_scroll_to_end(SHOES_CONTROL_REF ref) {
+ GtkWidget *textview;
+ GTK_CHILD(textview, ref);
+ GtkTextIter end;
+ GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview));
+ gtk_text_buffer_get_end_iter (buffer, &end);
+ /* get the current ( cursor )mark name */
+ GtkTextMark *insert_mark = gtk_text_buffer_get_insert (buffer);
+
+ /* move mark and selection bound to the end */
+ gtk_text_buffer_place_cursor(buffer, &end);
+
+ /* scroll to the end view */
+ gtk_text_view_scroll_to_mark( GTK_TEXT_VIEW (textview),
+ insert_mark, 0.0, TRUE, 0.0, 1.0);
+}
\ No newline at end of file
diff --git a/shoes/native/gtk/gtkeditbox.h b/shoes/native/gtk/gtkeditbox.h
new file mode 100644
index 00000000..6991bacd
--- /dev/null
+++ b/shoes/native/gtk/gtkeditbox.h
@@ -0,0 +1,14 @@
+#ifndef SHOES_GTK_EDIT_BOX_H
+#define SHOES_GTK_EDIT_BOX_H
+
+SHOES_CONTROL_REF shoes_native_edit_box(VALUE, shoes_canvas *, shoes_place *, VALUE, char *);
+VALUE shoes_native_edit_box_get_text(SHOES_CONTROL_REF);
+void shoes_native_edit_box_set_text(SHOES_CONTROL_REF, char *);
+// 3.2.25 adds
+void shoes_native_edit_box_append(SHOES_CONTROL_REF, char *);
+void shoes_native_edit_box_scroll_to_end(SHOES_CONTROL_REF);
+
+// gtk forward declaration
+extern void shoes_widget_changed(GtkWidget *ref, gpointer data);
+
+#endif
\ No newline at end of file
diff --git a/shoes/native/gtk/gtkeditline.c b/shoes/native/gtk/gtkeditline.c
new file mode 100644
index 00000000..c7a587ea
--- /dev/null
+++ b/shoes/native/gtk/gtkeditline.c
@@ -0,0 +1,54 @@
+#include "shoes/app.h"
+#include "shoes/ruby.h"
+#include "shoes/config.h"
+#include "shoes/world.h"
+#include "shoes/native/native.h"
+#include "shoes/types/native.h"
+#include "shoes/internal.h"
+
+#include "shoes/native/gtk/gtkentryalt.h"
+#include "shoes/native/gtk/gtkeditline.h"
+
+SHOES_CONTROL_REF shoes_native_edit_line(VALUE self, shoes_canvas *canvas, shoes_place *place, VALUE attr, char *msg) {
+ SHOES_CONTROL_REF ref = gtk_entry_alt_new();
+
+ if (RTEST(ATTR(attr, secret))) shoes_native_secrecy(ref);
+
+ if (!NIL_P(shoes_hash_get(attr, rb_intern("tooltip")))) {
+ gtk_widget_set_tooltip_text(GTK_WIDGET(ref), RSTRING_PTR(shoes_hash_get(attr, rb_intern("tooltip"))));
+ }
+
+ gtk_entry_set_text(GTK_ENTRY(ref), _(msg));
+
+ g_signal_connect(G_OBJECT(ref), "changed",
+ G_CALLBACK(shoes_widget_changed),
+ (gpointer)self);
+ // cjc: try to intercept \n bug 860 @ shoes4
+ g_signal_connect(G_OBJECT(ref), "activate",
+ G_CALLBACK(shoes_native_enterkey), // fix name?
+ (gpointer)self);
+
+ return ref;
+}
+
+VALUE shoes_native_edit_line_get_text(SHOES_CONTROL_REF ref) {
+ return rb_str_new2(gtk_entry_get_text(GTK_ENTRY(ref)));
+}
+
+void shoes_native_edit_line_set_text(SHOES_CONTROL_REF ref, char *msg) {
+ gtk_entry_set_text(GTK_ENTRY(ref), _(msg));
+}
+
+VALUE shoes_native_edit_line_cursor_to_end(SHOES_CONTROL_REF ref) {
+ gtk_editable_set_position(GTK_EDITABLE(ref), -1);
+ return Qnil;
+}
+
+void shoes_native_enterkey(GtkWidget *ref, gpointer data) {
+ VALUE self = (VALUE)data;
+ GET_STRUCT(control, self_t);
+ VALUE click = ATTR(self_t->attr, donekey);
+ if (!NIL_P(click)) {
+ shoes_safe_block(self_t->parent, click, rb_ary_new3(1, self));
+ }
+}
\ No newline at end of file
diff --git a/shoes/native/gtk/gtkeditline.h b/shoes/native/gtk/gtkeditline.h
new file mode 100644
index 00000000..c4c5145c
--- /dev/null
+++ b/shoes/native/gtk/gtkeditline.h
@@ -0,0 +1,14 @@
+#ifndef SHOES_GTK_EDIT_LINE_H
+#define SHOES_GTK_EDIT_LINE_H
+
+SHOES_CONTROL_REF shoes_native_edit_line(VALUE, shoes_canvas *, shoes_place *, VALUE, char *);
+VALUE shoes_native_edit_line_get_text(SHOES_CONTROL_REF);
+void shoes_native_edit_line_set_text(SHOES_CONTROL_REF, char *);
+VALUE shoes_native_edit_line_cursor_to_end(SHOES_CONTROL_REF);
+void shoes_native_enterkey(GtkWidget *ref, gpointer data);
+
+// gtk forward declaration
+extern void shoes_widget_changed(GtkWidget *ref, gpointer data);
+extern void shoes_native_secrecy(SHOES_CONTROL_REF ref);
+
+#endif
diff --git a/shoes/native/gtk/gtkentryalt.c b/shoes/native/gtk/gtkentryalt.c
new file mode 100644
index 00000000..b96bdae6
--- /dev/null
+++ b/shoes/native/gtk/gtkentryalt.c
@@ -0,0 +1,81 @@
+#include "shoes/app.h"
+#include "shoes/ruby.h"
+#include "shoes/config.h"
+#include "shoes/world.h"
+#include "shoes/native/native.h"
+#include "shoes/internal.h"
+
+#include "gtkentryalt.h"
+
+/* Private class member */
+#define GTKENTRY_ALT_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), \
+ GTK_TYPE_ENTRY_ALT, GtkEntry_AltPrivate))
+
+typedef struct _GtkEntry_AltPrivate GtkEntry_AltPrivate;
+
+struct _GtkEntry_AltPrivate {
+ /* to avoid warnings (g_type_class_add_private: assertion `private_size > 0' failed) */
+ gchar dummy;
+};
+
+/* Forward declarations */
+static void gtk_entry_alt_get_preferred_width(GtkWidget *widget,
+ int *minimal, int *natural);
+static void gtk_entry_alt_get_preferred_height(GtkWidget *widget,
+ int *minimal, int *natural);
+
+/* Define the GtkEntry_Alt type and inherit from GtkEntry */
+G_DEFINE_TYPE(GtkEntry_Alt, gtk_entry_alt, GTK_TYPE_ENTRY);
+
+/* Initialize the GtkEntry_Alt class */
+static void
+gtk_entry_alt_class_init(GtkEntry_AltClass *klass) {
+ /* Override GtkWidget methods */
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
+ widget_class->get_preferred_width = gtk_entry_alt_get_preferred_width;
+ widget_class->get_preferred_height = gtk_entry_alt_get_preferred_height;
+
+ /* Override GtkEntry methods */
+ // TODO: determine whether gobject_class has any use.
+ //GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ //GtkEntryClass *entry_class = GTK_ENTRY_CLASS(klass);
+ // ...
+
+ /* Add private indirection member */
+ g_type_class_add_private(klass, sizeof(GtkEntry_AltPrivate));
+}
+
+/* Initialize a new GtkEntry_Alt instance */
+static void
+gtk_entry_alt_init(GtkEntry_Alt *entryAlt) {
+ /* This means that GtkEntry_Alt doesn't supply its own GdkWindow */
+ gtk_widget_set_has_window(GTK_WIDGET(entryAlt), FALSE);
+
+ /* Initialize private members */
+ // TODO: determine whether priv has any use.
+ //GtkEntry_AltPrivate *priv = GTKENTRY_ALT_PRIVATE(entryAlt);
+
+}
+
+/* Return a new GtkEntry_Alt cast to a GtkWidget */
+GtkWidget *
+gtk_entry_alt_new() {
+ return GTK_WIDGET(g_object_new(gtk_entry_alt_get_type(), NULL));
+}
+
+
+static void
+gtk_entry_alt_get_preferred_width(GtkWidget *widget, int *minimal, int *natural) {
+ g_return_if_fail(widget != NULL);
+
+ *minimal = 1;
+ *natural = 1;
+}
+
+static void
+gtk_entry_alt_get_preferred_height(GtkWidget *widget, int *minimal, int *natural) {
+ g_return_if_fail(widget != NULL);
+
+ *minimal = 1;
+ *natural = 1;
+}
diff --git a/shoes/native/gtkentryalt.h b/shoes/native/gtk/gtkentryalt.h
similarity index 100%
rename from shoes/native/gtkentryalt.h
rename to shoes/native/gtk/gtkentryalt.h
diff --git a/shoes/native/gtkfixedalt.c b/shoes/native/gtk/gtkfixedalt.c
similarity index 59%
rename from shoes/native/gtkfixedalt.c
rename to shoes/native/gtk/gtkfixedalt.c
index e75aacb0..ec0f6a35 100644
--- a/shoes/native/gtkfixedalt.c
+++ b/shoes/native/gtk/gtkfixedalt.c
@@ -7,7 +7,7 @@
#include "shoes/ruby.h"
#include "shoes/config.h"
#include "shoes/world.h"
-#include "shoes/native.h"
+#include "shoes/native/native.h"
#include "shoes/internal.h"
#include "gtkfixedalt.h"
@@ -18,16 +18,15 @@
typedef struct _GtKFixed_AltPrivate GtKFixed_AltPrivate;
-struct _GtKFixed_AltPrivate
-{
- GList *children;
+struct _GtKFixed_AltPrivate {
+ GList *children;
};
/* Forward declarations */
static void gtkfixed_alt_get_preferred_width(GtkWidget *widget,
- int *minimal, int *natural);
+ int *minimal, int *natural);
static void gtkfixed_alt_get_preferred_height(GtkWidget *widget,
- int *minimal, int *natural);
+ int *minimal, int *natural);
//static void gtkfixed_alt_size_allocate(GtkWidget *widget,
// GtkAllocation *allocation);
//static GType gtkfixed_alt_child_type(GtkContainer *container);
@@ -38,39 +37,37 @@ G_DEFINE_TYPE(GtKFixed_Alt, gtkfixed_alt, GTK_TYPE_FIXED);
/* Initialize the GtKFixed_Alt class */
static void
-gtkfixed_alt_class_init(GtKFixed_AltClass *klass)
-{
- /* Override GtkWidget methods */
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
- widget_class->get_preferred_width = gtkfixed_alt_get_preferred_width;
- widget_class->get_preferred_height = gtkfixed_alt_get_preferred_height;
- //widget_class->size_allocate = gtkfixed_alt_size_allocate;
-
- /* Override GtkFixed methods */
- GtkFixedClass *fixed_class = GTK_FIXED_CLASS(klass);
+gtkfixed_alt_class_init(GtKFixed_AltClass *klass) {
+ /* Override GtkWidget methods */
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
+ widget_class->get_preferred_width = gtkfixed_alt_get_preferred_width;
+ widget_class->get_preferred_height = gtkfixed_alt_get_preferred_height;
+ //widget_class->size_allocate = gtkfixed_alt_size_allocate;
+
+ /* Override GtkFixed methods */
+ // TODO: determine whether fixed_class has any use.
+ //GtkFixedClass *fixed_class = GTK_FIXED_CLASS(klass);
// ...
- /* Add private indirection member */
- g_type_class_add_private(klass, sizeof(GtKFixed_AltPrivate));
+ /* Add private indirection member */
+ g_type_class_add_private(klass, sizeof(GtKFixed_AltPrivate));
}
/* Initialize a new GtKFixed_Alt instance */
static void
-gtkfixed_alt_init(GtKFixed_Alt *fixedAlt)
-{
- /* This means that GtKFixed_Alt doesn't supply its own GdkWindow */
- gtk_widget_set_has_window(GTK_WIDGET(fixedAlt), FALSE);
-
- /* Initialize private members */
- GtKFixed_AltPrivate *priv = GTKFIXED_ALT_PRIVATE(fixedAlt);
- priv->children = NULL;
+gtkfixed_alt_init(GtKFixed_Alt *fixedAlt) {
+ /* This means that GtKFixed_Alt doesn't supply its own GdkWindow */
+ gtk_widget_set_has_window(GTK_WIDGET(fixedAlt), FALSE);
+
+ /* Initialize private members */
+ GtKFixed_AltPrivate *priv = GTKFIXED_ALT_PRIVATE(fixedAlt);
+ priv->children = NULL;
}
/* Return a new GtKFixed_Alt cast to a GtkWidget */
GtkWidget *
-gtkfixed_alt_new()
-{
- return GTK_WIDGET(g_object_new(gtkfixed_alt_get_type(), NULL));
+gtkfixed_alt_new() {
+ return GTK_WIDGET(g_object_new(gtkfixed_alt_get_type(), NULL));
}
@@ -78,8 +75,7 @@ gtkfixed_alt_new()
* don't ask for children size so we can shrink as in gtk2
*/
static void
-gtkfixed_alt_get_preferred_width(GtkWidget *widget, int *minimal, int *natural)
-{
+gtkfixed_alt_get_preferred_width(GtkWidget *widget, int *minimal, int *natural) {
g_return_if_fail(widget != NULL);
g_return_if_fail(IS_GTKFIXED_ALT(widget));
@@ -91,8 +87,7 @@ gtkfixed_alt_get_preferred_width(GtkWidget *widget, int *minimal, int *natural)
* don't ask for children size so we can shrink as in gtk2
*/
static void
-gtkfixed_alt_get_preferred_height(GtkWidget *widget, int *minimal, int *natural)
-{
+gtkfixed_alt_get_preferred_height(GtkWidget *widget, int *minimal, int *natural) {
g_return_if_fail(widget != NULL);
g_return_if_fail(IS_GTKFIXED_ALT(widget));
diff --git a/shoes/native/gtkfixedalt.h b/shoes/native/gtk/gtkfixedalt.h
similarity index 100%
rename from shoes/native/gtkfixedalt.h
rename to shoes/native/gtk/gtkfixedalt.h
diff --git a/shoes/native/gtk/gtkprogressbaralt.c b/shoes/native/gtk/gtkprogressbaralt.c
new file mode 100644
index 00000000..891a2391
--- /dev/null
+++ b/shoes/native/gtk/gtkprogressbaralt.c
@@ -0,0 +1,76 @@
+#include "shoes/app.h"
+#include "shoes/ruby.h"
+#include "shoes/config.h"
+#include "shoes/world.h"
+#include "shoes/native/native.h"
+#include "shoes/internal.h"
+
+#include "gtkprogressbaralt.h"
+
+/* Private class member */
+#define GTK_PROGRESS_BAR_ALT_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), \
+ GTK_TYPE_PROGRESS_BAR_ALT, GtkProgressBar_AltPrivate))
+
+typedef struct _GtkProgressBar_AltPrivate GtkProgressBar_AltPrivate;
+
+struct _GtkProgressBar_AltPrivate {
+ /* to avoid warnings (g_type_class_add_private: assertion `private_size > 0' failed) */
+ gchar dummy;
+};
+
+/* Forward declarations */
+static void gtk_progress_bar_alt_get_preferred_width(GtkWidget *widget,
+ int *minimal, int *natural);
+static void gtk_progress_bar_alt_get_preferred_height(GtkWidget *widget,
+ int *minimal, int *natural);
+
+/* Define the GtkProgressBar_Alt type and inherit from GtkProgressBar */
+G_DEFINE_TYPE(GtkProgressBar_Alt, gtk_progress_bar_alt, GTK_TYPE_PROGRESS_BAR);
+
+/* Initialize the GtkProgressBar_Alt class */
+static void gtk_progress_bar_alt_class_init(GtkProgressBar_AltClass *klass) {
+ /* Override GtkWidget methods */
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
+ widget_class->get_preferred_width = gtk_progress_bar_alt_get_preferred_width;
+ widget_class->get_preferred_height = gtk_progress_bar_alt_get_preferred_height;
+
+ /* Override GtkProgressBar methods */
+ // TODO: determine whether gobject_class has any use.
+ //GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ // ...
+
+ /* Add private indirection member */
+ g_type_class_add_private(klass, sizeof(GtkProgressBar_AltPrivate));
+}
+
+/* Initialize a new GtkProgressBar_Alt instance */
+static void gtk_progress_bar_alt_init(GtkProgressBar_Alt *progressbarAlt) {
+ /* This means that GtkProgressBar_Alt doesn't supply its own GdkWindow */
+ gtk_widget_set_has_window(GTK_WIDGET(progressbarAlt), FALSE);
+
+ /* Initialize private members */
+ // TODO: determine whether priv has any use.
+ //GtkProgressBar_AltPrivate *priv = GTK_PROGRESS_BAR_ALT_PRIVATE(progressbarAlt);
+
+}
+
+/* Return a new GtkProgressBar_Alt cast to a GtkWidget */
+GtkWidget *gtk_progress_bar_alt_new() {
+ return GTK_WIDGET(g_object_new(gtk_progress_bar_alt_get_type(), NULL));
+}
+
+static void gtk_progress_bar_alt_get_preferred_width(GtkWidget *widget, int *minimal, int *natural) {
+ g_return_if_fail(widget != NULL);
+
+ *minimal = 1;
+ *natural = 1;
+}
+
+static void gtk_progress_bar_alt_get_preferred_height(GtkWidget *widget, int *minimal, int *natural) {
+ g_return_if_fail(widget != NULL);
+
+ *minimal = 1;
+ *natural = 1;
+}
+
+
diff --git a/shoes/native/gtkprogressbaralt.h b/shoes/native/gtk/gtkprogressbaralt.h
similarity index 100%
rename from shoes/native/gtkprogressbaralt.h
rename to shoes/native/gtk/gtkprogressbaralt.h
diff --git a/shoes/native/gtk/gtkradio.c b/shoes/native/gtk/gtkradio.c
new file mode 100644
index 00000000..3224b09e
--- /dev/null
+++ b/shoes/native/gtk/gtkradio.c
@@ -0,0 +1,31 @@
+#include "shoes/app.h"
+#include "shoes/ruby.h"
+#include "shoes/config.h"
+#include "shoes/world.h"
+#include "shoes/native/native.h"
+#include "shoes/types/native.h"
+#include "shoes/internal.h"
+#include "shoes/native/gtk/gtkradio.h"
+
+SHOES_CONTROL_REF shoes_native_radio(VALUE self, shoes_canvas *canvas, shoes_place *place, VALUE attr, VALUE group) {
+ SHOES_CONTROL_REF ref;
+ GSList *list = NULL;
+
+ if (!NIL_P(group)) {
+ shoes_control *lctrl;
+ VALUE leader = rb_ary_entry(group, 0);
+ Data_Get_Struct(leader, shoes_control, lctrl);
+ list = gtk_radio_button_get_group(GTK_RADIO_BUTTON(lctrl->ref));
+ }
+
+ ref = gtk_radio_button_new(list);
+
+ if (!NIL_P(shoes_hash_get(attr, rb_intern("tooltip")))) {
+ gtk_widget_set_tooltip_text(GTK_WIDGET(ref), RSTRING_PTR(shoes_hash_get(attr, rb_intern("tooltip"))));
+ }
+
+ g_signal_connect(G_OBJECT(ref), "clicked",
+ G_CALLBACK(shoes_button_gtk_clicked),
+ (gpointer)self);
+ return ref;
+}
diff --git a/shoes/native/gtk/gtkradio.h b/shoes/native/gtk/gtkradio.h
new file mode 100644
index 00000000..2cc86671
--- /dev/null
+++ b/shoes/native/gtk/gtkradio.h
@@ -0,0 +1,9 @@
+#ifndef SHOES_GTK_RADIO_H
+#define SHOES_GTK_RADIO_H
+
+SHOES_CONTROL_REF shoes_native_radio(VALUE self, shoes_canvas *canvas, shoes_place *place, VALUE attr, VALUE group);
+
+// gtk forward declaration
+extern gboolean shoes_button_gtk_clicked(GtkButton *button, gpointer data);
+
+#endif
diff --git a/shoes/native/gtk/gtkscrolledwindowalt.c b/shoes/native/gtk/gtkscrolledwindowalt.c
new file mode 100644
index 00000000..08c22a1b
--- /dev/null
+++ b/shoes/native/gtk/gtkscrolledwindowalt.c
@@ -0,0 +1,87 @@
+#include "shoes/app.h"
+#include "shoes/ruby.h"
+#include "shoes/config.h"
+#include "shoes/world.h"
+#include "shoes/native/native.h"
+#include "shoes/internal.h"
+
+#include "gtkscrolledwindowalt.h"
+
+/* Private class member */
+#define GTK_SCROLLED_WINDOW_ALT_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), \
+ GTK_TYPE_SCROLLED_WINDOW_ALT, GtkScrolledWindow_AltPrivate))
+
+typedef struct _GtkScrolledWindow_AltPrivate GtkScrolledWindow_AltPrivate;
+
+struct _GtkScrolledWindow_AltPrivate {
+ /* to avoid warnings (g_type_class_add_private: assertion `private_size > 0' failed) */
+ gchar dummy;
+};
+
+/* Forward declarations */
+static void gtk_scrolled_window_alt_get_preferred_width(GtkWidget *widget,
+ int *minimal, int *natural);
+static void gtk_scrolled_window_alt_get_preferred_height(GtkWidget *widget,
+ int *minimal, int *natural);
+
+/* Define the GtkScrolledWindow_Alt type and inherit from GtkScrolledWindow */
+G_DEFINE_TYPE(GtkScrolledWindow_Alt, gtk_scrolled_window_alt, GTK_TYPE_SCROLLED_WINDOW);
+
+/* Initialize the GtkScrolledWindow_Alt class */
+static void gtk_scrolled_window_alt_class_init(GtkScrolledWindow_AltClass *klass) {
+ /* Override GtkWidget methods */
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
+ widget_class->get_preferred_width = gtk_scrolled_window_alt_get_preferred_width;
+ widget_class->get_preferred_height = gtk_scrolled_window_alt_get_preferred_height;
+
+ /* Override GtkScrolledWindow methods */
+ // TODO: determine whether gobject_class has any use.
+ //GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ // ...
+
+ /* Add private indirection member */
+ g_type_class_add_private(klass, sizeof(GtkScrolledWindow_AltPrivate));
+}
+
+/* Initialize a new GtkScrolledWindow_Alt instance */
+static void gtk_scrolled_window_alt_init(GtkScrolledWindow_Alt *scrolledwindowAlt) {
+ /* This means that GtkScrolledWindow_Alt doesn't supply its own GdkWindow */
+ //gtk_widget_set_has_window(GTK_WIDGET(scrolledwindowAlt), FALSE);
+ gtk_widget_set_has_window(GTK_WIDGET(scrolledwindowAlt),
+ gtk_widget_get_has_window(GTK_WIDGET(&(scrolledwindowAlt->parent_instance))));
+
+ /* Initialize private members */
+ // TODO: determine whether gobject_class has any use.
+ //GtkScrolledWindow_AltPrivate *priv = GTK_SCROLLED_WINDOW_ALT_PRIVATE(scrolledwindowAlt);
+}
+
+/* Return a new GtkScrolledWindow_Alt cast to a GtkWidget */
+GtkWidget *gtk_scrolled_window_alt_new(GtkAdjustment *hadjustment,
+ GtkAdjustment *vadjustment) {
+ if (hadjustment)
+ g_return_val_if_fail (GTK_IS_ADJUSTMENT (hadjustment), NULL);
+
+ if (vadjustment)
+ g_return_val_if_fail (GTK_IS_ADJUSTMENT (vadjustment), NULL);
+
+ return GTK_WIDGET(g_object_new (gtk_scrolled_window_alt_get_type(),
+ "hadjustment", hadjustment,
+ "vadjustment", vadjustment,
+ NULL));
+}
+
+static void gtk_scrolled_window_alt_get_preferred_width(GtkWidget *widget, int *minimal, int *natural) {
+ g_return_if_fail(widget != NULL);
+
+ *minimal = 1;
+ *natural = 1;
+}
+
+static void gtk_scrolled_window_alt_get_preferred_height(GtkWidget *widget, int *minimal, int *natural) {
+ g_return_if_fail(widget != NULL);
+
+ *minimal = 1;
+ *natural = 1;
+}
+
+
diff --git a/shoes/native/gtkscrolledwindowalt.h b/shoes/native/gtk/gtkscrolledwindowalt.h
similarity index 100%
rename from shoes/native/gtkscrolledwindowalt.h
rename to shoes/native/gtk/gtkscrolledwindowalt.h
diff --git a/shoes/native/gtk/gtkspinner.c b/shoes/native/gtk/gtkspinner.c
new file mode 100644
index 00000000..10eb9a4c
--- /dev/null
+++ b/shoes/native/gtk/gtkspinner.c
@@ -0,0 +1,36 @@
+#include "shoes/app.h"
+#include "shoes/ruby.h"
+#include "shoes/config.h"
+#include "shoes/world.h"
+#include "shoes/native/native.h"
+#include "shoes/internal.h"
+#include "shoes/native/gtk/gtkspinner.h"
+
+SHOES_CONTROL_REF shoes_native_spinner(VALUE self, shoes_canvas *canvas, shoes_place *place, VALUE attr, char *msg) {
+ SHOES_CONTROL_REF ref = gtk_spinner_new();
+
+ if (!NIL_P(shoes_hash_get(attr, rb_intern("start")))) {
+ if (Qtrue == shoes_hash_get(attr, rb_intern("start")))
+ gtk_spinner_start(GTK_SPINNER(ref));
+ }
+
+ if (!NIL_P(shoes_hash_get(attr, rb_intern("tooltip")))) {
+ gtk_widget_set_tooltip_text(GTK_WIDGET(ref), RSTRING_PTR(shoes_hash_get(attr, rb_intern("tooltip"))));
+ }
+
+ return ref;
+}
+
+void shoes_native_spinner_start(SHOES_CONTROL_REF ref) {
+ gtk_spinner_start(GTK_SPINNER(ref));
+}
+
+void shoes_native_spinner_stop(SHOES_CONTROL_REF ref) {
+ gtk_spinner_stop(GTK_SPINNER(ref));
+}
+
+gboolean shoes_native_spinner_started(SHOES_CONTROL_REF ref) {
+ gboolean active;
+ g_object_get (GTK_SPINNER(ref), "active", &active, NULL);
+ return active;
+}
diff --git a/shoes/native/gtk/gtkspinner.h b/shoes/native/gtk/gtkspinner.h
new file mode 100644
index 00000000..32b289d1
--- /dev/null
+++ b/shoes/native/gtk/gtkspinner.h
@@ -0,0 +1,9 @@
+#ifndef SHOES_GTK_SPINNER_H
+#define SHOES_GTK_SPINNER_H
+
+SHOES_CONTROL_REF shoes_native_spinner(VALUE self, shoes_canvas *canvas, shoes_place *place, VALUE attr, char *msg);
+void shoes_native_spinner_start(SHOES_CONTROL_REF ref);
+void shoes_native_spinner_stop(SHOES_CONTROL_REF ref);
+gboolean shoes_native_spinner_started(SHOES_CONTROL_REF ref);
+
+#endif
\ No newline at end of file
diff --git a/shoes/native/gtk/gtkswitch.c b/shoes/native/gtk/gtkswitch.c
new file mode 100644
index 00000000..f6c2ddbb
--- /dev/null
+++ b/shoes/native/gtk/gtkswitch.c
@@ -0,0 +1,40 @@
+#include "shoes/app.h"
+#include "shoes/ruby.h"
+#include "shoes/config.h"
+#include "shoes/world.h"
+#include "shoes/native/native.h"
+#include "shoes/types/native.h"
+#include "shoes/internal.h"
+#include "shoes/native/gtk/gtkswitch.h"
+
+SHOES_CONTROL_REF shoes_native_switch(VALUE self, shoes_canvas *canvas, shoes_place *place, VALUE attr, char *msg) {
+ SHOES_CONTROL_REF ref = gtk_switch_new();
+
+ if (!NIL_P(shoes_hash_get(attr, rb_intern("active")))) {
+ gtk_switch_set_active(GTK_SWITCH(ref), shoes_hash_get(attr, rb_intern("active")) == Qtrue);
+ }
+
+ if (!NIL_P(shoes_hash_get(attr, rb_intern("tooltip")))) {
+ gtk_widget_set_tooltip_text(GTK_WIDGET(ref), RSTRING_PTR(shoes_hash_get(attr, rb_intern("tooltip"))));
+ }
+
+ g_signal_connect(G_OBJECT(ref), "notify::active",
+ G_CALLBACK(shoes_native_activate),
+ (gpointer)self);
+
+ return ref;
+}
+
+void shoes_native_switch_set_active(SHOES_CONTROL_REF ref, int activate) {
+ gtk_switch_set_active(GTK_SWITCH(ref), activate);
+}
+
+VALUE shoes_native_switch_get_active(SHOES_CONTROL_REF ref) {
+ return gtk_switch_get_active(GTK_SWITCH(ref)) ? Qtrue : Qfalse;
+}
+
+static void shoes_native_activate(GObject *switcher, GParamSpec *pspec, gpointer data) {
+ VALUE self = (VALUE)data;
+
+ shoes_control_send(self, s_active);
+}
diff --git a/shoes/native/gtk/gtkswitch.h b/shoes/native/gtk/gtkswitch.h
new file mode 100644
index 00000000..a2b129d4
--- /dev/null
+++ b/shoes/native/gtk/gtkswitch.h
@@ -0,0 +1,17 @@
+#include "shoes/ruby.h"
+
+#ifndef SHOES_GTK_SWITCH_H
+#define SHOES_GTK_SWITCH_H
+
+// There is some magical way to create this but let's do this manually for now
+SYMBOL_EXTERN(active);
+
+SHOES_CONTROL_REF shoes_native_switch(VALUE self, shoes_canvas *canvas, shoes_place *place, VALUE attr, char *msg);
+void shoes_native_switch_set_active(SHOES_CONTROL_REF ref, int activate);
+VALUE shoes_native_switch_get_active(SHOES_CONTROL_REF ref);
+static void shoes_native_activate(GObject *switcher, GParamSpec *pspec, gpointer data);
+
+// EVENT_COMMON generated functions
+VALUE shoes_control_active(int argc, VALUE *argv, VALUE self);
+
+#endif
diff --git a/shoes/native/gtk/gtksystray.c b/shoes/native/gtk/gtksystray.c
new file mode 100644
index 00000000..fa9dd46d
--- /dev/null
+++ b/shoes/native/gtk/gtksystray.c
@@ -0,0 +1,39 @@
+#include "shoes/app.h"
+#include "shoes/ruby.h"
+#include "shoes/config.h"
+#include "shoes/world.h"
+#include "shoes/native/native.h"
+#include "shoes/types/native.h"
+#include "shoes/internal.h"
+#include "shoes/native/gtk/gtksystray.h"
+
+//extern GApplication *shoes_GApp;
+#if !defined(SHOES_GTK_WIN32) && defined(GNOTE) // some Linux, not Windows
+void shoes_native_systray(char *title, char *message, char *path) {
+ GApplication *gapp = g_application_get_default();
+ GNotification *note;
+ note = g_notification_new (title);
+ g_notification_set_body (note, message);
+ GFile *iconf = g_file_new_for_path (path);
+ GIcon *icon = g_file_icon_new (iconf);
+ g_notification_set_icon(note, icon);
+ g_application_send_notification (gapp, "Shoes", note);
+}
+#else
+// use gtk_status_icon for Windows, deprecated but GNotification doesn't work
+static GtkStatusIcon *stsicon = NULL;
+static char *stspath = NULL;
+void shoes_native_systray(char *title, char *message, char *path) {
+ if (stsicon == NULL) {
+ stsicon = gtk_status_icon_new_from_file(path);
+ stspath = path;
+ }
+ // detect change of icon
+ if (strcmp(path, stspath)) {
+ stspath = path;
+ gtk_status_icon_set_from_file (stsicon, stspath);
+ }
+ gtk_status_icon_set_title(stsicon, title);
+ gtk_status_icon_set_tooltip_text(stsicon, message);
+}
+#endif
diff --git a/shoes/native/gtk/gtksystray.h b/shoes/native/gtk/gtksystray.h
new file mode 100644
index 00000000..7875c0a9
--- /dev/null
+++ b/shoes/native/gtk/gtksystray.h
@@ -0,0 +1,8 @@
+#include "shoes/ruby.h"
+
+#ifndef SHOES_GTK_SYSTRAY_H
+#define SHOES_GTK_SYSTRAY_H
+
+
+
+#endif
diff --git a/shoes/native/gtk/gtktextview.c b/shoes/native/gtk/gtktextview.c
new file mode 100644
index 00000000..426ee6a0
--- /dev/null
+++ b/shoes/native/gtk/gtktextview.c
@@ -0,0 +1,63 @@
+#include "shoes/app.h"
+#include "shoes/ruby.h"
+#include "shoes/config.h"
+#include "shoes/world.h"
+#include "shoes/native/native.h"
+#include "shoes/internal.h"
+
+#include "shoes/native/gtk.h"
+#include "shoes/native/gtk/gtkscrolledwindowalt.h"
+#include "shoes/native/gtk/gtktextview.h"
+
+SHOES_CONTROL_REF shoes_native_text_view(VALUE self, shoes_canvas *canvas, shoes_place *place, VALUE attr, char *msg) {
+ GtkTextBuffer *buffer;
+ GtkWidget* textview = gtk_text_view_new();
+ SHOES_CONTROL_REF ref = gtk_scrolled_window_alt_new(NULL, NULL);
+
+ if (!NIL_P(shoes_hash_get(attr, rb_intern("tooltip")))) {
+ gtk_widget_set_tooltip_text(GTK_WIDGET(ref), RSTRING_PTR(shoes_hash_get(attr, rb_intern("tooltip"))));
+ }
+
+ gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(textview), GTK_WRAP_WORD);
+ buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview));
+ gtk_text_buffer_set_text(buffer, _(msg), -1);
+ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(ref),
+ GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(ref), GTK_SHADOW_IN);
+ gtk_container_add(GTK_CONTAINER(ref), textview);
+
+ g_signal_connect(G_OBJECT(buffer), "changed",
+ G_CALLBACK(shoes_widget_changed),
+ (gpointer)self);
+
+ return ref;
+}
+
+VALUE shoes_native_text_view_get_text(SHOES_CONTROL_REF ref) {
+ GtkWidget *textview;
+ GTK_CHILD(textview, ref);
+ GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview));
+ GtkTextIter begin, end;
+ gtk_text_buffer_get_bounds(buffer, &begin, &end);
+ return rb_str_new2(gtk_text_buffer_get_text(buffer, &begin, &end, TRUE));
+}
+
+void shoes_native_text_view_set_text(SHOES_CONTROL_REF ref, char *msg) {
+ GtkWidget *textview;
+ GTK_CHILD(textview, ref);
+ GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview));
+ gtk_text_buffer_set_text(buffer, _(msg), -1);
+}
+
+VALUE shoes_native_text_view_append(SHOES_CONTROL_REF ref, char *msg) {
+ GtkWidget *textview;
+ GTK_CHILD(textview, ref);
+ GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview));
+ GtkTextIter begin, end;
+ gtk_text_buffer_get_bounds(buffer, &begin, &end);
+ gtk_text_buffer_insert(buffer, &end, msg, strlen(msg));
+ gtk_text_buffer_get_bounds(buffer, &begin, &end);
+ // TODO: return something useful
+ return Qnil;
+ //return rb_str_new2(gtk_text_buffer_get_text(buffer, &begin, &end, TRUE));
+}
diff --git a/shoes/native/gtk/gtktextview.h b/shoes/native/gtk/gtktextview.h
new file mode 100644
index 00000000..f287bf47
--- /dev/null
+++ b/shoes/native/gtk/gtktextview.h
@@ -0,0 +1,12 @@
+#ifndef SHOES_GTK_TEXT_VIEW_H
+#define SHOES_GTK_TEXT_VIEW_H
+
+SHOES_CONTROL_REF shoes_native_text_view(VALUE self, shoes_canvas *canvas, shoes_place *place, VALUE attr, char *msg);
+VALUE shoes_native_text_view_get_text(SHOES_CONTROL_REF ref);
+void shoes_native_text_view_set_text(SHOES_CONTROL_REF ref, char *msg);
+VALUE shoes_native_text_view_append(SHOES_CONTROL_REF ref, char *msg);
+
+// gtk forward declaration
+extern void shoes_widget_changed(GtkWidget *ref, gpointer data);
+
+#endif
\ No newline at end of file
diff --git a/shoes/native/gtk/gtktimerbase.c b/shoes/native/gtk/gtktimerbase.c
new file mode 100644
index 00000000..1f0e4fad
--- /dev/null
+++ b/shoes/native/gtk/gtktimerbase.c
@@ -0,0 +1,25 @@
+#include "shoes/app.h"
+#include "shoes/ruby.h"
+#include "shoes/config.h"
+#include "shoes/world.h"
+#include "shoes/native/native.h"
+#include "shoes/internal.h"
+#include "shoes/native/gtk/gtktimerbase.h"
+#include "shoes/types/timerbase.h"
+
+static gboolean shoes_gtk_animate(gpointer data) {
+ VALUE timer = (VALUE)data;
+ shoes_timer *self_t;
+ Data_Get_Struct(timer, shoes_timer, self_t);
+ if (self_t->started == ANIM_STARTED)
+ shoes_timer_call(timer);
+ return self_t->started == ANIM_STARTED;
+}
+
+void shoes_native_timer_remove(shoes_canvas *canvas, SHOES_TIMER_REF ref) {
+ g_source_remove(ref);
+}
+
+SHOES_TIMER_REF shoes_native_timer_start(VALUE self, shoes_canvas *canvas, unsigned int interval) {
+ return g_timeout_add(interval, shoes_gtk_animate, (gpointer)self);
+}
\ No newline at end of file
diff --git a/shoes/native/gtk/gtktimerbase.h b/shoes/native/gtk/gtktimerbase.h
new file mode 100644
index 00000000..6dc5c410
--- /dev/null
+++ b/shoes/native/gtk/gtktimerbase.h
@@ -0,0 +1,7 @@
+#ifndef SHOES_GTK_TIMERBASE_H
+#define SHOES_GTK_TIMERBASE_H
+
+SHOES_TIMER_REF shoes_native_timer_start(VALUE self, shoes_canvas *canvas, unsigned int interval);
+void shoes_native_timer_remove(shoes_canvas *canvas, SHOES_TIMER_REF ref);
+
+#endif
\ No newline at end of file
diff --git a/shoes/native/gtk/gtkvideo.c b/shoes/native/gtk/gtkvideo.c
new file mode 100644
index 00000000..b8f7e788
--- /dev/null
+++ b/shoes/native/gtk/gtkvideo.c
@@ -0,0 +1,76 @@
+#include "shoes/app.h"
+#include "shoes/ruby.h"
+#include "shoes/config.h"
+#include "shoes/world.h"
+#include "shoes/internal.h"
+#include "shoes/native/native.h"
+#include "shoes/native/gtk/gtkvideo.h"
+#include "shoes/types/color.h"
+#include "shoes/types/video.h"
+
+void surface_on_realize(SHOES_CONTROL_REF ref, gpointer data) {
+ VALUE rbvideo = (VALUE)data;
+ shoes_video *video;
+ Data_Get_Struct(rbvideo, shoes_video, video);
+ video->realized = 1;
+}
+
+// SHOES_SURFACE_REF and SHOES_CONTROL_REF expands the same : GtkWidget *
+// ref in shoes_video struct was a SHOES_CONTROL_REF anyway
+SHOES_CONTROL_REF shoes_native_surface_new(VALUE attr, VALUE video) {
+ SHOES_CONTROL_REF da = gtk_drawing_area_new();
+
+ if (!NIL_P(shoes_hash_get(attr, rb_intern("tooltip")))) {
+ gtk_widget_set_tooltip_text(GTK_WIDGET(da), RSTRING_PTR(shoes_hash_get(attr, rb_intern("tooltip"))));
+ }
+
+ gtk_widget_set_size_request(da, NUM2INT(ATTR(attr, width)), NUM2INT(ATTR(attr, height)));
+
+ VALUE uc = Qnil;
+ if (!NIL_P(attr)) uc = ATTR(attr, bg_color);
+
+ // TODO (better with GtkStyleProvider)
+ GdkRGBA color = {.0, .0, .0, 1.0};
+ if (!NIL_P(uc)) {
+ shoes_color *col;
+ Data_Get_Struct(uc, shoes_color, col);
+ color.red = col->r/255.0;
+ color.green = col->g/255.0;
+ color.blue = col->b/255.0;
+ }
+ gtk_widget_override_background_color(GTK_WIDGET(da), 0, &color);
+
+ g_signal_connect(G_OBJECT(da), "realize",
+ G_CALLBACK(surface_on_realize),
+ (gpointer)video);
+
+ return da;
+}
+
+void shoes_native_surface_remove(SHOES_CONTROL_REF ref) {
+ gtk_widget_destroy(ref);
+}
+
+/* doing this directly on control now
+ *
+void
+shoes_native_surface_position(SHOES_SURFACE_REF ref, shoes_place *p1,
+ VALUE self, shoes_canvas *canvas, shoes_place *p2)
+{
+ shoes_native_control_position((SHOES_CONTROL_REF)ref, p1, self, canvas, p2);
+}
+
+void
+//shoes_native_surface_hide(SHOES_SURFACE_REF ref)
+shoes_native_surface_hide(SHOES_CONTROL_REF ref)
+{
+ shoes_native_control_hide(ref);
+}
+
+void
+//shoes_native_surface_show(SHOES_SURFACE_REF ref)
+shoes_native_surface_show(SHOES_CONTROL_REF ref)
+{
+ shoes_native_control_show(ref);
+}
+*/
\ No newline at end of file
diff --git a/shoes/native/gtk/gtkvideo.h b/shoes/native/gtk/gtkvideo.h
new file mode 100644
index 00000000..6aaec5c7
--- /dev/null
+++ b/shoes/native/gtk/gtkvideo.h
@@ -0,0 +1,15 @@
+#include "shoes/config.h"
+#include "shoes/canvas.h"
+
+#ifndef SHOES_GTK_VIDEO_H
+#define SHOES_GTK_VIDEO_H
+
+SHOES_CONTROL_REF shoes_native_surface_new(VALUE, VALUE);
+unsigned long shoes_native_surface_get_window_handle(SHOES_CONTROL_REF);
+void shoes_native_surface_position(SHOES_SURFACE_REF, shoes_place *,
+ VALUE, shoes_canvas *, shoes_place *);
+void shoes_native_surface_hide(SHOES_SURFACE_REF);
+void shoes_native_surface_show(SHOES_SURFACE_REF);
+void shoes_native_surface_remove(SHOES_SURFACE_REF);
+
+#endif
\ No newline at end of file
diff --git a/shoes/native/gtkbuttonalt.c b/shoes/native/gtkbuttonalt.c
deleted file mode 100644
index 234ee6f0..00000000
--- a/shoes/native/gtkbuttonalt.c
+++ /dev/null
@@ -1,91 +0,0 @@
-
-#include "shoes/app.h"
-#include "shoes/ruby.h"
-#include "shoes/config.h"
-#include "shoes/world.h"
-#include "shoes/native.h"
-#include "shoes/internal.h"
-
-#include "gtkbuttonalt.h"
-
-/* Private class member */
-#define GTK_BUTTON_ALT_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), \
- GTK_TYPE_BUTTON_ALT, GtkButton_AltPrivate))
-
-typedef struct _GtkButton_AltPrivate GtkButton_AltPrivate;
-
-struct _GtkButton_AltPrivate
-{
- /* to avoid warnings (g_type_class_add_private: assertion `private_size > 0' failed) */
- gchar dummy;
-};
-
-/* Forward declarations */
-static void gtk_button_alt_get_preferred_width(GtkWidget *widget,
- int *minimal, int *natural);
-static void gtk_button_alt_get_preferred_height(GtkWidget *widget,
- int *minimal, int *natural);
-
-/* Define the GtkButton_Alt type and inherit from GtkButton */
-G_DEFINE_TYPE(GtkButton_Alt, gtk_button_alt, GTK_TYPE_BUTTON);
-
-/* Initialize the GtkButton_Alt class */
-static void
-gtk_button_alt_class_init(GtkButton_AltClass *klass)
-{
- /* Override GtkWidget methods */
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
- widget_class->get_preferred_width = gtk_button_alt_get_preferred_width;
- widget_class->get_preferred_height = gtk_button_alt_get_preferred_height;
-
- /* Override GtkButton methods */
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- // ...
-
- /* Add private indirection member */
- g_type_class_add_private(klass, sizeof(GtkButton_AltPrivate));
-}
-
-/* Initialize a new GtkButton_Alt instance */
-static void
-gtk_button_alt_init(GtkButton_Alt *buttontAlt)
-{
- /* This means that GtkButton_Alt doesn't supply its own GdkWindow */
- gtk_widget_set_has_window(GTK_WIDGET(buttontAlt), FALSE);
-
- /* Initialize private members */
- GtkButton_AltPrivate *priv = GTK_BUTTON_ALT_PRIVATE(buttontAlt);
-
-}
-
-/* Return a new GtkButton_Alt cast to a GtkWidget */
-GtkWidget *
-gtk_button_alt_new()
-{
- return GTK_WIDGET(g_object_new(gtk_button_alt_get_type(), NULL));
-}
-
-GtkWidget *
-gtk_button_alt_new_with_label(const gchar *label)
-{
- return GTK_WIDGET(g_object_new (gtk_button_alt_get_type(), "label", label, NULL));
-}
-
-
-static void
-gtk_button_alt_get_preferred_width(GtkWidget *widget, int *minimal, int *natural)
-{
- g_return_if_fail(widget != NULL);
-
- *minimal = 1;
- *natural = 1;
-}
-
-static void
-gtk_button_alt_get_preferred_height(GtkWidget *widget, int *minimal, int *natural)
-{
- g_return_if_fail(widget != NULL);
-
- *minimal = 1;
- *natural = 1;
-}
diff --git a/shoes/native/gtkcomboboxtextalt.c b/shoes/native/gtkcomboboxtextalt.c
deleted file mode 100644
index 43cba121..00000000
--- a/shoes/native/gtkcomboboxtextalt.c
+++ /dev/null
@@ -1,245 +0,0 @@
-
-
-#include "shoes/app.h"
-#include "shoes/ruby.h"
-#include "shoes/config.h"
-#include "shoes/world.h"
-#include "shoes/native.h"
-#include "shoes/internal.h"
-
-#include "gtkcomboboxtextalt.h"
-//#include
-
-
-struct _GtkComboBoxPrivate
-{
- GtkTreeModel *model;
-
- GtkCellArea *area;
-
- gint col_column;
- gint row_column;
-
- gint wrap_width;
- GtkShadowType shadow_type;
-
- gint active; /* Only temporary */
- GtkTreeRowReference *active_row;
-
- GtkWidget *tree_view;
-
- GtkWidget *cell_view;
- GtkWidget *cell_view_frame;
-
- GtkWidget *button;
- GtkWidget *box;
- GtkWidget *arrow;
- GtkWidget *separator;
-
- GtkWidget *popup_widget;
- GtkWidget *popup_window;
- GtkWidget *scrolled_window;
-
- gulong inserted_id;
- gulong deleted_id;
- gulong reordered_id;
- gulong changed_id;
- guint popup_idle_id;
- guint activate_button;
- guint32 activate_time;
- guint scroll_timer;
- guint resize_idle_id;
-
- /* For "has-entry" specific behavior we track
- * an automated cell renderer and text column
- */
- gint text_column;
- GtkCellRenderer *text_renderer;
-
- gint id_column;
-
- guint popup_in_progress : 1;
- guint popup_shown : 1;
- guint add_tearoffs : 1;
- guint has_frame : 1;
- guint is_cell_renderer : 1;
- guint editing_canceled : 1;
- guint auto_scroll : 1;
- guint focus_on_click : 1;
- guint button_sensitivity : 2;
- guint has_entry : 1;
- guint popup_fixed_width : 1;
-
- GtkTreeViewRowSeparatorFunc row_separator_func;
- gpointer row_separator_data;
- GDestroyNotify row_separator_destroy;
-
- GdkDevice *grab_pointer;
- GdkDevice *grab_keyboard;
-
- gchar *tearoff_title;
-};
-
-/* Private class member */
-#define GTK_COMBOBOXTEXT_ALT_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), \
- GTK_TYPE_COMBO_BOX_TEXT_ALT, GtkComboBoxText_AltPrivate))
-
-typedef struct _GtkComboBoxText_AltPrivate GtkComboBoxText_AltPrivate;
-
-struct _GtkComboBoxText_AltPrivate
-{
- /* to avoid warnings (g_type_class_add_private: assertion `private_size > 0' failed) */
- gchar dummy;
-};
-
-/* Forward declarations */
-static void gtk_combo_box_text_alt_get_preferred_width(GtkWidget *widget,
- int *minimal, int *natural);
-static void gtk_combo_box_text_alt_get_preferred_height(GtkWidget *widget,
- int *minimal, int *natural);
-static void gtk_combo_box_text_alt_get_preferred_height_for_width(GtkWidget *widget,
- gint avail_size, gint *minimum_size, gint *natural_size);
-static void gtk_combo_box_text_alt_get_preferred_width_for_height(GtkWidget *widget,
- gint avail_size, gint *minimum_size, gint *natural_size);
-
-/* Define the GtkComboBoxText_Alt type and inherit from GtkComboBoxText */
-G_DEFINE_TYPE(GtkComboBoxText_Alt, gtk_combo_box_text_alt, GTK_TYPE_COMBO_BOX_TEXT);
-
-/* Initialize the GtkComboBoxText_Alt class */
-static void
-gtk_combo_box_text_alt_class_init(GtkComboBoxText_AltClass *klass)
-{
- /* Override GtkWidget methods */
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
- widget_class->get_preferred_width = gtk_combo_box_text_alt_get_preferred_width;
- widget_class->get_preferred_height = gtk_combo_box_text_alt_get_preferred_height;
- widget_class->get_preferred_height_for_width = gtk_combo_box_text_alt_get_preferred_height_for_width;
- widget_class->get_preferred_width_for_height = gtk_combo_box_text_alt_get_preferred_width_for_height;
-
- /* Override GtkComboBoxText methods */
- GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
- // ...
-
- /* Add private indirection member */
- g_type_class_add_private(klass, sizeof(GtkComboBoxText_AltPrivate));
-}
-
-/* Initialize a new GtkComboBoxText_Alt instance */
-static void
-gtk_combo_box_text_alt_init(GtkComboBoxText_Alt *comboboxtextAlt)
-{
- /* This means that GtkComboBoxText_Alt doesn't supply its own GdkWindow */
- gtk_widget_set_has_window(GTK_WIDGET(comboboxtextAlt), FALSE);
-
- /* Initialize private members */
- GtkComboBoxText_AltPrivate *priv = GTK_COMBOBOXTEXT_ALT_PRIVATE(comboboxtextAlt);
-
-}
-
-/* Return a new GtkComboBoxText_Alt cast to a GtkWidget */
-GtkWidget *
-gtk_combo_box_text_alt_new(VALUE attribs, int bottom_margin)
-{
- GtkWidget *ref;
- ref = GTK_WIDGET(g_object_new(gtk_combo_box_text_alt_get_type(), NULL));
-
- /* emulating gtk2 defaults*/
- int w = 160, h = 30;
- if (RTEST(ATTR(attribs, width))) w = NUM2INT(ATTR(attribs, width));
- if (RTEST(ATTR(attribs, height))) h = NUM2INT(ATTR(attribs, height));
-
- //GtkCellArea *area = gtk_cell_layout_get_area((GtkCellLayout *)ref);
- GList *renderers = gtk_cell_layout_get_cells((GtkCellLayout *)ref);
- GtkCellRendererText *cell = g_list_first(renderers)->data; //only one renderer
- g_list_free(renderers);
- gtk_cell_renderer_set_fixed_size((GtkCellRenderer *)cell, w, h-bottom_margin*2);
- if (RTEST(ATTR(attribs, font))) {
- char *fontnm = RSTRING_PTR(ATTR(attribs, font));
- g_object_set((GtkCellRenderer *)cell, "font", fontnm, NULL);
- }
- if (RTEST(ATTR(attribs, wrap))) {
- g_object_set((GtkCellRenderer *)cell, "wrap-width", w, NULL);
- char *wrapstr = RSTRING_PTR(ATTR(attribs, wrap));
- if (strcmp(wrapstr, "char") == 0)
- g_object_set((GtkCellRenderer *)cell, "wrap-mode", PANGO_WRAP_CHAR, NULL);
- else if (strcmp(wrapstr, "word") == 0)
- g_object_set((GtkCellRenderer *)cell, "wrap-mode", PANGO_WRAP_WORD, NULL);
- else if (strcmp(wrapstr, "trim") == 0)
- g_object_set((GtkCellRenderer *)cell, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
- } else {
- g_object_set((GtkCellRenderer *)cell, "ellipsize", PANGO_ELLIPSIZE_MIDDLE, NULL);
- }
- return ref;
-}
-
-
-static void
-gtk_combo_box_text_alt_get_preferred_width(GtkWidget *widget, int *minimal, int *natural)
-{
- g_return_if_fail(widget != NULL);
-
-/* This is how we can access private data from parent Widget
- GtkComboBox *combo_box = GTK_COMBO_BOX(widget);
- GtkComboBoxPrivate *priv = G_TYPE_INSTANCE_GET_PRIVATE(combo_box,
- GTK_TYPE_COMBO_BOX,
- GtkComboBoxPrivate);
- gint box_width;
- gtk_widget_get_preferred_width(priv->box, &box_width, NULL);
-*/
-
- GList *renderers = gtk_cell_layout_get_cells((GtkCellLayout *)widget);
- GtkCellRenderer *cell = g_list_first(renderers)->data; //only one renderer
- g_list_free(renderers);
- gint cell_width, cell_height;
- gtk_cell_renderer_get_fixed_size(cell, &cell_width, &cell_height);
-
- *minimal = cell_width;
- *natural = cell_width;
-}
-
-static void
-gtk_combo_box_text_alt_get_preferred_height(GtkWidget *widget, int *minimal, int *natural)
-{
- g_return_if_fail(widget != NULL);
-
- /* Combo box is height-for-width only
- * (so we always just reserve enough height for the minimum width) */
- gint min_width, nat_width;
- GTK_WIDGET_GET_CLASS(widget)->get_preferred_width(widget, &min_width, &nat_width);
- GTK_WIDGET_GET_CLASS(widget)->get_preferred_height_for_width(widget, min_width, minimal, natural);
-
-}
-
-static void
-gtk_combo_box_text_alt_get_preferred_width_for_height(GtkWidget *widget,
- gint avail_size,
- gint *minimum_size,
- gint *natural_size)
-{
- /* Combo box is height-for-width only
- * (so we assume we always reserved enough height for the minimum width) */
- GTK_WIDGET_GET_CLASS(widget)->get_preferred_width(widget, minimum_size, natural_size);
-}
-
-static void
-gtk_combo_box_text_alt_get_preferred_height_for_width(GtkWidget *widget,
- gint avail_size,
- gint *minimum_size,
- gint *natural_size)
-{
- GList *renderers = gtk_cell_layout_get_cells((GtkCellLayout *)widget);
- GtkCellRenderer *cell = g_list_first(renderers)->data; //only one renderer
- g_list_free(renderers);
-
- GtkRequisition min_size, nat_size;
- gtk_cell_renderer_get_preferred_size(cell, widget, &min_size, &nat_size);
-
- gint xpad, ypad;
- gtk_cell_renderer_get_padding(cell, &xpad, &ypad);
- gtk_cell_renderer_set_padding(cell, xpad, 0);
-
- *minimum_size = min_size.height;
- *natural_size = nat_size.height;
-
-}
-
diff --git a/shoes/native/gtkentryalt.c b/shoes/native/gtkentryalt.c
deleted file mode 100644
index 6a1e369d..00000000
--- a/shoes/native/gtkentryalt.c
+++ /dev/null
@@ -1,87 +0,0 @@
-
-
-#include "shoes/app.h"
-#include "shoes/ruby.h"
-#include "shoes/config.h"
-#include "shoes/world.h"
-#include "shoes/native.h"
-#include "shoes/internal.h"
-
-#include "gtkentryalt.h"
-
-/* Private class member */
-#define GTKENTRY_ALT_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), \
- GTK_TYPE_ENTRY_ALT, GtkEntry_AltPrivate))
-
-typedef struct _GtkEntry_AltPrivate GtkEntry_AltPrivate;
-
-struct _GtkEntry_AltPrivate
-{
- /* to avoid warnings (g_type_class_add_private: assertion `private_size > 0' failed) */
- gchar dummy;
-};
-
-/* Forward declarations */
-static void gtk_entry_alt_get_preferred_width(GtkWidget *widget,
- int *minimal, int *natural);
-static void gtk_entry_alt_get_preferred_height(GtkWidget *widget,
- int *minimal, int *natural);
-
-/* Define the GtkEntry_Alt type and inherit from GtkEntry */
-G_DEFINE_TYPE(GtkEntry_Alt, gtk_entry_alt, GTK_TYPE_ENTRY);
-
-/* Initialize the GtkEntry_Alt class */
-static void
-gtk_entry_alt_class_init(GtkEntry_AltClass *klass)
-{
- /* Override GtkWidget methods */
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
- widget_class->get_preferred_width = gtk_entry_alt_get_preferred_width;
- widget_class->get_preferred_height = gtk_entry_alt_get_preferred_height;
-
- /* Override GtkEntry methods */
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- //GtkEntryClass *entry_class = GTK_ENTRY_CLASS(klass);
- // ...
-
- /* Add private indirection member */
- g_type_class_add_private(klass, sizeof(GtkEntry_AltPrivate));
-}
-
-/* Initialize a new GtkEntry_Alt instance */
-static void
-gtk_entry_alt_init(GtkEntry_Alt *entryAlt)
-{
- /* This means that GtkEntry_Alt doesn't supply its own GdkWindow */
- gtk_widget_set_has_window(GTK_WIDGET(entryAlt), FALSE);
-
- /* Initialize private members */
- GtkEntry_AltPrivate *priv = GTKENTRY_ALT_PRIVATE(entryAlt);
-
-}
-
-/* Return a new GtkEntry_Alt cast to a GtkWidget */
-GtkWidget *
-gtk_entry_alt_new()
-{
- return GTK_WIDGET(g_object_new(gtk_entry_alt_get_type(), NULL));
-}
-
-
-static void
-gtk_entry_alt_get_preferred_width(GtkWidget *widget, int *minimal, int *natural)
-{
- g_return_if_fail(widget != NULL);
-
- *minimal = 1;
- *natural = 1;
-}
-
-static void
-gtk_entry_alt_get_preferred_height(GtkWidget *widget, int *minimal, int *natural)
-{
- g_return_if_fail(widget != NULL);
-
- *minimal = 1;
- *natural = 1;
-}
diff --git a/shoes/native/gtkprogressbaralt.c b/shoes/native/gtkprogressbaralt.c
deleted file mode 100644
index 1fc52254..00000000
--- a/shoes/native/gtkprogressbaralt.c
+++ /dev/null
@@ -1,86 +0,0 @@
-
-#include "shoes/app.h"
-#include "shoes/ruby.h"
-#include "shoes/config.h"
-#include "shoes/world.h"
-#include "shoes/native.h"
-#include "shoes/internal.h"
-
-#include "gtkprogressbaralt.h"
-
-/* Private class member */
-#define GTK_PROGRESS_BAR_ALT_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), \
- GTK_TYPE_PROGRESS_BAR_ALT, GtkProgressBar_AltPrivate))
-
-typedef struct _GtkProgressBar_AltPrivate GtkProgressBar_AltPrivate;
-
-struct _GtkProgressBar_AltPrivate
-{
- /* to avoid warnings (g_type_class_add_private: assertion `private_size > 0' failed) */
- gchar dummy;
-};
-
-/* Forward declarations */
-static void gtk_progress_bar_alt_get_preferred_width(GtkWidget *widget,
- int *minimal, int *natural);
-static void gtk_progress_bar_alt_get_preferred_height(GtkWidget *widget,
- int *minimal, int *natural);
-
-/* Define the GtkProgressBar_Alt type and inherit from GtkProgressBar */
-G_DEFINE_TYPE(GtkProgressBar_Alt, gtk_progress_bar_alt, GTK_TYPE_PROGRESS_BAR);
-
-/* Initialize the GtkProgressBar_Alt class */
-static void
-gtk_progress_bar_alt_class_init(GtkProgressBar_AltClass *klass)
-{
- /* Override GtkWidget methods */
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
- widget_class->get_preferred_width = gtk_progress_bar_alt_get_preferred_width;
- widget_class->get_preferred_height = gtk_progress_bar_alt_get_preferred_height;
-
- /* Override GtkProgressBar methods */
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- // ...
-
- /* Add private indirection member */
- g_type_class_add_private(klass, sizeof(GtkProgressBar_AltPrivate));
-}
-
-/* Initialize a new GtkProgressBar_Alt instance */
-static void
-gtk_progress_bar_alt_init(GtkProgressBar_Alt *progressbarAlt)
-{
- /* This means that GtkProgressBar_Alt doesn't supply its own GdkWindow */
- gtk_widget_set_has_window(GTK_WIDGET(progressbarAlt), FALSE);
-
- /* Initialize private members */
- GtkProgressBar_AltPrivate *priv = GTK_PROGRESS_BAR_ALT_PRIVATE(progressbarAlt);
-
-}
-
-/* Return a new GtkProgressBar_Alt cast to a GtkWidget */
-GtkWidget *
-gtk_progress_bar_alt_new()
-{
- return GTK_WIDGET(g_object_new(gtk_progress_bar_alt_get_type(), NULL));
-}
-
-static void
-gtk_progress_bar_alt_get_preferred_width(GtkWidget *widget, int *minimal, int *natural)
-{
- g_return_if_fail(widget != NULL);
-
- *minimal = 1;
- *natural = 1;
-}
-
-static void
-gtk_progress_bar_alt_get_preferred_height(GtkWidget *widget, int *minimal, int *natural)
-{
- g_return_if_fail(widget != NULL);
-
- *minimal = 1;
- *natural = 1;
-}
-
-
diff --git a/shoes/native/gtkscrolledwindowalt.c b/shoes/native/gtkscrolledwindowalt.c
deleted file mode 100644
index e50916c2..00000000
--- a/shoes/native/gtkscrolledwindowalt.c
+++ /dev/null
@@ -1,98 +0,0 @@
-
-#include "shoes/app.h"
-#include "shoes/ruby.h"
-#include "shoes/config.h"
-#include "shoes/world.h"
-#include "shoes/native.h"
-#include "shoes/internal.h"
-
-#include "gtkscrolledwindowalt.h"
-
-/* Private class member */
-#define GTK_SCROLLED_WINDOW_ALT_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), \
- GTK_TYPE_SCROLLED_WINDOW_ALT, GtkScrolledWindow_AltPrivate))
-
-typedef struct _GtkScrolledWindow_AltPrivate GtkScrolledWindow_AltPrivate;
-
-struct _GtkScrolledWindow_AltPrivate
-{
- /* to avoid warnings (g_type_class_add_private: assertion `private_size > 0' failed) */
- gchar dummy;
-};
-
-/* Forward declarations */
-static void gtk_scrolled_window_alt_get_preferred_width(GtkWidget *widget,
- int *minimal, int *natural);
-static void gtk_scrolled_window_alt_get_preferred_height(GtkWidget *widget,
- int *minimal, int *natural);
-
-/* Define the GtkScrolledWindow_Alt type and inherit from GtkScrolledWindow */
-G_DEFINE_TYPE(GtkScrolledWindow_Alt, gtk_scrolled_window_alt, GTK_TYPE_SCROLLED_WINDOW);
-
-/* Initialize the GtkScrolledWindow_Alt class */
-static void
-gtk_scrolled_window_alt_class_init(GtkScrolledWindow_AltClass *klass)
-{
- /* Override GtkWidget methods */
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
- widget_class->get_preferred_width = gtk_scrolled_window_alt_get_preferred_width;
- widget_class->get_preferred_height = gtk_scrolled_window_alt_get_preferred_height;
-
- /* Override GtkScrolledWindow methods */
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- // ...
-
- /* Add private indirection member */
- g_type_class_add_private(klass, sizeof(GtkScrolledWindow_AltPrivate));
-}
-
-/* Initialize a new GtkScrolledWindow_Alt instance */
-static void
-gtk_scrolled_window_alt_init(GtkScrolledWindow_Alt *scrolledwindowAlt)
-{
- /* This means that GtkScrolledWindow_Alt doesn't supply its own GdkWindow */
- //gtk_widget_set_has_window(GTK_WIDGET(scrolledwindowAlt), FALSE);
- gtk_widget_set_has_window(GTK_WIDGET(scrolledwindowAlt),
- gtk_widget_get_has_window(GTK_WIDGET(&(scrolledwindowAlt->parent_instance))));
-
- /* Initialize private members */
- GtkScrolledWindow_AltPrivate *priv = GTK_SCROLLED_WINDOW_ALT_PRIVATE(scrolledwindowAlt);
-
-}
-
-/* Return a new GtkScrolledWindow_Alt cast to a GtkWidget */
-GtkWidget *
-gtk_scrolled_window_alt_new(GtkAdjustment *hadjustment,
- GtkAdjustment *vadjustment)
-{
- if (hadjustment)
- g_return_val_if_fail (GTK_IS_ADJUSTMENT (hadjustment), NULL);
-
- if (vadjustment)
- g_return_val_if_fail (GTK_IS_ADJUSTMENT (vadjustment), NULL);
-
- return GTK_WIDGET(g_object_new (gtk_scrolled_window_alt_get_type(),
- "hadjustment", hadjustment,
- "vadjustment", vadjustment,
- NULL));
-}
-
-static void
-gtk_scrolled_window_alt_get_preferred_width(GtkWidget *widget, int *minimal, int *natural)
-{
- g_return_if_fail(widget != NULL);
-
- *minimal = 1;
- *natural = 1;
-}
-
-static void
-gtk_scrolled_window_alt_get_preferred_height(GtkWidget *widget, int *minimal, int *natural)
-{
- g_return_if_fail(widget != NULL);
-
- *minimal = 1;
- *natural = 1;
-}
-
-
diff --git a/shoes/native.h b/shoes/native/native.h
similarity index 63%
rename from shoes/native.h
rename to shoes/native/native.h
index f81a99c0..3db1fd09 100644
--- a/shoes/native.h
+++ b/shoes/native/native.h
@@ -2,6 +2,9 @@
// shoes/native.h
// Common native Shoes routines.
//
+#ifndef SHOES_NATIVE_H
+#define SHOES_NATIVE_H
+
#define CHANGED_COORDS() \
(p1->ix != p2->ix || p1->iy != p2->iy || \
p1->iw != p2->iw || p1->dx != p2->dx || \
@@ -39,6 +42,10 @@ shoes_code shoes_app_cursor(shoes_app *, ID);
void shoes_native_app_resized(shoes_app *);
void shoes_native_app_title(shoes_app *, char *);
void shoes_native_app_fullscreen(shoes_app *, char);
+double shoes_native_app_get_opacity(shoes_app *app);
+void shoes_native_app_set_opacity(shoes_app *app, double opacity);
+void shoes_native_app_set_decoration(shoes_app *app, gboolean decorated);
+int shoes_native_app_get_decoration(shoes_app *app);
shoes_code shoes_native_app_open(shoes_app *, char *, int);
void shoes_native_app_show(shoes_app *);
void shoes_native_loop(void);
@@ -46,7 +53,7 @@ void shoes_native_app_close(shoes_app *);
void shoes_native_app_set_icon(shoes_app *, char *);
void shoes_native_app_set_wtitle(shoes_app *, char*);
int shoes_native_console(); // Yes it's different
-int shoes_native_terminal();
+int shoes_native_terminal();
void shoes_native_app_console();
void shoes_browser_open(char *);
void shoes_slot_init(VALUE, SHOES_SLOT_OS *, int, int, int, int, int, int);
@@ -56,72 +63,39 @@ void shoes_cairo_destroy(shoes_canvas *);
void shoes_group_clear(SHOES_GROUP_OS *);
void shoes_native_canvas_place(shoes_canvas *, shoes_canvas *);
void shoes_native_canvas_resize(shoes_canvas *);
+
+// TODO: Control belongs to types/native
void shoes_native_control_hide(SHOES_CONTROL_REF);
void shoes_native_control_show(SHOES_CONTROL_REF);
void shoes_native_control_position(SHOES_CONTROL_REF, shoes_place *,
- VALUE, shoes_canvas *, shoes_place *);
+ VALUE, shoes_canvas *, shoes_place *);
void shoes_native_control_position_no_pad(SHOES_CONTROL_REF, shoes_place *,
- VALUE, shoes_canvas *, shoes_place *);
+ VALUE, shoes_canvas *, shoes_place *);
void shoes_native_control_repaint(SHOES_CONTROL_REF, shoes_place *,
- shoes_canvas *, shoes_place *);
+ shoes_canvas *, shoes_place *);
void shoes_native_control_repaint_no_pad(SHOES_CONTROL_REF, shoes_place *,
- shoes_canvas *, shoes_place *);
+ shoes_canvas *, shoes_place *);
void shoes_native_control_focus(SHOES_CONTROL_REF);
void shoes_native_control_state(SHOES_CONTROL_REF, SHOES_BOOL, SHOES_BOOL);
void shoes_native_control_remove(SHOES_CONTROL_REF, shoes_canvas *);
void shoes_native_control_free(SHOES_CONTROL_REF);
-SHOES_CONTROL_REF shoes_native_surface_new(VALUE, VALUE);
-unsigned long shoes_native_surface_get_window_handle(SHOES_CONTROL_REF);
-void shoes_native_surface_position(SHOES_SURFACE_REF, shoes_place *,
- VALUE, shoes_canvas *, shoes_place *);
-void shoes_native_surface_hide(SHOES_SURFACE_REF);
-void shoes_native_surface_show(SHOES_SURFACE_REF);
-void shoes_native_surface_remove(SHOES_SURFACE_REF);
-
-//SHOES_SURFACE_REF shoes_native_svg(shoes_canvas *, VALUE, shoes_place *);
-//void shoes_native_svg_position(SHOES_SURFACE_REF, shoes_place *,
-// VALUE, shoes_canvas *, shoes_place *);
-//void shoes_native_svg_hide(SHOES_SURFACE_REF);
-//void shoes_native_svg_show(SHOES_SURFACE_REF);
-//void shoes_native_svg_remove(shoes_canvas *, SHOES_SURFACE_REF);
+void shoes_native_control_set_tooltip(SHOES_CONTROL_REF ref, VALUE tooltip);
+VALUE shoes_native_control_get_tooltip(SHOES_CONTROL_REF ref);
-SHOES_CONTROL_REF shoes_native_button(VALUE, shoes_canvas *, shoes_place *, char *);
-SHOES_CONTROL_REF shoes_native_edit_line(VALUE, shoes_canvas *, shoes_place *, VALUE, char *);
-VALUE shoes_native_edit_line_get_text(SHOES_CONTROL_REF);
-void shoes_native_edit_line_set_text(SHOES_CONTROL_REF, char *);
-VALUE shoes_native_edit_line_cursor_to_end(SHOES_CONTROL_REF);
-SHOES_CONTROL_REF shoes_native_edit_box(VALUE, shoes_canvas *, shoes_place *, VALUE, char *);
-VALUE shoes_native_edit_box_get_text(SHOES_CONTROL_REF);
-void shoes_native_edit_box_set_text(SHOES_CONTROL_REF, char *);
-// 3.2.25 adds
-void shoes_native_edit_box_append(SHOES_CONTROL_REF, char *);
-void shoes_native_edit_box_scroll_to_end(SHOES_CONTROL_REF);
// 3.3.x might add native_text_edit_box
SHOES_CONTROL_REF shoes_native_text_edit_box(VALUE, shoes_canvas *, shoes_place *, VALUE, char *);
VALUE shoes_native_text_edit_box_get_text(SHOES_CONTROL_REF);
void shoes_native_text_edit_box_set_text(SHOES_CONTROL_REF, char *);
VALUE shoes_native_text_edit_box_append(SHOES_CONTROL_REF, char *);
void shoes_native_text_edit_box_scroll_to_end(SHOES_CONTROL_REF);
-//
-SHOES_CONTROL_REF shoes_native_list_box(VALUE, shoes_canvas *, shoes_place *, VALUE, char *);
-void shoes_native_list_box_update(SHOES_CONTROL_REF, VALUE);
-VALUE shoes_native_list_box_get_active(SHOES_CONTROL_REF, VALUE);
-SHOES_CONTROL_REF shoes_native_progress(VALUE, shoes_canvas *, shoes_place *, VALUE, char *);
-double shoes_native_progress_get_fraction(SHOES_CONTROL_REF);
-void shoes_native_progress_set_fraction(SHOES_CONTROL_REF, double);
-SHOES_CONTROL_REF shoes_native_slider(VALUE, shoes_canvas *, shoes_place *, VALUE, char *);
-double shoes_native_slider_get_fraction(SHOES_CONTROL_REF);
-void shoes_native_slider_set_fraction(SHOES_CONTROL_REF, double);
SHOES_CONTROL_REF shoes_native_check(VALUE, shoes_canvas *, shoes_place *, VALUE, char *);
VALUE shoes_native_check_get(SHOES_CONTROL_REF);
void shoes_native_check_set(SHOES_CONTROL_REF, int);
-void shoes_native_list_box_set_active(SHOES_CONTROL_REF, VALUE, VALUE);
SHOES_CONTROL_REF shoes_native_radio(VALUE, shoes_canvas *, shoes_place *, VALUE, VALUE);
-void shoes_native_timer_remove(shoes_canvas *, SHOES_TIMER_REF);
-SHOES_TIMER_REF shoes_native_timer_start(VALUE, shoes_canvas *, unsigned int);
void shoes_native_canvas_oneshot(int, VALUE);
VALUE shoes_native_clipboard_get(shoes_app *);
void shoes_native_clipboard_set(shoes_app *, VALUE);
+void shoes_native_systray(char *, char *, char *); //temporary sig and location
VALUE shoes_native_to_s(VALUE);
char *shoes_native_to_utf8(VALUE, int *);
VALUE shoes_native_window_color(shoes_app *);
@@ -134,3 +108,5 @@ VALUE shoes_dialog_open(int,VALUE*,VALUE);
VALUE shoes_dialog_save(int,VALUE*,VALUE);
VALUE shoes_dialog_open_folder(int,VALUE*,VALUE);
VALUE shoes_dialog_save_folder(int,VALUE*,VALUE);
+
+#endif
diff --git a/shoes/plot/chart_series.c b/shoes/plot/chart_series.c
index 49ff7c3f..73b91421 100644
--- a/shoes/plot/chart_series.c
+++ b/shoes/plot/chart_series.c
@@ -1,391 +1,364 @@
/*
- * shoes_chart_series class
+ * shoes_chart_series class
* encapsulates the data and unique presentation values of them
- * not really Shoes api user visible (yet)
+ * not really Shoes api user visible (yet)
*/
+#include "shoes/types/color.h"
#include "shoes/plot/plot.h"
+
+
// forward declare
static VALUE shoes_chart_series_parse_points(VALUE);
-void
-shoes_chart_series_mark(shoes_chart_series *self_t)
-{
- rb_gc_mark_maybe(self_t->values);
- rb_gc_mark_maybe(self_t->labels);
- rb_gc_mark_maybe(self_t->minv);
- rb_gc_mark_maybe(self_t->maxv);
- rb_gc_mark_maybe(self_t->name);
- rb_gc_mark_maybe(self_t->desc);
- rb_gc_mark_maybe(self_t->strokes);
- rb_gc_mark_maybe(self_t->point_type);
- rb_gc_mark_maybe(self_t->color);
+void shoes_chart_series_mark(shoes_chart_series *self_t) {
+ rb_gc_mark_maybe(self_t->values);
+ rb_gc_mark_maybe(self_t->labels);
+ rb_gc_mark_maybe(self_t->minv);
+ rb_gc_mark_maybe(self_t->maxv);
+ rb_gc_mark_maybe(self_t->name);
+ rb_gc_mark_maybe(self_t->desc);
+ rb_gc_mark_maybe(self_t->strokes);
+ rb_gc_mark_maybe(self_t->point_type);
+ rb_gc_mark_maybe(self_t->color);
}
-void
-shoes_chart_series_free(shoes_chart_series *self_t)
-{
- RUBY_CRITICAL(SHOE_FREE(self_t));
+void shoes_chart_series_free(shoes_chart_series *self_t) {
+ RUBY_CRITICAL(SHOE_FREE(self_t));
}
-VALUE
-shoes_chart_series_alloc(VALUE klass)
-{
- VALUE obj;
- shoes_chart_series *ser = SHOE_ALLOC(shoes_chart_series);
- SHOE_MEMZERO(ser, shoes_chart_series, 1);
- obj = Data_Wrap_Struct(klass, shoes_chart_series_mark, shoes_chart_series_free, ser);
- ser->values = rb_ary_new();
- ser->labels = rb_ary_new();
- ser->minv = Qnil;
- ser->maxv = Qnil;
- ser->name = Qnil;
- ser->desc = Qnil;
- ser->strokes = Qnil;
- ser->point_type = Qnil;
- ser->color = Qnil;
- return obj;
+VALUE shoes_chart_series_alloc(VALUE klass) {
+ VALUE obj;
+ shoes_chart_series *ser = SHOE_ALLOC(shoes_chart_series);
+ SHOE_MEMZERO(ser, shoes_chart_series, 1);
+ obj = Data_Wrap_Struct(klass, shoes_chart_series_mark, shoes_chart_series_free, ser);
+ ser->values = rb_ary_new();
+ ser->labels = rb_ary_new();
+ ser->minv = Qnil;
+ ser->maxv = Qnil;
+ ser->name = Qnil;
+ ser->desc = Qnil;
+ ser->strokes = Qnil;
+ ser->point_type = Qnil;
+ ser->color = Qnil;
+ return obj;
}
// This is called from plot.c shoes_plot_add()
void shoes_chart_series_Cinit(shoes_chart_series *self_t, VALUE rbvals, VALUE rblabels,
- VALUE rbmax, VALUE rbmin, VALUE rbname, VALUE rbdesc, VALUE rbstroke,
- VALUE rbpoint_type, VALUE color_wrapped)
-{
- self_t->values = rbvals;
- self_t->labels = rblabels;
- self_t->maxv = rbmax;
- self_t->minv = rbmin;
- self_t->name = rbname;
- self_t->desc = rbdesc;
- if (NIL_P(rbdesc)) {
- //printf("fixme: no long name\n");
- self_t->desc = rbname;
- }
- self_t->strokes = rbstroke;
- self_t->point_type = rbpoint_type;
- self_t->color = color_wrapped;
-}
-
-// This is not a visible Shoes widget but it is a Shoes class.
-VALUE
-shoes_chart_series_new(int argc, VALUE *argv, VALUE self)
-{
- shoes_chart_series *self_t;
- VALUE newseries = Qnil;
- VALUE rbsz, rbvals, rblabels, rbmin, rbmax, rbname, rbdesc, rbcolor;
- VALUE rbstroke, rbpoint, rbpoint_type = Qnil;
- VALUE color_wrapped = Qnil;
- rb_arg_list args;
- switch (rb_parse_args(argc, argv, "h", &args)) {
- case 1:
- newseries = args.a[0];
- }
-
- if (TYPE(newseries) == T_HASH) {
- rbvals = shoes_hash_get(newseries, rb_intern("values"));
- rblabels = shoes_hash_get(newseries, rb_intern("labels"));
- rbmin = shoes_hash_get(newseries, rb_intern("min"));
- rbmax = shoes_hash_get(newseries, rb_intern("max"));
- rbname = shoes_hash_get(newseries, rb_intern("name"));
- rbdesc = shoes_hash_get(newseries, rb_intern("desc"));
- rbcolor = shoes_hash_get(newseries, rb_intern("color"));
- rbstroke = shoes_hash_get(newseries, rb_intern("strokewidth"));
- rbpoint = shoes_hash_get(newseries, rb_intern("points"));
-
- if ( NIL_P(rbvals) || TYPE(rbvals) != T_ARRAY ) {
- rb_raise(rb_eArgError, "plot.add: Missing an Array of values");
- }
- int valsz = RARRAY_LEN(rbvals);
- rbsz = INT2NUM(valsz);
- if (NIL_P(rbmin) || NIL_P(rbmax)) {
- rb_raise(rb_eArgError, "plot.add: Missing min: or max: option");
- }
- if ( NIL_P(rblabels)) {
- // we can fake it - poorly - TODO: call a user given proc ?
- int l = NUM2INT(rbsz);
- int i;
- rblabels = rb_ary_new2(l);
- for (i = 0; i < l; i++) {
- char t[8];
- sprintf(t, "%i", i+1);
- VALUE foostr = rb_str_new2(t);
- rb_ary_store(rblabels, i, foostr);
- }
- }
-
- if (NIL_P(rbname))
- rb_raise(rb_eArgError, "plot.add missing name:");
+ VALUE rbmax, VALUE rbmin, VALUE rbname, VALUE rbdesc, VALUE rbstroke,
+ VALUE rbpoint_type, VALUE color_wrapped) {
+ self_t->values = rbvals;
+ self_t->labels = rblabels;
+ self_t->maxv = rbmax;
+ self_t->minv = rbmin;
+ self_t->name = rbname;
+ self_t->desc = rbdesc;
if (NIL_P(rbdesc)) {
- rbdesc = rbname;
- }
- // handle colors
- if (! NIL_P(rbcolor)) {
- if (rb_obj_is_kind_of(rbcolor, cColor)) {
- color_wrapped = rbcolor;
- } else {
- if (TYPE(rbcolor) != T_STRING)
- rb_raise(rb_eArgError, "plot.add color must be a string");
- char *cstr = RSTRING_PTR(rbcolor);
- color_wrapped = shoes_hash_get(cColors, rb_intern(cstr));
- if (NIL_P(color_wrapped))
- rb_raise(rb_eArgError, "plot.add color: not a known color");
- }
- } else {
- // will have to accept the default colors of the chart
- color_wrapped = Qnil;
+ //printf("fixme: no long name\n");
+ self_t->desc = rbname;
}
-
- if (!NIL_P(rbstroke)) {
- if (TYPE(rbstroke) != T_FIXNUM)
- rb_raise(rb_eArgError, "plot.add strokewidth not an integer\n");
- } else {
- rbstroke = INT2NUM(1); // default
- }
-
- // This is weird. We handle :true, :false/nil and string.
- if (NIL_P(rbpoint)) {
- rbpoint_type = INT2NUM(NUB_NONE);
- } else {
- rbpoint_type = shoes_chart_series_parse_points(rbpoint);
+ self_t->strokes = rbstroke;
+ self_t->point_type = rbpoint_type;
+ self_t->color = color_wrapped;
+}
+
+// This is not a visible Shoes widget but it is a Shoes class.
+VALUE shoes_chart_series_new(int argc, VALUE *argv, VALUE self) {
+ shoes_chart_series *self_t;
+ VALUE newseries = Qnil;
+ VALUE rbsz, rbvals, rblabels, rbmin, rbmax, rbname, rbdesc, rbcolor;
+ VALUE rbstroke, rbpoint, rbpoint_type = Qnil;
+ VALUE color_wrapped = Qnil;
+ rb_arg_list args;
+ switch (rb_parse_args(argc, argv, "h", &args)) {
+ case 1:
+ newseries = args.a[0];
}
+
+ if (TYPE(newseries) == T_HASH) {
+ rbvals = shoes_hash_get(newseries, rb_intern("values"));
+ rblabels = shoes_hash_get(newseries, rb_intern("labels"));
+ rbmin = shoes_hash_get(newseries, rb_intern("min"));
+ rbmax = shoes_hash_get(newseries, rb_intern("max"));
+ rbname = shoes_hash_get(newseries, rb_intern("name"));
+ rbdesc = shoes_hash_get(newseries, rb_intern("desc"));
+ rbcolor = shoes_hash_get(newseries, rb_intern("color"));
+ rbstroke = shoes_hash_get(newseries, rb_intern("strokewidth"));
+ rbpoint = shoes_hash_get(newseries, rb_intern("points"));
+
+ if ( NIL_P(rbvals) || TYPE(rbvals) != T_ARRAY ) {
+ rb_raise(rb_eArgError, "plot.add: Missing an Array of values");
+ }
+ int valsz = RARRAY_LEN(rbvals);
+ rbsz = INT2NUM(valsz);
+ if (NIL_P(rbmin) || NIL_P(rbmax)) {
+ rb_raise(rb_eArgError, "plot.add: Missing min: or max: option");
+ }
+ if ( NIL_P(rblabels)) {
+ // we can fake it - poorly - TODO: call a user given proc ?
+ int l = NUM2INT(rbsz);
+ int i;
+ rblabels = rb_ary_new2(l);
+ for (i = 0; i < l; i++) {
+ char t[8];
+ sprintf(t, "%i", i+1);
+ VALUE foostr = rb_str_new2(t);
+ rb_ary_store(rblabels, i, foostr);
+ }
+ }
+
+ if (NIL_P(rbname))
+ rb_raise(rb_eArgError, "plot.add missing name:");
+ if (NIL_P(rbdesc)) {
+ rbdesc = rbname;
+ }
+ // handle colors
+ if (! NIL_P(rbcolor)) {
+ if (rb_obj_is_kind_of(rbcolor, cColor)) {
+ color_wrapped = rbcolor;
+ } else {
+ if (TYPE(rbcolor) != T_STRING)
+ rb_raise(rb_eArgError, "plot.add color must be a string");
+ char *cstr = RSTRING_PTR(rbcolor);
+ color_wrapped = shoes_hash_get(cColors, rb_intern(cstr));
+ if (NIL_P(color_wrapped))
+ rb_raise(rb_eArgError, "plot.add color: not a known color");
+ }
+ } else {
+ // will have to accept the default colors of the chart
+ color_wrapped = Qnil;
+ }
+
+ if (!NIL_P(rbstroke)) {
+ if (TYPE(rbstroke) != T_FIXNUM)
+ rb_raise(rb_eArgError, "plot.add strokewidth not an integer\n");
+ } else {
+ rbstroke = INT2NUM(1); // default
+ }
+
+ // This is weird. We handle :true, :false/nil and string.
+ if (NIL_P(rbpoint)) {
+ rbpoint_type = INT2NUM(NUB_NONE);
+ } else {
+ rbpoint_type = shoes_chart_series_parse_points(rbpoint);
+ }
#if 0
- if (TYPE(rbpoint) == T_STRING) {
- char *req = RSTRING_PTR(rbpoint);
- if (!strcmp(req, "dot"))
- rbpoint_type = INT2NUM(NUB_DOT);
- else if (!strcmp(req, "circle"))
- rbpoint_type = INT2NUM(NUB_CIRCLE);
- else if (!strcmp(req, "box"))
- rbpoint_type = INT2NUM(NUB_BOX);
- else if (!strcmp(req, "rect"))
- rbpoint_type = INT2NUM(NUB_RECT);
- else
- rb_raise(rb_eArgError, "plot.add points: string does not match known types\n");
- } else if (TYPE(rbpoint) == T_TRUE) {
- rbpoint_type = INT2NUM(NUB_DOT);
- } else if (TYPE(rbpoint) == T_FALSE) {
- rbpoint_type = INT2NUM(NUB_NONE);
- }
+ if (TYPE(rbpoint) == T_STRING) {
+ char *req = RSTRING_PTR(rbpoint);
+ if (!strcmp(req, "dot"))
+ rbpoint_type = INT2NUM(NUB_DOT);
+ else if (!strcmp(req, "circle"))
+ rbpoint_type = INT2NUM(NUB_CIRCLE);
+ else if (!strcmp(req, "box"))
+ rbpoint_type = INT2NUM(NUB_BOX);
+ else if (!strcmp(req, "rect"))
+ rbpoint_type = INT2NUM(NUB_RECT);
+ else
+ rb_raise(rb_eArgError, "plot.add points: string does not match known types\n");
+ } else if (TYPE(rbpoint) == T_TRUE) {
+ rbpoint_type = INT2NUM(NUB_DOT);
+ } else if (TYPE(rbpoint) == T_FALSE) {
+ rbpoint_type = INT2NUM(NUB_NONE);
+ }
#endif
- } else {
- rb_raise(rb_eArgError, "misssing something in plot.add \n");
- }
- VALUE obj = shoes_chart_series_alloc(cChartSeries);
- Data_Get_Struct(obj, shoes_chart_series, self_t);
- shoes_chart_series_Cinit(self_t, rbvals, rblabels, rbmax, rbmin, rbname, rbdesc,
- rbstroke, rbpoint_type, color_wrapped);
- return obj;
+ } else {
+ rb_raise(rb_eArgError, "misssing something in plot.add \n");
+ }
+ VALUE obj = shoes_chart_series_alloc(cChartSeries);
+ Data_Get_Struct(obj, shoes_chart_series, self_t);
+ shoes_chart_series_Cinit(self_t, rbvals, rblabels, rbmax, rbmin, rbname, rbdesc,
+ rbstroke, rbpoint_type, color_wrapped);
+ return obj;
}
-// ugly
+// ugly
static VALUE shoes_chart_series_parse_points(VALUE rbpoint) {
// This is weird. We handle :true, :false/nil and string.
VALUE rbpoint_type;
if (NIL_P(rbpoint)) {
- rbpoint_type = INT2NUM(NUB_NONE);
- return rbpoint_type;
+ rbpoint_type = INT2NUM(NUB_NONE);
+ return rbpoint_type;
}
if (TYPE(rbpoint) == T_STRING) {
- char *req = RSTRING_PTR(rbpoint);
- if (!strcmp(req, "dot"))
- rbpoint_type = INT2NUM(NUB_DOT);
- else if (!strcmp(req, "circle"))
- rbpoint_type = INT2NUM(NUB_CIRCLE);
- else if (!strcmp(req, "box"))
- rbpoint_type = INT2NUM(NUB_BOX);
- else if (!strcmp(req, "rect"))
- rbpoint_type = INT2NUM(NUB_RECT);
- else
- rb_raise(rb_eArgError, "plot.add points: string does not match known types\n");
+ char *req = RSTRING_PTR(rbpoint);
+ if (!strcmp(req, "dot"))
+ rbpoint_type = INT2NUM(NUB_DOT);
+ else if (!strcmp(req, "circle"))
+ rbpoint_type = INT2NUM(NUB_CIRCLE);
+ else if (!strcmp(req, "box"))
+ rbpoint_type = INT2NUM(NUB_BOX);
+ else if (!strcmp(req, "rect"))
+ rbpoint_type = INT2NUM(NUB_RECT);
+ else
+ rb_raise(rb_eArgError, "plot.add points: string does not match known types\n");
} else if (TYPE(rbpoint) == T_TRUE) {
rbpoint_type = INT2NUM(NUB_DOT);
} else if (TYPE(rbpoint) == T_FALSE) {
rbpoint_type = INT2NUM(NUB_NONE);
} else {
- rb_raise(rb_eArgError, "misssing something in plot.add \n");
+ rb_raise(rb_eArgError, "misssing something in plot.add \n");
}
- return rbpoint_type;
+ return rbpoint_type;
}
-// parse - Returns an mostly or entirely ruby array of arrays
-// used by radar charts called from shoes_plot_new() plot.c
+// parse - Returns an mostly or entirely ruby array of arrays
+// used by radar charts called from shoes_plot_new() plot.c
VALUE shoes_plot_parse_column_settings(VALUE opts) {
- if (TYPE(opts) != T_ARRAY)
- rb_raise(rb_eArgError, "column_settings is not an array");
- int count = RARRAY_LEN(opts);
- int i;
- VALUE outer_ary = rb_ary_new_capa(count);
- for (i = 0; i < count; i++) {
- VALUE rbcol = rb_ary_entry(opts, i);
- if (TYPE(rbcol) == T_ARRAY) {
- rb_ary_store(outer_ary, i, rbcol);
- } else if (TYPE(rbcol) != T_HASH) {
- rb_raise(rb_eArgError, "one of column_settings[] is not an array or hash");
- } else {
- // we know its a hash.
- VALUE inner_ary = rb_ary_new();
- VALUE rblabel, rbmin, rbmax, rbfmt;
- rblabel = shoes_hash_get(rbcol, rb_intern("label"));
- rbmin = shoes_hash_get(rbcol, rb_intern("min"));
- rbmax = shoes_hash_get(rbcol, rb_intern("max"));
- rbfmt = shoes_hash_get(rbcol, rb_intern("format"));
- rb_ary_store(inner_ary, 0, rblabel);
- rb_ary_store(inner_ary, 1, rbmin);
- rb_ary_store(inner_ary, 2, rbmax);
- if (! NIL_P(rbfmt))
- rb_ary_store(inner_ary, 3, rbfmt);
-
- rb_ary_store(outer_ary, i, inner_ary);
- }
- }
- return outer_ary;
+ if (TYPE(opts) != T_ARRAY)
+ rb_raise(rb_eArgError, "column_settings is not an array");
+ int count = RARRAY_LEN(opts);
+ int i;
+ VALUE outer_ary = rb_ary_new_capa(count);
+ for (i = 0; i < count; i++) {
+ VALUE rbcol = rb_ary_entry(opts, i);
+ if (TYPE(rbcol) == T_ARRAY) {
+ rb_ary_store(outer_ary, i, rbcol);
+ } else if (TYPE(rbcol) != T_HASH) {
+ rb_raise(rb_eArgError, "one of column_settings[] is not an array or hash");
+ } else {
+ // we know its a hash.
+ VALUE inner_ary = rb_ary_new();
+ VALUE rblabel, rbmin, rbmax, rbfmt;
+ rblabel = shoes_hash_get(rbcol, rb_intern("label"));
+ rbmin = shoes_hash_get(rbcol, rb_intern("min"));
+ rbmax = shoes_hash_get(rbcol, rb_intern("max"));
+ rbfmt = shoes_hash_get(rbcol, rb_intern("format"));
+ rb_ary_store(inner_ary, 0, rblabel);
+ rb_ary_store(inner_ary, 1, rbmin);
+ rb_ary_store(inner_ary, 2, rbmax);
+ if (! NIL_P(rbfmt))
+ rb_ary_store(inner_ary, 3, rbfmt);
+
+ rb_ary_store(outer_ary, i, inner_ary);
+ }
+ }
+ return outer_ary;
}
-// Simple getter/setter methods
-VALUE
-shoes_chart_series_values(VALUE self)
-{
- shoes_chart_series *cs;
- Data_Get_Struct(self, shoes_chart_series, cs);
- return cs->values;
+// Simple getter/setter methods
+VALUE shoes_chart_series_values(VALUE self) {
+ shoes_chart_series *cs;
+ Data_Get_Struct(self, shoes_chart_series, cs);
+ return cs->values;
}
-VALUE
-shoes_chart_series_labels(VALUE self)
-{
- shoes_chart_series *cs;
- Data_Get_Struct(self, shoes_chart_series, cs);
- return cs->labels;
+VALUE shoes_chart_series_labels(VALUE self) {
+ shoes_chart_series *cs;
+ Data_Get_Struct(self, shoes_chart_series, cs);
+ return cs->labels;
}
-VALUE shoes_chart_series_min(VALUE self)
-{
- shoes_chart_series *cs;
- Data_Get_Struct(self, shoes_chart_series, cs);
- return cs->minv;
+VALUE shoes_chart_series_min(VALUE self) {
+ shoes_chart_series *cs;
+ Data_Get_Struct(self, shoes_chart_series, cs);
+ return cs->minv;
}
-VALUE shoes_chart_series_min_set(VALUE self, VALUE val)
-{
- shoes_chart_series *cs;
- Data_Get_Struct(self, shoes_chart_series, cs);
- cs->minv = val;
- return cs->minv;
+VALUE shoes_chart_series_min_set(VALUE self, VALUE val) {
+ shoes_chart_series *cs;
+ Data_Get_Struct(self, shoes_chart_series, cs);
+ cs->minv = val;
+ return cs->minv;
}
-VALUE shoes_chart_series_max(VALUE self)
-{
- shoes_chart_series *cs;
- Data_Get_Struct(self, shoes_chart_series, cs);
- return cs->maxv;
+VALUE shoes_chart_series_max(VALUE self) {
+ shoes_chart_series *cs;
+ Data_Get_Struct(self, shoes_chart_series, cs);
+ return cs->maxv;
}
-VALUE shoes_chart_series_max_set(VALUE self, VALUE val)
-{
- shoes_chart_series *cs;
- Data_Get_Struct(self, shoes_chart_series, cs);
- cs->maxv = val;
- return cs->maxv;
+VALUE shoes_chart_series_max_set(VALUE self, VALUE val) {
+ shoes_chart_series *cs;
+ Data_Get_Struct(self, shoes_chart_series, cs);
+ cs->maxv = val;
+ return cs->maxv;
}
-VALUE shoes_chart_series_name(VALUE self)
-{
- shoes_chart_series *cs;
- Data_Get_Struct(self, shoes_chart_series, cs);
- return cs->name;
+VALUE shoes_chart_series_name(VALUE self) {
+ shoes_chart_series *cs;
+ Data_Get_Struct(self, shoes_chart_series, cs);
+ return cs->name;
}
-VALUE shoes_chart_series_desc(VALUE self)
-{
- shoes_chart_series *cs;
- Data_Get_Struct(self, shoes_chart_series, cs);
- return cs->desc;
+VALUE shoes_chart_series_desc(VALUE self) {
+ shoes_chart_series *cs;
+ Data_Get_Struct(self, shoes_chart_series, cs);
+ return cs->desc;
}
-VALUE shoes_chart_series_desc_set(VALUE self, VALUE str)
-{
- shoes_chart_series *cs;
- Data_Get_Struct(self, shoes_chart_series, cs);
- cs->desc = str;
- return cs->desc;
+VALUE shoes_chart_series_desc_set(VALUE self, VALUE str) {
+ shoes_chart_series *cs;
+ Data_Get_Struct(self, shoes_chart_series, cs);
+ cs->desc = str;
+ return cs->desc;
}
-VALUE shoes_chart_series_color(VALUE self)
-{
- shoes_chart_series *cs;
- Data_Get_Struct(self, shoes_chart_series, cs);
- return cs->color;
+VALUE shoes_chart_series_color(VALUE self) {
+ shoes_chart_series *cs;
+ Data_Get_Struct(self, shoes_chart_series, cs);
+ return cs->color;
}
-VALUE shoes_chart_series_color_set(VALUE self, VALUE clr)
-{
- shoes_chart_series *cs;
- Data_Get_Struct(self, shoes_chart_series, cs);
- cs->color = clr;
- return cs->color;
+VALUE shoes_chart_series_color_set(VALUE self, VALUE clr) {
+ shoes_chart_series *cs;
+ Data_Get_Struct(self, shoes_chart_series, cs);
+ cs->color = clr;
+ return cs->color;
}
-VALUE shoes_chart_series_strokewidth(VALUE self)
-{
- shoes_chart_series *cs;
- Data_Get_Struct(self, shoes_chart_series, cs);
- return cs->strokes;
+VALUE shoes_chart_series_strokewidth(VALUE self) {
+ shoes_chart_series *cs;
+ Data_Get_Struct(self, shoes_chart_series, cs);
+ return cs->strokes;
}
-VALUE shoes_chart_series_strokewidth_set(VALUE self, VALUE wid)
-{
- shoes_chart_series *cs;
- Data_Get_Struct(self, shoes_chart_series, cs);
- cs->strokes = wid;
- return cs->strokes;
+VALUE shoes_chart_series_strokewidth_set(VALUE self, VALUE wid) {
+ shoes_chart_series *cs;
+ Data_Get_Struct(self, shoes_chart_series, cs);
+ cs->strokes = wid;
+ return cs->strokes;
}
-VALUE shoes_chart_series_points(VALUE self)
-{
- shoes_chart_series *cs;
- Data_Get_Struct(self, shoes_chart_series, cs);
- return cs->point_type;
+VALUE shoes_chart_series_points(VALUE self) {
+ shoes_chart_series *cs;
+ Data_Get_Struct(self, shoes_chart_series, cs);
+ return cs->point_type;
}
-VALUE shoes_chart_series_points_set(VALUE self, VALUE pt)
-{
- shoes_chart_series *cs;
- Data_Get_Struct(self, shoes_chart_series, cs);
- if (TYPE(pt) == T_FIXNUM)
- cs->point_type = pt;
- else
- cs->point_type = shoes_chart_series_parse_points(pt);
- return cs->point_type;
+VALUE shoes_chart_series_points_set(VALUE self, VALUE pt) {
+ shoes_chart_series *cs;
+ Data_Get_Struct(self, shoes_chart_series, cs);
+ if (TYPE(pt) == T_FIXNUM)
+ cs->point_type = pt;
+ else
+ cs->point_type = shoes_chart_series_parse_points(pt);
+ return cs->point_type;
}
// ---- more interesting methods ----
// Returns and an array[label, value] at idx
-VALUE
-shoes_chart_series_get(VALUE self, VALUE idx)
-{
- shoes_chart_series *cs;
- Data_Get_Struct(self, shoes_chart_series, cs);
- VALUE nary = Qnil;
- if (TYPE(idx) == T_FIXNUM) {
- nary = rb_ary_new_capa(2);
- long i = NUM2INT(idx);
- rb_ary_store(nary, 0, rb_ary_entry(cs->labels, i));
- rb_ary_store(nary, 1, rb_ary_entry(cs->values, i));
- }
- return nary;
+VALUE shoes_chart_series_get(VALUE self, VALUE idx) {
+ shoes_chart_series *cs;
+ Data_Get_Struct(self, shoes_chart_series, cs);
+ VALUE nary = Qnil;
+ if (TYPE(idx) == T_FIXNUM) {
+ nary = rb_ary_new_capa(2);
+ long i = NUM2INT(idx);
+ rb_ary_store(nary, 0, rb_ary_entry(cs->labels, i));
+ rb_ary_store(nary, 1, rb_ary_entry(cs->values, i));
+ }
+ return nary;
}
// Sets labels[idx] and values[idx]
-VALUE
-shoes_chart_series_set(VALUE self, VALUE idx, VALUE ary)
-{
- shoes_chart_series *cs;
- Data_Get_Struct(self, shoes_chart_series, cs);
- if ((TYPE(idx) == T_FIXNUM) && (TYPE(ary) == T_ARRAY) && (RARRAY_LEN(ary) == 2)) {
- long i = NUM2INT(idx);
- rb_ary_store(cs->labels, i, rb_ary_entry(ary, 0));
- rb_ary_store(cs->values, i, rb_ary_entry(ary, 1));
- } else
- rb_raise(rb_eArgError, "bad arguments to chart_series.set");
- return Qtrue;
+VALUE shoes_chart_series_set(VALUE self, VALUE idx, VALUE ary) {
+ shoes_chart_series *cs;
+ Data_Get_Struct(self, shoes_chart_series, cs);
+ if ((TYPE(idx) == T_FIXNUM) && (TYPE(ary) == T_ARRAY) && (RARRAY_LEN(ary) == 2)) {
+ long i = NUM2INT(idx);
+ rb_ary_store(cs->labels, i, rb_ary_entry(ary, 0));
+ rb_ary_store(cs->values, i, rb_ary_entry(ary, 1));
+ } else
+ rb_raise(rb_eArgError, "bad arguments to chart_series.set");
+ return Qtrue;
}
diff --git a/shoes/plot/plot.c b/shoes/plot/plot.c
index 05a8f2a2..dd517091 100644
--- a/shoes/plot/plot.c
+++ b/shoes/plot/plot.c
@@ -1,5 +1,5 @@
/*
- * plot - draws charts/graphs
+ * plot - draws charts/graphs
*/
#include "shoes/plot/plot.h"
@@ -9,803 +9,763 @@
/* ------- Plot widget -----
* several methods are defined in ruby.c Macros (CLASS_COMMON2, TRANS_COMMON)
*/
-
+
// some forward declares for functions in this file
void shoes_plot_draw_everything(cairo_t *, shoes_place *, shoes_plot *);
// alloc some memory for a shoes_plot; We'll protect it's Ruby VALUES from gc
// out of caution. fingers crossed.
-void
-shoes_plot_mark(shoes_plot *self_t)
-{
- rb_gc_mark_maybe(self_t->parent);
- rb_gc_mark_maybe(self_t->attr);
- rb_gc_mark_maybe(self_t->series);
- rb_gc_mark_maybe(self_t->title);
- rb_gc_mark_maybe(self_t->caption);
- rb_gc_mark_maybe(self_t->legend);
- rb_gc_mark_maybe(self_t->background);
- rb_gc_mark_maybe(self_t->default_colors);
- rb_gc_mark_maybe(self_t->column_opts);
-}
-
-void
-shoes_plot_free(shoes_plot *self_t)
-{
- pango_font_description_free (self_t->title_pfd);
- pango_font_description_free (self_t->caption_pfd);
- pango_font_description_free (self_t->legend_pfd);
- pango_font_description_free (self_t->label_pfd);
- shoes_transform_release(self_t->st);
- if (self_t->c_things) {
- switch (self_t-> chart_type) {
- case PIE_CHART:
- shoes_plot_pie_dealloc(self_t);
- break;
- case RADAR_CHART:
- shoes_plot_radar_dealloc(self_t);
- break;
- }
- }
- RUBY_CRITICAL(SHOE_FREE(self_t));
-}
-
-VALUE
-shoes_plot_alloc(VALUE klass)
-{
- VALUE obj;
- shoes_plot *plot = SHOE_ALLOC(shoes_plot);
- SHOE_MEMZERO(plot, shoes_plot, 1);
- obj = Data_Wrap_Struct(klass, shoes_plot_mark, shoes_plot_free, plot);
- plot->parent = Qnil;
- plot->column_opts = Qnil;
- plot->series = rb_ary_new();
- plot->st = NULL;
- plot->auto_grid = 0;
- plot->x_ticks = 8;
- plot->y_ticks = 6;
- plot->missing = MISSING_SKIP;
- plot->chart_type = LINE_CHART;
- plot->background = Qnil;
- plot->default_colors = rb_ary_new();
- shoes_plot_util_default_colors(plot);
- plot->c_things = NULL;
- return obj;
-}
-
-VALUE
-shoes_plot_new(int argc, VALUE *argv, VALUE parent)
-{
- VALUE attr = Qnil, widthObj = Qnil, heightObj = Qnil;
- VALUE title = Qnil, caption = Qnil, fontreq = Qnil, auto_grid = Qnil;
- VALUE x_ticks = Qnil, y_ticks = Qnil, boundbox = Qnil;
- VALUE missing = Qnil, chart_type = Qnil, background = Qnil;
- VALUE pie_pct = Qnil, colors = Qnil, radar_opts = Qnil;
- VALUE rbcol_settings = Qnil, grid_lines = Qnil, radar_lbl_mult = Qnil;
- shoes_canvas *canvas;
- Data_Get_Struct(parent, shoes_canvas, canvas);
-
- rb_arg_list args;
- switch (rb_parse_args(argc, argv, "iih", &args))
- {
- case 1:
- widthObj = args.a[0];
- heightObj = args.a[1];
- attr = args.a[2];
- break;
- }
-
- if (!NIL_P(attr)) {
- title = shoes_hash_get(attr, rb_intern("title"));
- caption = shoes_hash_get(attr, rb_intern("caption"));
- fontreq = shoes_hash_get(attr, rb_intern("font"));
- auto_grid = shoes_hash_get(attr, rb_intern("auto_grid"));
- x_ticks = shoes_hash_get(attr, rb_intern("x_ticks"));
- y_ticks = shoes_hash_get(attr, rb_intern("y_ticks"));
- missing = shoes_hash_get(attr, rb_intern("default"));
- chart_type = shoes_hash_get(attr, rb_intern("chart"));
- background = shoes_hash_get(attr, rb_intern("background"));
- boundbox = shoes_hash_get(attr, rb_intern("boundary_box"));
- pie_pct = shoes_hash_get(attr, rb_intern("percent"));
- colors = shoes_hash_get(attr, rb_intern("colors"));
- radar_opts = shoes_hash_get(attr, rb_intern("column_settings"));
- grid_lines = shoes_hash_get(attr, rb_intern("grid_lines"));
- radar_lbl_mult = shoes_hash_get(attr, rb_intern("label_radius"));
- // there may be many other things in that hash :-)
- } else {
- rb_raise(rb_eArgError, "Plot: missing mandatory {options}");
- }
-
- VALUE obj = shoes_plot_alloc(cPlot);
- shoes_plot *self_t;
- Data_Get_Struct(obj, shoes_plot, self_t);
-
- self_t->place.w = NUM2INT(widthObj);
- self_t->place.h = NUM2INT(heightObj);
-
- if (NIL_P(chart_type)) {
- self_t->chart_type = LINE_CHART; // default
- } else {
- char *str;
- int err = 0;
- if (TYPE(chart_type) == T_STRING) {
- str = RSTRING_PTR(chart_type);
- if (! strcmp(str, "line"))
- self_t->chart_type = LINE_CHART;
- else if (! strcmp(str, "timeseries"))
- self_t->chart_type = TIMESERIES_CHART;
- else if (! strcmp(str, "column"))
- self_t->chart_type = COLUMN_CHART;
- else if (! strcmp(str, "scatter"))
- self_t->chart_type = SCATTER_CHART;
- else if (! strcmp(str, "pie"))
- self_t->chart_type = PIE_CHART;
- else if (! strcmp(str, "radar")) {
- self_t->chart_type = RADAR_CHART;
- if (NIL_P(radar_opts))
- rb_raise(rb_eArgError, "Plot: radar chart requires column settings");
- else {
- // parse radar only options here
- if (! NIL_P(grid_lines)) {
- if (TYPE(grid_lines) == T_FIXNUM ) {
- self_t->x_ticks = NUM2INT(grid_lines);
- } else if (grid_lines == Qfalse) {
- self_t->x_ticks = 0;
- } else if (grid_lines == Qtrue) {
- self_t->x_ticks = 1;
- } else {
- rb_raise(rb_eArgError, "Plot: grid_lines is not t/f or integer");
- }
- } else {
- self_t->x_ticks = 1; // use heuristic for default
- }
- // radar needs many options not writen yet. sigh.
- if (! NIL_P(radar_lbl_mult)) {
- self_t->radar_label_mult = NUM2DBL(radar_lbl_mult);
- } else {
- self_t->radar_label_mult = 1.15;
- }
- // returns an array of arrays
- rbcol_settings = shoes_plot_parse_column_settings(radar_opts);
- self_t->column_opts = rbcol_settings;
- // type check parser
- int i, cnt;
- cnt = RARRAY_LEN(rbcol_settings);
- for (i = 0; i < cnt; i++) {
- VALUE rbcol = rb_ary_entry(rbcol_settings, i);
- VALUE rbv;
- rbv = rb_ary_entry(rbcol, 0); // string - xaxis label
- if (TYPE(rbv) != T_STRING)
- rb_raise(rb_eArgError, "Plot: column_settings label [0] is not a string");
- rbv = rb_ary_entry(rbcol, 1); // number - xaxis min
- if (TYPE(rbv) != T_FIXNUM && (TYPE(rbv) != T_FLOAT))
- rb_raise(rb_eArgError, "Plot: column_settings min [1] is not a number");
- rbv = rb_ary_entry(rbcol, 2); // number - xaxis max
- if (TYPE(rbv) != T_FIXNUM && (TYPE(rbv) != T_FLOAT))
- rb_raise(rb_eArgError, "Plot: column_settings max [2] is not a number");
- rbv = rb_ary_entry(rbcol, 3); // optional format string
- if (! NIL_P(rbv) && (TYPE(rbv) != T_STRING))
- rb_raise(rb_eArgError, "Plot: column_settings format [3] is not a string");
- }
+void shoes_plot_mark(shoes_plot *self_t) {
+ rb_gc_mark_maybe(self_t->parent);
+ rb_gc_mark_maybe(self_t->attr);
+ rb_gc_mark_maybe(self_t->series);
+ rb_gc_mark_maybe(self_t->title);
+ rb_gc_mark_maybe(self_t->caption);
+ rb_gc_mark_maybe(self_t->legend);
+ rb_gc_mark_maybe(self_t->background);
+ rb_gc_mark_maybe(self_t->default_colors);
+ rb_gc_mark_maybe(self_t->column_opts);
+}
+
+void shoes_plot_free(shoes_plot *self_t) {
+ pango_font_description_free (self_t->title_pfd);
+ pango_font_description_free (self_t->caption_pfd);
+ pango_font_description_free (self_t->legend_pfd);
+ pango_font_description_free (self_t->label_pfd);
+ shoes_transform_release(self_t->st);
+ if (self_t->c_things) {
+ switch (self_t-> chart_type) {
+ case PIE_CHART:
+ shoes_plot_pie_dealloc(self_t);
+ break;
+ case RADAR_CHART:
+ shoes_plot_radar_dealloc(self_t);
+ break;
}
- } else
- err = 1;
- } else err = 1;
- if (err)
- rb_raise(rb_eArgError, "Plot: bad chart type");
- }
-
- if (! NIL_P(fontreq)) {
- self_t->fontname = RSTRING_PTR(fontreq);
- } else {
- self_t->fontname = "Helvitica";
- }
-
- if (!NIL_P(title)) {
- self_t->title = title;
- } else {
- self_t->title = rb_str_new2("Missing a title:");
- }
- // setup pangocairo for the title
- self_t->title_pfd = pango_font_description_new ();
- pango_font_description_set_family (self_t->title_pfd, self_t->fontname);
- pango_font_description_set_weight (self_t->title_pfd, PANGO_WEIGHT_BOLD);
- pango_font_description_set_absolute_size (self_t->title_pfd, 16 * PANGO_SCALE);
-
-
- self_t->auto_grid = 0; // default
- if (! NIL_P(auto_grid)) {
- if (RTEST(auto_grid))
- self_t->auto_grid = 1;
- }
-
- self_t->boundbox = 1; // default
- if (! NIL_P(boundbox)) {
- if (! RTEST(boundbox))
- self_t->boundbox = 0;
- }
-
- // TODO :sym would be more ruby like than strings but appears to
- // pollute symbol space in ruby.c and something of PITA.
- if ((!NIL_P(missing)) && (TYPE(missing) == T_STRING)) {
- char *mstr = RSTRING_PTR(missing);
- if (strcmp(mstr, "min") == 0)
- self_t->missing = MISSING_MIN;
- else if (strcmp(mstr, "max") == 0)
- self_t->missing = MISSING_MAX;
- else
- self_t->missing = MISSING_SKIP;
- }
- if (self_t->chart_type == PIE_CHART) {
- // using the missing field to keep track of percentage option
- self_t->missing = 0; // default
- if (! NIL_P(pie_pct))
- self_t->missing = RTEST(pie_pct);
- }
- if (!NIL_P(caption)) {
- self_t->caption = caption;
- } else {
- self_t->caption = rb_str_new2("Missing a caption:");
- }
-
- // setup pangocairo for the caption
- self_t->caption_pfd = pango_font_description_new ();
- pango_font_description_set_family (self_t->caption_pfd, self_t->fontname);
- pango_font_description_set_weight (self_t->caption_pfd, PANGO_WEIGHT_NORMAL);
- pango_font_description_set_absolute_size (self_t->caption_pfd, 12 * PANGO_SCALE);
-
- // setup pangocairo for the legend
- self_t->legend_pfd = pango_font_description_new ();
- pango_font_description_set_family (self_t->legend_pfd, self_t->fontname);
- pango_font_description_set_weight (self_t->legend_pfd, PANGO_WEIGHT_NORMAL);
- pango_font_description_set_absolute_size (self_t->legend_pfd, 14 * PANGO_SCALE);
-
- // setup pangocairo for the labels
- self_t->label_pfd = pango_font_description_new ();
- pango_font_description_set_family (self_t->label_pfd, self_t->fontname);
- pango_font_description_set_weight (self_t->label_pfd, PANGO_WEIGHT_NORMAL);
- pango_font_description_set_absolute_size (self_t->label_pfd, 12 * PANGO_SCALE);
-
- // setup pangocairo for realy small (used by radar)
- self_t->tiny_pfd = pango_font_description_new ();
- pango_font_description_set_family (self_t->tiny_pfd, self_t->fontname);
- pango_font_description_set_weight (self_t->tiny_pfd, PANGO_WEIGHT_NORMAL);
- pango_font_description_set_absolute_size (self_t->tiny_pfd, 10 * PANGO_SCALE);
-
- // TODO: these should be computed based on heuristics (% of vertical?)
- // and font sizes
- self_t->title_h = 50;
- self_t->legend_h = 25;
- self_t->caption_h = 25;
- self_t->yaxis_offset = 50;
-
- // width of y axis on left and right of plot, in pixels
- // really should be computed based on the data being presented.
- // TODO Of course.
-
- if (!NIL_P(x_ticks))
- self_t->x_ticks = NUM2INT(x_ticks);
- if (!NIL_P(y_ticks))
- self_t->y_ticks = NUM2INT(y_ticks);
+ }
+ RUBY_CRITICAL(SHOE_FREE(self_t));
+}
+
+VALUE shoes_plot_alloc(VALUE klass) {
+ VALUE obj;
+ shoes_plot *plot = SHOE_ALLOC(shoes_plot);
+ SHOE_MEMZERO(plot, shoes_plot, 1);
+ obj = Data_Wrap_Struct(klass, shoes_plot_mark, shoes_plot_free, plot);
+ plot->parent = Qnil;
+ plot->column_opts = Qnil;
+ plot->series = rb_ary_new();
+ plot->st = NULL;
+ plot->auto_grid = 0;
+ plot->x_ticks = 8;
+ plot->y_ticks = 6;
+ plot->missing = MISSING_SKIP;
+ plot->chart_type = LINE_CHART;
+ plot->background = Qnil;
+ plot->default_colors = rb_ary_new();
+ shoes_plot_util_default_colors(plot);
+ plot->c_things = NULL;
+ return obj;
+}
+
+VALUE shoes_plot_new(int argc, VALUE *argv, VALUE parent) {
+ VALUE attr = Qnil, widthObj = Qnil, heightObj = Qnil;
+ VALUE title = Qnil, caption = Qnil, fontreq = Qnil, auto_grid = Qnil;
+ VALUE x_ticks = Qnil, y_ticks = Qnil, boundbox = Qnil;
+ VALUE missing = Qnil, chart_type = Qnil, background = Qnil;
+ VALUE pie_pct = Qnil, colors = Qnil, radar_opts = Qnil;
+ VALUE rbcol_settings = Qnil, grid_lines = Qnil, radar_lbl_mult = Qnil;
+ shoes_canvas *canvas;
+ Data_Get_Struct(parent, shoes_canvas, canvas);
+
+ rb_arg_list args;
+ switch (rb_parse_args(argc, argv, "iih", &args)) {
+ case 1:
+ widthObj = args.a[0];
+ heightObj = args.a[1];
+ attr = args.a[2];
+ break;
+ }
+
+ if (!NIL_P(attr)) {
+ title = shoes_hash_get(attr, rb_intern("title"));
+ caption = shoes_hash_get(attr, rb_intern("caption"));
+ fontreq = shoes_hash_get(attr, rb_intern("font"));
+ auto_grid = shoes_hash_get(attr, rb_intern("auto_grid"));
+ x_ticks = shoes_hash_get(attr, rb_intern("x_ticks"));
+ y_ticks = shoes_hash_get(attr, rb_intern("y_ticks"));
+ missing = shoes_hash_get(attr, rb_intern("default"));
+ chart_type = shoes_hash_get(attr, rb_intern("chart"));
+ background = shoes_hash_get(attr, rb_intern("background"));
+ boundbox = shoes_hash_get(attr, rb_intern("boundary_box"));
+ pie_pct = shoes_hash_get(attr, rb_intern("percent"));
+ colors = shoes_hash_get(attr, rb_intern("colors"));
+ radar_opts = shoes_hash_get(attr, rb_intern("column_settings"));
+ grid_lines = shoes_hash_get(attr, rb_intern("grid_lines"));
+ radar_lbl_mult = shoes_hash_get(attr, rb_intern("label_radius"));
+ // there may be many other things in that hash :-)
+ } else {
+ rb_raise(rb_eArgError, "Plot: missing mandatory {options}");
+ }
+
+ VALUE obj = shoes_plot_alloc(cPlot);
+ shoes_plot *self_t;
+ Data_Get_Struct(obj, shoes_plot, self_t);
+
+ self_t->place.w = NUM2INT(widthObj);
+ self_t->place.h = NUM2INT(heightObj);
+
+ if (NIL_P(chart_type)) {
+ self_t->chart_type = LINE_CHART; // default
+ } else {
+ char *str;
+ int err = 0;
+ if (TYPE(chart_type) == T_STRING) {
+ str = RSTRING_PTR(chart_type);
+ if (! strcmp(str, "line"))
+ self_t->chart_type = LINE_CHART;
+ else if (! strcmp(str, "timeseries"))
+ self_t->chart_type = TIMESERIES_CHART;
+ else if (! strcmp(str, "column"))
+ self_t->chart_type = COLUMN_CHART;
+ else if (! strcmp(str, "scatter"))
+ self_t->chart_type = SCATTER_CHART;
+ else if (! strcmp(str, "pie"))
+ self_t->chart_type = PIE_CHART;
+ else if (! strcmp(str, "radar")) {
+ self_t->chart_type = RADAR_CHART;
+ if (NIL_P(radar_opts))
+ rb_raise(rb_eArgError, "Plot: radar chart requires column settings");
+ else {
+ // parse radar only options here
+ if (! NIL_P(grid_lines)) {
+ if (TYPE(grid_lines) == T_FIXNUM ) {
+ self_t->x_ticks = NUM2INT(grid_lines);
+ } else if (grid_lines == Qfalse) {
+ self_t->x_ticks = 0;
+ } else if (grid_lines == Qtrue) {
+ self_t->x_ticks = 1;
+ } else {
+ rb_raise(rb_eArgError, "Plot: grid_lines is not t/f or integer");
+ }
+ } else {
+ self_t->x_ticks = 1; // use heuristic for default
+ }
+ // radar needs many options not writen yet. sigh.
+ if (! NIL_P(radar_lbl_mult)) {
+ self_t->radar_label_mult = NUM2DBL(radar_lbl_mult);
+ } else {
+ self_t->radar_label_mult = 1.15;
+ }
+ // returns an array of arrays
+ rbcol_settings = shoes_plot_parse_column_settings(radar_opts);
+ self_t->column_opts = rbcol_settings;
+ // type check parser
+ int i, cnt;
+ cnt = RARRAY_LEN(rbcol_settings);
+ for (i = 0; i < cnt; i++) {
+ VALUE rbcol = rb_ary_entry(rbcol_settings, i);
+ VALUE rbv;
+ rbv = rb_ary_entry(rbcol, 0); // string - xaxis label
+ if (TYPE(rbv) != T_STRING)
+ rb_raise(rb_eArgError, "Plot: column_settings label [0] is not a string");
+ rbv = rb_ary_entry(rbcol, 1); // number - xaxis min
+ if (TYPE(rbv) != T_FIXNUM && (TYPE(rbv) != T_FLOAT))
+ rb_raise(rb_eArgError, "Plot: column_settings min [1] is not a number");
+ rbv = rb_ary_entry(rbcol, 2); // number - xaxis max
+ if (TYPE(rbv) != T_FIXNUM && (TYPE(rbv) != T_FLOAT))
+ rb_raise(rb_eArgError, "Plot: column_settings max [2] is not a number");
+ rbv = rb_ary_entry(rbcol, 3); // optional format string
+ if (! NIL_P(rbv) && (TYPE(rbv) != T_STRING))
+ rb_raise(rb_eArgError, "Plot: column_settings format [3] is not a string");
+ }
+ }
+ } else
+ err = 1;
+ } else err = 1;
+ if (err)
+ rb_raise(rb_eArgError, "Plot: bad chart type");
+ }
+
+ if (! NIL_P(fontreq)) {
+ self_t->fontname = RSTRING_PTR(fontreq);
+ } else {
+ self_t->fontname = "Helvitica";
+ }
+
+ if (!NIL_P(title)) {
+ self_t->title = title;
+ } else {
+ self_t->title = rb_str_new2("Missing a title:");
+ }
+ // setup pangocairo for the title
+ self_t->title_pfd = pango_font_description_new ();
+ pango_font_description_set_family (self_t->title_pfd, self_t->fontname);
+ pango_font_description_set_weight (self_t->title_pfd, PANGO_WEIGHT_BOLD);
+ pango_font_description_set_absolute_size (self_t->title_pfd, 16 * PANGO_SCALE);
+
+
+ self_t->auto_grid = 0; // default
+ if (! NIL_P(auto_grid)) {
+ if (RTEST(auto_grid))
+ self_t->auto_grid = 1;
+ }
+
+ self_t->boundbox = 1; // default unless
+ if (! NIL_P(boundbox)) {
+ if (! RTEST(boundbox))
+ self_t->boundbox = 0;
+ }
- if (! NIL_P(background) && rb_obj_is_kind_of(background, cColor)) {
- self_t->background = background;
- } else {
- self_t->background = shoes_hash_get(cColors, rb_intern("white"));
- }
-
- //Override series default colors? (created in alloc)
- if (! NIL_P(colors) && TYPE(colors) == T_ARRAY) {
- int sz = RARRAY_LEN(colors);
- int i;
- for (i = 0; i < sz; i++) {
- VALUE clr = rb_ary_entry(colors, i);
- rb_ary_store(self_t->default_colors, i, clr);
+ if (self_t->chart_type == PIE_CHART || self_t->chart_type == RADAR_CHART)
+ self_t->boundbox = 0;
+
+ // TODO :sym would be more ruby like than strings but appears to
+ // pollute symbol space in ruby.c and something of PITA.
+ if ((!NIL_P(missing)) && (TYPE(missing) == T_STRING)) {
+ char *mstr = RSTRING_PTR(missing);
+ if (strcmp(mstr, "min") == 0)
+ self_t->missing = MISSING_MIN;
+ else if (strcmp(mstr, "max") == 0)
+ self_t->missing = MISSING_MAX;
+ else
+ self_t->missing = MISSING_SKIP;
+ }
+ if (self_t->chart_type == PIE_CHART) {
+ // using the missing field to keep track of percentage option
+ self_t->missing = 0; // default
+ if (! NIL_P(pie_pct))
+ self_t->missing = RTEST(pie_pct);
}
- }
-
- self_t->parent = parent;
- self_t->attr = attr;
- // initialize cairo matrice used in transform methods (rotate, scale, skew, translate)
- self_t->st = shoes_transform_touch(canvas->st);
-
- return obj;
+ if (!NIL_P(caption)) {
+ self_t->caption = caption;
+ } else {
+ self_t->caption = rb_str_new2("Missing a caption:");
+ }
+
+ // setup pangocairo for the caption
+ self_t->caption_pfd = pango_font_description_new ();
+ pango_font_description_set_family (self_t->caption_pfd, self_t->fontname);
+ pango_font_description_set_weight (self_t->caption_pfd, PANGO_WEIGHT_NORMAL);
+ pango_font_description_set_absolute_size (self_t->caption_pfd, 12 * PANGO_SCALE);
+
+ // setup pangocairo for the legend
+ self_t->legend_pfd = pango_font_description_new ();
+ pango_font_description_set_family (self_t->legend_pfd, self_t->fontname);
+ pango_font_description_set_weight (self_t->legend_pfd, PANGO_WEIGHT_NORMAL);
+ pango_font_description_set_absolute_size (self_t->legend_pfd, 14 * PANGO_SCALE);
+
+ // setup pangocairo for the labels
+ self_t->label_pfd = pango_font_description_new ();
+ pango_font_description_set_family (self_t->label_pfd, self_t->fontname);
+ pango_font_description_set_weight (self_t->label_pfd, PANGO_WEIGHT_NORMAL);
+ pango_font_description_set_absolute_size (self_t->label_pfd, 12 * PANGO_SCALE);
+
+ // setup pangocairo for realy small (used by radar)
+ self_t->tiny_pfd = pango_font_description_new ();
+ pango_font_description_set_family (self_t->tiny_pfd, self_t->fontname);
+ pango_font_description_set_weight (self_t->tiny_pfd, PANGO_WEIGHT_NORMAL);
+ pango_font_description_set_absolute_size (self_t->tiny_pfd, 10 * PANGO_SCALE);
+
+ // TODO: these should be computed based on heuristics (% of vertical?)
+ // and font sizes
+ self_t->title_h = 50;
+ self_t->legend_h = 25;
+ self_t->caption_h = 25;
+ self_t->yaxis_offset = 50;
+
+ // width of y axis on left and right of plot, in pixels
+ // really should be computed based on the data being presented.
+ // TODO Of course.
+
+ if (!NIL_P(x_ticks))
+ self_t->x_ticks = NUM2INT(x_ticks);
+ if (!NIL_P(y_ticks))
+ self_t->y_ticks = NUM2INT(y_ticks);
+
+ if (! NIL_P(background) && rb_obj_is_kind_of(background, cColor)) {
+ self_t->background = background;
+ } else {
+ self_t->background = shoes_hash_get(cColors, rb_intern("white"));
+ }
+
+ //Override series default colors? (created in alloc)
+ if (! NIL_P(colors) && TYPE(colors) == T_ARRAY) {
+ int sz = RARRAY_LEN(colors);
+ int i;
+ for (i = 0; i < sz; i++) {
+ VALUE clr = rb_ary_entry(colors, i);
+ rb_ary_store(self_t->default_colors, i, clr);
+ }
+ }
+
+ self_t->parent = parent;
+ self_t->attr = attr;
+ // initialize cairo matrice used in transform methods (rotate, scale, skew, translate)
+ self_t->st = shoes_transform_touch(canvas->st);
+
+ return obj;
}
// This gets called very often by Shoes. May be slow for large plots?
-VALUE shoes_plot_draw(VALUE self, VALUE c, VALUE actual)
-{
- shoes_plot *self_t;
- shoes_place place;
- shoes_canvas *canvas;
- Data_Get_Struct(self, shoes_plot, self_t);
- Data_Get_Struct(c, shoes_canvas, canvas);
- if (ATTR(self_t->attr, hidden) == Qtrue) return self;
- int rel =(REL_CANVAS | REL_SCALE);
- shoes_place_decide(&place, c, self_t->attr, self_t->place.w, self_t->place.h, rel, REL_COORDS(rel) == REL_CANVAS);
-
- if (RTEST(actual)) {
- shoes_plot_draw_everything(CCR(canvas), &place, self_t);
- //self_t->place = place;
- }
-
- if (!ABSY(place)) {
- canvas->cx += place.w;
- canvas->cy = place.y;
- canvas->endx = canvas->cx;
- canvas->endy = max(canvas->endy, place.y + place.h);
- }
- if(rb_obj_class(c) == cStack) {
- canvas->cx = CPX(canvas);
- canvas->cy = canvas->endy;
- }
- return self;
+VALUE shoes_plot_draw(VALUE self, VALUE c, VALUE actual) {
+ shoes_plot *self_t;
+ shoes_place place;
+ shoes_canvas *canvas;
+ Data_Get_Struct(self, shoes_plot, self_t);
+ Data_Get_Struct(c, shoes_canvas, canvas);
+ if (ATTR(self_t->attr, hidden) == Qtrue) return self;
+ int rel =(REL_CANVAS | REL_SCALE);
+ shoes_place_decide(&place, c, self_t->attr, self_t->place.w, self_t->place.h, rel, REL_COORDS(rel) == REL_CANVAS);
+
+ if (RTEST(actual)) {
+ shoes_plot_draw_everything(CCR(canvas), &place, self_t);
+ //self_t->place = place;
+ }
+
+ if (!ABSY(place)) {
+ canvas->cx += place.w;
+ canvas->cy = place.y;
+ canvas->endx = canvas->cx;
+ canvas->endy = max(canvas->endy, place.y + place.h);
+ }
+ if(rb_obj_class(c) == cStack) {
+ canvas->cx = CPX(canvas);
+ canvas->cy = canvas->endy;
+ }
+ return self;
}
// this is called by both shoes_plot_draw (general Shoes refresh events)
// and by shoes_plot_save_as. The real code is in plot_util.c and the
// other plot_xxxx.c files
void shoes_plot_draw_everything(cairo_t *cr, shoes_place *place, shoes_plot *self_t) {
-
+
shoes_apply_transformation(cr, self_t->st, place, 0); // cairo_save(cr) is inside
cairo_translate(cr, place->ix + place->dx, place->iy + place->dy);
switch (self_t->chart_type) {
- case TIMESERIES_CHART:
- case LINE_CHART:
- shoes_plot_line_draw(cr, place, self_t);
- break;
- case COLUMN_CHART:
- shoes_plot_column_draw(cr, place, self_t);
- break;
- case SCATTER_CHART:
- shoes_plot_scatter_draw(cr, place, self_t);
- break;
- case PIE_CHART:
- shoes_plot_pie_draw(cr, place, self_t);
- break;
- case RADAR_CHART:
- shoes_plot_radar_draw(cr, place, self_t);
+ case TIMESERIES_CHART:
+ case LINE_CHART:
+ shoes_plot_line_draw(cr, place, self_t);
+ break;
+ case COLUMN_CHART:
+ shoes_plot_column_draw(cr, place, self_t);
+ break;
+ case SCATTER_CHART:
+ shoes_plot_scatter_draw(cr, place, self_t);
+ break;
+ case PIE_CHART:
+ shoes_plot_pie_draw(cr, place, self_t);
+ break;
+ case RADAR_CHART:
+ shoes_plot_radar_draw(cr, place, self_t);
}
// drawing finished
shoes_undo_transformation(cr, self_t->st, place, 0); // does cairo_restore(cr)
self_t->place = *place;
}
-VALUE shoes_plot_add(VALUE self, VALUE theseries)
-{
- shoes_plot *self_t;
- //VALUE rbsz, rbvals, rbobs, rbmin, rbmax, rbshname, rblgname, rbcolor;
- //VALUE rbstroke, rbnubs, rbnubtype = Qnil;
- //VALUE color_wrapped = Qnil;
- Data_Get_Struct(self, shoes_plot, self_t);
- int i = self_t->seriescnt; // track number of series to plot.
- VALUE newseries = theseries;
- if (i >= 6) {
- rb_raise(rb_eArgError, "Maximum of 6 series");
- }
- // we got a hash - convert it to a chart_series
- if (TYPE(theseries) == T_HASH) {
- newseries = shoes_chart_series_new(1, &theseries, self);
- }
-
- if (rb_obj_is_kind_of(newseries, cChartSeries)) {
- shoes_chart_series *cs;
- Data_Get_Struct(newseries, shoes_chart_series, cs);
- int nobs = RARRAY_LEN(cs->values);
- self_t->beg_idx = 0;
- self_t->end_idx = nobs;
- self_t->seriescnt++;
- rb_ary_store(self_t->series, i, newseries);
- // radar & pie chart types need to pre-compute some geometery and store it
- // in their own structs.
- if (self_t->chart_type == PIE_CHART)
- shoes_plot_pie_init(self_t);
- else if (self_t->chart_type == RADAR_CHART)
- shoes_plot_radar_init(self_t);
- // We need to specify a default color if we don't have an explicit one
- if (NIL_P(cs->color)) {
- cs->color = rb_ary_entry(self_t->default_colors, i);
+VALUE shoes_plot_add(VALUE self, VALUE theseries) {
+ shoes_plot *self_t;
+ //VALUE rbsz, rbvals, rbobs, rbmin, rbmax, rbshname, rblgname, rbcolor;
+ //VALUE rbstroke, rbnubs, rbnubtype = Qnil;
+ //VALUE color_wrapped = Qnil;
+ Data_Get_Struct(self, shoes_plot, self_t);
+ int i = self_t->seriescnt; // track number of series to plot.
+ VALUE newseries = theseries;
+ if (i >= 6) {
+ rb_raise(rb_eArgError, "Maximum of 6 series");
}
+ // we got a hash - convert it to a chart_series
+ if (TYPE(theseries) == T_HASH) {
+ newseries = shoes_chart_series_new(1, &theseries, self);
+ }
+
+ if (rb_obj_is_kind_of(newseries, cChartSeries)) {
+ shoes_chart_series *cs;
+ Data_Get_Struct(newseries, shoes_chart_series, cs);
+ int nobs = RARRAY_LEN(cs->values);
+ self_t->beg_idx = 0;
+ self_t->end_idx = nobs;
+ self_t->seriescnt++;
+ rb_ary_store(self_t->series, i, newseries);
+ // radar & pie chart types need to pre-compute some geometery and store it
+ // in their own structs.
+ if (self_t->chart_type == PIE_CHART)
+ shoes_plot_pie_init(self_t);
+ else if (self_t->chart_type == RADAR_CHART)
+ shoes_plot_radar_init(self_t);
+ // We need to specify a default color if we don't have an explicit one
+ if (NIL_P(cs->color)) {
+ cs->color = rb_ary_entry(self_t->default_colors, i);
+ }
+ shoes_canvas_repaint_all(self_t->parent);
+ return newseries;
+ }
+ // if we get here, we don't have a chart_series and we couldn't create one
+ // odds are exceptions have been raised already, but just in case:
+ rb_raise(rb_eArgError, "plot.add: not a valid hash or chart_series");
+ return self;
+}
+
+VALUE shoes_plot_delete(VALUE self, VALUE series) {
+ shoes_plot *self_t;
+ Data_Get_Struct(self, shoes_plot, self_t);
+ if (TYPE(series) != T_FIXNUM)
+ rb_raise(rb_eArgError, "plot.delete arg not integer");
+ int idx = NUM2INT(series);
+ if (! (idx >= 0 && idx <= self_t->seriescnt))
+ rb_raise(rb_eArgError, "plot.delete arg is out of range");
+ rb_ary_delete_at(self_t->series, idx);
+ if (self_t->chart_type == PIE_CHART)
+ shoes_plot_pie_dealloc(self_t);
+ self_t->seriescnt--;
shoes_canvas_repaint_all(self_t->parent);
- return newseries;
- }
- // if we get here, we don't have a chart_series and we couldn't create one
- // odds are exceptions have been raised already, but just in case:
- rb_raise(rb_eArgError, "plot.add: not a valid hash or chart_series");
- return self;
-}
-
-VALUE shoes_plot_delete(VALUE self, VALUE series)
-{
- shoes_plot *self_t;
- Data_Get_Struct(self, shoes_plot, self_t);
- if (TYPE(series) != T_FIXNUM)
- rb_raise(rb_eArgError, "plot.delete arg not integer");
- int idx = NUM2INT(series);
- if (! (idx >= 0 && idx <= self_t->seriescnt))
- rb_raise(rb_eArgError, "plot.delete arg is out of range");
- rb_ary_delete_at(self_t->series, idx);
- if (self_t->chart_type == PIE_CHART)
- shoes_plot_pie_dealloc(self_t);
- self_t->seriescnt--;
- shoes_canvas_repaint_all(self_t->parent);
- return Qtrue;
+ return Qtrue;
}
// odds are high that this may flash or crash if called too frequently
-VALUE shoes_plot_redraw_to(VALUE self, VALUE to_here)
-{
- shoes_plot *self_t;
- Data_Get_Struct(self, shoes_plot, self_t);
- // restrict to timeseries chart and line chart
- if ((self_t->chart_type != TIMESERIES_CHART) &&
- (self_t->chart_type != LINE_CHART))
- return Qnil;
- if (TYPE(to_here) != T_FIXNUM)
- rb_raise(rb_eArgError, "plot.redraw_to arg is not an integer");
- int idx = NUM2INT(to_here);
- self_t->end_idx = idx;
+VALUE shoes_plot_redraw_to(VALUE self, VALUE to_here) {
+ shoes_plot *self_t;
+ Data_Get_Struct(self, shoes_plot, self_t);
+ // restrict to timeseries chart and line chart
+ if ((self_t->chart_type != TIMESERIES_CHART) &&
+ (self_t->chart_type != LINE_CHART))
+ return Qnil;
+ if (TYPE(to_here) != T_FIXNUM)
+ rb_raise(rb_eArgError, "plot.redraw_to arg is not an integer");
+ int idx = NUM2INT(to_here);
+ self_t->end_idx = idx;
- shoes_canvas_repaint_all(self_t->parent);
- //printf("shoes_plot_redraw_to(%i) called\n", idx);
- return Qtrue;
+ shoes_canvas_repaint_all(self_t->parent);
+ //printf("shoes_plot_redraw_to(%i) called\n", idx);
+ return Qtrue;
}
// id method
-VALUE shoes_plot_find_name(VALUE self, VALUE name)
-{
- shoes_plot *self_t;
- Data_Get_Struct(self, shoes_plot, self_t);
- if (TYPE(name) != T_STRING) rb_raise(rb_eArgError, "plot.find arg is not a string");
- char *search = RSTRING_PTR(name);
- int i;
- for (i = 0; i seriescnt; i++) {
- VALUE rbser = rb_ary_entry(self_t->series, i);
- //VALUE rbstr = rb_ary_entry(self_t->names, i);
+VALUE shoes_plot_find_name(VALUE self, VALUE name) {
+ shoes_plot *self_t;
+ Data_Get_Struct(self, shoes_plot, self_t);
+ if (TYPE(name) != T_STRING) rb_raise(rb_eArgError, "plot.find arg is not a string");
+ char *search = RSTRING_PTR(name);
+ int i;
+ for (i = 0; i seriescnt; i++) {
+ VALUE rbser = rb_ary_entry(self_t->series, i);
+ //VALUE rbstr = rb_ary_entry(self_t->names, i);
+ shoes_chart_series *cs;
+ Data_Get_Struct(rbser, shoes_chart_series, cs);
+ VALUE rbstr = cs->name;
+ char *entry = RSTRING_PTR(rbstr);
+ if (strcmp(search, entry) == 0) {
+ return INT2NUM(i);
+ }
+ }
+ return Qnil; // when nothing matches
+}
+
+VALUE shoes_plot_zoom(VALUE self, VALUE beg, VALUE end) {
+ shoes_plot *self_t;
+ Data_Get_Struct(self, shoes_plot, self_t);
+ // restrict to timeseries chart
+ if (self_t->chart_type != TIMESERIES_CHART)
+ return Qnil;
+ if (self_t->seriescnt < 1)
+ return Qnil;
+ //int maxe = RARRAY_LEN(rb_ary_entry(self_t->values, 0));
+ VALUE rbser = rb_ary_entry(self_t->series, 0);
shoes_chart_series *cs;
Data_Get_Struct(rbser, shoes_chart_series, cs);
- VALUE rbstr = cs->name;
- char *entry = RSTRING_PTR(rbstr);
- if (strcmp(search, entry) == 0) {
- return INT2NUM(i);
+ int maxe = RARRAY_LEN(cs->values);
+ int b = NUM2INT(beg);
+ int e = NUM2INT(end);
+ int nb = max(0, b);
+ int ne = min(maxe, e);
+ if ((e - b) < 3) {
+ //printf("no smaller that 3 points\n");
+ return Qfalse;
}
- }
- return Qnil; // when nothing matches
+ //printf("zoom to %i -- %i\n", nb, ne);
+ self_t->beg_idx = nb;
+ self_t->end_idx = ne;
+ shoes_canvas_repaint_all(self_t->parent);
+ return Qtrue;
}
-VALUE shoes_plot_zoom(VALUE self, VALUE beg, VALUE end)
-{
- shoes_plot *self_t;
- Data_Get_Struct(self, shoes_plot, self_t);
- // restrict to timeseries chart
- if (self_t->chart_type != TIMESERIES_CHART)
- return Qnil;
- if (self_t->seriescnt < 1)
- return Qnil;
- //int maxe = RARRAY_LEN(rb_ary_entry(self_t->values, 0));
- VALUE rbser = rb_ary_entry(self_t->series, 0);
- shoes_chart_series *cs;
- Data_Get_Struct(rbser, shoes_chart_series, cs);
- int maxe = RARRAY_LEN(cs->values);
- int b = NUM2INT(beg);
- int e = NUM2INT(end);
- int nb = max(0, b);
- int ne = min(maxe, e);
- if ((e - b) < 3) {
- //printf("no smaller that 3 points\n");
- return Qfalse;
- }
- //printf("zoom to %i -- %i\n", nb, ne);
- self_t->beg_idx = nb;
- self_t->end_idx = ne;
- shoes_canvas_repaint_all(self_t->parent);
- return Qtrue;
-}
-
-VALUE shoes_plot_get_count(VALUE self)
-{
- shoes_plot *self_t;
- Data_Get_Struct(self, shoes_plot, self_t);
- return INT2NUM(self_t->seriescnt);
-}
-
-VALUE shoes_plot_get_first(VALUE self)
-{
- shoes_plot *self_t;
- Data_Get_Struct(self, shoes_plot, self_t);
- return INT2NUM(self_t->beg_idx);
-}
-
-VALUE shoes_plot_set_first(VALUE self, VALUE idx)
-{
- shoes_plot *self_t;
- Data_Get_Struct(self, shoes_plot, self_t);
- if (self_t->chart_type != TIMESERIES_CHART)
- return Qnil;
- if (TYPE(idx) != T_FIXNUM) rb_raise(rb_eArgError, "plot.set_first arg is not an integer");
- self_t->beg_idx = NUM2INT(idx);
- shoes_canvas_repaint_all(self_t->parent);
- return idx;
-}
-
-VALUE shoes_plot_get_last(VALUE self)
-{
- shoes_plot *self_t;
- Data_Get_Struct(self, shoes_plot, self_t);
- return INT2NUM(self_t->end_idx);
-}
-VALUE shoes_plot_set_last(VALUE self, VALUE idx)
-{
- shoes_plot *self_t;
- Data_Get_Struct(self, shoes_plot, self_t);
- if (self_t->chart_type != TIMESERIES_CHART)
- return Qnil;
- if (TYPE(idx) != T_FIXNUM) rb_raise(rb_eArgError, "plot.set_last arg is not an integer");
- self_t->end_idx = NUM2INT(idx);
- shoes_canvas_repaint_all(self_t->parent);
- return idx;
+VALUE shoes_plot_get_count(VALUE self) {
+ shoes_plot *self_t;
+ Data_Get_Struct(self, shoes_plot, self_t);
+ return INT2NUM(self_t->seriescnt);
+}
+
+VALUE shoes_plot_get_first(VALUE self) {
+ shoes_plot *self_t;
+ Data_Get_Struct(self, shoes_plot, self_t);
+ return INT2NUM(self_t->beg_idx);
+}
+
+VALUE shoes_plot_set_first(VALUE self, VALUE idx) {
+ shoes_plot *self_t;
+ Data_Get_Struct(self, shoes_plot, self_t);
+ if (self_t->chart_type != TIMESERIES_CHART)
+ return Qnil;
+ if (TYPE(idx) != T_FIXNUM) rb_raise(rb_eArgError, "plot.set_first arg is not an integer");
+ self_t->beg_idx = NUM2INT(idx);
+ shoes_canvas_repaint_all(self_t->parent);
+ return idx;
+}
+
+VALUE shoes_plot_get_last(VALUE self) {
+ shoes_plot *self_t;
+ Data_Get_Struct(self, shoes_plot, self_t);
+ return INT2NUM(self_t->end_idx);
+}
+VALUE shoes_plot_set_last(VALUE self, VALUE idx) {
+ shoes_plot *self_t;
+ Data_Get_Struct(self, shoes_plot, self_t);
+ if (self_t->chart_type != TIMESERIES_CHART)
+ return Qnil;
+ if (TYPE(idx) != T_FIXNUM) rb_raise(rb_eArgError, "plot.set_last arg is not an integer");
+ self_t->end_idx = NUM2INT(idx);
+ shoes_canvas_repaint_all(self_t->parent);
+ return idx;
}
// ------ widget methods for style and save/export ------
-VALUE shoes_plot_get_actual_width(VALUE self)
-{
- shoes_plot *self_t;
- Data_Get_Struct(self, shoes_plot, self_t);
- return INT2NUM(self_t->place.w);
+VALUE shoes_plot_get_actual_width(VALUE self) {
+ shoes_plot *self_t;
+ Data_Get_Struct(self, shoes_plot, self_t);
+ return INT2NUM(self_t->place.w);
}
-VALUE shoes_plot_get_actual_height(VALUE self)
-{
- shoes_plot *self_t;
- Data_Get_Struct(self, shoes_plot, self_t);
- return INT2NUM(self_t->place.h);
+VALUE shoes_plot_get_actual_height(VALUE self) {
+ shoes_plot *self_t;
+ Data_Get_Struct(self, shoes_plot, self_t);
+ return INT2NUM(self_t->place.h);
}
-VALUE
-shoes_plot_get_actual_left(VALUE self)
-{
- shoes_plot *self_t;
- Data_Get_Struct(self, shoes_plot, self_t);
- return INT2NUM(self_t->place.ix + self_t->place.dx);
+VALUE shoes_plot_get_actual_left(VALUE self) {
+ shoes_plot *self_t;
+ Data_Get_Struct(self, shoes_plot, self_t);
+ return INT2NUM(self_t->place.ix + self_t->place.dx);
}
-VALUE
-shoes_plot_get_actual_top(VALUE self)
-{
- shoes_plot *self_t;
- Data_Get_Struct(self, shoes_plot, self_t);
- return INT2NUM(self_t->place.iy + self_t->place.dy);
+VALUE shoes_plot_get_actual_top(VALUE self) {
+ shoes_plot *self_t;
+ Data_Get_Struct(self, shoes_plot, self_t);
+ return INT2NUM(self_t->place.iy + self_t->place.dy);
}
// --- fun with vector and png ---
//typedef cairo_public cairo_surface_t * (cairo_surface_function_t) (const char *filename, double width, double height);
-cairo_surface_function_t *get_vector_surface(char *format)
-{
- if (strcmp(format, "pdf") == 0) return & cairo_pdf_surface_create;
- if (strcmp(format, "ps") == 0) return & cairo_ps_surface_create;
- if (strcmp(format, "svg") == 0) return & cairo_svg_surface_create;
- return NULL;
-}
-
-cairo_surface_t*
-build_surface(VALUE self, double scale, int *result, char *filename, char *format)
-{
- shoes_plot *self_t;
- Data_Get_Struct(self, shoes_plot, self_t);
- shoes_canvas *canvas;
- Data_Get_Struct(self_t->parent, shoes_canvas, canvas);
- shoes_place place = self_t->place;
- cairo_surface_t *surf;
- cairo_t *cr;
-
- int w = (int)(NUM2INT(shoes_plot_get_actual_width(self))*scale);
- int h = (int)(NUM2INT(shoes_plot_get_actual_height(self))*scale);
- if (format != NULL)
- surf = get_vector_surface(format)(filename, w, h);
- else
- surf = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, w, h);
- cr = cairo_create(surf);
-
- if (scale != 1.0) cairo_scale(cr, scale, scale);
- cairo_translate(cr, -(place.ix + place.dx), -(place.iy + place.dy));
-
- shoes_plot_draw_everything(cr, &self_t->place, self_t);
- if (format != NULL) cairo_show_page(cr);
- cairo_destroy(cr);
-
- return surf;
-}
-int shoes_plot_save_png(VALUE self, char *filename)
-{
- int result;
- cairo_surface_t *surf = build_surface(self, 1.0, &result, NULL, NULL);
- cairo_status_t r = cairo_surface_write_to_png(surf, filename);
- cairo_surface_destroy(surf);
-
- return r == CAIRO_STATUS_SUCCESS ? Qtrue : Qfalse;
-}
-
-int shoes_plot_save_vector(VALUE self, char *filename, char *format)
-{
- int result;
- cairo_surface_t *surf = build_surface(self, 1.0, &result, filename, format);
- cairo_surface_destroy(surf);
-
- return 1;
-}
-
-VALUE shoes_plot_save_as(int argc, VALUE *argv, VALUE self)
-{
- if (argc == 0) {
- shoes_plot_save_png(self, NULL);
- printf("save to clipboard\n");
- } else if (TYPE(argv[0]) == T_STRING) {
- char *rbstr = RSTRING_PTR(argv[0]);
- char *lastslash = strrchr(rbstr,'/');
- char *basename = NULL;
- char *lastdot;
- char *ext = NULL;
- if (lastslash) {
- lastslash++;
- basename = malloc(strlen(lastslash)+1);
- strcpy(basename, lastslash);
- lastdot = strrchr(basename, '.');
- if (lastdot == 0) {
- rb_raise(rb_eArgError,"save_as does not have an extension");
- }
- // replace dot with null (EOS)
- *lastdot = '\0';
- ext = lastdot + 1;
- }
- //printf("save to: %s %s (long: %s)\n", basename, ext, rbstr);
- int result = 0;
- if (strcmp(ext, "png") == 0) {
- result = shoes_plot_save_png(self, rbstr);
- } else {
- result = shoes_plot_save_vector(self, rbstr, ext);
+cairo_surface_function_t *get_vector_surface(char *format) {
+ if (strcmp(format, "pdf") == 0) return & cairo_pdf_surface_create;
+ if (strcmp(format, "ps") == 0) return & cairo_ps_surface_create;
+ if (strcmp(format, "svg") == 0) return & cairo_svg_surface_create;
+ return NULL;
+}
+
+cairo_surface_t *build_surface(VALUE self, double scale, int *result, char *filename, char *format) {
+ shoes_plot *self_t;
+ Data_Get_Struct(self, shoes_plot, self_t);
+ shoes_canvas *canvas;
+ Data_Get_Struct(self_t->parent, shoes_canvas, canvas);
+ shoes_place place = self_t->place;
+ cairo_surface_t *surf;
+ cairo_t *cr;
+
+ int w = (int)(NUM2INT(shoes_plot_get_actual_width(self))*scale);
+ int h = (int)(NUM2INT(shoes_plot_get_actual_height(self))*scale);
+ if (format != NULL)
+ surf = get_vector_surface(format)(filename, w, h);
+ else
+ surf = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, w, h);
+ cr = cairo_create(surf);
+
+ if (scale != 1.0) cairo_scale(cr, scale, scale);
+ cairo_translate(cr, -(place.ix + place.dx), -(place.iy + place.dy));
+
+ shoes_plot_draw_everything(cr, &self_t->place, self_t);
+ if (format != NULL) cairo_show_page(cr);
+ cairo_destroy(cr);
+
+ return surf;
+}
+int shoes_plot_save_png(VALUE self, char *filename) {
+ int result;
+ cairo_surface_t *surf = build_surface(self, 1.0, &result, NULL, NULL);
+ cairo_status_t r = cairo_surface_write_to_png(surf, filename);
+ cairo_surface_destroy(surf);
+
+ return r == CAIRO_STATUS_SUCCESS ? Qtrue : Qfalse;
+}
+
+int shoes_plot_save_vector(VALUE self, char *filename, char *format) {
+ int result;
+ cairo_surface_t *surf = build_surface(self, 1.0, &result, filename, format);
+ cairo_surface_destroy(surf);
+
+ return 1;
+}
+
+VALUE shoes_plot_save_as(int argc, VALUE *argv, VALUE self) {
+ if (argc == 0) {
+ shoes_plot_save_png(self, NULL);
+ printf("save to clipboard\n");
+ } else if (TYPE(argv[0]) == T_STRING) {
+ char *rbstr = RSTRING_PTR(argv[0]);
+ char *lastslash = strrchr(rbstr,'/');
+ char *basename = NULL;
+ char *lastdot;
+ char *ext = NULL;
+ if (lastslash) {
+ lastslash++;
+ basename = malloc(strlen(lastslash)+1);
+ strcpy(basename, lastslash);
+ lastdot = strrchr(basename, '.');
+ if (lastdot == 0) {
+ rb_raise(rb_eArgError,"save_as does not have an extension");
+ }
+ // replace dot with null (EOS)
+ *lastdot = '\0';
+ ext = lastdot + 1;
+ }
+ //printf("save to: %s %s (long: %s)\n", basename, ext, rbstr);
+ int result = 0;
+ if (strcmp(ext, "png") == 0) {
+ result = shoes_plot_save_png(self, rbstr);
+ } else {
+ result = shoes_plot_save_vector(self, rbstr, ext);
+ }
+ if (basename) free(basename);
+ return (result ? Qtrue : Qnil);
}
- if (basename) free(basename);
- return (result ? Qtrue : Qnil);
- }
- return Qnil;
+ return Qnil;
}
/* Not using PLACE_COMMMON Macro in ruby.c, as we do the plot rendering a bit differently
* than other widgets [parent, left, top, width, height ruby methods]
*/
-VALUE
-shoes_plot_get_parent(VALUE self)
-{
- GET_STRUCT(plot, self_t);
- return self_t->parent;
-}
-
-VALUE shoes_plot_remove(VALUE self)
-{
- shoes_plot *self_t;
- shoes_canvas *canvas;
- Data_Get_Struct(self, shoes_plot, self_t);
- Data_Get_Struct(self_t->parent, shoes_canvas, canvas);
-
- rb_ary_delete(canvas->contents, self); // shoes_basic_remove does it this way
- // free some pango/cairo stuff
- pango_font_description_free (self_t->title_pfd);
- pango_font_description_free (self_t->caption_pfd);
- pango_font_description_free (self_t->legend_pfd);
- pango_font_description_free (self_t->label_pfd);
- shoes_canvas_repaint_all(self_t->parent);
-
- self_t = NULL;
- self = Qnil;
- return Qtrue;
+VALUE shoes_plot_get_parent(VALUE self) {
+ GET_STRUCT(plot, self_t);
+ return self_t->parent;
+}
+
+VALUE shoes_plot_remove(VALUE self) {
+ shoes_plot *self_t;
+ shoes_canvas *canvas;
+ Data_Get_Struct(self, shoes_plot, self_t);
+ Data_Get_Struct(self_t->parent, shoes_canvas, canvas);
+
+ rb_ary_delete(canvas->contents, self); // shoes_basic_remove does it this way
+ // free some pango/cairo stuff
+ pango_font_description_free (self_t->title_pfd);
+ pango_font_description_free (self_t->caption_pfd);
+ pango_font_description_free (self_t->legend_pfd);
+ pango_font_description_free (self_t->label_pfd);
+ shoes_canvas_repaint_all(self_t->parent);
+
+ self_t = NULL;
+ self = Qnil;
+ return Qtrue;
}
// ---- click handling ------
-/*
- * this attempts to compute the values/xobs index nearest the x pixel
+/*
+ * this attempts to compute the values/xobs index nearest the x pixel
* from a mouse click. First get a % of x between width
* use that to pick between beg_idx, end_idx and return that.
- *
+ *
*/
-VALUE shoes_plot_near(VALUE self, VALUE xpos)
-{
- shoes_plot *self_t;
- Data_Get_Struct(self, shoes_plot, self_t);
- int x = NUM2INT(xpos);
- int left,right;
- left = self_t->graph_x;
- right = self_t->graph_w;
- int newx = x - (self_t->place.ix + self_t->place.dx + left);
- int wid = right - left;
- double rpos = newx / wid;
- int rng = (self_t->end_idx - self_t->beg_idx);
- int idx = floorl(rpos * rng);
- printf("shoes_plot_near: %i newx: %i rpos: %f here: %i\n", x,newx,rpos,idx);
- return INT2NUM(idx);
+VALUE shoes_plot_near(VALUE self, VALUE xpos) {
+ shoes_plot *self_t;
+ Data_Get_Struct(self, shoes_plot, self_t);
+ int x = NUM2INT(xpos);
+ int left,right;
+ left = self_t->graph_x;
+ right = self_t->graph_w;
+ int newx = x - (self_t->place.ix + self_t->place.dx + left);
+ int wid = right - left;
+ double rpos = newx / wid;
+ int rng = (self_t->end_idx - self_t->beg_idx);
+ int idx = floorl(rpos * rng);
+ printf("shoes_plot_near: %i newx: %i rpos: %f here: %i\n", x,newx,rpos,idx);
+ return INT2NUM(idx);
}
// define our own inside function so we can offset our own margins
// this controls what cursor is shown - mostly
-int shoes_plot_inside(shoes_plot *self_t, int x, int y)
-{
- int inside = 0;
- inside = (self_t->place.iw > 0 && self_t->place.ih > 0 &&
- //x >= self_t->place.ix + self_t->place.dx &&
- x >= self_t->place.ix + self_t->place.dx + self_t->graph_x &&
- // x <= self_t->place.ix + self_t->place.dx + self_t->place.iw &&
- x <= self_t->place.ix + self_t->place.dx + self_t->place.iw -self_t->graph_x &&
- //y >= self_t->place.iy + self_t->place.dy &&
- y >= self_t->place.iy + self_t->place.dy + self_t->graph_y &&
- //y <= self_t->place.iy + self_t->place.dy + self_t->place.ih);
- y <= self_t->place.iy + self_t->place.dy + self_t->place.ih -
- (self_t->caption_h + self_t->legend_h + 25)); //TODO no hardcoding of offsets
- return inside;
+int shoes_plot_inside(shoes_plot *self_t, int x, int y) {
+ int inside = 0;
+ inside = (self_t->place.iw > 0 && self_t->place.ih > 0 &&
+ //x >= self_t->place.ix + self_t->place.dx &&
+ x >= self_t->place.ix + self_t->place.dx + self_t->graph_x &&
+ // x <= self_t->place.ix + self_t->place.dx + self_t->place.iw &&
+ x <= self_t->place.ix + self_t->place.dx + self_t->place.iw -self_t->graph_x &&
+ //y >= self_t->place.iy + self_t->place.dy &&
+ y >= self_t->place.iy + self_t->place.dy + self_t->graph_y &&
+ //y <= self_t->place.iy + self_t->place.dy + self_t->place.ih);
+ y <= self_t->place.iy + self_t->place.dy + self_t->place.ih -
+ (self_t->caption_h + self_t->legend_h + 25)); //TODO no hardcoding of offsets
+ return inside;
}
//called by shoes_plot_send_click and shoes_canvas_send_motion
-VALUE
-shoes_plot_motion(VALUE self, int x, int y, char *touch)
-{
- char h = 0;
- VALUE click;
- GET_STRUCT(plot, self_t);
- if (self_t->chart_type != TIMESERIES_CHART)
- return Qnil;
- click = ATTR(self_t->attr, click);
-
- //if (IS_INSIDE(self_t, x, y)) {
- if (shoes_plot_inside(self_t, x, y)) {
- if (!NIL_P(click)) {
- shoes_canvas *canvas;
- Data_Get_Struct(self_t->parent, shoes_canvas, canvas);
- shoes_app_cursor(canvas->app, s_link);
+VALUE shoes_plot_motion(VALUE self, int x, int y, char *touch) {
+ char h = 0;
+ VALUE click;
+ GET_STRUCT(plot, self_t);
+ if (self_t->chart_type != TIMESERIES_CHART)
+ return Qnil;
+ click = ATTR(self_t->attr, click);
+
+ //if (IS_INSIDE(self_t, x, y)) {
+ if (shoes_plot_inside(self_t, x, y)) {
+ if (!NIL_P(click)) {
+ shoes_canvas *canvas;
+ Data_Get_Struct(self_t->parent, shoes_canvas, canvas);
+ shoes_app_cursor(canvas->app, s_link);
+ }
+ h = 1;
}
- h = 1;
- }
-
- /* Checks if element is hovered, clicked, released, leaved
- * and eventually calls hover and/or leave callbacks
- * if hovered: self_t->hover == 1
- * if leaved: self_t->hover == 0
- * if clicked and not yet released:
- * if hovered + clicked: self_t->hover == 3
- * if leaved + clicked: self_t->hover == 2
- */
- CHECK_HOVER(self_t, h, touch);
-
- return h ? click : Qnil;
+
+ /* Checks if element is hovered, clicked, released, leaved
+ * and eventually calls hover and/or leave callbacks
+ * if hovered: self_t->hover == 1
+ * if leaved: self_t->hover == 0
+ * if clicked and not yet released:
+ * if hovered + clicked: self_t->hover == 3
+ * if leaved + clicked: self_t->hover == 2
+ */
+ CHECK_HOVER(self_t, h, touch);
+
+ return h ? click : Qnil;
}
// called by shoes_canvas_send_click --> shoes_canvas_send_click2
-VALUE
-shoes_plot_send_click(VALUE self, int button, int x, int y)
-{
- VALUE v = Qnil;
+VALUE shoes_plot_send_click(VALUE self, int button, int x, int y) {
+ VALUE v = Qnil;
+
+ if (button > 0) {
+ GET_STRUCT(plot, self_t);
+ v = shoes_plot_motion(self, x, y, NULL);
+ if (self_t->hover & HOVER_MOTION) // ok, cursor is over the element, proceed
+ self_t->hover = HOVER_MOTION | HOVER_CLICK; // we have been clicked, but not yet released
+ }
- if (button > 0) {
- GET_STRUCT(plot, self_t);
- v = shoes_plot_motion(self, x, y, NULL);
- if (self_t->hover & HOVER_MOTION) // ok, cursor is over the element, proceed
- self_t->hover = HOVER_MOTION | HOVER_CLICK; // we have been clicked, but not yet released
- }
-
- // if we found a click callback send it back to shoes_canvas_send_click method
- // where it will be processed
- return v;
+ // if we found a click callback send it back to shoes_canvas_send_click method
+ // where it will be processed
+ return v;
}
// called by shoes_canvas_send_release
-void
-shoes_plot_send_release(VALUE self, int button, int x, int y)
-{
- GET_STRUCT(plot, self_t);
- if (button > 0 && (self_t->hover & HOVER_CLICK)) {
- VALUE proc = ATTR(self_t->attr, release);
- self_t->hover ^= HOVER_CLICK; // we have been clicked and released
- if (!NIL_P(proc))
- //shoes_safe_block(self, proc, rb_ary_new3(1, self));
- shoes_safe_block(self, proc, rb_ary_new3(3, INT2NUM(button), INT2NUM(x), INT2NUM(y)));
- }
+void shoes_plot_send_release(VALUE self, int button, int x, int y) {
+ GET_STRUCT(plot, self_t);
+ if (button > 0 && (self_t->hover & HOVER_CLICK)) {
+ VALUE proc = ATTR(self_t->attr, release);
+ self_t->hover ^= HOVER_CLICK; // we have been clicked and released
+ if (!NIL_P(proc))
+ //shoes_safe_block(self, proc, rb_ary_new3(1, self));
+ shoes_safe_block(self, proc, rb_ary_new3(3, INT2NUM(button), INT2NUM(x), INT2NUM(y)));
+ }
}
diff --git a/shoes/plot/plot.h b/shoes/plot/plot.h
index 4a5ff1a5..2a79cd40 100644
--- a/shoes/plot/plot.h
+++ b/shoes/plot/plot.h
@@ -1,4 +1,4 @@
-/*
+/*
* plot.h
*/
#ifndef PLOT_H
@@ -8,119 +8,120 @@
#include "shoes/ruby.h"
#include "shoes/internal.h"
#include "shoes/world.h"
-#include "shoes/native.h"
+#include "shoes/native/native.h"
+#include "shoes/types/effect.h"
+#include "shoes/types/color.h"
#include "shoes/version.h"
#include "shoes/http.h"
-#include "shoes/effects.h"
#include
-/*
+/*
* NOTE: functions that changes the cairo state (aka ontext, cairo_t) for
* color or line width and the like should call shoes_plot_set_cairo_default()
* in plot_util.c to restore the default Shoes plot drawing state.
- *
+ *
* Only plot_*.c includes plot.h so the enums don't bleed into Shoes.
*/
enum {
- VERTICALLY,
- HORIZONTALLY
+ VERTICALLY,
+ HORIZONTALLY
};
enum {
- LEFT,
- BELOW,
- RIGHT
+ LEFT,
+ BELOW,
+ RIGHT
};
// missing value or observation handling
enum {
- MISSING_SKIP,
- MISSING_MIN,
- MISSING_MAX
+ MISSING_SKIP,
+ MISSING_MIN,
+ MISSING_MAX
};
// chart type - line is default
enum {
- LINE_CHART,
- TIMESERIES_CHART,
- COLUMN_CHART,
- SCATTER_CHART,
- PIE_CHART,
- RADAR_CHART
+ LINE_CHART,
+ TIMESERIES_CHART,
+ COLUMN_CHART,
+ SCATTER_CHART,
+ PIE_CHART,
+ RADAR_CHART
};
enum {
- NUB_NONE,
- NUB_DOT, //filled circle
- NUB_CIRCLE, //unfilled circle
- NUB_BOX, //filled rect
- NUB_RECT, //unfilled rect
+ NUB_NONE,
+ NUB_DOT, //filled circle
+ NUB_CIRCLE, //unfilled circle
+ NUB_BOX, //filled rect
+ NUB_RECT, //unfilled rect
};
// positional values for Radar Chart column_settings
enum {
- RADAR_LABEL,
- RADAR_MIN,
- RADAR_MAX,
- RADAR_EXTRA,
+ RADAR_LABEL,
+ RADAR_MIN,
+ RADAR_MAX,
+ RADAR_EXTRA,
};
// quadrant (pie, radar)
enum {
- QUAD_ONE,
- QUAD_TWO,
- QUAD_THREE,
- QUAD_FOUR,
- QUAD_ERR
+ QUAD_ONE,
+ QUAD_TWO,
+ QUAD_THREE,
+ QUAD_FOUR,
+ QUAD_ERR
};
-// Pie charts are sufficently complex that we need some structs for the
+// Pie charts are sufficently complex that we need some structs for the
// internal stuff. Probably should be done for the other types to
typedef struct {
- double value;
- double startAngle;
- double endAngle;
- shoes_color *color;
- char *label;
- int lh; // label height and width and placement
- int lw;
- int lx, ly;
- PangoLayout *layout;
+ double value;
+ double startAngle;
+ double endAngle;
+ shoes_color *color;
+ char *label;
+ int lh; // label height and width and placement
+ int lw;
+ int lx, ly;
+ PangoLayout *layout;
} pie_slice_t;
typedef struct {
- int percent; // true when display % instead of value
- double radius;
- int centerx;
- int centery;
- int count;
- int top, left, bottom, right, height, width;
- double maxv;
- double minv;
- pie_slice_t *slices; // treated as an array because it is.
+ int percent; // true when display % instead of value
+ double radius;
+ int centerx;
+ int centery;
+ int count;
+ int top, left, bottom, right, height, width;
+ double maxv;
+ double minv;
+ pie_slice_t *slices; // treated as an array because it is.
} pie_chart_t;
typedef struct {
- int percent; // true when display % instead of value
- double radius;
- double rotation;
- double angle;
- int centerx;
- int centery;
- int count;
- int top, left, bottom, right, height, width;
- double maxv;
- double minv;
- double *colmax; //array of
- double *colmin; //array of
- char **labels; //array of string ptrs;
- char **fmt_strs; //array of string ptrs;
- double *lh; // array
- double *lw; // array
- double *lx; // array
- double *ly; // array
- PangoLayout **layouts; // array
+ int percent; // true when display % instead of value
+ double radius;
+ double rotation;
+ double angle;
+ int centerx;
+ int centery;
+ int count;
+ int top, left, bottom, right, height, width;
+ double maxv;
+ double minv;
+ double *colmax; //array of
+ double *colmin; //array of
+ char **labels; //array of string ptrs;
+ char **fmt_strs; //array of string ptrs;
+ double *lh; // array
+ double *lw; // array
+ double *lx; // array
+ double *ly; // array
+ PangoLayout **layouts; // array
} radar_chart_t;
typedef cairo_public cairo_surface_t * (cairo_surface_function_t) (const char *filename, double width, double height);
@@ -135,7 +136,7 @@ extern void shoes_plot_radar_init(shoes_plot *);
extern void shoes_plot_radar_dealloc(shoes_plot *);
extern void shoes_plot_radar_draw(cairo_t *, shoes_place *, shoes_plot *);
extern void shoes_chart_series_Cinit(shoes_chart_series *, VALUE, VALUE,
- VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE);
+ VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE);
extern VALUE shoes_plot_parse_column_settings(VALUE);
// plot utility functions (in plot_util.c)
extern void shoes_plot_set_cairo_default(cairo_t *, shoes_plot *);
@@ -147,10 +148,12 @@ extern void shoes_plot_draw_boundbox(cairo_t *, shoes_plot *);
extern void shoes_plot_draw_ticks_and_labels(cairo_t *, shoes_plot *);
extern void shoes_plot_draw_legend(cairo_t *, shoes_plot *);
extern void shoes_plot_draw_tick(cairo_t *, shoes_plot *, int, int, int);
-extern void shoes_plot_draw_label(cairo_t *, shoes_plot *, int, int , char*, int);
+extern void shoes_plot_draw_label(cairo_t *, shoes_plot *, int, int, char*, int);
extern void shoes_plot_draw_nub(cairo_t *, shoes_plot *, double, double, int, int);
extern int shoes_plot_util_quadrant(double angle);
+extern void shoes_plot_util_adornments(cairo_t *, shoes_place *, shoes_plot *, int);
-
+// TODO: refactor into shoes/types?
+extern VALUE cPlot, cChartSeries;
#endif
diff --git a/shoes/plot/plot_column.c b/shoes/plot/plot_column.c
index cc791ada..f2cdd86a 100644
--- a/shoes/plot/plot_column.c
+++ b/shoes/plot/plot_column.c
@@ -7,129 +7,115 @@
#include "shoes/plot/plot.h"
-void shoes_plot_draw_column_top(cairo_t *cr, int x, int y)
-{
+void shoes_plot_draw_column_top(cairo_t *cr, int x, int y) {
}
-void shoes_plot_column_xaxis(cairo_t *cr, shoes_plot *plot, int x, VALUE obs)
-{
- char *rawstr = RSTRING_PTR(obs);
- int y;
- y = plot->graph_h;
- shoes_plot_draw_label(cr, plot, x, y, rawstr, BELOW);
- // we don't need to call shoes_plot_set_cairo_default on return
- // since we know it won't be changed on us.
+void shoes_plot_column_xaxis(cairo_t *cr, shoes_plot *plot, int x, VALUE obs) {
+ char *rawstr = RSTRING_PTR(obs);
+ int y;
+ y = plot->graph_h;
+ shoes_plot_draw_label(cr, plot, x, y, rawstr, BELOW);
+ // we don't need to call shoes_plot_set_cairo_default on return
+ // since we know it won't be changed on us.
}
-void shoes_plot_draw_columns(cairo_t *cr, shoes_plot *plot)
-{
- int i, num_series;
- int top,left,bottom,right;
- left = plot->graph_x; top = plot->graph_y;
- right = plot->graph_w; bottom = plot->graph_h;
- int width = right - left;
- int height = bottom - top;
- // need to compute x advance based on number of series and stroke width
- int colsw = 0; // combined stroke width for one set of bars
- num_series = plot->seriescnt;
- int strokesw[num_series];
- double maximums[num_series];
- double minimums[num_series];
- double vScales[num_series];
- shoes_color *colors[num_series];
- int nubs[num_series];
- VALUE values[num_series];
- VALUE labels[num_series];
- int range = plot->end_idx - plot->beg_idx; // zooming adj
- // load local var arrays
- for (i = 0; i < plot->seriescnt; i++) {
- VALUE rbser = rb_ary_entry(plot->series, i);
- shoes_chart_series *cs;
- Data_Get_Struct(rbser, shoes_chart_series, cs);
- values[i] = cs->values;
- labels[i] = cs->labels;
- maximums[i] = NUM2DBL(cs->maxv);
- minimums[i] = NUM2DBL(cs->minv);
- nubs[i] = (width / range > 10) ? RTEST(cs->point_type) : 0;
- Data_Get_Struct(cs->color, shoes_color, colors[i]);
- int sw = NUM2INT(cs->strokes);
- if (sw < 4) sw = 4;
- strokesw[i] = sw;
- colsw += sw;
- vScales[i] = (height / (maximums[i] - minimums[i]));
- //values[i] = rb_ary_entry(plot->values, i);
- //VALUE rbmaxv = rb_ary_entry(plot->maxvs, i);
- //VALUE rbminv = rb_ary_entry(plot->minvs, i);
- //maximums[i] = NUM2DBL(rbmaxv);
- //minimums[i] = NUM2DBL(rbminv);
- //VALUE rbnubs = rb_ary_entry(plot->nubs, i);
- //nubs[i] = (width / range > 10) ? RTEST(rbnubs) : 0;
- //VALUE rbcolor = rb_ary_entry(plot->color, i);
- //VALUE rbstroke = rb_ary_entry(plot->strokes, i);
- //int sw = NUM2INT(rbstroke);
- //if (sw < 4) sw = 4;
- //strokesw[i] = sw;
- //colsw += sw;
- //vScales[i] = (height / (maximums[i] - minimums[i]));
- //Data_Get_Struct(rbcolor, shoes_color, colors[i]);
- }
- int ncolsw = width / (range) ; //
- int xinset = left + (ncolsw / 2); // start inside the box, half a width
- int xpos = xinset;
- //printf("ncolsw: w: %i, advw: %i, start inset %i\n", width, ncolsw, xpos);
- for (i = plot->beg_idx; i < plot->end_idx; i++) {
- int j;
- for (j = 0; j < plot->seriescnt; j++) {
- VALUE rbdp = rb_ary_entry(values[j], i + plot->beg_idx);
- if (NIL_P(rbdp)) {
- printf("skipping nil at %i\n", i + plot->beg_idx);
- continue;
- }
- double v = NUM2DBL(rbdp);
- cairo_set_line_width(cr, strokesw[j]);
- cairo_set_source_rgba(cr, colors[j]->r / 255.0, colors[j]->g / 255.0,
- colors[j]->b / 255.0, colors[j]->a / 255.0);
-
- long y = height - roundl((v - minimums[j]) * vScales[j]);
- //printf("move i: %i, j: %i, x: %i, v: %f -> y: %i,%i \n", i, j, xpos, v, y, y+top);
- y += top;
- cairo_move_to(cr, xpos, bottom);
- cairo_line_to(cr, xpos, y);
- cairo_stroke(cr);
- xpos += strokesw[j];
+void shoes_plot_draw_columns(cairo_t *cr, shoes_plot *plot) {
+ int i, num_series;
+ int top,left,bottom,right;
+ left = plot->graph_x;
+ top = plot->graph_y;
+ right = plot->graph_w;
+ bottom = plot->graph_h;
+ int width = right - left;
+ int height = bottom - top;
+ // need to compute x advance based on number of series and stroke width
+ int colsw = 0; // combined stroke width for one set of bars
+ num_series = plot->seriescnt;
+ int strokesw[num_series];
+ double maximums[num_series];
+ double minimums[num_series];
+ double vScales[num_series];
+ shoes_color *colors[num_series];
+ int nubs[num_series];
+ VALUE values[num_series];
+ VALUE labels[num_series];
+ int range = plot->end_idx - plot->beg_idx; // zooming adj
+ // load local var arrays
+ for (i = 0; i < plot->seriescnt; i++) {
+ VALUE rbser = rb_ary_entry(plot->series, i);
+ shoes_chart_series *cs;
+ Data_Get_Struct(rbser, shoes_chart_series, cs);
+ values[i] = cs->values;
+ labels[i] = cs->labels;
+ maximums[i] = NUM2DBL(cs->maxv);
+ minimums[i] = NUM2DBL(cs->minv);
+ nubs[i] = (width / range > 10) ? RTEST(cs->point_type) : 0;
+ Data_Get_Struct(cs->color, shoes_color, colors[i]);
+ int sw = NUM2INT(cs->strokes);
+ if (sw < 4) sw = 4;
+ strokesw[i] = sw;
+ colsw += sw;
+ vScales[i] = (height / (maximums[i] - minimums[i]));
+ //values[i] = rb_ary_entry(plot->values, i);
+ //VALUE rbmaxv = rb_ary_entry(plot->maxvs, i);
+ //VALUE rbminv = rb_ary_entry(plot->minvs, i);
+ //maximums[i] = NUM2DBL(rbmaxv);
+ //minimums[i] = NUM2DBL(rbminv);
+ //VALUE rbnubs = rb_ary_entry(plot->nubs, i);
+ //nubs[i] = (width / range > 10) ? RTEST(rbnubs) : 0;
+ //VALUE rbcolor = rb_ary_entry(plot->color, i);
+ //VALUE rbstroke = rb_ary_entry(plot->strokes, i);
+ //int sw = NUM2INT(rbstroke);
+ //if (sw < 4) sw = 4;
+ //strokesw[i] = sw;
+ //colsw += sw;
+ //vScales[i] = (height / (maximums[i] - minimums[i]));
+ //Data_Get_Struct(rbcolor, shoes_color, colors[i]);
}
- // draw xaxis labels.
- shoes_plot_set_cairo_default(cr, plot); // reset to default
- VALUE obs = rb_ary_entry(labels[0], i + plot->beg_idx);
- //VALUE obs = rb_ary_entry(rbobs, i + plot->beg_idx);
- shoes_plot_column_xaxis(cr, plot, xpos-(colsw / 2), obs);
- xpos = (ncolsw * (i + 1)) + xinset;
- }
- // tell cairo to draw all lines (and points) not already drawn.
- cairo_stroke(cr);
- // set color back to dark gray and stroke to 1
- //cairo_set_source_rgba(cr, 0.9, 0.9, 0.9, 1.0);
- //cairo_set_line_width(cr, 1.0);
- shoes_plot_set_cairo_default(cr, plot);
+ int ncolsw = width / (range) ; //
+ int xinset = left + (ncolsw / 2); // start inside the box, half a width
+ int xpos = xinset;
+ //printf("ncolsw: w: %i, advw: %i, start inset %i\n", width, ncolsw, xpos);
+ for (i = plot->beg_idx; i < plot->end_idx; i++) {
+ int j;
+ for (j = 0; j < plot->seriescnt; j++) {
+ VALUE rbdp = rb_ary_entry(values[j], i + plot->beg_idx);
+ if (NIL_P(rbdp)) {
+ printf("skipping nil at %i\n", i + plot->beg_idx);
+ continue;
+ }
+ double v = NUM2DBL(rbdp);
+ cairo_set_line_width(cr, strokesw[j]);
+ cairo_set_source_rgba(cr, colors[j]->r / 255.0, colors[j]->g / 255.0,
+ colors[j]->b / 255.0, colors[j]->a / 255.0);
+
+ long y = height - roundl((v - minimums[j]) * vScales[j]);
+ //printf("move i: %i, j: %i, x: %i, v: %f -> y: %i,%i \n", i, j, xpos, v, y, y+top);
+ y += top;
+ cairo_move_to(cr, xpos, bottom);
+ cairo_line_to(cr, xpos, y);
+ cairo_stroke(cr);
+ xpos += strokesw[j];
+ }
+ // draw xaxis labels.
+ shoes_plot_set_cairo_default(cr, plot); // reset to default
+ VALUE obs = rb_ary_entry(labels[0], i + plot->beg_idx);
+ //VALUE obs = rb_ary_entry(rbobs, i + plot->beg_idx);
+ shoes_plot_column_xaxis(cr, plot, xpos-(colsw / 2), obs);
+ xpos = (ncolsw * (i + 1)) + xinset;
+ }
+ // tell cairo to draw all lines (and points) not already drawn.
+ cairo_stroke(cr);
+ shoes_plot_set_cairo_default(cr, plot);
}
-// called by the draw event - draw everything.
+// called by the draw event - draw everything.
void shoes_plot_column_draw(cairo_t *cr, shoes_place *place, shoes_plot *self_t) {
- shoes_plot_set_cairo_default(cr, self_t);
- shoes_plot_draw_fill(cr, self_t);
- shoes_plot_draw_title(cr, self_t);
- shoes_plot_draw_caption(cr, self_t);
- if (self_t->boundbox)
- shoes_plot_draw_boundbox(cr, self_t);
- self_t->graph_h = self_t->place.h - (self_t->title_h + self_t->caption_h);
- self_t->graph_y = self_t->title_h + 3;
- self_t->yaxis_offset = 50; // TODO: run TOTO, run!
- self_t->graph_w = self_t->place.w - self_t->yaxis_offset;
- self_t->graph_x = self_t->yaxis_offset;
- if (self_t->seriescnt) {
- // draw box, ticks and x,y labels.
- shoes_plot_draw_ticks_and_labels(cr, self_t); // FIX for v2?
- shoes_plot_draw_legend(cr, self_t); //Fix for v2?
- shoes_plot_draw_columns(cr, self_t);
- }
+ shoes_plot_util_adornments(cr, place, self_t, 50);
+ if (self_t->seriescnt) {
+ // draw box, ticks and x,y labels.
+ shoes_plot_draw_ticks_and_labels(cr, self_t); // FIX for v2?
+ shoes_plot_draw_legend(cr, self_t); //Fix for v2?
+ shoes_plot_draw_columns(cr, self_t);
+ }
}
diff --git a/shoes/plot/plot_line.c b/shoes/plot/plot_line.c
index ed39c7ae..dcd71e74 100644
--- a/shoes/plot/plot_line.c
+++ b/shoes/plot/plot_line.c
@@ -5,109 +5,109 @@
void shoes_plot_line_nub(cairo_t *, int, int);
-void shoes_plot_draw_datapts(cairo_t *cr, shoes_plot *plot)
-{
- int i;
- int top,left,bottom,right;
- left = plot->graph_x; top = plot->graph_y;
- right = plot->graph_w; bottom = plot->graph_h;
- for (i = 0; i < plot->seriescnt; i++) {
- VALUE rbser = rb_ary_entry(plot->series, i);
- shoes_chart_series *cs;
- Data_Get_Struct(rbser, shoes_chart_series, cs);
- VALUE rbvalues = cs->values;
- VALUE rbmaxv = cs->maxv;
- double maximum = NUM2DBL(rbmaxv);
- VALUE rbminv = cs->minv;
- double minimum = NUM2DBL(rbminv);
- int strokew = NUM2INT(cs->strokes);
- shoes_color *color;
- Data_Get_Struct(cs->color, shoes_color, color);
- /*
- VALUE rbvalues = rb_ary_entry(plot->values, i);
- VALUE rbmaxv = rb_ary_entry(plot->maxvs, i);
- VALUE rbminv = rb_ary_entry(plot->minvs, i);
- VALUE rbstroke = rb_ary_entry(plot->strokes, i);
- VALUE rbnubs = rb_ary_entry(plot->nubs, i);
- VALUE shcolor = rb_ary_entry(plot->color, i);
- shoes_color *color;
- Data_Get_Struct(shcolor, shoes_color, color);
- double maximum = NUM2DBL(rbmaxv);
- double minimum = NUM2DBL(rbminv);
- int strokew = NUM2INT(rbstroke);
- */
- if (strokew < 1) strokew = 1;
- cairo_set_line_width(cr, strokew);
- // Shoes: Remember - we use ints for x, y, w, h and for drawing lines and points
- int height = bottom - top;
- int width = right - left;
- int range = plot->end_idx - plot->beg_idx; // zooming adj
- float vScale = height / (maximum - minimum);
- float hScale = width / (double) (range - 1);
- //int nubs = (width / range > 10) ? NUM2INT(rbnubs) : 0;
- int nubs = (width / range > 10) ? NUM2INT(cs->point_type) : 0;
-
- cairo_set_source_rgba(cr, color->r / 255.0, color->g / 255.0,
- color->b / 255.0, color->a / 255.0);
+void shoes_plot_draw_datapts(cairo_t *cr, shoes_plot *plot) {
+ int i;
+ int top,left,bottom,right;
+ left = plot->graph_x;
+ top = plot->graph_y;
+ right = plot->graph_w;
+ bottom = plot->graph_h;
+ for (i = 0; i < plot->seriescnt; i++) {
+ VALUE rbser = rb_ary_entry(plot->series, i);
+ shoes_chart_series *cs;
+ Data_Get_Struct(rbser, shoes_chart_series, cs);
+ VALUE rbvalues = cs->values;
+ VALUE rbmaxv = cs->maxv;
+ double maximum = NUM2DBL(rbmaxv);
+ VALUE rbminv = cs->minv;
+ double minimum = NUM2DBL(rbminv);
+ int strokew = NUM2INT(cs->strokes);
+ shoes_color *color;
+ Data_Get_Struct(cs->color, shoes_color, color);
+ /*
+ VALUE rbvalues = rb_ary_entry(plot->values, i);
+ VALUE rbmaxv = rb_ary_entry(plot->maxvs, i);
+ VALUE rbminv = rb_ary_entry(plot->minvs, i);
+ VALUE rbstroke = rb_ary_entry(plot->strokes, i);
+ VALUE rbnubs = rb_ary_entry(plot->nubs, i);
+ VALUE shcolor = rb_ary_entry(plot->color, i);
+ shoes_color *color;
+ Data_Get_Struct(shcolor, shoes_color, color);
+ double maximum = NUM2DBL(rbmaxv);
+ double minimum = NUM2DBL(rbminv);
+ int strokew = NUM2INT(rbstroke);
+ */
+ if (strokew < 1) strokew = 1;
+ cairo_set_line_width(cr, strokew);
+ // Shoes: Remember - we use ints for x, y, w, h and for drawing lines and points
+ int height = bottom - top;
+ int width = right - left;
+ int range = plot->end_idx - plot->beg_idx; // zooming adj
+ float vScale = height / (maximum - minimum);
+ float hScale = width / (double) (range - 1);
+ //int nubs = (width / range > 10) ? NUM2INT(rbnubs) : 0;
+ int nubs = (width / range > 10) ? NUM2INT(cs->point_type) : 0;
- int j;
- int brk = 0; // for missing value control
- for (j = 0; j < range; j++) {
- VALUE rbdp = rb_ary_entry(rbvalues, j + plot->beg_idx);
- if (NIL_P(rbdp)) {
- if (plot->missing == MISSING_MIN) {
- rbdp = rbminv;
- } else if (plot->missing == MISSING_MAX) {
- rbdp = rbmaxv;
- } else {
- brk = 1;
- continue;
+ cairo_set_source_rgba(cr, color->r / 255.0, color->g / 255.0,
+ color->b / 255.0, color->a / 255.0);
+
+ int j;
+ int brk = 0; // for missing value control
+ for (j = 0; j < range; j++) {
+ VALUE rbdp = rb_ary_entry(rbvalues, j + plot->beg_idx);
+ if (NIL_P(rbdp)) {
+ if (plot->missing == MISSING_MIN) {
+ rbdp = rbminv;
+ } else if (plot->missing == MISSING_MAX) {
+ rbdp = rbmaxv;
+ } else {
+ brk = 1;
+ continue;
+ }
+ }
+ double v = NUM2DBL(rbdp);
+ long x = roundl(j * hScale);
+ long y = height - roundl((v - minimum) *vScale);
+ x += left;
+ y += top;
+ //printf("draw i: %i, x: %i, y: %i %f \n", j, (int) x, (int) y, hScale);
+ if (j == 0 || brk == 1) {
+ cairo_move_to(cr, x, y);
+ brk = 0;
+ } else {
+ cairo_line_to(cr, x, y);
+ }
+ if (nubs) {
+ //shoes_plot_line_nub(cr, x, y);
+ // TODO: shoes_plot_draw_nub(cr, plot, x, y, nubs, strokew + 2);
+ shoes_plot_draw_nub(cr, plot, x, y, 7, strokew + 2); // 7 will default to old code
+ }
}
- }
- double v = NUM2DBL(rbdp);
- long x = roundl(j * hScale);
- long y = height - roundl((v - minimum) *vScale);
- x += left;
- y += top;
- //printf("draw i: %i, x: %i, y: %i %f \n", j, (int) x, (int) y, hScale);
- if (j == 0 || brk == 1) {
- cairo_move_to(cr, x, y);
- brk = 0;
- } else {
- cairo_line_to(cr, x, y);
- }
- if (nubs) {
- //shoes_plot_line_nub(cr, x, y);
- // TODO: shoes_plot_draw_nub(cr, plot, x, y, nubs, strokew + 2);
- shoes_plot_draw_nub(cr, plot, x, y, 7, strokew + 2); // 7 will default to old code
- }
- }
+ cairo_stroke(cr);
+ cairo_set_line_width(cr, 1.0); // reset between series
+ } // end of drawing one series
+ // tell cairo to draw all lines (and points)
cairo_stroke(cr);
- cairo_set_line_width(cr, 1.0); // reset between series
- } // end of drawing one series
- // tell cairo to draw all lines (and points)
- cairo_stroke(cr);
- // set color back to dark gray and stroke to 1
- cairo_set_source_rgba(cr, 0.9, 0.9, 0.9, 1.0);
- cairo_set_line_width(cr, 1.0);
+ // set color back to dark gray and stroke to 1
+ cairo_set_source_rgba(cr, 0.9, 0.9, 0.9, 1.0);
+ cairo_set_line_width(cr, 1.0);
}
-void shoes_plot_line_nub(cairo_t *cr, int x, int y)
-{
- int sz = 2;
+void shoes_plot_line_nub(cairo_t *cr, int x, int y) {
+ int sz = 2;
cairo_move_to(cr, x - sz, y - sz);
cairo_line_to(cr, x + sz, y - sz);
-
+
cairo_move_to(cr, x - sz, y - sz);
cairo_line_to(cr, x - sz, y + sz);
-
+
cairo_move_to(cr, x + sz, y + sz);
cairo_line_to(cr, x + sz, y - sz);
-
+
cairo_move_to(cr, x + sz, y + sz);
cairo_line_to(cr, x - sz, y + sz);
-
+
cairo_move_to(cr, x, y); // back to center point.
}
@@ -115,22 +115,11 @@ void shoes_plot_line_nub(cairo_t *cr, int x, int y)
// called at draw time.
void shoes_plot_line_draw(cairo_t *cr, shoes_place *place, shoes_plot *self_t) {
- // draw widget box and fill with color (nearly white).
- shoes_plot_set_cairo_default(cr, self_t);
- shoes_plot_draw_fill(cr, self_t);
- shoes_plot_draw_title(cr, self_t);
- shoes_plot_draw_caption(cr, self_t);
- if (self_t->boundbox)
- shoes_plot_draw_boundbox(cr, self_t);
- self_t->graph_h = self_t->place.h - (self_t->title_h + self_t->caption_h);
- self_t->graph_y = self_t->title_h + 3;
- self_t->yaxis_offset = 50; // TODO: run TOTO, run!
- self_t->graph_w = self_t->place.w - self_t->yaxis_offset;
- self_t->graph_x = self_t->yaxis_offset;
- if (self_t->seriescnt) {
- // draw ticks and x,y labels.
- shoes_plot_draw_ticks_and_labels(cr, self_t);
- shoes_plot_draw_legend(cr, self_t);
- shoes_plot_draw_datapts(cr, self_t); // draw data
- }
+ shoes_plot_util_adornments(cr, place, self_t, 50);
+ if (self_t->seriescnt) {
+ // draw ticks and x,y labels.
+ shoes_plot_draw_ticks_and_labels(cr, self_t);
+ shoes_plot_draw_legend(cr, self_t);
+ shoes_plot_draw_datapts(cr, self_t); // draw data
+ }
}
diff --git a/shoes/plot/plot_pie.c b/shoes/plot/plot_pie.c
index 7f451269..ab97dbcd 100644
--- a/shoes/plot/plot_pie.c
+++ b/shoes/plot/plot_pie.c
@@ -1,7 +1,7 @@
// pie chart
#include "shoes/plot/plot.h"
-// REMEMBER - there is only one data series in a PIE CHART.
+// REMEMBER - there is only one data series in a PIE CHART.
/* borrows heavily from this python code
* https://bitbucket.org/lgs/pycha/src/e3e270a0e7ae4896052d4cc34fe7f1e532ece914/pycha/pie.py?at=default&fileviewer=file-view-default
@@ -12,297 +12,288 @@
// called when the data series is added to the chart.
// Trying very hard to not pollute Shoes C name space and h files with plot stuff
void shoes_plot_pie_init(shoes_plot *plot) {
- pie_chart_t *piechart = malloc(sizeof(pie_chart_t));
- plot->c_things = (void *)piechart;
- VALUE cs = rb_ary_entry(plot->series, 0);
- shoes_chart_series *ser;
- Data_Get_Struct(cs, shoes_chart_series, ser);
- int numobs = RARRAY_LEN(ser->values);
- piechart->count = numobs;
- pie_slice_t *slices = (pie_slice_t *)malloc(sizeof(pie_slice_t) * numobs);
- piechart->slices = slices;
- int i;
- piechart->maxv = 0.0;
- piechart->minv = 100000000.0; // TODO: use a max double constant
-
- // sum the values
- for (i = 0; i values, i);
- double v = NUM2DBL(rbv);
- slice->value = v;
- if (v < piechart->minv) piechart->minv = v;
- piechart->maxv += v;
- }
- double fraction = 0.0;
- double angle = 0.0;
- for (i = 0; i < numobs; i++) {
- pie_slice_t *slice = &slices[i];
- angle += fraction;
- double v = slice->value;
- fraction = v / piechart->maxv;
- slice->startAngle = 2 * angle * SHOES_PI;
- slice->endAngle = 2 * (angle + fraction) * SHOES_PI;
- //VALUE wedge_color = shoes_plot_pie_color(i);
- VALUE wedge_color = rb_ary_entry(plot->default_colors, i);
- Data_Get_Struct(wedge_color, shoes_color, slice->color);
- }
+ pie_chart_t *piechart = malloc(sizeof(pie_chart_t));
+ plot->c_things = (void *)piechart;
+ VALUE cs = rb_ary_entry(plot->series, 0);
+ shoes_chart_series *ser;
+ Data_Get_Struct(cs, shoes_chart_series, ser);
+ int numobs = RARRAY_LEN(ser->values);
+ piechart->count = numobs;
+ pie_slice_t *slices = (pie_slice_t *)malloc(sizeof(pie_slice_t) * numobs);
+ piechart->slices = slices;
+ int i;
+ piechart->maxv = 0.0;
+ piechart->minv = 100000000.0; // TODO: use a max double constant
+
+ // sum the values
+ for (i = 0; i values, i);
+ double v = NUM2DBL(rbv);
+ slice->value = v;
+ if (v < piechart->minv) piechart->minv = v;
+ piechart->maxv += v;
+ }
+ double fraction = 0.0;
+ double angle = 0.0;
+ for (i = 0; i < numobs; i++) {
+ pie_slice_t *slice = &slices[i];
+ angle += fraction;
+ double v = slice->value;
+ fraction = v / piechart->maxv;
+ slice->startAngle = 2 * angle * SHOES_PI;
+ slice->endAngle = 2 * (angle + fraction) * SHOES_PI;
+ //VALUE wedge_color = shoes_plot_pie_color(i);
+ VALUE wedge_color = rb_ary_entry(plot->default_colors, i);
+ Data_Get_Struct(wedge_color, shoes_color, slice->color);
+ }
}
// called when it needs to go away
void shoes_plot_pie_dealloc(shoes_plot *plot) {
- if (plot->c_things) {
- pie_chart_t *piechart = (pie_chart_t *) plot->c_things;
- free(piechart->slices);
- free(piechart);
- }
+ if (plot->c_things) {
+ pie_chart_t *piechart = (pie_chart_t *) plot->c_things;
+ free(piechart->slices);
+ free(piechart);
+ }
}
-void shoes_plot_draw_pie_chart(cairo_t *cr, shoes_plot *plot)
-{
- // first series (x) controls graphical settings.
- if (plot->seriescnt != 1)
- return; // we can only use one series
- int i;
- int top,left,bottom,right, height, width;
- left = plot->graph_x; top = plot->graph_y;
- right = plot->graph_w; bottom = plot->graph_h;
- width = right - left;
- height = bottom - top;
- pie_chart_t *chart = (pie_chart_t *) plot->c_things;
+void shoes_plot_draw_pie_chart(cairo_t *cr, shoes_plot *plot) {
+ // first series (x) controls graphical settings.
+ if (plot->seriescnt != 1)
+ return; // we can only use one series
+ int i;
+ int top,left,bottom,right, height, width;
+ left = plot->graph_x;
+ top = plot->graph_y;
+ right = plot->graph_w;
+ bottom = plot->graph_h;
+ width = right - left;
+ height = bottom - top;
+ pie_chart_t *chart = (pie_chart_t *) plot->c_things;
+
+ chart->centerx = left + roundl(width * 0.5);
+ chart->centery = top + roundl(height * 0.5);
+ chart->radius = min(width / 2.0, height / 2.0);
+ chart->top = top;
+ chart->left = left;
+ chart->bottom = bottom;
+ chart->right = right;
+ chart->width = width;
+ chart->height = height;
+ chart->percent = plot->missing; // Bait `n switch
- chart->centerx = left + roundl(width * 0.5);
- chart->centery = top + roundl(height * 0.5);
- chart->radius = min(width / 2.0, height / 2.0);
- chart->top = top; chart->left = left; chart->bottom = bottom;
- chart->right = right; chart->width = width; chart->height = height;
- chart->percent = plot->missing; // Bait `n switch
-
#if 0 // OR attr(drop_shadow)
- // draw something circular which might be the drop shadow of the pie.
- // Which we probably don't need since Shoes doesn't have a drop shadow option
- cairo_save(cr);
- cairo_set_source_rgba(cr, 0, 0, 0, 0.15);
- cairo_new_path(cr);
- cairo_move_to(cr, centerx, centery);
- cairo_arc(cr, centerx + 1, centery + 2, chart->radius + 1, 0, SHOES_PIM2);
- cairo_line_to(cr, centerx, centery);
- cairo_close_path(cr);
- cairo_fill(cr);
- cairo_restore(cr);
-#endif
+ // draw something circular which might be the drop shadow of the pie.
+ // Which we probably don't need since Shoes doesn't have a drop shadow option
+ cairo_save(cr);
+ cairo_set_source_rgba(cr, 0, 0, 0, 0.15);
+ cairo_new_path(cr);
+ cairo_move_to(cr, centerx, centery);
+ cairo_arc(cr, centerx + 1, centery + 2, chart->radius + 1, 0, SHOES_PIM2);
+ cairo_line_to(cr, centerx, centery);
+ cairo_close_path(cr);
+ cairo_fill(cr);
+ cairo_restore(cr);
+#endif
- for (i = 0; i < chart->count; i++) {
- pie_slice_t *slice = &chart->slices[i];
- if (fabs(slice->startAngle - slice->endAngle) > 0.001) { // bigEnough?
- shoes_color *color = slice->color;
- cairo_set_source_rgba(cr, color->r / 255.0, color->g / 255.0,
- color->b / 255.0, color->a / 255.0);
- //printf("pie color for %i: r:%i g:%i b:%i a:%i\n", i, color->r, color->g,
- // color->b, color->a);
- cairo_new_path(cr);
- cairo_move_to(cr, chart->centerx, chart->centery);
- cairo_arc(cr, chart->centerx, chart->centery, chart->radius, -(slice->endAngle), -(slice->startAngle));
- cairo_close_path(cr);
- cairo_fill(cr);
+ for (i = 0; i < chart->count; i++) {
+ pie_slice_t *slice = &chart->slices[i];
+ if (fabs(slice->startAngle - slice->endAngle) > 0.001) { // bigEnough?
+ shoes_color *color = slice->color;
+ cairo_set_source_rgba(cr, color->r / 255.0, color->g / 255.0,
+ color->b / 255.0, color->a / 255.0);
+ //printf("pie color for %i: r:%i g:%i b:%i a:%i\n", i, color->r, color->g,
+ // color->b, color->a);
+ cairo_new_path(cr);
+ cairo_move_to(cr, chart->centerx, chart->centery);
+ cairo_arc(cr, chart->centerx, chart->centery, chart->radius, -(slice->endAngle), -(slice->startAngle));
+ cairo_close_path(cr);
+ cairo_fill(cr);
+ }
}
- }
- shoes_plot_set_cairo_default(cr, plot);
+ shoes_plot_set_cairo_default(cr, plot);
}
// just draws a box
-void shoes_plot_pie_legend_box(cairo_t *cr, shoes_plot *self_t,
- int t, int l, int b, int r)
-{
- shoes_plot_set_cairo_default(cr, self_t);
- cairo_move_to(cr, l, t);
- cairo_line_to(cr, r, t); // across top
- cairo_line_to(cr, r, b); // down right side
- cairo_line_to(cr, l, b); // across bottom
- cairo_line_to(cr, l, t); // up left
- cairo_stroke(cr);
+void shoes_plot_pie_legend_box(cairo_t *cr, shoes_plot *self_t,
+ int t, int l, int b, int r) {
+ shoes_plot_set_cairo_default(cr, self_t);
+ cairo_move_to(cr, l, t);
+ cairo_line_to(cr, r, t); // across top
+ cairo_line_to(cr, r, b); // down right side
+ cairo_line_to(cr, l, b); // across bottom
+ cairo_line_to(cr, l, t); // up left
+ cairo_stroke(cr);
}
void shoes_plot_draw_pie_legend(cairo_t *cr, shoes_plot *self_t) {
- /* draw labels (strings) in the legend area in color, on the right
- * hand side. Need to compute the max height and width of all strings
- * attempt to get the most data on the chart. Ugly. TODO: it would
- * be nice to have shoes class/struct.
- */
- int i;
- if (self_t->seriescnt != 1) return;
- VALUE cs = rb_ary_entry(self_t->series, 0);
- shoes_chart_series *ser;
- Data_Get_Struct(cs, shoes_chart_series, ser);
- int numstrs = RARRAY_LEN(ser->labels);
- VALUE rbobs = ser->labels;
- PangoLayout *layouts[numstrs];
- char *strary[numstrs];
- char strh[numstrs];
- int boxh = 0, boxw = 0;
- // compute layouts for each string. Don't forget to g_unref them!
- for (i = 0; i < numstrs; i++) {
- strary[i] = RSTRING_PTR(rb_ary_entry(rbobs, i));
- layouts[i] = pango_cairo_create_layout (cr);
- pango_layout_set_font_description (layouts[i], self_t->caption_pfd);
- pango_layout_set_text (layouts[i], strary[i], -1);
- PangoRectangle logical;
- pango_layout_get_pixel_extents (layouts[i], NULL, &logical);
- strh[i] = logical.height;
- boxh += logical.height;
- boxw = max(boxw, logical.width);
- }
- int box_x = (self_t->place.iw - boxw) - 5; // everything we can get on the right
- int box_y = self_t->graph_y + 1;
- int box_t = box_y - 2;
- int box_l = box_x - 3;
- int box_r = self_t->place.iw - 1;
- int box_b = boxh + box_y + 1;
- // Draw strings using layout
- for (i = 0; i < numstrs; i++) {
- cairo_move_to(cr, box_x, box_y);
- shoes_color *color;
- VALUE rbcolor = rb_ary_entry(self_t->default_colors, i);
- Data_Get_Struct(rbcolor, shoes_color, color);
- cairo_set_source_rgba(cr, color->r / 255.0, color->g / 255.0,
- color->b / 255.0, color->a / 255.0);
- pango_cairo_show_layout(cr, layouts[i]);
- box_y += strh[i];
- g_object_unref(layouts[i]);
- }
- // Draw a box around the legend (auto grid repurpose?)
- if (self_t->auto_grid) {
- //printf("legend box l: %i, t: %i, b: %i, r: %i\n", box_l, box_t, box_b, box_r);
- shoes_plot_pie_legend_box(cr, self_t, box_t, box_l, box_b, box_r);
- }
+ /* draw labels (strings) in the legend area in color, on the right
+ * hand side. Need to compute the max height and width of all strings
+ * attempt to get the most data on the chart. Ugly. TODO: it would
+ * be nice to have shoes class/struct.
+ */
+ int i;
+ if (self_t->seriescnt != 1) return;
+ VALUE cs = rb_ary_entry(self_t->series, 0);
+ shoes_chart_series *ser;
+ Data_Get_Struct(cs, shoes_chart_series, ser);
+ int numstrs = RARRAY_LEN(ser->labels);
+ VALUE rbobs = ser->labels;
+ PangoLayout *layouts[numstrs];
+ char *strary[numstrs];
+ char strh[numstrs];
+ int boxh = 0, boxw = 0;
+ // compute layouts for each string. Don't forget to g_unref them!
+ for (i = 0; i < numstrs; i++) {
+ strary[i] = RSTRING_PTR(rb_ary_entry(rbobs, i));
+ layouts[i] = pango_cairo_create_layout (cr);
+ pango_layout_set_font_description (layouts[i], self_t->caption_pfd);
+ pango_layout_set_text (layouts[i], strary[i], -1);
+ PangoRectangle logical;
+ pango_layout_get_pixel_extents (layouts[i], NULL, &logical);
+ strh[i] = logical.height;
+ boxh += logical.height;
+ boxw = max(boxw, logical.width);
+ }
+ int box_x = (self_t->place.iw - boxw) - 5; // everything we can get on the right
+ int box_y = self_t->graph_y + 1;
+ int box_t = box_y - 2;
+ int box_l = box_x - 3;
+ int box_r = self_t->place.iw - 1;
+ int box_b = boxh + box_y + 1;
+ // Draw strings using layout
+ for (i = 0; i < numstrs; i++) {
+ cairo_move_to(cr, box_x, box_y);
+ shoes_color *color;
+ VALUE rbcolor = rb_ary_entry(self_t->default_colors, i);
+ Data_Get_Struct(rbcolor, shoes_color, color);
+ cairo_set_source_rgba(cr, color->r / 255.0, color->g / 255.0,
+ color->b / 255.0, color->a / 255.0);
+ pango_cairo_show_layout(cr, layouts[i]);
+ box_y += strh[i];
+ g_object_unref(layouts[i]);
+ }
+ // Draw a box around the legend (auto grid repurpose?)
+ if (self_t->auto_grid) {
+ //printf("legend box l: %i, t: %i, b: %i, r: %i\n", box_l, box_t, box_b, box_r);
+ shoes_plot_pie_legend_box(cr, self_t, box_t, box_l, box_b, box_r);
+ }
}
-/*
- * NOTE: here, "ticks" are values (or %?) drawn around the slices.
+/*
+ * NOTE: here, "ticks" are values (or %?) drawn around the slices.
* Expect confusion and many helper functions.
* This called after drawing the wedges in a shoes draw event so we know
- * we actually have a cairo_t that is real and the slices are OK.
- * We depend on that.
+ * we actually have a cairo_t that is real and the slices are OK.
+ * We depend on that.
*/
double shoes_plot_pie_getNormalisedAngle(pie_slice_t *self) {
- double normalisedAngle = (self->startAngle + self->endAngle) / 2;
- if (normalisedAngle > SHOES_PI * 2)
- normalisedAngle -= SHOES_PI * 2;
- else if (normalisedAngle < 0)
- normalisedAngle += SHOES_PI * 2;
+ double normalisedAngle = (self->startAngle + self->endAngle) / 2;
+ if (normalisedAngle > SHOES_PI * 2)
+ normalisedAngle -= SHOES_PI * 2;
+ else if (normalisedAngle < 0)
+ normalisedAngle += SHOES_PI * 2;
- return normalisedAngle;
+ return normalisedAngle;
}
-void
-shoes_plot_pie_tick_position(cairo_t *cr, pie_chart_t * chart, pie_slice_t *slice, double angle)
-{
- int text_height = slice->lh;
- int text_width = slice->lw;
- int half_width = text_width / 2.0;
- int half_height = text_height / 2.0;
- int k1, k2, j1, j2;
- int quad = shoes_plot_util_quadrant(angle);
- switch(quad) {
- case QUAD_ONE:
- k1 = j1 = k2 = 1;
- j2 = -1;
- break;
- case QUAD_TWO:
- k1 = k2 = -1;
- j1 = j2 = 1;
- break;
- case QUAD_THREE:
- k1 = j1 = k2 = -1;
- j2 = 1;
- break;
- case QUAD_FOUR:
- k1 = k2 = 1;
- j1 = j2 = -1;
- break;
- default:
- fprintf(stderr, "plot_pie- bad news\n");
- return;
- }
+void shoes_plot_pie_tick_position(cairo_t *cr, pie_chart_t * chart, pie_slice_t *slice, double angle) {
+ int text_height = slice->lh;
+ int text_width = slice->lw;
+ int half_width = text_width / 2.0;
+ int half_height = text_height / 2.0;
+ int k1, k2, j1, j2;
+ int quad = shoes_plot_util_quadrant(angle);
+ switch(quad) {
+ case QUAD_ONE:
+ k1 = j1 = k2 = 1;
+ j2 = -1;
+ break;
+ case QUAD_TWO:
+ k1 = k2 = -1;
+ j1 = j2 = 1;
+ break;
+ case QUAD_THREE:
+ k1 = j1 = k2 = -1;
+ j2 = 1;
+ break;
+ case QUAD_FOUR:
+ k1 = k2 = 1;
+ j1 = j2 = -1;
+ break;
+ default:
+ fprintf(stderr, "plot_pie- bad news\n");
+ return;
+ }
+
+ double cx = chart->radius * cos(angle) + k1 * half_width;
+ double cy = chart->radius * sin(angle) + j1 * half_height;
- double cx = chart->radius * cos(angle) + k1 * half_width;
- double cy = chart->radius * sin(angle) + j1 * half_height;
+ double radius2 = sqrt(cx * cx + cy * cy);
- double radius2 = sqrt(cx * cx + cy * cy);
+ double tang = tan(angle);
+ double x = sqrt((radius2 * radius2) / (1 + tang * tang));
+ double y = tang * x;
- double tang = tan(angle);
- double x = sqrt((radius2 * radius2) / (1 + tang * tang));
- double y = tang * x;
+ x = chart->centerx + k2 * x;
+ y = chart->centery + j2 * y;
- x = chart->centerx + k2 * x;
- y = chart->centery + j2 * y;
-
- // set 4 variables for return (python puts the list into the tick tuple)
- //return x - half_width, y - half_height, text_width, text_height
- slice->lx = x - half_width;
- slice->ly = y - half_height;
- slice->lw = text_width;
- slice->lh = text_height;
+ // set 4 variables for return (python puts the list into the tick tuple)
+ //return x - half_width, y - half_height, text_width, text_height
+ slice->lx = x - half_width;
+ slice->ly = y - half_height;
+ slice->lw = text_width;
+ slice->lh = text_height;
}
-void shoes_plot_draw_pie_ticks(cairo_t *cr, shoes_plot *plot)
-{
- if (plot->seriescnt != 1)
- return; // just in case
- pie_chart_t *chart = (pie_chart_t *) plot->c_things;
- int i;
- PangoRectangle logical;
- for (i = 0; i < chart->count; i++) {
- pie_slice_t *slice = &chart->slices[i];
- char vstr[10];
- if (chart->percent)
- sprintf(vstr, "%i%%", (int)((slice->value / (chart->maxv - chart->minv))*100.0));
- else
- sprintf(vstr, "%i", (int)slice->value);
+void shoes_plot_draw_pie_ticks(cairo_t *cr, shoes_plot *plot) {
+ if (plot->seriescnt != 1)
+ return; // just in case
+ pie_chart_t *chart = (pie_chart_t *) plot->c_things;
+ int i;
+ PangoRectangle logical;
+ for (i = 0; i < chart->count; i++) {
+ pie_slice_t *slice = &chart->slices[i];
+ char vstr[10];
+ if (chart->percent)
+ sprintf(vstr, "%i%%", (int)((slice->value / (chart->maxv - chart->minv))*100.0));
+ else
+ sprintf(vstr, "%i", (int)slice->value);
+
+ slice->label = malloc(strlen(vstr));
+ strcpy(slice->label, vstr);
+ slice->layout = pango_cairo_create_layout (cr);
+ pango_layout_set_font_description (slice->layout, plot->legend_pfd);
+ pango_layout_set_text (slice->layout, slice->label, -1);
+ pango_layout_get_pixel_extents (slice->layout, NULL, &logical);
+ slice->lw = logical.width;
+ slice->lh = logical.height;
+ //double angle = shoes_plot_pie_getNormalisedAngle(slice);
+ //double radius = get_min_radius(angle, chart->centerx, chart->centery,
+ // logical->width, logical->height)
+ }
- slice->label = malloc(strlen(vstr));
- strcpy(slice->label, vstr);
- slice->layout = pango_cairo_create_layout (cr);
- pango_layout_set_font_description (slice->layout, plot->legend_pfd);
- pango_layout_set_text (slice->layout, slice->label, -1);
- pango_layout_get_pixel_extents (slice->layout, NULL, &logical);
- slice->lw = logical.width;
- slice->lh = logical.height;
- //double angle = shoes_plot_pie_getNormalisedAngle(slice);
- //double radius = get_min_radius(angle, chart->centerx, chart->centery,
- // logical->width, logical->height)
- }
-
- // pass through the slices again, drawing, free the string, unref the layouts ?
- for (i = 0; i < chart->count; i++) {
- pie_slice_t *slice = &chart->slices[i];
- double angle = shoes_plot_pie_getNormalisedAngle(slice);
- shoes_plot_pie_tick_position(cr, chart, slice, angle);
- cairo_move_to(cr, slice->lx, slice->ly);
- // set color?
- pango_cairo_show_layout(cr, slice->layout);
- free(slice->label);
- g_object_unref(slice->layout);
- }
+ // pass through the slices again, drawing, free the string, unref the layouts ?
+ for (i = 0; i < chart->count; i++) {
+ pie_slice_t *slice = &chart->slices[i];
+ double angle = shoes_plot_pie_getNormalisedAngle(slice);
+ shoes_plot_pie_tick_position(cr, chart, slice, angle);
+ cairo_move_to(cr, slice->lx, slice->ly);
+ // set color?
+ pango_cairo_show_layout(cr, slice->layout);
+ free(slice->label);
+ g_object_unref(slice->layout);
+ }
}
-// called at Shoes draw time. Calls many other functions.
+// called at Shoes draw time. Calls many other functions.
// Whole lotta drawing going on
void shoes_plot_pie_draw(cairo_t *cr, shoes_place *place, shoes_plot *self_t) {
- shoes_plot_set_cairo_default(cr, self_t);
- shoes_plot_draw_fill(cr, self_t);
- shoes_plot_draw_title(cr, self_t);
- shoes_plot_draw_caption(cr, self_t);
- //if (self_t->boundbox)
- // shoes_plot_draw_boundbox(cr, self_t); // not helpful for pie charts. IMHO.
- self_t->graph_h = self_t->place.h - (self_t->title_h + self_t->caption_h);
- self_t->graph_y = self_t->title_h + 3;
- self_t->yaxis_offset = 20; // TODO: run TOTO! run!
- self_t->graph_w = self_t->place.w - self_t->yaxis_offset;
- self_t->graph_x = self_t->yaxis_offset;
- if (self_t->seriescnt) {
- shoes_plot_draw_pie_chart(cr, self_t);
- shoes_plot_draw_pie_ticks(cr, self_t);
- shoes_plot_draw_pie_legend(cr, self_t);
- }
+ shoes_plot_util_adornments(cr, place, self_t, 20);
+ if (self_t->seriescnt) {
+ shoes_plot_draw_pie_chart(cr, self_t);
+ shoes_plot_draw_pie_ticks(cr, self_t);
+ shoes_plot_draw_pie_legend(cr, self_t);
+ }
}
diff --git a/shoes/plot/plot_radar.c b/shoes/plot/plot_radar.c
index 6c980b6e..1db504bd 100644
--- a/shoes/plot/plot_radar.c
+++ b/shoes/plot/plot_radar.c
@@ -1,6 +1,6 @@
-/*
+/*
* radar chart
- *
+ *
* uses radar_chart_t and radar_pole_t for now. MAY NOT BE NEEDED
* It's more like a bar chart than a pie chart.
*/
@@ -17,165 +17,166 @@ static void shoes_plot_radar_draw_ticks(cairo_t *, shoes_plot *, radar_chart_t *
static void shoes_plot_radar_draw_rings(cairo_t *, shoes_plot *, radar_chart_t *);
static double deg2rad(double);
-/*
+/*
* called when each data series is added to the chart, after it's added to
* shoes_plot->series (array of) chart_series class and shoes_plot->seriescnt
* is accurate (1, 2, ..) Create a more gruff like struct to play with and
* convert to c values (normalized?)- don't forget to free things
*/
void shoes_plot_radar_init(shoes_plot *plot) {
- radar_chart_t *rdrchart;
-
- VALUE cs = rb_ary_entry(plot->series, plot->seriescnt -1);
- shoes_chart_series *ser;
- Data_Get_Struct(cs, shoes_chart_series, ser);
- int numcols = RARRAY_LEN(plot->column_opts);
- int i;
- if (plot->seriescnt == 1) {
- // one init time
- rdrchart = malloc(sizeof(radar_chart_t));
- plot->c_things = (void *)rdrchart;
- VALUE outer_ary = plot->column_opts;
- rdrchart->count = RARRAY_LEN(outer_ary);
- rdrchart->colmax = malloc(sizeof(double) * numcols);
- rdrchart->colmin = malloc(sizeof(double) * numcols);
- rdrchart->labels = malloc(sizeof(char *) * numcols);
- rdrchart->fmt_strs = malloc(sizeof(char *) * numcols);
- rdrchart->lw = malloc(sizeof(double) * numcols);
- rdrchart->lh = malloc(sizeof(double) * numcols);
- rdrchart->lx = malloc(sizeof(double) * numcols);
- rdrchart->ly = malloc(sizeof(double) * numcols);
- rdrchart->layouts = malloc(sizeof(PangoLayout *) * numcols);
- for (i = 0; i < numcols; i++) {
- // unwrap the Ruby array of arrays
- VALUE inner_ary = rb_ary_entry(outer_ary, i);
- int cnt;
- VALUE rbval;
- cnt = RARRAY_LEN(inner_ary);
- rbval = rb_ary_entry(inner_ary, RADAR_LABEL);
- rdrchart->labels[i] = RSTRING_PTR(rbval); // should be safe from gc
- rbval = rb_ary_entry(inner_ary, RADAR_MIN);
- rdrchart->colmin[i] = NUM2DBL(rbval);
- rbval = rb_ary_entry(inner_ary, RADAR_MAX);
- rdrchart->colmax[i] = NUM2DBL(rbval);
- rbval = rb_ary_entry(inner_ary, RADAR_EXTRA); // format [optional]
- if (NIL_P(rbval)) {
- rdrchart->fmt_strs[i] = strdup("%4.2f");
- } else {
- rdrchart->fmt_strs[i] = strdup(RSTRING_PTR(rbval));
- }
- // layout fun for outer labels
- rdrchart->lw[i] = 0.0;
- rdrchart->lh[i] = 0.0;
- rdrchart->lx[i] = 0.0;
- rdrchart->ly[i] = 0.0;
+ radar_chart_t *rdrchart;
+
+ VALUE cs = rb_ary_entry(plot->series, plot->seriescnt -1);
+ shoes_chart_series *ser;
+ Data_Get_Struct(cs, shoes_chart_series, ser);
+ int numcols = RARRAY_LEN(plot->column_opts);
+ int i;
+ if (plot->seriescnt == 1) {
+ // one init time
+ rdrchart = malloc(sizeof(radar_chart_t));
+ plot->c_things = (void *)rdrchart;
+ VALUE outer_ary = plot->column_opts;
+ rdrchart->count = RARRAY_LEN(outer_ary);
+ rdrchart->colmax = malloc(sizeof(double) * numcols);
+ rdrchart->colmin = malloc(sizeof(double) * numcols);
+ rdrchart->labels = malloc(sizeof(char *) * numcols);
+ rdrchart->fmt_strs = malloc(sizeof(char *) * numcols);
+ rdrchart->lw = malloc(sizeof(double) * numcols);
+ rdrchart->lh = malloc(sizeof(double) * numcols);
+ rdrchart->lx = malloc(sizeof(double) * numcols);
+ rdrchart->ly = malloc(sizeof(double) * numcols);
+ rdrchart->layouts = malloc(sizeof(PangoLayout *) * numcols);
+ for (i = 0; i < numcols; i++) {
+ // unwrap the Ruby array of arrays
+ VALUE inner_ary = rb_ary_entry(outer_ary, i);
+ int cnt;
+ VALUE rbval;
+ cnt = RARRAY_LEN(inner_ary);
+ rbval = rb_ary_entry(inner_ary, RADAR_LABEL);
+ rdrchart->labels[i] = RSTRING_PTR(rbval); // should be safe from gc
+ rbval = rb_ary_entry(inner_ary, RADAR_MIN);
+ rdrchart->colmin[i] = NUM2DBL(rbval);
+ rbval = rb_ary_entry(inner_ary, RADAR_MAX);
+ rdrchart->colmax[i] = NUM2DBL(rbval);
+ rbval = rb_ary_entry(inner_ary, RADAR_EXTRA); // format [optional]
+ if (NIL_P(rbval)) {
+ rdrchart->fmt_strs[i] = strdup("%4.2f");
+ } else {
+ rdrchart->fmt_strs[i] = strdup(RSTRING_PTR(rbval));
+ }
+ // layout fun for outer labels
+ rdrchart->lw[i] = 0.0;
+ rdrchart->lh[i] = 0.0;
+ rdrchart->lx[i] = 0.0;
+ rdrchart->ly[i] = 0.0;
+ }
}
- }
}
// called when it needs to go away
void shoes_plot_radar_dealloc(shoes_plot *plot) {
- if (plot->c_things) {
- radar_chart_t *rdrchart = (radar_chart_t *) plot->c_things;
- free(rdrchart->colmax);
- free(rdrchart->lw);
- free(rdrchart->lh);
- free(rdrchart->lx);
- free(rdrchart->ly);
- free(rdrchart->labels); // an array of RSTRING_PTRs
- int i;
- for (i = 0; i < rdrchart->count; i++)
- free(rdrchart->fmt_strs[i]);
- free(rdrchart->fmt_strs);
- free(rdrchart);
- }
+ if (plot->c_things) {
+ radar_chart_t *rdrchart = (radar_chart_t *) plot->c_things;
+ free(rdrchart->colmax);
+ free(rdrchart->lw);
+ free(rdrchart->lh);
+ free(rdrchart->lx);
+ free(rdrchart->ly);
+ free(rdrchart->labels); // an array of RSTRING_PTRs
+ int i;
+ for (i = 0; i < rdrchart->count; i++)
+ free(rdrchart->fmt_strs[i]);
+ free(rdrchart->fmt_strs);
+ free(rdrchart);
+ }
}
-void shoes_plot_draw_radar_chart(cairo_t *cr, shoes_plot *plot)
-{
- if (plot->seriescnt <= 0)
- return;
- int i;
- int top,left,bottom,right, height, width;
- left = plot->graph_x;
- top = plot->graph_y + 20;
- right = plot->graph_w;
- bottom = plot->graph_h -20;
- width = right - left;
- height = bottom - top;
-
- radar_chart_t *chart = (radar_chart_t *) plot->c_things;
- chart->centerx = left + roundl(width * 0.5);
- chart->centery = top + roundl(height * 0.5);
- chart->radius = min(width / 2.0, height / 2.0);
- chart->top = top; chart->left = left; chart->bottom = bottom;
- chart->right = right; chart->width = width; chart->height = height;
+void shoes_plot_draw_radar_chart(cairo_t *cr, shoes_plot *plot) {
+ if (plot->seriescnt <= 0)
+ return;
+ int i;
+ int top,left,bottom,right, height, width;
+ left = plot->graph_x;
+ top = plot->graph_y + 20;
+ right = plot->graph_w;
+ bottom = plot->graph_h -20;
+ width = right - left;
+ height = bottom - top;
- int count = chart->count;
- chart->angle = (2 * SHOES_PI) / count;
- chart->rotation = 0.0;
-
- shoes_plot_radar_draw_radials(cr, plot, chart);
- shoes_plot_radar_draw_ticks(cr, plot, chart);
- shoes_plot_radar_draw_rings(cr, plot, chart);
-
- // draw the data points -
- for (i = 0; i < plot->seriescnt; i++) {
- // for each row (aka chart_series)
- shoes_chart_series *cs;
- VALUE rbcs = rb_ary_entry(plot->series, i);
- Data_Get_Struct(rbcs, shoes_chart_series, cs);
- shoes_color *color;
- Data_Get_Struct(cs->color, shoes_color, color);
- int strokew = NUM2INT(cs->strokes);
- cairo_set_source_rgba(cr, color->r / 255.0 ,color->g / 255.0 ,
- color->b / 255.0 , color->a / 255.0);
- cairo_set_line_width(cr, strokew);
-
- double close_x = 0.0; // keep comilers from whining
- double close_y = 0.0;
- int j;
- for (j = 0; j < count; j++) {
- // scale the value (aka normalize) for the column min/max
- VALUE rbval = rb_ary_entry(cs->values, j);
- double val = NUM2DBL(rbval);
- double minv = chart->colmin[j];
- double maxv = chart->colmax[j];
- double spread = maxv - minv;
- double sv = (val - minv) / spread;
- // compute position on the axis to move/draw to
- double rad_pos = j * SHOES_PI * 2 / count;
- double point_distance = sv * chart->radius;
- double xpos = chart->centerx + sin(rad_pos) * point_distance;
- double ypos = chart->centery - cos(rad_pos) * point_distance;
- if (j == 0) {
- // move_to (save opening pos)
- close_x = xpos;
- close_y = ypos;
- cairo_move_to(cr, xpos, ypos);
- } else {
- // line to
- cairo_line_to(cr, xpos, ypos);
- }
+ radar_chart_t *chart = (radar_chart_t *) plot->c_things;
+ chart->centerx = left + roundl(width * 0.5);
+ chart->centery = top + roundl(height * 0.5);
+ chart->radius = min(width / 2.0, height / 2.0);
+ chart->top = top;
+ chart->left = left;
+ chart->bottom = bottom;
+ chart->right = right;
+ chart->width = width;
+ chart->height = height;
+
+ int count = chart->count;
+ chart->angle = (2 * SHOES_PI) / count;
+ chart->rotation = 0.0;
+
+ shoes_plot_radar_draw_radials(cr, plot, chart);
+ shoes_plot_radar_draw_ticks(cr, plot, chart);
+ shoes_plot_radar_draw_rings(cr, plot, chart);
+
+ // draw the data points -
+ for (i = 0; i < plot->seriescnt; i++) {
+ // for each row (aka chart_series)
+ shoes_chart_series *cs;
+ VALUE rbcs = rb_ary_entry(plot->series, i);
+ Data_Get_Struct(rbcs, shoes_chart_series, cs);
+ shoes_color *color;
+ Data_Get_Struct(cs->color, shoes_color, color);
+ int strokew = NUM2INT(cs->strokes);
+ cairo_set_source_rgba(cr, color->r / 255.0,color->g / 255.0,
+ color->b / 255.0, color->a / 255.0);
+ cairo_set_line_width(cr, strokew);
+
+ double close_x = 0.0; // keep comilers from whining
+ double close_y = 0.0;
+ int j;
+ for (j = 0; j < count; j++) {
+ // scale the value (aka normalize) for the column min/max
+ VALUE rbval = rb_ary_entry(cs->values, j);
+ double val = NUM2DBL(rbval);
+ double minv = chart->colmin[j];
+ double maxv = chart->colmax[j];
+ double spread = maxv - minv;
+ double sv = (val - minv) / spread;
+ // compute position on the axis to move/draw to
+ double rad_pos = j * SHOES_PI * 2 / count;
+ double point_distance = sv * chart->radius;
+ double xpos = chart->centerx + sin(rad_pos) * point_distance;
+ double ypos = chart->centery - cos(rad_pos) * point_distance;
+ if (j == 0) {
+ // move_to (save opening pos)
+ close_x = xpos;
+ close_y = ypos;
+ cairo_move_to(cr, xpos, ypos);
+ } else {
+ // line to
+ cairo_line_to(cr, xpos, ypos);
+ }
+ }
+ // line to first pos
+ cairo_line_to(cr, close_x, close_y);
+ cairo_stroke(cr);
}
- // line to first pos
- cairo_line_to(cr, close_x, close_y);
- cairo_stroke(cr);
- }
-
- shoes_plot_set_cairo_default(cr, plot);
+
+ shoes_plot_set_cairo_default(cr, plot);
}
-static double deg2rad(double angle)
-{
- return angle * (SHOES_PI / 180.0);
+static double deg2rad(double angle) {
+ return angle * (SHOES_PI / 180.0);
}
-// draw xaxis (radial) numeric value.
+// draw xaxis (radial) numeric value.
void shoes_plot_radar_draw_mark(cairo_t *cr, shoes_plot *plot, double cx, double cy,
- double angle, double radius, char *vlbl)
-{
+ double angle, double radius, char *vlbl) {
double r_offset = 1.0;
double x_offset = cx;
double y_offset = cy;
@@ -191,25 +192,25 @@ void shoes_plot_radar_draw_mark(cairo_t *cr, shoes_plot *plot, double cx, doubl
// tweak rx, ry based on quadrant
int quad = shoes_plot_util_quadrant(rad_pos);
if (angle != 0.0) {
- // printf("label ang: %4.2f, %i, %s\n", angle, quad+1, vlbl);
- switch (quad) {
- case QUAD_ONE:
- rx = rx - (logical.width / 2);
- break;
- case QUAD_TWO:
- ry = ry - (logical.height /2);
- rx = rx - (logical.width / 2);
- break;
- case QUAD_THREE:
- ry = ry - (logical.height / 2);
- rx = rx - (logical.width / 2);
- break;
- case QUAD_FOUR:
- rx = rx - (logical.width / 2);
- break;
- }
+ // printf("label ang: %4.2f, %i, %s\n", angle, quad+1, vlbl);
+ switch (quad) {
+ case QUAD_ONE:
+ rx = rx - (logical.width / 2);
+ break;
+ case QUAD_TWO:
+ ry = ry - (logical.height /2);
+ rx = rx - (logical.width / 2);
+ break;
+ case QUAD_THREE:
+ ry = ry - (logical.height / 2);
+ rx = rx - (logical.width / 2);
+ break;
+ case QUAD_FOUR:
+ rx = rx - (logical.width / 2);
+ break;
+ }
} else {
- ry = ry - (logical.height / 2);
+ ry = ry - (logical.height / 2);
}
cairo_save(cr);
cairo_move_to(cr, rx, ry);
@@ -219,181 +220,168 @@ void shoes_plot_radar_draw_mark(cairo_t *cr, shoes_plot *plot, double cx, doubl
cairo_restore(cr);
}
-// determines how many rings can be drawn without getting too busy.
+// determines how many rings can be drawn without getting too busy.
// user setting can override
static int shoes_plot_radar_ring_count(shoes_plot *plot, double radius) {
- if (plot->x_ticks == 1) {
- // magic heuristic
- return max(1, ceill(radius / 75));
- } else
- return plot->x_ticks;
+ if (plot->x_ticks == 1) {
+ // magic heuristic
+ return max(1, ceill(radius / 75));
+ } else
+ return plot->x_ticks;
}
// checks if all colmin[*] are the same AND all colmax[*] are the same
static int shoes_plot_radar_same_range(radar_chart_t *chart) {
- double same_min = chart->colmin[0];
- double same_max = chart->colmax[0];
- int sz = chart->count;
- int i;
- for (i = 0; i < sz; i++) {
- if (chart->colmin[i] != same_min) return 0;
- if (chart->colmax[i] != same_max) return 0;
- }
- return 1;
+ double same_min = chart->colmin[0];
+ double same_max = chart->colmax[0];
+ int sz = chart->count;
+ int i;
+ for (i = 0; i < sz; i++) {
+ if (chart->colmin[i] != same_min) return 0;
+ if (chart->colmax[i] != same_max) return 0;
+ }
+ return 1;
}
// Just draw the x_axis lines from center to outer
-static void shoes_plot_radar_draw_radials(cairo_t *cr, shoes_plot *plot, radar_chart_t *chart)
-{
- int i;
- int sz = chart->count;
- cairo_save(cr);
- cairo_set_source_rgba(cr, 0.0, 0.0 ,0.0, 0.6); // black, 60%
-
- for (i = 0; i < sz ; i++) {
- double rad_pos = (i * SHOES_PI * 2) / sz;
- int x = chart->centerx;
- int y = chart->centery;
- int rx = chart->centerx + sin(rad_pos) * chart->radius;
- int ry = chart->centery - cos(rad_pos) * chart->radius;
- cairo_move_to(cr, x, y);
- cairo_line_to(cr, rx, ry);
- cairo_stroke(cr);
- }
- cairo_restore(cr);
+static void shoes_plot_radar_draw_radials(cairo_t *cr, shoes_plot *plot, radar_chart_t *chart) {
+ int i;
+ int sz = chart->count;
+ cairo_save(cr);
+ cairo_set_source_rgba(cr, 0.0, 0.0,0.0, 0.6); // black, 60%
+
+ for (i = 0; i < sz ; i++) {
+ double rad_pos = (i * SHOES_PI * 2) / sz;
+ int x = chart->centerx;
+ int y = chart->centery;
+ int rx = chart->centerx + sin(rad_pos) * chart->radius;
+ int ry = chart->centery - cos(rad_pos) * chart->radius;
+ cairo_move_to(cr, x, y);
+ cairo_line_to(cr, rx, ry);
+ cairo_stroke(cr);
+ }
+ cairo_restore(cr);
}
// draws the xaxis (radial) numeric labels
-static void shoes_plot_radar_draw_ticks(cairo_t *cr, shoes_plot *plot, radar_chart_t *chart)
-{
- int i;
- int sz = chart->count;
- cairo_save(cr);
- cairo_set_source_rgba(cr, 0.0, 0.0 ,0.0, 0.6); // black, 60%
- // how many rings/labels for each axis?
- int rings = shoes_plot_radar_ring_count(plot, chart->radius);
- int only_one = shoes_plot_radar_same_range(chart);
- int j;
- for (j = 0; j < rings; j++) {
- double radius = (chart->radius / rings) * (j +1 ); // drawing pos
- double scale_pos = (1.0 / rings) * (j + 1);
- for (i = 0; i < sz ; i++) {
- double rad_pos = (i * SHOES_PI * 2) / sz;
- int x = chart->centerx;
- int y = chart->centery;
- cairo_move_to(cr, x, y);
- if (i == 0 || !only_one) {
- char vlbl[16];
- double range = chart->colmax[i] - chart->colmin[i];
- double lblv = range * scale_pos;
- sprintf(vlbl, chart->fmt_strs[i], lblv);
- shoes_plot_radar_draw_mark(cr, plot, chart->centerx, chart->centery,
- rad_pos * 360 / (2 * SHOES_PI), radius, vlbl);
- }
- }
- }
- cairo_restore(cr);
+static void shoes_plot_radar_draw_ticks(cairo_t *cr, shoes_plot *plot, radar_chart_t *chart) {
+ int i;
+ int sz = chart->count;
+ cairo_save(cr);
+ cairo_set_source_rgba(cr, 0.0, 0.0,0.0, 0.6); // black, 60%
+ // how many rings/labels for each axis?
+ int rings = shoes_plot_radar_ring_count(plot, chart->radius);
+ int only_one = shoes_plot_radar_same_range(chart);
+ int j;
+ for (j = 0; j < rings; j++) {
+ double radius = (chart->radius / rings) * (j +1 ); // drawing pos
+ double scale_pos = (1.0 / rings) * (j + 1);
+ for (i = 0; i < sz ; i++) {
+ double rad_pos = (i * SHOES_PI * 2) / sz;
+ int x = chart->centerx;
+ int y = chart->centery;
+ cairo_move_to(cr, x, y);
+ if (i == 0 || !only_one) {
+ char vlbl[16];
+ double range = chart->colmax[i] - chart->colmin[i];
+ double lblv = range * scale_pos;
+ sprintf(vlbl, chart->fmt_strs[i], lblv);
+ shoes_plot_radar_draw_mark(cr, plot, chart->centerx, chart->centery,
+ rad_pos * 360 / (2 * SHOES_PI), radius, vlbl);
+ }
+ }
+ }
+ cairo_restore(cr);
}
-static void shoes_plot_radar_draw_rings(cairo_t *cr, shoes_plot *plot, radar_chart_t *chart)
-{
- int i;
- int sz = chart->count;
- cairo_save(cr);
- cairo_set_source_rgba(cr, 0.4, 0.4 ,0.4, 1.0); // lt gray.
- // how many rings?
- int rings = shoes_plot_radar_ring_count(plot, chart->radius);
- int j;
- int close_x = 0, close_y = 0;
- for (j = 0; j < rings; j++) {
- double radius = (chart->radius / rings) * (j + 1 ); // drawing pos
- for (i = 0; i < sz ; i++) {
- double rad_pos = (i * SHOES_PI * 2) / sz;
- int rx = chart->centerx + sin(rad_pos) * radius;
- int ry = chart->centery - cos(rad_pos) * radius;
- if (i == 0) {
- cairo_move_to(cr, rx, ry);
- close_x = rx;
- close_y = ry;
- }
- else
- cairo_line_to(cr, rx, ry);
- }
- cairo_line_to(cr, close_x, close_y);
- cairo_stroke(cr);
- }
- cairo_stroke(cr);
- cairo_restore(cr);
+static void shoes_plot_radar_draw_rings(cairo_t *cr, shoes_plot *plot, radar_chart_t *chart) {
+ int i;
+ int sz = chart->count;
+ cairo_save(cr);
+ cairo_set_source_rgba(cr, 0.4, 0.4,0.4, 1.0); // lt gray.
+ // how many rings?
+ int rings = shoes_plot_radar_ring_count(plot, chart->radius);
+ int j;
+ int close_x = 0, close_y = 0;
+ for (j = 0; j < rings; j++) {
+ double radius = (chart->radius / rings) * (j + 1 ); // drawing pos
+ for (i = 0; i < sz ; i++) {
+ double rad_pos = (i * SHOES_PI * 2) / sz;
+ int rx = chart->centerx + sin(rad_pos) * radius;
+ int ry = chart->centery - cos(rad_pos) * radius;
+ if (i == 0) {
+ cairo_move_to(cr, rx, ry);
+ close_x = rx;
+ close_y = ry;
+ } else
+ cairo_line_to(cr, rx, ry);
+ }
+ cairo_line_to(cr, close_x, close_y);
+ cairo_stroke(cr);
+ }
+ cairo_stroke(cr);
+ cairo_restore(cr);
}
-void shoes_plot_draw_radar_outer_labels(cairo_t *cr, shoes_plot *plot)
-{
- if (plot->seriescnt < 1)
- return; // just in case
- radar_chart_t *chart = (radar_chart_t *) plot->c_things;
- int i;
- PangoRectangle logical;
- for (i = 0; i < chart->count; i++) {
- chart->layouts[i] = pango_cairo_create_layout (cr);
- pango_layout_set_font_description (chart->layouts[i], plot->legend_pfd);
- pango_layout_set_text (chart->layouts[i], chart->labels[i], -1);
- pango_layout_get_pixel_extents (chart->layouts[i], NULL, &logical);
- chart->lw[i] = logical.width;
- chart->lh[i] = logical.height;
- }
-
- // pass through the labels again, drawing, free the string, unref the layouts ?
- for (i = 0; i < chart->count; i++) {
- double angle = deg2rad(i * (360.0 / chart->count));
+void shoes_plot_draw_radar_outer_labels(cairo_t *cr, shoes_plot *plot) {
+ if (plot->seriescnt < 1)
+ return; // just in case
+ radar_chart_t *chart = (radar_chart_t *) plot->c_things;
+ int i;
+ PangoRectangle logical;
+ for (i = 0; i < chart->count; i++) {
+ chart->layouts[i] = pango_cairo_create_layout (cr);
+ pango_layout_set_font_description (chart->layouts[i], plot->legend_pfd);
+ pango_layout_set_text (chart->layouts[i], chart->labels[i], -1);
+ pango_layout_get_pixel_extents (chart->layouts[i], NULL, &logical);
+ chart->lw[i] = logical.width;
+ chart->lh[i] = logical.height;
+ }
- int quad = shoes_plot_util_quadrant(angle);
- double radius = chart->radius * plot->radar_label_mult; // extend it to draw outside
- double rad_pos = (i * SHOES_PI * 2) / chart->count;
- int rx = chart->centerx + sin(rad_pos) * radius;
- int ry = chart->centery - cos(rad_pos) * radius;
- if (i == 0) {
- // special case the first one. center x
- ry = ry - (chart->lh[i] / 2);
- rx = rx - (chart->lw[i] / 2);
- } else {
- switch (quad) {
- case QUAD_ONE:
- ry = ry - (chart->lh[i] / 2);
- break;
- case QUAD_TWO:
- ry = ry - (chart->lh[i] / 2);
- break;
- case QUAD_THREE:
- ry = ry - (chart->lh[i] / 2);
- rx = rx - (chart->lw[i]);
- break;
- case QUAD_FOUR:
- ry = ry - (chart->lh[i] / 2);
- rx = rx - (chart->lw[i]);
- break;
- }
+ // pass through the labels again, drawing, free the string, unref the layouts ?
+ for (i = 0; i < chart->count; i++) {
+ double angle = deg2rad(i * (360.0 / chart->count));
+
+ int quad = shoes_plot_util_quadrant(angle);
+ double radius = chart->radius * plot->radar_label_mult; // extend it to draw outside
+ double rad_pos = (i * SHOES_PI * 2) / chart->count;
+ int rx = chart->centerx + sin(rad_pos) * radius;
+ int ry = chart->centery - cos(rad_pos) * radius;
+ if (i == 0) {
+ // special case the first one. center x
+ ry = ry - (chart->lh[i] / 2);
+ rx = rx - (chart->lw[i] / 2);
+ } else {
+ switch (quad) {
+ case QUAD_ONE:
+ ry = ry - (chart->lh[i] / 2);
+ break;
+ case QUAD_TWO:
+ ry = ry - (chart->lh[i] / 2);
+ break;
+ case QUAD_THREE:
+ ry = ry - (chart->lh[i] / 2);
+ rx = rx - (chart->lw[i]);
+ break;
+ case QUAD_FOUR:
+ ry = ry - (chart->lh[i] / 2);
+ rx = rx - (chart->lw[i]);
+ break;
+ }
+ }
+ cairo_move_to(cr, rx, ry);
+ pango_cairo_show_layout(cr, chart->layouts[i]);
+ g_object_unref(chart->layouts[i]);
}
- cairo_move_to(cr, rx, ry);
- pango_cairo_show_layout(cr, chart->layouts[i]);
- g_object_unref(chart->layouts[i]);
- }
}
-// called at Shoes draw time. Calls many other functions.
+// called at Shoes draw time. Calls many other functions.
// Whole lotta drawing going on
void shoes_plot_radar_draw(cairo_t *cr, shoes_place *place, shoes_plot *self_t) {
- shoes_plot_set_cairo_default(cr, self_t);
- shoes_plot_draw_fill(cr, self_t);
- shoes_plot_draw_title(cr, self_t);
- shoes_plot_draw_caption(cr, self_t);
- self_t->graph_h = self_t->place.h - (self_t->title_h + self_t->caption_h);
- self_t->graph_y = self_t->title_h + 3;
- self_t->yaxis_offset = 20; // TODO: run TOTO! run!
- self_t->graph_w = self_t->place.w - self_t->yaxis_offset;
- self_t->graph_x = self_t->yaxis_offset;
- if (self_t->seriescnt) {
- shoes_plot_draw_radar_chart(cr, self_t);
- shoes_plot_draw_radar_outer_labels(cr, self_t);
- shoes_plot_draw_legend(cr, self_t);
- }
+ shoes_plot_util_adornments(cr, place, self_t, 20);
+ if (self_t->seriescnt) {
+ shoes_plot_draw_radar_chart(cr, self_t);
+ shoes_plot_draw_radar_outer_labels(cr, self_t);
+ shoes_plot_draw_legend(cr, self_t);
+ }
}
diff --git a/shoes/plot/plot_scatter.c b/shoes/plot/plot_scatter.c
index e385b579..7e4a76e6 100644
--- a/shoes/plot/plot_scatter.c
+++ b/shoes/plot/plot_scatter.c
@@ -2,234 +2,227 @@
#include "shoes/plot/plot.h"
-void shoes_plot_draw_scatter_pts(cairo_t *cr, shoes_plot *plot)
-{
- // first series (x) controls graphical settings.
- if (plot->seriescnt != 2)
- return; // we don't have just two series
- int i;
- int top,left,bottom,right;
- left = plot->graph_x; top = plot->graph_y;
- right = plot->graph_w; bottom = plot->graph_h;
- int height = bottom - top;
- int width = right - left;
- VALUE rbxser, rbyser;
- shoes_chart_series *serx, *sery;
- rbxser = rb_ary_entry(plot->series, 0);
- Data_Get_Struct(rbxser, shoes_chart_series, serx);
- rbyser = rb_ary_entry(plot->series, 1);
- Data_Get_Struct(rbyser, shoes_chart_series, sery);
-
- double xmax = NUM2DBL(serx->maxv);
- double ymax = NUM2DBL(sery->maxv);
- double xmin = NUM2DBL(serx->minv);
- double ymin = NUM2DBL(sery->minv);
- int nubs = NUM2INT(serx->point_type);
- VALUE shcolor = serx->color;
- VALUE rbstroke = serx->strokes;
- int strokew = NUM2INT(rbstroke);
- if (strokew < 1) strokew = 1;
- shoes_color *color;
- Data_Get_Struct(shcolor, shoes_color, color);
-
- int obvs = RARRAY_LEN(serx->values);
- for (i = 0; i < obvs; i++) {
- double xval, yval;
- xval = NUM2DBL(rb_ary_entry(serx->values, i));
- yval = NUM2DBL(rb_ary_entry(sery->values, i));
- //printf("scatter x: %f, y: %f\n", xval, yval);
- }
-
- double yScale = height / (ymax - ymin);
- double xScale = width / (xmax - xmin);
- cairo_set_source_rgba(cr, color->r / 255.0, color->g / 255.0,
- color->b / 255.0, color->a / 255.0);
- for (i = 0; i < obvs; i++) {
- VALUE rbx = rb_ary_entry(serx->values, i);
- double xval = NUM2DBL(rbx);
- VALUE rby = rb_ary_entry(sery->values, i);
- double yval = NUM2DBL(rby);
- long x = roundl((xval - xmin) * xScale);
- long y = height - roundl((yval - ymin) * yScale);
- x += left;
- y += top;
- //printf("x: %f, y: %f --> x: %i px, y: %i, px\n", xval, yval, x, y);
- // lets draw a nub at x, y
- cairo_move_to(cr, x, y);
- shoes_plot_draw_nub(cr, plot, x, y, nubs, strokew + 2);
- }
- cairo_stroke(cr);
- shoes_plot_set_cairo_default(cr, plot);
+void shoes_plot_draw_scatter_pts(cairo_t *cr, shoes_plot *plot) {
+ // first series (x) controls graphical settings.
+ if (plot->seriescnt != 2)
+ return; // we don't have just two series
+ int i;
+ int top,left,bottom,right;
+ left = plot->graph_x;
+ top = plot->graph_y;
+ right = plot->graph_w;
+ bottom = plot->graph_h;
+ int height = bottom - top;
+ int width = right - left;
+ VALUE rbxser, rbyser;
+ shoes_chart_series *serx, *sery;
+ rbxser = rb_ary_entry(plot->series, 0);
+ Data_Get_Struct(rbxser, shoes_chart_series, serx);
+ rbyser = rb_ary_entry(plot->series, 1);
+ Data_Get_Struct(rbyser, shoes_chart_series, sery);
+
+ double xmax = NUM2DBL(serx->maxv);
+ double ymax = NUM2DBL(sery->maxv);
+ double xmin = NUM2DBL(serx->minv);
+ double ymin = NUM2DBL(sery->minv);
+ int nubs = NUM2INT(serx->point_type);
+ VALUE shcolor = serx->color;
+ VALUE rbstroke = serx->strokes;
+ int strokew = NUM2INT(rbstroke);
+ if (strokew < 1) strokew = 1;
+ shoes_color *color;
+ Data_Get_Struct(shcolor, shoes_color, color);
+
+ int obvs = RARRAY_LEN(serx->values);
+ for (i = 0; i < obvs; i++) {
+ double xval, yval;
+ xval = NUM2DBL(rb_ary_entry(serx->values, i));
+ yval = NUM2DBL(rb_ary_entry(sery->values, i));
+ //printf("scatter x: %f, y: %f\n", xval, yval);
+ }
+
+ double yScale = height / (ymax - ymin);
+ double xScale = width / (xmax - xmin);
+ cairo_set_source_rgba(cr, color->r / 255.0, color->g / 255.0,
+ color->b / 255.0, color->a / 255.0);
+ for (i = 0; i < obvs; i++) {
+ VALUE rbx = rb_ary_entry(serx->values, i);
+ double xval = NUM2DBL(rbx);
+ VALUE rby = rb_ary_entry(sery->values, i);
+ double yval = NUM2DBL(rby);
+ long x = roundl((xval - xmin) * xScale);
+ long y = height - roundl((yval - ymin) * yScale);
+ x += left;
+ y += top;
+ //printf("x: %f, y: %f --> x: %i px, y: %i, px\n", xval, yval, x, y);
+ // lets draw a nub at x, y
+ cairo_move_to(cr, x, y);
+ shoes_plot_draw_nub(cr, plot, x, y, nubs, strokew + 2);
+ }
+ cairo_stroke(cr);
+ shoes_plot_set_cairo_default(cr, plot);
}
-static void shoes_plot_scatter_ticks_and_labels(cairo_t *cr, shoes_plot *plot)
-{
- int top, left, bottom, right; // these are cairo abs for plot->graph
- int width, height; // full plot space so it includes everything
- int range;
- int h_padding = 65;
- int v_padding = 25;
- left = plot->graph_x; top = plot->graph_y;
- right = plot->graph_w; bottom = plot->graph_h;
- range = plot->end_idx - plot->beg_idx;
- width = right - left;
- height = bottom - top;
- h_padding = width / plot->x_ticks; // TODO: rethink.
- v_padding = height / plot->y_ticks;
-
- VALUE rbserx, rbsery;
- shoes_chart_series *serx, *sery;
- rbserx = rb_ary_entry(plot->series, 0);
- rbsery = rb_ary_entry(plot->series, 1);
- Data_Get_Struct(rbserx, shoes_chart_series, serx);
- Data_Get_Struct(rbsery, shoes_chart_series, sery);
- double xmax = NUM2DBL(serx->maxv);
- double ymax = NUM2DBL(sery->maxv);
- double xmin = NUM2DBL(serx->minv);
- double ymin = NUM2DBL(sery->minv);
- /*
- VALUE rbxmax = rb_ary_entry(plot->maxvs, 0);
- VALUE rbymax = rb_ary_entry(plot->maxvs, 1);
- VALUE rbxmin = rb_ary_entry(plot->minvs, 0);
- VALUE rbymin = rb_ary_entry(plot->minvs, 1);
- double xmax = NUM2DBL(rbxmax);
- double ymax = NUM2DBL(rbymax);
- double xmin = NUM2DBL(rbxmin);
- double ymin = NUM2DBL(rbymin);
- */
- double h_scale;
- int h_interval;
- //h_scale = width / (double) (range -1);
- h_scale = width / (double) (range );
- h_interval = (int) ceil(h_padding / h_scale);
- char tstr[10];
-
- // draw x axis - labels and tick marks generated between xmin-->xmax
- int i;
- for (i = 0 ; i < range; i++ ) {
- int x = (int) roundl(i * h_scale);
- x += left;
- long y = bottom;
- if ((i % h_interval) == 0) {
- char rawstr[10];
- // convert i to number in the range of xmin->xmax
- sprintf(rawstr, "%4.2f", xmin + ((xmax - xmin) / range) * i); // Do not trust!!
- shoes_plot_draw_tick(cr, plot, x, y, VERTICALLY);
- shoes_plot_draw_label(cr, plot, x, y, rawstr, BELOW);
+static void shoes_plot_scatter_ticks_and_labels(cairo_t *cr, shoes_plot *plot) {
+ int top, left, bottom, right; // these are cairo abs for plot->graph
+ int width, height; // full plot space so it includes everything
+ int range;
+ int h_padding = 65;
+ int v_padding = 25;
+ left = plot->graph_x;
+ top = plot->graph_y;
+ right = plot->graph_w;
+ bottom = plot->graph_h;
+ range = plot->end_idx - plot->beg_idx;
+ width = right - left;
+ height = bottom - top;
+ h_padding = width / plot->x_ticks; // TODO: rethink.
+ v_padding = height / plot->y_ticks;
+
+ VALUE rbserx, rbsery;
+ shoes_chart_series *serx, *sery;
+ rbserx = rb_ary_entry(plot->series, 0);
+ rbsery = rb_ary_entry(plot->series, 1);
+ Data_Get_Struct(rbserx, shoes_chart_series, serx);
+ Data_Get_Struct(rbsery, shoes_chart_series, sery);
+ double xmax = NUM2DBL(serx->maxv);
+ double ymax = NUM2DBL(sery->maxv);
+ double xmin = NUM2DBL(serx->minv);
+ double ymin = NUM2DBL(sery->minv);
+ /*
+ VALUE rbxmax = rb_ary_entry(plot->maxvs, 0);
+ VALUE rbymax = rb_ary_entry(plot->maxvs, 1);
+ VALUE rbxmin = rb_ary_entry(plot->minvs, 0);
+ VALUE rbymin = rb_ary_entry(plot->minvs, 1);
+ double xmax = NUM2DBL(rbxmax);
+ double ymax = NUM2DBL(rbymax);
+ double xmin = NUM2DBL(rbxmin);
+ double ymin = NUM2DBL(rbymin);
+ */
+ double h_scale;
+ int h_interval;
+ //h_scale = width / (double) (range -1);
+ h_scale = width / (double) (range );
+ h_interval = (int) ceil(h_padding / h_scale);
+ char tstr[10];
+
+ // draw x axis - labels and tick marks generated between xmin-->xmax
+ int i;
+ for (i = 0 ; i < range; i++ ) {
+ int x = (int) roundl(i * h_scale);
+ x += left;
+ long y = bottom;
+ if ((i % h_interval) == 0) {
+ char rawstr[10];
+ // convert i to number in the range of xmin->xmax
+ sprintf(rawstr, "%4.2f", xmin + ((xmax - xmin) / range) * i); // Do not trust!!
+ shoes_plot_draw_tick(cr, plot, x, y, VERTICALLY);
+ shoes_plot_draw_label(cr, plot, x, y, rawstr, BELOW);
+ }
}
- }
- // draw the last label on x
- sprintf(tstr, "%4.2f", xmax);
- shoes_plot_draw_label(cr, plot, right, bottom, tstr, BELOW);
-
-
- // draw y axis - there is only one in a Shoes scatter plot
- double v_scale = height / (ymax - ymin);
- double j;
- int v_interval = (int) ceil(v_padding / v_scale);
- //printf("v_scale: %f, v_interval: %i\n", v_scale, v_interval);
- for (j = ymin ; j < ymax; j += v_interval) {
- int y = (int) (bottom - roundl((j - ymin) * v_scale));
- int x = left;
- sprintf(tstr, "%4.2f", j);
- //printf("hoz left %i, %i, %s\n", (int)x, (int)y, tstr);
- shoes_plot_draw_tick(cr, plot, x, y, HORIZONTALLY);
- shoes_plot_draw_label(cr, plot, x, y, tstr, LEFT);
- }
- // print top label
- sprintf(tstr, "%4.2f", ymax);
- shoes_plot_draw_label(cr, plot, left, top, tstr, LEFT);
-
+ // draw the last label on x
+ sprintf(tstr, "%4.2f", xmax);
+ shoes_plot_draw_label(cr, plot, right, bottom, tstr, BELOW);
+
+
+ // draw y axis - there is only one in a Shoes scatter plot
+ double v_scale = height / (ymax - ymin);
+ double j;
+ int v_interval = (int) ceil(v_padding / v_scale);
+ //printf("v_scale: %f, v_interval: %i\n", v_scale, v_interval);
+ for (j = ymin ; j < ymax; j += v_interval) {
+ int y = (int) (bottom - roundl((j - ymin) * v_scale));
+ int x = left;
+ sprintf(tstr, "%4.2f", j);
+ //printf("hoz left %i, %i, %s\n", (int)x, (int)y, tstr);
+ shoes_plot_draw_tick(cr, plot, x, y, HORIZONTALLY);
+ shoes_plot_draw_label(cr, plot, x, y, tstr, LEFT);
+ }
+ // print top label
+ sprintf(tstr, "%4.2f", ymax);
+ shoes_plot_draw_label(cr, plot, left, top, tstr, LEFT);
+
}
-void shoes_plot_scatter_legend(cairo_t *cr, shoes_plot *plot)
-{
- if (plot->seriescnt != 2) return;
- int top, left, bottom, right;
- int width, height;
- left = plot->place.x; top = plot->graph_h + 5;
- right = plot->place.w; bottom = top + plot->legend_h;
- width = right - left;
- height = bottom - top;
- // scatter has only two series - center the x string [0]
- // try to draw the y string [1] vertically. -fun or groan?
- VALUE rbserx, rbsery;
- shoes_chart_series *serx, *sery;
- rbserx = rb_ary_entry(plot->series, 0);
- rbsery = rb_ary_entry(plot->series, 1);
- Data_Get_Struct(rbserx, shoes_chart_series, serx);
- Data_Get_Struct(rbsery, shoes_chart_series, sery);
- int legend_width = 0;
- int x, y;
-
- char *xstr = RSTRING_PTR(serx->desc);
- PangoLayout *x_layout = pango_cairo_create_layout (cr);
- pango_layout_set_font_description (x_layout, plot->legend_pfd);
- pango_layout_set_text (x_layout, xstr, -1);
- PangoRectangle logical;
- pango_layout_get_pixel_extents (x_layout, NULL, &logical);
- legend_width = logical.width;
-
- int xoffset = (plot->place.w / 2) - (legend_width / 2);
- x = xoffset - (plot->place.dx);
- int yhalf = (plot->legend_h / 2 );
- int yoffset = yhalf;
- y = yoffset;
-
- int baseline = bottom - 5; //TODO: compute baseline better
- shoes_color *color;
- Data_Get_Struct(serx->color, shoes_color, color);
- cairo_set_source_rgba(cr, color->r / 255.0, color->g / 255.0,
- color->b / 255.0, color->a / 255.0);
- cairo_move_to(cr, x, baseline);
- pango_cairo_show_layout(cr, x_layout);
- /*
- * Now the y axis label. Rotate and put on the left side
- * Draw above (in the title area, left or right)??
- *
- */
- char *ystr = RSTRING_PTR(sery->desc);
- cairo_save(cr);
- PangoLayout *y_layout = pango_cairo_create_layout (cr);
- pango_layout_set_font_description (y_layout, plot->legend_pfd);
- pango_layout_set_text (y_layout, ystr, -1);
- pango_layout_get_pixel_extents (y_layout, NULL, &logical);
- Data_Get_Struct(sery->color, shoes_color, color);
- cairo_set_source_rgba(cr, color->r / 255.0, color->g / 255.0,
- color->b / 255.0, color->a / 255.0);
- // since we're drawing text vertically, compute text placement differently
- // It's very confusing (to me, at least).
- int yoff = ((plot->graph_h - plot->graph_y) - logical.width) / 2;
- cairo_move_to(cr, (plot->graph_x - plot->yaxis_offset) + 5,
- plot->graph_h - yoff);
- cairo_rotate(cr, -90.0 / (180.0 / G_PI)); // rotate in radians
- pango_cairo_show_layout(cr, y_layout);
- cairo_restore(cr);
- g_object_unref(x_layout);
- g_object_unref(y_layout);
+void shoes_plot_scatter_legend(cairo_t *cr, shoes_plot *plot) {
+ if (plot->seriescnt != 2) return;
+ int top, left, bottom, right;
+ int width, height;
+ left = plot->place.x;
+ top = plot->graph_h + 5;
+ right = plot->place.w;
+ bottom = top + plot->legend_h;
+ width = right - left;
+ height = bottom - top;
+ // scatter has only two series - center the x string [0]
+ // try to draw the y string [1] vertically. -fun or groan?
+ VALUE rbserx, rbsery;
+ shoes_chart_series *serx, *sery;
+ rbserx = rb_ary_entry(plot->series, 0);
+ rbsery = rb_ary_entry(plot->series, 1);
+ Data_Get_Struct(rbserx, shoes_chart_series, serx);
+ Data_Get_Struct(rbsery, shoes_chart_series, sery);
+ int legend_width = 0;
+ int x, y;
+
+ char *xstr = RSTRING_PTR(serx->desc);
+ PangoLayout *x_layout = pango_cairo_create_layout (cr);
+ pango_layout_set_font_description (x_layout, plot->legend_pfd);
+ pango_layout_set_text (x_layout, xstr, -1);
+ PangoRectangle logical;
+ pango_layout_get_pixel_extents (x_layout, NULL, &logical);
+ legend_width = logical.width;
+
+ int xoffset = (plot->place.w / 2) - (legend_width / 2);
+ x = xoffset - (plot->place.dx);
+ int yhalf = (plot->legend_h / 2 );
+ int yoffset = yhalf;
+ y = yoffset;
+
+ int baseline = bottom - 5; //TODO: compute baseline better
+ shoes_color *color;
+ Data_Get_Struct(serx->color, shoes_color, color);
+ cairo_set_source_rgba(cr, color->r / 255.0, color->g / 255.0,
+ color->b / 255.0, color->a / 255.0);
+ cairo_move_to(cr, x, baseline);
+ pango_cairo_show_layout(cr, x_layout);
+ /*
+ * Now the y axis label. Rotate and put on the left side
+ * Draw above (in the title area, left or right)??
+ *
+ */
+ char *ystr = RSTRING_PTR(sery->desc);
+ cairo_save(cr);
+ PangoLayout *y_layout = pango_cairo_create_layout (cr);
+ pango_layout_set_font_description (y_layout, plot->legend_pfd);
+ pango_layout_set_text (y_layout, ystr, -1);
+ pango_layout_get_pixel_extents (y_layout, NULL, &logical);
+ Data_Get_Struct(sery->color, shoes_color, color);
+ cairo_set_source_rgba(cr, color->r / 255.0, color->g / 255.0,
+ color->b / 255.0, color->a / 255.0);
+ // since we're drawing text vertically, compute text placement differently
+ // It's very confusing (to me, at least).
+ int yoff = ((plot->graph_h - plot->graph_y) - logical.width) / 2;
+ cairo_move_to(cr, (plot->graph_x - plot->yaxis_offset) + 5,
+ plot->graph_h - yoff);
+ cairo_rotate(cr, -90.0 / (180.0 / G_PI)); // rotate in radians
+ pango_cairo_show_layout(cr, y_layout);
+ cairo_restore(cr);
+ g_object_unref(x_layout);
+ g_object_unref(y_layout);
}
-// called at draw time. Calls many other functions.
+// called at draw time. Calls many other functions.
// Whole lotta drawing going on
-// Note: we expand the margins a bit shoe we can draw the label vertically
+// Note: we expand the margins a bit so we can draw the label vertically
void shoes_plot_scatter_draw(cairo_t *cr, shoes_place *place, shoes_plot *self_t) {
- shoes_plot_set_cairo_default(cr, self_t);
- shoes_plot_draw_fill(cr, self_t);
- shoes_plot_draw_title(cr, self_t);
- shoes_plot_draw_caption(cr, self_t);
- if (self_t->boundbox)
- shoes_plot_draw_boundbox(cr, self_t);
- self_t->graph_h = self_t->place.h - (self_t->title_h + self_t->caption_h);
- self_t->graph_y = self_t->title_h + 3;
- self_t->yaxis_offset = 70; // TODO: run TOTO! run!
- self_t->graph_w = self_t->place.w - self_t->yaxis_offset;
- self_t->graph_x = self_t->yaxis_offset;
- if (self_t->seriescnt) {
- // draw box, ticks and x,y labels.
- shoes_plot_scatter_ticks_and_labels(cr, self_t);
- shoes_plot_scatter_legend(cr, self_t);
- shoes_plot_draw_scatter_pts(cr, self_t);
- }
+ shoes_plot_util_adornments(cr, place, self_t, 70);
+ if (self_t->seriescnt) {
+ // draw box, ticks and x,y labels.
+ shoes_plot_scatter_ticks_and_labels(cr, self_t);
+ shoes_plot_scatter_legend(cr, self_t);
+ shoes_plot_draw_scatter_pts(cr, self_t);
+ }
}
diff --git a/shoes/plot/plot_util.c b/shoes/plot/plot_util.c
index 2c129f01..3afde12a 100644
--- a/shoes/plot/plot_util.c
+++ b/shoes/plot/plot_util.c
@@ -1,6 +1,7 @@
-/*
- * plot_util.c
+/*
+ * plot_util.c
*/
+#include "shoes/types/color.h"
#include "shoes/plot/plot.h"
/*
@@ -8,379 +9,395 @@
* If your function changes line_width or color you should probably
* call this to ensure others functions can have a consistent state.
*/
-void shoes_plot_set_cairo_default(cairo_t *cr, shoes_plot *plot)
-{
- cairo_set_source_rgba(cr, 0.01, 0.01, 0.01, 1.0);
- cairo_set_line_width(cr, 1);
+void shoes_plot_set_cairo_default(cairo_t *cr, shoes_plot *plot) {
+ cairo_set_source_rgba(cr, 0.01, 0.01, 0.01, 1.0);
+ cairo_set_line_width(cr, 1);
}
// fill graph area with background color
-void shoes_plot_draw_fill(cairo_t *cr, shoes_plot *plot)
-{
- if (NIL_P(plot->background)) {
- cairo_set_source_rgba(cr, 0.99, 0.99, 0.99, 0.99);
- } else {
- shoes_color *color;
- Data_Get_Struct(plot->background, shoes_color, color);
- cairo_set_source_rgba(cr,
- color->r / 255.0 ,
- color->g / 255.0 ,
- color->b / 255.0 ,
- color->a / 255.0
- );
- }
- cairo_set_line_width(cr, 1);
- cairo_rectangle(cr, 0, 0, plot->place.w, plot->place.h);
- cairo_fill(cr);
- shoes_plot_set_cairo_default(cr, plot);
+void shoes_plot_draw_fill(cairo_t *cr, shoes_plot *plot) {
+ if (NIL_P(plot->background)) {
+ cairo_set_source_rgba(cr, 0.99, 0.99, 0.99, 0.99);
+ } else {
+ shoes_color *color;
+ Data_Get_Struct(plot->background, shoes_color, color);
+ cairo_set_source_rgba(cr,
+ color->r / 255.0,
+ color->g / 255.0,
+ color->b / 255.0,
+ color->a / 255.0
+ );
+ }
+ cairo_set_line_width(cr, 1);
+ cairo_rectangle(cr, 0, 0, plot->place.w, plot->place.h);
+ cairo_fill(cr);
+ shoes_plot_set_cairo_default(cr, plot);
}
void shoes_plot_draw_boundbox(cairo_t *cr, shoes_plot *plot) {
- // draw box around data area (plot->graph_?)
- shoes_plot_set_cairo_default(cr, plot);
- int t,l,b,r;
- l = plot->graph_x; t = plot->graph_y;
- r = plot->graph_w; b = plot->graph_h;
- cairo_move_to(cr, l, t);
- cairo_line_to(cr, r, t); // across top
- cairo_line_to(cr, r, b); // down right side
- cairo_line_to(cr, l, b); // across bottom
- cairo_line_to(cr, l, t); // up left
- cairo_stroke(cr);
+ // draw box around data area (plot->graph_?)
+ shoes_plot_set_cairo_default(cr, plot);
+ int t,l,b,r;
+ l = plot->graph_x;
+ t = plot->graph_y;
+ r = plot->graph_w;
+ b = plot->graph_h;
+ cairo_move_to(cr, l, t);
+ cairo_line_to(cr, r, t); // across top
+ cairo_line_to(cr, r, b); // down right side
+ cairo_line_to(cr, l, b); // across bottom
+ cairo_line_to(cr, l, t); // up left
+ cairo_stroke(cr);
}
-void shoes_plot_draw_ticks_and_labels(cairo_t *cr, shoes_plot *plot)
-{
- int top, left, bottom, right; // these are cairo abs for plot->graph
- int width, height; // full plot space so it includes everything
- int range;
- int h_padding = 65; // default width of horizontal tick cell TODO: an option in plot->
- int v_padding = 25; // default height of tick TODO: an option in plot->
- left = plot->graph_x; top = plot->graph_y;
- right = plot->graph_w; bottom = plot->graph_h;
- range = plot->end_idx - plot->beg_idx;
- width = right - left;
- height = bottom - top;
- h_padding = width / plot->x_ticks;
- v_padding = height / plot->y_ticks;
-
- double h_scale;
- int h_interval;
- h_scale = width / (double) (range -1);
- h_interval = (int) ceil(h_padding / h_scale);
-
- // draw x axis - labels and tick mark uses series[0]->labels[*] - assumes it's strings
- // in the array -- TODO: allow a proc to be called to create the string. at 'i'
- int i;
- VALUE rbxser;
- shoes_chart_series *serx;
- rbxser = rb_ary_entry(plot->series, 0);
- Data_Get_Struct(rbxser, shoes_chart_series, serx);
- VALUE xobs = serx->labels;
- if (NIL_P(xobs) || TYPE(xobs) != T_ARRAY) rb_raise (rb_eArgError, "xobs must be an array");
-
- for (i = 0 ; i < range; i++ ) {
- int x = (int) roundl(i * h_scale);
- x += left;
- long y = bottom;
- if ((i % h_interval) == 0) {
- char *rawstr;
- VALUE rbstr = rb_ary_entry(xobs, i + plot->beg_idx);
- if (NIL_P(rbstr)) {
- rawstr = " ";
- } else {
- rawstr = RSTRING_PTR(rbstr);
- }
- //printf("x label i: %i, x: %i, y: %i, \"%s\" %i %f \n", i, (int) x, (int) y, rawstr, h_interval, h_scale);
- shoes_plot_draw_tick(cr, plot, x, y, VERTICALLY);
- if (plot->chart_type == LINE_CHART || plot->chart_type == TIMESERIES_CHART)
- shoes_plot_draw_label(cr, plot, x, y, rawstr, BELOW);
+void shoes_plot_draw_ticks_and_labels(cairo_t *cr, shoes_plot *plot) {
+ int top, left, bottom, right; // these are cairo abs for plot->graph
+ int width, height; // full plot space so it includes everything
+ int range;
+ int h_padding = 65; // default width of horizontal tick cell TODO: an option in plot->
+ int v_padding = 25; // default height of tick TODO: an option in plot->
+ left = plot->graph_x;
+ top = plot->graph_y;
+ right = plot->graph_w;
+ bottom = plot->graph_h;
+ range = plot->end_idx - plot->beg_idx;
+ width = right - left;
+ height = bottom - top;
+ h_padding = width / plot->x_ticks;
+ v_padding = height / plot->y_ticks;
+
+ double h_scale;
+ int h_interval;
+ h_scale = width / (double) (range -1);
+ h_interval = (int) ceil(h_padding / h_scale);
+
+ // draw x axis - labels and tick mark uses series[0]->labels[*] - assumes it's strings
+ // in the array -- TODO: allow a proc to be called to create the string. at 'i'
+ int i;
+ VALUE rbxser;
+ shoes_chart_series *serx;
+ rbxser = rb_ary_entry(plot->series, 0);
+ Data_Get_Struct(rbxser, shoes_chart_series, serx);
+ VALUE xobs = serx->labels;
+ if (NIL_P(xobs) || TYPE(xobs) != T_ARRAY) rb_raise (rb_eArgError, "xobs must be an array");
+
+ for (i = 0 ; i < range; i++ ) {
+ int x = (int) roundl(i * h_scale);
+ x += left;
+ long y = bottom;
+ if ((i % h_interval) == 0) {
+ char *rawstr;
+ VALUE rbstr = rb_ary_entry(xobs, i + plot->beg_idx);
+ if (NIL_P(rbstr)) {
+ rawstr = " ";
+ } else {
+ rawstr = RSTRING_PTR(rbstr);
+ }
+ //printf("x label i: %i, x: %i, y: %i, \"%s\" %i %f \n", i, (int) x, (int) y, rawstr, h_interval, h_scale);
+ shoes_plot_draw_tick(cr, plot, x, y, VERTICALLY);
+ if (plot->chart_type == LINE_CHART || plot->chart_type == TIMESERIES_CHART)
+ shoes_plot_draw_label(cr, plot, x, y, rawstr, BELOW);
+ }
}
- }
-
- int j;
- for (j = 0; j < min(2, plot->seriescnt); j++) {
- VALUE rbser = rb_ary_entry(plot->series, j);
- shoes_chart_series *cs;
- Data_Get_Struct(rbser, shoes_chart_series, cs);
- double maximum = NUM2DBL(cs->maxv);
- double minimum = NUM2DBL(cs->minv);
- double v_scale = height / (maximum - minimum);
- int v_interval = (int) ceil(v_padding / v_scale);
- char tstr[16];
- long i;
- for (i = ((long) minimum) + 1 ; i < ((long) roundl(maximum)); i = i + roundl(v_interval)) {
- int y = (int) (bottom - roundl((i - minimum) * v_scale));
- int x = 0;
- sprintf(tstr, "%i", (int)i); // TODO user specificed format?
- if (j == 0) { // left side y presentation
- x = left;
- //printf("hoz left %i, %i, %s\n", (int)x, (int)y,tstr);
- shoes_plot_draw_tick(cr, plot, x, y, HORIZONTALLY);
- shoes_plot_draw_label(cr, plot, x, y, tstr, LEFT);
- } else { // right side y presentation
- x = right;
- shoes_plot_draw_tick(cr, plot, x, y, HORIZONTALLY);
- shoes_plot_draw_label(cr, plot, x, y, tstr, RIGHT);
- }
+
+ int j;
+ for (j = 0; j < min(2, plot->seriescnt); j++) {
+ VALUE rbser = rb_ary_entry(plot->series, j);
+ shoes_chart_series *cs;
+ Data_Get_Struct(rbser, shoes_chart_series, cs);
+ double maximum = NUM2DBL(cs->maxv);
+ double minimum = NUM2DBL(cs->minv);
+ double v_scale = height / (maximum - minimum);
+ int v_interval = (int) ceil(v_padding / v_scale);
+ char tstr[16];
+ long i;
+ for (i = ((long) minimum) + 1 ; i < ((long) roundl(maximum)); i = i + roundl(v_interval)) {
+ int y = (int) (bottom - roundl((i - minimum) * v_scale));
+ int x = 0;
+ sprintf(tstr, "%i", (int)i); // TODO user specificed format?
+ if (j == 0) { // left side y presentation
+ x = left;
+ //printf("hoz left %i, %i, %s\n", (int)x, (int)y,tstr);
+ shoes_plot_draw_tick(cr, plot, x, y, HORIZONTALLY);
+ shoes_plot_draw_label(cr, plot, x, y, tstr, LEFT);
+ } else { // right side y presentation
+ x = right;
+ shoes_plot_draw_tick(cr, plot, x, y, HORIZONTALLY);
+ shoes_plot_draw_label(cr, plot, x, y, tstr, RIGHT);
+ }
+ }
}
- }
}
-void shoes_plot_draw_legend(cairo_t *cr, shoes_plot *plot)
-{
- int top, left, bottom, right;
- int width, height;
- left = plot->place.x; top = plot->graph_h + 5;
- right = plot->place.w; bottom = top + plot->legend_h;
- width = right - left;
- height = bottom - top;
- // TODO: Can some of this done in add/delete series ?
- // One Ugly Mess.
- int i, legend_width = 0;
- int x, y;
- int white_space = 0;
- PangoLayout *layouts[6];
- PangoLayout *space_layout = pango_cairo_create_layout (cr);
- pango_layout_set_font_description (space_layout , plot->legend_pfd);
- pango_layout_set_text (space_layout, " ", -1);
- PangoRectangle space_rect;
- pango_layout_get_pixel_extents (space_layout, NULL, &space_rect);
- white_space = space_rect.width;
- char *strary[6];
- int widary[6];
- for (i = 0; i < 6; i++) {
- strary[i] = NULL;
- widary[i] = 0;
- //layouts[i] = NULL;
- }
- for (i = 0; i < plot->seriescnt; i++) {
- if (i > 1) {
- legend_width += white_space;
+void shoes_plot_draw_legend(cairo_t *cr, shoes_plot *plot) {
+ int top, left, bottom, right;
+ int width, height;
+ left = plot->place.x;
+ top = plot->graph_h + 5;
+ right = plot->place.w;
+ bottom = top + plot->legend_h;
+ width = right - left;
+ height = bottom - top;
+ // TODO: Can some of this done in add/delete series ?
+ // One Ugly Mess.
+ int i, legend_width = 0;
+ int x, y;
+ int white_space = 0;
+ PangoLayout *layouts[6];
+ PangoLayout *space_layout = pango_cairo_create_layout (cr);
+ pango_layout_set_font_description (space_layout, plot->legend_pfd);
+ pango_layout_set_text (space_layout, " ", -1);
+ PangoRectangle space_rect;
+ pango_layout_get_pixel_extents (space_layout, NULL, &space_rect);
+ white_space = space_rect.width;
+ char *strary[6];
+ int widary[6];
+ for (i = 0; i < 6; i++) {
+ strary[i] = NULL;
+ widary[i] = 0;
+ //layouts[i] = NULL;
}
- VALUE cs = rb_ary_entry(plot->series, i);
- shoes_chart_series *ser;
- Data_Get_Struct(cs, shoes_chart_series, ser);
- //rbstr = rb_ary_entry(plot->long_names, i);
- strary[i] = RSTRING_PTR(ser->desc);
- layouts[i] = pango_cairo_create_layout (cr);
- pango_layout_set_font_description (layouts[i], plot->legend_pfd);
- pango_layout_set_text (layouts[i], strary[i], -1);
- PangoRectangle logical;
- pango_layout_get_pixel_extents (layouts[i], NULL, &logical);
- widary[i] = logical.width;
- legend_width += logical.width;
- }
- int xoffset = (plot->place.w / 2) - (legend_width / 2);
- x = xoffset - (plot->place.dx);
- int yhalf = (plot->legend_h / 2 );
- int yoffset = yhalf;
- y = yoffset;
-
- //int pos_x = plot->place.ix + x;
- int baseline = bottom - 5; //TODO: compute baseline better
- // printf("middle? w: %i, l: %i pos_x: %i, strw: %i\n", width, left, pos_x, legend_width);
- cairo_move_to(cr, x, baseline);
- for (i = 0; i < plot->seriescnt; i++) {
- VALUE cs = rb_ary_entry(plot->series, i);
- shoes_chart_series *ser;
- Data_Get_Struct(cs, shoes_chart_series, ser);
- VALUE rbcolor = ser->color;
- shoes_color *color;
- Data_Get_Struct(rbcolor, shoes_color, color);
- cairo_set_source_rgba(cr, color->r / 255.0, color->g / 255.0,
- color->b / 255.0, color->a / 255.0);
- pango_cairo_show_layout(cr, layouts[i]);
- g_object_unref(layouts[i]);
- x += (widary[i] + white_space);
- cairo_move_to(cr, x , baseline);
- }
- g_object_unref(space_layout);
+ for (i = 0; i < plot->seriescnt; i++) {
+ if (i > 1) {
+ legend_width += white_space;
+ }
+ VALUE cs = rb_ary_entry(plot->series, i);
+ shoes_chart_series *ser;
+ Data_Get_Struct(cs, shoes_chart_series, ser);
+ //rbstr = rb_ary_entry(plot->long_names, i);
+ strary[i] = RSTRING_PTR(ser->desc);
+ layouts[i] = pango_cairo_create_layout (cr);
+ pango_layout_set_font_description (layouts[i], plot->legend_pfd);
+ pango_layout_set_text (layouts[i], strary[i], -1);
+ PangoRectangle logical;
+ pango_layout_get_pixel_extents (layouts[i], NULL, &logical);
+ widary[i] = logical.width;
+ legend_width += logical.width;
+ }
+ int xoffset = (plot->place.w / 2) - (legend_width / 2);
+ x = xoffset - (plot->place.dx);
+ int yhalf = (plot->legend_h / 2 );
+ int yoffset = yhalf;
+ y = yoffset;
+
+ //int pos_x = plot->place.ix + x;
+ int baseline = bottom - 5; //TODO: compute baseline better
+ // printf("middle? w: %i, l: %i pos_x: %i, strw: %i\n", width, left, pos_x, legend_width);
+ cairo_move_to(cr, x, baseline);
+ for (i = 0; i < plot->seriescnt; i++) {
+ VALUE cs = rb_ary_entry(plot->series, i);
+ shoes_chart_series *ser;
+ Data_Get_Struct(cs, shoes_chart_series, ser);
+ VALUE rbcolor = ser->color;
+ shoes_color *color;
+ Data_Get_Struct(rbcolor, shoes_color, color);
+ cairo_set_source_rgba(cr, color->r / 255.0, color->g / 255.0,
+ color->b / 255.0, color->a / 255.0);
+ pango_cairo_show_layout(cr, layouts[i]);
+ g_object_unref(layouts[i]);
+ x += (widary[i] + white_space);
+ cairo_move_to(cr, x, baseline);
+ }
+ g_object_unref(space_layout);
}
void shoes_plot_draw_tick(cairo_t *cr, shoes_plot *plot,
- int x, int y, int orientation)
-{
- if (plot->auto_grid == 0) return;
- if (orientation == VERTICALLY) {
- cairo_move_to(cr, x, y);
- cairo_line_to(cr, x, plot->graph_y);
- } else if (orientation == HORIZONTALLY) {
- cairo_move_to(cr, x, y);
- cairo_line_to(cr, plot->graph_w, y);
- } else {
- printf("FAIL: shoes_plot_draw_tick orientation\n");
- }
- cairo_stroke(cr);
+ int x, int y, int orientation) {
+ if (plot->auto_grid == 0) return;
+ if (orientation == VERTICALLY) {
+ cairo_move_to(cr, x, y);
+ cairo_line_to(cr, x, plot->graph_y);
+ } else if (orientation == HORIZONTALLY) {
+ cairo_move_to(cr, x, y);
+ cairo_line_to(cr, plot->graph_w, y);
+ } else {
+ printf("FAIL: shoes_plot_draw_tick orientation\n");
+ }
+ cairo_stroke(cr);
}
void shoes_plot_draw_label(cairo_t *cr, shoes_plot *plot,
- int x, int y, char *str, int where)
-{
- // TODO: Font was previously set to Helvetica 12 and color was setup
- // keep them for now
+ int x, int y, char *str, int where) {
+ // TODO: Font was previously set to Helvetica 12 and color was setup
+ // keep them for now
- cairo_font_extents_t ft; // TODO: pangocairo way
- cairo_font_extents(cr, &ft);
- int str_h = (int) ceil(ft.height);
- PangoLayout *layout = pango_cairo_create_layout (cr);
- pango_layout_set_font_description (layout , plot->label_pfd);
- pango_layout_set_text (layout, str, -1);
- PangoRectangle ct;
- pango_layout_get_pixel_extents (layout, NULL, &ct);
- int str_w = ct.width;
- int newx = 0;
- int newy = 0;
- if (where == LEFT) { // left side y-axis
- newx = x - (str_w + 3) - 1 ;
- newy = y - (str_h / 2);
- } else if (where == RIGHT) { // right side y-axis
- newx = x;
- newy = y - (str_h / 2);
- //printf("lbl rightx: %i, y: %i, %s\n", (int)newx, (int)newy, str);
- } else if (where == BELOW) { // bottom side x axis
- newx = x - (str_w / 2);
- newy = y + (str_h / 2);
- } else {
- printf("FAIL: shoes_plot_draw_label 'where ?'\n");
- }
- cairo_move_to(cr, newx, newy);
- pango_cairo_show_layout(cr, layout);
- g_object_unref(layout);
- // printf("TODO: shoes_plot_draw_label called\n");
+ cairo_font_extents_t ft; // TODO: pangocairo way
+ cairo_font_extents(cr, &ft);
+ int str_h = (int) ceil(ft.height);
+ PangoLayout *layout = pango_cairo_create_layout (cr);
+ pango_layout_set_font_description (layout, plot->label_pfd);
+ pango_layout_set_text (layout, str, -1);
+ PangoRectangle ct;
+ pango_layout_get_pixel_extents (layout, NULL, &ct);
+ int str_w = ct.width;
+ int newx = 0;
+ int newy = 0;
+ if (where == LEFT) { // left side y-axis
+ newx = x - (str_w + 3) - 1 ;
+ newy = y - (str_h / 2);
+ } else if (where == RIGHT) { // right side y-axis
+ newx = x;
+ newy = y - (str_h / 2);
+ //printf("lbl rightx: %i, y: %i, %s\n", (int)newx, (int)newy, str);
+ } else if (where == BELOW) { // bottom side x axis
+ newx = x - (str_w / 2);
+ newy = y + (str_h / 2);
+ } else {
+ printf("FAIL: shoes_plot_draw_label 'where ?'\n");
+ }
+ cairo_move_to(cr, newx, newy);
+ pango_cairo_show_layout(cr, layout);
+ g_object_unref(layout);
+ // printf("TODO: shoes_plot_draw_label called\n");
}
-void shoes_plot_draw_title(cairo_t *cr, shoes_plot *plot)
-{
- char *str = RSTRING_PTR(plot->title);
- int x, y;
- PangoLayout *layout = pango_cairo_create_layout (cr);
- pango_layout_set_font_description (layout, plot->title_pfd);
- pango_layout_set_text (layout, str, -1);
- PangoRectangle logical;
- pango_layout_get_pixel_extents (layout, NULL, &logical);
- int xoffset = (plot->place.w / 2) - (logical.width / 2);
- x = xoffset - (plot->place.dx);
- int yhalf = (plot->title_h / 2 );
- int yoffset = yhalf;
- y = yoffset;
- if (plot->chart_type == PIE_CHART)
- y -= 8;
- cairo_move_to(cr, x, y);
- pango_cairo_show_layout (cr, layout);
+void shoes_plot_draw_title(cairo_t *cr, shoes_plot *plot) {
+ char *str = RSTRING_PTR(plot->title);
+ int x, y;
+ PangoLayout *layout = pango_cairo_create_layout (cr);
+ pango_layout_set_font_description (layout, plot->title_pfd);
+ pango_layout_set_text (layout, str, -1);
+ PangoRectangle logical;
+ pango_layout_get_pixel_extents (layout, NULL, &logical);
+ int xoffset = (plot->place.w / 2) - (logical.width / 2);
+ x = xoffset - (plot->place.dx);
+ int yhalf = (plot->title_h / 2 );
+ int yoffset = yhalf;
+ y = yoffset;
+ if (plot->chart_type == PIE_CHART)
+ y -= 8;
+ cairo_move_to(cr, x, y);
+ pango_cairo_show_layout (cr, layout);
}
-void shoes_plot_draw_caption(cairo_t *cr, shoes_plot *plot)
-{
- char *str = RSTRING_PTR(plot->caption);
- int x, y;
- PangoLayout *layout = pango_cairo_create_layout (cr);
- pango_layout_set_font_description (layout, plot->caption_pfd);
- pango_layout_set_text (layout, str, -1);
- PangoRectangle logical;
- pango_layout_get_pixel_extents (layout, NULL, &logical);
- int xoffset = (plot->place.w / 2) - (logical.width / 2);
- x = xoffset - (plot->place.dx);
-
- int yhalf = (plot->caption_h / 2 );
- int yoffset = yhalf + logical.height;
- y = plot->place.ih;
- y -= yoffset;
- cairo_move_to(cr, x, y);
- pango_cairo_show_layout (cr, layout);
+void shoes_plot_draw_caption(cairo_t *cr, shoes_plot *plot) {
+ char *str = RSTRING_PTR(plot->caption);
+ int x, y;
+ PangoLayout *layout = pango_cairo_create_layout (cr);
+ pango_layout_set_font_description (layout, plot->caption_pfd);
+ pango_layout_set_text (layout, str, -1);
+ PangoRectangle logical;
+ pango_layout_get_pixel_extents (layout, NULL, &logical);
+ int xoffset = (plot->place.w / 2) - (logical.width / 2);
+ x = xoffset - (plot->place.dx);
+
+ int yhalf = (plot->caption_h / 2 );
+ int yoffset = yhalf + logical.height;
+ //y = plot->place.ih;
+ y = plot->place.h;
+ //fprintf(stderr, "caption y = %i\n", y);
+ y -= yoffset;
+ cairo_move_to(cr, x, y);
+ pango_cairo_show_layout (cr, layout);
}
-void shoes_plot_draw_nub(cairo_t *cr, shoes_plot *plot, double x, double y, int nubt, int szhint )
-{
-
- shoes_color *bgcolor;
- Data_Get_Struct(plot->background, shoes_color, bgcolor);
- switch (nubt) {
- case NUB_NONE:
- return; // probably shouldn't happen but just in case
- case NUB_DOT:
- cairo_save(cr);
- cairo_arc(cr, x, y, szhint, 0.0, 2*M_PI);
- cairo_stroke_preserve(cr);
- cairo_fill(cr);
- cairo_restore(cr);
- break;
- case NUB_CIRCLE:
- cairo_arc(cr, x, y, szhint, 0.0, 2*M_PI);
- cairo_stroke_preserve(cr);
- cairo_save(cr);
- cairo_set_source_rgba(cr, bgcolor->r / 255.0, bgcolor->g / 255.0,
- bgcolor->b / 255.0, 1.0);
- cairo_fill(cr);
- cairo_restore(cr);
- break;
- case NUB_BOX:
- cairo_rectangle(cr, x-1, y-1, szhint, szhint);
- cairo_stroke_preserve(cr);
- cairo_fill(cr);
- break;
- case NUB_RECT:
- cairo_rectangle(cr, x-1, y-1, szhint, szhint);
- cairo_stroke_preserve(cr);
- cairo_save(cr);
- cairo_set_source_rgba(cr, bgcolor->r / 255.0, bgcolor->g / 255.0,
- bgcolor->b / 255.0, 1.0);
- cairo_fill(cr);
- cairo_restore(cr);
- break;
- default: { // TODO: The hard way to draw a rect, line chart uses this until bug fixed
- int sz = 2;
- cairo_move_to(cr, x - sz, y - sz);
- cairo_line_to(cr, x + sz, y - sz);
- cairo_move_to(cr, x - sz, y - sz);
- cairo_line_to(cr, x - sz, y + sz);
- cairo_move_to(cr, x + sz, y + sz);
- cairo_line_to(cr, x + sz, y - sz);
- cairo_move_to(cr, x + sz, y + sz);
- cairo_line_to(cr, x - sz, y + sz);
- cairo_move_to(cr, x, y); // back to center point.
+void shoes_plot_draw_nub(cairo_t *cr, shoes_plot *plot, double x, double y, int nubt, int szhint ) {
+
+ shoes_color *bgcolor;
+ Data_Get_Struct(plot->background, shoes_color, bgcolor);
+ switch (nubt) {
+ case NUB_NONE:
+ return; // probably shouldn't happen but just in case
+ case NUB_DOT:
+ cairo_save(cr);
+ cairo_arc(cr, x, y, szhint, 0.0, 2*M_PI);
+ cairo_stroke_preserve(cr);
+ cairo_fill(cr);
+ cairo_restore(cr);
+ break;
+ case NUB_CIRCLE:
+ cairo_arc(cr, x, y, szhint, 0.0, 2*M_PI);
+ cairo_stroke_preserve(cr);
+ cairo_save(cr);
+ cairo_set_source_rgba(cr, bgcolor->r / 255.0, bgcolor->g / 255.0,
+ bgcolor->b / 255.0, 1.0);
+ cairo_fill(cr);
+ cairo_restore(cr);
+ break;
+ case NUB_BOX:
+ cairo_rectangle(cr, x-1, y-1, szhint, szhint);
+ cairo_stroke_preserve(cr);
+ cairo_fill(cr);
+ break;
+ case NUB_RECT:
+ cairo_rectangle(cr, x-1, y-1, szhint, szhint);
+ cairo_stroke_preserve(cr);
+ cairo_save(cr);
+ cairo_set_source_rgba(cr, bgcolor->r / 255.0, bgcolor->g / 255.0,
+ bgcolor->b / 255.0, 1.0);
+ cairo_fill(cr);
+ cairo_restore(cr);
+ break;
+ default: { // TODO: The hard way to draw a rect, line chart uses this until bug fixed
+ int sz = 2;
+ cairo_move_to(cr, x - sz, y - sz);
+ cairo_line_to(cr, x + sz, y - sz);
+ cairo_move_to(cr, x - sz, y - sz);
+ cairo_line_to(cr, x - sz, y + sz);
+ cairo_move_to(cr, x + sz, y + sz);
+ cairo_line_to(cr, x + sz, y - sz);
+ cairo_move_to(cr, x + sz, y + sz);
+ cairo_line_to(cr, x - sz, y + sz);
+ cairo_move_to(cr, x, y); // back to center point.
+ }
}
- }
}
// initialize the default colors. Yes it could be a chart option. TODO ?
-void shoes_plot_util_default_colors(shoes_plot *plot)
-{
- rb_ary_store(plot->default_colors, 0, shoes_hash_get(cColors, rb_intern("blue")));
- rb_ary_store(plot->default_colors, 1, shoes_hash_get(cColors, rb_intern("red")));
- rb_ary_store(plot->default_colors, 2, shoes_hash_get(cColors, rb_intern("green")));
- rb_ary_store(plot->default_colors, 3, shoes_hash_get(cColors, rb_intern("coral")));
- rb_ary_store(plot->default_colors, 4, shoes_hash_get(cColors, rb_intern("purple")));
- rb_ary_store(plot->default_colors, 5, shoes_hash_get(cColors, rb_intern("orange")));
- rb_ary_store(plot->default_colors, 6, shoes_hash_get(cColors, rb_intern("aqua")));
- rb_ary_store(plot->default_colors, 7, shoes_hash_get(cColors, rb_intern("brown")));
- rb_ary_store(plot->default_colors, 8, shoes_hash_get(cColors, rb_intern("darkolive")));
- rb_ary_store(plot->default_colors, 9, shoes_hash_get(cColors, rb_intern("hotpink")));
- rb_ary_store(plot->default_colors, 10, shoes_hash_get(cColors, rb_intern("lightsky")));
- rb_ary_store(plot->default_colors, 11, shoes_hash_get(cColors, rb_intern("greenyellow")));
- rb_ary_store(plot->default_colors, 12, shoes_hash_get(cColors, rb_intern("gray")));
- rb_ary_store(plot->default_colors, 13, shoes_hash_get(cColors, rb_intern("black")));
+void shoes_plot_util_default_colors(shoes_plot *plot) {
+ rb_ary_store(plot->default_colors, 0, shoes_hash_get(cColors, rb_intern("blue")));
+ rb_ary_store(plot->default_colors, 1, shoes_hash_get(cColors, rb_intern("red")));
+ rb_ary_store(plot->default_colors, 2, shoes_hash_get(cColors, rb_intern("green")));
+ rb_ary_store(plot->default_colors, 3, shoes_hash_get(cColors, rb_intern("coral")));
+ rb_ary_store(plot->default_colors, 4, shoes_hash_get(cColors, rb_intern("purple")));
+ rb_ary_store(plot->default_colors, 5, shoes_hash_get(cColors, rb_intern("orange")));
+ rb_ary_store(plot->default_colors, 6, shoes_hash_get(cColors, rb_intern("aqua")));
+ rb_ary_store(plot->default_colors, 7, shoes_hash_get(cColors, rb_intern("brown")));
+ rb_ary_store(plot->default_colors, 8, shoes_hash_get(cColors, rb_intern("darkolive")));
+ rb_ary_store(plot->default_colors, 9, shoes_hash_get(cColors, rb_intern("hotpink")));
+ rb_ary_store(plot->default_colors, 10, shoes_hash_get(cColors, rb_intern("lightsky")));
+ rb_ary_store(plot->default_colors, 11, shoes_hash_get(cColors, rb_intern("greenyellow")));
+ rb_ary_store(plot->default_colors, 12, shoes_hash_get(cColors, rb_intern("gray")));
+ rb_ary_store(plot->default_colors, 13, shoes_hash_get(cColors, rb_intern("black")));
}
int shoes_plot_util_quadrant(double angle) {
if ((0 <= angle) && (angle < 0.5 * SHOES_PI)) {
- // first quadrant
- return QUAD_ONE;
- } else if ((0.5 * SHOES_PI <= angle) && (angle < SHOES_PI)) {
- // second quadrant
- return QUAD_TWO;
- } else if ((SHOES_PI <= angle) && (angle < 1.5 * SHOES_PI)) {
- // third quadrant
- return QUAD_THREE;
- } else if ((1.5 * SHOES_PI <= angle) && (angle < 2 * SHOES_PI)) {
- // fourth quadrant
- return QUAD_FOUR;
- } else {
- fprintf(stderr, "plot quadrant - bad news\n");
- return QUAD_ERR;
- }
+ // first quadrant
+ return QUAD_ONE;
+ } else if ((0.5 * SHOES_PI <= angle) && (angle < SHOES_PI)) {
+ // second quadrant
+ return QUAD_TWO;
+ } else if ((SHOES_PI <= angle) && (angle < 1.5 * SHOES_PI)) {
+ // third quadrant
+ return QUAD_THREE;
+ } else if ((1.5 * SHOES_PI <= angle) && (angle < 2 * SHOES_PI)) {
+ // fourth quadrant
+ return QUAD_FOUR;
+ } else {
+ fprintf(stderr, "plot quadrant - bad news\n");
+ return QUAD_ERR;
+ }
+}
+/*
+ * setup plot struct and draw the title, caption, boundary box
+ * called by some plot types at draw time.
+*/
+void shoes_plot_util_adornments(cairo_t *cr , shoes_place *place, shoes_plot *self_t, int tweak ) {
+ // draw widget box and fill with color (nearly white).
+ shoes_plot_set_cairo_default(cr, self_t);
+ shoes_plot_draw_fill(cr, self_t);
+ shoes_plot_draw_title(cr, self_t);
+ shoes_plot_draw_caption(cr, self_t);
+ self_t->graph_h = self_t->place.h - (self_t->title_h + self_t->caption_h);
+ self_t->graph_y = self_t->title_h + 3;
+ self_t->yaxis_offset = tweak;
+ self_t->graph_w = self_t->place.w - self_t->yaxis_offset;
+ self_t->graph_x = self_t->yaxis_offset;
+ if (self_t->boundbox)
+ shoes_plot_draw_boundbox(cr, self_t);
}
diff --git a/shoes/ruby.c b/shoes/ruby.c
index b02e9513..7d6c6a7a 100644
--- a/shoes/ruby.c
+++ b/shoes/ruby.c
@@ -7,19 +7,17 @@
#include "shoes/ruby.h"
#include "shoes/internal.h"
#include "shoes/world.h"
-#include "shoes/native.h"
+#include "shoes/native/native.h"
#include "shoes/version.h"
-#include "shoes/http.h"
-#include "shoes/effects.h"
+#include "shoes/types/types.h"
#include
-VALUE cShoes, cApp, cDialog, cTypes, cShoesWindow, cMouse, cCanvas, cFlow, cStack, cMask, cWidget, cShape, cImage, cEffect, cTimerBase, cTimer, cEvery, cAnim, cPattern, cBorder, cBackground, cTextBlock, cPara, cBanner, cTitle, cSubtitle, cTagline, cCaption, cInscription, cTextClass, cSpan, cDel, cStrong, cSub, cSup, cCode, cEm, cIns, cLinkUrl, cNative, cButton, cCheck, cRadio, cEditLine, cEditBox, cListBox, cProgress, cSlider, cColor, cDownload, cResponse, cColors, cLink, cLinkHover, ssNestSlot;
-VALUE cTextEditBox;
-VALUE cSvgHandle, cSvg, cPlot, cChartSeries;
-VALUE eVlcError, eImageError, eInvMode, eNotImpl;
+VALUE cShoes, cApp, cDialog, cTypes, cShoesWindow, cMouse, cCanvas, cFlow, cStack, cMask, cWidget, cProgress, cColor, cResponse, ssNestSlot;
+VALUE eImageError, eInvMode, eNotImpl;
VALUE reHEX_SOURCE, reHEX3_SOURCE, reRGB_SOURCE, reRGBA_SOURCE, reGRAY_SOURCE, reGRAYA_SOURCE, reLF;
VALUE symAltQuest, symAltSlash, symAltDot, symAltEqual, symAltSemiColon;
-ID s_checked_q, s_perc, s_fraction, s_aref, s_mult, s_donekey;
+ID s_perc, s_fraction, s_aref, s_mult, s_donekey;
+
SYMBOL_DEFS(SYMBOL_ID);
//
@@ -27,32 +25,26 @@ SYMBOL_DEFS(SYMBOL_ID);
//
VALUE instance_eval_proc;
-VALUE
-mfp_instance_eval(VALUE obj, VALUE block)
-{
- return rb_funcall(instance_eval_proc, s_call, 2, obj, block);
+VALUE mfp_instance_eval(VALUE obj, VALUE block) {
+ return rb_funcall(instance_eval_proc, s_call, 2, obj, block);
}
//
// From Guy Decoux [ruby-talk:144098]
//
-static VALUE
-ts_each(VALUE *tmp)
-{
- return rb_funcall2(tmp[0], (ID)tmp[1], (int)tmp[2], (VALUE *)tmp[3]);
+static VALUE ts_each(VALUE *tmp) {
+ return rb_funcall2(tmp[0], (ID)tmp[1], (int)tmp[2], (VALUE *)tmp[3]);
}
-VALUE
-ts_funcall2(VALUE obj, ID meth, int argc, VALUE *argv)
-{
- VALUE tmp[4];
- if (!rb_block_given_p())
- return rb_funcall2(obj, meth, argc, argv);
- tmp[0] = obj;
- tmp[1] = (VALUE)meth;
- tmp[2] = (VALUE)argc;
- tmp[3] = (VALUE)argv;
- return rb_iterate((VALUE(*)(VALUE))ts_each, (VALUE)tmp, CASTHOOK(rb_yield), 0);
+VALUE ts_funcall2(VALUE obj, ID meth, int argc, VALUE *argv) {
+ VALUE tmp[4];
+ if (!rb_block_given_p())
+ return rb_funcall2(obj, meth, argc, argv);
+ tmp[0] = obj;
+ tmp[1] = (VALUE)meth;
+ tmp[2] = (VALUE)argc;
+ tmp[3] = (VALUE)argv;
+ return rb_iterate((VALUE(*)(VALUE))ts_each, (VALUE)tmp, CASTHOOK(rb_yield), 0);
}
#define SET_ARG(o) args->a[n] = o, n = n + 1
@@ -90,225 +82,204 @@ ts_funcall2(VALUE obj, ID meth, int argc, VALUE *argv)
// returns 1 and up, the arg list matched.
// (args.n is set to the arg count, args.a is the args)
//
-static int
-rb_parse_args_p(unsigned char rais, int argc, const VALUE *argv, const char *fmt, rb_arg_list *args)
-{
- int i = 1, m = 0, n = 0, nmin = 0, x = 0;
- const char *p = fmt;
- args->n = 0;
-
- do
- {
- if (*p == ',')
- {
- if ((x && !m) || n < argc) { i++; x = 0; if (nmin == 0 || nmin > n) { nmin = n; } n = 0; }
- else break;
- }
- else if (*p == '|')
- {
- if (!x) m = i;
- }
- else if (*p == 's')
- CHECK_ARG_COERCE(T_STRING, to_str)
- else if (*p == 'S')
- CHECK_ARG_COERCE(T_STRING, to_s)
- else if (*p == 'i')
- CHECK_ARG_COERCE(T_FIXNUM, to_int)
- else if (*p == 'I')
- CHECK_ARG_COERCE(T_FIXNUM, to_i)
- else if (*p == 'f')
- CHECK_ARG_TYPE(T_FLOAT, Qnil)
- else if (*p == 'F')
- CHECK_ARG_COERCE(T_FLOAT, to_f)
- else if (*p == 'a')
- CHECK_ARG_COERCE(T_ARRAY, to_ary)
- else if (*p == 'A')
- CHECK_ARG_COERCE(T_ARRAY, to_a)
- else if (*p == 'k')
- CHECK_ARG_TYPE(T_CLASS, Qnil)
- else if (*p == 'h')
- CHECK_ARG_TYPE(T_HASH, Qnil)
- else if (*p == 'o')
- CHECK_ARG_NOT_NIL()
- else if (*p == '&')
- {
- if (rb_block_given_p())
- SET_ARG(rb_block_proc());
- else
- SET_ARG(Qnil);
- }
+static int rb_parse_args_p(unsigned char rais, int argc, const VALUE *argv, const char *fmt, rb_arg_list *args) {
+ int i = 1, m = 0, n = 0, nmin = 0, x = 0;
+ const char *p = fmt;
+ args->n = 0;
+
+ do {
+ if (*p == ',') {
+ if ((x && !m) || n < argc) {
+ i++;
+ x = 0;
+ if (nmin == 0 || nmin > n) {
+ nmin = n;
+ }
+ n = 0;
+ } else break;
+ } else if (*p == '|') {
+ if (!x) m = i;
+ } else if (*p == 's') {
+ CHECK_ARG_COERCE(T_STRING, to_str)
+ } else if (*p == 'S') {
+ CHECK_ARG_COERCE(T_STRING, to_s)
+ } else if (*p == 'i') {
+ CHECK_ARG_COERCE(T_FIXNUM, to_int)
+ } else if (*p == 'I') {
+ CHECK_ARG_COERCE(T_FIXNUM, to_i)
+ } else if (*p == 'f') {
+ CHECK_ARG_TYPE(T_FLOAT, Qnil)
+ } else if (*p == 'F') {
+ CHECK_ARG_COERCE(T_FLOAT, to_f)
+ } else if (*p == 'a') {
+ CHECK_ARG_COERCE(T_ARRAY, to_ary)
+ } else if (*p == 'A') {
+ CHECK_ARG_COERCE(T_ARRAY, to_a)
+ } else if (*p == 'k') {
+ CHECK_ARG_TYPE(T_CLASS, Qnil)
+ } else if (*p == 'h') {
+ CHECK_ARG_TYPE(T_HASH, Qnil)
+ } else if (*p == 'o') {
+ CHECK_ARG_NOT_NIL()
+ } else if (*p == '&') {
+ if (rb_block_given_p())
+ SET_ARG(rb_block_proc());
+ else
+ SET_ARG(Qnil);
+ }
- //
- // shoes-specific structures
- //
- else if (*p == 'e')
- CHECK_ARG_DATA(shoes_is_element)
- else if (*p == 'E')
- CHECK_ARG_DATA(shoes_is_any)
- else break;
- }
- while (p++);
+ //
+ // shoes-specific structures
+ //
+ else if (*p == 'e') {
+ CHECK_ARG_DATA(shoes_is_element)
+ } else if (*p == 'E') {
+ CHECK_ARG_DATA(shoes_is_any)
+ } else break;
+ } while (p++);
- if (!x && n >= argc)
- m = i;
- if (m)
- args->n = n;
+ if (!x && n >= argc)
+ m = i;
+ if (m)
+ args->n = n;
- // printf("rb_parse_args(%s): %d %d (%d)\n", fmt, m, n, x);
+ // printf("rb_parse_args(%s): %d %d (%d)\n", fmt, m, n, x);
- if (!m && rais)
- {
- if (argc < nmin)
- rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", argc, nmin);
- else
- rb_raise(rb_eArgError, "bad arguments");
- }
+ if (!m && rais) {
+ if (argc < nmin)
+ rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", argc, nmin);
+ else
+ rb_raise(rb_eArgError, "bad arguments");
+ }
- return m;
+ return m;
}
-int
-rb_parse_args(int argc, const VALUE *argv, const char *fmt, rb_arg_list *args)
-{
- return rb_parse_args_p(1, argc, argv, fmt, args);
+int rb_parse_args(int argc, const VALUE *argv, const char *fmt, rb_arg_list *args) {
+ return rb_parse_args_p(1, argc, argv, fmt, args);
}
-int
-rb_parse_args_allow(int argc, const VALUE *argv, const char *fmt, rb_arg_list *args)
-{
- return rb_parse_args_p(0, argc, argv, fmt, args);
+int rb_parse_args_allow(int argc, const VALUE *argv, const char *fmt, rb_arg_list *args) {
+ return rb_parse_args_p(0, argc, argv, fmt, args);
}
-long
-rb_ary_index_of(VALUE ary, VALUE val)
-{
- long i;
+long rb_ary_index_of(VALUE ary, VALUE val) {
+ long i;
- for (i=0; i= 0 && argc != len) {
- rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)",
- argc, len);
- }
-
- switch (len) {
- case -2:
- return (*func)(recv, rb_ary_new4(argc, argv));
- case -1:
- return (*func)(argc, argv, recv);
- case 0:
- return (*func)(recv);
- case 1:
- return (*func)(recv, argv[0]);
- case 2:
- return (*func)(recv, argv[0], argv[1]);
- case 3:
- return (*func)(recv, argv[0], argv[1], argv[2]);
- case 4:
- return (*func)(recv, argv[0], argv[1], argv[2], argv[3]);
- case 5:
- return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4]);
- case 6:
- return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4],
- argv[5]);
- case 7:
- return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4],
- argv[5], argv[6]);
- case 8:
- return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4],
- argv[5], argv[6], argv[7]);
- case 9:
- return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4],
- argv[5], argv[6], argv[7], argv[8]);
- case 10:
- return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4],
- argv[5], argv[6], argv[7], argv[8], argv[9]);
- case 11:
- return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4],
- argv[5], argv[6], argv[7], argv[8], argv[9], argv[10]);
- case 12:
- return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4],
- argv[5], argv[6], argv[7], argv[8], argv[9],
- argv[10], argv[11]);
- case 13:
- return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4],
- argv[5], argv[6], argv[7], argv[8], argv[9], argv[10],
- argv[11], argv[12]);
- case 14:
- return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4],
- argv[5], argv[6], argv[7], argv[8], argv[9], argv[10],
- argv[11], argv[12], argv[13]);
- case 15:
- return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4],
- argv[5], argv[6], argv[7], argv[8], argv[9], argv[10],
- argv[11], argv[12], argv[13], argv[14]);
- default:
- rb_raise(rb_eArgError, "too many arguments (%d)", len);
- break;
- }
- return Qnil; /* not reached */
+inline VALUE call_cfunc(HOOK func, VALUE recv, int len, int argc, VALUE *argv) {
+ if (len >= 0 && argc != len) {
+ rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)",
+ argc, len);
+ }
+
+ switch (len) {
+ case -2:
+ return (*func)(recv, rb_ary_new4(argc, argv));
+ case -1:
+ return (*func)(argc, argv, recv);
+ case 0:
+ return (*func)(recv);
+ case 1:
+ return (*func)(recv, argv[0]);
+ case 2:
+ return (*func)(recv, argv[0], argv[1]);
+ case 3:
+ return (*func)(recv, argv[0], argv[1], argv[2]);
+ case 4:
+ return (*func)(recv, argv[0], argv[1], argv[2], argv[3]);
+ case 5:
+ return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4]);
+ case 6:
+ return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4],
+ argv[5]);
+ case 7:
+ return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4],
+ argv[5], argv[6]);
+ case 8:
+ return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4],
+ argv[5], argv[6], argv[7]);
+ case 9:
+ return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4],
+ argv[5], argv[6], argv[7], argv[8]);
+ case 10:
+ return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4],
+ argv[5], argv[6], argv[7], argv[8], argv[9]);
+ case 11:
+ return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4],
+ argv[5], argv[6], argv[7], argv[8], argv[9], argv[10]);
+ case 12:
+ return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4],
+ argv[5], argv[6], argv[7], argv[8], argv[9],
+ argv[10], argv[11]);
+ case 13:
+ return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4],
+ argv[5], argv[6], argv[7], argv[8], argv[9], argv[10],
+ argv[11], argv[12]);
+ case 14:
+ return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4],
+ argv[5], argv[6], argv[7], argv[8], argv[9], argv[10],
+ argv[11], argv[12], argv[13]);
+ case 15:
+ return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4],
+ argv[5], argv[6], argv[7], argv[8], argv[9], argv[10],
+ argv[11], argv[12], argv[13], argv[14]);
+ default:
+ rb_raise(rb_eArgError, "too many arguments (%d)", len);
+ break;
+ }
+ return Qnil; /* not reached */
}
-typedef struct
-{
- VALUE canvas;
- VALUE block;
- VALUE args;
+typedef struct {
+ VALUE canvas;
+ VALUE block;
+ VALUE args;
} safe_block;
-static VALUE
-shoes_safe_block_call(VALUE rb_sb)
-{
- int i;
- VALUE vargs[10];
- safe_block *sb = (safe_block *)rb_sb;
- for (i = 0; i < RARRAY_LEN(sb->args); i++)
- vargs[i] = rb_ary_entry(sb->args, i);
- return rb_funcall2(sb->block, s_call, (int)RARRAY_LEN(sb->args), vargs);
+static VALUE shoes_safe_block_call(VALUE rb_sb) {
+ int i;
+ VALUE vargs[10];
+ safe_block *sb = (safe_block *)rb_sb;
+ for (i = 0; i < RARRAY_LEN(sb->args); i++)
+ vargs[i] = rb_ary_entry(sb->args, i);
+ return rb_funcall2(sb->block, s_call, (int)RARRAY_LEN(sb->args), vargs);
}
-static VALUE
-shoes_safe_block_exception(VALUE rb_sb, VALUE e)
-{
- safe_block *sb = (safe_block *)rb_sb;
- shoes_canvas_error(sb->canvas, e);
- return Qnil;
+static VALUE shoes_safe_block_exception(VALUE rb_sb, VALUE e) {
+ safe_block *sb = (safe_block *)rb_sb;
+ shoes_canvas_error(sb->canvas, e);
+ return Qnil;
}
-VALUE
-shoes_safe_block(VALUE self, VALUE block, VALUE args)
-{
- safe_block sb;
- VALUE v;
+VALUE shoes_safe_block(VALUE self, VALUE block, VALUE args) {
+ safe_block sb;
+ VALUE v;
- sb.canvas = shoes_find_canvas(self);
- sb.block = block;
- sb.args = args;
- rb_gc_register_address(&args);
+ sb.canvas = shoes_find_canvas(self);
+ sb.block = block;
+ sb.args = args;
+ rb_gc_register_address(&args);
- v = rb_rescue2(CASTHOOK(shoes_safe_block_call), (VALUE)&sb,
- CASTHOOK(shoes_safe_block_exception), (VALUE)&sb, rb_cObject, 0);
- rb_gc_unregister_address(&args);
- return v;
+ v = rb_rescue2(CASTHOOK(shoes_safe_block_call), (VALUE)&sb,
+ CASTHOOK(shoes_safe_block_exception), (VALUE)&sb, rb_cObject, 0);
+ rb_gc_unregister_address(&args);
+ return v;
}
@@ -321,30 +292,27 @@ shoes_safe_block(VALUE self, VALUE block, VALUE args)
** int nv : switch (boolean) to substract or not computed value from base dimension
*/
-int
-shoes_px(VALUE obj, int dv, int pv, int nv)
-{
- int px;
- if (TYPE(obj) == T_STRING) {
- char *ptr = RSTRING_PTR(obj);
- int len = (int)RSTRING_LEN(obj);
- obj = rb_funcall(obj, s_to_i, 0);
- if (len > 1 && ptr[len - 1] == '%')
- {
- obj = rb_funcall(obj, s_mult, 1, rb_float_new(0.01));
+int shoes_px(VALUE obj, int dv, int pv, int nv) {
+ int px;
+ if (TYPE(obj) == T_STRING) {
+ char *ptr = RSTRING_PTR(obj);
+ int len = (int)RSTRING_LEN(obj);
+ obj = rb_funcall(obj, s_to_i, 0);
+ if (len > 1 && ptr[len - 1] == '%') {
+ obj = rb_funcall(obj, s_mult, 1, rb_float_new(0.01));
+ }
}
- }
- if (rb_obj_is_kind_of(obj, rb_cFloat)) {
- px = (int)((double)pv * NUM2DBL(obj));
- } else {
- if (NIL_P(obj))
- px = dv;
- else
- px = NUM2INT(obj);
- if (px < 0 && nv == 1)
- px += pv;
- }
- return px;
+ if (rb_obj_is_kind_of(obj, rb_cFloat)) {
+ px = (int)((double)pv * NUM2DBL(obj));
+ } else {
+ if (NIL_P(obj))
+ px = dv;
+ else
+ px = NUM2INT(obj);
+ if (px < 0 && nv == 1)
+ px += pv;
+ }
+ return px;
}
/* get a coordinate, in pixels, given bounds (left/right or top/bottom)
@@ -353,110 +321,87 @@ shoes_px(VALUE obj, int dv, int pv, int nv)
** int dr : a delta to substract if working with :right or :bottom
*/
-int
-shoes_px2(VALUE attr, ID k1, ID k2, int dv, int dr, int pv)
-{
- int px;
- VALUE obj = shoes_hash_get(attr, k2);
- if (!NIL_P(obj))
- {
- px = shoes_px(obj, 0, pv, 0);
- px = (pv - dr) - px;
- }
- else
- {
- px = shoes_px(shoes_hash_get(attr, k1), dv, pv, 0);
- }
- return px;
+int shoes_px2(VALUE attr, ID k1, ID k2, int dv, int dr, int pv) {
+ int px;
+ VALUE obj = shoes_hash_get(attr, k2);
+ if (!NIL_P(obj)) {
+ px = shoes_px(obj, 0, pv, 0);
+ px = (pv - dr) - px;
+ } else {
+ px = shoes_px(shoes_hash_get(attr, k1), dv, pv, 0);
+ }
+ return px;
}
-VALUE
-shoes_hash_set(VALUE hsh, ID key, VALUE val)
-{
- if (NIL_P(hsh))
- hsh = rb_hash_new();
- rb_hash_aset(hsh, ID2SYM(key), val);
- return hsh;
+VALUE shoes_hash_set(VALUE hsh, ID key, VALUE val) {
+ if (NIL_P(hsh))
+ hsh = rb_hash_new();
+ rb_hash_aset(hsh, ID2SYM(key), val);
+ return hsh;
}
-VALUE
-shoes_hash_get(VALUE hsh, ID key)
-{
- VALUE v;
+VALUE shoes_hash_get(VALUE hsh, ID key) {
+ VALUE v;
- if (TYPE(hsh) == T_HASH)
- {
- v = rb_hash_aref(hsh, ID2SYM(key));
- if (!NIL_P(v)) return v;
- }
+ if (TYPE(hsh) == T_HASH) {
+ v = rb_hash_aref(hsh, ID2SYM(key));
+ if (!NIL_P(v)) return v;
+ }
- return Qnil;
+ return Qnil;
}
-int
-shoes_hash_int(VALUE hsh, ID key, int dn)
-{
- VALUE v = shoes_hash_get(hsh, key);
- if (!NIL_P(v)) return NUM2INT(v);
- return dn;
+int shoes_hash_int(VALUE hsh, ID key, int dn) {
+ VALUE v = shoes_hash_get(hsh, key);
+ if (!NIL_P(v)) return NUM2INT(v);
+ return dn;
}
-double
-shoes_hash_dbl(VALUE hsh, ID key, double dn)
-{
- VALUE v = shoes_hash_get(hsh, key);
- if (!NIL_P(v)) return NUM2DBL(v);
- return dn;
+double shoes_hash_dbl(VALUE hsh, ID key, double dn) {
+ VALUE v = shoes_hash_get(hsh, key);
+ if (!NIL_P(v)) return NUM2DBL(v);
+ return dn;
}
-char *
-shoes_hash_cstr(VALUE hsh, ID key, char *dn)
-{
- VALUE v = shoes_hash_get(hsh, key);
- if (!NIL_P(v)) return RSTRING_PTR(v);
- return dn;
+char * shoes_hash_cstr(VALUE hsh, ID key, char *dn) {
+ VALUE v = shoes_hash_get(hsh, key);
+ if (!NIL_P(v)) return RSTRING_PTR(v);
+ return dn;
}
-VALUE
-rb_str_to_pas(VALUE str)
-{
- VALUE str2;
- char slen[2];
- slen[0] = RSTRING_LEN(str);
- slen[1] = '\0';
- str2 = rb_str_new2(slen);
- rb_str_append(str2, str);
- return str2;
+VALUE rb_str_to_pas(VALUE str) {
+ VALUE str2;
+ char slen[2];
+ slen[0] = RSTRING_LEN(str);
+ slen[1] = '\0';
+ str2 = rb_str_new2(slen);
+ rb_str_append(str2, str);
+ return str2;
}
-void
-shoes_place_exact(shoes_place *place, VALUE attr, int ox, int oy)
-{
- int r;
- VALUE x;
- place->dx = ATTR2(int, attr, displace_left, 0);
- place->dy = ATTR2(int, attr, displace_top, 0);
- place->flags = FLAG_ABSX | FLAG_ABSY;
- place->ix = place->x = ATTR2(int, attr, left, 0) + ox;
- place->iy = place->y = ATTR2(int, attr, top, 0) + oy;
- r = ATTR2(int, attr, radius, 0) * 2;
- place->iw = place->w = ATTR2(int, attr, width, r);
- place->ih = place->h = ATTR2(int, attr, height, place->w);
- x = ATTR(attr, right);
- if (!NIL_P(x)) place->iw = place->w = (NUM2INT(x) + ox) - place->x;
- x = ATTR(attr, bottom);
- if (!NIL_P(x)) place->ih = place->h = (NUM2INT(x) + oy) - place->y;
+void shoes_place_exact(shoes_place *place, VALUE attr, int ox, int oy) {
+ int r;
+ VALUE x;
+ place->dx = ATTR2(int, attr, displace_left, 0);
+ place->dy = ATTR2(int, attr, displace_top, 0);
+ place->flags = FLAG_ABSX | FLAG_ABSY;
+ place->ix = place->x = ATTR2(int, attr, left, 0) + ox;
+ place->iy = place->y = ATTR2(int, attr, top, 0) + oy;
+ r = ATTR2(int, attr, radius, 0) * 2;
+ place->iw = place->w = ATTR2(int, attr, width, r);
+ place->ih = place->h = ATTR2(int, attr, height, place->w);
+ x = ATTR(attr, right);
+ if (!NIL_P(x)) place->iw = place->w = (NUM2INT(x) + ox) - place->x;
+ x = ATTR(attr, bottom);
+ if (!NIL_P(x)) place->ih = place->h = (NUM2INT(x) + oy) - place->y;
- if (RTEST(ATTR(attr, center)))
- {
- place->ix = place->x = place->x - (place->w / 2);
- place->iy = place->y = place->y - (place->h / 2);
- }
+ if (RTEST(ATTR(attr, center))) {
+ place->ix = place->x = place->x - (place->w / 2);
+ place->iy = place->y = place->y - (place->h / 2);
+ }
}
-void
-shoes_place_decide(shoes_place *place, VALUE c, VALUE attr, int dw, int dh, unsigned char rel, int padded)
-{
+void shoes_place_decide(shoes_place *place, VALUE c, VALUE attr, int dw, int dh, unsigned char rel, int padded) {
shoes_canvas *canvas = NULL;
if (!NIL_P(c)) Data_Get_Struct(c, shoes_canvas, canvas);
VALUE ck = rb_obj_class(c);
@@ -468,14 +413,13 @@ shoes_place_decide(shoes_place *place, VALUE c, VALUE attr, int dw, int dh, unsi
VALUE rw = ATTR(attr, width), rh = ATTR(attr, height);
if (NIL_P(rw) && !NIL_P(rh)) { // we have height
- // fetch height in pixels whatever the input (string, float, positive/negative int)
+ // fetch height in pixels whatever the input (string, float, positive/negative int)
int spx = shoes_px(rh, dh, CPH(canvas), 1);
- // compute width with image aspect ratio [(dh == dw) means a square ]
+ // compute width with image aspect ratio [(dh == dw) means a square ]
dw = (dh == dw) ? spx : ROUND(((dh * 1.) / dw) * spx);
dh = spx; // now re-init 'dh' for next calculations
ATTRSET(attr, width, INT2NUM(dw)); // set calculated width
- }
- else if (NIL_P(rh) && !NIL_P(rw)) {
+ } else if (NIL_P(rh) && !NIL_P(rw)) {
int spx = shoes_px(rw, dw, CPW(canvas), 1);
dh = (dh == dw) ? spx : ROUND(((dh * 1.) / dw) * spx);
dw = spx;
@@ -487,4832 +431,443 @@ shoes_place_decide(shoes_place *place, VALUE c, VALUE attr, int dw, int dh, unsi
if (padded || dh == 0) dh += tmargin + bmargin;
if (padded || dw == 0) dw += lmargin + rmargin;
- int testw = dw;
- if (testw == 0) testw = lmargin + 1 + rmargin;
-
- if (!NIL_P(stuck))
- {
- if (stuck == cShoesWindow)
- rel = REL_FLAGS(rel) | REL_WINDOW;
- else if (stuck == cMouse)
- rel = REL_FLAGS(rel) | REL_CURSOR;
- else
- rel = REL_FLAGS(rel) | REL_STICKY;
- }
-
- place->flags = rel;
- place->dx = place->dy = 0;
- if (canvas == NULL)
- {
- place->ix = place->x = 0;
- place->iy = place->y = 0;
- place->iw = place->w = dw;
- place->ih = place->h = dh;
- }
- else
- {
- int cx, cy, ox, oy, tw = dw, th = dh;
-
- switch (REL_COORDS(rel))
- {
- case REL_WINDOW:
- cx = 0; cy = 0;
- ox = 0; oy = canvas->slot->scrolly;
- break;
-
- case REL_CANVAS:
- cx = canvas->cx - CPX(canvas);
- cy = canvas->cy - CPY(canvas);
- ox = CPX(canvas);
- oy = CPY(canvas);
- break;
-
- case REL_CURSOR:
- cx = 0; cy = 0;
- ox = canvas->app->mousex; oy = canvas->app->mousey;
- break;
-
- case REL_TILE:
- cx = 0; cy = 0;
- ox = CPX(canvas);
- oy = CPY(canvas);
- testw = dw = CPW(canvas);
- dh = max(canvas->height, CPH(canvas));
- // Fix #2 ?
- //dh = (max(canvas->height, canvas->fully - CPB(canvas)) - CPY(canvas));
- break;
-
- default:
- cx = 0; cy = 0;
- ox = canvas->cx; oy = canvas->cy;
- if ((REL_COORDS(rel) & REL_STICKY) && shoes_is_element(stuck))
- {
- shoes_element *element;
- Data_Get_Struct(stuck, shoes_element, element);
- ox = element->place.x;
- oy = element->place.y;
+ int testw = dw;
+ if (testw == 0) testw = lmargin + 1 + rmargin;
+
+ if (!NIL_P(stuck)) {
+ if (stuck == cShoesWindow)
+ rel = REL_FLAGS(rel) | REL_WINDOW;
+ else if (stuck == cMouse)
+ rel = REL_FLAGS(rel) | REL_CURSOR;
+ else
+ rel = REL_FLAGS(rel) | REL_STICKY;
+ }
+
+ place->flags = rel;
+ place->dx = place->dy = 0;
+ if (canvas == NULL) {
+ place->ix = place->x = 0;
+ place->iy = place->y = 0;
+ place->iw = place->w = dw;
+ place->ih = place->h = dh;
+ } else {
+ int cx, cy, ox, oy, tw = dw, th = dh;
+
+ switch (REL_COORDS(rel)) {
+ case REL_WINDOW:
+ cx = 0;
+ cy = 0;
+ ox = 0;
+ oy = canvas->slot->scrolly;
+ break;
+
+ case REL_CANVAS:
+ cx = canvas->cx - CPX(canvas);
+ cy = canvas->cy - CPY(canvas);
+ ox = CPX(canvas);
+ oy = CPY(canvas);
+ break;
+
+ case REL_CURSOR:
+ cx = 0;
+ cy = 0;
+ ox = canvas->app->mousex;
+ oy = canvas->app->mousey;
+ break;
+
+ case REL_TILE:
+ cx = 0;
+ cy = 0;
+ ox = CPX(canvas);
+ oy = CPY(canvas);
+ testw = dw = CPW(canvas);
+ dh = max(canvas->height, CPH(canvas));
+ // Fix #2 ?
+ //dh = (max(canvas->height, canvas->fully - CPB(canvas)) - CPY(canvas));
+ break;
+
+ default:
+ cx = 0;
+ cy = 0;
+ ox = canvas->cx;
+ oy = canvas->cy;
+ if ((REL_COORDS(rel) & REL_STICKY) && shoes_is_element(stuck)) {
+ shoes_element *element;
+ Data_Get_Struct(stuck, shoes_element, element);
+ ox = element->place.x;
+ oy = element->place.y;
+ }
+ break;
}
- break;
- }
-
- place->w = PX(attr, width, testw, CPW(canvas));
- if (dw == 0 && place->w + (int)canvas->cx > canvas->place.iw) {
- canvas->cx = canvas->endx = CPX(canvas);
- canvas->cy = canvas->endy;
- place->w = canvas->place.iw;
- }
- place->h = PX(attr, height, dh, CPH(canvas));
- if (REL_COORDS(rel) != REL_TILE)
- {
- tw = place->w;
- th = place->h;
- }
- place->x = PX2(attr, left, right, cx, tw, canvas->place.iw) + ox;
- place->y = PX2(attr, top, bottom, cy, th,
- ORIGIN(canvas->place) ? canvas->height : canvas->fully) + oy;
- if (!ORIGIN(canvas->place))
- {
- place->dx = canvas->place.dx;
- place->dy = canvas->place.dy;
- }
- place->dx += PXN(attr, displace_left, 0, CPW(canvas));
- place->dy += PXN(attr, displace_top, 0, CPH(canvas));
+ place->w = PX(attr, width, testw, CPW(canvas));
+ if (dw == 0 && place->w + (int)canvas->cx > canvas->place.iw) {
+ canvas->cx = canvas->endx = CPX(canvas);
+ canvas->cy = canvas->endy;
+ place->w = canvas->place.iw;
+ }
+ place->h = PX(attr, height, dh, CPH(canvas));
- place->flags |= NIL_P(ATTR(attr, left)) && NIL_P(ATTR(attr, right)) ? 0 : FLAG_ABSX;
- place->flags |= NIL_P(ATTR(attr, top)) && NIL_P(ATTR(attr, bottom)) ? 0 : FLAG_ABSY;
- if (REL_COORDS(rel) != REL_TILE && ABSY(*place) == 0 && (ck == cStack || place->x + place->w > CPX(canvas) + canvas->place.iw))
- {
- canvas->cx = place->x = CPX(canvas);
- canvas->cy = place->y = canvas->endy;
+ if (REL_COORDS(rel) != REL_TILE) {
+ tw = place->w;
+ th = place->h;
+ }
+ place->x = PX2(attr, left, right, cx, tw, canvas->place.iw) + ox;
+ place->y = PX2(attr, top, bottom, cy, th,
+ ORIGIN(canvas->place) ? canvas->height : canvas->fully) + oy;
+ if (!ORIGIN(canvas->place)) {
+ place->dx = canvas->place.dx;
+ place->dy = canvas->place.dy;
+ }
+ place->dx += PXN(attr, displace_left, 0, CPW(canvas));
+ place->dy += PXN(attr, displace_top, 0, CPH(canvas));
+
+ place->flags |= NIL_P(ATTR(attr, left)) && NIL_P(ATTR(attr, right)) ? 0 : FLAG_ABSX;
+ place->flags |= NIL_P(ATTR(attr, top)) && NIL_P(ATTR(attr, bottom)) ? 0 : FLAG_ABSY;
+ if (REL_COORDS(rel) != REL_TILE && ABSY(*place) == 0 && (ck == cStack || place->x + place->w > CPX(canvas) + canvas->place.iw)) {
+ canvas->cx = place->x = CPX(canvas);
+ canvas->cy = place->y = canvas->endy;
+ }
}
- }
- place->ix = place->x + lmargin;
- place->iy = place->y + tmargin;
- place->iw = place->w - (lmargin + rmargin);
- //place->iw = (RTEST(ATTR(attr, width))) ? place->w : place->w - (lmargin + rmargin);
- if (place->iw < 0) place->iw = 0;
- place->ih = place->h - (tmargin + bmargin);
- //place->ih = (RTEST(ATTR(attr, height))) ? place->h : place->h - (tmargin + bmargin);
- if (place->ih < 0) place->ih = 0;
+ place->ix = place->x + lmargin;
+ place->iy = place->y + tmargin;
+ place->iw = place->w - (lmargin + rmargin);
+ //place->iw = (RTEST(ATTR(attr, width))) ? place->w : place->w - (lmargin + rmargin);
+ if (place->iw < 0) place->iw = 0;
+ place->ih = place->h - (tmargin + bmargin);
+ //place->ih = (RTEST(ATTR(attr, height))) ? place->h : place->h - (tmargin + bmargin);
+ if (place->ih < 0) place->ih = 0;
- INFO("PLACE: (%d, %d), (%d: %d, %d: %d) [%d, %d] %x\n", place->x, place->y, place->w, place->iw, place->h, place->ih, ABSX(*place), ABSY(*place), place->flags);
+ INFO("PLACE: (%d, %d), (%d: %d, %d: %d) [%d, %d] %x\n", place->x, place->y, place->w, place->iw, place->h, place->ih, ABSX(*place), ABSY(*place), place->flags);
}
//
// shoes_basic routines
//
-VALUE
-shoes_basic_remove(VALUE self)
-{
- GET_STRUCT(basic, self_t);
- shoes_canvas_remove_item(self_t->parent, self, 0, 0);
- shoes_canvas_repaint_all(self_t->parent);
- return self;
-}
-
-unsigned char
-shoes_is_element_p(VALUE ele, unsigned char any)
-{
- void *dmark;
- if (TYPE(ele) != T_DATA)
- return 0;
- dmark = RDATA(ele)->dmark;
- return (dmark == shoes_canvas_mark || dmark == shoes_shape_mark ||
- dmark == shoes_image_mark || dmark == shoes_effect_mark ||
- dmark == shoes_pattern_mark || dmark == shoes_textblock_mark ||
- dmark == shoes_control_mark ||
- (any && (dmark == shoes_http_mark || dmark == shoes_timer_mark ||
- dmark == shoes_color_mark || dmark == shoes_link_mark ||
- dmark == shoes_text_mark))
- );
-}
-
-unsigned char
-shoes_is_element(VALUE ele)
-{
- return shoes_is_element_p(ele, 0);
-}
-
-unsigned char
-shoes_is_any(VALUE ele)
-{
- return shoes_is_element_p(ele, 1);
+VALUE shoes_basic_remove(VALUE self) {
+ GET_STRUCT(basic, self_t);
+ shoes_canvas_remove_item(self_t->parent, self, 0, 0);
+ shoes_canvas_repaint_all(self_t->parent);
+ return self;
}
-void
-shoes_extras_remove_all(shoes_canvas *canvas)
-{
- int i;
- shoes_basic *basic;
- shoes_canvas *parent;
- if (canvas->app == NULL) return;
- for (i = (int)RARRAY_LEN(canvas->app->extras) - 1; i >= 0; i--)
- {
- VALUE ele = rb_ary_entry(canvas->app->extras, i);
- if (!NIL_P(ele)) {
- Data_Get_Struct(ele, shoes_basic, basic);
- Data_Get_Struct(basic->parent, shoes_canvas, parent);
- if (parent == canvas)
- {
- rb_funcall(ele, s_remove, 0);
- rb_ary_delete_at(canvas->app->extras, i);
- }
+unsigned char shoes_is_element_p(VALUE ele, unsigned char any) {
+ void *dmark;
+ if (TYPE(ele) != T_DATA)
+ return 0;
+ dmark = RDATA(ele)->dmark;
+ return (dmark == shoes_canvas_mark || dmark == shoes_shape_mark ||
+ dmark == shoes_image_mark || dmark == shoes_effect_mark ||
+ dmark == shoes_pattern_mark || dmark == shoes_textblock_mark ||
+ dmark == shoes_control_mark ||
+ (any && (dmark == shoes_http_mark || dmark == shoes_timer_mark ||
+ dmark == shoes_color_mark || dmark == shoes_link_mark ||
+ dmark == shoes_text_mark))
+ );
+}
+
+unsigned char shoes_is_element(VALUE ele) {
+ return shoes_is_element_p(ele, 0);
+}
+
+unsigned char shoes_is_any(VALUE ele) {
+ return shoes_is_element_p(ele, 1);
+}
+
+void shoes_extras_remove_all(shoes_canvas *canvas) {
+ int i;
+ shoes_basic *basic;
+ shoes_canvas *parent;
+ if (canvas->app == NULL) return;
+ for (i = (int)RARRAY_LEN(canvas->app->extras) - 1; i >= 0; i--) {
+ VALUE ele = rb_ary_entry(canvas->app->extras, i);
+ if (!NIL_P(ele)) {
+ Data_Get_Struct(ele, shoes_basic, basic);
+ Data_Get_Struct(basic->parent, shoes_canvas, parent);
+ if (parent == canvas) {
+ rb_funcall(ele, s_remove, 0);
+ rb_ary_delete_at(canvas->app->extras, i);
+ }
+ }
}
- }
}
-void
-shoes_ele_remove_all(VALUE contents)
-{
- if (!NIL_P(contents))
- {
- long i;
- VALUE ary;
- ary = rb_ary_dup(contents);
- rb_gc_register_address(&ary);
- for (i = 0; i < RARRAY_LEN(ary); i++)
- if (!NIL_P(rb_ary_entry(ary, i)))
- rb_funcall(rb_ary_entry(ary, i), s_remove, 0);
- rb_gc_unregister_address(&ary);
- rb_ary_clear(contents);
- }
+void shoes_ele_remove_all(VALUE contents) {
+ if (!NIL_P(contents)) {
+ long i;
+ VALUE ary;
+ ary = rb_ary_dup(contents);
+ rb_gc_register_address(&ary);
+ for (i = 0; i < RARRAY_LEN(ary); i++)
+ if (!NIL_P(rb_ary_entry(ary, i)))
+ rb_funcall(rb_ary_entry(ary, i), s_remove, 0);
+ rb_gc_unregister_address(&ary);
+ rb_ary_clear(contents);
+ }
}
-void
-shoes_cairo_arc(cairo_t *cr, double x, double y, double w, double h, double a1, double a2)
-{
- cairo_translate(cr, x, y);
- cairo_scale(cr, w / 2., h / 2.);
- cairo_arc(cr, 0., 0., 1., a1, a2);
+void shoes_cairo_arc(cairo_t *cr, double x, double y, double w, double h, double a1, double a2) {
+ cairo_translate(cr, x, y);
+ cairo_scale(cr, w / 2., h / 2.);
+ cairo_arc(cr, 0., 0., 1., a1, a2);
}
-void
-shoes_cairo_rect(cairo_t *cr, double x, double y, double w, double h, double r)
-{
- double rc = r * BEZIER;
- cairo_move_to(cr, x + r, y);
- cairo_rel_line_to(cr, w - 2 * r, 0.0);
- if (r != 0.) cairo_rel_curve_to(cr, rc, 0.0, r, rc, r, r);
- cairo_rel_line_to(cr, 0, h - 2 * r);
- if (r != 0.) cairo_rel_curve_to(cr, 0.0, rc, rc - r, r, -r, r);
- cairo_rel_line_to(cr, -w + 2 * r, 0);
- if (r != 0.) cairo_rel_curve_to(cr, -rc, 0, -r, -rc, -r, -r);
- cairo_rel_line_to(cr, 0, -h + 2 * r);
- if (r != 0.) cairo_rel_curve_to(cr, 0.0, -rc, r - rc, -r, r, -r);
- cairo_close_path(cr);
+void shoes_cairo_rect(cairo_t *cr, double x, double y, double w, double h, double r) {
+ double rc = r * BEZIER;
+ cairo_move_to(cr, x + r, y);
+ cairo_rel_line_to(cr, w - 2 * r, 0.0);
+ if (r != 0.) cairo_rel_curve_to(cr, rc, 0.0, r, rc, r, r);
+ cairo_rel_line_to(cr, 0, h - 2 * r);
+ if (r != 0.) cairo_rel_curve_to(cr, 0.0, rc, rc - r, r, -r, r);
+ cairo_rel_line_to(cr, -w + 2 * r, 0);
+ if (r != 0.) cairo_rel_curve_to(cr, -rc, 0, -r, -rc, -r, -r);
+ cairo_rel_line_to(cr, 0, -h + 2 * r);
+ if (r != 0.) cairo_rel_curve_to(cr, 0.0, -rc, r - rc, -r, r, -r);
+ cairo_close_path(cr);
}
-void
-shoes_control_hide_ref(SHOES_CONTROL_REF ref)
-{
- if (ref != NULL) shoes_native_control_hide(ref);
-}
+VALUE shoes_app_method_missing(int argc, VALUE *argv, VALUE self) {
+ VALUE cname, canvas;
+ GET_STRUCT(app, app);
-void
-shoes_control_show_ref(SHOES_CONTROL_REF ref)
-{
- if (ref != NULL) shoes_native_control_show(ref);
+ cname = argv[0];
+ canvas = rb_ary_entry(app->nesting, RARRAY_LEN(app->nesting) - 1);
+ if (!NIL_P(canvas) && rb_respond_to(canvas, SYM2ID(cname)))
+ return ts_funcall2(canvas, SYM2ID(cname), argc - 1, argv + 1);
+ return shoes_color_method_missing(argc, argv, self);
}
-//
-// Macros for setting up drawing
-//
-#define SETUP(self_type, rel, dw, dh) \
- self_type *self_t; \
- shoes_place place; \
- shoes_canvas *canvas; \
- Data_Get_Struct(self, self_type, self_t); \
- Data_Get_Struct(c, shoes_canvas, canvas); \
- if (ATTR(self_t->attr, hidden) == Qtrue) return self; \
- shoes_place_decide(&place, c, self_t->attr, dw, dh, rel, REL_COORDS(rel) == REL_CANVAS)
-
-#define SETUP_CONTROL(dh, dw, flex) \
- char *msg = ""; \
- int len = dw ? dw : 200; \
- shoes_control *self_t; \
- shoes_canvas *canvas; \
- shoes_place place; \
- VALUE text = Qnil, ck = rb_obj_class(c); \
- Data_Get_Struct(self, shoes_control, self_t); \
- Data_Get_Struct(c, shoes_canvas, canvas); \
- text = ATTR(self_t->attr, text); \
- if (!NIL_P(text)) { \
- text = shoes_native_to_s(text); \
- msg = RSTRING_PTR(text); \
- if (flex) len = ((int)RSTRING_LEN(text) * 8) + 32; \
- } \
- shoes_place_decide(&place, c, self_t->attr, len, 28 + dh, REL_CANVAS, TRUE)
-
-#define FINISH() \
- if (!ABSY(place)) { \
- canvas->cx += place.w; \
- canvas->cy = place.y; \
- canvas->endx = canvas->cx; \
- canvas->endy = max(canvas->endy, place.y + place.h); \
- } \
- if (ck == cStack) { \
- canvas->cx = CPX(canvas); \
- canvas->cy = canvas->endy; \
- }
-
-#define PATTERN_SCALE(self_t, place, sw) \
- if (self_t->cached == NULL) \
- { \
- double woff = abs(place.iw) + (sw * 2.), hoff = abs(place.ih) + (sw * 2.); \
- cairo_pattern_get_matrix(PATTERN(self_t), &matrix1); \
- cairo_pattern_get_matrix(PATTERN(self_t), &matrix2); \
- if (cairo_pattern_get_type(PATTERN(self_t)) == CAIRO_PATTERN_TYPE_RADIAL) \
- cairo_matrix_translate(&matrix2, (-place.ix * 1.) / woff, (-place.iy * 1.) / hoff); \
- cairo_matrix_scale(&matrix2, 1. / woff, 1. / hoff); \
- if (sw != 0.0) cairo_matrix_translate(&matrix2, sw, sw); \
- cairo_pattern_set_matrix(PATTERN(self_t), &matrix2); \
- }
-
-#define PATTERN_RESET(self_t) \
- if (self_t->cached == NULL) \
- { \
- cairo_pattern_set_matrix(PATTERN(self_t), &matrix1); \
- }
+PLACE_COMMON(canvas)
+TRANS_COMMON(canvas, 0);
-#define CAP_SET(cr, cap) \
- if (cap == s_project) \
- cairo_set_line_cap(cr, CAIRO_LINE_CAP_SQUARE); \
- else if (cap == s_round || cap == s_curve) \
- cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND); \
- else if (cap == s_square || cap == s_rect) \
- cairo_set_line_cap(cr, CAIRO_LINE_CAP_BUTT)
+void shoes_msg(ID typ, VALUE str) {
+#ifndef RUBY_1_8
+ ID func = rb_frame_this_func();
+ rb_ary_push(shoes_world->msgs, rb_ary_new3(6,
+ ID2SYM(typ), str, rb_funcall(rb_cTime, s_now, 0),
+ func ? ID2SYM(func) : Qnil,
+ rb_str_new2(""), INT2NUM(0)));
+#else
+ ID func = rb_frame_last_func();
+ rb_ary_push(shoes_world->msgs, rb_ary_new3(6,
+ ID2SYM(typ), str, rb_funcall(rb_cTime, s_now, 0),
+ func ? ID2SYM(func) : Qnil,
+ rb_str_new2(ruby_sourcefile), INT2NUM(ruby_sourceline)));
+#endif
+}
-#define DASH_SET(cr, dash) \
- if (dash == s_onedot) \
+#define DEBUG_TYPE(t) \
+ VALUE \
+ shoes_canvas_##t(VALUE self, VALUE str) \
{ \
- double dashes[] = {50.0, 10.0, 10.0, 10.0}; \
- int ndash = sizeof (dashes)/sizeof(dashes[0]); \
- double offset = -50.0; \
- cairo_set_dash(cr, dashes, ndash, offset); \
+ shoes_msg(s_##t, str); \
+ return Qnil; \
} \
- else \
- { \
- cairo_set_dash(cr, NULL, 0, 0.0); \
- }
-
-#define PATH_OUT(cr, attr, place, sw, cap, dash, pen, cfunc) \
-{ \
- VALUE p = ATTR(attr, pen); \
- if (!NIL_P(p)) \
+ \
+ void \
+ shoes_##t(const char *fmt, ...) \
{ \
- CAP_SET(cr, cap); \
- DASH_SET(cr, dash); \
- cairo_set_line_width(cr, sw); \
- if (rb_obj_is_kind_of(p, cColor)) \
- { \
- shoes_color *color; \
- Data_Get_Struct(p, shoes_color, color); \
- cairo_set_source_rgba(cr, color->r / 255., color->g / 255., color->b / 255., color->a / 255.); \
- cfunc(cr); \
- } \
- else \
- { \
- if (!rb_obj_is_kind_of(p, cPattern)) \
- ATTRSET(attr, pen, p = shoes_pattern_new(cPattern, p, Qnil, Qnil)); \
- cairo_matrix_t matrix1, matrix2; \
- shoes_pattern *pattern; \
- Data_Get_Struct(p, shoes_pattern, pattern); \
- PATTERN_SCALE(pattern, (place), sw); \
- cairo_set_source(cr, PATTERN(pattern)); \
- cfunc(cr); \
- PATTERN_RESET(pattern); \
- } \
- } \
-}
-
-//
-// Shoes::Shape
-//
-void
-shoes_shape_mark(shoes_shape *path)
-{
- rb_gc_mark_maybe(path->parent);
- rb_gc_mark_maybe(path->attr);
-}
-
-static void
-shoes_shape_free(shoes_shape *path)
-{
- shoes_transform_release(path->st);
- if (path->line != NULL) cairo_path_destroy(path->line);
- RUBY_CRITICAL(free(path));
-}
-
-VALUE
-shoes_shape_attr(int argc, VALUE *argv, int syms, ...)
-{
- int i;
- va_list args;
- VALUE hsh = Qnil;
- va_start(args, syms);
- if (argc < 1) hsh = rb_hash_new();
- else if (rb_obj_is_kind_of(argv[argc - 1], rb_cHash)) hsh = argv[argc - 1];
- for (i = 0; i < syms; i++)
- {
- ID sym = va_arg(args, ID);
- if (argc > i && !rb_obj_is_kind_of(argv[i], rb_cHash))
- hsh = shoes_hash_set(hsh, sym, argv[i]);
- }
- va_end(args);
- return hsh;
-}
-
-unsigned char
-shoes_shape_check(cairo_t *cr, shoes_place *place)
-{
- double ox1 = place->ix, oy1 = place->iy, ox2 = place->ix + place->iw, oy2 = place->iy + place->ih;
- double cx1, cy1, cx2, cy2;
- cairo_clip_extents(cr, &cx1, &cy1, &cx2, &cy2);
- if (place->iw < 0) ox1 = place->ix - (ox2 = -place->iw);
- if (place->ih < 0) oy1 = place->iy - (oy2 = -place->ih);
- if (cy2 - cy1 == 1.0 && cx2 - cx1 == 1.0) return 1;
- if ((ox1 < cx1 && ox2 < cx1) || (oy1 < cy1 && oy2 < cy1) ||
- (ox1 > cx2 && ox2 > cx2) || (oy1 > cy2 && oy2 > cy2)) return 0;
- return 1;
-}
-
-void
-shoes_shape_sketch(cairo_t *cr, ID name, shoes_place *place, shoes_transform *st, VALUE attr, cairo_path_t* line, unsigned char draw)
-{
- double sw = ATTR2(dbl, attr, strokewidth, 1.);
- if (name == s_oval && place->w > 0 && place->h > 0)
- {
- shoes_apply_transformation(cr, st, place, 1);
- if (!shoes_shape_check(cr, place))
- return shoes_undo_transformation(cr, st, place, 1);
- if (draw) cairo_new_path(cr);
- cairo_translate(cr, (place->x * 1.) + (place->w / 2.), (place->y * 1.) + (place->h / 2.));
- cairo_scale(cr, place->w / 2., place->h / 2.);
- cairo_arc(cr, 0., 0., 1., 0., SHOES_PIM2);
- cairo_close_path(cr);
- shoes_undo_transformation(cr, st, place, 1);
- }
- else if (name == s_arc && place->w > 0 && place->h > 0)
- {
- double a1 = ATTR2(dbl, attr, angle1, 0.);
- double a2 = ATTR2(dbl, attr, angle2, 0.);
- shoes_apply_transformation(cr, st, place, 0);
- if (!shoes_shape_check(cr, place))
- return shoes_undo_transformation(cr, st, place, 0);
- if (draw) cairo_new_path(cr);
- shoes_cairo_arc(cr, SWPOS(place->x), SWPOS(place->y),
- place->w * 1., place->h * 1., a1, a2);
- shoes_undo_transformation(cr, st, place, 0);
- }
- else if (name == s_rect && place->w > 0 && place->h > 0)
- {
- double cv = ATTR2(dbl, attr, curve, 0.);
- shoes_apply_transformation(cr, st, place, 0);
- if (!shoes_shape_check(cr, place))
- return shoes_undo_transformation(cr, st, place, 0);
- if (draw) cairo_new_path(cr);
- shoes_cairo_rect(cr, SWPOS(place->x), SWPOS(place->y), place->w * 1., place->h * 1., cv);
- shoes_undo_transformation(cr, st, place, 0);
- }
- else if (name == s_line)
- {
- shoes_apply_transformation(cr, st, place, 0);
- if (!shoes_shape_check(cr, place))
- return shoes_undo_transformation(cr, st, place, 0);
- cairo_move_to(cr, SWPOS(place->ix), SWPOS(place->iy));
- cairo_line_to(cr, SWPOS(place->ix + place->iw), SWPOS(place->iy + place->ih));
- shoes_undo_transformation(cr, st, place, 0);
- }
- else if (name == s_arrow && place->w > 0)
- {
- double h, tip, x;
- x = place->x + (place->w / 2.);
- h = place->w * 0.8;
- place->h = ROUND(h);
- tip = place->w * 0.42;
-
- shoes_apply_transformation(cr, st, place, 0);
- if (!shoes_shape_check(cr, place))
- return shoes_undo_transformation(cr, st, place, 0);
- if (draw) cairo_new_path(cr);
- cairo_move_to(cr, SWPOS(x), SWPOS(place->y));
- cairo_rel_line_to(cr, -tip, +(h*0.5));
- cairo_rel_line_to(cr, 0, -(h*0.25));
- cairo_rel_line_to(cr, -(place->w-tip), 0);
- cairo_rel_line_to(cr, 0, -(h*0.5));
- cairo_rel_line_to(cr, +(place->w-tip), 0);
- cairo_rel_line_to(cr, 0, -(h*0.25));
- cairo_close_path(cr);
- shoes_undo_transformation(cr, st, place, 0);
- }
- else if (name == s_star)
- {
- int i, points;
- double outer, inner, angle, r;
- points = ATTR2(int, attr, points, 10);
- outer = ATTR2(dbl, attr, outer, 100.);
- inner = ATTR2(dbl, attr, inner, 50.);
-
- if (outer > 0)
- {
- place->w = place->h = ROUND(outer);
- shoes_apply_transformation(cr, st, place, 0);
- if (!shoes_shape_check(cr, place))
- return shoes_undo_transformation(cr, st, place, 0);
- if (draw) cairo_new_path(cr);
- cairo_move_to(cr, place->x * 1., (place->y * 1.) + outer);
- for (i = 1; i <= points * 2; i++) {
- angle = (i * SHOES_PI) / (points * 1.);
- r = (i % 2 == 0 ? outer : inner);
- cairo_line_to(cr, place->x + r * sin(angle), place->y + r * cos(angle));
- }
- cairo_close_path(cr);
- shoes_undo_transformation(cr, st, place, 0);
- }
- }
- else if (name == s_shape)
- {
- shoes_apply_transformation(cr, st, place, 0);
- if (!shoes_shape_check(cr, place))
- return shoes_undo_transformation(cr, st, place, 0);
- cairo_translate(cr, SWPOS(place->x), SWPOS(place->y));
- cairo_append_path(cr, line);
- shoes_undo_transformation(cr, st, place, 0);
- }
- else return;
-
- if (draw)
- {
- ID cap = s_rect;
- if (!NIL_P(ATTR(attr, cap))) cap = SYM2ID(ATTR(attr, cap));
- ID dash = s_nodot;
- if (!NIL_P(ATTR(attr, dash))) dash = SYM2ID(ATTR(attr, dash));
- PATH_OUT(cr, attr, *place, sw, cap, dash, fill, cairo_fill_preserve);
- PATH_OUT(cr, attr, *place, sw, cap, dash, stroke, cairo_stroke);
- }
-}
-
-VALUE
-shoes_shape_new(VALUE parent, ID name, VALUE attr, shoes_transform *st, cairo_path_t *line)
-{
- shoes_shape *path;
- shoes_canvas *canvas;
- VALUE obj = shoes_shape_alloc(cShape);
- Data_Get_Struct(obj, shoes_shape, path);
- Data_Get_Struct(parent, shoes_canvas, canvas);
- path->parent = parent;
- path->attr = attr;
- path->name = name;
- path->st = shoes_transform_touch(st);
- path->line = line;
- COPY_PENS(path->attr, canvas->attr);
- return obj;
-}
-
-VALUE
-shoes_shape_alloc(VALUE klass)
-{
- VALUE obj;
- shoes_shape *shape = SHOE_ALLOC(shoes_shape);
- SHOE_MEMZERO(shape, shoes_shape, 1);
- obj = Data_Wrap_Struct(klass, shoes_shape_mark, shoes_shape_free, shape);
- shape->attr = Qnil;
- shape->parent = Qnil;
- shape->line = NULL;
- return obj;
-}
-
-VALUE
-shoes_shape_draw(VALUE self, VALUE c, VALUE actual)
-{
- shoes_place place;
- shoes_canvas *canvas;
- GET_STRUCT(shape, self_t);
- if (ATTR(self_t->attr, hidden) == Qtrue) return self;
- Data_Get_Struct(self_t->parent, shoes_canvas, canvas);
- shoes_place_exact(&place, self_t->attr, CPX(canvas), CPY(canvas));
-
- if (RTEST(actual))
- shoes_shape_sketch(CCR(canvas), self_t->name, &place, self_t->st, self_t->attr, self_t->line, 1);
-
- self_t->place = place;
- return self;
-}
-
-VALUE
-shoes_shape_motion(VALUE self, int x, int y, char *touch)
-{
- char h = 0;
- VALUE click;
- GET_STRUCT(shape, self_t);
-
- click = ATTR(self_t->attr, click);
-
- if (IS_INSIDE(self_t, x, y))
- {
- cairo_bool_t in_shape;
- cairo_t *cr = cairo_create(cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 1, 1));
- // if (self_t->line != NULL)
- // {
- // cairo_new_path(cr);
- // cairo_append_path(cr, self_t->line);
- // }
- // else
- shoes_shape_sketch(cr, self_t->name, &self_t->place, self_t->st, self_t->attr, self_t->line, 0);
- in_shape = cairo_in_fill(cr, x, y);
- cairo_destroy(cr);
-
- if (in_shape)
- {
- if (!NIL_P(click))
- {
- shoes_canvas *canvas;
- Data_Get_Struct(self_t->parent, shoes_canvas, canvas);
- shoes_app_cursor(canvas->app, s_link);
- }
- h = 1;
- }
+ va_list args; \
+ char buf[BUFSIZ]; \
+ \
+ va_start(args,fmt); \
+ vsnprintf(buf, BUFSIZ, fmt, args); \
+ va_end(args); \
+ shoes_msg(s_##t, rb_str_new2(buf)); \
}
- CHECK_HOVER(self_t, h, touch);
+DEBUG_TYPE(info);
+DEBUG_TYPE(debug);
+DEBUG_TYPE(warn);
+DEBUG_TYPE(error);
- return h ? click : Qnil;
- return Qnil;
+VALUE shoes_p(VALUE self, VALUE obj) {
+ return shoes_canvas_debug(self, rb_inspect(obj));
}
-VALUE
-shoes_shape_send_click(VALUE self, int button, int x, int y)
-{
- VALUE v = Qnil;
-
- if (button > 0)
- {
- GET_STRUCT(shape, self_t);
- v = shoes_shape_motion(self, x, y, NULL);
- if (self_t->hover & HOVER_MOTION)
- self_t->hover = HOVER_MOTION | HOVER_CLICK;
- }
-
- return v;
+VALUE shoes_log(VALUE self) {
+ return shoes_world->msgs;
}
-void
-shoes_shape_send_release(VALUE self, int button, int x, int y)
-{
- GET_STRUCT(shape, self_t);
- if (button > 0 && (self_t->hover & HOVER_CLICK))
- {
- VALUE proc = ATTR(self_t->attr, release);
- self_t->hover ^= HOVER_CLICK;
- if (!NIL_P(proc))
- shoes_safe_block(self, proc, rb_ary_new3(3, INT2NUM(button), INT2NUM(x), INT2NUM(y)));
- }
+VALUE shoes_font(VALUE self, VALUE path) {
+ StringValue(path);
+ return shoes_load_font(RSTRING_PTR(path));
}
//
-// Shoes::Image
+// See ruby.h for the complete list of App methods which redirect to Canvas.
//
-void
-shoes_image_mark(shoes_image *image)
-{
- rb_gc_mark_maybe(image->path);
- rb_gc_mark_maybe(image->parent);
- rb_gc_mark_maybe(image->attr);
-}
-
-static void
-shoes_image_free(shoes_image *image)
-{
- if (image->type == SHOES_CACHE_MEM)
- {
- if (image->cr != NULL) cairo_destroy(image->cr);
- if (image->cached != NULL) cairo_surface_destroy(image->cached->surface);
- SHOE_FREE(image->cached);
- }
- shoes_transform_release(image->st);
- RUBY_CRITICAL(SHOE_FREE(image));
-}
-
-VALUE
-shoes_image_new(VALUE klass, VALUE path, VALUE attr, VALUE parent, shoes_transform *st)
-{
- VALUE obj = Qnil;
- shoes_image *image;
- shoes_basic *basic;
- Data_Get_Struct(parent, shoes_basic, basic);
-
- obj = shoes_image_alloc(klass);
- Data_Get_Struct(obj, shoes_image, image);
-
- image->path = Qnil;
- image->st = shoes_transform_touch(st);
- image->attr = attr;
- image->parent = shoes_find_canvas(parent);
- COPY_PENS(image->attr, basic->attr);
-
- if (rb_obj_is_kind_of(path, cImage))
- {
- shoes_image *image2;
- Data_Get_Struct(path, shoes_image, image2);
- image->cached = image2->cached;
- image->type = SHOES_CACHE_ALIAS;
- }
- else if (!NIL_P(path))
- {
- path = shoes_native_to_s(path);
- image->path = path;
- image->cached = shoes_load_image(image->parent, path);
- image->type = SHOES_CACHE_FILE;
- }
- else
- {
- shoes_canvas *canvas;
- Data_Get_Struct(image->parent, shoes_canvas, canvas);
- int w = ATTR2(int, attr, width, canvas->width);
- int h = ATTR2(int, attr, height, canvas->height);
- VALUE block = ATTR(attr, draw);
- image->cached = shoes_cached_image_new(w, h, NULL);
- image->cr = cairo_create(image->cached->surface);
- image->type = SHOES_CACHE_MEM;
- if (!NIL_P(block)) DRAW(obj, canvas->app, rb_funcall(block, s_call, 0));
- }
-
- return obj;
-}
-
-VALUE
-shoes_image_alloc(VALUE klass)
-{
- VALUE obj;
- shoes_image *image = SHOE_ALLOC(shoes_image);
- SHOE_MEMZERO(image, shoes_image, 1);
- obj = Data_Wrap_Struct(klass, shoes_image_mark, shoes_image_free, image);
- image->path = Qnil;
- image->st = NULL;
- image->attr = Qnil;
- image->parent = Qnil;
- image->type = SHOES_CACHE_MEM;
- return obj;
-}
-
-VALUE
-shoes_image_get_full_width(VALUE self)
-{
- GET_STRUCT(image, image);
- return INT2NUM(image->cached->width);
-}
-
-VALUE
-shoes_image_get_full_height(VALUE self)
-{
- GET_STRUCT(image, image);
- return INT2NUM(image->cached->height);
-}
-
-void
-shoes_image_ensure_dup(shoes_image *image)
-{
- if (image->type == SHOES_CACHE_MEM)
- return;
- shoes_cached_image *cached = shoes_cached_image_new(image->cached->width, image->cached->height, NULL);
- image->cr = cairo_create(cached->surface);
- cairo_set_source_surface(image->cr, image->cached->surface, 0, 0);
- cairo_paint(image->cr);
-
- image->cached = cached;
- image->type = SHOES_CACHE_MEM;
-}
-
-unsigned char *
-shoes_image_surface_get_pixel(shoes_cached_image *cached, int x, int y)
-{
- if (x >= 0 && y >= 0 && x < cached->width && y < cached->height)
- {
- unsigned char* pixels = cairo_image_surface_get_data(cached->surface);
- if (cairo_image_surface_get_format(cached->surface) == CAIRO_FORMAT_ARGB32)
- return pixels + (y * (4 * cached->width)) + (4 * x);
- }
- return NULL;
-}
-
-VALUE
-shoes_image_get_pixel(VALUE self, VALUE _x, VALUE _y)
-{
- VALUE color = Qnil;
- int x = NUM2INT(_x), y = NUM2INT(_y);
- GET_STRUCT(image, image);
- unsigned char *pixels = shoes_image_surface_get_pixel(image->cached, x, y);
- if (pixels != NULL)
- color = shoes_color_new(pixels[2], pixels[1], pixels[0], pixels[3]);
- return color;
-}
-
-VALUE
-shoes_image_set_pixel(VALUE self, VALUE _x, VALUE _y, VALUE col)
-{
- int x = NUM2INT(_x), y = NUM2INT(_y);
- GET_STRUCT(image, image);
- shoes_image_ensure_dup(image);
- unsigned char *pixels = shoes_image_surface_get_pixel(image->cached, x, y);
- if (pixels != NULL)
- {
- if (TYPE(col) == T_STRING)
- col = shoes_color_parse(cColor, col);
- if (rb_obj_is_kind_of(col, cColor))
- {
- shoes_color *color;
- Data_Get_Struct(col, shoes_color, color);
- pixels[0] = color->b;
- pixels[1] = color->g;
- pixels[2] = color->r;
- pixels[3] = color->a;
- }
- }
- return self;
-}
-
-VALUE
-shoes_image_get_path(VALUE self)
-{
- GET_STRUCT(image, image);
- return image->path;
-}
-
-VALUE
-shoes_image_set_path(VALUE self, VALUE path)
-{
- GET_STRUCT(image, image);
- image->path = path;
- image->cached = shoes_load_image(image->parent, path);
- image->type = SHOES_CACHE_FILE;
- shoes_canvas_repaint_all(image->parent);
- return path;
-}
-
-static void
-shoes_image_draw_surface(cairo_t *cr, shoes_image *self_t, shoes_place *place, cairo_surface_t *surf, int imw, int imh)
-{
- shoes_apply_transformation(cr, self_t->st, place, 0);
- cairo_translate(cr, place->ix + place->dx, place->iy + place->dy);
- if (place->iw != imw || place->ih != imh)
- cairo_scale(cr, (place->iw * 1.) / imw, (place->ih * 1.) / imh);
- cairo_set_source_surface(cr, surf, 0., 0.);
- cairo_paint(cr);
- shoes_undo_transformation(cr, self_t->st, place, 0);
- self_t->place = *place;
-}
-
-#define SHOES_IMAGE_PLACE(type, imw, imh, surf) \
- SETUP(shoes_##type, (REL_CANVAS | REL_SCALE), imw, imh); \
- VALUE ck = rb_obj_class(c); \
- if (RTEST(actual)) \
- shoes_image_draw_surface(CCR(canvas), self_t, &place, surf, imw, imh); \
- FINISH(); \
- return self;
-
-VALUE
-shoes_image_draw(VALUE self, VALUE c, VALUE actual)
-{
- SHOES_IMAGE_PLACE(image, self_t->cached->width, self_t->cached->height, self_t->cached->surface);
-}
-
-void
-shoes_image_image(VALUE parent, VALUE path, VALUE attr)
-{
- shoes_image *pi;
- shoes_place place;
- Data_Get_Struct(parent, shoes_image, pi);
- VALUE self = shoes_image_new(cImage, path, attr, parent, pi->st);
- GET_STRUCT(image, image);
- shoes_image_ensure_dup(pi);
- shoes_place_exact(&place, image->attr, 0, 0);
- if (place.iw < 1) place.w = place.iw = image->cached->width;
- if (place.ih < 1) place.h = place.ih = image->cached->height;
- shoes_image_draw_surface(pi->cr, image, &place, image->cached->surface, image->cached->width, image->cached->height);
-}
-
-VALUE
-shoes_image_size(VALUE self)
-{
- GET_STRUCT(image, self_t);
- return rb_ary_new3(2, INT2NUM(self_t->cached->width), INT2NUM(self_t->cached->height));
-}
-
-VALUE
-shoes_image_motion(VALUE self, int x, int y, char *touch)
-{
- char h = 0;
- VALUE click;
- GET_STRUCT(image, self_t);
-
- click = ATTR(self_t->attr, click);
- if (self_t->cached == NULL) return Qnil;
-
- if (IS_INSIDE(self_t, x, y))
- {
- if (!NIL_P(click))
- {
- shoes_canvas *canvas;
- Data_Get_Struct(self_t->parent, shoes_canvas, canvas);
- shoes_app_cursor(canvas->app, s_link);
- }
- h = 1;
- }
-
- CHECK_HOVER(self_t, h, touch);
-
- return h ? click : Qnil;
-}
-
-VALUE
-shoes_image_send_click(VALUE self, int button, int x, int y)
-{
- VALUE v = Qnil;
-
- if (button > 0)
- {
- GET_STRUCT(image, self_t);
- v = shoes_image_motion(self, x, y, NULL);
- if (self_t->hover & HOVER_MOTION)
- self_t->hover = HOVER_MOTION | HOVER_CLICK;
- }
+CANVAS_DEFS(FUNC_M);
- return v;
-}
+#define C(n, s) \
+ re##n = rb_eval_string(s); \
+ rb_const_set(cShoes, rb_intern("" # n), re##n);
-void
-shoes_image_send_release(VALUE self, int button, int x, int y)
-{
- GET_STRUCT(image, self_t);
- if (button > 0 && (self_t->hover & HOVER_CLICK))
- {
- VALUE proc = ATTR(self_t->attr, release);
- self_t->hover ^= HOVER_CLICK;
- if (!NIL_P(proc))
- shoes_safe_block(self, proc, rb_ary_new3(3, INT2NUM(button), INT2NUM(x), INT2NUM(y)));
- }
-}
+VALUE progname;
//
-// Shoes::Effect
+// Everything exposed to Ruby is exposed here.
//
-void
-shoes_effect_mark(shoes_effect *fx)
-{
- rb_gc_mark_maybe(fx->parent);
- rb_gc_mark_maybe(fx->attr);
-}
-
-static void
-shoes_effect_free(shoes_effect *fx)
-{
- RUBY_CRITICAL(free(fx));
-}
-
-shoes_effect_filter
-shoes_effect_for_type(ID name)
-{
- if (name == s_blur)
- return &shoes_gaussian_blur_filter;
- else if (name == s_shadow)
- return &shoes_shadow_filter;
- else if (name == s_glow)
- return &shoes_glow_filter;
- return NULL;
-}
-
-VALUE
-shoes_effect_new(ID name, VALUE attr, VALUE parent)
-{
- shoes_effect *fx;
- shoes_canvas *canvas;
- VALUE obj = shoes_effect_alloc(cEffect);
- Data_Get_Struct(obj, shoes_effect, fx);
- Data_Get_Struct(parent, shoes_canvas, canvas);
- fx->parent = parent;
- fx->attr = attr;
- fx->filter = shoes_effect_for_type(name);
- return obj;
-}
-
-VALUE
-shoes_effect_alloc(VALUE klass)
-{
- VALUE obj;
- shoes_effect *fx = SHOE_ALLOC(shoes_effect);
- SHOE_MEMZERO(fx, shoes_effect, 1);
- obj = Data_Wrap_Struct(klass, shoes_effect_mark, shoes_effect_free, fx);
- fx->attr = Qnil;
- fx->parent = Qnil;
- return obj;
-}
-
-VALUE
-shoes_effect_draw(VALUE self, VALUE c, VALUE actual)
-{
- SETUP(shoes_effect, REL_TILE, canvas->width, canvas->height);
+void shoes_ruby_init() {
+ progname = rb_str_new2("(eval)");
+ rb_define_variable("$0", &progname);
+ rb_define_variable("$PROGRAM_NAME", &progname);
- if (RTEST(actual) && self_t->filter != NULL)
- self_t->filter(CCR(canvas), self_t->attr, &self_t->place);
+ instance_eval_proc = rb_eval_string("lambda{|o,b| o.instance_eval(&b)}");
+ rb_gc_register_address(&instance_eval_proc);
+ ssNestSlot = rb_eval_string("{:height => 1.0}");
+ rb_gc_register_address(&ssNestSlot);
- self_t->place = place;
- return self;
-}
+ s_aref = rb_intern("[]=");
+ s_perc = rb_intern("%");
+ s_mult = rb_intern("*");
+ SYMBOL_DEFS(SYMBOL_INTERN);
-//
-// Shoes::Pattern
-//
-void
-shoes_pattern_mark(shoes_pattern *pattern)
-{
- rb_gc_mark_maybe(pattern->source);
- rb_gc_mark_maybe(pattern->parent);
- rb_gc_mark_maybe(pattern->attr);
-}
+ symAltQuest = ID2SYM(rb_intern("alt_?"));
+ symAltSlash = ID2SYM(rb_intern("alt_/"));
+ symAltEqual = ID2SYM(rb_intern("alt_="));
+ symAltDot = ID2SYM(rb_intern("alt_."));
+ symAltSemiColon = ID2SYM(rb_intern("alt_;"));
-static void
-shoes_pattern_free(shoes_pattern *pattern)
-{
- if (pattern->pattern != NULL)
- cairo_pattern_destroy(pattern->pattern);
- RUBY_CRITICAL(free(pattern));
-}
+ //
+ // I want all elements to be addressed Shoes::Name, but also available in
+ // a separate mixin (cTypes), for inclusion in every Shoes.app block.
+ //
+ cTypes = rb_define_module("Shoes");
+ rb_mod_remove_const(rb_cObject, rb_str_new2("Shoes"));
+
+ cShoesWindow = rb_define_class_under(cTypes, "Window", rb_cObject);
+ cMouse = rb_define_class_under(cTypes, "Mouse", rb_cObject);
+
+ cCanvas = rb_define_class_under(cTypes, "Canvas", rb_cObject);
+ rb_define_alloc_func(cCanvas, shoes_canvas_alloc);
+ rb_define_method(cCanvas, "top", CASTHOOK(shoes_canvas_get_top), 0);
+ rb_define_method(cCanvas, "left", CASTHOOK(shoes_canvas_get_left), 0);
+ rb_define_method(cCanvas, "width", CASTHOOK(shoes_canvas_get_width), 0);
+ rb_define_method(cCanvas, "height", CASTHOOK(shoes_canvas_get_height), 0);
+ rb_define_method(cCanvas, "scroll_height", CASTHOOK(shoes_canvas_get_scroll_height), 0);
+ rb_define_method(cCanvas, "scroll_max", CASTHOOK(shoes_canvas_get_scroll_max), 0);
+ rb_define_method(cCanvas, "scroll_top", CASTHOOK(shoes_canvas_get_scroll_top), 0);
+ rb_define_method(cCanvas, "scroll_top=", CASTHOOK(shoes_canvas_set_scroll_top), 1);
+ rb_define_method(cCanvas, "displace", CASTHOOK(shoes_canvas_displace), 2);
+ rb_define_method(cCanvas, "move", CASTHOOK(shoes_canvas_move), 2);
+ rb_define_method(cCanvas, "style", CASTHOOK(shoes_canvas_style), -1);
+ rb_define_method(cCanvas, "parent", CASTHOOK(shoes_canvas_get_parent), 0);
+ rb_define_method(cCanvas, "contents", CASTHOOK(shoes_canvas_contents), 0);
+ rb_define_method(cCanvas, "children", CASTHOOK(shoes_canvas_children), 0);
+ rb_define_method(cCanvas, "draw", CASTHOOK(shoes_canvas_draw), 2);
+ rb_define_method(cCanvas, "hide", CASTHOOK(shoes_canvas_hide), 0);
+ rb_define_method(cCanvas, "show", CASTHOOK(shoes_canvas_show), 0);
+ rb_define_method(cCanvas, "toggle", CASTHOOK(shoes_canvas_toggle), 0);
+ rb_define_method(cCanvas, "remove", CASTHOOK(shoes_canvas_remove), 0);
+ rb_define_method(cCanvas, "refresh_slot", CASTHOOK(shoes_canvas_refresh_slot), 0);
+ rb_define_method(cCanvas, "refresh", CASTHOOK(shoes_canvas_refresh_slot), 0);
+ rb_define_method(cCanvas, "cursor=", CASTHOOK(shoes_canvas_get_cursor), 0);
+ rb_define_method(cCanvas, "cursor=", CASTHOOK(shoes_canvas_set_cursor), 1);
+
+ cShoes = rb_define_class("Shoes", cCanvas);
+ rb_include_module(cShoes, cTypes);
+ rb_const_set(cShoes, rb_intern("Types"), cTypes);
+
+ shoes_version_init();
+
+ // other Shoes:: constants
+ rb_const_set(cTypes, rb_intern("RAD2PI"), rb_float_new(SHOES_RAD2PI));
+ rb_const_set(cTypes, rb_intern("TWO_PI"), rb_float_new(SHOES_PIM2));
+ rb_const_set(cTypes, rb_intern("HALF_PI"), rb_float_new(SHOES_HALFPI));
+ rb_const_set(cTypes, rb_intern("PI"), rb_float_new(SHOES_PI));
+
+ cApp = rb_define_class_under(cTypes, "App", rb_cObject);
+ rb_define_alloc_func(cApp, shoes_app_alloc);
+ rb_define_method(cApp, "fullscreen", CASTHOOK(shoes_app_get_fullscreen), 0);
+ rb_define_method(cApp, "fullscreen=", CASTHOOK(shoes_app_set_fullscreen), 1);
+ rb_define_method(cApp, "name", CASTHOOK(shoes_app_get_title), 0);
+ rb_define_method(cApp, "name=", CASTHOOK(shoes_app_set_title), 1);
+ rb_define_method(cApp, "location", CASTHOOK(shoes_app_location), 0);
+ rb_define_method(cApp, "started?", CASTHOOK(shoes_app_is_started), 0);
+ rb_define_method(cApp, "width", CASTHOOK(shoes_app_get_width), 0);
+ rb_define_method(cApp, "height", CASTHOOK(shoes_app_get_height), 0);
+ rb_define_method(cApp, "resize", CASTHOOK(shoes_app_resize_window), 2);
+ rb_define_method(cApp, "slot", CASTHOOK(shoes_app_slot), 0);
+ rb_define_method(cApp, "set_window_icon_path", CASTHOOK(shoes_app_set_icon), 1); // New in 3.2.19
+ rb_define_method(cApp, "set_window_title", CASTHOOK(shoes_app_set_wtitle), 1); // New in 3.2.19
+ rb_define_method(cApp, "opacity", CASTHOOK(shoes_app_get_opacity), 0);
+ rb_define_method(cApp, "opacity=", CASTHOOK(shoes_app_set_opacity), 1);
+ rb_define_method(cApp, "decorated", CASTHOOK(shoes_app_get_decoration), 0);
+ rb_define_method(cApp, "decorated=", CASTHOOK(shoes_app_set_decoration), 1);
+ rb_define_alias(cApp, "decorated?", "decorated");
+
+ cDialog = rb_define_class_under(cTypes, "Dialog", cApp);
+
+ eInvMode = rb_define_class_under(cTypes, "InvalidModeError", rb_eStandardError);
+ eNotImpl = rb_define_class_under(cTypes, "NotImplementedError", rb_eStandardError);
+ eImageError = rb_define_class_under(cTypes, "ImageError", rb_eStandardError);
+ C(HEX_SOURCE, "/^(?:0x|#)?([0-9A-F]{2})([0-9A-F]{2})([0-9A-F]{2})$/i");
+ C(HEX3_SOURCE, "/^(?:0x|#)?([0-9A-F])([0-9A-F])([0-9A-F])$/i");
+ C(RGB_SOURCE, "/^rgb\\((\\d+), *(\\d+), *(\\d+)\\)$/i");
+ C(RGBA_SOURCE, "/^rgb\\((\\d+), *(\\d+), *(\\d+), *(\\d+)\\)$/i");
+ C(GRAY_SOURCE, "/^gray\\((\\d+)\\)$/i");
+ C(GRAYA_SOURCE, "/^gray\\((\\d+), *(\\d+)\\)$/i");
+ C(LF, "/\\r?\\n/");
+ rb_eval_string(
+ "def Shoes.escape(string);"
+ "string.gsub(/&/n, '&').gsub(/\\\"/n, '"').gsub(/>/n, '>').gsub(/pattern = cairo_pattern_create_radial(0.5, 0.5, r, edge / 2., edge / 2., edge / 2.);
- }
- else
- {
- pattern->pattern = cairo_pattern_create_linear(0.5 + (-dx * edge), 0.5 + (-dy * edge),
- 0.5 + (dx * edge), 0.5 + (dy * edge));
- }
- shoes_color_grad_stop(pattern->pattern, 0.0, r1);
- shoes_color_grad_stop(pattern->pattern, 1.0, r2);
-}
-
-VALUE
-shoes_pattern_set_fill(VALUE self, VALUE source)
-{
- shoes_pattern *pattern;
- Data_Get_Struct(self, shoes_pattern, pattern);
-
- if (pattern->pattern != NULL)
- cairo_pattern_destroy(pattern->pattern);
- pattern->pattern = NULL;
-
- if (rb_obj_is_kind_of(source, rb_cRange))
- {
- VALUE r1 = rb_funcall(source, s_begin, 0);
- VALUE r2 = rb_funcall(source, s_end, 0);
- shoes_pattern_gradient(pattern, r1, r2, pattern->attr);
- }
- else
- {
- if (!rb_obj_is_kind_of(source, cColor))
- {
- VALUE rgb = shoes_color_parse(cColor, source);
- if (!NIL_P(rgb)) source = rgb;
- }
-
- if (rb_obj_is_kind_of(source, cColor))
- {
- pattern->pattern = shoes_color_pattern(source);
- }
- else
- {
- pattern->cached = shoes_load_image(pattern->parent, source);
- if (pattern->cached != NULL && pattern->cached->pattern == NULL)
- pattern->cached->pattern = cairo_pattern_create_for_surface(pattern->cached->surface);
- }
- cairo_pattern_set_extend(PATTERN(pattern), CAIRO_EXTEND_REPEAT);
- }
-
- pattern->source = source;
- return source;
-}
-
-VALUE
-shoes_pattern_get_fill(VALUE self)
-{
- shoes_pattern *pattern;
- Data_Get_Struct(self, shoes_pattern, pattern);
- return pattern->source;
-}
-
-VALUE
-shoes_pattern_self(VALUE self)
-{
- return self;
-}
-
-VALUE
-shoes_pattern_args(int argc, VALUE *argv, VALUE self)
-{
- VALUE source, attr;
- rb_scan_args(argc, argv, "11", &source, &attr);
- CHECK_HASH(attr);
- return shoes_pattern_new(cPattern, source, attr, Qnil);
-}
-
-VALUE
-shoes_pattern_new(VALUE klass, VALUE source, VALUE attr, VALUE parent)
-{
- shoes_pattern *pattern;
- VALUE obj = shoes_pattern_alloc(klass);
- Data_Get_Struct(obj, shoes_pattern, pattern);
- pattern->source = Qnil;
- pattern->attr = attr;
- pattern->parent = parent;
- shoes_pattern_set_fill(obj, source);
- return obj;
-}
-
-VALUE
-shoes_pattern_method(VALUE klass, VALUE source)
-{
- return shoes_pattern_new(cPattern, source, Qnil, Qnil);
-}
-
-VALUE
-shoes_pattern_alloc(VALUE klass)
-{
- VALUE obj;
- shoes_pattern *pattern = SHOE_ALLOC(shoes_pattern);
- SHOE_MEMZERO(pattern, shoes_pattern, 1);
- obj = Data_Wrap_Struct(klass, shoes_pattern_mark, shoes_pattern_free, pattern);
- pattern->source = Qnil;
- pattern->attr = Qnil;
- pattern->parent = Qnil;
- return obj;
-}
-
-VALUE
-shoes_background_draw(VALUE self, VALUE c, VALUE actual)
-{
- cairo_matrix_t matrix1, matrix2;
- double r = 0., sw = 1.;
- SETUP(shoes_pattern, REL_TILE, PATTERN_DIM(self_t, width), PATTERN_DIM(self_t, height));
- r = ATTR2(dbl, self_t->attr, curve, 0.);
-
- if (RTEST(actual))
- {
- cairo_t *cr = CCR(canvas);
- cairo_save(cr);
- cairo_translate(cr, place.ix + place.dx, place.iy + place.dy);
- PATTERN_SCALE(self_t, place, sw);
- cairo_new_path(cr);
- shoes_cairo_rect(cr, 0, 0, place.iw, place.ih, r);
- cairo_set_source(cr, PATTERN(self_t));
- cairo_fill(cr);
- cairo_restore(cr);
- PATTERN_RESET(self_t);
- }
-
- self_t->place = place;
- INFO("BACKGROUND: (%d, %d), (%d, %d)\n", place.x, place.y, place.w, place.h);
- return self;
-}
-
-VALUE
-shoes_border_draw(VALUE self, VALUE c, VALUE actual)
-{
- cairo_matrix_t matrix1, matrix2;
- ID cap = s_rect;
- ID dash = s_nodot;
- double r = 0., sw = 1.;
- SETUP(shoes_pattern, REL_TILE, PATTERN_DIM(self_t, width), PATTERN_DIM(self_t, height));
- r = ATTR2(dbl, self_t->attr, curve, 0.);
- sw = ATTR2(dbl, self_t->attr, strokewidth, 1.);
- if (!NIL_P(ATTR(self_t->attr, cap))) cap = SYM2ID(ATTR(self_t->attr, cap));
- if (!NIL_P(ATTR(self_t->attr, dash))) dash = SYM2ID(ATTR(self_t->attr, dash));
-
- place.iw -= (int)round(sw);
- place.ih -= (int)round(sw);
- place.ix += (int)round(sw / 2.);
- place.iy += (int)round(sw / 2.);
-
- if (RTEST(actual))
- {
- cairo_t *cr = CCR(canvas);
- cairo_save(cr);
- cairo_translate(cr, place.ix + place.dx, place.iy + place.dy);
- PATTERN_SCALE(self_t, place, sw);
- cairo_set_source(cr, PATTERN(self_t));
- cairo_new_path(cr);
- shoes_cairo_rect(cr, 0, 0, place.iw, place.ih, r);
- cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE);
- CAP_SET(cr, cap);
- DASH_SET(cr, dash);
- cairo_set_line_width(cr, sw);
- cairo_stroke(cr);
- cairo_restore(cr);
- PATTERN_RESET(self_t);
- }
-
- self_t->place = place;
- INFO("BORDER: (%d, %d), (%d, %d)\n", place.x, place.y, place.w, place.h);
- return self;
-}
-
-VALUE
-shoes_subpattern_new(VALUE klass, VALUE pat, VALUE parent)
-{
- shoes_pattern *back, *pattern;
- VALUE obj = shoes_pattern_alloc(klass);
- Data_Get_Struct(obj, shoes_pattern, back);
- Data_Get_Struct(pat, shoes_pattern, pattern);
- back->source = pattern->source;
- back->cached = pattern->cached;
- back->pattern = pattern->pattern;
- if (back->pattern != NULL) cairo_pattern_reference(back->pattern);
- back->attr = pattern->attr;
- back->parent = parent;
- return obj;
-}
-
-//
-// Shoes::Color
-//
-void
-shoes_color_mark(shoes_color *color)
-{
-}
-
-static void
-shoes_color_free(shoes_color *color)
-{
- RUBY_CRITICAL(free(color));
-}
-
-VALUE
-shoes_color_new(int r, int g, int b, int a)
-{
- shoes_color *color;
- VALUE obj = shoes_color_alloc(cColor);
- Data_Get_Struct(obj, shoes_color, color);
- color->r = r;
- color->g = g;
- color->b = b;
- color->a = a;
- return obj;
-}
-
-VALUE
-shoes_color_alloc(VALUE klass)
-{
- VALUE obj;
- shoes_color *color = SHOE_ALLOC(shoes_color);
- SHOE_MEMZERO(color, shoes_color, 1);
- obj = Data_Wrap_Struct(klass, shoes_color_mark, shoes_color_free, color);
- color->a = SHOES_COLOR_OPAQUE;
- color->on = TRUE;
- return obj;
-}
-
-VALUE
-shoes_color_rgb(int argc, VALUE *argv, VALUE self)
-{
- int a;
- VALUE _r, _g, _b, _a;
- rb_scan_args(argc, argv, "31", &_r, &_g, &_b, &_a);
-
- a = SHOES_COLOR_OPAQUE;
- if (!NIL_P(_a)) a = NUM2RGBINT(_a);
- return shoes_color_new(NUM2RGBINT(_r), NUM2RGBINT(_g), NUM2RGBINT(_b), a);
-}
-
-VALUE
-shoes_color_gradient(int argc, VALUE *argv, VALUE self)
-{
- shoes_pattern *pattern;
- VALUE obj, r1, r2;
- VALUE attr = Qnil;
- rb_scan_args(argc, argv, "21", &r1, &r2, &attr);
- CHECK_HASH(attr);
-
- obj = shoes_pattern_alloc(cPattern);
- Data_Get_Struct(obj, shoes_pattern, pattern);
- pattern->source = Qnil;
- shoes_pattern_gradient(pattern, r1, r2, attr);
- return obj;
-}
-
-VALUE
-shoes_color_gray(int argc, VALUE *argv, VALUE self)
-{
- VALUE _g, _a;
- int g, a;
- rb_scan_args(argc, argv, "02", &_g, &_a);
-
- a = SHOES_COLOR_OPAQUE;
- g = 128;
- if (!NIL_P(_g)) g = NUM2RGBINT(_g);
- if (!NIL_P(_a)) a = NUM2RGBINT(_a);
- return shoes_color_new(g, g, g, a);
-}
-
-cairo_pattern_t *
-shoes_color_pattern(VALUE self)
-{
- GET_STRUCT(color, color);
- if (color->a == 255)
- return cairo_pattern_create_rgb(color->r / 255., color->g / 255., color->b / 255.);
- else
- return cairo_pattern_create_rgba(color->r / 255., color->g / 255., color->b / 255., color->a / 255.);
-}
-
-void
-shoes_color_grad_stop(cairo_pattern_t *pattern, double stop, VALUE self)
-{
- GET_STRUCT(color, color);
- if (color->a == 255)
- return cairo_pattern_add_color_stop_rgb(pattern, stop, color->r / 255., color->g / 255., color->b / 255.);
- else
- return cairo_pattern_add_color_stop_rgba(pattern, stop, color->r / 255., color->g / 255., color->b / 255., color->a / 255.);
-}
-
-VALUE
-shoes_color_args(int argc, VALUE *argv, VALUE self)
-{
- VALUE _r, _g, _b, _a, _color;
- argc = rb_scan_args(argc, argv, "13", &_r, &_g, &_b, &_a);
-
- if (argc == 1 && rb_obj_is_kind_of(_r, cColor))
- _color = _r;
- else if (argc == 1 && rb_obj_is_kind_of(_r, rb_cString))
- _color = shoes_color_parse(cColor, _r);
- else if (argc == 1 || argc == 2)
- _color = shoes_color_gray(argc, argv, cColor);
- else
- _color = shoes_color_rgb(argc, argv, cColor);
-
- return _color;
-}
-
-#define NEW_COLOR(v, o) \
- shoes_color *v; \
- VALUE o = shoes_color_alloc(cColor); \
- Data_Get_Struct(o, shoes_color, v)
-
-VALUE
-shoes_color_parse(VALUE self, VALUE source)
-{
- VALUE reg;
-
- reg = rb_funcall(source, s_match, 1, reHEX3_SOURCE);
- if (!NIL_P(reg))
- {
- NEW_COLOR(color, obj);
- color->r = NUM2INT(rb_str2inum(rb_reg_nth_match(1, reg), 16)) * 17;
- color->g = NUM2INT(rb_str2inum(rb_reg_nth_match(2, reg), 16)) * 17;
- color->b = NUM2INT(rb_str2inum(rb_reg_nth_match(3, reg), 16)) * 17;
- return obj;
- }
-
- reg = rb_funcall(source, s_match, 1, reHEX_SOURCE);
- if (!NIL_P(reg))
- {
- NEW_COLOR(color, obj);
- color->r = NUM2INT(rb_str2inum(rb_reg_nth_match(1, reg), 16));
- color->g = NUM2INT(rb_str2inum(rb_reg_nth_match(2, reg), 16));
- color->b = NUM2INT(rb_str2inum(rb_reg_nth_match(3, reg), 16));
- return obj;
- }
-
- reg = rb_funcall(source, s_match, 1, reRGB_SOURCE);
- if (!NIL_P(reg))
- {
- NEW_COLOR(color, obj);
- color->r = NUM2INT(rb_Integer(rb_reg_nth_match(1, reg)));
- color->g = NUM2INT(rb_Integer(rb_reg_nth_match(2, reg)));
- color->b = NUM2INT(rb_Integer(rb_reg_nth_match(3, reg)));
- return obj;
- }
-
- reg = rb_funcall(source, s_match, 1, reRGBA_SOURCE);
- if (!NIL_P(reg))
- {
- NEW_COLOR(color, obj);
- color->r = NUM2INT(rb_Integer(rb_reg_nth_match(1, reg)));
- color->g = NUM2INT(rb_Integer(rb_reg_nth_match(2, reg)));
- color->b = NUM2INT(rb_Integer(rb_reg_nth_match(3, reg)));
- color->a = NUM2INT(rb_Integer(rb_reg_nth_match(4, reg)));
- return obj;
- }
-
- reg = rb_funcall(source, s_match, 1, reGRAY_SOURCE);
- if (!NIL_P(reg))
- {
- NEW_COLOR(color, obj);
- color->r = color->g = color->b = NUM2INT(rb_Integer(rb_reg_nth_match(1, reg)));
- return obj;
- }
-
- reg = rb_funcall(source, s_match, 1, reGRAYA_SOURCE);
- if (!NIL_P(reg))
- {
- NEW_COLOR(color, obj);
- color->r = color->g = color->b = NUM2INT(rb_Integer(rb_reg_nth_match(1, reg)));
- color->a = NUM2INT(rb_Integer(rb_reg_nth_match(2, reg)));
- return obj;
- }
-
- return Qnil;
-}
-
-VALUE
-shoes_color_spaceship(VALUE self, VALUE c2)
-{
- int v1, v2;
- shoes_color *color2;
- GET_STRUCT(color, color);
- if (!rb_obj_is_kind_of(c2, cColor)) return Qnil;
- Data_Get_Struct(c2, shoes_color, color2);
- v1 = color->r + color->g + color->b;
- v2 = color2->r + color2->g + color2->b;
- if (v1 == v2) return INT2FIX(0);
- if (v1 > v2) return INT2FIX(1);
- else return INT2FIX(-1);
-}
-
-VALUE
-shoes_color_equal(VALUE self, VALUE c2)
-{
- if (!rb_obj_is_kind_of(c2, cColor)) return Qnil;
-
- GET_STRUCT(color, color);
- shoes_color *color2;
- Data_Get_Struct(c2, shoes_color, color2);
- if (color->r == color2->r && color->g == color2->g &&
- color->b == color2->b && color->a == color2->a ) {
- return Qtrue;
- } else return Qfalse;
-}
-
-VALUE
-shoes_color_get_red(VALUE self)
-{
- GET_STRUCT(color, color);
- return INT2NUM(color->r);
-}
-
-VALUE
-shoes_color_get_green(VALUE self)
-{
- GET_STRUCT(color, color);
- return INT2NUM(color->g);
-}
-
-VALUE
-shoes_color_get_blue(VALUE self)
-{
- GET_STRUCT(color, color);
- return INT2NUM(color->b);
-}
-
-VALUE
-shoes_color_get_alpha(VALUE self)
-{
- GET_STRUCT(color, color);
- return INT2NUM(color->a);
-}
-
-VALUE
-shoes_color_is_black(VALUE self)
-{
- GET_STRUCT(color, color);
- return (color->r + color->g + color->b == 0) ? Qtrue : Qfalse;
-}
-
-VALUE
-shoes_color_is_dark(VALUE self)
-{
- GET_STRUCT(color, color);
- return ((int)color->r + (int)color->g + (int)color->b < SHOES_COLOR_DARK) ? Qtrue : Qfalse;
-}
-
-VALUE
-shoes_color_is_light(VALUE self)
-{
- GET_STRUCT(color, color);
- return ((int)color->r + (int)color->g + (int)color->b > SHOES_COLOR_LIGHT) ? Qtrue : Qfalse;
-}
-
-VALUE
-shoes_color_is_opaque(VALUE self)
-{
- GET_STRUCT(color, color);
- return (color->a == SHOES_COLOR_OPAQUE) ? Qtrue : Qfalse;
-}
-
-VALUE
-shoes_color_is_transparent(VALUE self)
-{
- GET_STRUCT(color, color);
- return (color->a == SHOES_COLOR_TRANSPARENT) ? Qtrue : Qfalse;
-}
-
-VALUE
-shoes_color_is_white(VALUE self)
-{
- GET_STRUCT(color, color);
- return (color->r + color->g + color->b == 765) ? Qtrue : Qfalse;
-}
-
-VALUE
-shoes_color_invert(VALUE self)
-{
- GET_STRUCT(color, color);
- NEW_COLOR(color2, obj);
- color2->r = 255 - color->r; color2->g = 255 - color->g; color2->b = 255 - color->b; color2->a = color->a;
- return obj;
-}
-
-VALUE
-shoes_color_to_s(VALUE self)
-{
- GET_STRUCT(color, color);
-
- VALUE ary = rb_ary_new3(4,
- INT2NUM(color->r), INT2NUM(color->g), INT2NUM(color->b),
- rb_float_new((color->a * 1.) / 255.));
-
- if (color->a == 255)
- return rb_funcall(rb_str_new2("rgb(%d, %d, %d)"), s_perc, 1, ary);
- else
- return rb_funcall(rb_str_new2("rgb(%d, %d, %d, %0.1f)"), s_perc, 1, ary);
-}
-
-VALUE
-shoes_color_to_pattern(VALUE self)
-{
- return shoes_pattern_method(cPattern, self);
-}
-
-VALUE
-shoes_color_method_missing(int argc, VALUE *argv, VALUE self)
-{
- VALUE alpha;
- VALUE cname = argv[0];
- VALUE c = Qnil;
- if (rb_obj_is_kind_of(cColors, rb_cHash))
- c = rb_hash_aref(cColors, cname);
- if (NIL_P(c))
- {
- self = rb_inspect(self);
- rb_raise(rb_eNoMethodError, "undefined method `%s' for %s",
- rb_id2name(SYM2ID(cname)), RSTRING_PTR(self));
- }
-
- rb_scan_args(argc, argv, "11", &cname, &alpha);
- if (!NIL_P(alpha))
- {
- shoes_color *color;
- Data_Get_Struct(c, shoes_color, color);
- c = shoes_color_new(color->r, color->g, color->b, NUM2RGBINT(alpha));
- }
-
- return c;
-}
-
-VALUE
-shoes_app_method_missing(int argc, VALUE *argv, VALUE self)
-{
- VALUE cname, canvas;
- GET_STRUCT(app, app);
-
- cname = argv[0];
- canvas = rb_ary_entry(app->nesting, RARRAY_LEN(app->nesting) - 1);
- if (!NIL_P(canvas) && rb_respond_to(canvas, SYM2ID(cname)))
- return ts_funcall2(canvas, SYM2ID(cname), argc - 1, argv + 1);
- return shoes_color_method_missing(argc, argv, self);
-}
-
-//
-// Shoes::LinkUrl
-//
-void
-shoes_link_mark(shoes_link *link)
-{
-}
-
-static void
-shoes_link_free(shoes_link *link)
-{
- RUBY_CRITICAL(free(link));
-}
-
-VALUE
-shoes_link_new(VALUE ele, int start, int end)
-{
- shoes_link *link;
- VALUE obj = shoes_link_alloc(cLinkUrl);
- Data_Get_Struct(obj, shoes_link, link);
- link->ele = ele;
- link->start = start;
- link->end = end;
- return obj;
-}
-
-VALUE
-shoes_link_alloc(VALUE klass)
-{
- VALUE obj;
- shoes_link *link = SHOE_ALLOC(shoes_link);
- SHOE_MEMZERO(link, shoes_link, 1);
- obj = Data_Wrap_Struct(klass, shoes_link_mark, shoes_link_free, link);
- link->ele = Qnil;
- return obj;
-}
-
-static VALUE
-shoes_link_at(shoes_textblock *t, VALUE self, int index, int blockhover, VALUE *clicked, char *touch)
-{
- char h = 0;
- VALUE url = Qnil;
- shoes_text *self_t;
-
- GET_STRUCT(link, link);
- Data_Get_Struct(link->ele, shoes_text, self_t);
- if (blockhover && link->start <= index && link->end >= index)
- {
- h = 1;
- if (clicked != NULL) *clicked = link->ele;
- url = ATTR(self_t->attr, click);
- }
-
- self = link->ele;
- CHECK_HOVER(self_t, h, touch);
- t->hover = (t->hover & HOVER_CLICK) | h;
-
- return url;
-}
-
-//
-// Shoes::Text
-//
-void
-shoes_text_mark(shoes_text *text)
-{
- rb_gc_mark_maybe(text->texts);
- rb_gc_mark_maybe(text->attr);
- rb_gc_mark_maybe(text->parent);
-}
-
-static void
-shoes_text_free(shoes_text *text)
-{
- RUBY_CRITICAL(free(text));
-}
-
-static VALUE
-shoes_text_check(VALUE texts, VALUE parent)
-{
- long i;
- for (i = 0; i < RARRAY_LEN(texts); i++)
- {
- VALUE ele = rb_ary_entry(texts, i);
- if (rb_obj_is_kind_of(ele, cTextClass))
- {
- shoes_text *text;
- Data_Get_Struct(ele, shoes_text, text);
- text->parent = parent;
- }
- }
- return texts;
-}
-
-VALUE
-shoes_text_to_s(VALUE self)
-{
- GET_STRUCT(textblock, self_t);
- return rb_funcall(self_t->texts, s_to_s, 0);
-}
-
-VALUE
-shoes_text_new(VALUE klass, VALUE texts, VALUE attr)
-{
- shoes_text *text;
- VALUE obj = shoes_text_alloc(klass);
- Data_Get_Struct(obj, shoes_text, text);
- text->hover = 0;
- text->texts = shoes_text_check(texts, obj);
- text->attr = attr;
- return obj;
-}
-
-VALUE
-shoes_text_alloc(VALUE klass)
-{
- VALUE obj;
- shoes_text *text = SHOE_ALLOC(shoes_text);
- SHOE_MEMZERO(text, shoes_text, 1);
- obj = Data_Wrap_Struct(klass, shoes_text_mark, shoes_text_free, text);
- text->texts = Qnil;
- text->attr = Qnil;
- text->parent = Qnil;
- return obj;
-}
-
-VALUE
-shoes_text_parent(VALUE self)
-{
- GET_STRUCT(text, text);
- return text->parent;
-}
-
-VALUE
-shoes_text_children(VALUE self)
-{
- GET_STRUCT(text, text);
- return text->texts;
-}
-
-//
-// Shoes::TextBlock
-//
-void
-shoes_textblock_mark(shoes_textblock *text)
-{
- rb_gc_mark_maybe(text->texts);
- rb_gc_mark_maybe(text->links);
- rb_gc_mark_maybe(text->attr);
- rb_gc_mark_maybe(text->parent);
-}
-
-//
-// Frees the pango attribute list.
-// The `all` flag means the string has changed as well.
-//
-static void
-shoes_textblock_uncache(shoes_textblock *text, unsigned char all)
-{
- if (text->pattr != NULL)
- pango_attr_list_unref(text->pattr);
- text->pattr = NULL;
- if (all)
- {
- if (text->text != NULL)
- g_string_free(text->text, TRUE);
- text->text = NULL;
- text->cached = 0;
- }
-}
-
-static void
-shoes_textblock_free(shoes_textblock *text)
-{
- shoes_transform_release(text->st);
- shoes_textblock_uncache(text, TRUE);
- if (text->cursor != NULL)
- SHOE_FREE(text->cursor);
- if (text->layout != NULL)
- g_object_unref(text->layout);
- RUBY_CRITICAL(free(text));
-}
-
-VALUE
-shoes_textblock_new(VALUE klass, VALUE texts, VALUE attr, VALUE parent, shoes_transform *st)
-{
- shoes_canvas *canvas;
- shoes_textblock *text;
- VALUE obj = shoes_textblock_alloc(klass);
- Data_Get_Struct(obj, shoes_textblock, text);
- Data_Get_Struct(parent, shoes_canvas, canvas);
- text->texts = shoes_text_check(texts, obj);
- text->attr = attr;
- text->parent = parent;
- text->st = shoes_transform_touch(st);
- return obj;
-}
-
-VALUE
-shoes_textblock_alloc(VALUE klass)
-{
- VALUE obj;
- shoes_textblock *text = SHOE_ALLOC(shoes_textblock);
- SHOE_MEMZERO(text, shoes_textblock, 1);
- obj = Data_Wrap_Struct(klass, shoes_textblock_mark, shoes_textblock_free, text);
- text->texts = Qnil;
- text->links = Qnil;
- text->attr = Qnil;
- text->parent = Qnil;
- text->cursor = NULL;
- return obj;
-}
-
-VALUE
-shoes_textblock_children(VALUE self)
-{
- GET_STRUCT(textblock, text);
- return text->texts;
-}
-
-static void
-shoes_textcursor_reset(shoes_textcursor *c)
-{
- c->pos = c->hi = c->x = c->y = INT_MAX;
-}
-
-VALUE
-shoes_textblock_set_cursor(VALUE self, VALUE pos)
-{
- GET_STRUCT(textblock, self_t);
- if (self_t->cursor == NULL)
- {
- if (NIL_P(pos)) return Qnil;
- else shoes_textcursor_reset(self_t->cursor = SHOE_ALLOC(shoes_textcursor));
- }
-
- if (NIL_P(pos)) shoes_textcursor_reset(self_t->cursor);
- else if (pos == ID2SYM(s_marker)) {
- if (self_t->cursor->hi != INT_MAX) {
- self_t->cursor->pos = min(self_t->cursor->pos, self_t->cursor->hi);
- self_t->cursor->hi = INT_MAX;
- }
- }
- else self_t->cursor->pos = NUM2INT(pos);
- shoes_textblock_uncache(self_t, FALSE);
- shoes_canvas_repaint_all(self_t->parent);
- return pos;
-}
-
-VALUE
-shoes_textblock_get_cursor(VALUE self)
-{
- GET_STRUCT(textblock, self_t);
- if (self_t->cursor == NULL || self_t->cursor->pos == INT_MAX) return Qnil;
- return INT2NUM(self_t->cursor->pos);
-}
-
-VALUE
-shoes_textblock_cursorx(VALUE self)
-{
- GET_STRUCT(textblock, self_t);
- if (self_t->cursor == NULL || self_t->cursor->x == INT_MAX) return Qnil;
- return INT2NUM(self_t->cursor->x);
-}
-
-VALUE
-shoes_textblock_cursory(VALUE self)
-{
- GET_STRUCT(textblock, self_t);
- if (self_t->cursor == NULL || self_t->cursor->y == INT_MAX) return Qnil;
- return INT2NUM(self_t->cursor->y);
-}
-
-VALUE
-shoes_textblock_set_marker(VALUE self, VALUE pos)
-{
- GET_STRUCT(textblock, self_t);
- if (self_t->cursor == NULL)
- {
- if (NIL_P(pos)) return Qnil;
- else shoes_textcursor_reset(self_t->cursor = SHOE_ALLOC(shoes_textcursor));
- }
-
- if (NIL_P(pos)) self_t->cursor->hi = INT_MAX;
- else self_t->cursor->hi = NUM2INT(pos);
- shoes_textblock_uncache(self_t, FALSE);
- shoes_canvas_repaint_all(self_t->parent);
- return pos;
-}
-
-VALUE
-shoes_textblock_get_marker(VALUE self)
-{
- GET_STRUCT(textblock, self_t);
- if (self_t->cursor == NULL || self_t->cursor->hi == INT_MAX) return Qnil;
- return INT2NUM(self_t->cursor->hi);
-}
-
-VALUE
-shoes_textblock_get_highlight(VALUE self)
-{
- int marker, start, len;
- GET_STRUCT(textblock, self_t);
- if (self_t->cursor == NULL || self_t->cursor->pos == INT_MAX) return Qnil;
- marker = self_t->cursor->hi;
- if (marker == INT_MAX) marker = self_t->cursor->pos;
- start = min(self_t->cursor->pos, marker);
- len = max(self_t->cursor->pos, marker) - start;
- return rb_ary_new3(2, INT2NUM(start), INT2NUM(len));
-}
-
-static VALUE
-shoes_find_textblock(VALUE self)
-{
- while (!NIL_P(self) && !rb_obj_is_kind_of(self, cTextBlock))
- {
- SETUP_BASIC();
- self = basic->parent;
- }
- return self;
-}
-
-static VALUE
-shoes_textblock_send_hover(VALUE self, int x, int y, VALUE *clicked, char *t)
-{
- VALUE url = Qnil;
- int index, trailing, i, hover;
- GET_STRUCT(textblock, self_t);
- if (self_t->layout == NULL || NIL_P(self_t->links)) return Qnil;
- if (!NIL_P(self_t->attr) && ATTR(self_t->attr, hidden) == Qtrue) return Qnil;
-
- x -= self_t->place.ix + self_t->place.dx;
- y -= self_t->place.iy + self_t->place.dy;
- hover = pango_layout_xy_to_index(self_t->layout, x * PANGO_SCALE, y * PANGO_SCALE, &index, &trailing);
- if (hover != (self_t->hover & HOVER_MOTION))
- {
- shoes_textblock_uncache(self_t, FALSE);
- INFO("HOVER (%d, %d) OVER (%d, %d)\n", x, y, self_t->place.ix + self_t->place.dx, self_t->place.iy + self_t->place.dy);
- }
- for (i = 0; i < RARRAY_LEN(self_t->links); i++)
- {
- VALUE urll = shoes_link_at(self_t, rb_ary_entry(self_t->links, i), index, hover, clicked, t);
- if (NIL_P(url)) url = urll;
- }
-
- return url;
-}
-
-VALUE
-shoes_textblock_motion(VALUE self, int x, int y, char *t)
-{
- VALUE url = shoes_textblock_send_hover(self, x, y, NULL, t);
- if (!NIL_P(url))
- {
- shoes_canvas *canvas;
- GET_STRUCT(textblock, self_t);
- Data_Get_Struct(self_t->parent, shoes_canvas, canvas);
- shoes_app_cursor(canvas->app, s_link);
- }
- return url;
-}
-
-VALUE
-shoes_textblock_hit(VALUE self, VALUE _x, VALUE _y)
-{
- int x = NUM2INT(_x), y = NUM2INT(_y), index, trailing;
- GET_STRUCT(textblock, self_t);
- x -= self_t->place.ix + self_t->place.dx;
- y -= self_t->place.iy + self_t->place.dy;
- if (x < 0 || x > self_t->place.iw || y < 0 || y > self_t->place.ih)
- return Qnil;
- pango_layout_xy_to_index(self_t->layout, x * PANGO_SCALE, y * PANGO_SCALE, &index, &trailing);
- return INT2NUM(index);
-}
-
-VALUE
-shoes_textblock_send_click(VALUE self, int button, int x, int y, VALUE *clicked)
-{
- VALUE v = Qnil;
-
- if (button > 0)
- {
- GET_STRUCT(textblock, self_t);
- v = shoes_textblock_send_hover(self, x, y, clicked, NULL);
- if (self_t->hover & HOVER_MOTION)
- self_t->hover = HOVER_MOTION | HOVER_CLICK;
- }
-
- return v;
-}
-
-void
-shoes_textblock_send_release(VALUE self, int button, int x, int y)
-{
- GET_STRUCT(textblock, self_t);
- if (button > 0 && (self_t->hover & HOVER_CLICK))
- {
- VALUE proc = ATTR(self_t->attr, release);
- self_t->hover ^= HOVER_CLICK;
- if (!NIL_P(proc))
- shoes_safe_block(self, proc, rb_ary_new3(1, self));
- }
-}
-
-#define APPLY_ATTR() \
- if (attr != NULL) { \
- attr->start_index = start_index; \
- attr->end_index = end_index; \
- pango_attr_list_insert_before(block->pattr, attr); \
- attr = NULL; \
- }
-
-#define GET_STYLE(name) \
- attr = NULL; \
- str = Qnil; \
- if (!NIL_P(oattr)) str = rb_hash_aref(oattr, ID2SYM(s_##name)); \
- if (!NIL_P(hsh) && NIL_P(str)) str = rb_hash_aref(hsh, ID2SYM(s_##name))
-
-#define APPLY_STYLE_COLOR(name, func) \
- GET_STYLE(name); \
- if (!NIL_P(str)) \
- { \
- if (TYPE(str) == T_STRING) \
- str = shoes_color_parse(cColor, str); \
- if (rb_obj_is_kind_of(str, cColor)) \
- { \
- shoes_color *color; \
- Data_Get_Struct(str, shoes_color, color); \
- attr = pango_attr_##func##_new(color->r * 255, color->g * 255, color-> b * 255); \
- } \
- APPLY_ATTR(); \
- }
-
-static void
-shoes_app_style_for(shoes_textblock *block, shoes_app *app, VALUE klass, VALUE oattr, guint start_index, guint end_index)
-{
- VALUE str = Qnil;
- VALUE hsh = rb_hash_aref(app->styles, klass);
- if (NIL_P(hsh) && NIL_P(oattr)) return;
-
- PangoAttribute *attr = NULL;
-
- APPLY_STYLE_COLOR(stroke, foreground);
- APPLY_STYLE_COLOR(fill, background);
- APPLY_STYLE_COLOR(strikecolor, strikethrough_color);
- APPLY_STYLE_COLOR(undercolor, underline_color);
-
- GET_STYLE(font);
- if (!NIL_P(str))
- {
- if (TYPE(str) == T_STRING)
- {
- attr = pango_attr_font_desc_new(pango_font_description_from_string(RSTRING_PTR(str)));
- }
- APPLY_ATTR();
- }
-
- GET_STYLE(size);
- if (!NIL_P(str))
- {
- if (TYPE(str) == T_STRING)
- {
- if (strncmp(RSTRING_PTR(str), "xx-small", 8) == 0)
- attr = pango_attr_scale_new(PANGO_SCALE_XX_SMALL);
- else if (strncmp(RSTRING_PTR(str), "x-small", 7) == 0)
- attr = pango_attr_scale_new(PANGO_SCALE_X_SMALL);
- else if (strncmp(RSTRING_PTR(str), "small", 5) == 0)
- attr = pango_attr_scale_new(PANGO_SCALE_SMALL);
- else if (strncmp(RSTRING_PTR(str), "medium", 6) == 0)
- attr = pango_attr_scale_new(PANGO_SCALE_MEDIUM);
- else if (strncmp(RSTRING_PTR(str), "large", 5) == 0)
- attr = pango_attr_scale_new(PANGO_SCALE_LARGE);
- else if (strncmp(RSTRING_PTR(str), "x-large", 7) == 0)
- attr = pango_attr_scale_new(PANGO_SCALE_X_LARGE);
- else if (strncmp(RSTRING_PTR(str), "xx-large", 8) == 0)
- attr = pango_attr_scale_new(PANGO_SCALE_XX_LARGE);
- else
- str = rb_funcall(str, s_to_i, 0);
- }
- if (TYPE(str) == T_FIXNUM)
- {
- int i = NUM2INT(str);
- if (i > 0)
- attr = pango_attr_size_new_absolute(ROUND(i * PANGO_SCALE * (96./72.)));
- }
- APPLY_ATTR();
- }
-
- GET_STYLE(family);
- if (!NIL_P(str))
- {
- if (TYPE(str) == T_STRING)
- {
- attr = pango_attr_family_new(RSTRING_PTR(str));
- }
- APPLY_ATTR();
- }
-
- GET_STYLE(weight);
- if (!NIL_P(str))
- {
- if (TYPE(str) == T_STRING)
- {
- if (strncmp(RSTRING_PTR(str), "ultralight", 10) == 0)
- attr = pango_attr_weight_new(PANGO_WEIGHT_ULTRALIGHT);
- else if (strncmp(RSTRING_PTR(str), "light", 5) == 0)
- attr = pango_attr_weight_new(PANGO_WEIGHT_LIGHT);
- else if (strncmp(RSTRING_PTR(str), "normal", 6) == 0)
- attr = pango_attr_weight_new(PANGO_WEIGHT_NORMAL);
- else if (strncmp(RSTRING_PTR(str), "semibold", 8) == 0)
- attr = pango_attr_weight_new(PANGO_WEIGHT_SEMIBOLD);
- else if (strncmp(RSTRING_PTR(str), "bold", 4) == 0)
- attr = pango_attr_weight_new(PANGO_WEIGHT_BOLD);
- else if (strncmp(RSTRING_PTR(str), "ultrabold", 9) == 0)
- attr = pango_attr_weight_new(PANGO_WEIGHT_ULTRABOLD);
- else if (strncmp(RSTRING_PTR(str), "heavy", 5) == 0)
- attr = pango_attr_weight_new(PANGO_WEIGHT_HEAVY);
- }
- else if (TYPE(str) == T_FIXNUM)
- {
- int i = NUM2INT(str);
- if (i >= 100 && i <= 900)
- attr = pango_attr_weight_new((PangoWeight)i);
- }
- APPLY_ATTR();
- }
-
- GET_STYLE(rise);
- if (!NIL_P(str))
- {
- if (TYPE(str) == T_STRING)
- str = rb_funcall(str, s_to_i, 0);
- if (TYPE(str) == T_FIXNUM)
- {
- int i = NUM2INT(str);
- attr = pango_attr_rise_new(i * PANGO_SCALE);
- }
- APPLY_ATTR();
- }
-
- GET_STYLE(kerning);
- if (!NIL_P(str))
- {
- if (TYPE(str) == T_STRING)
- str = rb_funcall(str, s_to_i, 0);
- if (TYPE(str) == T_FIXNUM)
- {
- int i = NUM2INT(str);
- attr = pango_attr_letter_spacing_new(i * PANGO_SCALE);
- }
- APPLY_ATTR();
- }
-
- GET_STYLE(emphasis);
- if (!NIL_P(str))
- {
- if (TYPE(str) == T_STRING)
- {
- if (strncmp(RSTRING_PTR(str), "normal", 6) == 0)
- attr = pango_attr_style_new(PANGO_STYLE_NORMAL);
- else if (strncmp(RSTRING_PTR(str), "oblique", 7) == 0)
- attr = pango_attr_style_new(PANGO_STYLE_OBLIQUE);
- else if (strncmp(RSTRING_PTR(str), "italic", 6) == 0)
- attr = pango_attr_style_new(PANGO_STYLE_ITALIC);
- }
- APPLY_ATTR();
- }
-
- GET_STYLE(strikethrough);
- if (!NIL_P(str))
- {
- if (TYPE(str) == T_STRING)
- {
- if (strncmp(RSTRING_PTR(str), "none", 4) == 0)
- attr = pango_attr_strikethrough_new(FALSE);
- else if (strncmp(RSTRING_PTR(str), "single", 6) == 0)
- attr = pango_attr_strikethrough_new(TRUE);
- }
- APPLY_ATTR();
- }
-
- GET_STYLE(stretch);
- if (!NIL_P(str))
- {
- if (TYPE(str) == T_STRING)
- {
- if (strncmp(RSTRING_PTR(str), "condensed", 9) == 0)
- attr = pango_attr_stretch_new(PANGO_STRETCH_CONDENSED);
- else if (strncmp(RSTRING_PTR(str), "normal", 6) == 0)
- attr = pango_attr_stretch_new(PANGO_STRETCH_NORMAL);
- else if (strncmp(RSTRING_PTR(str), "expanded", 8) == 0)
- attr = pango_attr_stretch_new(PANGO_STRETCH_EXPANDED);
- }
- APPLY_ATTR();
- }
-
- GET_STYLE(underline);
- if (!NIL_P(str))
- {
- if (TYPE(str) == T_STRING)
- {
- if (strncmp(RSTRING_PTR(str), "none", 4) == 0)
- attr = pango_attr_underline_new(PANGO_UNDERLINE_NONE);
- else if (strncmp(RSTRING_PTR(str), "single", 6) == 0)
- attr = pango_attr_underline_new(PANGO_UNDERLINE_SINGLE);
- else if (strncmp(RSTRING_PTR(str), "double", 6) == 0)
- attr = pango_attr_underline_new(PANGO_UNDERLINE_DOUBLE);
- else if (strncmp(RSTRING_PTR(str), "low", 3) == 0)
- attr = pango_attr_underline_new(PANGO_UNDERLINE_LOW);
- else if (strncmp(RSTRING_PTR(str), "error", 5) == 0)
- attr = pango_attr_underline_new(PANGO_UNDERLINE_ERROR);
- }
- APPLY_ATTR();
- }
-
- GET_STYLE(variant);
- if (!NIL_P(str))
- {
- if (TYPE(str) == T_STRING)
- {
- if (strncmp(RSTRING_PTR(str), "normal", 6) == 0)
- attr = pango_attr_variant_new(PANGO_VARIANT_NORMAL);
- else if (strncmp(RSTRING_PTR(str), "smallcaps", 9) == 0)
- attr = pango_attr_variant_new(PANGO_VARIANT_SMALL_CAPS);
- }
- APPLY_ATTR();
- }
-}
-
-static void
-shoes_textblock_iter_pango(VALUE texts, shoes_textblock *block, shoes_app *app)
-{
- VALUE v;
- long i;
-
- if (NIL_P(texts))
- return;
-
- for (i = 0; i < RARRAY_LEN(texts); i++)
- {
- v = rb_ary_entry(texts, i);
- if (rb_obj_is_kind_of(v, cTextClass))
- {
- VALUE tklass = rb_obj_class(v);
- guint start;
- shoes_text *text;
- Data_Get_Struct(v, shoes_text, text);
-
- start = block->len;
- shoes_textblock_iter_pango(text->texts, block, app);
- if ((text->hover & HOVER_MOTION) && tklass == cLink)
- tklass = cLinkHover;
- shoes_app_style_for(block, app, tklass, text->attr, start, block->len);
- if (!block->cached && rb_obj_is_kind_of(v, cLink) && !NIL_P(text->attr))
- {
- rb_ary_push(block->links, shoes_link_new(v, start, block->len));
- }
- }
- else if (rb_obj_is_kind_of(v, rb_cArray))
- {
- shoes_textblock_iter_pango(v, block, app);
- }
- else
- {
- char *start, *end;
- v = rb_funcall(v, s_to_s, 0);
- block->len += (guint)RSTRING_LEN(v);
- if (!block->cached)
- {
- start = RSTRING_PTR(v);
- if (!g_utf8_validate(start, RSTRING_LEN(v), (const gchar **)&end))
- shoes_error("not a valid UTF-8 string: %.*s", end - start, start);
- if (end > start)
- g_string_append_len(block->text, start, end - start);
- }
- }
- }
-}
-
-static void
-shoes_textblock_make_pango(shoes_app *app, VALUE klass, shoes_textblock *block)
-{
- if (!block->cached)
- {
- block->text = g_string_new(NULL);
- block->links = rb_ary_new();
- }
- block->len = 0;
- block->pattr = pango_attr_list_new();
-
- shoes_textblock_iter_pango(block->texts, block, app);
- shoes_app_style_for(block, app, klass, block->attr, 0, block->len);
-
- if (block->cursor != NULL && block->cursor->pos != INT_MAX &&
- block->cursor->hi != INT_MAX && block->cursor->pos != block->cursor->hi)
- {
- PangoAttribute *attr = pango_attr_background_new(255 * 255, 255 * 255, 0);
- attr->start_index = min(block->cursor->pos, block->cursor->hi);
- attr->end_index = max(block->cursor->pos, block->cursor->hi);
- pango_attr_list_insert(block->pattr, attr);
- }
-
- block->cached = 1;
-}
-
-static void
-shoes_textblock_on_layout(shoes_app *app, VALUE klass, shoes_textblock *block)
-{
- char *attr = NULL;
- VALUE str = Qnil, hsh = Qnil, oattr = Qnil;
- g_return_if_fail(block != NULL);
- g_return_if_fail(PANGO_IS_LAYOUT(block->layout));
-
- oattr = block->attr;
- hsh = rb_hash_aref(app->styles, klass);
-
- if (!block->cached || block->pattr == NULL)
- shoes_textblock_make_pango(app, klass, block);
- pango_layout_set_text(block->layout, block->text->str, -1);
- pango_layout_set_attributes(block->layout, block->pattr);
-
- GET_STYLE(justify);
- if (!NIL_P(str))
- pango_layout_set_justify(block->layout, RTEST(str));
-
- GET_STYLE(align);
- if (TYPE(str) == T_STRING)
- {
- if (strncmp(RSTRING_PTR(str), "left", 4) == 0)
- pango_layout_set_alignment(block->layout, PANGO_ALIGN_LEFT);
- else if (strncmp(RSTRING_PTR(str), "center", 6) == 0)
- pango_layout_set_alignment(block->layout, PANGO_ALIGN_CENTER);
- else if (strncmp(RSTRING_PTR(str), "right", 5) == 0)
- pango_layout_set_alignment(block->layout, PANGO_ALIGN_RIGHT);
- }
-
- GET_STYLE(wrap);
- if (TYPE(str) == T_STRING)
- {
- if (strncmp(RSTRING_PTR(str), "word", 4) == 0)
- pango_layout_set_wrap(block->layout, PANGO_WRAP_WORD);
- else if (strncmp(RSTRING_PTR(str), "char", 4) == 0)
- pango_layout_set_wrap(block->layout, PANGO_WRAP_CHAR);
- else if (strncmp(RSTRING_PTR(str), "trim", 4) == 0)
- pango_layout_set_ellipsize(block->layout, PANGO_ELLIPSIZE_END);
- }
-}
-
-VALUE
-shoes_textblock_draw(VALUE self, VALUE c, VALUE actual)
-{
- double crx = 0., cry = 0.;
- int px, py, pd, li, ld;
- cairo_t *cr;
- shoes_canvas *canvas;
- PangoLayoutLine *last;
- PangoRectangle crect, lrect;
-
- VALUE ck = rb_obj_class(c);
- GET_STRUCT(textblock, self_t);
- Data_Get_Struct(c, shoes_canvas, canvas);
- cr = CCR(canvas);
-
- if (!NIL_P(self_t->attr) && ATTR(self_t->attr, hidden) == Qtrue)
- return self;
-
- ATTR_MARGINS(self_t->attr, 4, canvas);
- if (NIL_P(ATTR(self_t->attr, margin)) && NIL_P(ATTR(self_t->attr, margin_bottom)))
- bmargin = 12;
- self_t->place.flags = REL_CANVAS;
- self_t->place.flags |= NIL_P(ATTR(self_t->attr, left)) && NIL_P(ATTR(self_t->attr, right)) ? 0 : FLAG_ABSX;
- self_t->place.flags |= NIL_P(ATTR(self_t->attr, top)) && NIL_P(ATTR(self_t->attr, bottom)) ? 0 : FLAG_ABSY;
- self_t->place.x = ATTR2(int, self_t->attr, left, canvas->cx);
- self_t->place.y = ATTR2(int, self_t->attr, top, canvas->cy);
- if (!ORIGIN(canvas->place))
- {
- self_t->place.dx = canvas->place.dx;
- self_t->place.dy = canvas->place.dy;
- }
- else
- {
- self_t->place.dx = 0;
- self_t->place.dy = 0;
- }
- self_t->place.dx += PXN(self_t->attr, displace_left, 0, CPW(canvas));
- self_t->place.dy += PXN(self_t->attr, displace_top, 0, CPH(canvas));
- self_t->place.w = ATTR2(int, self_t->attr, width, canvas->place.iw - (canvas->cx - self_t->place.x));
- self_t->place.iw = self_t->place.w - (lmargin + rmargin);
- ld = ATTR2(int, self_t->attr, leading, 4);
-
- if (self_t->layout != NULL)
- g_object_unref(self_t->layout);
-
- self_t->layout = pango_cairo_create_layout(cr);
- pd = 0;
- if (!ABSX(self_t->place) && self_t->place.x == canvas->cx)
- {
- if (self_t->place.x - CPX(canvas) > self_t->place.w)
- {
- self_t->place.x = CPX(canvas);
- canvas->cy = self_t->place.y = canvas->endy;
- }
- else
- {
- if (self_t->place.x > CPX(canvas)) {
- pd = self_t->place.x - CPX(canvas);
- pango_layout_set_indent(self_t->layout, pd * PANGO_SCALE);
- self_t->place.x = CPX(canvas);
- }
- }
- }
-
- pango_layout_set_width(self_t->layout, self_t->place.iw * PANGO_SCALE);
- pango_layout_set_spacing(self_t->layout, ld * PANGO_SCALE);
- shoes_textblock_on_layout(canvas->app, rb_obj_class(self), self_t);
- pango_layout_set_font_description(self_t->layout, shoes_world->default_font);
-
- //
- // Line up the first line with the y-cursor
- //
- if (!ABSX(self_t->place) && !ABSY(self_t->place) && pd)
- {
- last = pango_layout_get_line(self_t->layout, 0);
- pango_layout_line_get_pixel_extents(last, NULL, &lrect);
- if (lrect.width > self_t->place.iw - pd)
- {
- pango_layout_set_indent(self_t->layout, 0);
- self_t->place.x = CPX(canvas);
- canvas->cy = self_t->place.y = canvas->endy;
- pd = 0;
- }
- }
- self_t->place.ix = self_t->place.x + lmargin;
- self_t->place.iy = self_t->place.y + tmargin;
-
- li = pango_layout_get_line_count(self_t->layout) - 1;
- last = pango_layout_get_line(self_t->layout, li);
- pango_layout_line_get_pixel_extents(last, NULL, &lrect);
- pango_layout_get_pixel_size(self_t->layout, &px, &py);
-
- if (self_t->cursor != NULL && self_t->cursor->pos != INT_MAX)
- {
- int cursor = self_t->cursor->pos;
- if (cursor < 0) cursor += self_t->text->len + 1;
- pango_layout_index_to_pos(self_t->layout, cursor, &crect);
- crx = (self_t->place.ix + self_t->place.dx) + (crect.x / PANGO_SCALE);
- cry = (self_t->place.iy + self_t->place.dy) + (crect.y / PANGO_SCALE);
- self_t->cursor->x = (int)crx;
- self_t->cursor->y = (int)cry;
- }
-
- if (RTEST(actual))
- {
- shoes_apply_transformation(cr, self_t->st, &self_t->place, 0);
- if (shoes_shape_check(cr, &self_t->place))
- {
- cairo_move_to(cr, self_t->place.ix + self_t->place.dx, self_t->place.iy + self_t->place.dy);
- cairo_set_source_rgb(cr, 0., 0., 0.);
- pango_cairo_update_layout(cr, self_t->layout);
- pango_cairo_show_layout(cr, self_t->layout);
-
- if (self_t->cursor != NULL && self_t->cursor->pos != INT_MAX)
- {
- cairo_save(cr);
- cairo_new_path(cr);
- cairo_move_to(cr, crx, cry);
- cairo_line_to(cr, crx, cry + (crect.height / PANGO_SCALE));
- cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE);
- cairo_set_source_rgb(cr, 0., 0., 0.);
- cairo_set_line_width(cr, 1.);
- cairo_stroke(cr);
- cairo_restore(cr);
- }
- }
-
- shoes_undo_transformation(cr, self_t->st, &self_t->place, 0);
- }
-
- if (li == 0) {
- self_t->place.iw = px;
- self_t->place.w = px + lmargin + rmargin;
- }
- self_t->place.ih = py;
- self_t->place.h = py + tmargin + bmargin;
- INFO("TEXT: %d, %d (%d, %d) / (%d: %d, %d: %d) %d, %d [%d]\n", canvas->cx, canvas->cy,
- canvas->place.w, canvas->height, self_t->place.x, self_t->place.ix,
- self_t->place.y, self_t->place.iy, self_t->place.w, self_t->place.h, pd);
-
- if (!ABSY(self_t->place)) {
- // newlines have an empty size
- if (ck != cStack) {
- if (li == 0) {
- canvas->cx = self_t->place.x + lrect.x + lrect.width + rmargin + pd;
- } else {
- canvas->cy = self_t->place.y + py - lrect.height;
- if (lrect.width == 0) {
- canvas->cx = self_t->place.x + lrect.x;
- } else {
- canvas->cx = self_t->place.x + lrect.width + rmargin;
- }
- }
- }
-
- canvas->endy = max(self_t->place.y + self_t->place.h, canvas->endy);
- canvas->endx = canvas->cx;
-
- if (ck == cStack || canvas->cx - CPX(canvas) > canvas->width) {
- canvas->cx = CPX(canvas);
- canvas->cy = canvas->endy;
- }
- if (NIL_P(ATTR(self_t->attr, margin)) && NIL_P(ATTR(self_t->attr, margin_top)))
- bmargin = lrect.height;
-
- INFO("CX: (%d, %d) / LRECT: (%d, %d) / END: (%d, %d)\n",
- canvas->cx, canvas->cy,
- lrect.x, lrect.width,
- canvas->endx, canvas->endy);
- }
- return self;
-}
-
-VALUE
-shoes_textblock_string(VALUE self)
-{
- shoes_canvas *canvas;
- GET_STRUCT(textblock, self_t);
- Data_Get_Struct(self_t->parent, shoes_canvas, canvas);
- if (!self_t->cached || self_t->pattr == NULL)
- shoes_textblock_make_pango(canvas->app, rb_obj_class(self), self_t);
- return rb_str_new(self_t->text->str, self_t->text->len);
-}
-
-//
-// Shoes::Button
-//
-void
-shoes_control_mark(shoes_control *control)
-{
- rb_gc_mark_maybe(control->parent);
- rb_gc_mark_maybe(control->attr);
-}
-
-static void
-shoes_control_free(shoes_control *control)
-{
- if (control->ref != NULL) shoes_native_control_free(control->ref);
- RUBY_CRITICAL(free(control));
-}
-
-VALUE
-shoes_control_new(VALUE klass, VALUE attr, VALUE parent)
-{
- shoes_control *control;
- VALUE obj = shoes_control_alloc(klass);
- Data_Get_Struct(obj, shoes_control, control);
- control->attr = attr;
- control->parent = parent;
- return obj;
-}
-
-VALUE
-shoes_control_alloc(VALUE klass)
-{
- VALUE obj;
- shoes_control *control = SHOE_ALLOC(shoes_control);
- SHOE_MEMZERO(control, shoes_control, 1);
- obj = Data_Wrap_Struct(klass, shoes_control_mark, shoes_control_free, control);
- control->attr = Qnil;
- control->parent = Qnil;
- return obj;
-}
-
-VALUE
-shoes_control_focus(VALUE self)
-{
- GET_STRUCT(control, self_t);
-// ATTRSET(self_t->attr, hidden, Qtrue);
- if (self_t->ref != NULL) shoes_native_control_focus(self_t->ref);
- return self;
-}
-
-VALUE
-shoes_control_get_state(VALUE self)
-{
- GET_STRUCT(control, self_t);
- return ATTR(self_t->attr, state);
-}
-
-static VALUE
-shoes_control_try_state(shoes_control *self_t, VALUE state)
-{
- unsigned char cstate;
- if (NIL_P(state))
- cstate = CONTROL_NORMAL;
- else if (TYPE(state) == T_STRING)
- {
- if (strncmp(RSTRING_PTR(state), "disabled", 8) == 0)
- cstate = CONTROL_DISABLED;
- else if (strncmp(RSTRING_PTR(state), "readonly", 8) == 0)
- cstate = CONTROL_READONLY;
- else
- {
- shoes_error("control can't have :state of %s\n", RSTRING_PTR(state));
- return Qfalse;
- }
- }
- else return Qfalse;
-
- if (self_t->ref != NULL)
- {
- if (cstate == CONTROL_NORMAL)
- shoes_native_control_state(self_t->ref, TRUE, TRUE);
- else if (cstate == CONTROL_DISABLED)
- shoes_native_control_state(self_t->ref, FALSE, TRUE);
- else if (cstate == CONTROL_READONLY)
- shoes_native_control_state(self_t->ref, TRUE, FALSE);
- }
- return Qtrue;
-}
-
-VALUE
-shoes_control_set_state(VALUE self, VALUE state)
-{
- GET_STRUCT(control, self_t);
- if (shoes_control_try_state(self_t, state))
- ATTRSET(self_t->attr, state, state);
- return self;
-}
-
-VALUE
-shoes_control_temporary_hide(VALUE self)
-{
- GET_STRUCT(control, self_t);
- if (self_t->ref != NULL) shoes_control_hide_ref(self_t->ref);
- return self;
-}
-
-VALUE
-shoes_control_hide(VALUE self)
-{
- GET_STRUCT(control, self_t);
- ATTRSET(self_t->attr, hidden, Qtrue);
- if (self_t->ref != NULL) shoes_control_hide_ref(self_t->ref);
- return self;
-}
-
-VALUE
-shoes_control_temporary_show(VALUE self)
-{
- GET_STRUCT(control, self_t);
- if (self_t->ref != NULL) shoes_control_show_ref(self_t->ref);
- return self;
-}
-
-VALUE
-shoes_control_show(VALUE self)
-{
- GET_STRUCT(control, self_t);
- ATTRSET(self_t->attr, hidden, Qfalse);
- if (self_t->ref != NULL) shoes_control_show_ref(self_t->ref);
- return self;
-}
-
-VALUE
-shoes_control_remove(VALUE self)
-{
- shoes_canvas *canvas;
- GET_STRUCT(control, self_t);
- shoes_canvas_remove_item(self_t->parent, self, 1, 0);
-
- Data_Get_Struct(self_t->parent, shoes_canvas, canvas);
- if (self_t->ref != NULL) {
- SHOES_CONTROL_REF ref = self_t->ref;
- self_t->ref = NULL;
- shoes_native_control_remove(ref, canvas);
- }
- return self;
-}
-
-void
-shoes_control_check_styles(shoes_control *self_t)
-{
- VALUE x = ATTR(self_t->attr, state);
- shoes_control_try_state(self_t, x);
-}
-
-void
-shoes_control_send(VALUE self, ID event)
-{
- VALUE click;
- GET_STRUCT(control, self_t);
-
- if (rb_respond_to(self, s_checked_q))
- ATTRSET(self_t->attr, checked, rb_funcall(self, s_checked_q, 0));
-
- if (!NIL_P(self_t->attr))
- {
- click = rb_hash_aref(self_t->attr, ID2SYM(event));
- if (!NIL_P(click))
- shoes_safe_block(self_t->parent, click, rb_ary_new3(1, self));
- }
-}
-
-VALUE
-shoes_button_draw(VALUE self, VALUE c, VALUE actual)
-{
- SETUP_CONTROL(2, 0, TRUE);
-
-#ifdef SHOES_QUARTZ
- place.h += 8;
- place.ih += 8;
-#endif
- if (RTEST(actual))
- {
- if (self_t->ref == NULL)
- {
- self_t->ref = shoes_native_button(self, canvas, &place, msg);
- shoes_control_check_styles(self_t);
- shoes_native_control_position(self_t->ref, &self_t->place, self, canvas, &place);
- }
- else
- shoes_native_control_repaint(self_t->ref, &self_t->place, canvas, &place);
- }
-
- FINISH();
-
- return self;
-}
-
-VALUE
-shoes_edit_line_get_text(VALUE self)
-{
- GET_STRUCT(control, self_t);
- if (self_t->ref == NULL) return Qnil;
- return shoes_native_edit_line_get_text(self_t->ref);
-}
-
-VALUE
-shoes_edit_line_set_text(VALUE self, VALUE text)
-{
- char *msg = "";
- GET_STRUCT(control, self_t);
- if (!NIL_P(text))
- {
- text = shoes_native_to_s(text);
- ATTRSET(self_t->attr, text, text);
- msg = RSTRING_PTR(text);
- }
- if (self_t->ref != NULL) shoes_native_edit_line_set_text(self_t->ref, msg);
- return text;
-}
-
-// cjc: added in Shoes 3.2.15
-VALUE
-shoes_edit_line_enterkey(VALUE self, VALUE proc)
-{
- // store the proc in the attr
- GET_STRUCT(control, self_t);
- if (!NIL_P(proc))
- {
- ATTRSET(self_t->attr, donekey, proc);
- }
- return Qnil;
-}
-
-VALUE
-shoes_edit_line_cursor_to_end(VALUE self)
-{
- GET_STRUCT(control, self_t);
- shoes_native_edit_line_cursor_to_end(self_t->ref);
- return Qnil;
-}
-
-VALUE
-shoes_edit_line_draw(VALUE self, VALUE c, VALUE actual)
-{
- SETUP_CONTROL(0, 0, FALSE);
-
-#ifdef SHOES_QUARTZ
- // cjc 2015-03-15 only change h, ih
- //place.x += 4; place.ix += 4;
- //place.y += 4; place.iy += 4;
- place.h += 4; place.ih += 4;
- //place.w += 4; place.iw += 4;
-#endif
- if (RTEST(actual))
- {
- if (self_t->ref == NULL)
- {
- self_t->ref = shoes_native_edit_line(self, canvas, &place, self_t->attr, msg);
- shoes_control_check_styles(self_t);
- shoes_native_control_position(self_t->ref, &self_t->place, self, canvas, &place);
- }
- else
- shoes_native_control_repaint(self_t->ref, &self_t->place, canvas, &place);
- }
-
- FINISH();
-
- return self;
-}
-
-VALUE
-shoes_edit_box_get_text(VALUE self)
-{
- GET_STRUCT(control, self_t);
- if (self_t->ref == NULL) return Qnil;
- return shoes_native_edit_box_get_text(self_t->ref);
-}
-
-VALUE
-shoes_edit_box_set_text(VALUE self, VALUE text)
-{
- char *msg = "";
- GET_STRUCT(control, self_t);
- if (!NIL_P(text))
- {
- text = shoes_native_to_s(text);
- ATTRSET(self_t->attr, text, text);
- msg = RSTRING_PTR(text);
- }
- if (self_t->ref != NULL) shoes_native_edit_box_set_text(self_t->ref, msg);
- return text;
-}
-
-VALUE
-shoes_edit_box_append(VALUE self, VALUE text)
-{
- char *msg = "";
- GET_STRUCT(control, self_t);
- if (!NIL_P(text))
- {
- text = shoes_native_to_s(text);
- ATTRSET(self_t->attr, text, text);
- msg = RSTRING_PTR(text);
- }
- if (self_t->ref != NULL) shoes_native_edit_box_append(self_t->ref, msg);
- return Qnil;
- }
-
-VALUE
-shoes_edit_box_scroll_to_end(VALUE self)
-{
- GET_STRUCT(control, self_t);
- if (self_t->ref != NULL) shoes_native_edit_box_scroll_to_end(self_t->ref);
- return Qnil;
-}
-
-VALUE
-shoes_edit_box_draw(VALUE self, VALUE c, VALUE actual)
-{
- SETUP_CONTROL(80, 0, FALSE);
-
- if (RTEST(actual))
- {
- if (self_t->ref == NULL)
- {
- self_t->ref = shoes_native_edit_box(self, canvas, &place, self_t->attr, msg);
- shoes_control_check_styles(self_t);
- shoes_native_control_position(self_t->ref, &self_t->place, self, canvas, &place);
- }
- else
- shoes_native_control_repaint(self_t->ref, &self_t->place, canvas, &place);
- }
-
- FINISH();
-
- return self;
-}
-
-// text_edit_box methods added in 3.2.25
-VALUE
-shoes_text_edit_box_get_text(VALUE self)
-{
- GET_STRUCT(control, self_t);
- if (self_t->ref == NULL) return Qnil;
- return shoes_native_text_edit_box_get_text(self_t->ref);
-}
-
-VALUE
-shoes_text_edit_box_set_text(VALUE self, VALUE text)
-{
- char *msg = "";
- GET_STRUCT(control, self_t);
- if (!NIL_P(text))
- {
- text = shoes_native_to_s(text);
- ATTRSET(self_t->attr, text, text);
- msg = RSTRING_PTR(text);
- }
- if (self_t->ref != NULL) shoes_native_text_edit_box_set_text(self_t->ref, msg);
- return text;
-}
-
-VALUE
-shoes_text_edit_box_append (VALUE self, VALUE text)
-{
- char *msg = "";
- VALUE ret;
- GET_STRUCT(control, self_t);
- if (!NIL_P(text))
- {
- text = shoes_native_to_s(text);
- ATTRSET(self_t->attr, text, text);
- msg = RSTRING_PTR(text);
- }
- if (self_t->ref != NULL)
- ret = shoes_native_text_edit_box_append(self_t->ref, msg);
- else
- ret = text;
- return ret; //TODO: should return updated internal insertion point
-}
-
-VALUE
-shoes_text_edit_box_insert (VALUE self, VALUE args)
-{
- // parse args
- return Qnil;
-}
-
-VALUE
-shoes_text_edit_box_delete( VALUE self, VALUE args)
-{
- return args;
-}
-
-VALUE
-shoes_text_edit_box_get(VALUE self, VALUE args)
-{
- return args;
-}
-
-VALUE
-shoes_text_edit_box_create_insertion(VALUE self, VALUE args)
-{
- return args;
-}
-
-VALUE
-shoes_text_edit_box_current_insertion(VALUE self)
-{
- return Qnil;
-}
-
-VALUE
-shoes_text_edit_box_scroll_to_insertion(VALUE seff, VALUE insert_pt)
-{
- return insert_pt; // TODO: wrong
-}
-
-VALUE
-shoes_text_edit_box_scroll_to_end (VALUE self)
-{
- return self; // TODO: Not even wrong
-}
-
-
-VALUE
-shoes_text_edit_box_draw(VALUE self, VALUE c, VALUE actual)
-{
- SETUP_CONTROL(80, 0, FALSE);
-
- if (RTEST(actual))
- {
- if (self_t->ref == NULL)
- {
- self_t->ref = shoes_native_text_edit_box(self, canvas, &place, self_t->attr, msg);
- shoes_control_check_styles(self_t);
- shoes_native_control_position(self_t->ref, &self_t->place, self, canvas, &place);
- }
- else
- shoes_native_control_repaint(self_t->ref, &self_t->place, canvas, &place);
- }
-
- FINISH();
-
- return self;
-
-}
-
-
-VALUE
-shoes_list_box_choose(VALUE self, VALUE item)
-{
- VALUE items = Qnil;
- GET_STRUCT(control, self_t);
- ATTRSET(self_t->attr, choose, item);
- if (self_t->ref == NULL) return self;
-
- items = ATTR(self_t->attr, items);
- shoes_native_list_box_set_active(self_t->ref, items, item);
- return self;
-}
-
-VALUE
-shoes_list_box_text(VALUE self)
-{
- GET_STRUCT(control, self_t);
- if (self_t->ref == NULL) return Qnil;
- return shoes_native_list_box_get_active(self_t->ref, ATTR(self_t->attr, items));
-}
-
-VALUE
-shoes_list_box_items_get(VALUE self)
-{
- GET_STRUCT(control, self_t);
- return ATTR(self_t->attr, items);
-}
-
-VALUE
-shoes_list_box_items_set(VALUE self, VALUE items)
-{
- VALUE opt = shoes_list_box_text(self);
- GET_STRUCT(control, self_t);
- if (!rb_obj_is_kind_of(items, rb_cArray))
- rb_raise(rb_eArgError, "ListBox items must be an array.");
- ATTRSET(self_t->attr, items, items);
- if (self_t->ref != NULL) shoes_native_list_box_update(self_t->ref, items);
- if (!NIL_P(opt)) shoes_list_box_choose(self, opt);
- return items;
-}
-
-VALUE
-shoes_list_box_draw(VALUE self, VALUE c, VALUE actual)
-{
- SETUP_CONTROL(0, 0, TRUE);
-
-#ifdef SHOES_QUARTZ
- place.h += 4;
- place.ih += 4;
-#endif
- if (RTEST(actual))
- {
- if (self_t->ref == NULL)
- {
- VALUE items = ATTR(self_t->attr, items);
- self_t->ref = shoes_native_list_box(self, canvas, &place, self_t->attr, msg);
-
- if (!NIL_P(items))
- {
- shoes_list_box_items_set(self, items);
- shoes_control_check_styles(self_t);
- if (!NIL_P(ATTR(self_t->attr, choose)))
- shoes_native_list_box_set_active(self_t->ref, items, ATTR(self_t->attr, choose));
- }
-
-#ifdef SHOES_WIN32
- shoes_native_control_position_no_pad(self_t->ref, &self_t->place, self, canvas, &place);
-#else
- shoes_native_control_position(self_t->ref, &self_t->place, self, canvas, &place);
-#endif
- }
- else
-#ifdef SHOES_WIN32
- shoes_native_control_repaint_no_pad(self_t->ref, &self_t->place, canvas, &place);
-#else
- shoes_native_control_repaint(self_t->ref, &self_t->place, canvas, &place);
-#endif
- }
-
- FINISH();
-
- return self;
-}
-
-VALUE
-shoes_progress_draw(VALUE self, VALUE c, VALUE actual)
-{
- SETUP_CONTROL(0, 0, FALSE);
-
- if (RTEST(actual))
- {
- if (self_t->ref == NULL)
- {
- self_t->ref = shoes_native_progress(self, canvas, &place, self_t->attr, msg);
- shoes_native_control_position(self_t->ref, &self_t->place, self, canvas, &place);
- }
- else
- shoes_native_control_repaint(self_t->ref, &self_t->place, canvas, &place);
- }
-
- FINISH();
-
- return self;
-}
-
-VALUE
-shoes_progress_get_fraction(VALUE self)
-{
- double perc = 0.;
- GET_STRUCT(control, self_t);
- if (self_t->ref != NULL)
- perc = shoes_native_progress_get_fraction(self_t->ref);
- return rb_float_new(perc);
-}
-
-VALUE
-shoes_progress_set_fraction(VALUE self, VALUE _perc)
-{
- double perc = min(max(NUM2DBL(_perc), 0.0), 1.0);
- GET_STRUCT(control, self_t);
- if (self_t->ref != NULL)
- shoes_native_progress_set_fraction(self_t->ref, perc);
- return self;
-}
-
-VALUE
-shoes_check_draw(VALUE self, VALUE c, VALUE actual)
-{
- SETUP_CONTROL(0, 20, FALSE);
-
- if (RTEST(actual))
- {
- if (self_t->ref == NULL)
- {
- self_t->ref = shoes_native_check(self, canvas, &place, self_t->attr, msg);
- if (RTEST(ATTR(self_t->attr, checked))) shoes_native_check_set(self_t->ref, Qtrue);
- shoes_control_check_styles(self_t);
- shoes_native_control_position(self_t->ref, &self_t->place, self, canvas, &place);
- }
- else
- shoes_native_control_repaint(self_t->ref, &self_t->place, canvas, &place);
- }
-
- FINISH();
-
- return self;
-}
-
-VALUE
-shoes_slider_draw(VALUE self, VALUE c, VALUE actual)
-{
- SETUP_CONTROL(0, 0, FALSE);
-
- if (RTEST(actual))
- {
- if (self_t->ref == NULL)
- {
- self_t->ref = shoes_native_slider(self, canvas, &place, self_t->attr, msg);
- shoes_control_check_styles(self_t);
- if (RTEST(ATTR(self_t->attr, fraction))) shoes_native_slider_set_fraction(self_t->ref, NUM2DBL(ATTR(self_t->attr, fraction)));
- shoes_native_control_position(self_t->ref, &self_t->place, self, canvas, &place);
- }
- else
- shoes_native_control_repaint(self_t->ref, &self_t->place, canvas, &place);
- }
-
- FINISH();
-
- return self;
-}
-
-VALUE
-shoes_slider_get_fraction(VALUE self)
-{
- double perc = 0.;
- GET_STRUCT(control, self_t);
- if (self_t->ref != NULL)
- perc = shoes_native_slider_get_fraction(self_t->ref);
- return rb_float_new(perc);
-}
-
-VALUE
-shoes_slider_set_fraction(VALUE self, VALUE _perc)
-{
- double perc = min(max(NUM2DBL(_perc), 0.0), 1.0);
- GET_STRUCT(control, self_t);
- if (self_t->ref != NULL)
- shoes_native_slider_set_fraction(self_t->ref, perc);
-
- return self;
-}
-
-VALUE
-shoes_check_is_checked(VALUE self)
-{
- GET_STRUCT(control, self_t);
- return shoes_native_check_get(self_t->ref);
-}
-
-VALUE
-shoes_button_group(VALUE self)
-{
- GET_STRUCT(control, self_t);
- if (!NIL_P(self_t->parent))
- {
- shoes_canvas *canvas;
- VALUE group = ATTR(self_t->attr, group);
- if (NIL_P(group)) group = self_t->parent;
- Data_Get_Struct(self_t->parent, shoes_canvas, canvas);
- return shoes_hash_get(canvas->app->groups, group);
- }
- return Qnil;
-}
-
-VALUE
-shoes_check_set_checked(VALUE self, VALUE on)
-{
- GET_STRUCT(control, self_t);
- ATTRSET(self_t->attr, checked, on);
- if (self_t->ref != NULL)
- shoes_native_check_set(self_t->ref, RTEST(on));
- return on;
-}
-
-VALUE
-shoes_check_set_checked_m(VALUE self, VALUE on)
-{
-#ifdef SHOES_FORCE_RADIO
- if (RTEST(on))
- {
- VALUE glist = shoes_button_group(self);
-
- if (!NIL_P(glist))
- {
- long i;
- for (i = 0; i < RARRAY_LEN(glist); i++)
- {
- VALUE ele = rb_ary_entry(glist, i);
- shoes_check_set_checked(ele, ele == self ? Qtrue : Qfalse);
- }
- }
- else
- {
- shoes_check_set_checked(self, on);
- }
- return on;
- }
-#endif
- shoes_check_set_checked(self, on);
- return on;
-}
-
-void
-shoes_button_send_click(VALUE control)
-{
- if (rb_obj_is_kind_of(control, cRadio))
- shoes_check_set_checked_m(control, Qtrue);
- shoes_control_send(control, s_click);
-}
-
-#ifdef SHOES_FORCE_RADIO
-void
-shoes_radio_button_click(VALUE control)
-{
- shoes_check_set_checked_m(control, Qtrue);
-}
-#endif
-
-VALUE
-shoes_radio_draw(VALUE self, VALUE c, VALUE actual)
-{
- SETUP_CONTROL(0, 20, FALSE);
-
- if (RTEST(actual))
- {
- if (self_t->ref == NULL)
- {
- VALUE group = ATTR(self_t->attr, group);
- if (NIL_P(group)) group = c;
-
- VALUE glist = shoes_hash_get(canvas->app->groups, group);
-#ifdef SHOES_FORCE_RADIO // aka OSX - create group before realizing widget
- if (NIL_P(glist))
- canvas->app->groups = shoes_hash_set(canvas->app->groups, group, (glist = rb_ary_new3(1, self)));
- else
- rb_ary_push(glist, self);
- glist = shoes_hash_get(canvas->app->groups, group);
- self_t->ref = shoes_native_radio(self, canvas, &place, self_t->attr, glist);
-#else
- self_t->ref = shoes_native_radio(self, canvas, &place, self_t->attr, glist);
-
- if (NIL_P(glist))
- canvas->app->groups = shoes_hash_set(canvas->app->groups, group, (glist = rb_ary_new3(1, self)));
- else
- rb_ary_push(glist, self);
-#endif
- if (RTEST(ATTR(self_t->attr, checked))) shoes_native_check_set(self_t->ref, Qtrue);
- shoes_control_check_styles(self_t);
- shoes_native_control_position(self_t->ref, &self_t->place, self, canvas, &place);
- }
- else
- shoes_native_control_repaint(self_t->ref, &self_t->place, canvas, &place);
- }
-
- FINISH();
-
- return self;
-}
-
-//
-// Transformations
-//
-#define TRANS_COMMON(ele, repaint) \
- VALUE \
- shoes_##ele##_transform(VALUE self, VALUE _m) \
- { \
- GET_STRUCT(ele, self_t); \
- ID m = SYM2ID(_m); \
- if (m == s_center || m == s_corner) \
- { \
- self_t->st = shoes_transform_detach(self_t->st); \
- self_t->st->mode = m; \
- } \
- else \
- { \
- rb_raise(rb_eArgError, "transform must be called with either :center or :corner."); \
- } \
- return self; \
- } \
- VALUE \
- shoes_##ele##_translate(VALUE self, VALUE _x, VALUE _y) \
- { \
- double x, y; \
- GET_STRUCT(ele, self_t); \
- x = NUM2DBL(_x); \
- y = NUM2DBL(_y); \
- self_t->st = shoes_transform_detach(self_t->st); \
- cairo_matrix_translate(&self_t->st->tf, x, y); \
- return self; \
- } \
- VALUE \
- shoes_##ele##_rotate(VALUE self, VALUE _deg) \
- { \
- double rad; \
- GET_STRUCT(ele, self_t); \
- rad = NUM2DBL(_deg) * SHOES_RAD2PI; \
- self_t->st = shoes_transform_detach(self_t->st); \
- cairo_matrix_rotate(&self_t->st->tf, -rad); \
- if (repaint) shoes_canvas_repaint_all(self_t->parent); \
- return self; \
- } \
- VALUE \
- shoes_##ele##_scale(int argc, VALUE *argv, VALUE self) \
- { \
- VALUE _sx, _sy; \
- double sx, sy; \
- GET_STRUCT(ele, self_t); \
- rb_scan_args(argc, argv, "11", &_sx, &_sy); \
- sx = NUM2DBL(_sx); \
- if (NIL_P(_sy)) sy = sx; \
- else sy = NUM2DBL(_sy); \
- self_t->st = shoes_transform_detach(self_t->st); \
- cairo_matrix_scale(&self_t->st->tf, sx, sy); \
- if (repaint) shoes_canvas_repaint_all(self_t->parent); \
- return self; \
- } \
- VALUE \
- shoes_##ele##_skew(int argc, VALUE *argv, VALUE self) \
- { \
- cairo_matrix_t matrix; \
- VALUE _sx, _sy; \
- double sx, sy; \
- GET_STRUCT(ele, self_t); \
- rb_scan_args(argc, argv, "11", &_sx, &_sy); \
- sx = NUM2DBL(_sx) * SHOES_RAD2PI; \
- sy = 0.0; \
- if (!NIL_P(_sy)) sy = NUM2DBL(_sy) * SHOES_RAD2PI; \
- cairo_matrix_init(&matrix, 1.0, sy, sx, 1.0, 0.0, 0.0); \
- self_t->st = shoes_transform_detach(self_t->st); \
- cairo_matrix_multiply(&self_t->st->tf, &self_t->st->tf, &matrix); \
- if (repaint) shoes_canvas_repaint_all(self_t->parent); \
- return self; \
- }
-
-#define REPLACE_COMMON(ele) \
- VALUE \
- shoes_##ele##_replace(int argc, VALUE *argv, VALUE self) \
- { \
- long i; \
- shoes_textblock *block_t; \
- VALUE texts, attr, block; \
- GET_STRUCT(ele, self_t); \
- attr = Qnil; \
- texts = rb_ary_new(); \
- for (i = 0; i < argc; i++) \
- { \
- if (rb_obj_is_kind_of(argv[i], rb_cHash)) \
- attr = argv[i]; \
- else \
- rb_ary_push(texts, argv[i]); \
- } \
- self_t->texts = texts; \
- if (!NIL_P(attr)) self_t->attr = attr; \
- block = shoes_find_textblock(self); \
- Data_Get_Struct(block, shoes_textblock, block_t); \
- shoes_textblock_uncache(block_t, TRUE); \
- shoes_canvas_repaint_all(self_t->parent); \
- return self; \
- }
-
-//
-// Common methods
-//
-#define EVENT_COMMON(ele, est, sym) \
- VALUE \
- shoes_##ele##_##sym(int argc, VALUE *argv, VALUE self) \
- { \
- VALUE str = Qnil, blk = Qnil; \
- GET_STRUCT(est, self_t); \
- \
- rb_scan_args(argc, argv, "01&", &str, &blk); \
- if (NIL_P(self_t->attr)) self_t->attr = rb_hash_new(); \
- rb_hash_aset(self_t->attr, ID2SYM(s_##sym), NIL_P(blk) ? str : blk ); \
- return self; \
- }
-
-#define CLASS_COMMON(ele) \
- VALUE \
- shoes_##ele##_style(int argc, VALUE *argv, VALUE self) \
- { \
- rb_arg_list args; \
- GET_STRUCT(ele, self_t); \
- switch (rb_parse_args(argc, argv, "h,", &args)) { \
- case 1: \
- if (NIL_P(self_t->attr)) self_t->attr = rb_hash_new(); \
- rb_funcall(self_t->attr, s_update, 1, args.a[0]); \
- shoes_canvas_repaint_all(self_t->parent); \
- break; \
- case 2: return rb_obj_freeze(rb_obj_dup(self_t->attr)); \
- } \
- return self; \
- } \
- \
- VALUE \
- shoes_##ele##_displace(VALUE self, VALUE x, VALUE y) \
- { \
- GET_STRUCT(ele, self_t); \
- ATTRSET(self_t->attr, displace_left, x); \
- ATTRSET(self_t->attr, displace_top, y); \
- shoes_canvas_repaint_all(self_t->parent); \
- return self; \
- } \
- \
- VALUE \
- shoes_##ele##_move(VALUE self, VALUE x, VALUE y) \
- { \
- GET_STRUCT(ele, self_t); \
- ATTRSET(self_t->attr, left, x); \
- ATTRSET(self_t->attr, top, y); \
- shoes_canvas_repaint_all(self_t->parent); \
- return self; \
- }
-
-#define CLASS_COMMON2(ele) \
- VALUE \
- shoes_##ele##_hide(VALUE self) \
- { \
- GET_STRUCT(ele, self_t); \
- ATTRSET(self_t->attr, hidden, Qtrue); \
- shoes_canvas_repaint_all(self_t->parent); \
- return self; \
- } \
- \
- VALUE \
- shoes_##ele##_show(VALUE self) \
- { \
- GET_STRUCT(ele, self_t); \
- ATTRSET(self_t->attr, hidden, Qfalse); \
- shoes_canvas_repaint_all(self_t->parent); \
- return self; \
- } \
- \
- VALUE \
- shoes_##ele##_toggle(VALUE self) \
- { \
- GET_STRUCT(ele, self_t); \
- ATTRSET(self_t->attr, hidden, ATTR(self_t->attr, hidden) == Qtrue ? Qfalse : Qtrue); \
- shoes_canvas_repaint_all(self_t->parent); \
- return self; \
- } \
- \
- VALUE \
- shoes_##ele##_is_hidden(VALUE self) \
- { \
- GET_STRUCT(ele, self_t); \
- if (RTEST(ATTR(self_t->attr, hidden))) \
- return ATTR(self_t->attr, hidden); \
- else return Qfalse; \
- } \
- CLASS_COMMON(ele); \
- EVENT_COMMON(ele, ele, change); \
- EVENT_COMMON(ele, ele, click); \
- EVENT_COMMON(ele, ele, release); \
- EVENT_COMMON(ele, ele, hover); \
- EVENT_COMMON(ele, ele, leave);
-
-#define PLACE_COMMON(ele) \
- VALUE \
- shoes_##ele##_get_parent(VALUE self) \
- { \
- GET_STRUCT(ele, self_t); \
- return self_t->parent; \
- } \
- \
- VALUE \
- shoes_##ele##_get_left(VALUE self) \
- { \
- shoes_canvas *canvas = NULL; \
- GET_STRUCT(ele, self_t); \
- if (!NIL_P(self_t->parent)) { \
- Data_Get_Struct(self_t->parent, shoes_canvas, canvas); \
- } else { \
- Data_Get_Struct(self, shoes_canvas, canvas); \
- } \
- return INT2NUM(self_t->place.x - CPX(canvas)); \
- } \
- \
- VALUE \
- shoes_##ele##_get_top(VALUE self) \
- { \
- shoes_canvas *canvas = NULL; \
- GET_STRUCT(ele, self_t); \
- if (!NIL_P(self_t->parent)) { \
- Data_Get_Struct(self_t->parent, shoes_canvas, canvas); \
- } else { \
- Data_Get_Struct(self, shoes_canvas, canvas); \
- } \
- return INT2NUM(self_t->place.y - CPY(canvas)); \
- } \
- \
- VALUE \
- shoes_##ele##_get_height(VALUE self) \
- { \
- GET_STRUCT(ele, self_t); \
- return INT2NUM(self_t->place.h); \
- } \
- \
- VALUE \
- shoes_##ele##_get_width(VALUE self) \
- { \
- GET_STRUCT(ele, self_t); \
- return INT2NUM(self_t->place.w); \
- }
-
-PLACE_COMMON(canvas)
-TRANS_COMMON(canvas, 0);
-PLACE_COMMON(control)
-CLASS_COMMON(control)
-EVENT_COMMON(control, control, click)
-EVENT_COMMON(control, control, change)
-CLASS_COMMON(text)
-REPLACE_COMMON(text)
-#ifdef VIDEO_C_VLC
-PLACE_COMMON(video)
-CLASS_COMMON(video)
-#endif
-PLACE_COMMON(image)
-CLASS_COMMON2(image)
-TRANS_COMMON(image, 1);
-EVENT_COMMON(linktext, text, click);
-EVENT_COMMON(linktext, text, release);
-EVENT_COMMON(linktext, text, hover);
-EVENT_COMMON(linktext, text, leave);
-PLACE_COMMON(shape)
-CLASS_COMMON2(shape)
-TRANS_COMMON(shape, 1);
-CLASS_COMMON2(pattern)
-PLACE_COMMON(textblock)
-CLASS_COMMON2(textblock)
-REPLACE_COMMON(textblock)
-
-// The next two macros are very important for new widget writers.
-CLASS_COMMON2(svg)
-TRANS_COMMON(svg, 1);
-
-CLASS_COMMON2(plot)
-TRANS_COMMON(plot, 1);
-
-VALUE
-shoes_textblock_style_m(int argc, VALUE *argv, VALUE self)
-{
- GET_STRUCT(textblock, self_t);
- VALUE obj = shoes_textblock_style(argc, argv, self);
- shoes_textblock_uncache(self_t, FALSE);
- return obj;
-}
-
-//
-// Shoes::Timer
-//
-//
-void
-shoes_timer_call(VALUE self)
-{
- GET_STRUCT(timer, timer);
- shoes_safe_block(timer->parent, timer->block, rb_ary_new3(1, INT2NUM(timer->frame)));
- timer->frame++;
-
- if (rb_obj_is_kind_of(self, cTimer))
- {
- timer->ref = 0;
- timer->started = ANIM_STOPPED;
- }
-}
-
-void
-shoes_timer_mark(shoes_timer *timer)
-{
- rb_gc_mark_maybe(timer->block);
- rb_gc_mark_maybe(timer->parent);
-}
-
-static void
-shoes_timer_free(shoes_timer *timer)
-{
- RUBY_CRITICAL(free(timer));
-}
-
-VALUE
-shoes_timer_new(VALUE klass, VALUE rate, VALUE block, VALUE parent)
-{
- shoes_timer *timer;
- VALUE obj = shoes_timer_alloc(klass);
- Data_Get_Struct(obj, shoes_timer, timer);
- timer->block = block;
- if (!NIL_P(rate))
- {
- if (klass == cAnim)
- timer->rate = 1000 / NUM2INT(rate);
- else
- timer->rate = (int)(1000. * NUM2DBL(rate));
- }
- if (timer->rate < 1) timer->rate = 1;
- timer->parent = parent;
- return obj;
-}
-
-VALUE
-shoes_timer_alloc(VALUE klass)
-{
- VALUE obj;
- shoes_timer *timer = SHOE_ALLOC(shoes_timer);
- SHOE_MEMZERO(timer, shoes_timer, 1);
- obj = Data_Wrap_Struct(klass, shoes_timer_mark, shoes_timer_free, timer);
- timer->block = Qnil;
- timer->rate = 1000 / 12; // 12 frames per second
- timer->parent = Qnil;
- timer->started = ANIM_NADA;
- return obj;
-}
-
-VALUE
-shoes_timer_remove(VALUE self)
-{
- GET_STRUCT(timer, self_t);
- shoes_timer_stop(self);
- shoes_canvas_remove_item(self_t->parent, self, 0, 1);
- return self;
-}
-
-VALUE
-shoes_timer_stop(VALUE self)
-{
- GET_STRUCT(timer, self_t);
- if (self_t->started == ANIM_STARTED)
- {
- shoes_canvas *canvas;
- Data_Get_Struct(self_t->parent, shoes_canvas, canvas);
- shoes_native_timer_remove(canvas, self_t->ref);
- self_t->started = ANIM_PAUSED;
- }
- return self;
-}
-
-VALUE
-shoes_timer_start(VALUE self)
-{
- GET_STRUCT(timer, self_t);
- unsigned int interval = self_t->rate;
- if (self_t->started != ANIM_STARTED)
- {
- shoes_canvas *canvas;
- Data_Get_Struct(self_t->parent, shoes_canvas, canvas);
- self_t->ref = shoes_native_timer_start(self, canvas, interval);
- self_t->started = ANIM_STARTED;
- }
- return self;
-}
-
-VALUE
-shoes_timer_toggle(VALUE self)
-{
- GET_STRUCT(timer, self_t);
- return self_t->started == ANIM_STARTED ? shoes_timer_stop(self) : shoes_timer_start(self);
-}
-
-VALUE
-shoes_timer_draw(VALUE self, VALUE c, VALUE actual)
-{
- shoes_canvas *canvas;
- GET_STRUCT(timer, self_t);
- Data_Get_Struct(self_t->parent, shoes_canvas, canvas);
- if (RTEST(actual) && self_t->started == ANIM_NADA)
- {
- self_t->frame = 0;
- shoes_timer_start(self);
- }
- return self;
-}
-
-
-void
-shoes_msg(ID typ, VALUE str)
-{
-#ifndef RUBY_1_8
- ID func = rb_frame_this_func();
- rb_ary_push(shoes_world->msgs, rb_ary_new3(6,
- ID2SYM(typ), str, rb_funcall(rb_cTime, s_now, 0),
- func ? ID2SYM(func) : Qnil,
- rb_str_new2(""), INT2NUM(0)));
-#else
- ID func = rb_frame_last_func();
- rb_ary_push(shoes_world->msgs, rb_ary_new3(6,
- ID2SYM(typ), str, rb_funcall(rb_cTime, s_now, 0),
- func ? ID2SYM(func) : Qnil,
- rb_str_new2(ruby_sourcefile), INT2NUM(ruby_sourceline)));
-#endif
-}
-
-#define DEBUG_TYPE(t) \
- VALUE \
- shoes_canvas_##t(VALUE self, VALUE str) \
- { \
- shoes_msg(s_##t, str); \
- return Qnil; \
- } \
- \
- void \
- shoes_##t(const char *fmt, ...) \
- { \
- va_list args; \
- char buf[BUFSIZ]; \
- \
- va_start(args,fmt); \
- vsnprintf(buf, BUFSIZ, fmt, args); \
- va_end(args); \
- shoes_msg(s_##t, rb_str_new2(buf)); \
- }
-
-//
-// Shoes::Download
-//
-void
-shoes_http_mark(shoes_http_klass *dl)
-{
- rb_gc_mark_maybe(dl->parent);
- rb_gc_mark_maybe(dl->attr);
- rb_gc_mark_maybe(dl->response);
-}
-
-static void
-shoes_http_free(shoes_http_klass *dl)
-{
- RUBY_CRITICAL(free(dl));
-}
-
-VALUE
-shoes_http_new(VALUE klass, VALUE parent, VALUE attr)
-{
- shoes_http_klass *dl;
- VALUE obj = shoes_http_alloc(klass);
- Data_Get_Struct(obj, shoes_http_klass, dl);
- dl->parent = parent;
- dl->attr = attr;
- return obj;
-}
-
-VALUE
-shoes_http_alloc(VALUE klass)
-{
- VALUE obj;
- shoes_http_klass *dl = SHOE_ALLOC(shoes_http_klass);
- SHOE_MEMZERO(dl, shoes_http_klass, 1);
- obj = Data_Wrap_Struct(klass, shoes_http_mark, shoes_http_free, dl);
- dl->parent = Qnil;
- dl->attr = Qnil;
- dl->response = Qnil;
- return obj;
-}
-
-VALUE
-shoes_http_remove(VALUE self)
-{
- GET_STRUCT(http_klass, self_t);
- self_t->state = SHOES_DOWNLOAD_HALT;
- shoes_canvas_remove_item(self_t->parent, self, 0, 1);
- return self;
-}
-
-VALUE
-shoes_http_abort(VALUE self)
-{
- GET_STRUCT(http_klass, self_t);
- self_t->state = SHOES_DOWNLOAD_HALT;
- return self;
-}
-
-int
-shoes_message_download(VALUE self, void *data)
-{
- VALUE proc = Qnil;
- shoes_http_event *de = (shoes_http_event *)data;
- GET_STRUCT(http_klass, dl);
- INFO("EVENT: %d (%d), %lu, %llu, %llu\n", (int)de->stage, (int)de->error, de->percent,
- de->transferred, de->total);
-
- switch (de->stage)
- {
- case SHOES_HTTP_STATUS:
- dl->response = shoes_response_new(cResponse, (int)de->status);
- return 0;
-
- case SHOES_HTTP_HEADER:
- {
- VALUE h = shoes_response_headers(dl->response);
- rb_hash_aset(h, rb_str_new(de->hkey, de->hkeylen), rb_str_new(de->hval, de->hvallen));
- }
- return 0;
-
- case SHOES_HTTP_ERROR:
- proc = ATTR(dl->attr, error);
- if (!NIL_P(proc))
- shoes_safe_block(dl->parent, proc, rb_ary_new3(2, self, shoes_http_err(de->error)));
- else
- shoes_canvas_error(self, shoes_http_err(de->error));
- return 0;
-
- case SHOES_HTTP_COMPLETED:
- if (de->body != NULL) rb_iv_set(dl->response, "body", rb_str_new(de->body, de->total));
- }
-
- dl->percent = de->percent;
- dl->total = de->total;
- dl->transferred = de->transferred;
-
- switch (de->stage) {
- case SHOES_HTTP_CONNECTED: proc = ATTR(dl->attr, start); break;
- case SHOES_HTTP_TRANSFER: proc = ATTR(dl->attr, progress); break;
- case SHOES_HTTP_COMPLETED: proc = ATTR(dl->attr, finish); break;
- }
-
- if (!NIL_P(proc))
- shoes_safe_block(dl->parent, proc, rb_ary_new3(1, self));
- return dl->state;
-}
-
-typedef struct {
- SHOES_CONTROL_REF ref;
- VALUE download;
-} shoes_doth_data;
-
-int
-shoes_doth_handler(shoes_http_event *de, void *data)
-{
- shoes_doth_data *doth = (shoes_doth_data *)data;
- shoes_http_event *de2 = SHOE_ALLOC(shoes_http_event);
- SHOE_MEMCPY(de2, de, shoes_http_event, 1);
- return shoes_throw_message(SHOES_THREAD_DOWNLOAD, doth->download, de2);
-}
-
-void
-shoes_http_request_free(shoes_http_request *req)
-{
- if (req->url != NULL) free(req->url);
- if (req->scheme != NULL) free(req->scheme);
- if (req->host != NULL) free(req->host);
- if (req->path != NULL) free(req->path);
- if (req->method != NULL) free(req->method);
- if (req->filepath != NULL) free(req->filepath);
- if (req->body != NULL) free(req->body);
- if (req->headers != NULL) shoes_http_headers_free(req->headers);
- if (req->mem != NULL) free(req->mem);
-}
-
-VALUE
-shoes_http_threaded(VALUE self, VALUE url, VALUE attr)
-{
- VALUE obj = shoes_http_new(cDownload, self, attr);
- GET_STRUCT(canvas, self_t);
- char *url_string = NULL;
-
- if (!rb_respond_to(url, s_host)) {
- url_string = strdup(RSTRING_PTR(url));
- url = rb_funcall(rb_mKernel, s_URI, 1, url);
- }
-
- VALUE scheme = rb_funcall(url, s_scheme, 0);
- VALUE host = rb_funcall(url, s_host, 0);
- VALUE port = rb_funcall(url, s_port, 0);
- VALUE path = rb_funcall(url, s_request_uri, 0);
-
- if (url_string == NULL) {
- url_string = SHOE_ALLOC_N(char, SHOES_BUFSIZE);
- char slash[2] = "/";
- if (RSTRING_PTR(path)[0] == '/') slash[0] = '\0';
-// sprintf(url_string, "%s://%s:%d%s%s", RSTRING_PTR(scheme), RSTRING_PTR(host),
- sprintf(url_string, "%s://%s:%s%s%s", RSTRING_PTR(scheme), RSTRING_PTR(host),
- RSTRING_PTR(port), slash, RSTRING_PTR(path));
- }
-
- shoes_http_request *req = SHOE_ALLOC(shoes_http_request);
- SHOE_MEMZERO(req, shoes_http_request, 1);
- req->url = url_string;
- req->scheme = strdup(RSTRING_PTR(scheme));
- req->host = strdup(RSTRING_PTR(host));
- req->port = NUM2INT(port);
- req->path = strdup(RSTRING_PTR(path));
- req->handler = shoes_doth_handler;
- req->flags = SHOES_DL_DEFAULTS;
- if (ATTR(attr, redirect) == Qfalse) req->flags ^= SHOES_DL_REDIRECTS;
-
- VALUE method = ATTR(attr, method);
- VALUE headers = ATTR(attr, headers);
- VALUE body = ATTR(attr, body);
- if (!NIL_P(body))
- {
- req->body = strdup(RSTRING_PTR(body));
- req->bodylen = RSTRING_LEN(body);
- }
- if (!NIL_P(method)) req->method = strdup(RSTRING_PTR(method));
- if (!NIL_P(headers)) req->headers = shoes_http_headers(headers);
-
- VALUE save = ATTR(attr, save);
- if (req->method == NULL || strcmp(req->method, "HEAD") != 0)
- {
- if (NIL_P(save))
- {
- req->mem = SHOE_ALLOC_N(char, SHOES_BUFSIZE);
- req->memlen = SHOES_BUFSIZE;
- }
- else
- {
- req->filepath = strdup(RSTRING_PTR(save));
- }
- }
-
- shoes_doth_data *data = SHOE_ALLOC(shoes_doth_data);
- data->download = obj;
- req->data = data;
-
- shoes_queue_download(req);
- return obj;
-}
-
-VALUE
-shoes_http_length(VALUE self)
-{
- GET_STRUCT(http_klass, dl);
- return rb_ull2inum(dl->total);
-}
-
-VALUE
-shoes_http_percent(VALUE self)
-{
- GET_STRUCT(http_klass, dl);
- return rb_uint2inum(dl->percent);
-}
-
-VALUE
-shoes_http_response(VALUE self)
-{
- GET_STRUCT(http_klass, dl);
- return dl->response;
-}
-
-VALUE
-shoes_http_transferred(VALUE self)
-{
- GET_STRUCT(http_klass, dl);
- return rb_ull2inum(dl->transferred);
-}
-
-EVENT_COMMON(http, http_klass, start);
-EVENT_COMMON(http, http_klass, progress);
-EVENT_COMMON(http, http_klass, finish);
-EVENT_COMMON(http, http_klass, error);
-
-//
-// Shoes::Response
-//
-VALUE
-shoes_response_new(VALUE klass, int status)
-{
- VALUE obj = rb_obj_alloc(cResponse);
- rb_iv_set(obj, "body", Qnil);
- rb_iv_set(obj, "headers", rb_hash_new());
- rb_iv_set(obj, "status", INT2NUM(status));
- return obj;
-}
-
-VALUE
-shoes_response_body(VALUE self)
-{
- return rb_iv_get(self, "body");
-}
-
-VALUE
-shoes_response_headers(VALUE self)
-{
- return rb_iv_get(self, "headers");
-}
-
-VALUE
-shoes_response_status(VALUE self)
-{
- return rb_iv_get(self, "status");
-}
-
-// TODO: handle exceptions
-int shoes_catch_message(unsigned int name, VALUE obj, void *data) {
- int ret = SHOES_DOWNLOAD_CONTINUE;
- switch (name) {
- case SHOES_THREAD_DOWNLOAD:
- ret = shoes_message_download(obj, data);
- free(data);
- break;
- case SHOES_IMAGE_DOWNLOAD:
- {
- VALUE hash, etag = Qnil, uri, uext, path, realpath;
- shoes_image_download_event *side = (shoes_image_download_event *)data;
- if (shoes_image_downloaded(side))
- {
- shoes_canvas_repaint_all(side->slot);
-
- path = rb_str_new2(side->filepath);
- uri = rb_str_new2(side->uripath);
- hash = rb_str_new2(side->hexdigest);
- if (side->etag != NULL) etag = rb_str_new2(side->etag);
- uext = rb_funcall(rb_cFile, rb_intern("extname"), 1, path);
-
- rb_funcall(rb_const_get(rb_cObject, rb_intern("DATABASE")),
- rb_intern("notify_cache_of"), 3, uri, etag, hash);
- if (side->status != 304)
- {
- realpath = rb_funcall(cShoes, rb_intern("image_cache_path"), 2, hash, uext);
- rename(side->filepath, RSTRING_PTR(realpath));
- }
- }
-
- free(side->filepath);
- free(side->uripath);
- if (side->etag != NULL) free(side->etag);
- free(data);
- }
- break;
- }
- return ret;
-}
-
-DEBUG_TYPE(info);
-DEBUG_TYPE(debug);
-DEBUG_TYPE(warn);
-DEBUG_TYPE(error);
-
-VALUE
-shoes_p(VALUE self, VALUE obj)
-{
- return shoes_canvas_debug(self, rb_inspect(obj));
-}
-
-VALUE
-shoes_log(VALUE self)
-{
- return shoes_world->msgs;
-}
-
-VALUE
-shoes_font(VALUE self, VALUE path)
-{
- StringValue(path);
- return shoes_load_font(RSTRING_PTR(path));
-}
-
-//
-// Defines a redirecting function which applies the element or transformation
-// to the currently active canvas. This is used in place of the old instance_eval
-// and ensures that you have access to the App's instance variables while
-// assembling elements in a layout.
-//
-#define FUNC_M(name, func, argn) \
- VALUE \
- shoes_canvas_c_##func(int argc, VALUE *argv, VALUE self) \
- { \
- VALUE canvas, obj; \
- GET_STRUCT(canvas, self_t); \
- char *n = name; \
- if (rb_ary_entry(self_t->app->nesting, 0) == self || \
- ((rb_obj_is_kind_of(self, cWidget) || self == self_t->app->nestslot) && \
- RARRAY_LEN(self_t->app->nesting) > 0)) \
- canvas = rb_ary_entry(self_t->app->nesting, RARRAY_LEN(self_t->app->nesting) - 1); \
- else \
- canvas = self; \
- if (!rb_obj_is_kind_of(canvas, cCanvas)) \
- return ts_funcall2(canvas, rb_intern(n + 1), argc, argv); \
- obj = call_cfunc(CASTHOOK(shoes_canvas_##func), canvas, argn, argc, argv); \
- if (n[0] == '+' && RARRAY_LEN(self_t->app->nesting) == 0) shoes_canvas_repaint_all(self); \
- return obj; \
- } \
- VALUE \
- shoes_app_c_##func(int argc, VALUE *argv, VALUE self) \
- { \
- VALUE canvas; \
- char *n = name; \
- GET_STRUCT(app, app); \
- if (RARRAY_LEN(app->nesting) > 0) \
- canvas = rb_ary_entry(app->nesting, RARRAY_LEN(app->nesting) - 1); \
- else \
- canvas = app->canvas; \
- if (!rb_obj_is_kind_of(canvas, cCanvas)) \
- return ts_funcall2(canvas, rb_intern(n + 1), argc, argv); \
- return shoes_canvas_c_##func(argc, argv, canvas); \
- }
-
-//
-// See ruby.h for the complete list of App methods which redirect to Canvas.
-//
-CANVAS_DEFS(FUNC_M);
-
-#define C(n, s) \
- re##n = rb_eval_string(s); \
- rb_const_set(cShoes, rb_intern("" # n), re##n);
-
-VALUE progname;
-
-//
-// Everything exposed to Ruby is exposed here.
-//
-void
-shoes_ruby_init()
-{
- progname = rb_str_new2("(eval)");
- rb_define_variable("$0", &progname);
- rb_define_variable("$PROGRAM_NAME", &progname);
-
- instance_eval_proc = rb_eval_string("lambda{|o,b| o.instance_eval(&b)}");
- rb_gc_register_address(&instance_eval_proc);
- ssNestSlot = rb_eval_string("{:height => 1.0}");
- rb_gc_register_address(&ssNestSlot);
-
- s_aref = rb_intern("[]=");
- s_perc = rb_intern("%");
- s_mult = rb_intern("*");
- s_checked_q = rb_intern("checked?");
- SYMBOL_DEFS(SYMBOL_INTERN);
-
- symAltQuest = ID2SYM(rb_intern("alt_?"));
- symAltSlash = ID2SYM(rb_intern("alt_/"));
- symAltEqual = ID2SYM(rb_intern("alt_="));
- symAltDot = ID2SYM(rb_intern("alt_."));
- symAltSemiColon = ID2SYM(rb_intern("alt_;"));
-
- //
- // I want all elements to be addressed Shoes::Name, but also available in
- // a separate mixin (cTypes), for inclusion in every Shoes.app block.
- //
- cTypes = rb_define_module("Shoes");
- rb_mod_remove_const(rb_cObject, rb_str_new2("Shoes"));
-
- cShoesWindow = rb_define_class_under(cTypes, "Window", rb_cObject);
- cMouse = rb_define_class_under(cTypes, "Mouse", rb_cObject);
-
- cCanvas = rb_define_class_under(cTypes, "Canvas", rb_cObject);
- rb_define_alloc_func(cCanvas, shoes_canvas_alloc);
- rb_define_method(cCanvas, "top", CASTHOOK(shoes_canvas_get_top), 0);
- rb_define_method(cCanvas, "left", CASTHOOK(shoes_canvas_get_left), 0);
- rb_define_method(cCanvas, "width", CASTHOOK(shoes_canvas_get_width), 0);
- rb_define_method(cCanvas, "height", CASTHOOK(shoes_canvas_get_height), 0);
- rb_define_method(cCanvas, "scroll_height", CASTHOOK(shoes_canvas_get_scroll_height), 0);
- rb_define_method(cCanvas, "scroll_max", CASTHOOK(shoes_canvas_get_scroll_max), 0);
- rb_define_method(cCanvas, "scroll_top", CASTHOOK(shoes_canvas_get_scroll_top), 0);
- rb_define_method(cCanvas, "scroll_top=", CASTHOOK(shoes_canvas_set_scroll_top), 1);
- rb_define_method(cCanvas, "displace", CASTHOOK(shoes_canvas_displace), 2);
- rb_define_method(cCanvas, "move", CASTHOOK(shoes_canvas_move), 2);
- rb_define_method(cCanvas, "style", CASTHOOK(shoes_canvas_style), -1);
- rb_define_method(cCanvas, "parent", CASTHOOK(shoes_canvas_get_parent), 0);
- rb_define_method(cCanvas, "contents", CASTHOOK(shoes_canvas_contents), 0);
- rb_define_method(cCanvas, "children", CASTHOOK(shoes_canvas_children), 0);
- rb_define_method(cCanvas, "draw", CASTHOOK(shoes_canvas_draw), 2);
- rb_define_method(cCanvas, "hide", CASTHOOK(shoes_canvas_hide), 0);
- rb_define_method(cCanvas, "show", CASTHOOK(shoes_canvas_show), 0);
- rb_define_method(cCanvas, "toggle", CASTHOOK(shoes_canvas_toggle), 0);
- rb_define_method(cCanvas, "remove", CASTHOOK(shoes_canvas_remove), 0);
- rb_define_method(cCanvas, "refresh_slot", CASTHOOK(shoes_canvas_refresh_slot), 0);
- rb_define_method(cCanvas, "refresh", CASTHOOK(shoes_canvas_refresh_slot), 0);
- rb_define_method(cCanvas, "cursor=", CASTHOOK(shoes_canvas_get_cursor), 0);
- rb_define_method(cCanvas, "cursor=", CASTHOOK(shoes_canvas_set_cursor), 1);
-
- cShoes = rb_define_class("Shoes", cCanvas);
- rb_include_module(cShoes, cTypes);
- rb_const_set(cShoes, rb_intern("Types"), cTypes);
- // for compatibily pre 3.2.22
- rb_const_set(cTypes, rb_intern("RELEASE_NAME"), rb_str_new2(SHOES_RELEASE_NAME));
- rb_const_set(cTypes, rb_intern("RELEASE_TYPE"), rb_str_new2(SHOES_STYLE));
- rb_const_set(cTypes, rb_intern("RELEASE_ID"), INT2NUM(SHOES_RELEASE_ID));
- rb_const_set(cTypes, rb_intern("REVISION"), INT2NUM(SHOES_REVISION));
- rb_const_set(cTypes, rb_intern("RELEASE_BUILD_DATE"), rb_str_new2(SHOES_BUILD_DATE));
- rb_const_set(cTypes, rb_intern("VERSION"), rb_str_new2(SHOES_RELEASE_NAME));
- // post 3.2.22 constants
- rb_const_set(cTypes, rb_intern("VERSION_NUMBER"), rb_str_new2(SHOES_VERSION_NUMBER));
- rb_const_set(cTypes, rb_intern("VERSION_MAJOR"), INT2NUM(SHOES_VERSION_MAJOR));
- rb_const_set(cTypes, rb_intern("VERSION_MINOR"), INT2NUM(SHOES_VERSION_MINOR));
- rb_const_set(cTypes, rb_intern("VERSION_TINY"), INT2NUM(SHOES_VERSION_TINY));
- rb_const_set(cTypes, rb_intern("VERSION_NAME"), rb_str_new2(SHOES_VERSION_NAME));
- rb_const_set(cTypes, rb_intern("VERSION_REVISION"), INT2NUM(SHOES_VERSION_REVISION));
- rb_const_set(cTypes, rb_intern("VERSION_DATE"), rb_str_new2(SHOES_VERSION_DATE));
- rb_const_set(cTypes, rb_intern("VERSION_PLATFORM"), rb_str_new2(SHOES_VERSION_PLATFORM));
-
- // other Shoes:: constants
- rb_const_set(cTypes, rb_intern("RAD2PI"), rb_float_new(SHOES_RAD2PI));
- rb_const_set(cTypes, rb_intern("TWO_PI"), rb_float_new(SHOES_PIM2));
- rb_const_set(cTypes, rb_intern("HALF_PI"), rb_float_new(SHOES_HALFPI));
- rb_const_set(cTypes, rb_intern("PI"), rb_float_new(SHOES_PI));
- //rb_const_set(cTypes, rb_intern("VIDEO"), SHOES_VIDEO ? Qtrue : Qfalse);
- rb_const_set(cTypes, rb_intern("VIDEO"), Qtrue);
-
- cApp = rb_define_class_under(cTypes, "App", rb_cObject);
- rb_define_alloc_func(cApp, shoes_app_alloc);
- rb_define_method(cApp, "fullscreen", CASTHOOK(shoes_app_get_fullscreen), 0);
- rb_define_method(cApp, "fullscreen=", CASTHOOK(shoes_app_set_fullscreen), 1);
- rb_define_method(cApp, "name", CASTHOOK(shoes_app_get_title), 0);
- rb_define_method(cApp, "name=", CASTHOOK(shoes_app_set_title), 1);
- rb_define_method(cApp, "location", CASTHOOK(shoes_app_location), 0);
- rb_define_method(cApp, "started?", CASTHOOK(shoes_app_is_started), 0);
- rb_define_method(cApp, "width", CASTHOOK(shoes_app_get_width), 0);
- rb_define_method(cApp, "height", CASTHOOK(shoes_app_get_height), 0);
- rb_define_method(cApp, "slot", CASTHOOK(shoes_app_slot), 0);
- rb_define_method(cApp, "set_window_icon_path", CASTHOOK(shoes_app_set_icon), 1); // New in 3.2.19
- rb_define_method(cApp, "set_window_title", CASTHOOK(shoes_app_set_wtitle), 1); // New in 3.2.19
- //rb_define_method(cApp, "svghandle", CASTHOOK(shoes_svghandle_new), -1); // Deprecate somehow
- //rb_define_method(cApp, "chart_series", CASTHOOK(shoes_chart_series_new), -1);
-
- cDialog = rb_define_class_under(cTypes, "Dialog", cApp);
-
- eInvMode = rb_define_class_under(cTypes, "InvalidModeError", rb_eStandardError);
- eNotImpl = rb_define_class_under(cTypes, "NotImplementedError", rb_eStandardError);
- eVlcError = rb_define_class_under(cTypes, "VideoError", rb_eStandardError);
- eImageError = rb_define_class_under(cTypes, "ImageError", rb_eStandardError);
- C(HEX_SOURCE, "/^(?:0x|#)?([0-9A-F]{2})([0-9A-F]{2})([0-9A-F]{2})$/i");
- C(HEX3_SOURCE, "/^(?:0x|#)?([0-9A-F])([0-9A-F])([0-9A-F])$/i");
- C(RGB_SOURCE, "/^rgb\\((\\d+), *(\\d+), *(\\d+)\\)$/i");
- C(RGBA_SOURCE, "/^rgb\\((\\d+), *(\\d+), *(\\d+), *(\\d+)\\)$/i");
- C(GRAY_SOURCE, "/^gray\\((\\d+)\\)$/i");
- C(GRAYA_SOURCE, "/^gray\\((\\d+), *(\\d+)\\)$/i");
- C(LF, "/\\r?\\n/");
- rb_eval_string(
- "def Shoes.escape(string);"
- "string.gsub(/&/n, '&').gsub(/\\\"/n, '"').gsub(/>/n, '>').gsub(/", CASTHOOK(shoes_color_spaceship), 1);
- rb_define_method(cColor, "==", CASTHOOK(shoes_color_equal), 1);
- rb_define_method(cColor, "eql?", CASTHOOK(shoes_color_equal), 1);
- rb_define_method(cColor, "red", CASTHOOK(shoes_color_get_red), 0);
- rb_define_method(cColor, "green", CASTHOOK(shoes_color_get_green), 0);
- rb_define_method(cColor, "blue", CASTHOOK(shoes_color_get_blue), 0);
- rb_define_method(cColor, "alpha", CASTHOOK(shoes_color_get_alpha), 0);
- rb_define_method(cColor, "black?", CASTHOOK(shoes_color_is_black), 0);
- rb_define_method(cColor, "dark?", CASTHOOK(shoes_color_is_dark), 0);
- rb_define_method(cColor, "inspect", CASTHOOK(shoes_color_to_s), 0);
- rb_define_method(cColor, "invert", CASTHOOK(shoes_color_invert), 0);
- rb_define_method(cColor, "light?", CASTHOOK(shoes_color_is_light), 0);
- rb_define_method(cColor, "opaque?", CASTHOOK(shoes_color_is_opaque), 0);
- rb_define_method(cColor, "to_s", CASTHOOK(shoes_color_to_s), 0);
- rb_define_method(cColor, "to_pattern", CASTHOOK(shoes_color_to_pattern), 0);
- rb_define_method(cColor, "transparent?", CASTHOOK(shoes_color_is_transparent), 0);
- rb_define_method(cColor, "white?", CASTHOOK(shoes_color_is_white), 0);
-
- cDownload = rb_define_class_under(cTypes, "Download", rb_cObject);
- rb_define_alloc_func(cDownload, shoes_http_alloc);
- rb_define_method(cDownload, "abort", CASTHOOK(shoes_http_abort), 0);
- rb_define_method(cDownload, "finish", CASTHOOK(shoes_http_finish), -1);
- rb_define_method(cDownload, "remove", CASTHOOK(shoes_http_remove), 0);
- rb_define_method(cDownload, "length", CASTHOOK(shoes_http_length), 0);
- rb_define_method(cDownload, "percent", CASTHOOK(shoes_http_percent), 0);
- rb_define_method(cDownload, "progress", CASTHOOK(shoes_http_progress), -1);
- rb_define_method(cDownload, "response", CASTHOOK(shoes_http_response), 0);
- rb_define_method(cDownload, "size", CASTHOOK(shoes_http_length), 0);
- rb_define_method(cDownload, "start", CASTHOOK(shoes_http_start), -1);
- rb_define_method(cDownload, "transferred", CASTHOOK(shoes_http_transferred), 0);
-
- cResponse = rb_define_class_under(cDownload, "Response", rb_cObject);
- rb_define_method(cResponse, "body", CASTHOOK(shoes_response_body), 0);
- rb_define_method(cResponse, "headers", CASTHOOK(shoes_response_headers), 0);
- rb_define_method(cResponse, "status", CASTHOOK(shoes_response_status), 0);
- rb_define_method(cResponse, "text", CASTHOOK(shoes_response_body), 0);
-
- rb_define_method(cCanvas, "method_missing", CASTHOOK(shoes_color_method_missing), -1);
- rb_define_method(cApp, "method_missing", CASTHOOK(shoes_app_method_missing), -1);
-
- rb_const_set(cTypes, rb_intern("ALL_NAMED_COLORS"), rb_hash_new());
- cColors = rb_const_get(cTypes, rb_intern("ALL_NAMED_COLORS"));
- rb_const_set(cTypes, rb_intern("COLORS"), cColors);
- DEF_COLOR(aliceblue, 240, 248, 255);
- DEF_COLOR(antiquewhite, 250, 235, 215);
- DEF_COLOR(aqua, 0, 255, 255);
- DEF_COLOR(aquamarine, 127, 255, 212);
- DEF_COLOR(azure, 240, 255, 255);
- DEF_COLOR(beige, 245, 245, 220);
- DEF_COLOR(bisque, 255, 228, 196);
- DEF_COLOR(black, 0, 0, 0);
- DEF_COLOR(blanchedalmond, 255, 235, 205);
- DEF_COLOR(blue, 0, 0, 255);
- DEF_COLOR(blueviolet, 138, 43, 226);
- DEF_COLOR(brown, 165, 42, 42);
- DEF_COLOR(burlywood, 222, 184, 135);
- DEF_COLOR(cadetblue, 95, 158, 160);
- DEF_COLOR(chartreuse, 127, 255, 0);
- DEF_COLOR(chocolate, 210, 105, 30);
- DEF_COLOR(coral, 255, 127, 80);
- DEF_COLOR(cornflowerblue, 100, 149, 237);
- DEF_COLOR(cornsilk, 255, 248, 220);
- DEF_COLOR(crimson, 220, 20, 60);
- DEF_COLOR(cyan, 0, 255, 255);
- DEF_COLOR(darkblue, 0, 0, 139);
- DEF_COLOR(darkcyan, 0, 139, 139);
- DEF_COLOR(darkgoldenrod, 184, 134, 11);
- DEF_COLOR(darkgray, 169, 169, 169);
- DEF_COLOR(darkgreen, 0, 100, 0);
- DEF_COLOR(darkkhaki, 189, 183, 107);
- DEF_COLOR(darkmagenta, 139, 0, 139);
- DEF_COLOR(darkolivegreen, 85, 107, 47);
- DEF_COLOR(darkorange, 255, 140, 0);
- DEF_COLOR(darkorchid, 153, 50, 204);
- DEF_COLOR(darkred, 139, 0, 0);
- DEF_COLOR(darksalmon, 233, 150, 122);
- DEF_COLOR(darkseagreen, 143, 188, 143);
- DEF_COLOR(darkslateblue, 72, 61, 139);
- DEF_COLOR(darkslategray, 47, 79, 79);
- DEF_COLOR(darkturquoise, 0, 206, 209);
- DEF_COLOR(darkviolet, 148, 0, 211);
- DEF_COLOR(deeppink, 255, 20, 147);
- DEF_COLOR(deepskyblue, 0, 191, 255);
- DEF_COLOR(dimgray, 105, 105, 105);
- DEF_COLOR(dodgerblue, 30, 144, 255);
- DEF_COLOR(firebrick, 178, 34, 34);
- DEF_COLOR(floralwhite, 255, 250, 240);
- DEF_COLOR(forestgreen, 34, 139, 34);
- DEF_COLOR(fuchsia, 255, 0, 255);
- DEF_COLOR(gainsboro, 220, 220, 220);
- DEF_COLOR(ghostwhite, 248, 248, 255);
- DEF_COLOR(gold, 255, 215, 0);
- DEF_COLOR(goldenrod, 218, 165, 32);
- DEF_COLOR(gray, 128, 128, 128);
- DEF_COLOR(green, 0, 128, 0);
- DEF_COLOR(greenyellow, 173, 255, 47);
- DEF_COLOR(honeydew, 240, 255, 240);
- DEF_COLOR(hotpink, 255, 105, 180);
- DEF_COLOR(indianred, 205, 92, 92);
- DEF_COLOR(indigo, 75, 0, 130);
- DEF_COLOR(ivory, 255, 255, 240);
- DEF_COLOR(khaki, 240, 230, 140);
- DEF_COLOR(lavender, 230, 230, 250);
- DEF_COLOR(lavenderblush, 255, 240, 245);
- DEF_COLOR(lawngreen, 124, 252, 0);
- DEF_COLOR(lemonchiffon, 255, 250, 205);
- DEF_COLOR(lightblue, 173, 216, 230);
- DEF_COLOR(lightcoral, 240, 128, 128);
- DEF_COLOR(lightcyan, 224, 255, 255);
- DEF_COLOR(lightgoldenrodyellow, 250, 250, 210);
- DEF_COLOR(lightgreen, 144, 238, 144);
- DEF_COLOR(lightgrey, 211, 211, 211);
- DEF_COLOR(lightpink, 255, 182, 193);
- DEF_COLOR(lightsalmon, 255, 160, 122);
- DEF_COLOR(lightseagreen, 32, 178, 170);
- DEF_COLOR(lightskyblue, 135, 206, 250);
- DEF_COLOR(lightslategray, 119, 136, 153);
- DEF_COLOR(lightsteelblue, 176, 196, 222);
- DEF_COLOR(lightyellow, 255, 255, 224);
- DEF_COLOR(lime, 0, 255, 0);
- DEF_COLOR(limegreen, 50, 205, 50);
- DEF_COLOR(linen, 250, 240, 230);
- DEF_COLOR(magenta, 255, 0, 255);
- DEF_COLOR(maroon, 128, 0, 0);
- DEF_COLOR(mediumaquamarine, 102, 205, 170);
- DEF_COLOR(mediumblue, 0, 0, 205);
- DEF_COLOR(mediumorchid, 186, 85, 211);
- DEF_COLOR(mediumpurple, 147, 112, 219);
- DEF_COLOR(mediumseagreen, 60, 179, 113);
- DEF_COLOR(mediumslateblue, 123, 104, 238);
- DEF_COLOR(mediumspringgreen, 0, 250, 154);
- DEF_COLOR(mediumturquoise, 72, 209, 204);
- DEF_COLOR(mediumvioletred, 199, 21, 133);
- DEF_COLOR(midnightblue, 25, 25, 112);
- DEF_COLOR(mintcream, 245, 255, 250);
- DEF_COLOR(mistyrose, 255, 228, 225);
- DEF_COLOR(moccasin, 255, 228, 181);
- DEF_COLOR(navajowhite, 255, 222, 173);
- DEF_COLOR(navy, 0, 0, 128);
- DEF_COLOR(oldlace, 253, 245, 230);
- DEF_COLOR(olive, 128, 128, 0);
- DEF_COLOR(olivedrab, 107, 142, 35);
- DEF_COLOR(orange, 255, 165, 0);
- DEF_COLOR(orangered, 255, 69, 0);
- DEF_COLOR(orchid, 218, 112, 214);
- DEF_COLOR(palegoldenrod, 238, 232, 170);
- DEF_COLOR(palegreen, 152, 251, 152);
- DEF_COLOR(paleturquoise, 175, 238, 238);
- DEF_COLOR(palevioletred, 219, 112, 147);
- DEF_COLOR(papayawhip, 255, 239, 213);
- DEF_COLOR(peachpuff, 255, 218, 185);
- DEF_COLOR(peru, 205, 133, 63);
- DEF_COLOR(pink, 255, 192, 203);
- DEF_COLOR(plum, 221, 160, 221);
- DEF_COLOR(powderblue, 176, 224, 230);
- DEF_COLOR(purple, 128, 0, 128);
- DEF_COLOR(red, 255, 0, 0);
- DEF_COLOR(rosybrown, 188, 143, 143);
- DEF_COLOR(royalblue, 65, 105, 225);
- DEF_COLOR(saddlebrown, 139, 69, 19);
- DEF_COLOR(salmon, 250, 128, 114);
- DEF_COLOR(sandybrown, 244, 164, 96);
- DEF_COLOR(seagreen, 46, 139, 87);
- DEF_COLOR(seashell, 255, 245, 238);
- DEF_COLOR(sienna, 160, 82, 45);
- DEF_COLOR(silver, 192, 192, 192);
- DEF_COLOR(skyblue, 135, 206, 235);
- DEF_COLOR(slateblue, 106, 90, 205);
- DEF_COLOR(slategray, 112, 128, 144);
- DEF_COLOR(snow, 255, 250, 250);
- DEF_COLOR(springgreen, 0, 255, 127);
- DEF_COLOR(steelblue, 70, 130, 180);
- DEF_COLOR(tan, 210, 180, 140);
- DEF_COLOR(teal, 0, 128, 128);
- DEF_COLOR(thistle, 216, 191, 216);
- DEF_COLOR(tomato, 255, 99, 71);
- DEF_COLOR(turquoise, 64, 224, 208);
- DEF_COLOR(violet, 238, 130, 238);
- DEF_COLOR(wheat, 245, 222, 179);
- DEF_COLOR(white, 255, 255, 255);
- DEF_COLOR(whitesmoke, 245, 245, 245);
- DEF_COLOR(yellow, 255, 255, 0);
- DEF_COLOR(yellowgreen, 154, 205, 50);
-
- cLinkUrl = rb_define_class_under(cTypes, "LinkUrl", rb_cObject);
-
- rb_define_method(rb_mKernel, "alert", CASTHOOK(shoes_dialog_alert), -1);
- rb_define_method(rb_mKernel, "ask", CASTHOOK(shoes_dialog_ask), -1);
- rb_define_method(rb_mKernel, "confirm", CASTHOOK(shoes_dialog_confirm), -1);
- rb_define_method(rb_mKernel, "ask_color", CASTHOOK(shoes_dialog_color), 1);
- rb_define_method(rb_mKernel, "ask_open_file", CASTHOOK(shoes_dialog_open), -1);
- rb_define_method(rb_mKernel, "ask_save_file", CASTHOOK(shoes_dialog_save), -1);
- rb_define_method(rb_mKernel, "ask_open_folder", CASTHOOK(shoes_dialog_open_folder), -1);
- rb_define_method(rb_mKernel, "ask_save_folder", CASTHOOK(shoes_dialog_save_folder), -1);
- rb_define_method(rb_mKernel, "font", CASTHOOK(shoes_font), 1);
+ //
+ // Shoes Kernel methods
+ //
+ //rb_define_method(rb_mKernel, "quit", CASTHOOK(shoes_app_quit), 0);
+ //rb_define_method(rb_mKernel, "exit", CASTHOOK(shoes_app_quit), 0);
+ rb_define_method(rb_mKernel, "secret_exit_hook", CASTHOOK(shoes_exit_setup),0); //unused?
+
+ rb_define_method(rb_mKernel, "debug", CASTHOOK(shoes_canvas_debug), 1);
+ rb_define_method(rb_mKernel, "info", CASTHOOK(shoes_canvas_info), 1);
+ rb_define_method(rb_mKernel, "warn", CASTHOOK(shoes_canvas_warn), 1);
+ rb_define_method(rb_mKernel, "error", CASTHOOK(shoes_canvas_error), 1);
+
+ cFlow = rb_define_class_under(cTypes, "Flow", cShoes);
+ cStack = rb_define_class_under(cTypes, "Stack", cShoes);
+ cMask = rb_define_class_under(cTypes, "Mask", cShoes);
+ cWidget = rb_define_class_under(cTypes, "Widget", cShoes);
+
+ rb_define_method(cApp, "method_missing", CASTHOOK(shoes_app_method_missing), -1);
+
+ rb_define_method(rb_mKernel, "alert", CASTHOOK(shoes_dialog_alert), -1);
+ rb_define_method(rb_mKernel, "ask", CASTHOOK(shoes_dialog_ask), -1);
+ rb_define_method(rb_mKernel, "confirm", CASTHOOK(shoes_dialog_confirm), -1);
+ rb_define_method(rb_mKernel, "ask_color", CASTHOOK(shoes_dialog_color), 1);
+ rb_define_method(rb_mKernel, "ask_open_file", CASTHOOK(shoes_dialog_open), -1);
+ rb_define_method(rb_mKernel, "ask_save_file", CASTHOOK(shoes_dialog_save), -1);
+ rb_define_method(rb_mKernel, "ask_open_folder", CASTHOOK(shoes_dialog_open_folder), -1);
+ rb_define_method(rb_mKernel, "ask_save_folder", CASTHOOK(shoes_dialog_save_folder), -1);
+ rb_define_method(rb_mKernel, "font", CASTHOOK(shoes_font), 1);
+
+ SHOES_TYPES_INIT;
}
VALUE shoes_exit_setup(VALUE self) {
- rb_define_method(rb_mKernel, "quit", CASTHOOK(shoes_app_quit), 0);
- rb_define_method(rb_mKernel, "exit", CASTHOOK(shoes_app_quit), 0);
- return Qtrue;
+ rb_define_method(rb_mKernel, "quit", CASTHOOK(shoes_app_quit), 0);
+ rb_define_method(rb_mKernel, "exit", CASTHOOK(shoes_app_quit), 0);
+ return Qtrue;
}
diff --git a/shoes/ruby.h b/shoes/ruby.h
index f6b6e489..f612fde7 100644
--- a/shoes/ruby.h
+++ b/shoes/ruby.h
@@ -24,7 +24,8 @@ extern "C" {
#if defined(__cplusplus)
#if 0
-{ /* satisfy cc-mode */
+{
+ /* satisfy cc-mode */
#endif
} /* extern "C" { */
#endif
@@ -58,14 +59,14 @@ typedef VALUE (*HOOK)();
#define LE_CPU(x) LE_CPU_N(&(x), sizeof(x))
static inline void flip_endian(unsigned char* x, int length) {
- int i;
- unsigned char tmp;
+ int i;
+ unsigned char tmp;
- for(i = 0; i < (length / 2); i++) {
- tmp = x[i];
- x[i] = x[length - i - 1];
- x[length - i - 1] = tmp;
- }
+ for(i = 0; i < (length / 2); i++) {
+ tmp = x[i];
+ x[i] = x[length - i - 1];
+ x[length - i - 1] = tmp;
+ }
}
#ifndef RARRAY_LEN
@@ -78,25 +79,20 @@ static inline void flip_endian(unsigned char* x, int length) {
#undef s_host
extern VALUE cShoes, cApp, cDialog, cTypes, cShoesWindow, cMouse, cCanvas;
-extern VALUE cFlow, cStack, cMask, cNative, cShape, cVideo, cImage, cEffect, cEvery;
-extern VALUE cTimer, cAnim, cPattern, cBorder, cBackground, cPara, cBanner, cTitle;
-extern VALUE cSubtitle, cTagline, cCaption, cInscription, cLinkText, cTextBlock;
-extern VALUE cTextClass, cSpan, cStrong, cSub, cSup, cCode, cDel, cEm, cIns, cButton;
-extern VALUE cEditLine, cEditBox, cListBox, cProgress, cSlider, cCheck, cRadio, cColor;
-extern VALUE cDownload, cResponse, cColors, cLink, cLinkHover, ssNestSlot;
-extern VALUE cTextEditBox;
-extern VALUE cSvgHandle, cSvg, cPlot, cChartSeries;
+extern VALUE cFlow, cStack, cMask;
+extern VALUE cProgress;
+extern VALUE ssNestSlot;
extern VALUE cWidget;
extern VALUE aMsgList;
extern VALUE eInvMode, eNotImpl, eImageError;
extern VALUE reHEX_SOURCE, reHEX3_SOURCE, reRGB_SOURCE, reRGBA_SOURCE, reGRAY_SOURCE, reGRAYA_SOURCE, reLF;
extern VALUE symAltQuest, symAltSlash, symAltDot, symAltEqual, symAltSemiColon;
extern VALUE instance_eval_proc;
-extern ID s_checked_q, s_perc, s_fraction, s_aref, s_mult, s_donekey;
+extern ID s_perc, s_fraction, s_aref, s_mult, s_donekey, s_progress;
typedef struct {
- int n;
- VALUE a[10];
+ int n;
+ VALUE a[10];
} rb_arg_list;
VALUE mfp_instance_eval(VALUE, VALUE);
@@ -107,10 +103,11 @@ long rb_ary_index_of(VALUE, VALUE);
VALUE rb_ary_insert_at(VALUE, long, int, VALUE);
VALUE shoes_safe_block(VALUE, VALUE, VALUE);
void shoes_ruby_init(void);
-void shoes_ruby_video_init(void);
VALUE shoes_exit_setup(VALUE);
#define BEZIER 0.55228475;
+VALUE call_cfunc(HOOK func, VALUE recv, int len, int argc, VALUE *argv);
+
//
// Exception handling strings for eval
//
@@ -131,7 +128,7 @@ VALUE shoes_exit_setup(VALUE);
return SHOES_QUIT;
#define NUM2RGBINT(x) (rb_obj_is_kind_of(x, rb_cFloat) ? ROUND(NUM2DBL(x) * 255) : NUM2INT(x))
-#define DEF_COLOR(name, r, g, b) rb_hash_aset(cColors, ID2SYM(rb_intern("" # name)), shoes_color_new(r, g, b, 255))
+
#define GET_STRUCT(ele, var) \
shoes_##ele *var; \
Data_Get_Struct(self, shoes_##ele, var)
@@ -185,6 +182,337 @@ VALUE shoes_exit_setup(VALUE);
y >= self_t->place.iy + self_t->place.dy && \
y <= self_t->place.iy + self_t->place.dy + self_t->place.ih)
+#define RUBY_M(name, func, argc) \
+ rb_define_method(cCanvas, name + 1, CASTHOOK(shoes_canvas_c_##func), -1); \
+ rb_define_method(cApp, name + 1, CASTHOOK(shoes_app_c_##func), -1)
+
+//
+// Defines a redirecting function which applies the element or transformation
+// to the currently active canvas. This is used in place of the old instance_eval
+// and ensures that you have access to the App's instance variables while
+// assembling elements in a layout.
+//
+#define FUNC_M(name, func, argn) \
+ VALUE \
+ shoes_canvas_c_##func(int argc, VALUE *argv, VALUE self) \
+ { \
+ VALUE canvas, obj; \
+ GET_STRUCT(canvas, self_t); \
+ char *n = name; \
+ if (rb_ary_entry(self_t->app->nesting, 0) == self || \
+ ((rb_obj_is_kind_of(self, cWidget) || self == self_t->app->nestslot) && \
+ RARRAY_LEN(self_t->app->nesting) > 0)) \
+ canvas = rb_ary_entry(self_t->app->nesting, RARRAY_LEN(self_t->app->nesting) - 1); \
+ else \
+ canvas = self; \
+ if (!rb_obj_is_kind_of(canvas, cCanvas)) \
+ return ts_funcall2(canvas, rb_intern(n + 1), argc, argv); \
+ obj = call_cfunc(CASTHOOK(shoes_canvas_##func), canvas, argn, argc, argv); \
+ if (n[0] == '+' && RARRAY_LEN(self_t->app->nesting) == 0) shoes_canvas_repaint_all(self); \
+ return obj; \
+ } \
+ VALUE \
+ shoes_app_c_##func(int argc, VALUE *argv, VALUE self) \
+ { \
+ VALUE canvas; \
+ char *n = name; \
+ GET_STRUCT(app, app); \
+ if (RARRAY_LEN(app->nesting) > 0) \
+ canvas = rb_ary_entry(app->nesting, RARRAY_LEN(app->nesting) - 1); \
+ else \
+ canvas = app->canvas; \
+ if (!rb_obj_is_kind_of(canvas, cCanvas)) \
+ return ts_funcall2(canvas, rb_intern(n + 1), argc, argv); \
+ return shoes_canvas_c_##func(argc, argv, canvas); \
+ }
+
+#define SETUP_CONTROL(dh, dw, flex) \
+ char *msg = ""; \
+ int len = dw ? dw : 200; \
+ shoes_control *self_t; \
+ shoes_canvas *canvas; \
+ shoes_place place; \
+ VALUE text = Qnil, ck = rb_obj_class(c); \
+ Data_Get_Struct(self, shoes_control, self_t); \
+ Data_Get_Struct(c, shoes_canvas, canvas); \
+ text = ATTR(self_t->attr, text); \
+ if (!NIL_P(text)) { \
+ text = shoes_native_to_s(text); \
+ msg = RSTRING_PTR(text); \
+ if (flex) len = ((int)RSTRING_LEN(text) * 8) + 32; \
+ } \
+ shoes_place_decide(&place, c, self_t->attr, len, 28 + dh, REL_CANVAS, TRUE)
+
+#define FINISH() \
+ if (!ABSY(place)) { \
+ canvas->cx += place.w; \
+ canvas->cy = place.y; \
+ canvas->endx = canvas->cx; \
+ canvas->endy = max(canvas->endy, place.y + place.h); \
+ } \
+ if (ck == cStack) { \
+ canvas->cx = CPX(canvas); \
+ canvas->cy = canvas->endy; \
+ }
+
+//
+// Macros for setting up drawing
+//
+#define SETUP_DRAWING(self_type, rel, dw, dh) \
+ self_type *self_t; \
+ shoes_place place; \
+ shoes_canvas *canvas; \
+ Data_Get_Struct(self, self_type, self_t); \
+ Data_Get_Struct(c, shoes_canvas, canvas); \
+ if (ATTR(self_t->attr, hidden) == Qtrue) return self; \
+ shoes_place_decide(&place, c, self_t->attr, dw, dh, rel, REL_COORDS(rel) == REL_CANVAS)
+
+#define EVENT_COMMON(ele, est, sym) \
+ VALUE \
+ shoes_##ele##_##sym(int argc, VALUE *argv, VALUE self) \
+ { \
+ VALUE str = Qnil, blk = Qnil; \
+ GET_STRUCT(est, self_t); \
+ \
+ rb_scan_args(argc, argv, "01&", &str, &blk); \
+ if (NIL_P(self_t->attr)) self_t->attr = rb_hash_new(); \
+ rb_hash_aset(self_t->attr, ID2SYM(s_##sym), NIL_P(blk) ? str : blk ); \
+ return self; \
+ }
+
+//
+// Common methods
+//
+
+#define CLASS_COMMON(ele) \
+ VALUE \
+ shoes_##ele##_style(int argc, VALUE *argv, VALUE self) \
+ { \
+ rb_arg_list args; \
+ GET_STRUCT(ele, self_t); \
+ switch (rb_parse_args(argc, argv, "h,", &args)) { \
+ case 1: \
+ if (NIL_P(self_t->attr)) self_t->attr = rb_hash_new(); \
+ rb_funcall(self_t->attr, s_update, 1, args.a[0]); \
+ shoes_canvas_repaint_all(self_t->parent); \
+ break; \
+ case 2: return rb_obj_freeze(rb_obj_dup(self_t->attr)); \
+ } \
+ return self; \
+ } \
+ \
+ VALUE \
+ shoes_##ele##_displace(VALUE self, VALUE x, VALUE y) \
+ { \
+ GET_STRUCT(ele, self_t); \
+ ATTRSET(self_t->attr, displace_left, x); \
+ ATTRSET(self_t->attr, displace_top, y); \
+ shoes_canvas_repaint_all(self_t->parent); \
+ return self; \
+ } \
+ \
+ VALUE \
+ shoes_##ele##_move(VALUE self, VALUE x, VALUE y) \
+ { \
+ GET_STRUCT(ele, self_t); \
+ ATTRSET(self_t->attr, left, x); \
+ ATTRSET(self_t->attr, top, y); \
+ shoes_canvas_repaint_all(self_t->parent); \
+ return self; \
+ }
+
+#define CLASS_COMMON2(ele) \
+ VALUE \
+ shoes_##ele##_hide(VALUE self) \
+ { \
+ GET_STRUCT(ele, self_t); \
+ ATTRSET(self_t->attr, hidden, Qtrue); \
+ shoes_canvas_repaint_all(self_t->parent); \
+ return self; \
+ } \
+ \
+ VALUE \
+ shoes_##ele##_show(VALUE self) \
+ { \
+ GET_STRUCT(ele, self_t); \
+ ATTRSET(self_t->attr, hidden, Qfalse); \
+ shoes_canvas_repaint_all(self_t->parent); \
+ return self; \
+ } \
+ \
+ VALUE \
+ shoes_##ele##_toggle(VALUE self) \
+ { \
+ GET_STRUCT(ele, self_t); \
+ ATTRSET(self_t->attr, hidden, ATTR(self_t->attr, hidden) == Qtrue ? Qfalse : Qtrue); \
+ shoes_canvas_repaint_all(self_t->parent); \
+ return self; \
+ } \
+ \
+ VALUE \
+ shoes_##ele##_is_hidden(VALUE self) \
+ { \
+ GET_STRUCT(ele, self_t); \
+ if (RTEST(ATTR(self_t->attr, hidden))) \
+ return ATTR(self_t->attr, hidden); \
+ else return Qfalse; \
+ } \
+ CLASS_COMMON(ele); \
+ EVENT_COMMON(ele, ele, change); \
+ EVENT_COMMON(ele, ele, click); \
+ EVENT_COMMON(ele, ele, release); \
+ EVENT_COMMON(ele, ele, hover); \
+ EVENT_COMMON(ele, ele, leave);
+
+#define PLACE_COMMON(ele) \
+ VALUE \
+ shoes_##ele##_get_parent(VALUE self) \
+ { \
+ GET_STRUCT(ele, self_t); \
+ return self_t->parent; \
+ } \
+ \
+ VALUE \
+ shoes_##ele##_get_left(VALUE self) \
+ { \
+ shoes_canvas *canvas = NULL; \
+ GET_STRUCT(ele, self_t); \
+ if (!NIL_P(self_t->parent)) { \
+ Data_Get_Struct(self_t->parent, shoes_canvas, canvas); \
+ } else { \
+ Data_Get_Struct(self, shoes_canvas, canvas); \
+ } \
+ return INT2NUM(self_t->place.x - CPX(canvas)); \
+ } \
+ \
+ VALUE \
+ shoes_##ele##_get_top(VALUE self) \
+ { \
+ shoes_canvas *canvas = NULL; \
+ GET_STRUCT(ele, self_t); \
+ if (!NIL_P(self_t->parent)) { \
+ Data_Get_Struct(self_t->parent, shoes_canvas, canvas); \
+ } else { \
+ Data_Get_Struct(self, shoes_canvas, canvas); \
+ } \
+ return INT2NUM(self_t->place.y - CPY(canvas)); \
+ } \
+ \
+ VALUE \
+ shoes_##ele##_get_height(VALUE self) \
+ { \
+ GET_STRUCT(ele, self_t); \
+ return INT2NUM(self_t->place.h); \
+ } \
+ \
+ VALUE \
+ shoes_##ele##_get_width(VALUE self) \
+ { \
+ GET_STRUCT(ele, self_t); \
+ return INT2NUM(self_t->place.w); \
+ }
+
+#define REPLACE_COMMON(ele) \
+ VALUE \
+ shoes_##ele##_replace(int argc, VALUE *argv, VALUE self) \
+ { \
+ long i; \
+ shoes_textblock *block_t; \
+ VALUE texts, attr, block; \
+ GET_STRUCT(ele, self_t); \
+ attr = Qnil; \
+ texts = rb_ary_new(); \
+ for (i = 0; i < argc; i++) \
+ { \
+ if (rb_obj_is_kind_of(argv[i], rb_cHash)) \
+ attr = argv[i]; \
+ else \
+ rb_ary_push(texts, argv[i]); \
+ } \
+ self_t->texts = texts; \
+ if (!NIL_P(attr)) self_t->attr = attr; \
+ block = shoes_find_textblock(self); \
+ Data_Get_Struct(block, shoes_textblock, block_t); \
+ shoes_textblock_uncache(block_t, TRUE); \
+ shoes_canvas_repaint_all(self_t->parent); \
+ return self; \
+ }
+
+//
+// Transformations
+//
+#define TRANS_COMMON(ele, repaint) \
+ VALUE \
+ shoes_##ele##_transform(VALUE self, VALUE _m) \
+ { \
+ GET_STRUCT(ele, self_t); \
+ ID m = SYM2ID(_m); \
+ if (m == s_center || m == s_corner) \
+ { \
+ self_t->st = shoes_transform_detach(self_t->st); \
+ self_t->st->mode = m; \
+ } \
+ else \
+ { \
+ rb_raise(rb_eArgError, "transform must be called with either :center or :corner."); \
+ } \
+ return self; \
+ } \
+ VALUE \
+ shoes_##ele##_translate(VALUE self, VALUE _x, VALUE _y) \
+ { \
+ double x, y; \
+ GET_STRUCT(ele, self_t); \
+ x = NUM2DBL(_x); \
+ y = NUM2DBL(_y); \
+ self_t->st = shoes_transform_detach(self_t->st); \
+ cairo_matrix_translate(&self_t->st->tf, x, y); \
+ return self; \
+ } \
+ VALUE \
+ shoes_##ele##_rotate(VALUE self, VALUE _deg) \
+ { \
+ double rad; \
+ GET_STRUCT(ele, self_t); \
+ rad = NUM2DBL(_deg) * SHOES_RAD2PI; \
+ self_t->st = shoes_transform_detach(self_t->st); \
+ cairo_matrix_rotate(&self_t->st->tf, -rad); \
+ if (repaint) shoes_canvas_repaint_all(self_t->parent); \
+ return self; \
+ } \
+ VALUE \
+ shoes_##ele##_scale(int argc, VALUE *argv, VALUE self) \
+ { \
+ VALUE _sx, _sy; \
+ double sx, sy; \
+ GET_STRUCT(ele, self_t); \
+ rb_scan_args(argc, argv, "11", &_sx, &_sy); \
+ sx = NUM2DBL(_sx); \
+ if (NIL_P(_sy)) sy = sx; \
+ else sy = NUM2DBL(_sy); \
+ self_t->st = shoes_transform_detach(self_t->st); \
+ cairo_matrix_scale(&self_t->st->tf, sx, sy); \
+ if (repaint) shoes_canvas_repaint_all(self_t->parent); \
+ return self; \
+ } \
+ VALUE \
+ shoes_##ele##_skew(int argc, VALUE *argv, VALUE self) \
+ { \
+ cairo_matrix_t matrix; \
+ VALUE _sx, _sy; \
+ double sx, sy; \
+ GET_STRUCT(ele, self_t); \
+ rb_scan_args(argc, argv, "11", &_sx, &_sy); \
+ sx = NUM2DBL(_sx) * SHOES_RAD2PI; \
+ sy = 0.0; \
+ if (!NIL_P(_sy)) sy = NUM2DBL(_sy) * SHOES_RAD2PI; \
+ cairo_matrix_init(&matrix, 1.0, sy, sx, 1.0, 0.0, 0.0); \
+ self_t->st = shoes_transform_detach(self_t->st); \
+ cairo_matrix_multiply(&self_t->st->tf, &self_t->st->tf, &matrix); \
+ if (repaint) shoes_canvas_repaint_all(self_t->parent); \
+ return self; \
+ }
+
int shoes_px(VALUE, int, int, int);
int shoes_px2(VALUE, ID, ID, int, int, int);
VALUE shoes_hash_set(VALUE, ID, VALUE);
@@ -202,82 +530,45 @@ void shoes_ele_remove_all(VALUE);
void shoes_cairo_rect(cairo_t *, double, double, double, double, double);
void shoes_cairo_arc(cairo_t *, double, double, double, double, double, double);
-#define SYMBOL_DEFS(f) f(bind); f(gsub); f(keys); f(update); f(merge); f(new); f(URI); f(now); f(debug); f(info); f(warn); f(error); f(run); f(to_a); f(to_ary); f(to_f); f(to_i); f(to_int); f(to_s); f(to_str); f(to_pattern); f(align); f(angle); f(angle1); f(angle2); f(arrow); f(autoplay); f(begin); f(body); f(cancel); f(call); f(center); f(change); f(checked); f(choose); f(click); f(corner); f(curve); f(distance); f(displace_left); f(displace_top); f(downcase); f(draw); f(emphasis); f(end); f(family); f(fill); f(finish); f(font); f(fraction); f(fullscreen); f(group); f(hand); f(headers); f(hidden); f(host); f(hover); f(href); f(insert); f(inner); f(items); f(justify); f(kerning); f(keydown); f(keypress); f(keyup); f(match); f(method); f(motion); f(link); f(leading); f(leave); f(ok); f(outer); f(path); f(points); f(port); f(progress); f(redirect); f(release); f(request_uri); f(rise); f(scheme); f(save); f(size); f(slider); f(state); f(wheel); f(scroll); f(stretch); f(strikecolor); f(strikethrough); f(stroke); f(start); f(attach); f(text); f(title); f(top); f(right); f(bottom); f(left); f(up); f(down); f(height); f(minheight); f(remove); f(resizable); f(strokewidth); f(cap); f(widget); f(width); f(minwidth); f(marker); f(margin); f(margin_left); f(margin_right); f(margin_top); f(margin_bottom); f(radius); f(secret); f(blur); f(glow); f(shadow); f(arc); f(rect); f(oval); f(line); f(shape); f(star); f(project); f(round); f(square); f(undercolor); f(underline); f(variant); f(weight); f(wrap); f(dash); f(nodot); f(onedot); f(donekey); f(volume); f(bg_color)
+// FIXME: Symbols in Shoes are broken in many ways. For example, the symbol progress is shared amongst types/progress and types/download, which causes Shoes to crash if defined in either ones. It should also be noted that Shoes crashes even if progress is defined here below. It apparently has to be defined on top of ruby{.c,.h}. Image and TextBlock/Text/TextLink are also heavily affected by this.
+#define SYMBOL_DEFS(f) f(bind); f(gsub); f(keys); f(update); f(merge); \
+ f(new); f(URI); f(now); f(debug); f(info); f(warn); f(error); f(run); \
+ f(to_a); f(to_ary); f(to_f); f(to_i); f(to_int); f(to_s); f(to_str); \
+ f(align); f(angle); f(angle1); f(angle2); f(arrow); f(autoplay); f(begin); \
+ f(body); f(cancel); f(call); f(center); f(change); f(choose); f(click); \
+ f(corner); f(curve); f(distance); f(displace_left); f(displace_top); \
+ f(downcase); f(draw); f(emphasis); f(end); f(family); f(fill); f(finish); \
+ f(font); f(fraction); f(fullscreen); f(group); f(hand); f(headers); \
+ f(hidden); f(host); f(hover); f(href); f(insert); f(inner); f(items); \
+ f(justify); f(kerning); f(keydown); f(keypress); f(keyup); f(match); \
+ f(method); f(motion); f(leading); f(leave); f(ok); f(outer); f(path); \
+ f(points); f(port); f(redirect); f(release); f(request_uri); f(rise); \
+ f(scheme); f(save); f(size); f(state); f(wheel); f(scroll); f(stretch); \
+ f(strikecolor); f(strikethrough); f(stroke); f(start); f(attach); f(title); \
+ f(top); f(right); f(bottom); f(left); f(up); f(down); f(height); \
+ f(minheight); f(remove); f(resizable); f(strokewidth); f(cap); f(widget); \
+ f(width); f(minwidth); f(marker); f(margin); f(margin_left); f(margin_right); \
+ f(margin_top); f(margin_bottom); f(radius); f(secret); f(blur); f(glow); \
+ f(shadow); f(arc); f(rect); f(oval); f(line); f(star); f(project); f(round); \
+ f(square); f(undercolor); f(underline); f(variant); f(weight); f(wrap); \
+ f(dash); f(nodot); f(onedot); f(donekey); f(volume); f(bg_color); \
+ f(decorated); f(opacity)
#define SYMBOL_INTERN(name) s_##name = rb_intern("" # name)
#define SYMBOL_ID(name) ID s_##name
#define SYMBOL_EXTERN(name) extern ID s_##name
SYMBOL_DEFS(SYMBOL_EXTERN);
+// TODO: temporary extern until refactoring proper component, i.e. text should move with TextEditBox in native/gtk
+SYMBOL_EXTERN(text);
+SYMBOL_EXTERN(link);
+
#define CANVAS_DEFS(f) \
f(".close", close, 0); \
f(".gutter", get_gutter_width, 0); \
- f(".nostroke", nostroke, 0); \
- f(".stroke", stroke, -1); \
- f(".strokewidth", strokewidth, 1); \
- f(".dash", dash, 1); \
- f(".cap", cap, 1); \
- f(".nofill", nofill, 0); \
- f(".fill", fill, -1); \
- f("+arc", arc, -1); \
- f("+rect", rect, -1); \
- f("+oval", oval, -1); \
- f("+line", line, -1); \
- f("+arrow", arrow, -1); \
- f("+star", star, -1); \
- f("+para", para, -1); \
- f("+banner", banner, -1); \
- f("+title", title, -1); \
- f("+subtitle", subtitle, -1); \
- f("+tagline", tagline, -1); \
- f("+caption", caption, -1); \
- f("+inscription", inscription, -1); \
- f(".code", code, -1); \
- f(".del", del, -1); \
- f(".em", em, -1); \
- f(".ins", ins, -1); \
- f(".link", link, -1); \
- f(".span", span, -1); \
- f(".strong", strong, -1); \
- f(".sub", sub, -1); \
- f(".sup", sup, -1); \
- f("+background", background, -1); \
- f("+border", border, -1); \
- /*f("+video", video, -1);*/ \
- f(".blur", blur, -1); \
- f(".glow", glow, -1); \
- f(".shadow", shadow, -1); \
- f("+image", image, -1); \
- f(".imagesize", imagesize, 1); \
- f("+animate", animate, -1); \
- f("+every", every, -1); \
- f("+timer", timer, -1); \
- f("+svg", svg, -1); \
- f("+svghandle", svghandle, -1); \
- f("+plot", plot, -1); \
- f("+chart_series", chart_series, -1); \
- f("+shape", shape, -1); \
- f(".move_to", move_to, 2); \
- f(".line_to", line_to, 2); \
- f(".curve_to", curve_to, 6); \
- f(".arc_to", arc_to, 6); \
- f(".transform", transform, 1); \
- f(".translate", translate, 2); \
- f(".rotate", rotate, 1); \
- f(".scale", scale, -1); \
- f(".skew", skew, -1); \
f(".push", push, 0); \
f(".pop", pop, 0); \
f(".reset", reset, 0); \
- f("+button", button, -1); \
- f("+list_box", list_box, -1); \
- f("+edit_line", edit_line, -1); \
- f("+edit_box", edit_box, -1); \
- f("+text_edit_box", text_edit_box, -1); \
- f("+progress", progress, -1); \
- f("+slider", slider, -1); \
- f("+check", check, -1); \
- f("+radio", radio, -1); \
f(".app", get_app, 0); \
f("+after", after, -1); \
f("+before", before, -1); \
@@ -304,7 +595,6 @@ SYMBOL_DEFS(SYMBOL_EXTERN);
f(".cursor=", set_cursor, 1); \
f(".clipboard", get_clipboard, 0); \
f(".clipboard=", set_clipboard, 1); \
- f(".download", download, -1); \
f(".owner", owner, 0); \
f(".window", window, -1); \
f(".dialog", dialog, -1); \
diff --git a/shoes/svg.c b/shoes/svg.c
deleted file mode 100644
index a9f69a67..00000000
--- a/shoes/svg.c
+++ /dev/null
@@ -1,741 +0,0 @@
-/*
- * svghandle - experimental for 3.3.0
- * svg (the widget - two different Shoes/Ruby object
-*/
-#include "shoes/app.h"
-#include "shoes/canvas.h"
-#include "shoes/ruby.h"
-#include "shoes/internal.h"
-#include "shoes/world.h"
-#include "shoes/native.h"
-#include "shoes/version.h"
-#include "shoes/http.h"
-#include "shoes/effects.h"
-#include
-
-// ------svghandle --------
-
-void
-shoes_svghandle_mark(shoes_svghandle *handle)
-{
- // we don't have any Ruby objects to mark.
-}
-
-static void
-shoes_svghandle_free(shoes_svghandle *handle)
-{
- if (handle->handle != NULL)
- g_object_unref(handle->handle);
- if (handle->path) free(handle->path);
- if (handle->data) free(handle->data);
- if (handle->subid) free(handle->subid);
- RUBY_CRITICAL(SHOE_FREE(handle));
-}
-
-VALUE
-shoes_svghandle_alloc(VALUE klass)
-{
- VALUE obj;
- shoes_svghandle *handle = SHOE_ALLOC(shoes_svghandle);
- SHOE_MEMZERO(handle, shoes_svghandle, 1);
- obj = Data_Wrap_Struct(klass, NULL, shoes_svghandle_free, handle);
- handle->handle = NULL;
- handle->subid = NULL;
- return obj;
-}
-
-VALUE
-shoes_svghandle_new(int argc, VALUE *argv, VALUE parent)
-{
- // parse args for :content or :filename (load file if needed)
- // parse arg for subid.
- VALUE filename = shoes_hash_get(argv[0], rb_intern("filename"));
- VALUE fromstring = shoes_hash_get(argv[0], rb_intern("content"));
- VALUE subidObj = shoes_hash_get(argv[0], rb_intern("group"));
- VALUE aspectObj = shoes_hash_get(argv[0], rb_intern("aspect"));
-
- VALUE obj = shoes_svghandle_alloc(cSvgHandle);
- shoes_svghandle *self_t;
- Data_Get_Struct(obj, shoes_svghandle, self_t);
-
- GError *gerror = NULL;
- if (!NIL_P(filename)) {
- // load it from a file
- char *path = RSTRING_PTR(filename);
- self_t->handle = rsvg_handle_new_from_file (path, &gerror);
- if (self_t->handle == NULL) {
- self_t->path = NULL;
- printf("Failed SVG: %s\n", gerror->message);
- } else self_t->path = strdup(RSTRING_PTR(filename));
-
- } else if (!NIL_P(fromstring)) {
- // load it from a string
- char *data = RSTRING_PTR(fromstring);
- int len = RSTRING_LEN(fromstring);
- // being Ruby, those are UTF-8, may not be what rsvg wants (const guint8 *)
- // Problem for OSX ?
- self_t->handle = rsvg_handle_new_from_data ((const unsigned char *)data, len, &gerror);
- if (self_t->handle == NULL) {
- self_t->data = NULL;
- printf("Failed SVG: %s\n", gerror->message);
- } //else self_t->data = strdup(RSTRING_PTR(fromstring));
-
- } else {
- // never reached, handled by shoes_svg_new
- }
-
- if (!NIL_P(subidObj) && (RSTRING_LEN(subidObj) > 0))
- {
- if (rsvg_handle_has_sub(self_t->handle, RSTRING_PTR(subidObj))) {
- self_t->subid = strdup(RSTRING_PTR(subidObj));
- if (!rsvg_handle_get_dimensions_sub(self_t->handle, &self_t->svghdim, self_t->subid))
- printf("no dim for %s\n", self_t->subid);
- if (!rsvg_handle_get_position_sub(self_t->handle, &self_t->svghpos, self_t->subid))
- printf("no pos for %s\n",self_t->subid);
- } else {
- printf("not a valid id %s\n",self_t->subid);
- self_t->subid = NULL;
- }
- }
- else
- {
- rsvg_handle_get_dimensions(self_t->handle, &self_t->svghdim);
- self_t->svghpos.x = self_t->svghpos.y = 0;
- self_t->subid = NULL;
- }
-
- if (NIL_P(aspectObj) || (aspectObj == Qtrue))
- { // :aspect => true or not specified, Keep aspect ratio
- self_t->aspect = 0.0;
- }
- else if (aspectObj == Qfalse)
- { // :aspect => false, Don't keep aspect ratio
- self_t->aspect = -1.0;
- }
- else if (TYPE(aspectObj) == T_FLOAT)
- { // :aspect => a double (ie 1.33), Don't keep aspect ratio
- self_t->aspect = NUM2DBL(aspectObj);
- }
- else
- { // fallback on keep aspect ratio
- self_t->aspect = 0.0;
- }
-/*
- printf("sub x: %i, y: %i, w: %i, h: %i)\n",
- self_t->svghpos.x, self_t->svghpos.y,
- self_t->svghdim.width, self_t->svghdim.height);
-*/
- return obj;
-}
-
-VALUE
-shoes_svghandle_get_width(VALUE self)
-{
- GET_STRUCT(svghandle, self_t);
- return INT2NUM(self_t->svghdim.width);
-}
-
-VALUE
-shoes_svghandle_get_height(VALUE self)
-{
- GET_STRUCT(svghandle, self_t);
- return INT2NUM(self_t->svghdim.height);
-}
-
-/* Needed for some odd situations -samples/good-flip.rb */
-VALUE shoes_svghandle_has_group(VALUE self, VALUE group)
-{
- shoes_svghandle *handle;
- Data_Get_Struct(self, shoes_svghandle, handle);
- if (!NIL_P(group) && (TYPE(group) == T_STRING)) {
- char *grp = RSTRING_PTR(group);
- int has = rsvg_handle_has_sub(handle->handle, grp);
- if (has)
- return Qtrue;
- else
- return Qnil;
- }
- else {
- rb_raise(rb_eArgError, "bad argument, expecting a String \n");
- }
-}
-
-
-/* ------- SVG widget -----
- * several methods are defined in ruby.c Macros (CLASS_COMMON2, TRANS_COMMON)
- */
-
-// forward declares in this file
-static int
-shoes_svg_draw_surface(cairo_t *, shoes_svg *, shoes_place *, int, int);
-
-// alloc some memory for a shoes_svg; We'll protect it from gc
-// out of caution. fingers crossed.
-void
-shoes_svg_mark(shoes_svg *svg)
-{
- rb_gc_mark_maybe(svg->parent);
- rb_gc_mark_maybe(svg->attr);
- rb_gc_mark_maybe(svg->svghandle);
-}
-
-static void
-shoes_svg_free(shoes_svg *svg)
-{
- shoes_transform_release(svg->st);
- RUBY_CRITICAL(SHOE_FREE(svg));
-}
-
-VALUE
-shoes_svg_alloc(VALUE klass)
-{
- VALUE obj;
- shoes_svg *svg = SHOE_ALLOC(shoes_svg);
- SHOE_MEMZERO(svg, shoes_svg, 1);
- obj = Data_Wrap_Struct(klass, shoes_svg_mark, shoes_svg_free, svg);
- svg->svghandle = Qnil;
- svg->parent = Qnil;
- svg->st = NULL;
- return obj;
-}
-
-void
-svg_aspect_ratio(int imw, int imh, shoes_svg *self_t, shoes_svghandle *svghan)
-{
- double outw = imw * 1.0; // width given to svg()
- double outh = imh * 1.0; // height given to svg()
-
- self_t->scalew = outw / svghan->svghdim.width; // don't keep aspect ratio, Fill provided or deduced dimensions
- self_t->scaleh = outh / svghan->svghdim.height; //
-
- if (svghan->aspect == 0.0) { // keep aspect ratio
- self_t->scalew = self_t->scaleh = MIN(outw / svghan->svghdim.width, outh / svghan->svghdim.height);
-
- } else if (svghan->aspect > 0.0) { // don't keep aspect ratio, User aspect ratio
-
- double new_svgdim_height = svghan->svghdim.width / svghan->aspect;
- double new_svgdim_width = svghan->svghdim.height * svghan->aspect;
-
- if (outw / new_svgdim_width < outh / new_svgdim_height)
- self_t->scaleh = self_t->scalew * new_svgdim_height / svghan->svghdim.height;
- else
- self_t->scalew = self_t->scaleh * new_svgdim_width / svghan->svghdim.width;
- }
-}
-
-VALUE
-shoes_svg_new(int argc, VALUE *argv, VALUE parent)
-{
- VALUE attr = Qnil, widthObj, heightObj, svg_string = Qnil;
- VALUE svghanObj = Qnil;
- shoes_canvas *canvas;
- Data_Get_Struct(parent, shoes_canvas, canvas);
-
- rb_arg_list args;
-// switch (rb_parse_args(argc, argv, "s|h", &args))
- switch (rb_parse_args(argc, argv, "s|h,o|h", &args))
- {
- case 1:
- svg_string = args.a[0];
- attr = args.a[1];
- break;
- case 2:
- // if first arg is an svghandle
- if (rb_obj_is_kind_of(args.a[0], cSvgHandle)) {
- svghanObj = args.a[0];
- attr = args.a[1];
- } else
- rb_raise(rb_eArgError, "bad argument, expecting a String or a Shoes::SvgHandle \n");
- break;
- }
- if (NIL_P(attr)) attr = rb_hash_new();
-
- // get width and height out of hash/attr arg
- if (RTEST(ATTR(attr, width))) {
- widthObj = ATTR(attr, width);
- } else
- widthObj = RTEST(ATTR(canvas->attr, width)) ? ATTR(canvas->attr, width) : Qnil;
-
- if ( RTEST(ATTR(attr, height))) {
- heightObj = ATTR(attr, height);
- } else
- heightObj = RTEST(ATTR(canvas->attr, height)) ? ATTR(canvas->attr, height) : Qnil;
-
- if (NIL_P(svghanObj)) { // likely case
- if (strstr(RSTRING_PTR(svg_string), "") != NULL) //TODO
- shoes_hash_set(attr, rb_intern("content"), svg_string);
- else
- shoes_hash_set(attr, rb_intern("filename"), svg_string);
- svghanObj = shoes_svghandle_new(1, &attr, parent);
- }
-
- shoes_svghandle *shandle;
- Data_Get_Struct(svghanObj, shoes_svghandle, shandle);
-
- // we couldn't find the width/height of the parent canvas, now that we have a rsvg handle,
- // fallback to original size as defined in the svg file but no more than Shoes.app size
- if (widthObj == Qnil) {
- widthObj = INT2NUM(shandle->svghdim.width);
- widthObj = (shandle->svghdim.width >= canvas->app->width) ?
- INT2NUM(canvas->app->width) : widthObj;
- }
- if (heightObj == Qnil) {
- heightObj = INT2NUM(shandle->svghdim.height);
- heightObj = (shandle->svghdim.height >= canvas->app->height) ?
- INT2NUM(canvas->app->height) : heightObj;
- }
- ATTRSET(attr, width, widthObj);
- ATTRSET(attr, height, heightObj);
-
- VALUE obj = shoes_svg_alloc(cSvg);
- shoes_svg *self_t;
- Data_Get_Struct(obj, shoes_svg, self_t);
-
- self_t->svghandle = svghanObj;
- self_t->place.w = NUM2INT(widthObj);
- self_t->place.h = NUM2INT(heightObj);
- self_t->parent = parent;
- self_t->scalew = 0.0;
- self_t->scaleh = 0.0;
- self_t->attr = attr;
- // initialize cairo matrice used in transform methods (rotate, scale, skew, translate)
- self_t->st = shoes_transform_touch(canvas->st);
-
- // useless !!?? needs to be confirmed
-// shoes_place place;
-// shoes_place_exact(&place, self_t->attr, 0, 0);
-// if (place.iw < 1) place.w = place.iw;
-// if (place.ih < 1) place.h = place.ih;
-//
-// shoes_svg_draw_surface(self_t->cr, self_t, &place, place.w, place.h);
-
- return obj;
-}
-
-static int
-shoes_svg_draw_surface(cairo_t *cr, shoes_svg *self_t, shoes_place *place, int imw, int imh)
-{
- shoes_svghandle *svghan;
- Data_Get_Struct(self_t->svghandle, shoes_svghandle, svghan);
-
- // calculate aspect ratio only once at initialization
- if (self_t->scalew == 0.0 && self_t->scaleh == 0.0) {
- svg_aspect_ratio(imw, imh, self_t, svghan);
- }
-
- /* drawing on svg parent's (canvas) surface */
- // applying any transform : translate, rotate, scale, skew
- shoes_apply_transformation(cr, self_t->st, place, 0); // cairo_save(cr) inside
-
- cairo_translate(cr, place->ix + place->dx, place->iy + place->dy);
-
- if (svghan->subid == NULL) {
- cairo_scale(cr, self_t->scalew, self_t->scaleh);
- } else {
- cairo_scale(cr, self_t->scalew, self_t->scaleh); // order of scaling + translate matters !!!
- cairo_translate(cr, -svghan->svghpos.x, -svghan->svghpos.y);
- }
-
- int result = rsvg_handle_render_cairo_sub(svghan->handle, cr, svghan->subid);
-
- shoes_undo_transformation(cr, self_t->st, place, 0); // doing cairo_restore(cr)
-
- self_t->place = *place;
-
- return result;
-}
-
-// This gets called very often by Shoes. May be slow for large SVG?
-VALUE shoes_svg_draw(VALUE self, VALUE c, VALUE actual)
-{
- shoes_svg *self_t;
- shoes_place place;
- shoes_canvas *canvas;
- Data_Get_Struct(self, shoes_svg, self_t);
- Data_Get_Struct(c, shoes_canvas, canvas);
- if (ATTR(self_t->attr, hidden) == Qtrue) return self;
- int rel =(REL_CANVAS | REL_SCALE);
- shoes_place_decide(&place, c, self_t->attr, self_t->place.w, self_t->place.h, rel, REL_COORDS(rel) == REL_CANVAS);
-
- if (RTEST(actual))
- shoes_svg_draw_surface( CCR(canvas), self_t, &place, place.w, place.h);
-
- if (!ABSY(place)) {
- canvas->cx += place.w;
- canvas->cy = place.y;
- canvas->endx = canvas->cx;
- canvas->endy = max(canvas->endy, place.y + place.h);
- }
- if(rb_obj_class(c) == cStack) {
- canvas->cx = CPX(canvas);
- canvas->cy = canvas->endy;
- }
- //printf("svg draw\n");
- return self;
-
-}
-
-VALUE
-shoes_svg_get_handle(VALUE self)
-{
- shoes_svg *self_t;
- Data_Get_Struct(self, shoes_svg, self_t);
- return self_t->svghandle;
-}
-
-
-VALUE
-shoes_svg_set_handle(VALUE self, VALUE han)
-{
- shoes_svg *self_t;
- Data_Get_Struct(self, shoes_svg, self_t);
-
- if ( !NIL_P(han) && (rb_obj_is_kind_of(han, cSvgHandle)) ) {
- self_t->svghandle = han;
- // force a garbage collection, cSvgHandles could pile up if set at a fast rate
- rb_gc();
-
- shoes_svghandle *svghan;
- Data_Get_Struct(self_t->svghandle, shoes_svghandle, svghan);
- svg_aspect_ratio(ATTR(self_t->attr, width), ATTR(self_t->attr, height), self_t, svghan);
- self_t->scalew = self_t->scalew/2; self_t->scaleh = self_t->scaleh/2;
-
- // updating cSvg attributes
- shoes_hash_set(self_t->attr, rb_intern("filename"),
- svghan->path ? rb_str_new_cstr(svghan->path) : Qnil);
-
- shoes_hash_set(self_t->attr, rb_intern("content"),
- svghan->data ? rb_str_new_cstr(svghan->data) : Qnil);
-
- shoes_hash_set(self_t->attr, rb_intern("group"),
- svghan->subid ? rb_str_new_cstr(svghan->subid) : Qnil);
-
- if (svghan->aspect == -1.0)
- shoes_hash_set(self_t->attr, rb_intern("aspect"), Qfalse);
- else if (svghan->aspect == 0.0 || svghan->aspect == 1.0)
- shoes_hash_set(self_t->attr, rb_intern("aspect"), Qtrue);
- else
- shoes_hash_set(self_t->attr, rb_intern("aspect"), DBL2NUM(svghan->aspect));
-
- shoes_canvas_repaint_all(self_t->parent);
-
- } else {
- rb_raise(rb_eArgError, "bad argument, expecting a Shoes::SvgHandle \n");
- }
-
- return han;
-}
-
-VALUE
-shoes_svg_get_dpi(VALUE self)
-{
- shoes_svg *self_t;
- Data_Get_Struct(self, shoes_svg, self_t);
- shoes_svghandle *svghan;
- Data_Get_Struct(self_t->svghandle, shoes_svghandle, svghan);
- double dpix, dpiy;
- g_object_get(svghan->handle, "dpi-x", &dpix, NULL);
- g_object_get(svghan->handle, "dpi-y", &dpiy, NULL);
-
- return DBL2NUM(dpix); //TODO dpi-x, dpi-y ?
-}
-
-VALUE
-shoes_svg_set_dpi(VALUE self, VALUE dpi)
-{
- shoes_svg *self_t;
- Data_Get_Struct(self, shoes_svg, self_t);
- shoes_svghandle *svghan;
- Data_Get_Struct(self_t->svghandle, shoes_svghandle, svghan);
-
- /* We have to handle the change in dpi ourselves as nothing in Shoes has a clue of what actually a dpi is
- * Default is 90 as per rsvg specification, so if dpi is set to 180 we have to
- * provide twice the number of pixels in x, twice in y,
- * IF at any moment it has a meaning inside the Shoes environment !!!
- */
- rsvg_handle_set_dpi(svghan->handle, NUM2DBL(dpi));
- //shoes_canvas_repaint_all(self_t->parent); // no meaning at the moment !
-
- return Qnil;
-}
-
-typedef cairo_public cairo_surface_t * (cairo_surface_function_t) (const char *filename, double width, double height);
-
-static cairo_surface_function_t *
-get_vector_surface(char *format)
-{
- if (strstr(format, "pdf") != NULL) return & cairo_pdf_surface_create;
- if (strstr(format, "ps") != NULL) return & cairo_ps_surface_create;
- if (strstr(format, "svg") != NULL) return & cairo_svg_surface_create;
- return NULL;
-}
-
-static cairo_surface_t*
-buid_surface(VALUE self, VALUE docanvas, double scale, int *result, char *filename, char *format)
-{
- shoes_svg *self_t;
- Data_Get_Struct(self, shoes_svg, self_t);
- shoes_canvas *canvas;
- Data_Get_Struct(self_t->parent, shoes_canvas, canvas);
- shoes_place place = self_t->place;
- cairo_surface_t *surf;
- cairo_t *cr;
-
- if (docanvas == Qtrue) {
- if (format != NULL)
- surf = get_vector_surface(format)(filename, canvas->width*scale, canvas->height*scale);
- else
- surf = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, (int)(canvas->width*scale), (int)(canvas->height*scale));
- cr = cairo_create(surf);
-
- if (scale != 1.0) cairo_scale(cr, scale, scale);
-// *result = shoes_svg_draw_surface(cr, self_t, &place, (int)(place.w*scale), (int)(place.h*scale));
- place.w = (int)(place.w*scale); place.h = (int)(place.h*scale);
- cairo_t *waz_cr = canvas->cr;
- canvas->cr = cr;
- shoes_canvas_draw(self_t->parent, self_t->parent, Qtrue);
- canvas->cr = waz_cr;
- *result = 1; //TODO
- } else {
- int w = (int)(NUM2INT(shoes_svg_get_actual_width(self))*scale);
- int h = (int)(NUM2INT(shoes_svg_get_actual_height(self))*scale);
- if (format != NULL)
- surf = get_vector_surface(format)(filename, w, h);
- else
- surf = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, w, h);
- cr = cairo_create(surf);
-
- if (scale != 1.0) cairo_scale(cr, scale, scale);
- cairo_translate(cr, -(place.ix + place.dx), -(place.iy + place.dy));
- *result = shoes_svg_draw_surface(cr, self_t, &place, w, h);
- }
- if (format != NULL) cairo_show_page(cr);
- cairo_destroy(cr);
-
- return surf;
-}
-
-VALUE shoes_svg_export(VALUE self, VALUE attr)
-{
- VALUE _filename, _dpi, _docanvas;
- _filename = shoes_hash_get(attr, rb_intern("filename"));
- _dpi = shoes_hash_get(attr, rb_intern("dpi"));
- _docanvas = shoes_hash_get(attr, rb_intern("canvas"));
- double scale = 1.0;
- int result;
-
- if (NIL_P(_filename)) {
- rb_raise(rb_eArgError, "wrong arguments for svg export ({:filename=>'...', "
- "[:dpi=>90, :canvas=>true|false] })\n:filename is mandatory\n");
- }
-
- if (!NIL_P(_dpi)) scale = NUM2INT(_dpi)/90.0;
-
- cairo_surface_t *surf = buid_surface(self, _docanvas, scale, &result, NULL, NULL);
-
- cairo_status_t r = cairo_surface_write_to_png(surf, RSTRING_PTR(_filename));
- cairo_surface_destroy(surf);
-
- return r == CAIRO_STATUS_SUCCESS ? Qtrue : Qfalse;
-}
-
-VALUE shoes_svg_save(VALUE self, VALUE attr)
-{
- VALUE _filename, _format, _docanvas;
- _filename = shoes_hash_get(attr, rb_intern("filename"));
- _format = shoes_hash_get(attr, rb_intern("format"));
- _docanvas = shoes_hash_get(attr, rb_intern("canvas"));
- int result;
-
- if (NIL_P(_filename) || NIL_P(_format)) {
- rb_raise(rb_eArgError, "wrong arguments for svg save ({:filename=>'...', "
- ":format=>'pdf'|'ps'|'svg' [, :canvas=>true|false] })\n:filename and :format are mandatory");
- }
-
- char *filename = RSTRING_PTR(_filename);
- char *format = RSTRING_PTR(_format);
-
- cairo_surface_t *surf = buid_surface(self, _docanvas, 1.0, &result, filename, format);
- cairo_surface_destroy(surf);
-
- return result == 0 ? Qfalse : Qtrue;
-}
-
-
-/* Not using PLACE_COMMMON Macro in ruby.c, as we do the svg rendering a bit differently
- * than other widgets [parent, left, top, width, height ruby methods]
- */
-VALUE
-shoes_svg_get_parent(VALUE self)
-{
- GET_STRUCT(svg, self_t);
- return self_t->parent;
-}
-
-VALUE
-shoes_svg_get_actual_width(VALUE self)
-{
- GET_STRUCT(svg, self_t);
- shoes_svghandle *svghan;
- Data_Get_Struct(self_t->svghandle, shoes_svghandle, svghan);
- return INT2NUM((int)floor(svghan->svghdim.width*self_t->scalew));
-}
-
-VALUE
-shoes_svg_get_actual_height(VALUE self)
-{
- GET_STRUCT(svg, self_t);
- shoes_svghandle *svghan;
- Data_Get_Struct(self_t->svghandle, shoes_svghandle, svghan);
- return INT2NUM((int)floor(svghan->svghdim.height*self_t->scaleh));
-}
-
-VALUE
-shoes_svg_get_actual_left(VALUE self)
-{
- GET_STRUCT(svg, self_t);
- return INT2NUM(self_t->place.ix + self_t->place.dx);
-}
-
-VALUE
-shoes_svg_get_actual_top(VALUE self)
-{
- GET_STRUCT(svg, self_t);
- return INT2NUM(self_t->place.iy + self_t->place.dy);
-}
-
-VALUE shoes_svg_preferred_width(VALUE self)
-{
- int w;
- GET_STRUCT(svg, self_t);
- shoes_svghandle *svghan;
- Data_Get_Struct(self_t->svghandle, shoes_svghandle, svghan);
- w = svghan->svghdim.width;
- return INT2NUM(w);
-}
-
-VALUE shoes_svg_preferred_height(VALUE self)
-{
- int h;
- GET_STRUCT(svg, self_t);
- shoes_svghandle *svghan;
- Data_Get_Struct(self_t->svghandle, shoes_svghandle, svghan);
- h = svghan->svghdim.height;
- return INT2NUM(h);
-}
-
-VALUE shoes_svg_get_offsetX(VALUE self)
-{
- GET_STRUCT(svg, self_t);
- shoes_svghandle *svghan;
- Data_Get_Struct(self_t->svghandle, shoes_svghandle, svghan);
- return INT2NUM(svghan->svghpos.x);
-}
-
-VALUE shoes_svg_get_offsetY(VALUE self)
-{
- GET_STRUCT(svg, self_t);
- shoes_svghandle *svghan;
- Data_Get_Struct(self_t->svghandle, shoes_svghandle, svghan);
- return INT2NUM(svghan->svghpos.y);
-}
-
-VALUE shoes_svg_has_group(VALUE self, VALUE group)
-{
- shoes_svg *self_t;
- shoes_svghandle *handle;
- int result = 0;
- Data_Get_Struct(self, shoes_svg, self_t);
- Data_Get_Struct(self_t->svghandle, shoes_svghandle, handle);
- if (!NIL_P(group) && (TYPE(group) == T_STRING)) {
- char *grp = RSTRING_PTR(group);
- result = rsvg_handle_has_sub(handle->handle, grp);
- }
- else {
- rb_raise(rb_eArgError, "bad argument, expecting a String \n");
- }
- return (result ? Qtrue : Qnil);
-}
-
-VALUE shoes_svg_remove(VALUE self)
-{
- //printf("remove\n");
- shoes_svg *self_t;
- shoes_canvas *canvas;
- Data_Get_Struct(self, shoes_svg, self_t);
- Data_Get_Struct(self_t->parent, shoes_canvas, canvas);
-
- rb_ary_delete(canvas->contents, self); // shoes_basic_remove does it this way
- shoes_canvas_repaint_all(self_t->parent); //
-
- // let ruby gc collect handle (it may be shared) just remove this ref
- self_t->svghandle = Qnil;
- self_t = NULL;
- self = Qnil;
-
- return Qtrue;
-}
-
-//called by shoes_svg_send_click and shoes_canvas_send_motion
-VALUE
-shoes_svg_motion(VALUE self, int x, int y, char *touch)
-{
- char h = 0;
- VALUE click;
- GET_STRUCT(svg, self_t);
-
- click = ATTR(self_t->attr, click);
-
- if (IS_INSIDE(self_t, x, y)) {
- if (!NIL_P(click)) {
- shoes_canvas *canvas;
- Data_Get_Struct(self_t->parent, shoes_canvas, canvas);
- shoes_app_cursor(canvas->app, s_link);
- }
- h = 1;
- }
-
- /* Checks if element is hovered, clicked, released, leaved
- * and eventually calls hover and/or leave callbacks
- * if hovered: self_t->hover == 1
- * if leaved: self_t->hover == 0
- * if clicked and not yet released:
- * if hovered + clicked: self_t->hover == 3
- * if leaved + clicked: self_t->hover == 2
- */
- CHECK_HOVER(self_t, h, touch);
-
- return h ? click : Qnil;
-}
-
-// called by shoes_canvas_send_click --> shoes_canvas_send_click2
-VALUE
-shoes_svg_send_click(VALUE self, int button, int x, int y)
-{
- VALUE v = Qnil;
-
- if (button > 0) {
- GET_STRUCT(svg, self_t);
- v = shoes_svg_motion(self, x, y, NULL);
- if (self_t->hover & HOVER_MOTION) // ok, cursor is over the element, proceed
- self_t->hover = HOVER_MOTION | HOVER_CLICK; // we have been clicked, but not yet released
- }
-
- // if we found a click callback send it back to shoes_canvas_send_click method
- // where it will be processed
- return v;
-}
-
-// called by shoes_canvas_send_release
-void
-shoes_svg_send_release(VALUE self, int button, int x, int y)
-{
- GET_STRUCT(svg, self_t);
- if (button > 0 && (self_t->hover & HOVER_CLICK)) {
- VALUE proc = ATTR(self_t->attr, release);
- self_t->hover ^= HOVER_CLICK; // we have been clicked and released
- if (!NIL_P(proc))
- shoes_safe_block(self, proc, rb_ary_new3(3, INT2NUM(button), INT2NUM(x), INT2NUM(y)));
- }
-}
-
diff --git a/shoes/types/button.c b/shoes/types/button.c
new file mode 100644
index 00000000..31b837c2
--- /dev/null
+++ b/shoes/types/button.c
@@ -0,0 +1,74 @@
+#include "shoes/types/native.h"
+#include "shoes/types/radio.h"
+#include "shoes/types/button.h"
+
+// ruby
+VALUE cButton;
+
+FUNC_M("+button", button, -1);
+
+void shoes_button_init() {
+ cButton = rb_define_class_under(cTypes, "Button", cNative);
+ rb_define_method(cButton, "draw", CASTHOOK(shoes_button_draw), 2);
+ rb_define_method(cButton, "click", CASTHOOK(shoes_control_click), -1);
+ rb_define_method(cButton, "tooltip", CASTHOOK(shoes_control_get_tooltip), 0);
+ rb_define_method(cButton, "tooltip=", CASTHOOK(shoes_control_set_tooltip), 1);
+ RUBY_M("+button", button, -1);
+}
+
+VALUE shoes_button_draw(VALUE self, VALUE c, VALUE actual) {
+ SETUP_CONTROL(2, 0, TRUE);
+
+#ifdef SHOES_QUARTZ
+ place.h += 8;
+ place.ih += 8;
+#endif
+ if (RTEST(actual)) {
+ if (self_t->ref == NULL) {
+ self_t->ref = shoes_native_button(self, canvas, &place, self_t->attr, msg);
+ shoes_control_check_styles(self_t);
+ shoes_native_control_position(self_t->ref, &self_t->place, self, canvas, &place);
+ } else
+ shoes_native_control_repaint(self_t->ref, &self_t->place, canvas, &place);
+ }
+
+ FINISH();
+
+ return self;
+}
+
+void shoes_button_send_click(VALUE control) {
+ if (rb_obj_is_kind_of(control, cRadio))
+ shoes_check_set_checked_m(control, Qtrue);
+ shoes_control_send(control, s_click);
+}
+
+// canvas
+VALUE shoes_canvas_button(int argc, VALUE *argv, VALUE self) {
+ rb_arg_list args;
+ VALUE text = Qnil, attr = Qnil, button;
+
+ SETUP_CANVAS();
+
+ switch (rb_parse_args(argc, argv, "s|h,|h", &args)) {
+ case 1:
+ text = args.a[0];
+ attr = args.a[1];
+ break;
+
+ case 2:
+ attr = args.a[0];
+ break;
+ }
+
+ if (!NIL_P(text))
+ ATTRSET(attr, text, text);
+
+ if (rb_block_given_p())
+ ATTRSET(attr, click, rb_block_proc());
+
+ button = shoes_control_new(cButton, attr, self);
+ shoes_add_ele(canvas, button);
+
+ return button;
+}
diff --git a/shoes/types/button.h b/shoes/types/button.h
new file mode 100644
index 00000000..d524b87c
--- /dev/null
+++ b/shoes/types/button.h
@@ -0,0 +1,29 @@
+#include "shoes/ruby.h"
+#include "shoes/canvas.h"
+#include "shoes/app.h"
+#include "shoes/internal.h"
+#include "shoes/world.h"
+#include "shoes/native/native.h"
+
+#ifndef SHOES_BUTTON_TYPE_H
+#define SHOES_BUTTON_TYPE_H
+
+/* extern variables necessary to communicate with other parts of Shoes */
+extern VALUE cShoes, cApp, cTypes, cCanvas, cWidget;
+extern shoes_app _shoes_app;
+
+/* Should be automatically available but ruby.c is not sharing enough information */
+extern VALUE shoes_control_click(int argc, VALUE *argv, VALUE self);
+extern SHOES_CONTROL_REF shoes_native_button(VALUE self, shoes_canvas *canvas, shoes_place *place, VALUE attr, char *msg);
+
+/* each widget should have its own init function */
+void shoes_button_init();
+
+// ruby
+VALUE shoes_button_draw(VALUE self, VALUE c, VALUE actual);
+void shoes_button_send_click(VALUE control);
+
+// canvas
+VALUE shoes_canvas_button(int argc, VALUE *argv, VALUE self);
+
+#endif
diff --git a/shoes/types/check.c b/shoes/types/check.c
new file mode 100644
index 00000000..15dc7a1b
--- /dev/null
+++ b/shoes/types/check.c
@@ -0,0 +1,69 @@
+#include "shoes/types/native.h"
+#include "shoes/types/check.h"
+
+// ruby
+VALUE cCheck;
+
+FUNC_M("+check", check, -1);
+
+void shoes_check_init() {
+ cCheck = rb_define_class_under(cTypes, "Check", cNative);
+ rb_define_method(cCheck, "draw", CASTHOOK(shoes_check_draw), 2);
+ rb_define_method(cCheck, "checked?", CASTHOOK(shoes_check_is_checked), 0);
+ rb_define_method(cCheck, "checked=", CASTHOOK(shoes_check_set_checked), 1);
+ rb_define_method(cCheck, "click", CASTHOOK(shoes_control_click), -1);
+ rb_define_method(cCheck, "tooltip", CASTHOOK(shoes_control_get_tooltip), 0);
+ rb_define_method(cCheck, "tooltip=", CASTHOOK(shoes_control_set_tooltip), 1);
+
+ RUBY_M("+check", check, -1);
+}
+
+// ruby
+VALUE shoes_check_draw(VALUE self, VALUE c, VALUE actual) {
+ SETUP_CONTROL(0, 20, FALSE);
+
+ if (RTEST(actual)) {
+ if (self_t->ref == NULL) {
+ self_t->ref = shoes_native_check(self, canvas, &place, self_t->attr, msg);
+ if (RTEST(ATTR(self_t->attr, checked))) shoes_native_check_set(self_t->ref, Qtrue);
+ shoes_control_check_styles(self_t);
+ shoes_native_control_position(self_t->ref, &self_t->place, self, canvas, &place);
+ } else
+ shoes_native_control_repaint(self_t->ref, &self_t->place, canvas, &place);
+ }
+
+ FINISH();
+
+ return self;
+}
+
+VALUE shoes_check_is_checked(VALUE self) {
+ GET_STRUCT(control, self_t);
+ return shoes_native_check_get(self_t->ref);
+}
+
+VALUE shoes_check_set_checked(VALUE self, VALUE on) {
+ GET_STRUCT(control, self_t);
+ ATTRSET(self_t->attr, checked, on);
+ if (self_t->ref != NULL)
+ shoes_native_check_set(self_t->ref, RTEST(on));
+ return on;
+}
+
+// canvas
+VALUE shoes_canvas_check(int argc, VALUE *argv, VALUE self) {
+ rb_arg_list args;
+ VALUE check;
+
+ SETUP_CANVAS();
+
+ rb_parse_args(argc, argv, "|h", &args);
+
+ if (rb_block_given_p())
+ ATTRSET(args.a[0], click, rb_block_proc());
+
+ check = shoes_control_new(cCheck, args.a[0], self);
+ shoes_add_ele(canvas, check);
+
+ return check;
+}
diff --git a/shoes/types/check.h b/shoes/types/check.h
new file mode 100644
index 00000000..ae824446
--- /dev/null
+++ b/shoes/types/check.h
@@ -0,0 +1,36 @@
+#include "shoes/ruby.h"
+#include "shoes/canvas.h"
+#include "shoes/app.h"
+#include "shoes/internal.h"
+#include "shoes/world.h"
+#include "shoes/native/native.h"
+
+#ifndef SHOES_CHECK_TYPE_H
+#define SHOES_CHECK_TYPE_H
+
+/* extern variables necessary to communicate with other parts of Shoes */
+extern VALUE cShoes, cApp, cTypes, cCanvas, cWidget;
+extern shoes_app _shoes_app;
+
+SYMBOL_ID(checked);
+
+/* Should be automatically available but ruby.c is not sharing enough information */
+extern VALUE shoes_control_click(int argc, VALUE *argv, VALUE self);
+
+// native forward declarations
+extern SHOES_CONTROL_REF shoes_native_check(VALUE self, shoes_canvas *canvas, shoes_place *place, VALUE attr, char *msg);
+extern VALUE shoes_native_check_get(SHOES_CONTROL_REF ref);
+extern void shoes_native_check_set(SHOES_CONTROL_REF ref, int on);
+
+/* each widget should have its own init function */
+void shoes_check_init();
+
+// ruby
+VALUE shoes_check_draw(VALUE self, VALUE c, VALUE actual);
+VALUE shoes_check_is_checked(VALUE self);
+VALUE shoes_check_set_checked(VALUE self, VALUE on);
+
+// canvas
+VALUE shoes_canvas_check(int, VALUE *, VALUE);
+
+#endif
diff --git a/shoes/types/color.c b/shoes/types/color.c
new file mode 100644
index 00000000..7a3814e4
--- /dev/null
+++ b/shoes/types/color.c
@@ -0,0 +1,465 @@
+#include "shoes/types/pattern.h"
+#include "shoes/types/color.h"
+
+// ruby
+VALUE cColor, cColors;
+
+void shoes_color_init() {
+ cColor = rb_define_class_under(cTypes, "Color", rb_cObject);
+
+ rb_define_alloc_func(cColor, shoes_color_alloc);
+ rb_define_method(rb_mKernel, "rgb", CASTHOOK(shoes_color_rgb), -1);
+ rb_define_method(rb_mKernel, "gray", CASTHOOK(shoes_color_gray), -1);
+ rb_define_singleton_method(cColor, "rgb", CASTHOOK(shoes_color_rgb), -1);
+ rb_define_singleton_method(cColor, "gray", CASTHOOK(shoes_color_gray), -1);
+ rb_define_singleton_method(cColor, "parse", CASTHOOK(shoes_color_parse), 1);
+
+ rb_include_module(cColor, rb_mComparable);
+ rb_define_method(cColor, "<=>", CASTHOOK(shoes_color_spaceship), 1);
+ rb_define_method(cColor, "==", CASTHOOK(shoes_color_equal), 1);
+ rb_define_method(cColor, "eql?", CASTHOOK(shoes_color_equal), 1);
+ rb_define_method(cColor, "red", CASTHOOK(shoes_color_get_red), 0);
+ rb_define_method(cColor, "green", CASTHOOK(shoes_color_get_green), 0);
+ rb_define_method(cColor, "blue", CASTHOOK(shoes_color_get_blue), 0);
+ rb_define_method(cColor, "alpha", CASTHOOK(shoes_color_get_alpha), 0);
+ rb_define_method(cColor, "black?", CASTHOOK(shoes_color_is_black), 0);
+ rb_define_method(cColor, "dark?", CASTHOOK(shoes_color_is_dark), 0);
+ rb_define_method(cColor, "inspect", CASTHOOK(shoes_color_to_s), 0);
+ rb_define_method(cColor, "invert", CASTHOOK(shoes_color_invert), 0);
+ rb_define_method(cColor, "light?", CASTHOOK(shoes_color_is_light), 0);
+ rb_define_method(cColor, "opaque?", CASTHOOK(shoes_color_is_opaque), 0);
+ rb_define_method(cColor, "to_s", CASTHOOK(shoes_color_to_s), 0);
+ rb_define_method(cColor, "to_pattern", CASTHOOK(shoes_color_to_pattern), 0);
+ rb_define_method(cColor, "transparent?", CASTHOOK(shoes_color_is_transparent), 0);
+ rb_define_method(cColor, "white?", CASTHOOK(shoes_color_is_white), 0);
+
+ rb_define_method(cCanvas, "method_missing", CASTHOOK(shoes_color_method_missing), -1);
+
+ rb_define_method(rb_mKernel, "rgb", CASTHOOK(shoes_color_rgb), -1);
+ rb_define_method(rb_mKernel, "gray", CASTHOOK(shoes_color_gray), -1);
+ rb_define_method(rb_mKernel, "gradient", CASTHOOK(shoes_color_gradient), -1);
+
+ rb_const_set(cTypes, rb_intern("ALL_NAMED_COLORS"), rb_hash_new());
+ cColors = rb_const_get(cTypes, rb_intern("ALL_NAMED_COLORS"));
+ rb_const_set(cTypes, rb_intern("COLORS"), cColors);
+ DEF_COLOR(aliceblue, 240, 248, 255);
+ DEF_COLOR(antiquewhite, 250, 235, 215);
+ DEF_COLOR(aqua, 0, 255, 255);
+ DEF_COLOR(aquamarine, 127, 255, 212);
+ DEF_COLOR(azure, 240, 255, 255);
+ DEF_COLOR(beige, 245, 245, 220);
+ DEF_COLOR(bisque, 255, 228, 196);
+ DEF_COLOR(black, 0, 0, 0);
+ DEF_COLOR(blanchedalmond, 255, 235, 205);
+ DEF_COLOR(blue, 0, 0, 255);
+ DEF_COLOR(blueviolet, 138, 43, 226);
+ DEF_COLOR(brown, 165, 42, 42);
+ DEF_COLOR(burlywood, 222, 184, 135);
+ DEF_COLOR(cadetblue, 95, 158, 160);
+ DEF_COLOR(chartreuse, 127, 255, 0);
+ DEF_COLOR(chocolate, 210, 105, 30);
+ DEF_COLOR(coral, 255, 127, 80);
+ DEF_COLOR(cornflowerblue, 100, 149, 237);
+ DEF_COLOR(cornsilk, 255, 248, 220);
+ DEF_COLOR(crimson, 220, 20, 60);
+ DEF_COLOR(cyan, 0, 255, 255);
+ DEF_COLOR(darkblue, 0, 0, 139);
+ DEF_COLOR(darkcyan, 0, 139, 139);
+ DEF_COLOR(darkgoldenrod, 184, 134, 11);
+ DEF_COLOR(darkgray, 169, 169, 169);
+ DEF_COLOR(darkgreen, 0, 100, 0);
+ DEF_COLOR(darkkhaki, 189, 183, 107);
+ DEF_COLOR(darkmagenta, 139, 0, 139);
+ DEF_COLOR(darkolivegreen, 85, 107, 47);
+ DEF_COLOR(darkorange, 255, 140, 0);
+ DEF_COLOR(darkorchid, 153, 50, 204);
+ DEF_COLOR(darkred, 139, 0, 0);
+ DEF_COLOR(darksalmon, 233, 150, 122);
+ DEF_COLOR(darkseagreen, 143, 188, 143);
+ DEF_COLOR(darkslateblue, 72, 61, 139);
+ DEF_COLOR(darkslategray, 47, 79, 79);
+ DEF_COLOR(darkturquoise, 0, 206, 209);
+ DEF_COLOR(darkviolet, 148, 0, 211);
+ DEF_COLOR(deeppink, 255, 20, 147);
+ DEF_COLOR(deepskyblue, 0, 191, 255);
+ DEF_COLOR(dimgray, 105, 105, 105);
+ DEF_COLOR(dodgerblue, 30, 144, 255);
+ DEF_COLOR(firebrick, 178, 34, 34);
+ DEF_COLOR(floralwhite, 255, 250, 240);
+ DEF_COLOR(forestgreen, 34, 139, 34);
+ DEF_COLOR(fuchsia, 255, 0, 255);
+ DEF_COLOR(gainsboro, 220, 220, 220);
+ DEF_COLOR(ghostwhite, 248, 248, 255);
+ DEF_COLOR(gold, 255, 215, 0);
+ DEF_COLOR(goldenrod, 218, 165, 32);
+ DEF_COLOR(gray, 128, 128, 128);
+ DEF_COLOR(green, 0, 128, 0);
+ DEF_COLOR(greenyellow, 173, 255, 47);
+ DEF_COLOR(honeydew, 240, 255, 240);
+ DEF_COLOR(hotpink, 255, 105, 180);
+ DEF_COLOR(indianred, 205, 92, 92);
+ DEF_COLOR(indigo, 75, 0, 130);
+ DEF_COLOR(ivory, 255, 255, 240);
+ DEF_COLOR(khaki, 240, 230, 140);
+ DEF_COLOR(lavender, 230, 230, 250);
+ DEF_COLOR(lavenderblush, 255, 240, 245);
+ DEF_COLOR(lawngreen, 124, 252, 0);
+ DEF_COLOR(lemonchiffon, 255, 250, 205);
+ DEF_COLOR(lightblue, 173, 216, 230);
+ DEF_COLOR(lightcoral, 240, 128, 128);
+ DEF_COLOR(lightcyan, 224, 255, 255);
+ DEF_COLOR(lightgoldenrodyellow, 250, 250, 210);
+ DEF_COLOR(lightgreen, 144, 238, 144);
+ DEF_COLOR(lightgrey, 211, 211, 211);
+ DEF_COLOR(lightpink, 255, 182, 193);
+ DEF_COLOR(lightsalmon, 255, 160, 122);
+ DEF_COLOR(lightseagreen, 32, 178, 170);
+ DEF_COLOR(lightskyblue, 135, 206, 250);
+ DEF_COLOR(lightslategray, 119, 136, 153);
+ DEF_COLOR(lightsteelblue, 176, 196, 222);
+ DEF_COLOR(lightyellow, 255, 255, 224);
+ DEF_COLOR(lime, 0, 255, 0);
+ DEF_COLOR(limegreen, 50, 205, 50);
+ DEF_COLOR(linen, 250, 240, 230);
+ DEF_COLOR(magenta, 255, 0, 255);
+ DEF_COLOR(maroon, 128, 0, 0);
+ DEF_COLOR(mediumaquamarine, 102, 205, 170);
+ DEF_COLOR(mediumblue, 0, 0, 205);
+ DEF_COLOR(mediumorchid, 186, 85, 211);
+ DEF_COLOR(mediumpurple, 147, 112, 219);
+ DEF_COLOR(mediumseagreen, 60, 179, 113);
+ DEF_COLOR(mediumslateblue, 123, 104, 238);
+ DEF_COLOR(mediumspringgreen, 0, 250, 154);
+ DEF_COLOR(mediumturquoise, 72, 209, 204);
+ DEF_COLOR(mediumvioletred, 199, 21, 133);
+ DEF_COLOR(midnightblue, 25, 25, 112);
+ DEF_COLOR(mintcream, 245, 255, 250);
+ DEF_COLOR(mistyrose, 255, 228, 225);
+ DEF_COLOR(moccasin, 255, 228, 181);
+ DEF_COLOR(navajowhite, 255, 222, 173);
+ DEF_COLOR(navy, 0, 0, 128);
+ DEF_COLOR(oldlace, 253, 245, 230);
+ DEF_COLOR(olive, 128, 128, 0);
+ DEF_COLOR(olivedrab, 107, 142, 35);
+ DEF_COLOR(orange, 255, 165, 0);
+ DEF_COLOR(orangered, 255, 69, 0);
+ DEF_COLOR(orchid, 218, 112, 214);
+ DEF_COLOR(palegoldenrod, 238, 232, 170);
+ DEF_COLOR(palegreen, 152, 251, 152);
+ DEF_COLOR(paleturquoise, 175, 238, 238);
+ DEF_COLOR(palevioletred, 219, 112, 147);
+ DEF_COLOR(papayawhip, 255, 239, 213);
+ DEF_COLOR(peachpuff, 255, 218, 185);
+ DEF_COLOR(peru, 205, 133, 63);
+ DEF_COLOR(pink, 255, 192, 203);
+ DEF_COLOR(plum, 221, 160, 221);
+ DEF_COLOR(powderblue, 176, 224, 230);
+ DEF_COLOR(purple, 128, 0, 128);
+ DEF_COLOR(red, 255, 0, 0);
+ DEF_COLOR(rosybrown, 188, 143, 143);
+ DEF_COLOR(royalblue, 65, 105, 225);
+ DEF_COLOR(saddlebrown, 139, 69, 19);
+ DEF_COLOR(salmon, 250, 128, 114);
+ DEF_COLOR(sandybrown, 244, 164, 96);
+ DEF_COLOR(seagreen, 46, 139, 87);
+ DEF_COLOR(seashell, 255, 245, 238);
+ DEF_COLOR(sienna, 160, 82, 45);
+ DEF_COLOR(silver, 192, 192, 192);
+ DEF_COLOR(skyblue, 135, 206, 235);
+ DEF_COLOR(slateblue, 106, 90, 205);
+ DEF_COLOR(slategray, 112, 128, 144);
+ DEF_COLOR(snow, 255, 250, 250);
+ DEF_COLOR(springgreen, 0, 255, 127);
+ DEF_COLOR(steelblue, 70, 130, 180);
+ DEF_COLOR(tan, 210, 180, 140);
+ DEF_COLOR(teal, 0, 128, 128);
+ DEF_COLOR(thistle, 216, 191, 216);
+ DEF_COLOR(tomato, 255, 99, 71);
+ DEF_COLOR(turquoise, 64, 224, 208);
+ DEF_COLOR(violet, 238, 130, 238);
+ DEF_COLOR(wheat, 245, 222, 179);
+ DEF_COLOR(white, 255, 255, 255);
+ DEF_COLOR(whitesmoke, 245, 245, 245);
+ DEF_COLOR(yellow, 255, 255, 0);
+ DEF_COLOR(yellowgreen, 154, 205, 50);
+}
+
+// ruby
+void shoes_color_mark(shoes_color *color) {
+}
+
+void shoes_color_free(shoes_color *color) {
+ RUBY_CRITICAL(free(color));
+}
+
+VALUE shoes_color_new(int r, int g, int b, int a) {
+ shoes_color *color;
+ VALUE obj = shoes_color_alloc(cColor);
+ Data_Get_Struct(obj, shoes_color, color);
+ color->r = r;
+ color->g = g;
+ color->b = b;
+ color->a = a;
+ return obj;
+}
+
+VALUE shoes_color_alloc(VALUE klass) {
+ VALUE obj;
+ shoes_color *color = SHOE_ALLOC(shoes_color);
+ SHOE_MEMZERO(color, shoes_color, 1);
+ obj = Data_Wrap_Struct(klass, shoes_color_mark, shoes_color_free, color);
+ color->a = SHOES_COLOR_OPAQUE;
+ color->on = TRUE;
+ return obj;
+}
+
+VALUE shoes_color_rgb(int argc, VALUE *argv, VALUE self) {
+ int a;
+ VALUE _r, _g, _b, _a;
+ rb_scan_args(argc, argv, "31", &_r, &_g, &_b, &_a);
+
+ a = SHOES_COLOR_OPAQUE;
+ if (!NIL_P(_a)) a = NUM2RGBINT(_a);
+ return shoes_color_new(NUM2RGBINT(_r), NUM2RGBINT(_g), NUM2RGBINT(_b), a);
+}
+
+VALUE shoes_color_gradient(int argc, VALUE *argv, VALUE self) {
+ shoes_pattern *pattern;
+ VALUE obj, r1, r2;
+ VALUE attr = Qnil;
+ rb_scan_args(argc, argv, "21", &r1, &r2, &attr);
+ CHECK_HASH(attr);
+
+ obj = shoes_pattern_alloc(cPattern);
+ Data_Get_Struct(obj, shoes_pattern, pattern);
+ pattern->source = Qnil;
+ shoes_pattern_gradient(pattern, r1, r2, attr);
+ return obj;
+}
+
+VALUE shoes_color_gray(int argc, VALUE *argv, VALUE self) {
+ VALUE _g, _a;
+ int g, a;
+ rb_scan_args(argc, argv, "02", &_g, &_a);
+
+ a = SHOES_COLOR_OPAQUE;
+ g = 128;
+ if (!NIL_P(_g)) g = NUM2RGBINT(_g);
+ if (!NIL_P(_a)) a = NUM2RGBINT(_a);
+ return shoes_color_new(g, g, g, a);
+}
+
+cairo_pattern_t *shoes_color_pattern(VALUE self) {
+ GET_STRUCT(color, color);
+ if (color->a == 255)
+ return cairo_pattern_create_rgb(color->r / 255., color->g / 255., color->b / 255.);
+ else
+ return cairo_pattern_create_rgba(color->r / 255., color->g / 255., color->b / 255., color->a / 255.);
+}
+
+void shoes_color_grad_stop(cairo_pattern_t *pattern, double stop, VALUE self) {
+ GET_STRUCT(color, color);
+ if (color->a == 255)
+ return cairo_pattern_add_color_stop_rgb(pattern, stop, color->r / 255., color->g / 255., color->b / 255.);
+ else
+ return cairo_pattern_add_color_stop_rgba(pattern, stop, color->r / 255., color->g / 255., color->b / 255., color->a / 255.);
+}
+
+VALUE shoes_color_args(int argc, VALUE *argv, VALUE self) {
+ VALUE _r, _g, _b, _a, _color;
+ argc = rb_scan_args(argc, argv, "13", &_r, &_g, &_b, &_a);
+
+ if (argc == 1 && rb_obj_is_kind_of(_r, cColor))
+ _color = _r;
+ else if (argc == 1 && rb_obj_is_kind_of(_r, rb_cString))
+ _color = shoes_color_parse(cColor, _r);
+ else if (argc == 1 || argc == 2)
+ _color = shoes_color_gray(argc, argv, cColor);
+ else
+ _color = shoes_color_rgb(argc, argv, cColor);
+
+ return _color;
+}
+
+VALUE shoes_color_parse(VALUE self, VALUE source) {
+ VALUE reg;
+
+ reg = rb_funcall(source, s_match, 1, reHEX3_SOURCE);
+ if (!NIL_P(reg)) {
+ NEW_COLOR(color, obj);
+ color->r = NUM2INT(rb_str2inum(rb_reg_nth_match(1, reg), 16)) * 17;
+ color->g = NUM2INT(rb_str2inum(rb_reg_nth_match(2, reg), 16)) * 17;
+ color->b = NUM2INT(rb_str2inum(rb_reg_nth_match(3, reg), 16)) * 17;
+ return obj;
+ }
+
+ reg = rb_funcall(source, s_match, 1, reHEX_SOURCE);
+ if (!NIL_P(reg)) {
+ NEW_COLOR(color, obj);
+ color->r = NUM2INT(rb_str2inum(rb_reg_nth_match(1, reg), 16));
+ color->g = NUM2INT(rb_str2inum(rb_reg_nth_match(2, reg), 16));
+ color->b = NUM2INT(rb_str2inum(rb_reg_nth_match(3, reg), 16));
+ return obj;
+ }
+
+ reg = rb_funcall(source, s_match, 1, reRGB_SOURCE);
+ if (!NIL_P(reg)) {
+ NEW_COLOR(color, obj);
+ color->r = NUM2INT(rb_Integer(rb_reg_nth_match(1, reg)));
+ color->g = NUM2INT(rb_Integer(rb_reg_nth_match(2, reg)));
+ color->b = NUM2INT(rb_Integer(rb_reg_nth_match(3, reg)));
+ return obj;
+ }
+
+ reg = rb_funcall(source, s_match, 1, reRGBA_SOURCE);
+ if (!NIL_P(reg)) {
+ NEW_COLOR(color, obj);
+ color->r = NUM2INT(rb_Integer(rb_reg_nth_match(1, reg)));
+ color->g = NUM2INT(rb_Integer(rb_reg_nth_match(2, reg)));
+ color->b = NUM2INT(rb_Integer(rb_reg_nth_match(3, reg)));
+ color->a = NUM2INT(rb_Integer(rb_reg_nth_match(4, reg)));
+ return obj;
+ }
+
+ reg = rb_funcall(source, s_match, 1, reGRAY_SOURCE);
+ if (!NIL_P(reg)) {
+ NEW_COLOR(color, obj);
+ color->r = color->g = color->b = NUM2INT(rb_Integer(rb_reg_nth_match(1, reg)));
+ return obj;
+ }
+
+ reg = rb_funcall(source, s_match, 1, reGRAYA_SOURCE);
+ if (!NIL_P(reg)) {
+ NEW_COLOR(color, obj);
+ color->r = color->g = color->b = NUM2INT(rb_Integer(rb_reg_nth_match(1, reg)));
+ color->a = NUM2INT(rb_Integer(rb_reg_nth_match(2, reg)));
+ return obj;
+ }
+
+ return Qnil;
+}
+
+VALUE shoes_color_spaceship(VALUE self, VALUE c2) {
+ int v1, v2;
+ shoes_color *color2;
+ GET_STRUCT(color, color);
+ if (!rb_obj_is_kind_of(c2, cColor)) return Qnil;
+ Data_Get_Struct(c2, shoes_color, color2);
+ v1 = color->r + color->g + color->b;
+ v2 = color2->r + color2->g + color2->b;
+ if (v1 == v2) return INT2FIX(0);
+ if (v1 > v2) return INT2FIX(1);
+ else return INT2FIX(-1);
+}
+
+VALUE shoes_color_equal(VALUE self, VALUE c2) {
+ if (!rb_obj_is_kind_of(c2, cColor)) return Qnil;
+
+ GET_STRUCT(color, color);
+ shoes_color *color2;
+ Data_Get_Struct(c2, shoes_color, color2);
+ if (color->r == color2->r && color->g == color2->g &&
+ color->b == color2->b && color->a == color2->a ) {
+ return Qtrue;
+ } else return Qfalse;
+}
+
+VALUE shoes_color_get_red(VALUE self) {
+ GET_STRUCT(color, color);
+ return INT2NUM(color->r);
+}
+
+VALUE shoes_color_get_green(VALUE self) {
+ GET_STRUCT(color, color);
+ return INT2NUM(color->g);
+}
+
+VALUE shoes_color_get_blue(VALUE self) {
+ GET_STRUCT(color, color);
+ return INT2NUM(color->b);
+}
+
+VALUE shoes_color_get_alpha(VALUE self) {
+ GET_STRUCT(color, color);
+ return INT2NUM(color->a);
+}
+
+VALUE shoes_color_is_black(VALUE self) {
+ GET_STRUCT(color, color);
+ return (color->r + color->g + color->b == 0) ? Qtrue : Qfalse;
+}
+
+VALUE shoes_color_is_dark(VALUE self) {
+ GET_STRUCT(color, color);
+ return ((int)color->r + (int)color->g + (int)color->b < SHOES_COLOR_DARK) ? Qtrue : Qfalse;
+}
+
+VALUE shoes_color_is_light(VALUE self) {
+ GET_STRUCT(color, color);
+ return ((int)color->r + (int)color->g + (int)color->b > SHOES_COLOR_LIGHT) ? Qtrue : Qfalse;
+}
+
+VALUE shoes_color_is_opaque(VALUE self) {
+ GET_STRUCT(color, color);
+ return (color->a == SHOES_COLOR_OPAQUE) ? Qtrue : Qfalse;
+}
+
+VALUE shoes_color_is_transparent(VALUE self) {
+ GET_STRUCT(color, color);
+ return (color->a == SHOES_COLOR_TRANSPARENT) ? Qtrue : Qfalse;
+}
+
+VALUE shoes_color_is_white(VALUE self) {
+ GET_STRUCT(color, color);
+ return (color->r + color->g + color->b == 765) ? Qtrue : Qfalse;
+}
+
+VALUE shoes_color_invert(VALUE self) {
+ GET_STRUCT(color, color);
+ NEW_COLOR(color2, obj);
+ color2->r = 255 - color->r;
+ color2->g = 255 - color->g;
+ color2->b = 255 - color->b;
+ color2->a = color->a;
+ return obj;
+}
+
+VALUE shoes_color_to_s(VALUE self) {
+ GET_STRUCT(color, color);
+
+ VALUE ary = rb_ary_new3(4,
+ INT2NUM(color->r), INT2NUM(color->g), INT2NUM(color->b),
+ rb_float_new((color->a * 1.) / 255.));
+
+ if (color->a == 255)
+ return rb_funcall(rb_str_new2("rgb(%d, %d, %d)"), s_perc, 1, ary);
+ else
+ return rb_funcall(rb_str_new2("rgb(%d, %d, %d, %0.1f)"), s_perc, 1, ary);
+}
+
+// TODO: deprecated code remove after 2017-10
+VALUE shoes_color_to_pattern(VALUE self) {
+ return shoes_pattern_method(cPattern, self);
+}
+
+VALUE shoes_color_method_missing(int argc, VALUE *argv, VALUE self) {
+ VALUE alpha;
+ VALUE cname = argv[0];
+ VALUE c = Qnil;
+ if (rb_obj_is_kind_of(cColors, rb_cHash))
+ c = rb_hash_aref(cColors, cname);
+ if (NIL_P(c)) {
+ self = rb_inspect(self);
+ rb_raise(rb_eNoMethodError, "undefined method `%s' for %s",
+ rb_id2name(SYM2ID(cname)), RSTRING_PTR(self));
+ }
+
+ rb_scan_args(argc, argv, "11", &cname, &alpha);
+ if (!NIL_P(alpha)) {
+ shoes_color *color;
+ Data_Get_Struct(c, shoes_color, color);
+ c = shoes_color_new(color->r, color->g, color->b, NUM2RGBINT(alpha));
+ }
+
+ return c;
+}
\ No newline at end of file
diff --git a/shoes/types/color.h b/shoes/types/color.h
new file mode 100644
index 00000000..4b7c6749
--- /dev/null
+++ b/shoes/types/color.h
@@ -0,0 +1,68 @@
+#include "shoes/ruby.h"
+#include "shoes/canvas.h"
+#include "shoes/app.h"
+#include "shoes/internal.h"
+#include "shoes/world.h"
+#include "shoes/native/native.h"
+
+#ifndef SHOES_COLOR_TYPE_H
+#define SHOES_COLOR_TYPE_H
+
+/* extern variables necessary to communicate with other parts of Shoes */
+extern VALUE cShoes, cApp, cTypes, cCanvas, cWidget;
+extern shoes_app _shoes_app;
+
+VALUE cColor, cColors;
+
+typedef struct {
+ unsigned char r, g, b, a, on;
+} shoes_color;
+
+#define SHOES_COLOR_OPAQUE 0xFF
+#define SHOES_COLOR_TRANSPARENT 0x0
+#define SHOES_COLOR_DARK (0x55 * 3)
+#define SHOES_COLOR_LIGHT (0xAA * 3)
+
+#define DEF_COLOR(name, r, g, b) rb_hash_aset(cColors, ID2SYM(rb_intern("" # name)), shoes_color_new(r, g, b, 255))
+#define NEW_COLOR(v, o) \
+ shoes_color *v; \
+ VALUE o = shoes_color_alloc(cColor); \
+ Data_Get_Struct(o, shoes_color, v)
+
+VALUE cColor, cColors;
+
+/* each widget should have its own init function */
+void shoes_color_init();
+
+// ruby
+void shoes_color_mark(shoes_color *color);
+void shoes_color_free(shoes_color *color);
+VALUE shoes_color_new(int r, int g, int b, int a);
+VALUE shoes_color_alloc(VALUE klass);
+VALUE shoes_color_rgb(int argc, VALUE *argv, VALUE self);
+VALUE shoes_color_gradient(int argc, VALUE *argv, VALUE self);
+VALUE shoes_color_gray(int argc, VALUE *argv, VALUE self);
+cairo_pattern_t *shoes_color_pattern(VALUE self);
+void shoes_color_grad_stop(cairo_pattern_t *pattern, double stop, VALUE self);
+VALUE shoes_color_args(int argc, VALUE *argv, VALUE self);
+VALUE shoes_color_parse(VALUE self, VALUE source);
+VALUE shoes_color_spaceship(VALUE self, VALUE c2);
+VALUE shoes_color_equal(VALUE self, VALUE c2);
+VALUE shoes_color_get_red(VALUE self);
+VALUE shoes_color_get_green(VALUE self);
+VALUE shoes_color_get_blue(VALUE self);
+VALUE shoes_color_get_alpha(VALUE self);
+VALUE shoes_color_is_black(VALUE self);
+VALUE shoes_color_is_dark(VALUE self);
+VALUE shoes_color_is_light(VALUE self);
+VALUE shoes_color_is_opaque(VALUE self);
+VALUE shoes_color_is_transparent(VALUE self);
+VALUE shoes_color_is_white(VALUE self);
+VALUE shoes_color_invert(VALUE self);
+VALUE shoes_color_to_s(VALUE self);
+VALUE shoes_color_to_pattern(VALUE self);
+VALUE shoes_color_method_missing(int argc, VALUE *argv, VALUE self);
+
+// canvas
+
+#endif
diff --git a/shoes/types/download.c b/shoes/types/download.c
new file mode 100644
index 00000000..12bbb5d3
--- /dev/null
+++ b/shoes/types/download.c
@@ -0,0 +1,306 @@
+#include "shoes/types/download.h"
+
+// ruby
+VALUE cDownload, cResponse;
+
+FUNC_M("+download", download, -1);
+
+EVENT_COMMON(http, http_klass, start);
+EVENT_COMMON(http, http_klass, progress);
+EVENT_COMMON(http, http_klass, finish);
+EVENT_COMMON(http, http_klass, error);
+
+void shoes_download_init() {
+ cDownload = rb_define_class_under(cTypes, "Download", rb_cObject);
+ rb_define_alloc_func(cDownload, shoes_http_alloc);
+ rb_define_method(cDownload, "abort", CASTHOOK(shoes_http_abort), 0);
+ rb_define_method(cDownload, "finish", CASTHOOK(shoes_http_finish), -1);
+ rb_define_method(cDownload, "remove", CASTHOOK(shoes_http_remove), 0);
+ rb_define_method(cDownload, "length", CASTHOOK(shoes_http_length), 0);
+ rb_define_method(cDownload, "percent", CASTHOOK(shoes_http_percent), 0);
+ rb_define_method(cDownload, "progress", CASTHOOK(shoes_http_progress), -1);
+ rb_define_method(cDownload, "response", CASTHOOK(shoes_http_response), 0);
+ rb_define_method(cDownload, "size", CASTHOOK(shoes_http_length), 0);
+ rb_define_method(cDownload, "start", CASTHOOK(shoes_http_start), -1);
+ rb_define_method(cDownload, "transferred", CASTHOOK(shoes_http_transferred), 0);
+
+ cResponse = rb_define_class_under(cDownload, "Response", rb_cObject);
+ rb_define_method(cResponse, "body", CASTHOOK(shoes_response_body), 0);
+ rb_define_method(cResponse, "headers", CASTHOOK(shoes_response_headers), 0);
+ rb_define_method(cResponse, "status", CASTHOOK(shoes_response_status), 0);
+ rb_define_method(cResponse, "text", CASTHOOK(shoes_response_body), 0);
+
+ RUBY_M("+download", download, -1);
+}
+
+// ruby (download)
+void shoes_http_mark(shoes_http_klass *dl) {
+ rb_gc_mark_maybe(dl->parent);
+ rb_gc_mark_maybe(dl->attr);
+ rb_gc_mark_maybe(dl->response);
+}
+
+void shoes_http_free(shoes_http_klass *dl) {
+ RUBY_CRITICAL(free(dl));
+}
+
+VALUE shoes_http_new(VALUE klass, VALUE parent, VALUE attr) {
+ shoes_http_klass *dl;
+ VALUE obj = shoes_http_alloc(klass);
+ Data_Get_Struct(obj, shoes_http_klass, dl);
+ dl->parent = parent;
+ dl->attr = attr;
+ return obj;
+}
+
+VALUE shoes_http_alloc(VALUE klass) {
+ VALUE obj;
+ shoes_http_klass *dl = SHOE_ALLOC(shoes_http_klass);
+ SHOE_MEMZERO(dl, shoes_http_klass, 1);
+ obj = Data_Wrap_Struct(klass, shoes_http_mark, shoes_http_free, dl);
+ dl->parent = Qnil;
+ dl->attr = Qnil;
+ dl->response = Qnil;
+ return obj;
+}
+
+VALUE shoes_http_remove(VALUE self) {
+ GET_STRUCT(http_klass, self_t);
+ self_t->state = SHOES_DOWNLOAD_HALT;
+ shoes_canvas_remove_item(self_t->parent, self, 0, 1);
+ return self;
+}
+
+VALUE shoes_http_abort(VALUE self) {
+ GET_STRUCT(http_klass, self_t);
+ self_t->state = SHOES_DOWNLOAD_HALT;
+ return self;
+}
+
+int shoes_message_download(VALUE self, void *data) {
+ VALUE proc = Qnil;
+ shoes_http_event *de = (shoes_http_event *)data;
+ GET_STRUCT(http_klass, dl);
+ INFO("EVENT: %d (%d), %lu, %llu, %llu\n", (int)de->stage, (int)de->error, de->percent,
+ de->transferred, de->total);
+
+ switch (de->stage) {
+ case SHOES_HTTP_STATUS:
+ dl->response = shoes_response_new(cResponse, (int)de->status);
+ return 0;
+
+ case SHOES_HTTP_HEADER: {
+ VALUE h = shoes_response_headers(dl->response);
+ rb_hash_aset(h, rb_str_new(de->hkey, de->hkeylen), rb_str_new(de->hval, de->hvallen));
+ }
+ return 0;
+
+ case SHOES_HTTP_ERROR:
+ proc = ATTR(dl->attr, error);
+ if (!NIL_P(proc))
+ shoes_safe_block(dl->parent, proc, rb_ary_new3(2, self, shoes_http_err(de->error)));
+ else
+ shoes_canvas_error(self, shoes_http_err(de->error));
+ return 0;
+
+ case SHOES_HTTP_COMPLETED:
+ if (de->body != NULL) rb_iv_set(dl->response, "body", rb_str_new(de->body, de->total));
+ }
+
+ dl->percent = de->percent;
+ dl->total = de->total;
+ dl->transferred = de->transferred;
+
+ switch (de->stage) {
+ case SHOES_HTTP_CONNECTED:
+ proc = ATTR(dl->attr, start);
+ break;
+ case SHOES_HTTP_TRANSFER:
+ proc = ATTR(dl->attr, progress);
+ break;
+ case SHOES_HTTP_COMPLETED:
+ proc = ATTR(dl->attr, finish);
+ break;
+ }
+
+ if (!NIL_P(proc))
+ shoes_safe_block(dl->parent, proc, rb_ary_new3(1, self));
+ return dl->state;
+}
+
+int shoes_doth_handler(shoes_http_event *de, void *data) {
+ shoes_doth_data *doth = (shoes_doth_data *)data;
+ shoes_http_event *de2 = SHOE_ALLOC(shoes_http_event);
+ SHOE_MEMCPY(de2, de, shoes_http_event, 1);
+ return shoes_throw_message(SHOES_THREAD_DOWNLOAD, doth->download, de2);
+}
+
+void shoes_http_request_free(shoes_http_request *req) {
+ if (req->url != NULL) free(req->url);
+ if (req->scheme != NULL) free(req->scheme);
+ if (req->host != NULL) free(req->host);
+ if (req->path != NULL) free(req->path);
+ if (req->method != NULL) free(req->method);
+ if (req->filepath != NULL) free(req->filepath);
+ if (req->body != NULL) free(req->body);
+ if (req->headers != NULL) shoes_http_headers_free(req->headers);
+ if (req->mem != NULL) free(req->mem);
+}
+
+VALUE shoes_http_threaded(VALUE self, VALUE url, VALUE attr) {
+ VALUE obj = shoes_http_new(cDownload, self, attr);
+ GET_STRUCT(canvas, self_t);
+ char *url_string = NULL;
+
+ if (!rb_respond_to(url, s_host)) {
+ url_string = strdup(RSTRING_PTR(url));
+ url = rb_funcall(rb_mKernel, s_URI, 1, url);
+ }
+
+ VALUE scheme = rb_funcall(url, s_scheme, 0);
+ VALUE host = rb_funcall(url, s_host, 0);
+ VALUE port = rb_funcall(url, s_port, 0);
+ VALUE path = rb_funcall(url, s_request_uri, 0);
+
+ if (url_string == NULL) {
+ url_string = SHOE_ALLOC_N(char, SHOES_BUFSIZE);
+ char slash[2] = "/";
+ if (RSTRING_PTR(path)[0] == '/') slash[0] = '\0';
+// sprintf(url_string, "%s://%s:%d%s%s", RSTRING_PTR(scheme), RSTRING_PTR(host),
+ sprintf(url_string, "%s://%s:%s%s%s", RSTRING_PTR(scheme), RSTRING_PTR(host),
+ RSTRING_PTR(port), slash, RSTRING_PTR(path));
+ }
+
+ shoes_http_request *req = SHOE_ALLOC(shoes_http_request);
+ SHOE_MEMZERO(req, shoes_http_request, 1);
+ req->url = url_string;
+ req->scheme = strdup(RSTRING_PTR(scheme));
+ req->host = strdup(RSTRING_PTR(host));
+ req->port = NUM2INT(port);
+ req->path = strdup(RSTRING_PTR(path));
+ req->handler = shoes_doth_handler;
+ req->flags = SHOES_DL_DEFAULTS;
+ if (ATTR(attr, redirect) == Qfalse) req->flags ^= SHOES_DL_REDIRECTS;
+
+ VALUE method = ATTR(attr, method);
+ VALUE headers = ATTR(attr, headers);
+ VALUE body = ATTR(attr, body);
+ if (!NIL_P(body)) {
+ req->body = strdup(RSTRING_PTR(body));
+ req->bodylen = RSTRING_LEN(body);
+ }
+ if (!NIL_P(method)) req->method = strdup(RSTRING_PTR(method));
+ if (!NIL_P(headers)) req->headers = shoes_http_headers(headers);
+
+ VALUE save = ATTR(attr, save);
+ if (req->method == NULL || strcmp(req->method, "HEAD") != 0) {
+ if (NIL_P(save)) {
+ req->mem = SHOE_ALLOC_N(char, SHOES_BUFSIZE);
+ req->memlen = SHOES_BUFSIZE;
+ } else {
+ req->filepath = strdup(RSTRING_PTR(save));
+ }
+ }
+
+ shoes_doth_data *data = SHOE_ALLOC(shoes_doth_data);
+ data->download = obj;
+ req->data = data;
+
+ shoes_queue_download(req);
+ return obj;
+}
+
+VALUE shoes_http_length(VALUE self) {
+ GET_STRUCT(http_klass, dl);
+ return rb_ull2inum(dl->total);
+}
+
+VALUE shoes_http_percent(VALUE self) {
+ GET_STRUCT(http_klass, dl);
+ return rb_uint2inum(dl->percent);
+}
+
+VALUE shoes_http_response(VALUE self) {
+ GET_STRUCT(http_klass, dl);
+ return dl->response;
+}
+
+VALUE shoes_http_transferred(VALUE self) {
+ GET_STRUCT(http_klass, dl);
+ return rb_ull2inum(dl->transferred);
+}
+
+// ruby (response)
+VALUE shoes_response_new(VALUE klass, int status) {
+ VALUE obj = rb_obj_alloc(cResponse);
+ rb_iv_set(obj, "body", Qnil);
+ rb_iv_set(obj, "headers", rb_hash_new());
+ rb_iv_set(obj, "status", INT2NUM(status));
+ return obj;
+}
+
+VALUE shoes_response_body(VALUE self) {
+ return rb_iv_get(self, "body");
+}
+
+VALUE shoes_response_headers(VALUE self) {
+ return rb_iv_get(self, "headers");
+}
+
+VALUE shoes_response_status(VALUE self) {
+ return rb_iv_get(self, "status");
+}
+
+// TODO: handle exceptions
+int shoes_catch_message(unsigned int name, VALUE obj, void *data) {
+ int ret = SHOES_DOWNLOAD_CONTINUE;
+ switch (name) {
+ case SHOES_THREAD_DOWNLOAD:
+ ret = shoes_message_download(obj, data);
+ free(data);
+ break;
+ case SHOES_IMAGE_DOWNLOAD: {
+ VALUE hash, etag = Qnil, uri, uext, path, realpath;
+ shoes_image_download_event *side = (shoes_image_download_event *)data;
+ if (shoes_image_downloaded(side)) {
+ shoes_canvas_repaint_all(side->slot);
+
+ path = rb_str_new2(side->filepath);
+ uri = rb_str_new2(side->uripath);
+ hash = rb_str_new2(side->hexdigest);
+ if (side->etag != NULL) etag = rb_str_new2(side->etag);
+ uext = rb_funcall(rb_cFile, rb_intern("extname"), 1, path);
+
+ rb_funcall(rb_const_get(rb_cObject, rb_intern("DATABASE")),
+ rb_intern("notify_cache_of"), 3, uri, etag, hash);
+ if (side->status != 304) {
+ realpath = rb_funcall(cShoes, rb_intern("image_cache_path"), 2, hash, uext);
+ rename(side->filepath, RSTRING_PTR(realpath));
+ }
+ }
+
+ free(side->filepath);
+ free(side->uripath);
+ if (side->etag != NULL) free(side->etag);
+ free(data);
+ }
+ break;
+ }
+ return ret;
+}
+
+// canvas
+VALUE shoes_canvas_download(int argc, VALUE *argv, VALUE self) {
+ VALUE url, block, obj, attr = Qnil;
+
+ SETUP_CANVAS();
+
+ rb_scan_args(argc, argv, "11&", &url, &attr, &block);
+ CHECK_HASH(attr);
+ if (!NIL_P(block))
+ ATTRSET(attr, finish, block);
+ obj = shoes_http_threaded(self, url, attr);
+ rb_ary_push(canvas->app->extras, obj);
+
+ return obj;
+}
diff --git a/shoes/types/download.h b/shoes/types/download.h
new file mode 100644
index 00000000..bbe5e9c9
--- /dev/null
+++ b/shoes/types/download.h
@@ -0,0 +1,51 @@
+#include "shoes/ruby.h"
+#include "shoes/canvas.h"
+#include "shoes/app.h"
+#include "shoes/internal.h"
+#include "shoes/world.h"
+#include "shoes/native/native.h"
+#include "shoes/http.h"
+
+#ifndef SHOES_DOWNLOAD_TYPE_H
+#define SHOES_DOWNLOAD_TYPE_H
+
+/* extern variables necessary to communicate with other parts of Shoes */
+extern VALUE cShoes, cApp, cTypes, cCanvas, cWidget;
+extern shoes_app _shoes_app;
+
+typedef struct {
+ SHOES_CONTROL_REF ref;
+ VALUE download;
+} shoes_doth_data;
+
+/* each widget should have its own init function */
+void shoes_download_init();
+
+// ruby (download)
+void shoes_http_mark(shoes_http_klass *dl);
+void shoes_http_free(shoes_http_klass *dl);
+VALUE shoes_http_new(VALUE klass, VALUE parent, VALUE attr);
+VALUE shoes_http_alloc(VALUE klass);
+VALUE shoes_http_remove(VALUE self);
+VALUE shoes_http_abort(VALUE self);
+int shoes_message_download(VALUE self, void *data);
+
+int shoes_doth_handler(shoes_http_event *de, void *data);
+void shoes_http_request_free(shoes_http_request *req);
+VALUE shoes_http_threaded(VALUE self, VALUE url, VALUE attr);
+VALUE shoes_http_length(VALUE self);
+VALUE shoes_http_percent(VALUE self);
+VALUE shoes_http_response(VALUE self);
+VALUE shoes_http_transferred(VALUE self);
+
+// ruby (response)
+VALUE shoes_response_new(VALUE klass, int status);
+VALUE shoes_response_body(VALUE self);
+VALUE shoes_response_headers(VALUE self);
+VALUE shoes_response_status(VALUE self);
+int shoes_catch_message(unsigned int name, VALUE obj, void *data);
+
+// canvas
+VALUE shoes_canvas_download(int, VALUE *, VALUE);
+
+#endif
diff --git a/shoes/types/edit_box.c b/shoes/types/edit_box.c
new file mode 100644
index 00000000..34f87d5b
--- /dev/null
+++ b/shoes/types/edit_box.c
@@ -0,0 +1,108 @@
+#include "shoes/types/native.h"
+#include "shoes/types/edit_box.h"
+
+// ruby
+VALUE cEditBox;
+
+FUNC_M("+edit_box", edit_box, -1);
+
+void shoes_edit_box_init() {
+ cEditBox = rb_define_class_under(cTypes, "EditBox", cNative);
+ rb_define_method(cEditBox, "text", CASTHOOK(shoes_edit_box_get_text), 0);
+ rb_define_method(cEditBox, "text=", CASTHOOK(shoes_edit_box_set_text), 1);
+ rb_define_method(cEditBox, "draw", CASTHOOK(shoes_edit_box_draw), 2);
+ rb_define_method(cEditBox, "change", CASTHOOK(shoes_control_change), -1);
+ rb_define_method(cEditBox, "append", CASTHOOK(shoes_edit_box_append), 1);
+ rb_define_method(cEditBox, "scroll_to_end", CASTHOOK(shoes_edit_box_scroll_to_end), 0);
+ rb_define_method(cEditBox, "tooltip", CASTHOOK(shoes_control_get_tooltip), 0);
+ rb_define_method(cEditBox, "tooltip=", CASTHOOK(shoes_control_set_tooltip), 1);
+
+ RUBY_M("+edit_box", edit_box, -1);
+}
+
+VALUE shoes_edit_box_get_text(VALUE self) {
+ GET_STRUCT(control, self_t);
+ if (self_t->ref == NULL) return Qnil;
+ return shoes_native_edit_box_get_text(self_t->ref);
+}
+
+VALUE shoes_edit_box_set_text(VALUE self, VALUE text) {
+ char *msg = "";
+
+ GET_STRUCT(control, self_t);
+ if (!NIL_P(text)) {
+ text = shoes_native_to_s(text);
+ ATTRSET(self_t->attr, text, text);
+ msg = RSTRING_PTR(text);
+ }
+ if (self_t->ref != NULL) shoes_native_edit_box_set_text(self_t->ref, msg);
+
+ return text;
+}
+
+VALUE shoes_edit_box_append(VALUE self, VALUE text) {
+ char *msg = "";
+
+ GET_STRUCT(control, self_t);
+ if (!NIL_P(text)) {
+ text = shoes_native_to_s(text);
+ ATTRSET(self_t->attr, text, text);
+ msg = RSTRING_PTR(text);
+ }
+ if (self_t->ref != NULL) shoes_native_edit_box_append(self_t->ref, msg);
+
+ return Qnil;
+}
+
+VALUE shoes_edit_box_scroll_to_end(VALUE self) {
+ GET_STRUCT(control, self_t);
+ if (self_t->ref != NULL) shoes_native_edit_box_scroll_to_end(self_t->ref);
+ return Qnil;
+}
+
+VALUE shoes_edit_box_draw(VALUE self, VALUE c, VALUE actual) {
+ SETUP_CONTROL(80, 0, FALSE);
+
+ if (RTEST(actual)) {
+ if (self_t->ref == NULL) {
+ self_t->ref = shoes_native_edit_box(self, canvas, &place, self_t->attr, msg);
+ shoes_control_check_styles(self_t);
+ shoes_native_control_position(self_t->ref, &self_t->place, self, canvas, &place);
+ } else
+ shoes_native_control_repaint(self_t->ref, &self_t->place, canvas, &place);
+ }
+
+ FINISH();
+
+ return self;
+}
+
+// canvas
+VALUE shoes_canvas_edit_box(int argc, VALUE *argv, VALUE self) {
+ rb_arg_list args;
+ VALUE phrase = Qnil, attr = Qnil, edit_box;
+
+ SETUP_CANVAS();
+
+ switch (rb_parse_args(argc, argv, "h,S|h,", &args)) {
+ case 1:
+ attr = args.a[0];
+ break;
+
+ case 2:
+ phrase = args.a[0];
+ attr = args.a[1];
+ break;
+ }
+
+ if (!NIL_P(phrase))
+ ATTRSET(attr, text, phrase);
+
+ if (rb_block_given_p())
+ ATTRSET(attr, change, rb_block_proc());
+
+ edit_box = shoes_control_new(cEditBox, attr, self);
+ shoes_add_ele(canvas, edit_box);
+
+ return edit_box;
+}
diff --git a/shoes/types/edit_box.h b/shoes/types/edit_box.h
new file mode 100644
index 00000000..eae1b411
--- /dev/null
+++ b/shoes/types/edit_box.h
@@ -0,0 +1,39 @@
+#include "shoes/ruby.h"
+#include "shoes/canvas.h"
+#include "shoes/app.h"
+#include "shoes/internal.h"
+#include "shoes/world.h"
+#include "shoes/native/native.h"
+
+#ifndef SHOES_EDIT_BOX_TYPE_H
+#define SHOES_EDIT_BOX_TYPE_H
+
+/* extern variables necessary to communicate with other parts of Shoes */
+extern VALUE cShoes, cApp, cTypes, cCanvas, cWidget;
+extern shoes_app _shoes_app;
+
+/* Should be automatically available but ruby.c is not sharing enough information */
+extern VALUE shoes_control_change(int argc, VALUE *argv, VALUE self);
+
+// native forward declarations
+extern SHOES_CONTROL_REF shoes_native_edit_box(VALUE, shoes_canvas *, shoes_place *, VALUE, char *);
+extern VALUE shoes_native_edit_box_get_text(SHOES_CONTROL_REF);
+extern void shoes_native_edit_box_set_text(SHOES_CONTROL_REF, char *);
+// 3.2.25 adds
+extern void shoes_native_edit_box_append(SHOES_CONTROL_REF, char *);
+extern void shoes_native_edit_box_scroll_to_end(SHOES_CONTROL_REF);
+
+/* each widget should have its own init function */
+void shoes_edit_box_init();
+
+// ruby
+VALUE shoes_edit_box_get_text(VALUE self);
+VALUE shoes_edit_box_set_text(VALUE self, VALUE text);
+VALUE shoes_edit_box_append(VALUE self, VALUE text);
+VALUE shoes_edit_box_scroll_to_end(VALUE self);
+VALUE shoes_edit_box_draw(VALUE self, VALUE c, VALUE actual);
+
+// canvas
+VALUE shoes_canvas_edit_box(int, VALUE *, VALUE);
+
+#endif
diff --git a/shoes/types/edit_line.c b/shoes/types/edit_line.c
new file mode 100644
index 00000000..b8705aef
--- /dev/null
+++ b/shoes/types/edit_line.c
@@ -0,0 +1,106 @@
+#include "shoes/types/native.h"
+#include "shoes/types/edit_line.h"
+
+// ruby
+VALUE cEditLine;
+
+FUNC_M("+edit_line", edit_line, -1);
+
+void shoes_edit_line_init() {
+ cEditLine = rb_define_class_under(cTypes, "EditLine", cNative);
+ rb_define_method(cEditLine, "text", CASTHOOK(shoes_edit_line_get_text), 0);
+ rb_define_method(cEditLine, "text=", CASTHOOK(shoes_edit_line_set_text), 1);
+ rb_define_method(cEditLine, "draw", CASTHOOK(shoes_edit_line_draw), 2);
+ rb_define_method(cEditLine, "change", CASTHOOK(shoes_control_change), -1);
+ rb_define_method(cEditLine, "finish=", CASTHOOK(shoes_edit_line_enterkey), 1);
+ rb_define_method(cEditLine, "to_end", CASTHOOK(shoes_edit_line_cursor_to_end), 0);
+ rb_define_method(cEditLine, "tooltip", CASTHOOK(shoes_control_get_tooltip), 0);
+ rb_define_method(cEditLine, "tooltip=", CASTHOOK(shoes_control_set_tooltip), 1);
+
+ RUBY_M("+edit_line", edit_line, -1);
+}
+
+VALUE shoes_edit_line_get_text(VALUE self) {
+ GET_STRUCT(control, self_t);
+ if (self_t->ref == NULL) return Qnil;
+ return shoes_native_edit_line_get_text(self_t->ref);
+}
+
+VALUE shoes_edit_line_set_text(VALUE self, VALUE text) {
+ char *msg = "";
+ GET_STRUCT(control, self_t);
+ if (!NIL_P(text)) {
+ text = shoes_native_to_s(text);
+ ATTRSET(self_t->attr, text, text);
+ msg = RSTRING_PTR(text);
+ }
+ if (self_t->ref != NULL) shoes_native_edit_line_set_text(self_t->ref, msg);
+ return text;
+}
+
+// cjc: added in Shoes 3.2.15
+VALUE shoes_edit_line_enterkey(VALUE self, VALUE proc) {
+ // store the proc in the attr
+ GET_STRUCT(control, self_t);
+ if (!NIL_P(proc)) {
+ ATTRSET(self_t->attr, donekey, proc);
+ }
+ return Qnil;
+}
+
+VALUE shoes_edit_line_cursor_to_end(VALUE self) {
+ GET_STRUCT(control, self_t);
+ shoes_native_edit_line_cursor_to_end(self_t->ref);
+ return Qnil;
+}
+
+VALUE shoes_edit_line_draw(VALUE self, VALUE c, VALUE actual) {
+ SETUP_CONTROL(0, 0, FALSE);
+
+#ifdef SHOES_QUARTZ
+ // cjc 2015-03-15 only change h, ih
+ place.h += 4;
+ place.ih += 4;
+#endif
+ if (RTEST(actual)) {
+ if (self_t->ref == NULL) {
+ self_t->ref = shoes_native_edit_line(self, canvas, &place, self_t->attr, msg);
+ shoes_control_check_styles(self_t);
+ shoes_native_control_position(self_t->ref, &self_t->place, self, canvas, &place);
+ } else
+ shoes_native_control_repaint(self_t->ref, &self_t->place, canvas, &place);
+ }
+
+ FINISH();
+
+ return self;
+}
+
+// canvas
+VALUE shoes_canvas_edit_line(int argc, VALUE *argv, VALUE self) {
+ rb_arg_list args;
+ VALUE phrase = Qnil, attr = Qnil, edit_line;
+ SETUP_CANVAS();
+
+ switch (rb_parse_args(argc, argv, "h,S|h,", &args)) {
+ case 1:
+ attr = args.a[0];
+ break;
+
+ case 2:
+ phrase = args.a[0];
+ attr = args.a[1];
+ break;
+ }
+
+ if (!NIL_P(phrase))
+ ATTRSET(attr, text, phrase);
+
+ if (rb_block_given_p())
+ ATTRSET(attr, change, rb_block_proc());
+
+ edit_line = shoes_control_new(cEditLine, attr, self);
+ shoes_add_ele(canvas, edit_line);
+
+ return edit_line;
+}
diff --git a/shoes/types/edit_line.h b/shoes/types/edit_line.h
new file mode 100644
index 00000000..ce5d3ea3
--- /dev/null
+++ b/shoes/types/edit_line.h
@@ -0,0 +1,40 @@
+#include "shoes/ruby.h"
+#include "shoes/canvas.h"
+#include "shoes/app.h"
+#include "shoes/internal.h"
+#include "shoes/world.h"
+#include "shoes/native/native.h"
+
+#ifndef SHOES_EDIT_LINE_TYPE_H
+#define SHOES_EDIT_LINE_TYPE_H
+
+/* extern variables necessary to communicate with other parts of Shoes */
+extern VALUE cShoes, cApp, cTypes, cCanvas, cWidget;
+extern shoes_app _shoes_app;
+
+/* Should be automatically available but ruby.c is not sharing enough information */
+extern VALUE shoes_control_change(int argc, VALUE *argv, VALUE self);
+
+// native forward declarations
+extern SHOES_CONTROL_REF shoes_native_edit_line(VALUE, shoes_canvas *, shoes_place *, VALUE, char *);
+extern VALUE shoes_native_edit_line_get_text(SHOES_CONTROL_REF);
+extern void shoes_native_edit_line_set_text(SHOES_CONTROL_REF, char *);
+extern VALUE shoes_native_edit_line_cursor_to_end(SHOES_CONTROL_REF);
+#ifdef GTK
+extern void shoes_native_enterkey(GtkWidget *ref, gpointer data);
+#endif
+
+/* each widget should have its own init function */
+void shoes_edit_line_init();
+
+// ruby
+VALUE shoes_edit_line_get_text(VALUE self);
+VALUE shoes_edit_line_set_text(VALUE self, VALUE text);
+VALUE shoes_edit_line_enterkey(VALUE self, VALUE proc);
+VALUE shoes_edit_line_cursor_to_end(VALUE self);
+VALUE shoes_edit_line_draw(VALUE self, VALUE c, VALUE actual);
+
+// canvas
+VALUE shoes_canvas_edit_line(int argc, VALUE *argv, VALUE self);
+
+#endif
diff --git a/shoes/types/effect.c b/shoes/types/effect.c
new file mode 100644
index 00000000..b97dc931
--- /dev/null
+++ b/shoes/types/effect.c
@@ -0,0 +1,289 @@
+#include "shoes/types/color.h"
+#include "shoes/types/image.h"
+#include "shoes/types/pattern.h"
+#include "shoes/types/shape.h"
+#include "shoes/types/effect.h"
+
+// ruby
+VALUE cEffect;
+
+void shoes_effect_init() {
+ cEffect = rb_define_class_under(cTypes, "Effect", rb_cObject);
+ rb_define_alloc_func(cEffect, shoes_effect_alloc);
+ rb_define_method(cEffect, "draw", CASTHOOK(shoes_effect_draw), 2);
+ rb_define_method(cEffect, "remove", CASTHOOK(shoes_basic_remove), 0);
+}
+
+// ruby
+VALUE shoes_effect_draw(VALUE self, VALUE c, VALUE actual) {
+ SETUP_DRAWING(shoes_effect, REL_TILE, canvas->width, canvas->height);
+
+ if (RTEST(actual) && self_t->filter != NULL)
+ self_t->filter(CCR(canvas), self_t->attr, &self_t->place);
+
+ self_t->place = place;
+ return self;
+}
+
+VALUE shoes_effect_new(ID name, VALUE attr, VALUE parent) {
+ shoes_effect *fx;
+ shoes_canvas *canvas;
+ VALUE obj = shoes_effect_alloc(cEffect);
+
+ Data_Get_Struct(obj, shoes_effect, fx);
+ Data_Get_Struct(parent, shoes_canvas, canvas);
+ fx->parent = parent;
+ fx->attr = attr;
+ fx->filter = shoes_effect_for_type(name);
+
+ return obj;
+}
+
+VALUE shoes_effect_alloc(VALUE klass) {
+ VALUE obj;
+ shoes_effect *fx = SHOE_ALLOC(shoes_effect);
+
+ SHOE_MEMZERO(fx, shoes_effect, 1);
+ obj = Data_Wrap_Struct(klass, shoes_effect_mark, shoes_effect_free, fx);
+ fx->attr = Qnil;
+ fx->parent = Qnil;
+
+ return obj;
+}
+
+void shoes_effect_mark(shoes_effect *fx) {
+ rb_gc_mark_maybe(fx->parent);
+ rb_gc_mark_maybe(fx->attr);
+}
+
+void shoes_effect_free(shoes_effect *fx) {
+ RUBY_CRITICAL(free(fx));
+}
+
+shoes_effect_filter shoes_effect_for_type(ID name) {
+ if (name == s_blur)
+ return &shoes_gaussian_blur_filter;
+ else if (name == s_shadow)
+ return &shoes_shadow_filter;
+ else if (name == s_glow)
+ return &shoes_glow_filter;
+ return NULL;
+}
+
+// Canvas
+VALUE shoes_add_effect(VALUE self, ID name, VALUE attr) {
+ if (rb_obj_is_kind_of(self, cImage)) {
+ shoes_effect_filter filter = shoes_effect_for_type(name);
+ SETUP_IMAGE();
+ if (filter == NULL) return self;
+ filter(image->cr, attr, &place);
+ return self;
+ }
+
+ SETUP_CANVAS();
+
+ return shoes_add_ele(canvas, shoes_effect_new(name, attr, self));
+}
+
+VALUE shoes_canvas_blur(int argc, VALUE *argv, VALUE self) {
+ VALUE attr = shoes_shape_attr(argc, argv, 1, s_radius);
+ return shoes_add_effect(self, s_blur, attr);
+}
+
+VALUE shoes_canvas_glow(int argc, VALUE *argv, VALUE self) {
+ VALUE attr = shoes_shape_attr(argc, argv, 1, s_radius);
+ return shoes_add_effect(self, s_glow, attr);
+}
+
+VALUE shoes_canvas_shadow(int argc, VALUE *argv, VALUE self) {
+ VALUE attr = shoes_shape_attr(argc, argv, 2, s_distance, s_radius);
+ return shoes_add_effect(self, s_shadow, attr);
+}
+
+// shoes/effect.c
+
+static unsigned char *box_run(unsigned int size) {
+ int i;
+ unsigned char *tmp = SHOE_ALLOC_N(unsigned char, size * 256);
+ for (i = 0; i < 256; i++)
+ memset(tmp + i * size, i, size);
+ return tmp;
+}
+
+#define BOX_H 1
+#define BOX_V 2
+
+static void box_blur(unsigned char *in, unsigned char *out,
+ int stride, shoes_place *place,
+ unsigned int edge1, unsigned int edge2,
+ const unsigned char *run, int dir) {
+ int i, j1, j2, l = 0, l2, l3, l4, lx = 0, c1, c2, c3, c4, start;
+ int boxSize = edge1 + edge2 + 1;
+ if (dir == BOX_H) {
+ c1 = place->y;
+ c2 = place->y + place->h;
+ c3 = place->x;
+ c4 = place->x + place->w;
+ } else {
+ c1 = place->x;
+ c2 = place->x + place->w;
+ c3 = place->y;
+ c4 = place->y + place->h;
+ }
+
+ start = c3 - edge1;
+ for (j1 = c1; j1 < c2; j1++) {
+ unsigned int sums[4] = {0, 0, 0, 0};
+ if (dir == BOX_H)
+ l = stride * j1;
+ else
+ lx = j1 << 2;
+ for (i = 0; i < boxSize; i++) {
+ int pos = start + i;
+ pos = max(pos, c3);
+ pos = min(pos, c4 - 1);
+ if (dir == BOX_V)
+ l = stride * pos + lx;
+ sums[0] += in[l];
+ sums[1] += in[l + 1];
+ sums[2] += in[l + 2];
+ sums[3] += in[l + 3];
+ }
+ for (j2 = c3; j2 < c4; j2++) {
+ if (dir == BOX_H)
+ l2 = l + (j2 << 2);
+ else
+ l2 = stride * j2 + lx;
+ out[l2] = run[(int)sums[0]];
+ out[l2 + 1] = run[(int)sums[1]];
+ out[l2 + 2] = run[(int)sums[2]];
+ out[l2 + 3] = run[(int)sums[3]];
+
+ int tmp = j2 - edge1;
+ int last = max(tmp, c3);
+ int next = min(tmp + boxSize, c4 - 1);
+ if (dir == BOX_H) {
+ l3 = l + (next << 2);
+ l4 = l + (last << 2);
+ } else {
+ l3 = stride * next + lx;
+ l4 = stride * last + lx;
+ }
+
+ sums[0] += in[l3] - in[l4];
+ sums[1] += in[l3 + 1] - in[l4 + 1];
+ sums[2] += in[l3 + 2] - in[l4 + 2];
+ sums[3] += in[l3 + 3] - in[l4 + 3];
+ }
+ }
+}
+
+void shoes_gaussian_blur_filter(cairo_t *cr, VALUE attr, shoes_place *place) {
+ double blur_d = ATTR2(dbl, attr, radius, 2.);
+ double blur_x = blur_d, blur_y = blur_d;
+
+ RAW_FILTER_START(place);
+ if (blur_x < 0 || blur_y < 0)
+ return;
+ if (blur_x == 0 || blur_y == 0)
+ memset(out, 0, len);
+ unsigned int dX, dY;
+ dX = (unsigned int) floor(blur_x * 3*sqrt(2*SHOES_PI)/4 + 0.5);
+ dY = (unsigned int) floor((blur_y * 3*sqrt(2*SHOES_PI)/4) + 0.5);
+
+ unsigned char *tmp = SHOE_ALLOC_N(unsigned char, len);
+
+ if (dX & 1) { // odd dX
+ unsigned char *run = box_run(2 * (dX / 2) + 1);
+ box_blur(in, tmp, stride, place, dX/2, dX/2, run, BOX_H);
+ box_blur(tmp, out, stride, place, dX/2, dX/2, run, BOX_H);
+ box_blur(out, tmp, stride, place, dX/2, dX/2, run, BOX_H);
+ SHOE_FREE(run);
+ } else { // even dX
+ if (dX == 0) {
+ memcpy(tmp, in, len);
+ } else {
+ unsigned char *run1 = box_run(2 * (dX / 2) + 1);
+ unsigned char *run2 = box_run(2 * (dX / 2));
+ box_blur(in, tmp, stride, place, dX/2, dX/2 - 1, run2, BOX_H);
+ box_blur(tmp, out, stride, place, dX/2 - 1, dX/2, run2, BOX_H);
+ box_blur(out, tmp, stride, place, dX/2, dX/2, run1, BOX_H);
+ SHOE_FREE(run1);
+ SHOE_FREE(run2);
+ }
+ }
+ if (dY & 1) {
+ unsigned char *run = box_run(2 * (dY / 2) + 1);
+ box_blur(tmp, out, stride, place, dY/2, dY/2, run, BOX_V);
+ box_blur(out, tmp, stride, place, dY/2, dY/2, run, BOX_V);
+ box_blur(tmp, out, stride, place, dY/2, dY/2, run, BOX_V);
+ SHOE_FREE(run);
+ } else {
+ if (dY == 0) {
+ memcpy(out, tmp, len);
+ } else {
+ unsigned char *run1 = box_run(2 * (dY / 2) + 1);
+ unsigned char *run2 = box_run(2 * (dY / 2));
+ box_blur(tmp, out, stride, place, dY/2, dY/2 - 1, run2, BOX_V);
+ box_blur(out, tmp, stride, place, dY/2 - 1, dY/2, run2, BOX_V);
+ box_blur(tmp, out, stride, place, dY/2, dY/2, run1, BOX_V);
+ SHOE_FREE(run1);
+ SHOE_FREE(run2);
+ }
+ }
+
+ SHOE_FREE(tmp);
+ RAW_FILTER_END();
+}
+
+static void shoes_layer_blur_filter(cairo_t *cr, VALUE attr, shoes_place *place,
+ cairo_operator_t blur_op, cairo_operator_t merge_op, int distance) {
+ cairo_surface_t *source = cairo_get_target(cr);
+ int width = cairo_image_surface_get_width(source);
+ int height = cairo_image_surface_get_height(source);
+ VALUE fill = ATTR(attr, fill);
+ int dx = ATTR2(int, attr, displace_left, 0);
+ int dy = ATTR2(int, attr, displace_top, 0);
+
+ cairo_surface_t *target = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
+ cairo_t *cr2 = cairo_create(target);
+ if (dx != 0 || dy != 0)
+ cairo_set_source_surface(cr2, source, dx, dy);
+ else
+ cairo_set_source_surface(cr2, source, distance, distance);
+ cairo_paint(cr2);
+ cairo_set_operator(cr2, blur_op);
+ if (NIL_P(fill))
+ cairo_set_source_rgb(cr2, 0., 0., 0.);
+ else if (rb_obj_is_kind_of(fill, cColor)) {
+ shoes_color *color;
+ Data_Get_Struct(fill, shoes_color, color);
+ cairo_set_source_rgba(cr2, color->r / 255., color->g / 255., color->b / 255., color->a / 255.);
+ } else {
+ shoes_pattern *pattern;
+ Data_Get_Struct(fill, shoes_pattern, pattern);
+ cairo_set_source(cr2, PATTERN(pattern));
+ }
+ cairo_rectangle(cr2, 0, 0, width, height);
+ cairo_paint(cr2);
+ shoes_gaussian_blur_filter(cr2, attr, place);
+ cairo_set_operator(cr, merge_op);
+ cairo_set_source_surface(cr, target, 0, 0);
+ cairo_paint(cr);
+ cairo_destroy(cr2);
+}
+
+void shoes_shadow_filter(cairo_t *cr, VALUE attr, shoes_place *place) {
+ int distance = ATTR2(int, attr, distance, 4);
+ shoes_layer_blur_filter(cr, attr, place, CAIRO_OPERATOR_IN, CAIRO_OPERATOR_DEST_OVER, distance);
+}
+
+void shoes_glow_filter(cairo_t *cr, VALUE attr, shoes_place *place) {
+ cairo_operator_t blur_op = CAIRO_OPERATOR_IN;
+ cairo_operator_t merge_op = CAIRO_OPERATOR_DEST_OVER;
+ if (RTEST(ATTR(attr, inner))) {
+ blur_op = CAIRO_OPERATOR_OUT;
+ merge_op = CAIRO_OPERATOR_ATOP;
+ }
+ shoes_layer_blur_filter(cr, attr, place, blur_op, merge_op, 0);
+}
diff --git a/shoes/types/effect.h b/shoes/types/effect.h
new file mode 100644
index 00000000..3e616806
--- /dev/null
+++ b/shoes/types/effect.h
@@ -0,0 +1,98 @@
+#include "shoes/ruby.h"
+#include "shoes/canvas.h"
+#include "shoes/app.h"
+#include "shoes/internal.h"
+#include "shoes/world.h"
+#include "shoes/native/native.h"
+#include
+
+#ifndef SHOES_EFFECT_TYPE_H
+#define SHOES_EFFECT_TYPE_H
+
+/* extern variables necessary to communicate with other parts of Shoes */
+extern VALUE cShoes, cApp, cTypes, cCanvas, cWidget;
+extern shoes_app _shoes_app;
+
+typedef void (*shoes_effect_filter)(cairo_t *, VALUE attr, shoes_place *);
+
+typedef struct {
+ VALUE parent;
+ VALUE attr;
+ shoes_place place;
+ shoes_effect_filter filter;
+} shoes_effect;
+
+// TODO: this needs refactoring, perhaps should go to native directory?
+#ifdef GTK3
+#define RAW_FILTER_START(place) \
+ int width, height, stride; \
+ guchar *out; \
+ static const cairo_user_data_key_t key; \
+ cairo_surface_t *source = cairo_get_target(cr); \
+ cairo_surface_t *target; \
+ unsigned char *in = cairo_image_surface_get_data(source); \
+ \
+ place->x = place->y = 0; \
+ place->w = width = cairo_image_surface_get_width(source); \
+ place->h = height = cairo_image_surface_get_height(source); \
+ stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width); \
+ \
+ out = (guchar *)g_malloc(4 * width * height); \
+ target = cairo_image_surface_create_for_data((unsigned char *)out, \
+ CAIRO_FORMAT_ARGB32, \
+ width, height, stride); \
+ cairo_surface_set_user_data(target, &key, out, (cairo_destroy_func_t)g_free); \
+ unsigned int len = 4 * width * height
+#else
+#define RAW_FILTER_START(place) \
+ int width, height, stride; \
+ guchar *out; \
+ static const cairo_user_data_key_t key; \
+ cairo_surface_t *source = cairo_get_target(cr); \
+ cairo_surface_t *target; \
+ unsigned char *in = cairo_image_surface_get_data(source); \
+ \
+ place->x = place->y = 0; \
+ place->w = width = cairo_image_surface_get_width(source); \
+ place->h = height = cairo_image_surface_get_height(source); \
+ stride = cairo_image_surface_get_stride(source); \
+ \
+ out = (guchar *)g_malloc(4 * width * height); \
+ target = cairo_image_surface_create_for_data((unsigned char *)out, \
+ CAIRO_FORMAT_ARGB32, \
+ width, height, 4 * width); \
+ cairo_surface_set_user_data(target, &key, out, (cairo_destroy_func_t)g_free); \
+ unsigned int len = 4 * width * height
+#endif
+
+#define RAW_FILTER_END() \
+ cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR); \
+ cairo_paint(cr); \
+ cairo_set_operator(cr, CAIRO_OPERATOR_OVER); \
+ cairo_set_source_surface(cr, target, 0, 0); \
+ cairo_paint(cr); \
+ cairo_surface_destroy(target);
+
+/* each widget should have its own init function */
+void shoes_effect_init();
+
+// ruby
+VALUE shoes_effect_new(ID name, VALUE attr, VALUE parent);
+VALUE shoes_effect_alloc(VALUE klass);
+VALUE shoes_effect_draw(VALUE self, VALUE c, VALUE actual);
+
+void shoes_effect_mark(shoes_effect *fx);
+void shoes_effect_free(shoes_effect *fx);
+shoes_effect_filter shoes_effect_for_type(ID name);
+
+void shoes_gaussian_blur_filter(cairo_t *, VALUE, shoes_place *);
+void shoes_shadow_filter(cairo_t *, VALUE, shoes_place *);
+void shoes_glow_filter(cairo_t *, VALUE, shoes_place *);
+
+// canvas
+VALUE shoes_add_effect(VALUE self, ID name, VALUE attr);
+VALUE shoes_canvas_blur(int argc, VALUE *argv, VALUE self);
+VALUE shoes_canvas_glow(int argc, VALUE *argv, VALUE self);
+VALUE shoes_canvas_shadow(int argc, VALUE *argv, VALUE self);
+
+#endif
diff --git a/shoes/types/image.c b/shoes/types/image.c
new file mode 100644
index 00000000..868d4964
--- /dev/null
+++ b/shoes/types/image.c
@@ -0,0 +1,464 @@
+#include "shoes/types/native.h"
+#include "shoes/types/color.h"
+#include "shoes/types/pattern.h"
+#include "shoes/types/shape.h"
+#include "shoes/types/image.h"
+
+// ruby
+VALUE cImage;
+
+FUNC_M("+image", image, -1);
+FUNC_M(".imagesize", imagesize, 1);
+
+FUNC_M(".nostroke", nostroke, 0);
+FUNC_M(".stroke", stroke, -1);
+FUNC_M(".strokewidth", strokewidth, 1);
+FUNC_M(".dash", dash, 1);
+FUNC_M(".cap", cap, 1);
+FUNC_M(".nofill", nofill, 0);
+FUNC_M(".fill", fill, -1);
+FUNC_M("+arc", arc, -1);
+FUNC_M("+rect", rect, -1);
+FUNC_M("+oval", oval, -1);
+FUNC_M("+line", line, -1);
+FUNC_M("+arrow", arrow, -1);
+FUNC_M("+star", star, -1);
+FUNC_M(".blur", blur, -1);
+FUNC_M(".glow", glow, -1);
+FUNC_M(".shadow", shadow, -1);
+FUNC_M(".move_to", move_to, 2);
+FUNC_M(".line_to", line_to, 2);
+FUNC_M(".curve_to", curve_to, 6);
+FUNC_M(".arc_to", arc_to, 6);
+FUNC_M(".transform", transform, 1);
+FUNC_M(".translate", translate, 2);
+FUNC_M(".rotate", rotate, 1);
+FUNC_M(".scale", scale, -1);
+FUNC_M(".skew", skew, -1);
+
+PLACE_COMMON(image);
+CLASS_COMMON2(image);
+TRANS_COMMON(image, 1);
+
+void shoes_image_init() {
+ cImage = rb_define_class_under(cTypes, "Image", rb_cObject);
+
+ rb_define_alloc_func(cImage, shoes_image_alloc);
+
+ rb_define_method(cImage, "[]", CASTHOOK(shoes_image_get_pixel), 2);
+ rb_define_method(cImage, "[]=", CASTHOOK(shoes_image_set_pixel), 3);
+ rb_define_method(cImage, "nostroke", CASTHOOK(shoes_canvas_nostroke), 0);
+ rb_define_method(cImage, "stroke", CASTHOOK(shoes_canvas_stroke), -1);
+ rb_define_method(cImage, "strokewidth", CASTHOOK(shoes_canvas_strokewidth), 1);
+ rb_define_method(cImage, "dash", CASTHOOK(shoes_canvas_dash), 1);
+ rb_define_method(cImage, "cap", CASTHOOK(shoes_canvas_cap), 1);
+ rb_define_method(cImage, "nofill", CASTHOOK(shoes_canvas_nofill), 0);
+ rb_define_method(cImage, "fill", CASTHOOK(shoes_canvas_fill), -1);
+ rb_define_method(cImage, "arrow", CASTHOOK(shoes_canvas_arrow), -1);
+ rb_define_method(cImage, "line", CASTHOOK(shoes_canvas_line), -1);
+ rb_define_method(cImage, "arc", CASTHOOK(shoes_canvas_arc), -1);
+ rb_define_method(cImage, "oval", CASTHOOK(shoes_canvas_oval), -1);
+ rb_define_method(cImage, "rect", CASTHOOK(shoes_canvas_rect), -1);
+ rb_define_method(cImage, "shape", CASTHOOK(shoes_canvas_shape), -1);
+ rb_define_method(cImage, "star", CASTHOOK(shoes_canvas_star), -1);
+ rb_define_method(cImage, "move_to", CASTHOOK(shoes_canvas_move_to), 2);
+ rb_define_method(cImage, "line_to", CASTHOOK(shoes_canvas_line_to), 2);
+ rb_define_method(cImage, "curve_to", CASTHOOK(shoes_canvas_curve_to), 6);
+ rb_define_method(cImage, "arc_to", CASTHOOK(shoes_canvas_arc_to), 6);
+ rb_define_method(cImage, "blur", CASTHOOK(shoes_canvas_blur), -1);
+ rb_define_method(cImage, "glow", CASTHOOK(shoes_canvas_glow), -1);
+ rb_define_method(cImage, "shadow", CASTHOOK(shoes_canvas_shadow), -1);
+ rb_define_method(cImage, "image", CASTHOOK(shoes_canvas_image), -1);
+ rb_define_method(cImage, "path", CASTHOOK(shoes_image_get_path), 0);
+ rb_define_method(cImage, "path=", CASTHOOK(shoes_image_set_path), 1);
+ rb_define_method(cImage, "app", CASTHOOK(shoes_canvas_get_app), 0);
+ rb_define_method(cImage, "displace", CASTHOOK(shoes_image_displace), 2);
+ rb_define_method(cImage, "draw", CASTHOOK(shoes_image_draw), 2);
+ rb_define_method(cImage, "size", CASTHOOK(shoes_image_size), 0);
+ rb_define_method(cImage, "move", CASTHOOK(shoes_image_move), 2);
+ rb_define_method(cImage, "parent", CASTHOOK(shoes_image_get_parent), 0);
+ rb_define_method(cImage, "rotate", CASTHOOK(shoes_image_rotate), 1);
+ rb_define_method(cImage, "scale", CASTHOOK(shoes_image_scale), -1);
+ rb_define_method(cImage, "skew", CASTHOOK(shoes_image_skew), -1);
+ rb_define_method(cImage, "transform", CASTHOOK(shoes_image_transform), 1);
+ rb_define_method(cImage, "translate", CASTHOOK(shoes_image_translate), 2);
+ rb_define_method(cImage, "top", CASTHOOK(shoes_image_get_top), 0);
+ rb_define_method(cImage, "left", CASTHOOK(shoes_image_get_left), 0);
+ rb_define_method(cImage, "width", CASTHOOK(shoes_image_get_width), 0);
+ rb_define_method(cImage, "height", CASTHOOK(shoes_image_get_height), 0);
+ rb_define_method(cImage, "full_width", CASTHOOK(shoes_image_get_full_width), 0);
+ rb_define_method(cImage, "full_height", CASTHOOK(shoes_image_get_full_height), 0);
+ rb_define_method(cImage, "remove", CASTHOOK(shoes_basic_remove), 0);
+ rb_define_method(cImage, "style", CASTHOOK(shoes_image_style), -1);
+ rb_define_method(cImage, "hide", CASTHOOK(shoes_image_hide), 0);
+ rb_define_method(cImage, "show", CASTHOOK(shoes_image_show), 0);
+ rb_define_method(cImage, "toggle", CASTHOOK(shoes_image_toggle), 0);
+ rb_define_method(cImage, "click", CASTHOOK(shoes_image_click), -1);
+ rb_define_method(cImage, "release", CASTHOOK(shoes_image_release), -1);
+ rb_define_method(cImage, "hover", CASTHOOK(shoes_image_hover), -1);
+ rb_define_method(cImage, "leave", CASTHOOK(shoes_image_leave), -1);
+
+ RUBY_M("+image", image, -1);
+ RUBY_M(".imagesize", imagesize, 1);
+
+ RUBY_M(".nostroke", nostroke, 0);
+ RUBY_M(".stroke", stroke, -1);
+ RUBY_M(".strokewidth", strokewidth, 1);
+ RUBY_M(".dash", dash, 1);
+ RUBY_M(".cap", cap, 1);
+ RUBY_M(".nofill", nofill, 0);
+ RUBY_M(".fill", fill, -1);
+ RUBY_M("+arc", arc, -1);
+ RUBY_M("+rect", rect, -1);
+ RUBY_M("+oval", oval, -1);
+ RUBY_M("+line", line, -1);
+ RUBY_M("+arrow", arrow, -1);
+ RUBY_M("+star", star, -1);
+ RUBY_M(".blur", blur, -1);
+ RUBY_M(".glow", glow, -1);
+ RUBY_M(".shadow", shadow, -1);
+ RUBY_M(".move_to", move_to, 2);
+ RUBY_M(".line_to", line_to, 2);
+ RUBY_M(".curve_to", curve_to, 6);
+ RUBY_M(".arc_to", arc_to, 6);
+ RUBY_M(".transform", transform, 1);
+ RUBY_M(".translate", translate, 2);
+ RUBY_M(".rotate", rotate, 1);
+ RUBY_M(".scale", scale, -1);
+ RUBY_M(".skew", skew, -1);
+}
+
+// ruby
+void shoes_image_mark(shoes_image *image) {
+ rb_gc_mark_maybe(image->path);
+ rb_gc_mark_maybe(image->parent);
+ rb_gc_mark_maybe(image->attr);
+}
+
+void shoes_image_free(shoes_image *image) {
+ if (image->type == SHOES_CACHE_MEM) {
+ if (image->cr != NULL) cairo_destroy(image->cr);
+ if (image->cached != NULL) cairo_surface_destroy(image->cached->surface);
+ SHOE_FREE(image->cached);
+ }
+ shoes_transform_release(image->st);
+ RUBY_CRITICAL(SHOE_FREE(image));
+}
+
+VALUE shoes_image_new(VALUE klass, VALUE path, VALUE attr, VALUE parent, shoes_transform *st) {
+ VALUE obj = Qnil;
+ shoes_image *image;
+ shoes_basic *basic;
+ Data_Get_Struct(parent, shoes_basic, basic);
+
+ obj = shoes_image_alloc(klass);
+ Data_Get_Struct(obj, shoes_image, image);
+
+ image->path = Qnil;
+ image->st = shoes_transform_touch(st);
+ image->attr = attr;
+ image->parent = shoes_find_canvas(parent);
+ COPY_PENS(image->attr, basic->attr);
+
+ if (rb_obj_is_kind_of(path, cImage)) {
+ shoes_image *image2;
+ Data_Get_Struct(path, shoes_image, image2);
+ image->cached = image2->cached;
+ image->type = SHOES_CACHE_ALIAS;
+ } else if (!NIL_P(path)) {
+ path = shoes_native_to_s(path);
+ image->path = path;
+ image->cached = shoes_load_image(image->parent, path);
+ image->type = SHOES_CACHE_FILE;
+ } else {
+ shoes_canvas *canvas;
+ Data_Get_Struct(image->parent, shoes_canvas, canvas);
+ int w = ATTR2(int, attr, width, canvas->width);
+ int h = ATTR2(int, attr, height, canvas->height);
+ VALUE block = ATTR(attr, draw);
+ image->cached = shoes_cached_image_new(w, h, NULL);
+ image->cr = cairo_create(image->cached->surface);
+ image->type = SHOES_CACHE_MEM;
+ if (!NIL_P(block)) DRAW(obj, canvas->app, rb_funcall(block, s_call, 0));
+ }
+
+ return obj;
+}
+
+VALUE shoes_image_alloc(VALUE klass) {
+ VALUE obj;
+ shoes_image *image = SHOE_ALLOC(shoes_image);
+ SHOE_MEMZERO(image, shoes_image, 1);
+ obj = Data_Wrap_Struct(klass, shoes_image_mark, shoes_image_free, image);
+ image->path = Qnil;
+ image->st = NULL;
+ image->attr = Qnil;
+ image->parent = Qnil;
+ image->type = SHOES_CACHE_MEM;
+ return obj;
+}
+
+VALUE shoes_image_get_full_width(VALUE self) {
+ GET_STRUCT(image, image);
+ return INT2NUM(image->cached->width);
+}
+
+VALUE shoes_image_get_full_height(VALUE self) {
+ GET_STRUCT(image, image);
+ return INT2NUM(image->cached->height);
+}
+
+void shoes_image_ensure_dup(shoes_image *image) {
+ if (image->type == SHOES_CACHE_MEM)
+ return;
+ shoes_cached_image *cached = shoes_cached_image_new(image->cached->width, image->cached->height, NULL);
+ image->cr = cairo_create(cached->surface);
+ cairo_set_source_surface(image->cr, image->cached->surface, 0, 0);
+ cairo_paint(image->cr);
+
+ image->cached = cached;
+ image->type = SHOES_CACHE_MEM;
+}
+
+unsigned char *shoes_image_surface_get_pixel(shoes_cached_image *cached, int x, int y) {
+ if (x >= 0 && y >= 0 && x < cached->width && y < cached->height) {
+ unsigned char* pixels = cairo_image_surface_get_data(cached->surface);
+ if (cairo_image_surface_get_format(cached->surface) == CAIRO_FORMAT_ARGB32)
+ return pixels + (y * (4 * cached->width)) + (4 * x);
+ }
+ return NULL;
+}
+
+VALUE shoes_image_get_pixel(VALUE self, VALUE _x, VALUE _y) {
+ VALUE color = Qnil;
+ int x = NUM2INT(_x), y = NUM2INT(_y);
+ GET_STRUCT(image, image);
+ unsigned char *pixels = shoes_image_surface_get_pixel(image->cached, x, y);
+ if (pixels != NULL)
+ color = shoes_color_new(pixels[2], pixels[1], pixels[0], pixels[3]);
+ return color;
+}
+
+VALUE shoes_image_set_pixel(VALUE self, VALUE _x, VALUE _y, VALUE col) {
+ int x = NUM2INT(_x), y = NUM2INT(_y);
+ GET_STRUCT(image, image);
+ shoes_image_ensure_dup(image);
+ unsigned char *pixels = shoes_image_surface_get_pixel(image->cached, x, y);
+ if (pixels != NULL) {
+ if (TYPE(col) == T_STRING)
+ col = shoes_color_parse(cColor, col);
+ if (rb_obj_is_kind_of(col, cColor)) {
+ shoes_color *color;
+ Data_Get_Struct(col, shoes_color, color);
+ pixels[0] = color->b;
+ pixels[1] = color->g;
+ pixels[2] = color->r;
+ pixels[3] = color->a;
+ }
+ }
+ return self;
+}
+
+VALUE shoes_image_get_path(VALUE self) {
+ GET_STRUCT(image, image);
+ return image->path;
+}
+
+VALUE shoes_image_set_path(VALUE self, VALUE path) {
+ GET_STRUCT(image, image);
+ image->path = path;
+ image->cached = shoes_load_image(image->parent, path);
+ image->type = SHOES_CACHE_FILE;
+ shoes_canvas_repaint_all(image->parent);
+ return path;
+}
+
+static void shoes_image_draw_surface(cairo_t *cr, shoes_image *self_t, shoes_place *place, cairo_surface_t *surf, int imw, int imh) {
+ shoes_apply_transformation(cr, self_t->st, place, 0);
+ cairo_translate(cr, place->ix + place->dx, place->iy + place->dy);
+ if (place->iw != imw || place->ih != imh)
+ cairo_scale(cr, (place->iw * 1.) / imw, (place->ih * 1.) / imh);
+ cairo_set_source_surface(cr, surf, 0., 0.);
+ cairo_paint(cr);
+ shoes_undo_transformation(cr, self_t->st, place, 0);
+ self_t->place = *place;
+}
+
+#define SHOES_IMAGE_PLACE(type, imw, imh, surf) \
+ SETUP_DRAWING(shoes_##type, (REL_CANVAS | REL_SCALE), imw, imh); \
+ VALUE ck = rb_obj_class(c); \
+ if (RTEST(actual)) \
+ shoes_image_draw_surface(CCR(canvas), self_t, &place, surf, imw, imh); \
+ FINISH(); \
+ return self;
+
+VALUE shoes_image_draw(VALUE self, VALUE c, VALUE actual) {
+ SHOES_IMAGE_PLACE(image, self_t->cached->width, self_t->cached->height, self_t->cached->surface);
+}
+
+void shoes_image_image(VALUE parent, VALUE path, VALUE attr) {
+ shoes_image *pi;
+ shoes_place place;
+ Data_Get_Struct(parent, shoes_image, pi);
+ VALUE self = shoes_image_new(cImage, path, attr, parent, pi->st);
+ GET_STRUCT(image, image);
+ shoes_image_ensure_dup(pi);
+ shoes_place_exact(&place, image->attr, 0, 0);
+ if (place.iw < 1) place.w = place.iw = image->cached->width;
+ if (place.ih < 1) place.h = place.ih = image->cached->height;
+ shoes_image_draw_surface(pi->cr, image, &place, image->cached->surface, image->cached->width, image->cached->height);
+}
+
+VALUE shoes_image_size(VALUE self) {
+ GET_STRUCT(image, self_t);
+ return rb_ary_new3(2, INT2NUM(self_t->cached->width), INT2NUM(self_t->cached->height));
+}
+
+VALUE shoes_image_motion(VALUE self, int x, int y, char *touch) {
+ char h = 0;
+ VALUE click;
+ GET_STRUCT(image, self_t);
+
+ click = ATTR(self_t->attr, click);
+ if (self_t->cached == NULL) return Qnil;
+
+ if (IS_INSIDE(self_t, x, y)) {
+ if (!NIL_P(click)) {
+ shoes_canvas *canvas;
+ Data_Get_Struct(self_t->parent, shoes_canvas, canvas);
+ shoes_app_cursor(canvas->app, s_link);
+ }
+ h = 1;
+ }
+
+ CHECK_HOVER(self_t, h, touch);
+
+ return h ? click : Qnil;
+}
+
+VALUE shoes_image_send_click(VALUE self, int button, int x, int y) {
+ VALUE v = Qnil;
+
+ if (button > 0) {
+ GET_STRUCT(image, self_t);
+ v = shoes_image_motion(self, x, y, NULL);
+ if (self_t->hover & HOVER_MOTION)
+ self_t->hover = HOVER_MOTION | HOVER_CLICK;
+ }
+
+ return v;
+}
+
+void shoes_image_send_release(VALUE self, int button, int x, int y) {
+ GET_STRUCT(image, self_t);
+ if (button > 0 && (self_t->hover & HOVER_CLICK)) {
+ VALUE proc = ATTR(self_t->attr, release);
+ self_t->hover ^= HOVER_CLICK;
+ if (!NIL_P(proc))
+ shoes_safe_block(self, proc, rb_ary_new3(3, INT2NUM(button), INT2NUM(x), INT2NUM(y)));
+ }
+}
+
+// canvas
+VALUE shoes_canvas_image(int argc, VALUE *argv, VALUE self) {
+ rb_arg_list args;
+ VALUE path = Qnil, attr = Qnil, _w, _h, image;
+
+ switch (rb_parse_args(argc, argv, "ii|h,s|h,|h", &args)) {
+ case 1:
+ _w = args.a[0];
+ _h = args.a[1];
+ attr = args.a[2];
+ ATTRSET(attr, width, _w);
+ ATTRSET(attr, height, _h);
+ if (rb_block_given_p()) ATTRSET(attr, draw, rb_block_proc());
+ break;
+
+ case 2:
+ path = args.a[0];
+ attr = args.a[1];
+ if (rb_block_given_p()) ATTRSET(attr, click, rb_block_proc());
+ break;
+
+ case 3:
+ attr = args.a[0];
+ if (rb_block_given_p()) ATTRSET(attr, draw, rb_block_proc());
+ break;
+ }
+
+ if (rb_obj_is_kind_of(self, cImage)) {
+ shoes_image_image(self, path, attr);
+ return self;
+ }
+
+ SETUP_CANVAS();
+ image = shoes_image_new(cImage, path, attr, self, canvas->st);
+ shoes_add_ele(canvas, image);
+
+ return image;
+}
+
+VALUE shoes_canvas_nostroke(VALUE self) {
+ SETUP_BASIC();
+ ATTRSET(basic->attr, stroke, Qnil);
+ return self;
+}
+
+VALUE shoes_canvas_stroke(int argc, VALUE *argv, VALUE self) {
+ VALUE pat;
+ SETUP_BASIC();
+
+ if (argc == 1 && rb_obj_is_kind_of(argv[0], cPattern))
+ pat = argv[0];
+ else
+ pat = shoes_pattern_args(argc, argv, self);
+
+ ATTRSET(basic->attr, stroke, pat);
+
+ return pat;
+}
+
+VALUE shoes_canvas_strokewidth(VALUE self, VALUE w) {
+ SETUP_BASIC();
+ ATTRSET(basic->attr, strokewidth, w);
+ return self;
+}
+
+VALUE shoes_canvas_dash(VALUE self, VALUE dash) {
+ SETUP_BASIC();
+ ATTRSET(basic->attr, dash, dash);
+ return self;
+}
+
+VALUE shoes_canvas_cap(VALUE self, VALUE cap) {
+ SETUP_BASIC();
+ ATTRSET(basic->attr, cap, cap);
+ return self;
+}
+
+VALUE shoes_canvas_nofill(VALUE self) {
+ SETUP_BASIC();
+ ATTRSET(basic->attr, fill, Qnil);
+ return self;
+}
+
+VALUE shoes_canvas_fill(int argc, VALUE *argv, VALUE self) {
+ VALUE pat;
+ SETUP_BASIC();
+
+ if (argc == 1 && rb_obj_is_kind_of(argv[0], cPattern))
+ pat = argv[0];
+ else
+ pat = shoes_pattern_args(argc, argv, self);
+
+ ATTRSET(basic->attr, fill, pat);
+
+ return pat;
+}
+
+VALUE shoes_canvas_imagesize(VALUE self, VALUE _path) {
+ int w, h;
+ if (shoes_load_imagesize(_path, &w, &h) == SHOES_OK)
+ return rb_ary_new3(2, INT2NUM(w), INT2NUM(h));
+ return Qnil;
+}
diff --git a/shoes/types/image.h b/shoes/types/image.h
new file mode 100644
index 00000000..bb1b3d3c
--- /dev/null
+++ b/shoes/types/image.h
@@ -0,0 +1,88 @@
+#include "shoes/ruby.h"
+#include "shoes/canvas.h"
+#include "shoes/app.h"
+#include "shoes/internal.h"
+#include "shoes/world.h"
+#include "shoes/native/native.h"
+
+#ifndef SHOES_IMAGE_TYPE_H
+#define SHOES_IMAGE_TYPE_H
+
+/* extern variables necessary to communicate with other parts of Shoes */
+extern VALUE cShoes, cApp, cTypes, cCanvas, cWidget;
+extern shoes_app _shoes_app;
+
+// native forward declarations
+// extern SHOES_CONTROL_REF shoes_native_spinner(VALUE self, shoes_canvas *canvas, shoes_place *place, VALUE attr, char *msg);
+// extern void shoes_native_spinner_start(SHOES_CONTROL_REF ref);
+// extern void shoes_native_spinner_stop(SHOES_CONTROL_REF ref);
+// extern gboolean shoes_native_spinner_started(SHOES_CONTROL_REF ref);
+
+VALUE cImage;
+
+/* each widget should have its own init function */
+void shoes_image_init();
+
+// ruby
+void shoes_image_mark(shoes_image *image);
+void shoes_image_free(shoes_image *image);
+VALUE shoes_image_new(VALUE klass, VALUE path, VALUE attr, VALUE parent, shoes_transform *st);
+VALUE shoes_image_alloc(VALUE klass);
+VALUE shoes_image_get_full_width(VALUE self);
+VALUE shoes_image_get_full_height(VALUE self);
+void shoes_image_ensure_dup(shoes_image *image);
+unsigned char *shoes_image_surface_get_pixel(shoes_cached_image *cached, int x, int y);
+VALUE shoes_image_get_pixel(VALUE self, VALUE _x, VALUE _y);
+VALUE shoes_image_set_pixel(VALUE self, VALUE _x, VALUE _y, VALUE col);
+VALUE shoes_image_get_path(VALUE self);
+VALUE shoes_image_set_path(VALUE self, VALUE path);
+VALUE shoes_image_draw(VALUE self, VALUE c, VALUE actual);
+void shoes_image_image(VALUE parent, VALUE path, VALUE attr);
+VALUE shoes_image_size(VALUE self);
+VALUE shoes_image_motion(VALUE self, int x, int y, char *touch);
+VALUE shoes_image_send_click(VALUE self, int button, int x, int y);
+void shoes_image_send_release(VALUE self, int button, int x, int y);
+
+// canvas
+VALUE shoes_canvas_image(int, VALUE *, VALUE);
+VALUE shoes_canvas_imagesize(VALUE self, VALUE _path);
+VALUE shoes_canvas_nostroke(VALUE);
+VALUE shoes_canvas_stroke(int, VALUE *, VALUE);
+VALUE shoes_canvas_strokewidth(VALUE, VALUE);
+VALUE shoes_canvas_dash(VALUE, VALUE);
+VALUE shoes_canvas_cap(VALUE, VALUE);
+VALUE shoes_canvas_nofill(VALUE);
+VALUE shoes_canvas_fill(int, VALUE *, VALUE);
+VALUE shoes_canvas_move_to(VALUE, VALUE, VALUE);
+VALUE shoes_canvas_line_to(VALUE, VALUE, VALUE);
+VALUE shoes_canvas_curve_to(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE);
+VALUE shoes_canvas_arc_to(VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE);
+VALUE shoes_canvas_transform(VALUE, VALUE);
+VALUE shoes_canvas_translate(VALUE, VALUE, VALUE);
+VALUE shoes_canvas_rotate(VALUE, VALUE);
+VALUE shoes_canvas_scale(int, VALUE *, VALUE);
+VALUE shoes_canvas_skew(int, VALUE *, VALUE);
+
+// canvas (shape related)
+VALUE shoes_canvas_rect(int, VALUE *, VALUE);
+VALUE shoes_canvas_arc(int, VALUE *, VALUE);
+VALUE shoes_canvas_oval(int, VALUE *, VALUE);
+VALUE shoes_canvas_line(int, VALUE *, VALUE);
+VALUE shoes_canvas_arrow(int, VALUE *, VALUE);
+VALUE shoes_canvas_star(int, VALUE *, VALUE);
+
+// ruby (effect related)
+VALUE shoes_canvas_blur(int, VALUE *, VALUE);
+VALUE shoes_canvas_glow(int, VALUE *, VALUE);
+VALUE shoes_canvas_shadow(int, VALUE *, VALUE);
+
+
+#define SHOES_IMAGE_PLACE(type, imw, imh, surf) \
+ SETUP_DRAWING(shoes_##type, (REL_CANVAS | REL_SCALE), imw, imh); \
+ VALUE ck = rb_obj_class(c); \
+ if (RTEST(actual)) \
+ shoes_image_draw_surface(CCR(canvas), self_t, &place, surf, imw, imh); \
+ FINISH(); \
+ return self;
+
+#endif
diff --git a/shoes/types/list_box.c b/shoes/types/list_box.c
new file mode 100644
index 00000000..51f7b1f0
--- /dev/null
+++ b/shoes/types/list_box.c
@@ -0,0 +1,113 @@
+#include "shoes/types/native.h"
+#include "shoes/types/list_box.h"
+
+// ruby
+VALUE cListBox;
+
+FUNC_M("+list_box", list_box, -1);
+
+void shoes_list_box_init() {
+ cListBox = rb_define_class_under(cTypes, "ListBox", cNative);
+ rb_define_method(cListBox, "text", CASTHOOK(shoes_list_box_text), 0);
+ rb_define_method(cListBox, "draw", CASTHOOK(shoes_list_box_draw), 2);
+ rb_define_method(cListBox, "choose", CASTHOOK(shoes_list_box_choose), 1);
+ rb_define_method(cListBox, "change", CASTHOOK(shoes_control_change), -1);
+ rb_define_method(cListBox, "items", CASTHOOK(shoes_list_box_items_get), 0);
+ rb_define_method(cListBox, "items=", CASTHOOK(shoes_list_box_items_set), 1);
+ rb_define_method(cListBox, "tooltip", CASTHOOK(shoes_control_get_tooltip), 0);
+ rb_define_method(cListBox, "tooltip=", CASTHOOK(shoes_control_set_tooltip), 1);
+
+ RUBY_M("+list_box", list_box, -1);
+}
+
+VALUE shoes_list_box_choose(VALUE self, VALUE item) {
+ VALUE items = Qnil;
+
+ GET_STRUCT(control, self_t);
+ ATTRSET(self_t->attr, choose, item);
+ if (self_t->ref == NULL) return self;
+
+ items = ATTR(self_t->attr, items);
+ shoes_native_list_box_set_active(self_t->ref, items, item);
+
+ return self;
+}
+
+VALUE shoes_list_box_text(VALUE self) {
+ GET_STRUCT(control, self_t);
+ if (self_t->ref == NULL) return Qnil;
+ return shoes_native_list_box_get_active(self_t->ref, ATTR(self_t->attr, items));
+}
+
+VALUE shoes_list_box_items_get(VALUE self) {
+ GET_STRUCT(control, self_t);
+ return ATTR(self_t->attr, items);
+}
+
+VALUE shoes_list_box_items_set(VALUE self, VALUE items) {
+ VALUE opt = shoes_list_box_text(self);
+
+ GET_STRUCT(control, self_t);
+ if (!rb_obj_is_kind_of(items, rb_cArray))
+ rb_raise(rb_eArgError, "ListBox items must be an array.");
+ ATTRSET(self_t->attr, items, items);
+ if (self_t->ref != NULL) shoes_native_list_box_update(self_t->ref, items);
+ if (!NIL_P(opt)) shoes_list_box_choose(self, opt);
+
+ return items;
+}
+
+VALUE shoes_list_box_draw(VALUE self, VALUE c, VALUE actual) {
+ SETUP_CONTROL(0, 0, TRUE);
+
+#ifdef SHOES_QUARTZ
+ place.h += 4;
+ place.ih += 4;
+#endif
+ if (RTEST(actual)) {
+ if (self_t->ref == NULL) {
+ VALUE items = ATTR(self_t->attr, items);
+ self_t->ref = shoes_native_list_box(self, canvas, &place, self_t->attr, msg);
+
+ if (!NIL_P(items)) {
+ shoes_list_box_items_set(self, items);
+ shoes_control_check_styles(self_t);
+ if (!NIL_P(ATTR(self_t->attr, choose)))
+ shoes_native_list_box_set_active(self_t->ref, items, ATTR(self_t->attr, choose));
+ }
+
+#ifdef SHOES_WIN32
+ shoes_native_control_position_no_pad(self_t->ref, &self_t->place, self, canvas, &place);
+#else
+ shoes_native_control_position(self_t->ref, &self_t->place, self, canvas, &place);
+#endif
+ } else
+#ifdef SHOES_WIN32
+ shoes_native_control_repaint_no_pad(self_t->ref, &self_t->place, canvas, &place);
+#else
+ shoes_native_control_repaint(self_t->ref, &self_t->place, canvas, &place);
+#endif
+ }
+
+ FINISH();
+
+ return self;
+}
+
+// canvas
+VALUE shoes_canvas_list_box(int argc, VALUE *argv, VALUE self) {
+ rb_arg_list args;
+ VALUE list_box;
+
+ SETUP_CANVAS();
+
+ rb_parse_args(argc, argv, "|h&", &args);
+
+ if (!NIL_P(args.a[1]))
+ ATTRSET(args.a[0], change, args.a[1]);
+
+ list_box = shoes_control_new(cListBox, args.a[0], self);
+ shoes_add_ele(canvas, list_box);
+
+ return list_box;
+}
diff --git a/shoes/types/list_box.h b/shoes/types/list_box.h
new file mode 100644
index 00000000..70cd6a26
--- /dev/null
+++ b/shoes/types/list_box.h
@@ -0,0 +1,37 @@
+#include "shoes/ruby.h"
+#include "shoes/canvas.h"
+#include "shoes/app.h"
+#include "shoes/internal.h"
+#include "shoes/world.h"
+#include "shoes/native/native.h"
+
+#ifndef SHOES_LIST_BOX_TYPE_H
+#define SHOES_LIST_BOX_TYPE_H
+
+/* extern variables necessary to communicate with other parts of Shoes */
+extern VALUE cShoes, cApp, cTypes, cCanvas, cWidget;
+extern shoes_app _shoes_app;
+
+/* Should be automatically available but ruby.c is not sharing enough information */
+extern VALUE shoes_control_change(int argc, VALUE *argv, VALUE self);
+
+// native forward declarations
+extern SHOES_CONTROL_REF shoes_native_list_box(VALUE, shoes_canvas *, shoes_place *, VALUE, char *);
+extern void shoes_native_list_box_update(SHOES_CONTROL_REF, VALUE);
+extern VALUE shoes_native_list_box_get_active(SHOES_CONTROL_REF, VALUE);
+extern void shoes_native_list_box_set_active(SHOES_CONTROL_REF, VALUE, VALUE);
+
+/* each widget should have its own init function */
+void shoes_list_box_init();
+
+// ruby
+VALUE shoes_list_box_choose(VALUE self, VALUE item);
+VALUE shoes_list_box_text(VALUE self);
+VALUE shoes_list_box_items_get(VALUE self);
+VALUE shoes_list_box_items_set(VALUE self, VALUE items);
+VALUE shoes_list_box_draw(VALUE self, VALUE c, VALUE actual);
+
+// canvas
+VALUE shoes_canvas_list_box(int, VALUE *, VALUE);
+
+#endif
diff --git a/shoes/types/native.c b/shoes/types/native.c
new file mode 100644
index 00000000..8dbd4128
--- /dev/null
+++ b/shoes/types/native.c
@@ -0,0 +1,207 @@
+#include "shoes/types/native.h"
+
+// ruby
+VALUE cNative;
+
+PLACE_COMMON(control);
+CLASS_COMMON(control);
+EVENT_COMMON(control, control, click);
+EVENT_COMMON(control, control, change);
+
+// TODO: May need to refactor all types depending on native to use either types/native_{.c,.h} or types/native/{.c,.h}. That would be proper etiquette. For now, just using shoes_0_native_type_init().
+
+// Many types depend on native, so initialization needs to be triggered first.
+void shoes_0_native_type_init() {
+ cNative = rb_define_class_under(cTypes, "Native", rb_cObject);
+
+ rb_define_alloc_func(cNative, shoes_control_alloc);
+
+ rb_define_method(cNative, "app", CASTHOOK(shoes_canvas_get_app), 0);
+ rb_define_method(cNative, "parent", CASTHOOK(shoes_control_get_parent), 0);
+ rb_define_method(cNative, "style", CASTHOOK(shoes_control_style), -1);
+ rb_define_method(cNative, "displace", CASTHOOK(shoes_control_displace), 2);
+ rb_define_method(cNative, "focus", CASTHOOK(shoes_control_focus), 0);
+ rb_define_method(cNative, "hide", CASTHOOK(shoes_control_hide), 0);
+ rb_define_method(cNative, "show", CASTHOOK(shoes_control_show), 0);
+ rb_define_method(cNative, "state=", CASTHOOK(shoes_control_set_state), 1);
+ rb_define_method(cNative, "state", CASTHOOK(shoes_control_get_state), 0);
+ rb_define_method(cNative, "move", CASTHOOK(shoes_control_move), 2);
+ rb_define_method(cNative, "top", CASTHOOK(shoes_control_get_top), 0);
+ rb_define_method(cNative, "left", CASTHOOK(shoes_control_get_left), 0);
+ rb_define_method(cNative, "width", CASTHOOK(shoes_control_get_width), 0);
+ rb_define_method(cNative, "height", CASTHOOK(shoes_control_get_height), 0);
+ rb_define_method(cNative, "remove", CASTHOOK(shoes_control_remove), 0);
+}
+
+// ruby
+void shoes_control_mark(shoes_control *control) {
+ rb_gc_mark_maybe(control->parent);
+ rb_gc_mark_maybe(control->attr);
+}
+
+void shoes_control_free(shoes_control *control) {
+ if (control->ref != NULL) shoes_native_control_free(control->ref);
+ RUBY_CRITICAL(free(control));
+}
+
+VALUE shoes_control_new(VALUE klass, VALUE attr, VALUE parent) {
+ shoes_control *control;
+ VALUE obj = shoes_control_alloc(klass);
+ Data_Get_Struct(obj, shoes_control, control);
+ control->attr = attr;
+ control->parent = parent;
+ return obj;
+}
+
+VALUE shoes_control_alloc(VALUE klass) {
+ VALUE obj;
+ shoes_control *control = SHOE_ALLOC(shoes_control);
+ SHOE_MEMZERO(control, shoes_control, 1);
+ obj = Data_Wrap_Struct(klass, shoes_control_mark, shoes_control_free, control);
+ control->attr = Qnil;
+ control->parent = Qnil;
+ return obj;
+}
+
+VALUE shoes_control_focus(VALUE self) {
+ GET_STRUCT(control, self_t);
+// ATTRSET(self_t->attr, hidden, Qtrue);
+ if (self_t->ref != NULL) shoes_native_control_focus(self_t->ref);
+ return self;
+}
+
+VALUE shoes_control_get_state(VALUE self) {
+ GET_STRUCT(control, self_t);
+ return ATTR(self_t->attr, state);
+}
+
+static VALUE shoes_control_try_state(shoes_control *self_t, VALUE state) {
+ unsigned char cstate;
+ if (NIL_P(state))
+ cstate = CONTROL_NORMAL;
+ else if (TYPE(state) == T_STRING) {
+ if (strncmp(RSTRING_PTR(state), "disabled", 8) == 0)
+ cstate = CONTROL_DISABLED;
+ else if (strncmp(RSTRING_PTR(state), "readonly", 8) == 0)
+ cstate = CONTROL_READONLY;
+ else {
+ shoes_error("control can't have :state of %s\n", RSTRING_PTR(state));
+ return Qfalse;
+ }
+ } else return Qfalse;
+
+ if (self_t->ref != NULL) {
+ if (cstate == CONTROL_NORMAL)
+ shoes_native_control_state(self_t->ref, TRUE, TRUE);
+ else if (cstate == CONTROL_DISABLED)
+ shoes_native_control_state(self_t->ref, FALSE, TRUE);
+ else if (cstate == CONTROL_READONLY)
+ shoes_native_control_state(self_t->ref, TRUE, FALSE);
+ }
+ return Qtrue;
+}
+
+VALUE shoes_control_set_state(VALUE self, VALUE state) {
+ GET_STRUCT(control, self_t);
+ if (shoes_control_try_state(self_t, state))
+ ATTRSET(self_t->attr, state, state);
+ return self;
+}
+
+VALUE shoes_control_temporary_hide(VALUE self) {
+ GET_STRUCT(control, self_t);
+ if (self_t->ref != NULL) shoes_control_hide_ref(self_t->ref);
+ return self;
+}
+
+VALUE shoes_control_hide(VALUE self) {
+ GET_STRUCT(control, self_t);
+ ATTRSET(self_t->attr, hidden, Qtrue);
+ if (self_t->ref != NULL) shoes_control_hide_ref(self_t->ref);
+ return self;
+}
+
+VALUE shoes_control_temporary_show(VALUE self) {
+ GET_STRUCT(control, self_t);
+ if (self_t->ref != NULL) shoes_control_show_ref(self_t->ref);
+ return self;
+}
+
+VALUE shoes_control_show(VALUE self) {
+ GET_STRUCT(control, self_t);
+ ATTRSET(self_t->attr, hidden, Qfalse);
+ if (self_t->ref != NULL) shoes_control_show_ref(self_t->ref);
+ return self;
+}
+
+VALUE shoes_control_remove(VALUE self) {
+ shoes_canvas *canvas;
+ GET_STRUCT(control, self_t);
+ shoes_canvas_remove_item(self_t->parent, self, 1, 0);
+
+ Data_Get_Struct(self_t->parent, shoes_canvas, canvas);
+ if (self_t->ref != NULL) {
+ SHOES_CONTROL_REF ref = self_t->ref;
+ self_t->ref = NULL;
+ shoes_native_control_remove(ref, canvas);
+ }
+ return self;
+}
+
+void shoes_control_check_styles(shoes_control *self_t) {
+ VALUE x = ATTR(self_t->attr, state);
+ shoes_control_try_state(self_t, x);
+}
+
+void shoes_control_send(VALUE self, ID event) {
+ VALUE click;
+ GET_STRUCT(control, self_t);
+
+ if (!NIL_P(self_t->attr)) {
+ click = rb_hash_aref(self_t->attr, ID2SYM(event));
+ if (!NIL_P(click))
+ shoes_safe_block(self_t->parent, click, rb_ary_new3(1, self));
+ }
+}
+
+
+VALUE shoes_control_get_tooltip(VALUE self) {
+ GET_STRUCT(control, self_t);
+ return shoes_native_control_get_tooltip(self_t->ref);
+}
+
+VALUE shoes_control_set_tooltip(VALUE self, VALUE tooltip) {
+ GET_STRUCT(control, self_t);
+ if (self_t->ref != NULL)
+ shoes_native_control_set_tooltip(self_t->ref, tooltip);
+
+ return self;
+}
+
+
+void shoes_control_hide_ref(SHOES_CONTROL_REF ref) {
+ if (ref != NULL) shoes_native_control_hide(ref);
+}
+
+void shoes_control_show_ref(SHOES_CONTROL_REF ref) {
+ if (ref != NULL) shoes_native_control_show(ref);
+}
+
+// canvas
+VALUE shoes_canvas_hide(VALUE self) {
+ shoes_canvas *self_t;
+ Data_Get_Struct(self, shoes_canvas, self_t);
+ ATTRSET(self_t->attr, hidden, Qtrue);
+ shoes_canvas_ccall(self, shoes_control_temporary_hide, shoes_native_control_hide, 1);
+ shoes_canvas_repaint_all(self);
+ return self;
+}
+
+VALUE shoes_canvas_show(VALUE self) {
+ shoes_canvas *self_t;
+ Data_Get_Struct(self, shoes_canvas, self_t);
+ ATTRSET(self_t->attr, hidden, Qfalse);
+ shoes_canvas_ccall(self, shoes_control_temporary_show, shoes_native_control_show, 1);
+ shoes_canvas_repaint_all(self);
+ return self;
+}
diff --git a/shoes/types/native.h b/shoes/types/native.h
new file mode 100644
index 00000000..fa508720
--- /dev/null
+++ b/shoes/types/native.h
@@ -0,0 +1,55 @@
+#include "shoes/ruby.h"
+#include "shoes/canvas.h"
+#include "shoes/app.h"
+#include "shoes/internal.h"
+#include "shoes/world.h"
+#include "shoes/native/native.h"
+
+#ifndef SHOES_NATIVE_TYPE_H
+#define SHOES_NATIVE_TYPE_H
+
+/* extern variables necessary to communicate with other parts of Shoes */
+extern VALUE cShoes, cApp, cTypes, cCanvas, cWidget;
+extern shoes_app _shoes_app;
+
+VALUE cNative;
+
+#define CONTROL_NORMAL 0
+#define CONTROL_READONLY 1
+#define CONTROL_DISABLED 2
+
+typedef struct {
+ VALUE parent;
+ VALUE attr;
+ shoes_place place;
+ SHOES_CONTROL_REF ref;
+} shoes_control;
+
+/* each widget should have its own init function */
+void shoes_0_native_type_init();
+
+// ruby
+void shoes_control_mark(shoes_control *control);
+void shoes_control_free(shoes_control *control);
+VALUE shoes_control_new(VALUE klass, VALUE attr, VALUE parent);
+VALUE shoes_control_alloc(VALUE klass);
+VALUE shoes_control_focus(VALUE self);
+VALUE shoes_control_get_state(VALUE self);
+VALUE shoes_control_set_state(VALUE self, VALUE state);
+VALUE shoes_control_temporary_hide(VALUE self);
+VALUE shoes_control_hide(VALUE self);
+VALUE shoes_control_temporary_show(VALUE self);
+VALUE shoes_control_show(VALUE self);
+VALUE shoes_control_remove(VALUE self);
+void shoes_control_check_styles(shoes_control *self_t);
+void shoes_control_send(VALUE self, ID event);
+VALUE shoes_control_get_tooltip(VALUE self);
+VALUE shoes_control_set_tooltip(VALUE self, VALUE tooltip);
+void shoes_control_hide_ref(SHOES_CONTROL_REF ref);
+void shoes_control_show_ref(SHOES_CONTROL_REF ref);
+
+// canvas
+VALUE shoes_canvas_hide(VALUE self);
+VALUE shoes_canvas_show(VALUE self) ;
+
+#endif
diff --git a/shoes/types/pattern.c b/shoes/types/pattern.c
new file mode 100644
index 00000000..eb9546b0
--- /dev/null
+++ b/shoes/types/pattern.c
@@ -0,0 +1,295 @@
+#include "shoes/types/color.h"
+#include "shoes/types/pattern.h"
+
+// ruby
+VALUE cPattern, cBorder, cBackground;
+
+CLASS_COMMON2(pattern);
+
+FUNC_M("+background", background, -1);
+FUNC_M("+border", border, -1);
+
+void shoes_pattern_init() {
+ cPattern = rb_define_class_under(cTypes, "Pattern", rb_cObject);
+
+ rb_define_alloc_func(cPattern, shoes_pattern_alloc);
+
+ rb_define_method(cPattern, "displace", CASTHOOK(shoes_pattern_displace), 2);
+ rb_define_method(cPattern, "move", CASTHOOK(shoes_pattern_move), 2);
+ rb_define_method(cPattern, "remove", CASTHOOK(shoes_basic_remove), 0);
+ rb_define_method(cPattern, "to_pattern", CASTHOOK(shoes_pattern_self), 0);
+ rb_define_method(cPattern, "style", CASTHOOK(shoes_pattern_style), -1);
+ rb_define_method(cPattern, "fill", CASTHOOK(shoes_pattern_get_fill), 0);
+ rb_define_method(cPattern, "fill=", CASTHOOK(shoes_pattern_set_fill), 1);
+ rb_define_method(cPattern, "hide", CASTHOOK(shoes_pattern_hide), 0);
+ rb_define_method(cPattern, "show", CASTHOOK(shoes_pattern_show), 0);
+ rb_define_method(cPattern, "toggle", CASTHOOK(shoes_pattern_toggle), 0);
+
+ cBackground = rb_define_class_under(cTypes, "Background", cPattern);
+ rb_define_method(cBackground, "draw", CASTHOOK(shoes_background_draw), 2);
+ cBorder = rb_define_class_under(cTypes, "Border", cPattern);
+ rb_define_method(cBorder, "draw", CASTHOOK(shoes_border_draw), 2);
+
+ rb_define_method(rb_mKernel, "pattern", CASTHOOK(shoes_pattern_method), 1);
+
+ RUBY_M("+background", background, -1);
+ RUBY_M("+border", border, -1);
+}
+
+// ruby
+void shoes_pattern_mark(shoes_pattern *pattern) {
+ rb_gc_mark_maybe(pattern->source);
+ rb_gc_mark_maybe(pattern->parent);
+ rb_gc_mark_maybe(pattern->attr);
+}
+
+void shoes_pattern_free(shoes_pattern *pattern) {
+ if (pattern->pattern != NULL)
+ cairo_pattern_destroy(pattern->pattern);
+ RUBY_CRITICAL(free(pattern));
+}
+
+void shoes_pattern_gradient(shoes_pattern *pattern, VALUE r1, VALUE r2, VALUE attr) {
+ double angle = ATTR2(dbl, attr, angle, 0.);
+ double rads = angle * SHOES_RAD2PI;
+ double dx = sin(rads);
+ double dy = cos(rads);
+ double edge = (fabs(dx) + fabs(dy)) * 0.5;
+
+ if (rb_obj_is_kind_of(r1, rb_cString))
+ r1 = shoes_color_parse(cColor, r1);
+ if (rb_obj_is_kind_of(r2, rb_cString))
+ r2 = shoes_color_parse(cColor, r2);
+
+ VALUE radius = ATTR(attr, radius);
+ if (!NIL_P(radius)) {
+ double r = 0.001;
+ if (rb_obj_is_kind_of(r, rb_cFloat)) r = NUM2DBL(radius);
+ pattern->pattern = cairo_pattern_create_radial(0.5, 0.5, r, edge / 2., edge / 2., edge / 2.);
+ } else {
+ pattern->pattern = cairo_pattern_create_linear(0.5 + (-dx * edge), 0.5 + (-dy * edge),
+ 0.5 + (dx * edge), 0.5 + (dy * edge));
+ }
+ shoes_color_grad_stop(pattern->pattern, 0.0, r1);
+ shoes_color_grad_stop(pattern->pattern, 1.0, r2);
+}
+
+VALUE shoes_pattern_set_fill(VALUE self, VALUE source) {
+ shoes_pattern *pattern;
+ Data_Get_Struct(self, shoes_pattern, pattern);
+
+ if (pattern->pattern != NULL)
+ cairo_pattern_destroy(pattern->pattern);
+ pattern->pattern = NULL;
+
+ if (rb_obj_is_kind_of(source, rb_cRange)) {
+ VALUE r1 = rb_funcall(source, s_begin, 0);
+ VALUE r2 = rb_funcall(source, s_end, 0);
+ shoes_pattern_gradient(pattern, r1, r2, pattern->attr);
+ } else {
+ if (!rb_obj_is_kind_of(source, cColor)) {
+ VALUE rgb = shoes_color_parse(cColor, source);
+ if (!NIL_P(rgb)) source = rgb;
+ }
+
+ if (rb_obj_is_kind_of(source, cColor)) {
+ pattern->pattern = shoes_color_pattern(source);
+ } else {
+ pattern->cached = shoes_load_image(pattern->parent, source);
+ if (pattern->cached != NULL && pattern->cached->pattern == NULL)
+ pattern->cached->pattern = cairo_pattern_create_for_surface(pattern->cached->surface);
+ }
+ cairo_pattern_set_extend(PATTERN(pattern), CAIRO_EXTEND_REPEAT);
+ }
+
+ pattern->source = source;
+ return source;
+}
+
+VALUE shoes_pattern_get_fill(VALUE self) {
+ shoes_pattern *pattern;
+ Data_Get_Struct(self, shoes_pattern, pattern);
+ return pattern->source;
+}
+
+VALUE shoes_pattern_self(VALUE self) {
+ return self;
+}
+
+VALUE shoes_pattern_args(int argc, VALUE *argv, VALUE self) {
+ VALUE source, attr;
+ rb_scan_args(argc, argv, "11", &source, &attr);
+ CHECK_HASH(attr);
+ return shoes_pattern_new(cPattern, source, attr, Qnil);
+}
+
+VALUE shoes_pattern_new(VALUE klass, VALUE source, VALUE attr, VALUE parent) {
+ shoes_pattern *pattern;
+ VALUE obj = shoes_pattern_alloc(klass);
+ Data_Get_Struct(obj, shoes_pattern, pattern);
+ pattern->source = Qnil;
+ pattern->attr = attr;
+ pattern->parent = parent;
+ shoes_pattern_set_fill(obj, source);
+ return obj;
+}
+
+VALUE shoes_pattern_method(VALUE klass, VALUE source) {
+ return shoes_pattern_new(cPattern, source, Qnil, Qnil);
+}
+
+VALUE shoes_pattern_alloc(VALUE klass) {
+ VALUE obj;
+ shoes_pattern *pattern = SHOE_ALLOC(shoes_pattern);
+ SHOE_MEMZERO(pattern, shoes_pattern, 1);
+ obj = Data_Wrap_Struct(klass, shoes_pattern_mark, shoes_pattern_free, pattern);
+ pattern->source = Qnil;
+ pattern->attr = Qnil;
+ pattern->parent = Qnil;
+ return obj;
+}
+
+
+// This crawls up the parent tree at draw time to learn if there is
+// an active scroll bar 'above'. Returns the width of the gutter
+// TODO: Breaks manual (help.rb) so it's not used.
+int is_slot_scrolled(shoes_canvas *canvas) {
+ int gutterw = 0;
+ shoes_canvas *cvs = canvas;
+ gutterw = shoes_native_slot_gutter(cvs->slot);
+ while (gutterw == 0 && (! NIL_P(cvs->parent)) ) {
+ //fprintf(stderr, "Backgound Climb up\n");
+ Data_Get_Struct(cvs->parent, shoes_canvas, cvs);
+ gutterw = shoes_native_slot_gutter(cvs->slot);
+ }
+ return gutterw;
+}
+
+// background is treated differently from other patterns.
+VALUE shoes_background_draw(VALUE self, VALUE c, VALUE actual) {
+ cairo_matrix_t matrix1, matrix2;
+ double r = 0., sw = 1.;
+ int expand = 0;
+ SETUP_DRAWING(shoes_pattern, REL_TILE, PATTERN_DIM(self_t, width), PATTERN_DIM(self_t, height));
+ r = ATTR2(dbl, self_t->attr, curve, 0.);
+ VALUE ev = shoes_hash_get(self_t->attr, s_scroll);
+ if (!NIL_P(ev) && (ev == Qtrue))
+ expand = 1;
+
+ if (RTEST(actual)) {
+ cairo_t *cr = CCR(canvas);
+ cairo_save(cr);
+ if (expand == 0) {
+ cairo_translate(cr, place.ix + place.dx, place.iy + place.dy);
+ PATTERN_SCALE(self_t, place, sw);
+ cairo_new_path(cr);
+ shoes_cairo_rect(cr, 0, 0, place.iw, place.ih, r);
+ } else {
+ // new option with 3.3.3
+ int scrollwidth = is_slot_scrolled(canvas);
+ int top = INT2NUM(canvas->slot->scrolly);
+ //fprintf(stderr, "inside y: %d, iy: %d, dy: %d\n", place.y, place.iy, place.dy );
+ //fprintf(stderr, " h: %d, ih: %d, top: %d\n", place.h, place.ih, top);
+ cairo_translate(cr, place.ix + place.dx - scrollwidth, place.iy + place.dy + top);
+ PATTERN_SCALE(self_t, place, sw);
+ cairo_new_path(cr);
+ shoes_cairo_rect(cr, 0, 0 - top, place.iw, place.ih + top, r);
+ }
+
+ cairo_set_source(cr, PATTERN(self_t));
+ cairo_fill(cr);
+ cairo_restore(cr);
+ PATTERN_RESET(self_t);
+ }
+
+ self_t->place = place;
+ //INFO("BACKGROUND: (%d, %d), (%d, %d)\n", place.x, place.y, place.w, place.h);
+ return self;
+}
+
+VALUE shoes_border_draw(VALUE self, VALUE c, VALUE actual) {
+ cairo_matrix_t matrix1, matrix2;
+ ID cap = s_rect;
+ ID dash = s_nodot;
+ double r = 0., sw = 1.;
+ SETUP_DRAWING(shoes_pattern, REL_TILE, PATTERN_DIM(self_t, width), PATTERN_DIM(self_t, height));
+ r = ATTR2(dbl, self_t->attr, curve, 0.);
+ sw = ATTR2(dbl, self_t->attr, strokewidth, 1.);
+ if (!NIL_P(ATTR(self_t->attr, cap))) cap = SYM2ID(ATTR(self_t->attr, cap));
+ if (!NIL_P(ATTR(self_t->attr, dash))) dash = SYM2ID(ATTR(self_t->attr, dash));
+
+ place.iw -= (int)round(sw);
+ place.ih -= (int)round(sw);
+ place.ix += (int)round(sw / 2.);
+ place.iy += (int)round(sw / 2.);
+
+ if (RTEST(actual)) {
+ cairo_t *cr = CCR(canvas);
+ cairo_save(cr);
+ cairo_translate(cr, place.ix + place.dx, place.iy + place.dy);
+ PATTERN_SCALE(self_t, place, sw);
+ cairo_set_source(cr, PATTERN(self_t));
+ cairo_new_path(cr);
+ shoes_cairo_rect(cr, 0, 0, place.iw, place.ih, r);
+ cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE);
+ CAP_SET(cr, cap);
+ DASH_SET(cr, dash);
+ cairo_set_line_width(cr, sw);
+ cairo_stroke(cr);
+ cairo_restore(cr);
+ PATTERN_RESET(self_t);
+ }
+
+ self_t->place = place;
+ INFO("BORDER: (%d, %d), (%d, %d)\n", place.x, place.y, place.w, place.h);
+ return self;
+}
+
+VALUE shoes_subpattern_new(VALUE klass, VALUE pat, VALUE parent) {
+ shoes_pattern *back, *pattern;
+ VALUE obj = shoes_pattern_alloc(klass);
+ Data_Get_Struct(obj, shoes_pattern, back);
+ Data_Get_Struct(pat, shoes_pattern, pattern);
+ back->source = pattern->source;
+ back->cached = pattern->cached;
+ back->pattern = pattern->pattern;
+ if (back->pattern != NULL) cairo_pattern_reference(back->pattern);
+ back->attr = pattern->attr;
+ back->parent = parent;
+ return obj;
+}
+
+// canvas
+VALUE shoes_canvas_background(int argc, VALUE *argv, VALUE self) {
+ VALUE pat;
+ SETUP_CANVAS();
+
+ if (argc == 1 && rb_obj_is_kind_of(argv[0], cPattern))
+ pat = argv[0];
+ else
+ pat = shoes_pattern_args(argc, argv, self);
+
+ if (!NIL_P(pat)) {
+ pat = shoes_subpattern_new(cBackground, pat, self);
+ shoes_add_ele(canvas, pat);
+ }
+
+ return pat;
+}
+
+VALUE shoes_canvas_border(int argc, VALUE *argv, VALUE self) {
+ VALUE pat;
+ SETUP_CANVAS();
+
+ if (argc == 1 && rb_obj_is_kind_of(argv[0], cPattern))
+ pat = argv[0];
+ else
+ pat = shoes_pattern_args(argc, argv, self);
+
+ if (!NIL_P(pat)) {
+ pat = shoes_subpattern_new(cBorder, pat, self);
+ shoes_add_ele(canvas, pat);
+ }
+
+ return pat;
+}
diff --git a/shoes/types/pattern.h b/shoes/types/pattern.h
new file mode 100644
index 00000000..7e0dfa5a
--- /dev/null
+++ b/shoes/types/pattern.h
@@ -0,0 +1,121 @@
+#include "shoes/ruby.h"
+#include "shoes/canvas.h"
+#include "shoes/app.h"
+#include "shoes/internal.h"
+#include "shoes/world.h"
+#include "shoes/native/native.h"
+
+#ifndef SHOES_PATTERN_TYPE_H
+#define SHOES_PATTERN_TYPE_H
+
+/* extern variables necessary to communicate with other parts of Shoes */
+extern VALUE cShoes, cApp, cTypes, cCanvas, cWidget;
+extern shoes_app _shoes_app;
+
+VALUE cPattern, cBorder, cBackground;
+
+typedef struct {
+ VALUE parent;
+ VALUE attr;
+ shoes_place place;
+ VALUE source;
+ char hover;
+ shoes_cached_image *cached;
+ cairo_pattern_t *pattern;
+} shoes_pattern;
+
+/* each widget should have its own init function */
+void shoes_pattern_init();
+
+// ruby
+void shoes_pattern_mark(shoes_pattern *pattern);
+void shoes_pattern_free(shoes_pattern *pattern);
+void shoes_pattern_gradient(shoes_pattern *pattern, VALUE r1, VALUE r2, VALUE attr);
+VALUE shoes_pattern_set_fill(VALUE self, VALUE source);
+VALUE shoes_pattern_get_fill(VALUE self);
+VALUE shoes_pattern_self(VALUE self);
+VALUE shoes_pattern_args(int argc, VALUE *argv, VALUE self);
+VALUE shoes_pattern_new(VALUE klass, VALUE source, VALUE attr, VALUE parent);
+VALUE shoes_pattern_method(VALUE klass, VALUE source);
+VALUE shoes_pattern_alloc(VALUE klass);
+VALUE shoes_background_draw(VALUE self, VALUE c, VALUE actual);
+VALUE shoes_border_draw(VALUE self, VALUE c, VALUE actual);
+VALUE shoes_subpattern_new(VALUE klass, VALUE pat, VALUE parent);
+
+// canvas
+VALUE shoes_canvas_background(int argc, VALUE *argv, VALUE self);
+VALUE shoes_canvas_border(int argc, VALUE *argv, VALUE self);
+
+#define PATH_OUT(cr, attr, place, sw, cap, dash, pen, cfunc) \
+{ \
+ VALUE p = ATTR(attr, pen); \
+ if (!NIL_P(p)) \
+ { \
+ CAP_SET(cr, cap); \
+ DASH_SET(cr, dash); \
+ cairo_set_line_width(cr, sw); \
+ if (rb_obj_is_kind_of(p, cColor)) \
+ { \
+ shoes_color *color; \
+ Data_Get_Struct(p, shoes_color, color); \
+ cairo_set_source_rgba(cr, color->r / 255., color->g / 255., color->b / 255., color->a / 255.); \
+ cfunc(cr); \
+ } \
+ else \
+ { \
+ if (!rb_obj_is_kind_of(p, cPattern)) \
+ ATTRSET(attr, pen, p = shoes_pattern_new(cPattern, p, Qnil, Qnil)); \
+ cairo_matrix_t matrix1, matrix2; \
+ shoes_pattern *pattern; \
+ Data_Get_Struct(p, shoes_pattern, pattern); \
+ PATTERN_SCALE(pattern, (place), sw); \
+ cairo_set_source(cr, PATTERN(pattern)); \
+ cfunc(cr); \
+ PATTERN_RESET(pattern); \
+ } \
+ } \
+}
+
+#define CAP_SET(cr, cap) \
+ if (cap == s_project) \
+ cairo_set_line_cap(cr, CAIRO_LINE_CAP_SQUARE); \
+ else if (cap == s_round || cap == s_curve) \
+ cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND); \
+ else if (cap == s_square || cap == s_rect) \
+ cairo_set_line_cap(cr, CAIRO_LINE_CAP_BUTT)
+
+#define DASH_SET(cr, dash) \
+ if (dash == s_onedot) \
+ { \
+ double dashes[] = {50.0, 10.0, 10.0, 10.0}; \
+ int ndash = sizeof (dashes)/sizeof(dashes[0]); \
+ double offset = -50.0; \
+ cairo_set_dash(cr, dashes, ndash, offset); \
+ } \
+ else \
+ { \
+ cairo_set_dash(cr, NULL, 0, 0.0); \
+ }
+
+#define PATTERN_DIM(self_t, x) (self_t->cached != NULL ? self_t->cached->x : 1)
+#define PATTERN(self_t) (self_t->cached != NULL ? self_t->cached->pattern : self_t->pattern)
+#define PATTERN_SCALE(self_t, place, sw) \
+ if (self_t->cached == NULL) \
+ { \
+ double woff = abs(place.iw) + (sw * 2.), hoff = abs(place.ih) + (sw * 2.); \
+ cairo_pattern_get_matrix(PATTERN(self_t), &matrix1); \
+ cairo_pattern_get_matrix(PATTERN(self_t), &matrix2); \
+ if (cairo_pattern_get_type(PATTERN(self_t)) == CAIRO_PATTERN_TYPE_RADIAL) \
+ cairo_matrix_translate(&matrix2, (-place.ix * 1.) / woff, (-place.iy * 1.) / hoff); \
+ cairo_matrix_scale(&matrix2, 1. / woff, 1. / hoff); \
+ if (sw != 0.0) cairo_matrix_translate(&matrix2, sw, sw); \
+ cairo_pattern_set_matrix(PATTERN(self_t), &matrix2); \
+ }
+
+#define PATTERN_RESET(self_t) \
+ if (self_t->cached == NULL) \
+ { \
+ cairo_pattern_set_matrix(PATTERN(self_t), &matrix1); \
+ }
+
+#endif
diff --git a/shoes/types/plot.c b/shoes/types/plot.c
new file mode 100644
index 00000000..9e7a1dcc
--- /dev/null
+++ b/shoes/types/plot.c
@@ -0,0 +1,102 @@
+#include "shoes/plot/plot.h"
+#include "shoes/types/plot.h"
+
+// ruby
+VALUE cPlot, cChartSeries;
+
+FUNC_M("+plot", plot, -1);
+FUNC_M("+chart_series", chart_series, -1);
+
+// The next two macros are very important for new widget writers.
+CLASS_COMMON2(plot)
+TRANS_COMMON(plot, 1);
+
+void shoes_plot_init() {
+ cPlot = rb_define_class_under(cTypes, "Plot", rb_cObject); // 3.3.2
+ rb_define_alloc_func(cPlot, shoes_plot_alloc);
+
+ // methods unique to plot
+ rb_define_method(cPlot, "add", CASTHOOK(shoes_plot_add), 1);
+ rb_define_method(cPlot, "redraw_to", CASTHOOK(shoes_plot_redraw_to), 1);
+ rb_define_method(cPlot, "delete", CASTHOOK(shoes_plot_delete), 1);
+ rb_define_method(cPlot, "id", CASTHOOK(shoes_plot_find_name), 1);
+ rb_define_method(cPlot, "count", CASTHOOK(shoes_plot_get_count), 0);
+ rb_define_method(cPlot, "first", CASTHOOK(shoes_plot_get_first), 0);
+ rb_define_method(cPlot, "set_first", CASTHOOK(shoes_plot_set_first), 1);
+ rb_define_method(cPlot, "last", CASTHOOK(shoes_plot_get_last), 0);
+ rb_define_method(cPlot, "set_last", CASTHOOK(shoes_plot_set_last), 1);
+ rb_define_method(cPlot, "zoom", CASTHOOK(shoes_plot_zoom), 2);
+ rb_define_method(cPlot, "save_as", CASTHOOK(shoes_plot_save_as), -1);
+ rb_define_method(cPlot, "near_x", CASTHOOK(shoes_plot_near), 1);
+
+ // methods commom to many Shoes widgets
+ rb_define_method(cPlot, "draw", CASTHOOK(shoes_plot_draw), 2);
+ rb_define_method(cPlot, "remove", CASTHOOK(shoes_plot_remove), 0);
+ rb_define_method(cPlot, "parent", CASTHOOK(shoes_plot_get_parent), 0);
+ rb_define_method(cPlot, "style", CASTHOOK(shoes_plot_style), -1);
+ rb_define_method(cPlot, "move", CASTHOOK(shoes_plot_move), 2);
+ rb_define_method(cPlot, "displace", CASTHOOK(shoes_plot_displace), 2);
+ rb_define_method(cPlot, "hide", CASTHOOK(shoes_plot_hide), 0);
+ rb_define_method(cPlot, "show", CASTHOOK(shoes_plot_show), 0);
+ rb_define_method(cPlot, "toggle", CASTHOOK(shoes_plot_toggle), 0);
+ rb_define_method(cPlot, "hidden?", CASTHOOK(shoes_plot_is_hidden), 0);
+ rb_define_method(cPlot, "click", CASTHOOK(shoes_plot_click), -1);
+ rb_define_method(cPlot, "released", CASTHOOK(shoes_plot_release), -1);
+ rb_define_method(cPlot, "hover", CASTHOOK(shoes_plot_hover), -1);
+ rb_define_method(cPlot, "leave", CASTHOOK(shoes_plot_leave), -1);
+ rb_define_method(cPlot, "top", CASTHOOK(shoes_plot_get_actual_top), 0);
+ rb_define_method(cPlot, "left", CASTHOOK(shoes_plot_get_actual_left), 0);
+ rb_define_method(cPlot, "width", CASTHOOK(shoes_plot_get_actual_width), 0);
+ rb_define_method(cPlot, "height", CASTHOOK(shoes_plot_get_actual_height), 0);
+ rb_define_method(cPlot, "transform", CASTHOOK(shoes_plot_transform), 1);
+ rb_define_method(cPlot, "translate", CASTHOOK(shoes_plot_translate), 2);
+ rb_define_method(cPlot, "rotate", CASTHOOK(shoes_plot_rotate), 1);
+ rb_define_method(cPlot, "scale", CASTHOOK(shoes_plot_scale), -1);
+ rb_define_method(cPlot, "skew", CASTHOOK(shoes_plot_skew), -1);
+
+ cChartSeries = rb_define_class_under(cTypes, "chart_series", rb_cObject); // 3.3.2
+ rb_define_alloc_func(cChartSeries, shoes_chart_series_alloc);
+
+ // simple getters/setters
+ rb_define_method(cChartSeries, "values", CASTHOOK(shoes_chart_series_values), 0);
+ rb_define_method(cChartSeries, "labels", CASTHOOK(shoes_chart_series_labels), 0);
+ rb_define_method(cChartSeries, "min", CASTHOOK(shoes_chart_series_min), 0);
+ rb_define_method(cChartSeries, "min=", CASTHOOK(shoes_chart_series_min_set), 1);
+ rb_define_method(cChartSeries, "max", CASTHOOK(shoes_chart_series_max), 0);
+ rb_define_method(cChartSeries, "max=", CASTHOOK(shoes_chart_series_max_set), 1);
+ rb_define_method(cChartSeries, "name", CASTHOOK(shoes_chart_series_name), 0);
+ rb_define_method(cChartSeries, "desc", CASTHOOK(shoes_chart_series_desc), 0);
+ rb_define_method(cChartSeries, "desc=", CASTHOOK(shoes_chart_series_desc_set), 1);
+ rb_define_method(cChartSeries, "color", CASTHOOK(shoes_chart_series_color), 0);
+ rb_define_method(cChartSeries, "color=", CASTHOOK(shoes_chart_series_color_set), 1);
+ rb_define_method(cChartSeries, "strokewidth", CASTHOOK(shoes_chart_series_strokewidth), 0);
+ rb_define_method(cChartSeries, "strokewidth=", CASTHOOK(shoes_chart_series_strokewidth_set), 1);
+ rb_define_method(cChartSeries, "points", CASTHOOK(shoes_chart_series_points), 0);
+ rb_define_method(cChartSeries, "points=", CASTHOOK(shoes_chart_series_points_set), 1);
+
+ // more complcated methods
+ rb_define_method(cChartSeries, "at", CASTHOOK(shoes_chart_series_get), 1);
+ rb_define_method(cChartSeries, "get", CASTHOOK(shoes_chart_series_get), 1);
+ rb_define_method(cChartSeries, "set", CASTHOOK(shoes_chart_series_set), 2);
+
+ RUBY_M("+plot", plot, -1);
+ RUBY_M("+chart_series", chart_series, -1);
+}
+
+// canvas
+VALUE shoes_canvas_plot(int argc, VALUE *argv, VALUE self) {
+ VALUE widget;
+
+ SETUP_CANVAS();
+
+ widget = shoes_plot_new(argc, argv, self);
+ shoes_add_ele(canvas, widget);
+
+ return widget;
+}
+
+VALUE shoes_canvas_chart_series(int argc, VALUE *argv, VALUE self) {
+ SETUP_CANVAS();
+
+ return shoes_chart_series_new(argc, argv, self);
+}
\ No newline at end of file
diff --git a/shoes/types/plot.h b/shoes/types/plot.h
new file mode 100644
index 00000000..a2e43eca
--- /dev/null
+++ b/shoes/types/plot.h
@@ -0,0 +1,26 @@
+#include "shoes/ruby.h"
+#include "shoes/canvas.h"
+#include "shoes/app.h"
+#include "shoes/internal.h"
+#include "shoes/world.h"
+#include "shoes/native/native.h"
+
+#ifndef SHOES_PLOT_TYPE_H
+#define SHOES_PLOT_TYPE_H
+
+/* extern variables necessary to communicate with other parts of Shoes */
+extern VALUE cShoes, cApp, cTypes, cCanvas, cWidget;
+extern shoes_app _shoes_app;
+
+// native forward declarations
+
+/* each widget should have its own init function */
+void shoes_plot_init();
+
+// ruby
+
+// canvas
+VALUE shoes_canvas_plot(int argc, VALUE *argv, VALUE self);
+VALUE shoes_canvas_chart_series(int argc, VALUE *argv, VALUE self);
+
+#endif
diff --git a/shoes/types/progress.c b/shoes/types/progress.c
new file mode 100644
index 00000000..a21baeba
--- /dev/null
+++ b/shoes/types/progress.c
@@ -0,0 +1,63 @@
+#include "shoes/types/native.h"
+#include "shoes/types/progress.h"
+
+// ruby
+VALUE cProgress;
+
+FUNC_M("+progress", progress, -1);
+
+void shoes_progress_init() {
+ cProgress = rb_define_class_under(cTypes, "Progress", cNative);
+ rb_define_method(cProgress, "draw", CASTHOOK(shoes_progress_draw), 2);
+ rb_define_method(cProgress, "fraction", CASTHOOK(shoes_progress_get_fraction), 0);
+ rb_define_method(cProgress, "fraction=", CASTHOOK(shoes_progress_set_fraction), 1);
+ rb_define_method(cProgress, "tooltip", CASTHOOK(shoes_control_get_tooltip), 0);
+ rb_define_method(cProgress, "tooltip=", CASTHOOK(shoes_control_set_tooltip), 1);
+
+ RUBY_M("+progress", progress, -1);
+}
+
+// ruby
+VALUE shoes_progress_draw(VALUE self, VALUE c, VALUE actual) {
+ SETUP_CONTROL(0, 0, FALSE);
+
+ if (RTEST(actual)) {
+ if (self_t->ref == NULL) {
+ self_t->ref = shoes_native_progress(self, canvas, &place, self_t->attr, msg);
+ shoes_native_control_position(self_t->ref, &self_t->place, self, canvas, &place);
+ } else
+ shoes_native_control_repaint(self_t->ref, &self_t->place, canvas, &place);
+ }
+
+ FINISH();
+
+ return self;
+}
+
+VALUE shoes_progress_get_fraction(VALUE self) {
+ double perc = 0.;
+ GET_STRUCT(control, self_t);
+ if (self_t->ref != NULL)
+ perc = shoes_native_progress_get_fraction(self_t->ref);
+ return rb_float_new(perc);
+}
+
+VALUE shoes_progress_set_fraction(VALUE self, VALUE _perc) {
+ double perc = min(max(NUM2DBL(_perc), 0.0), 1.0);
+ GET_STRUCT(control, self_t);
+ if (self_t->ref != NULL)
+ shoes_native_progress_set_fraction(self_t->ref, perc);
+ return self;
+}
+
+// canvas
+VALUE shoes_canvas_progress(int argc, VALUE *argv, VALUE self) {
+ rb_arg_list args;
+ VALUE progress;
+ SETUP_CANVAS();
+
+ rb_parse_args(argc, argv, "|h", &args);
+ progress = shoes_control_new(cProgress, args.a[0], self);
+ shoes_add_ele(canvas, progress);
+ return progress;
+}
diff --git a/shoes/types/progress.h b/shoes/types/progress.h
new file mode 100644
index 00000000..ea621a2d
--- /dev/null
+++ b/shoes/types/progress.h
@@ -0,0 +1,34 @@
+#include "shoes/ruby.h"
+#include "shoes/canvas.h"
+#include "shoes/app.h"
+#include "shoes/internal.h"
+#include "shoes/world.h"
+#include "shoes/native/native.h"
+
+#ifndef SHOES_PROGRESS_TYPE_H
+#define SHOES_PROGRESS_TYPE_H
+
+/* extern variables necessary to communicate with other parts of Shoes */
+extern VALUE cShoes, cApp, cTypes, cCanvas, cWidget;
+extern shoes_app _shoes_app;
+
+// forward progress.c's own s_progress, other components are using it.
+SYMBOL_ID(progress);
+
+// native forward declarations
+SHOES_CONTROL_REF shoes_native_progress(VALUE, shoes_canvas *, shoes_place *, VALUE, char *);
+double shoes_native_progress_get_fraction(SHOES_CONTROL_REF);
+void shoes_native_progress_set_fraction(SHOES_CONTROL_REF, double);
+
+/* each widget should have its own init function */
+void shoes_progress_init();
+
+// ruby
+VALUE shoes_progress_draw(VALUE, VALUE, VALUE);
+VALUE shoes_progress_get_fraction(VALUE self);
+VALUE shoes_progress_set_fraction(VALUE self, VALUE _perc);
+
+// canvas
+VALUE shoes_canvas_progress(int, VALUE *, VALUE);
+
+#endif
diff --git a/shoes/types/radio.c b/shoes/types/radio.c
new file mode 100644
index 00000000..591e613c
--- /dev/null
+++ b/shoes/types/radio.c
@@ -0,0 +1,122 @@
+#include "shoes/types/native.h"
+#include "shoes/types/radio.h"
+
+// ruby
+VALUE cRadio;
+
+FUNC_M("+radio", radio, -1);
+
+void shoes_radio_init() {
+ cRadio = rb_define_class_under(cTypes, "Radio", cNative);
+ rb_define_method(cRadio, "draw", CASTHOOK(shoes_radio_draw), 2);
+ rb_define_method(cRadio, "checked?", CASTHOOK(shoes_check_is_checked), 0);
+ rb_define_method(cRadio, "checked=", CASTHOOK(shoes_check_set_checked_m), 1);
+ rb_define_method(cRadio, "click", CASTHOOK(shoes_control_click), -1);
+ rb_define_method(cRadio, "tooltip", CASTHOOK(shoes_control_get_tooltip), 0);
+ rb_define_method(cRadio, "tooltip=", CASTHOOK(shoes_control_set_tooltip), 1);
+
+ RUBY_M("+radio", radio, -1);
+}
+
+// ruby
+VALUE shoes_radio_draw(VALUE self, VALUE c, VALUE actual) {
+ SETUP_CONTROL(0, 20, FALSE);
+
+ if (RTEST(actual)) {
+ if (self_t->ref == NULL) {
+ VALUE group = ATTR(self_t->attr, group);
+ if (NIL_P(group)) group = c;
+
+ VALUE glist = shoes_hash_get(canvas->app->groups, group);
+#ifdef SHOES_FORCE_RADIO // aka OSX - create group before realizing widget
+ if (NIL_P(glist))
+ canvas->app->groups = shoes_hash_set(canvas->app->groups, group, (glist = rb_ary_new3(1, self)));
+ else
+ rb_ary_push(glist, self);
+ glist = shoes_hash_get(canvas->app->groups, group);
+ self_t->ref = shoes_native_radio(self, canvas, &place, self_t->attr, glist);
+#else
+ self_t->ref = shoes_native_radio(self, canvas, &place, self_t->attr, glist);
+
+ if (NIL_P(glist))
+ canvas->app->groups = shoes_hash_set(canvas->app->groups, group, (glist = rb_ary_new3(1, self)));
+ else
+ rb_ary_push(glist, self);
+#endif
+ if (RTEST(ATTR(self_t->attr, checked))) shoes_native_check_set(self_t->ref, Qtrue);
+ shoes_control_check_styles(self_t);
+ shoes_native_control_position(self_t->ref, &self_t->place, self, canvas, &place);
+ } else
+ shoes_native_control_repaint(self_t->ref, &self_t->place, canvas, &place);
+ }
+
+ FINISH();
+
+ return self;
+}
+
+VALUE shoes_check_set_checked_m(VALUE self, VALUE on) {
+#ifdef SHOES_FORCE_RADIO
+ if (RTEST(on)) {
+ VALUE glist = shoes_radio_group(self);
+
+ if (!NIL_P(glist)) {
+ long i;
+ for (i = 0; i < RARRAY_LEN(glist); i++) {
+ VALUE ele = rb_ary_entry(glist, i);
+ shoes_check_set_checked(ele, ele == self ? Qtrue : Qfalse);
+ }
+ } else {
+ shoes_check_set_checked(self, on);
+ }
+ return on;
+ }
+#endif
+ shoes_check_set_checked(self, on);
+ return on;
+}
+
+#ifdef SHOES_FORCE_RADIO
+void shoes_radio_button_click(VALUE control) {
+ shoes_check_set_checked_m(control, Qtrue);
+}
+#endif
+
+VALUE shoes_radio_group(VALUE self) {
+ GET_STRUCT(control, self_t);
+ if (!NIL_P(self_t->parent)) {
+ shoes_canvas *canvas;
+ VALUE group = ATTR(self_t->attr, group);
+ if (NIL_P(group)) group = self_t->parent;
+ Data_Get_Struct(self_t->parent, shoes_canvas, canvas);
+ return shoes_hash_get(canvas->app->groups, group);
+ }
+ return Qnil;
+}
+
+// canvas
+VALUE shoes_canvas_radio(int argc, VALUE *argv, VALUE self) {
+ rb_arg_list args;
+ VALUE group = Qnil, attr = Qnil, radio;
+ SETUP_CANVAS();
+
+ switch (rb_parse_args(argc, argv, "h,o|h,", &args)) {
+ case 1:
+ attr = args.a[0];
+ break;
+
+ case 2:
+ group = args.a[0];
+ attr = args.a[1];
+ break;
+ }
+
+ if (!NIL_P(group))
+ ATTRSET(attr, group, group);
+ if (rb_block_given_p())
+ ATTRSET(attr, click, rb_block_proc());
+
+ radio = shoes_control_new(cRadio, attr, self);
+ shoes_add_ele(canvas, radio);
+ return radio;
+}
diff --git a/shoes/types/radio.h b/shoes/types/radio.h
new file mode 100644
index 00000000..97c399ff
--- /dev/null
+++ b/shoes/types/radio.h
@@ -0,0 +1,41 @@
+#include "shoes/ruby.h"
+#include "shoes/canvas.h"
+#include "shoes/app.h"
+#include "shoes/internal.h"
+#include "shoes/world.h"
+#include "shoes/native/native.h"
+
+#ifndef SHOES_RADIO_TYPE_H
+#define SHOES_RADIO_TYPE_H
+
+/* extern variables necessary to communicate with other parts of Shoes */
+extern VALUE cShoes, cApp, cTypes, cCanvas, cWidget;
+extern shoes_app _shoes_app;
+
+SYMBOL_EXTERN(checked);
+
+/* Should be automatically available but ruby.c is not sharing enough information */
+extern VALUE shoes_control_click(int argc, VALUE *argv, VALUE self);
+
+// native forward declarations
+SHOES_CONTROL_REF shoes_native_radio(VALUE self, shoes_canvas *canvas, shoes_place *place, VALUE attr, VALUE group);
+
+VALUE cRadio;
+
+/* each widget should have its own init function */
+void shoes_radio_init();
+
+// ruby
+VALUE shoes_radio_draw(VALUE self, VALUE c, VALUE actual);
+VALUE shoes_check_set_checked_m(VALUE self, VALUE on);
+void shoes_radio_button_click(VALUE control);
+VALUE shoes_radio_group(VALUE self);
+
+// reuse code from check type
+extern VALUE shoes_check_is_checked(VALUE self);
+extern VALUE shoes_check_set_checked(VALUE self, VALUE on);
+
+// canvas
+VALUE shoes_canvas_radio(int, VALUE *, VALUE);
+
+#endif
diff --git a/shoes/types/shape.c b/shoes/types/shape.c
new file mode 100644
index 00000000..ab297018
--- /dev/null
+++ b/shoes/types/shape.c
@@ -0,0 +1,358 @@
+#include "shoes/types/color.h"
+#include "shoes/types/image.h"
+#include "shoes/types/pattern.h"
+#include "shoes/types/shape.h"
+
+// ruby
+VALUE cShape;
+
+FUNC_M("+shape", shape, -1);
+
+PLACE_COMMON(shape);
+CLASS_COMMON2(shape);
+TRANS_COMMON(shape, 1);
+
+void shoes_shape_init() {
+ cShape = rb_define_class_under(cTypes, "Shape", rb_cObject);
+
+ rb_define_alloc_func(cShape, shoes_shape_alloc);
+
+ rb_define_method(cShape, "app", CASTHOOK(shoes_canvas_get_app), 0);
+ rb_define_method(cShape, "displace", CASTHOOK(shoes_shape_displace), 2);
+ rb_define_method(cShape, "draw", CASTHOOK(shoes_shape_draw), 2);
+ rb_define_method(cShape, "move", CASTHOOK(shoes_shape_move), 2);
+ rb_define_method(cShape, "parent", CASTHOOK(shoes_shape_get_parent), 0);
+ rb_define_method(cShape, "top", CASTHOOK(shoes_shape_get_top), 0);
+ rb_define_method(cShape, "left", CASTHOOK(shoes_shape_get_left), 0);
+ rb_define_method(cShape, "width", CASTHOOK(shoes_shape_get_width), 0);
+ rb_define_method(cShape, "height", CASTHOOK(shoes_shape_get_height), 0);
+ rb_define_method(cShape, "remove", CASTHOOK(shoes_basic_remove), 0);
+ rb_define_method(cShape, "style", CASTHOOK(shoes_shape_style), -1);
+ rb_define_method(cShape, "hide", CASTHOOK(shoes_shape_hide), 0);
+ rb_define_method(cShape, "show", CASTHOOK(shoes_shape_show), 0);
+ rb_define_method(cShape, "toggle", CASTHOOK(shoes_shape_toggle), 0);
+ rb_define_method(cShape, "click", CASTHOOK(shoes_shape_click), -1);
+ rb_define_method(cShape, "release", CASTHOOK(shoes_shape_release), -1);
+ rb_define_method(cShape, "hover", CASTHOOK(shoes_shape_hover), -1);
+ rb_define_method(cShape, "leave", CASTHOOK(shoes_shape_leave), -1);
+
+ RUBY_M("+shape", shape, -1);
+}
+
+// ruby
+VALUE shoes_shape_draw(VALUE self, VALUE c, VALUE actual) {
+ shoes_place place;
+ shoes_canvas *canvas;
+ GET_STRUCT(shape, self_t);
+ if (ATTR(self_t->attr, hidden) == Qtrue) return self;
+ Data_Get_Struct(self_t->parent, shoes_canvas, canvas);
+ shoes_place_exact(&place, self_t->attr, CPX(canvas), CPY(canvas));
+
+ if (RTEST(actual))
+ shoes_shape_sketch(CCR(canvas), self_t->name, &place, self_t->st, self_t->attr, self_t->line, 1);
+
+ self_t->place = place;
+ return self;
+}
+
+void shoes_shape_mark(shoes_shape *path) {
+ rb_gc_mark_maybe(path->parent);
+ rb_gc_mark_maybe(path->attr);
+}
+
+void shoes_shape_free(shoes_shape *path) {
+ shoes_transform_release(path->st);
+ if (path->line != NULL) cairo_path_destroy(path->line);
+ RUBY_CRITICAL(free(path));
+}
+
+VALUE shoes_shape_attr(int argc, VALUE *argv, int syms, ...) {
+ int i;
+ va_list args;
+ VALUE hsh = Qnil;
+ va_start(args, syms);
+ if (argc < 1) hsh = rb_hash_new();
+ else if (rb_obj_is_kind_of(argv[argc - 1], rb_cHash)) hsh = argv[argc - 1];
+ for (i = 0; i < syms; i++) {
+ ID sym = va_arg(args, ID);
+ if (argc > i && !rb_obj_is_kind_of(argv[i], rb_cHash))
+ hsh = shoes_hash_set(hsh, sym, argv[i]);
+ }
+ va_end(args);
+ return hsh;
+}
+
+unsigned char shoes_shape_check(cairo_t *cr, shoes_place *place) {
+ double ox1 = place->ix, oy1 = place->iy, ox2 = place->ix + place->iw, oy2 = place->iy + place->ih;
+ double cx1, cy1, cx2, cy2;
+ cairo_clip_extents(cr, &cx1, &cy1, &cx2, &cy2);
+ if (place->iw < 0) ox1 = place->ix - (ox2 = -place->iw);
+ if (place->ih < 0) oy1 = place->iy - (oy2 = -place->ih);
+ if (cy2 - cy1 == 1.0 && cx2 - cx1 == 1.0) return 1;
+ if ((ox1 < cx1 && ox2 < cx1) || (oy1 < cy1 && oy2 < cy1) ||
+ (ox1 > cx2 && ox2 > cx2) || (oy1 > cy2 && oy2 > cy2)) return 0;
+ return 1;
+}
+
+void shoes_shape_sketch(cairo_t *cr, ID name, shoes_place *place, shoes_transform *st, VALUE attr, cairo_path_t* line, unsigned char draw) {
+ double sw = ATTR2(dbl, attr, strokewidth, 1.);
+ if (name == s_oval && place->w > 0 && place->h > 0) {
+ shoes_apply_transformation(cr, st, place, 1);
+ if (!shoes_shape_check(cr, place))
+ return shoes_undo_transformation(cr, st, place, 1);
+ if (draw) cairo_new_path(cr);
+ cairo_translate(cr, (place->x * 1.) + (place->w / 2.), (place->y * 1.) + (place->h / 2.));
+ cairo_scale(cr, place->w / 2., place->h / 2.);
+ cairo_arc(cr, 0., 0., 1., 0., SHOES_PIM2);
+ cairo_close_path(cr);
+ shoes_undo_transformation(cr, st, place, 1);
+ } else if (name == s_arc && place->w > 0 && place->h > 0) {
+ double a1 = ATTR2(dbl, attr, angle1, 0.);
+ double a2 = ATTR2(dbl, attr, angle2, 0.);
+ shoes_apply_transformation(cr, st, place, 0);
+ if (!shoes_shape_check(cr, place))
+ return shoes_undo_transformation(cr, st, place, 0);
+ if (draw) cairo_new_path(cr);
+ shoes_cairo_arc(cr, SWPOS(place->x), SWPOS(place->y),
+ place->w * 1., place->h * 1., a1, a2);
+ shoes_undo_transformation(cr, st, place, 0);
+ } else if (name == s_rect && place->w > 0 && place->h > 0) {
+ double cv = ATTR2(dbl, attr, curve, 0.);
+ shoes_apply_transformation(cr, st, place, 0);
+ if (!shoes_shape_check(cr, place))
+ return shoes_undo_transformation(cr, st, place, 0);
+ if (draw) cairo_new_path(cr);
+ shoes_cairo_rect(cr, SWPOS(place->x), SWPOS(place->y), place->w * 1., place->h * 1., cv);
+ shoes_undo_transformation(cr, st, place, 0);
+ } else if (name == s_line) {
+ shoes_apply_transformation(cr, st, place, 0);
+ if (!shoes_shape_check(cr, place))
+ return shoes_undo_transformation(cr, st, place, 0);
+ cairo_move_to(cr, SWPOS(place->ix), SWPOS(place->iy));
+ cairo_line_to(cr, SWPOS(place->ix + place->iw), SWPOS(place->iy + place->ih));
+ shoes_undo_transformation(cr, st, place, 0);
+ } else if (name == s_arrow && place->w > 0) {
+ double h, tip, x;
+ x = place->x + (place->w / 2.);
+ h = place->w * 0.8;
+ place->h = ROUND(h);
+ tip = place->w * 0.42;
+
+ shoes_apply_transformation(cr, st, place, 0);
+ if (!shoes_shape_check(cr, place))
+ return shoes_undo_transformation(cr, st, place, 0);
+ if (draw) cairo_new_path(cr);
+ cairo_move_to(cr, SWPOS(x), SWPOS(place->y));
+ cairo_rel_line_to(cr, -tip, +(h*0.5));
+ cairo_rel_line_to(cr, 0, -(h*0.25));
+ cairo_rel_line_to(cr, -(place->w-tip), 0);
+ cairo_rel_line_to(cr, 0, -(h*0.5));
+ cairo_rel_line_to(cr, +(place->w-tip), 0);
+ cairo_rel_line_to(cr, 0, -(h*0.25));
+ cairo_close_path(cr);
+ shoes_undo_transformation(cr, st, place, 0);
+ } else if (name == s_star) {
+ int i, points;
+ double outer, inner, angle, r;
+ points = ATTR2(int, attr, points, 10);
+ outer = ATTR2(dbl, attr, outer, 100.);
+ inner = ATTR2(dbl, attr, inner, 50.);
+
+ if (outer > 0) {
+ place->w = place->h = ROUND(outer);
+ shoes_apply_transformation(cr, st, place, 0);
+ if (!shoes_shape_check(cr, place))
+ return shoes_undo_transformation(cr, st, place, 0);
+ if (draw) cairo_new_path(cr);
+ cairo_move_to(cr, place->x * 1., (place->y * 1.) + outer);
+ for (i = 1; i <= points * 2; i++) {
+ angle = (i * SHOES_PI) / (points * 1.);
+ r = (i % 2 == 0 ? outer : inner);
+ cairo_line_to(cr, place->x + r * sin(angle), place->y + r * cos(angle));
+ }
+ cairo_close_path(cr);
+ shoes_undo_transformation(cr, st, place, 0);
+ }
+ } else if (name == s_shape) {
+ shoes_apply_transformation(cr, st, place, 0);
+ if (!shoes_shape_check(cr, place))
+ return shoes_undo_transformation(cr, st, place, 0);
+ cairo_translate(cr, SWPOS(place->x), SWPOS(place->y));
+ cairo_append_path(cr, line);
+ shoes_undo_transformation(cr, st, place, 0);
+ } else return;
+
+ if (draw) {
+ ID cap = s_rect;
+ if (!NIL_P(ATTR(attr, cap))) cap = SYM2ID(ATTR(attr, cap));
+ ID dash = s_nodot;
+ if (!NIL_P(ATTR(attr, dash))) dash = SYM2ID(ATTR(attr, dash));
+ PATH_OUT(cr, attr, *place, sw, cap, dash, fill, cairo_fill_preserve);
+ PATH_OUT(cr, attr, *place, sw, cap, dash, stroke, cairo_stroke);
+ }
+}
+
+VALUE shoes_shape_new(VALUE parent, ID name, VALUE attr, shoes_transform *st, cairo_path_t *line) {
+ shoes_shape *path;
+ shoes_canvas *canvas;
+ VALUE obj = shoes_shape_alloc(cShape);
+ Data_Get_Struct(obj, shoes_shape, path);
+ Data_Get_Struct(parent, shoes_canvas, canvas);
+ path->parent = parent;
+ path->attr = attr;
+ path->name = name;
+ path->st = shoes_transform_touch(st);
+ path->line = line;
+ COPY_PENS(path->attr, canvas->attr);
+ return obj;
+}
+
+VALUE shoes_shape_alloc(VALUE klass) {
+ VALUE obj;
+ shoes_shape *shape = SHOE_ALLOC(shoes_shape);
+ SHOE_MEMZERO(shape, shoes_shape, 1);
+ obj = Data_Wrap_Struct(klass, shoes_shape_mark, shoes_shape_free, shape);
+ shape->attr = Qnil;
+ shape->parent = Qnil;
+ shape->line = NULL;
+ return obj;
+}
+
+VALUE shoes_shape_motion(VALUE self, int x, int y, char *touch) {
+ char h = 0;
+ VALUE click;
+ GET_STRUCT(shape, self_t);
+
+ click = ATTR(self_t->attr, click);
+
+ if (IS_INSIDE(self_t, x, y)) {
+ cairo_bool_t in_shape;
+ cairo_t *cr = cairo_create(cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 1, 1));
+ // if (self_t->line != NULL)
+ // {
+ // cairo_new_path(cr);
+ // cairo_append_path(cr, self_t->line);
+ // }
+ // else
+ shoes_shape_sketch(cr, self_t->name, &self_t->place, self_t->st, self_t->attr, self_t->line, 0);
+ in_shape = cairo_in_fill(cr, x, y);
+ cairo_destroy(cr);
+
+ if (in_shape) {
+ if (!NIL_P(click)) {
+ shoes_canvas *canvas;
+ Data_Get_Struct(self_t->parent, shoes_canvas, canvas);
+ shoes_app_cursor(canvas->app, s_link);
+ }
+ h = 1;
+ }
+ }
+
+ CHECK_HOVER(self_t, h, touch);
+
+ return h ? click : Qnil;
+ return Qnil;
+}
+
+VALUE shoes_shape_send_click(VALUE self, int button, int x, int y) {
+ VALUE v = Qnil;
+
+ if (button > 0) {
+ GET_STRUCT(shape, self_t);
+ v = shoes_shape_motion(self, x, y, NULL);
+ if (self_t->hover & HOVER_MOTION)
+ self_t->hover = HOVER_MOTION | HOVER_CLICK;
+ }
+
+ return v;
+}
+
+void shoes_shape_send_release(VALUE self, int button, int x, int y) {
+ GET_STRUCT(shape, self_t);
+ if (button > 0 && (self_t->hover & HOVER_CLICK)) {
+ VALUE proc = ATTR(self_t->attr, release);
+ self_t->hover ^= HOVER_CLICK;
+ if (!NIL_P(proc))
+ shoes_safe_block(self, proc, rb_ary_new3(3, INT2NUM(button), INT2NUM(x), INT2NUM(y)));
+ }
+}
+
+// canvas
+VALUE shoes_canvas_shape(int argc, VALUE *argv, VALUE self) {
+ int x;
+ double x1, y1, x2, y2;
+ cairo_t *shape = NULL;
+ cairo_path_t *line = NULL;
+
+ SETUP_SHAPE();
+
+ shape = canvas->shape;
+ VALUE attr = shoes_shape_attr(argc, argv, 2, s_left, s_top);
+ canvas->shape = cairo_create(cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 1, 1));
+ cairo_move_to(canvas->shape, 0, 0);
+ if (rb_block_given_p()) rb_funcall(rb_block_proc(), s_call, 0);
+
+#if CAIRO_VERSION_MAJOR == 1 && CAIRO_VERSION_MINOR <= 4
+ cairo_fill_extents(canvas->shape, &x1, &y1, &x2, &y2);
+#else
+ cairo_path_extents(canvas->shape, &x1, &y1, &x2, &y2);
+#endif
+ x = ROUND(x2 - x1);
+ ATTRSET(attr, width, INT2NUM(x));
+ x = ROUND(y2 - y1);
+ ATTRSET(attr, height, INT2NUM(x));
+ line = cairo_copy_path(canvas->shape);
+ canvas->shape = shape;
+ return shoes_add_shape(self, s_shape, attr, line);
+}
+
+VALUE shoes_add_shape(VALUE self, ID name, VALUE attr, cairo_path_t *line) {
+ if (rb_obj_is_kind_of(self, cImage)) {
+ SETUP_IMAGE();
+ shoes_shape_sketch(image->cr, name, &place, NULL, attr, line, 1);
+ return self;
+ }
+
+ SETUP_CANVAS();
+ if (canvas->shape != NULL) {
+ shoes_place place;
+ shoes_place_exact(&place, attr, 0, 0);
+ cairo_new_sub_path(canvas->shape);
+ shoes_shape_sketch(canvas->shape, name, &place, canvas->st, attr, line, 0);
+ return self;
+ }
+
+ return shoes_add_ele(canvas, shoes_shape_new(self, name, attr, canvas->st, line));
+}
+
+VALUE shoes_canvas_arc(int argc, VALUE *argv, VALUE self) {
+ VALUE attr = shoes_shape_attr(argc, argv, 6, s_left, s_top, s_width, s_height, s_angle1, s_angle2);
+ return shoes_add_shape(self, s_arc, attr, NULL);
+}
+
+VALUE shoes_canvas_rect(int argc, VALUE *argv, VALUE self) {
+ VALUE attr = shoes_shape_attr(argc, argv, 5, s_left, s_top, s_width, s_height, s_curve);
+ return shoes_add_shape(self, s_rect, attr, NULL);
+}
+
+VALUE shoes_canvas_oval(int argc, VALUE *argv, VALUE self) {
+ VALUE attr = shoes_shape_attr(argc, argv, 4, s_left, s_top, s_width, s_height);
+ //VALUE attr = shoes_shape_attr(argc, argv, 3, s_left, s_top, s_radius);
+ //rb_warn("shoes_canvas_oval: %s\n", RSTRING_PTR(rb_inspect(attr)));
+ return shoes_add_shape(self, s_oval, attr, NULL);
+}
+
+VALUE shoes_canvas_line(int argc, VALUE *argv, VALUE self) {
+ VALUE attr = shoes_shape_attr(argc, argv, 4, s_left, s_top, s_right, s_bottom);
+ return shoes_add_shape(self, s_line, attr, NULL);
+}
+
+VALUE shoes_canvas_arrow(int argc, VALUE *argv, VALUE self) {
+ VALUE attr = shoes_shape_attr(argc, argv, 3, s_left, s_top, s_width);
+ return shoes_add_shape(self, s_arrow, attr, NULL);
+}
+
+VALUE shoes_canvas_star(int argc, VALUE *argv, VALUE self) {
+ VALUE attr = shoes_shape_attr(argc, argv, 5, s_left, s_top, s_points, s_outer, s_inner);
+ return shoes_add_shape(self, s_star, attr, NULL);
+}
\ No newline at end of file
diff --git a/shoes/types/shape.h b/shoes/types/shape.h
new file mode 100644
index 00000000..857a19c8
--- /dev/null
+++ b/shoes/types/shape.h
@@ -0,0 +1,57 @@
+#include "shoes/ruby.h"
+#include "shoes/canvas.h"
+#include "shoes/app.h"
+#include "shoes/internal.h"
+#include "shoes/world.h"
+#include "shoes/native/native.h"
+
+#ifndef SHOES_SHAPE_TYPE_H
+#define SHOES_SHAPE_TYPE_H
+
+/* extern variables necessary to communicate with other parts of Shoes */
+extern VALUE cShoes, cApp, cTypes, cCanvas, cWidget;
+extern shoes_app _shoes_app;
+
+VALUE cShape;
+
+SYMBOL_ID(shape);
+
+typedef struct {
+ VALUE parent;
+ VALUE attr;
+ shoes_place place;
+ ID name;
+ char hover;
+ cairo_path_t *line;
+ shoes_transform *st;
+} shoes_shape;
+
+// native forward declarations
+
+/* each widget should have its own init function */
+void shoes_shape_init();
+
+// ruby
+VALUE shoes_shape_draw(VALUE self, VALUE c, VALUE actual);
+void shoes_shape_mark(shoes_shape *path);
+void shoes_shape_free(shoes_shape *path);
+VALUE shoes_shape_attr(int argc, VALUE *argv, int syms, ...);
+unsigned char shoes_shape_check(cairo_t *cr, shoes_place *place);
+void shoes_shape_sketch(cairo_t *cr, ID name, shoes_place *place, shoes_transform *st, VALUE attr, cairo_path_t* line, unsigned char draw);
+VALUE shoes_shape_new(VALUE parent, ID name, VALUE attr, shoes_transform *st, cairo_path_t *line);
+VALUE shoes_shape_alloc(VALUE klass);
+VALUE shoes_shape_motion(VALUE self, int x, int y, char *touch);
+VALUE shoes_shape_send_click(VALUE self, int button, int x, int y);
+void shoes_shape_send_release(VALUE self, int button, int x, int y);
+
+// canvas
+VALUE shoes_canvas_shape(int argc, VALUE *argv, VALUE self);
+VALUE shoes_add_shape(VALUE self, ID name, VALUE attr, cairo_path_t *line);
+VALUE shoes_canvas_arc(int argc, VALUE *argv, VALUE self);
+VALUE shoes_canvas_rect(int argc, VALUE *argv, VALUE self);
+VALUE shoes_canvas_oval(int argc, VALUE *argv, VALUE self);
+VALUE shoes_canvas_line(int argc, VALUE *argv, VALUE self);
+VALUE shoes_canvas_arrow(int argc, VALUE *argv, VALUE self);
+VALUE shoes_canvas_star(int argc, VALUE *argv, VALUE self);
+
+#endif
diff --git a/shoes/types/slider.c b/shoes/types/slider.c
new file mode 100644
index 00000000..bddaeb81
--- /dev/null
+++ b/shoes/types/slider.c
@@ -0,0 +1,74 @@
+#include "shoes/types/native.h"
+#include "shoes/types/slider.h"
+
+// ruby
+VALUE cSlider;
+
+FUNC_M("+slider", slider, -1);
+
+void shoes_slider_init() {
+ cSlider = rb_define_class_under(cTypes, "Slider", cNative);
+ rb_define_method(cSlider, "draw", CASTHOOK(shoes_slider_draw), 2);
+ rb_define_method(cSlider, "fraction", CASTHOOK(shoes_slider_get_fraction), 0);
+ rb_define_method(cSlider, "fraction=", CASTHOOK(shoes_slider_set_fraction), 1);
+ rb_define_method(cSlider, "change", CASTHOOK(shoes_control_change), -1);
+ rb_define_method(cSlider, "tooltip", CASTHOOK(shoes_control_get_tooltip), 0);
+ rb_define_method(cSlider, "tooltip=", CASTHOOK(shoes_control_set_tooltip), 1);
+
+ RUBY_M("+slider", slider, -1);
+}
+
+VALUE shoes_slider_draw(VALUE self, VALUE c, VALUE actual) {
+ SETUP_CONTROL(0, 0, FALSE);
+
+ if (RTEST(actual)) {
+ if (self_t->ref == NULL) {
+ self_t->ref = shoes_native_slider(self, canvas, &place, self_t->attr, msg);
+ shoes_control_check_styles(self_t);
+ if (RTEST(ATTR(self_t->attr, fraction))) shoes_native_slider_set_fraction(self_t->ref, NUM2DBL(ATTR(self_t->attr, fraction)));
+ shoes_native_control_position(self_t->ref, &self_t->place, self, canvas, &place);
+ } else
+ shoes_native_control_repaint(self_t->ref, &self_t->place, canvas, &place);
+ }
+
+ FINISH();
+
+ return self;
+}
+
+VALUE shoes_slider_get_fraction(VALUE self) {
+ double perc = 0.;
+ GET_STRUCT(control, self_t);
+ if (self_t->ref != NULL)
+ perc = shoes_native_slider_get_fraction(self_t->ref);
+
+ return rb_float_new(perc);
+}
+
+VALUE shoes_slider_set_fraction(VALUE self, VALUE _perc) {
+ double perc = min(max(NUM2DBL(_perc), 0.0), 1.0);
+
+ GET_STRUCT(control, self_t);
+ if (self_t->ref != NULL)
+ shoes_native_slider_set_fraction(self_t->ref, perc);
+
+ return self;
+}
+
+// canvas
+VALUE shoes_canvas_slider(int argc, VALUE *argv, VALUE self) {
+ rb_arg_list args;
+ VALUE slider;
+
+ SETUP_CANVAS();
+
+ rb_parse_args(argc, argv, "|h&", &args);
+
+ if (!NIL_P(args.a[1]))
+ ATTRSET(args.a[0], change, args.a[1]);
+
+ slider = shoes_control_new(cSlider, args.a[0], self);
+ shoes_add_ele(canvas, slider);
+
+ return slider;
+}
diff --git a/shoes/types/slider.h b/shoes/types/slider.h
new file mode 100644
index 00000000..ad49ea61
--- /dev/null
+++ b/shoes/types/slider.h
@@ -0,0 +1,34 @@
+#include "shoes/ruby.h"
+#include "shoes/canvas.h"
+#include "shoes/app.h"
+#include "shoes/internal.h"
+#include "shoes/world.h"
+#include "shoes/native/native.h"
+
+#ifndef SHOES_SLIDER_TYPE_H
+#define SHOES_SLIDER_TYPE_H
+
+/* extern variables necessary to communicate with other parts of Shoes */
+extern VALUE cShoes, cApp, cTypes, cCanvas, cWidget;
+extern shoes_app _shoes_app;
+
+/* Should be automatically available but ruby.c is not sharing enough information */
+extern VALUE shoes_control_change(int argc, VALUE *argv, VALUE self);
+
+// native forward declarations
+extern SHOES_CONTROL_REF shoes_native_slider(VALUE, shoes_canvas *, shoes_place *, VALUE, char *);
+extern double shoes_native_slider_get_fraction(SHOES_CONTROL_REF);
+extern void shoes_native_slider_set_fraction(SHOES_CONTROL_REF, double);
+
+/* each widget should have its own init function */
+void shoes_slider_init();
+
+// ruby
+VALUE shoes_slider_draw(VALUE self, VALUE c, VALUE actual);
+VALUE shoes_slider_get_fraction(VALUE self);
+VALUE shoes_slider_set_fraction(VALUE self, VALUE _perc);
+
+// canvas
+VALUE shoes_canvas_slider(int, VALUE *, VALUE);
+
+#endif
diff --git a/shoes/types/spinner.c b/shoes/types/spinner.c
new file mode 100644
index 00000000..6ef31e1f
--- /dev/null
+++ b/shoes/types/spinner.c
@@ -0,0 +1,69 @@
+#include "shoes/types/native.h"
+#include "shoes/types/spinner.h"
+
+// ruby
+VALUE cSpinner;
+
+FUNC_M("+spinner", spinner, -1);
+
+void shoes_spinner_init() {
+ cSpinner = rb_define_class_under(cTypes, "Spinner", cNative);
+ rb_define_method(cSpinner, "draw", CASTHOOK(shoes_spinner_draw), 2);
+ rb_define_method(cSpinner, "start", CASTHOOK(shoes_spinner_start), 0);
+ rb_define_method(cSpinner, "stop", CASTHOOK(shoes_spinner_stop),0);
+ rb_define_method(cSpinner, "started?", CASTHOOK(shoes_spinner_started), 0);
+ rb_define_method(cSpinner, "tooltip", CASTHOOK(shoes_control_get_tooltip), 0);
+ rb_define_method(cSpinner, "tooltip=", CASTHOOK(shoes_control_set_tooltip), 1);
+
+ RUBY_M("+spinner", spinner, -1);
+}
+
+// ruby
+VALUE shoes_spinner_draw(VALUE self, VALUE c, VALUE actual) {
+ SETUP_CONTROL(0, 0, FALSE);
+
+ if (RTEST(actual)) {
+ if (self_t->ref == NULL) {
+ self_t->ref = shoes_native_spinner(self, canvas, &place, self_t->attr, msg);
+ shoes_control_check_styles(self_t);
+ shoes_native_control_position(self_t->ref, &self_t->place, self, canvas, &place);
+ } else
+ shoes_native_control_repaint(self_t->ref, &self_t->place, canvas, &place);
+ }
+
+ FINISH();
+
+ return self;
+}
+
+VALUE shoes_spinner_start(VALUE self) {
+ GET_STRUCT(control, self_t);
+ shoes_native_spinner_start(self_t->ref);
+ return self;
+}
+
+VALUE shoes_spinner_stop(VALUE self) {
+ GET_STRUCT(control, self_t);
+ shoes_native_spinner_stop(self_t->ref);
+ return self;
+}
+
+VALUE shoes_spinner_started(VALUE self) {
+ GET_STRUCT(control, self_t);
+ return (shoes_native_spinner_started(self_t->ref) ? Qtrue : Qfalse);
+}
+
+// canvas
+VALUE shoes_canvas_spinner(int argc, VALUE *argv, VALUE self) {
+ rb_arg_list args;
+ VALUE spinner;
+
+ SETUP_CANVAS();
+
+ rb_parse_args(argc, argv, "|h", &args);
+
+ spinner = shoes_control_new(cSpinner, args.a[0], self);
+ shoes_add_ele(canvas, spinner);
+
+ return spinner;
+}
diff --git a/shoes/types/spinner.h b/shoes/types/spinner.h
new file mode 100644
index 00000000..6eb6a01f
--- /dev/null
+++ b/shoes/types/spinner.h
@@ -0,0 +1,33 @@
+#include "shoes/ruby.h"
+#include "shoes/canvas.h"
+#include "shoes/app.h"
+#include "shoes/internal.h"
+#include "shoes/world.h"
+#include "shoes/native/native.h"
+
+#ifndef SHOES_SPINNER_TYPE_H
+#define SHOES_SPINNER_TYPE_H
+
+/* extern variables necessary to communicate with other parts of Shoes */
+extern VALUE cShoes, cApp, cTypes, cCanvas, cWidget;
+extern shoes_app _shoes_app;
+
+// native forward declarations
+extern SHOES_CONTROL_REF shoes_native_spinner(VALUE self, shoes_canvas *canvas, shoes_place *place, VALUE attr, char *msg);
+extern void shoes_native_spinner_start(SHOES_CONTROL_REF ref);
+extern void shoes_native_spinner_stop(SHOES_CONTROL_REF ref);
+extern gboolean shoes_native_spinner_started(SHOES_CONTROL_REF ref);
+
+/* each widget should have its own init function */
+void shoes_spinner_init();
+
+// ruby
+VALUE shoes_spinner_draw(VALUE self, VALUE c, VALUE actual);
+VALUE shoes_spinner_start(VALUE self);
+VALUE shoes_spinner_stop(VALUE self);
+VALUE shoes_spinner_started(VALUE self);
+
+// canvas
+VALUE shoes_canvas_spinner(int argc, VALUE *argv, VALUE self);
+
+#endif
diff --git a/shoes/types/svg.c b/shoes/types/svg.c
new file mode 100644
index 00000000..4645177b
--- /dev/null
+++ b/shoes/types/svg.c
@@ -0,0 +1,744 @@
+/*
+ * svghandle - experimental for 3.3.0
+ * svg (the widget - two different Shoes/Ruby object
+*/
+
+#include
+#include
+#include
+#include
+
+#include "shoes/app.h"
+#include "shoes/canvas.h"
+#include "shoes/ruby.h"
+#include "shoes/internal.h"
+#include "shoes/world.h"
+#include "shoes/native/native.h"
+#include "shoes/version.h"
+#include "shoes/http.h"
+#include "shoes/types/effect.h"
+#include "shoes/types/svg.h"
+
+// ruby
+VALUE cSvg, cSvgHandle;
+
+FUNC_M("+svg", svg, -1);
+FUNC_M("+svghandle", svghandle, -1);
+
+CLASS_COMMON2(svg);
+TRANS_COMMON(svg, 1);
+
+void shoes_svg_init() {
+ // svg is kind of like cImage with different methods
+ // do not call draw from Shoes scripts - just don't do it!
+ cSvg = rb_define_class_under(cTypes, "Svg", rb_cObject);
+ rb_define_alloc_func(cSvg, shoes_svg_alloc);
+ rb_define_method(cSvg, "draw", CASTHOOK(shoes_svg_draw), 2);
+ rb_define_method(cSvg, "preferred_width", CASTHOOK(shoes_svg_preferred_width), 0);
+ rb_define_method(cSvg, "preferred_height", CASTHOOK(shoes_svg_preferred_height),0);
+ rb_define_method(cSvg, "offset_x", CASTHOOK(shoes_svg_get_offsetX),0);
+ rb_define_method(cSvg, "offset_y", CASTHOOK(shoes_svg_get_offsetY),0);
+ rb_define_method(cSvg, "remove", CASTHOOK(shoes_svg_remove), 0);
+ rb_define_method(cSvg, "export", CASTHOOK(shoes_svg_export), 1);
+ rb_define_method(cSvg, "save", CASTHOOK(shoes_svg_save), 1);
+ rb_define_method(cSvg, "handle", CASTHOOK(shoes_svg_get_handle), 0);
+ rb_define_method(cSvg, "handle=", CASTHOOK(shoes_svg_set_handle), 1);
+ rb_define_method(cSvg, "dpi", CASTHOOK(shoes_svg_get_dpi), 0);
+ rb_define_method(cSvg, "dpi=", CASTHOOK(shoes_svg_set_dpi), 1);
+ rb_define_method(cSvg, "style", CASTHOOK(shoes_svg_style), -1);
+ rb_define_method(cSvg, "move", CASTHOOK(shoes_svg_move), 2);
+ rb_define_method(cSvg, "displace", CASTHOOK(shoes_svg_displace), 2);
+ rb_define_method(cSvg, "hide", CASTHOOK(shoes_svg_hide), 0);
+ rb_define_method(cSvg, "show", CASTHOOK(shoes_svg_show), 0);
+ rb_define_method(cSvg, "toggle", CASTHOOK(shoes_svg_toggle), 0);
+ rb_define_method(cSvg, "hidden?", CASTHOOK(shoes_svg_is_hidden), 0);
+ rb_define_method(cSvg, "click", CASTHOOK(shoes_svg_click), -1);
+ rb_define_method(cSvg, "release", CASTHOOK(shoes_svg_release), -1);
+ rb_define_method(cSvg, "hover", CASTHOOK(shoes_svg_hover), -1);
+ rb_define_method(cSvg, "leave", CASTHOOK(shoes_svg_leave), -1);
+ rb_define_method(cSvg, "parent", CASTHOOK(shoes_svg_get_parent), 0);
+ rb_define_method(cSvg, "top", CASTHOOK(shoes_svg_get_actual_top), 0);
+ rb_define_method(cSvg, "left", CASTHOOK(shoes_svg_get_actual_left), 0);
+ rb_define_method(cSvg, "width", CASTHOOK(shoes_svg_get_actual_width), 0);
+ rb_define_method(cSvg, "height", CASTHOOK(shoes_svg_get_actual_height), 0);
+ rb_define_method(cSvg, "group?", CASTHOOK(shoes_svg_has_group), 1);
+ rb_define_method(cSvg, "transform", CASTHOOK(shoes_svg_transform), 1);
+ rb_define_method(cSvg, "translate", CASTHOOK(shoes_svg_translate), 2);
+ rb_define_method(cSvg, "rotate", CASTHOOK(shoes_svg_rotate), 1);
+ rb_define_method(cSvg, "scale", CASTHOOK(shoes_svg_scale), -1);
+ rb_define_method(cSvg, "skew", CASTHOOK(shoes_svg_skew), -1);
+
+ RUBY_M("+svg", svg, -1);
+
+ cSvgHandle = rb_define_class_under(cTypes, "SvgHandle", rb_cObject); // new with 3.3.0
+ rb_define_alloc_func(cSvgHandle, shoes_svghandle_alloc);
+ rb_define_method(cSvgHandle, "width", CASTHOOK(shoes_svghandle_get_width), 0);
+ rb_define_method(cSvgHandle, "height", CASTHOOK(shoes_svghandle_get_height), 0);
+ rb_define_method(cSvgHandle, "group?", CASTHOOK(shoes_svghandle_has_group), 1);
+
+ RUBY_M("+svghandle", svghandle, -1);
+}
+
+// canvas
+VALUE shoes_canvas_svg(int argc, VALUE *argv, VALUE self) {
+ VALUE widget;
+ SETUP_CANVAS();
+ widget = shoes_svg_new(argc, argv, self);
+ shoes_add_ele(canvas, widget);
+ return widget;
+}
+
+VALUE shoes_canvas_svghandle(int argc, VALUE *argv, VALUE self) {
+ VALUE han;
+ SETUP_CANVAS();
+ han = shoes_svghandle_new(argc, argv, self);
+ return han;
+}
+
+// svg
+
+// forward declares in this file
+static int shoes_svg_draw_surface(cairo_t *, shoes_svg *, shoes_place *, int, int);
+
+// alloc some memory for a shoes_svg; We'll protect it from gc
+// out of caution. fingers crossed.
+void shoes_svg_mark(shoes_svg *svg) {
+ rb_gc_mark_maybe(svg->parent);
+ rb_gc_mark_maybe(svg->attr);
+ rb_gc_mark_maybe(svg->svghandle);
+}
+
+static void shoes_svg_free(shoes_svg *svg) {
+ shoes_transform_release(svg->st);
+ RUBY_CRITICAL(SHOE_FREE(svg));
+}
+
+VALUE shoes_svg_alloc(VALUE klass) {
+ VALUE obj;
+ shoes_svg *svg = SHOE_ALLOC(shoes_svg);
+ SHOE_MEMZERO(svg, shoes_svg, 1);
+ obj = Data_Wrap_Struct(klass, shoes_svg_mark, shoes_svg_free, svg);
+ svg->svghandle = Qnil;
+ svg->parent = Qnil;
+ svg->st = NULL;
+ return obj;
+}
+
+void svg_aspect_ratio(int imw, int imh, shoes_svg *self_t, shoes_svghandle *svghan) {
+ double outw = imw * 1.0; // width given to svg()
+ double outh = imh * 1.0; // height given to svg()
+
+ self_t->scalew = outw / svghan->svghdim.width; // don't keep aspect ratio, Fill provided or deduced dimensions
+ self_t->scaleh = outh / svghan->svghdim.height; //
+
+ if (svghan->aspect == 0.0) { // keep aspect ratio
+ self_t->scalew = self_t->scaleh = MIN(outw / svghan->svghdim.width, outh / svghan->svghdim.height);
+
+ } else if (svghan->aspect > 0.0) { // don't keep aspect ratio, User aspect ratio
+ double new_svgdim_height = svghan->svghdim.width / svghan->aspect;
+ double new_svgdim_width = svghan->svghdim.height * svghan->aspect;
+
+ if (outw / new_svgdim_width < outh / new_svgdim_height)
+ self_t->scaleh = self_t->scalew * new_svgdim_height / svghan->svghdim.height;
+ else
+ self_t->scalew = self_t->scaleh * new_svgdim_width / svghan->svghdim.width;
+ }
+}
+
+VALUE shoes_svg_new(int argc, VALUE *argv, VALUE parent) {
+ VALUE attr = Qnil, widthObj, heightObj, svg_string = Qnil;
+ VALUE svghanObj = Qnil;
+ shoes_canvas *canvas;
+ Data_Get_Struct(parent, shoes_canvas, canvas);
+
+ rb_arg_list args;
+// switch (rb_parse_args(argc, argv, "s|h", &args))
+ switch (rb_parse_args(argc, argv, "s|h,o|h", &args)) {
+ case 1:
+ svg_string = args.a[0];
+ attr = args.a[1];
+ break;
+ case 2:
+ // if first arg is an svghandle
+ if (rb_obj_is_kind_of(args.a[0], cSvgHandle)) {
+ svghanObj = args.a[0];
+ attr = args.a[1];
+ } else
+ rb_raise(rb_eArgError, "bad argument, expecting a String or a Shoes::SvgHandle \n");
+ break;
+ }
+ if (NIL_P(attr)) attr = rb_hash_new();
+
+ // get width and height out of hash/attr arg
+ if (RTEST(ATTR(attr, width))) {
+ widthObj = ATTR(attr, width);
+ } else
+ widthObj = RTEST(ATTR(canvas->attr, width)) ? ATTR(canvas->attr, width) : Qnil;
+
+ if ( RTEST(ATTR(attr, height))) {
+ heightObj = ATTR(attr, height);
+ } else
+ heightObj = RTEST(ATTR(canvas->attr, height)) ? ATTR(canvas->attr, height) : Qnil;
+
+ if (NIL_P(svghanObj)) { // likely case
+ if (strstr(RSTRING_PTR(svg_string), "") != NULL) //TODO
+ shoes_hash_set(attr, rb_intern("content"), svg_string);
+ else
+ shoes_hash_set(attr, rb_intern("filename"), svg_string);
+ svghanObj = shoes_svghandle_new(1, &attr, parent);
+ }
+
+ shoes_svghandle *shandle;
+ Data_Get_Struct(svghanObj, shoes_svghandle, shandle);
+
+ // we couldn't find the width/height of the parent canvas, now that we have a rsvg handle,
+ // fallback to original size as defined in the svg file but no more than Shoes.app size
+ if (widthObj == Qnil) {
+ widthObj = INT2NUM(shandle->svghdim.width);
+ widthObj = (shandle->svghdim.width >= canvas->app->width) ?
+ INT2NUM(canvas->app->width) : widthObj;
+ }
+ if (heightObj == Qnil) {
+ heightObj = INT2NUM(shandle->svghdim.height);
+ heightObj = (shandle->svghdim.height >= canvas->app->height) ?
+ INT2NUM(canvas->app->height) : heightObj;
+ }
+ ATTRSET(attr, width, widthObj);
+ ATTRSET(attr, height, heightObj);
+
+ VALUE obj = shoes_svg_alloc(cSvg);
+ shoes_svg *self_t;
+ Data_Get_Struct(obj, shoes_svg, self_t);
+
+ self_t->svghandle = svghanObj;
+ self_t->place.w = NUM2INT(widthObj);
+ self_t->place.h = NUM2INT(heightObj);
+ self_t->parent = parent;
+ self_t->scalew = 0.0;
+ self_t->scaleh = 0.0;
+ self_t->attr = attr;
+ // initialize cairo matrice used in transform methods (rotate, scale, skew, translate)
+ self_t->st = shoes_transform_touch(canvas->st);
+
+ // useless !!?? needs to be confirmed
+// shoes_place place;
+// shoes_place_exact(&place, self_t->attr, 0, 0);
+// if (place.iw < 1) place.w = place.iw;
+// if (place.ih < 1) place.h = place.ih;
+//
+// shoes_svg_draw_surface(self_t->cr, self_t, &place, place.w, place.h);
+
+ return obj;
+}
+
+static int shoes_svg_draw_surface(cairo_t *cr, shoes_svg *self_t, shoes_place *place, int imw, int imh) {
+ shoes_svghandle *svghan;
+ Data_Get_Struct(self_t->svghandle, shoes_svghandle, svghan);
+
+ // calculate aspect ratio only once at initialization
+ if (self_t->scalew == 0.0 && self_t->scaleh == 0.0) {
+ svg_aspect_ratio(imw, imh, self_t, svghan);
+ }
+
+ /* drawing on svg parent's (canvas) surface */
+ // applying any transform : translate, rotate, scale, skew
+ shoes_apply_transformation(cr, self_t->st, place, 0); // cairo_save(cr) inside
+
+ cairo_translate(cr, place->ix + place->dx, place->iy + place->dy);
+
+ if (svghan->subid == NULL) {
+ cairo_scale(cr, self_t->scalew, self_t->scaleh);
+ } else {
+ cairo_scale(cr, self_t->scalew, self_t->scaleh); // order of scaling + translate matters !!!
+ cairo_translate(cr, -svghan->svghpos.x, -svghan->svghpos.y);
+ }
+
+ int result = rsvg_handle_render_cairo_sub(svghan->handle, cr, svghan->subid);
+
+ shoes_undo_transformation(cr, self_t->st, place, 0); // doing cairo_restore(cr)
+
+ self_t->place = *place;
+
+ return result;
+}
+
+// This gets called very often by Shoes. May be slow for large SVG?
+VALUE shoes_svg_draw(VALUE self, VALUE c, VALUE actual) {
+ shoes_svg *self_t;
+ shoes_place place;
+ shoes_canvas *canvas;
+ Data_Get_Struct(self, shoes_svg, self_t);
+ Data_Get_Struct(c, shoes_canvas, canvas);
+ if (ATTR(self_t->attr, hidden) == Qtrue) return self;
+ int rel =(REL_CANVAS | REL_SCALE);
+ shoes_place_decide(&place, c, self_t->attr, self_t->place.w, self_t->place.h, rel, REL_COORDS(rel) == REL_CANVAS);
+
+ if (RTEST(actual))
+ shoes_svg_draw_surface( CCR(canvas), self_t, &place, place.w, place.h);
+
+ if (!ABSY(place)) {
+ canvas->cx += place.w;
+ canvas->cy = place.y;
+ canvas->endx = canvas->cx;
+ canvas->endy = max(canvas->endy, place.y + place.h);
+ }
+ if(rb_obj_class(c) == cStack) {
+ canvas->cx = CPX(canvas);
+ canvas->cy = canvas->endy;
+ }
+ //printf("svg draw\n");
+ return self;
+}
+
+VALUE shoes_svg_get_handle(VALUE self) {
+ shoes_svg *self_t;
+ Data_Get_Struct(self, shoes_svg, self_t);
+ return self_t->svghandle;
+}
+
+VALUE shoes_svg_set_handle(VALUE self, VALUE han) {
+ shoes_svg *self_t;
+ Data_Get_Struct(self, shoes_svg, self_t);
+
+ if ( !NIL_P(han) && (rb_obj_is_kind_of(han, cSvgHandle)) ) {
+ self_t->svghandle = han;
+ // force a garbage collection, cSvgHandles could pile up if set at a fast rate
+ rb_gc();
+
+ shoes_svghandle *svghan;
+ Data_Get_Struct(self_t->svghandle, shoes_svghandle, svghan);
+ svg_aspect_ratio(ATTR(self_t->attr, width), ATTR(self_t->attr, height), self_t, svghan);
+ self_t->scalew = self_t->scalew/2;
+ self_t->scaleh = self_t->scaleh/2;
+
+ // updating cSvg attributes
+ shoes_hash_set(self_t->attr, rb_intern("filename"),
+ svghan->path ? rb_str_new_cstr(svghan->path) : Qnil);
+
+ shoes_hash_set(self_t->attr, rb_intern("content"),
+ svghan->data ? rb_str_new_cstr(svghan->data) : Qnil);
+
+ shoes_hash_set(self_t->attr, rb_intern("group"),
+ svghan->subid ? rb_str_new_cstr(svghan->subid) : Qnil);
+
+ if (svghan->aspect == -1.0)
+ shoes_hash_set(self_t->attr, rb_intern("aspect"), Qfalse);
+ else if (svghan->aspect == 0.0 || svghan->aspect == 1.0)
+ shoes_hash_set(self_t->attr, rb_intern("aspect"), Qtrue);
+ else
+ shoes_hash_set(self_t->attr, rb_intern("aspect"), DBL2NUM(svghan->aspect));
+
+ shoes_canvas_repaint_all(self_t->parent);
+
+ } else {
+ rb_raise(rb_eArgError, "bad argument, expecting a Shoes::SvgHandle \n");
+ }
+
+ return han;
+}
+
+VALUE shoes_svg_get_dpi(VALUE self) {
+ shoes_svg *self_t;
+ Data_Get_Struct(self, shoes_svg, self_t);
+ shoes_svghandle *svghan;
+ Data_Get_Struct(self_t->svghandle, shoes_svghandle, svghan);
+ double dpix, dpiy;
+ g_object_get(svghan->handle, "dpi-x", &dpix, NULL);
+ g_object_get(svghan->handle, "dpi-y", &dpiy, NULL);
+
+ return DBL2NUM(dpix); //TODO dpi-x, dpi-y ?
+}
+
+VALUE shoes_svg_set_dpi(VALUE self, VALUE dpi) {
+ shoes_svg *self_t;
+ Data_Get_Struct(self, shoes_svg, self_t);
+ shoes_svghandle *svghan;
+ Data_Get_Struct(self_t->svghandle, shoes_svghandle, svghan);
+
+ /* We have to handle the change in dpi ourselves as nothing in Shoes has a clue of what actually a dpi is
+ * Default is 90 as per rsvg specification, so if dpi is set to 180 we have to
+ * provide twice the number of pixels in x, twice in y,
+ * IF at any moment it has a meaning inside the Shoes environment !!!
+ */
+ rsvg_handle_set_dpi(svghan->handle, NUM2DBL(dpi));
+ //shoes_canvas_repaint_all(self_t->parent); // no meaning at the moment !
+
+ return Qnil;
+}
+
+typedef cairo_public cairo_surface_t * (cairo_surface_function_t) (const char *filename, double width, double height);
+
+static cairo_surface_function_t *get_vector_surface(char *format) {
+ if (strstr(format, "pdf") != NULL) return & cairo_pdf_surface_create;
+ if (strstr(format, "ps") != NULL) return & cairo_ps_surface_create;
+ if (strstr(format, "svg") != NULL) return & cairo_svg_surface_create;
+ return NULL;
+}
+
+static cairo_surface_t *buid_surface(VALUE self, VALUE docanvas, double scale, int *result, char *filename, char *format) {
+ shoes_svg *self_t;
+ Data_Get_Struct(self, shoes_svg, self_t);
+ shoes_canvas *canvas;
+ Data_Get_Struct(self_t->parent, shoes_canvas, canvas);
+ shoes_place place = self_t->place;
+ cairo_surface_t *surf;
+ cairo_t *cr;
+
+ if (docanvas == Qtrue) {
+ if (format != NULL)
+ surf = get_vector_surface(format)(filename, canvas->width*scale, canvas->height*scale);
+ else
+ surf = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, (int)(canvas->width*scale), (int)(canvas->height*scale));
+ cr = cairo_create(surf);
+
+ if (scale != 1.0) cairo_scale(cr, scale, scale);
+// *result = shoes_svg_draw_surface(cr, self_t, &place, (int)(place.w*scale), (int)(place.h*scale));
+ place.w = (int)(place.w*scale);
+ place.h = (int)(place.h*scale);
+ cairo_t *waz_cr = canvas->cr;
+ canvas->cr = cr;
+ shoes_canvas_draw(self_t->parent, self_t->parent, Qtrue);
+ canvas->cr = waz_cr;
+ *result = 1; //TODO
+ } else {
+ int w = (int)(NUM2INT(shoes_svg_get_actual_width(self))*scale);
+ int h = (int)(NUM2INT(shoes_svg_get_actual_height(self))*scale);
+ if (format != NULL)
+ surf = get_vector_surface(format)(filename, w, h);
+ else
+ surf = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, w, h);
+ cr = cairo_create(surf);
+
+ if (scale != 1.0) cairo_scale(cr, scale, scale);
+ cairo_translate(cr, -(place.ix + place.dx), -(place.iy + place.dy));
+ *result = shoes_svg_draw_surface(cr, self_t, &place, w, h);
+ }
+ if (format != NULL) cairo_show_page(cr);
+ cairo_destroy(cr);
+
+ return surf;
+}
+
+VALUE shoes_svg_export(VALUE self, VALUE attr) {
+ VALUE _filename, _dpi, _docanvas;
+ _filename = shoes_hash_get(attr, rb_intern("filename"));
+ _dpi = shoes_hash_get(attr, rb_intern("dpi"));
+ _docanvas = shoes_hash_get(attr, rb_intern("canvas"));
+ double scale = 1.0;
+ int result;
+
+ if (NIL_P(_filename)) {
+ rb_raise(rb_eArgError, "wrong arguments for svg export ({:filename=>'...', "
+ "[:dpi=>90, :canvas=>true|false] })\n:filename is mandatory\n");
+ }
+
+ if (!NIL_P(_dpi)) scale = NUM2INT(_dpi)/90.0;
+
+ cairo_surface_t *surf = buid_surface(self, _docanvas, scale, &result, NULL, NULL);
+
+ cairo_status_t r = cairo_surface_write_to_png(surf, RSTRING_PTR(_filename));
+ cairo_surface_destroy(surf);
+
+ return r == CAIRO_STATUS_SUCCESS ? Qtrue : Qfalse;
+}
+
+VALUE shoes_svg_save(VALUE self, VALUE attr) {
+ VALUE _filename, _format, _docanvas;
+ _filename = shoes_hash_get(attr, rb_intern("filename"));
+ _format = shoes_hash_get(attr, rb_intern("format"));
+ _docanvas = shoes_hash_get(attr, rb_intern("canvas"));
+ int result;
+
+ if (NIL_P(_filename) || NIL_P(_format)) {
+ rb_raise(rb_eArgError, "wrong arguments for svg save ({:filename=>'...', "
+ ":format=>'pdf'|'ps'|'svg' [, :canvas=>true|false] })\n:filename and :format are mandatory");
+ }
+
+ char *filename = RSTRING_PTR(_filename);
+ char *format = RSTRING_PTR(_format);
+
+ cairo_surface_t *surf = buid_surface(self, _docanvas, 1.0, &result, filename, format);
+ cairo_surface_destroy(surf);
+
+ return result == 0 ? Qfalse : Qtrue;
+}
+
+/* Not using PLACE_COMMMON Macro in ruby.c, as we do the svg rendering a bit differently
+ * than other widgets [parent, left, top, width, height ruby methods]
+ */
+VALUE shoes_svg_get_parent(VALUE self) {
+ GET_STRUCT(svg, self_t);
+ return self_t->parent;
+}
+
+VALUE shoes_svg_get_actual_width(VALUE self) {
+ GET_STRUCT(svg, self_t);
+ shoes_svghandle *svghan;
+ Data_Get_Struct(self_t->svghandle, shoes_svghandle, svghan);
+ return INT2NUM((int)floor(svghan->svghdim.width*self_t->scalew));
+}
+
+VALUE shoes_svg_get_actual_height(VALUE self) {
+ GET_STRUCT(svg, self_t);
+ shoes_svghandle *svghan;
+ Data_Get_Struct(self_t->svghandle, shoes_svghandle, svghan);
+ return INT2NUM((int)floor(svghan->svghdim.height*self_t->scaleh));
+}
+
+VALUE shoes_svg_get_actual_left(VALUE self) {
+ GET_STRUCT(svg, self_t);
+ return INT2NUM(self_t->place.ix + self_t->place.dx);
+}
+
+VALUE shoes_svg_get_actual_top(VALUE self) {
+ GET_STRUCT(svg, self_t);
+ return INT2NUM(self_t->place.iy + self_t->place.dy);
+}
+
+VALUE shoes_svg_preferred_width(VALUE self) {
+ int w;
+ GET_STRUCT(svg, self_t);
+ shoes_svghandle *svghan;
+ Data_Get_Struct(self_t->svghandle, shoes_svghandle, svghan);
+ w = svghan->svghdim.width;
+ return INT2NUM(w);
+}
+
+VALUE shoes_svg_preferred_height(VALUE self) {
+ int h;
+ GET_STRUCT(svg, self_t);
+ shoes_svghandle *svghan;
+ Data_Get_Struct(self_t->svghandle, shoes_svghandle, svghan);
+ h = svghan->svghdim.height;
+ return INT2NUM(h);
+}
+
+VALUE shoes_svg_get_offsetX(VALUE self) {
+ GET_STRUCT(svg, self_t);
+ shoes_svghandle *svghan;
+ Data_Get_Struct(self_t->svghandle, shoes_svghandle, svghan);
+ return INT2NUM(svghan->svghpos.x);
+}
+
+VALUE shoes_svg_get_offsetY(VALUE self) {
+ GET_STRUCT(svg, self_t);
+ shoes_svghandle *svghan;
+ Data_Get_Struct(self_t->svghandle, shoes_svghandle, svghan);
+ return INT2NUM(svghan->svghpos.y);
+}
+
+VALUE shoes_svg_has_group(VALUE self, VALUE group) {
+ shoes_svg *self_t;
+ shoes_svghandle *handle;
+ int result = 0;
+ Data_Get_Struct(self, shoes_svg, self_t);
+ Data_Get_Struct(self_t->svghandle, shoes_svghandle, handle);
+ if (!NIL_P(group) && (TYPE(group) == T_STRING)) {
+ char *grp = RSTRING_PTR(group);
+ result = rsvg_handle_has_sub(handle->handle, grp);
+ } else {
+ rb_raise(rb_eArgError, "bad argument, expecting a String \n");
+ }
+ return (result ? Qtrue : Qnil);
+}
+
+VALUE shoes_svg_remove(VALUE self) {
+ //printf("remove\n");
+ shoes_svg *self_t;
+ shoes_canvas *canvas;
+ Data_Get_Struct(self, shoes_svg, self_t);
+ Data_Get_Struct(self_t->parent, shoes_canvas, canvas);
+
+ rb_ary_delete(canvas->contents, self); // shoes_basic_remove does it this way
+ shoes_canvas_repaint_all(self_t->parent); //
+
+ // let ruby gc collect handle (it may be shared) just remove this ref
+ self_t->svghandle = Qnil;
+ self_t = NULL;
+ self = Qnil;
+
+ return Qtrue;
+}
+
+//called by shoes_svg_send_click and shoes_canvas_send_motion
+VALUE shoes_svg_motion(VALUE self, int x, int y, char *touch) {
+ char h = 0;
+ VALUE click;
+ GET_STRUCT(svg, self_t);
+
+ click = ATTR(self_t->attr, click);
+
+ if (IS_INSIDE(self_t, x, y)) {
+ if (!NIL_P(click)) {
+ shoes_canvas *canvas;
+ Data_Get_Struct(self_t->parent, shoes_canvas, canvas);
+ shoes_app_cursor(canvas->app, s_link);
+ }
+ h = 1;
+ }
+
+ /* Checks if element is hovered, clicked, released, leaved
+ * and eventually calls hover and/or leave callbacks
+ * if hovered: self_t->hover == 1
+ * if leaved: self_t->hover == 0
+ * if clicked and not yet released:
+ * if hovered + clicked: self_t->hover == 3
+ * if leaved + clicked: self_t->hover == 2
+ */
+ CHECK_HOVER(self_t, h, touch);
+
+ return h ? click : Qnil;
+}
+
+// called by shoes_canvas_send_click --> shoes_canvas_send_click2
+VALUE shoes_svg_send_click(VALUE self, int button, int x, int y) {
+ VALUE v = Qnil;
+
+ if (button > 0) {
+ GET_STRUCT(svg, self_t);
+ v = shoes_svg_motion(self, x, y, NULL);
+ if (self_t->hover & HOVER_MOTION) // ok, cursor is over the element, proceed
+ self_t->hover = HOVER_MOTION | HOVER_CLICK; // we have been clicked, but not yet released
+ }
+
+ // if we found a click callback send it back to shoes_canvas_send_click method
+ // where it will be processed
+ return v;
+}
+
+// called by shoes_canvas_send_release
+void shoes_svg_send_release(VALUE self, int button, int x, int y) {
+ GET_STRUCT(svg, self_t);
+ if (button > 0 && (self_t->hover & HOVER_CLICK)) {
+ VALUE proc = ATTR(self_t->attr, release);
+ self_t->hover ^= HOVER_CLICK; // we have been clicked and released
+ if (!NIL_P(proc))
+ shoes_safe_block(self, proc, rb_ary_new3(3, INT2NUM(button), INT2NUM(x), INT2NUM(y)));
+ }
+}
+
+// svghandle
+void shoes_svghandle_mark(shoes_svghandle *handle) {
+ // we don't have any Ruby objects to mark.
+}
+
+static void shoes_svghandle_free(shoes_svghandle *handle) {
+ if (handle->handle != NULL)
+ g_object_unref(handle->handle);
+ if (handle->path) free(handle->path);
+ if (handle->data) free(handle->data);
+ if (handle->subid) free(handle->subid);
+ RUBY_CRITICAL(SHOE_FREE(handle));
+}
+
+VALUE shoes_svghandle_alloc(VALUE klass) {
+ VALUE obj;
+ shoes_svghandle *handle = SHOE_ALLOC(shoes_svghandle);
+ SHOE_MEMZERO(handle, shoes_svghandle, 1);
+ obj = Data_Wrap_Struct(klass, NULL, shoes_svghandle_free, handle);
+ handle->handle = NULL;
+ handle->subid = NULL;
+ return obj;
+}
+
+VALUE shoes_svghandle_new(int argc, VALUE *argv, VALUE parent) {
+ // parse args for :content or :filename (load file if needed)
+ // parse arg for subid.
+ VALUE filename = shoes_hash_get(argv[0], rb_intern("filename"));
+ VALUE fromstring = shoes_hash_get(argv[0], rb_intern("content"));
+ VALUE subidObj = shoes_hash_get(argv[0], rb_intern("group"));
+ VALUE aspectObj = shoes_hash_get(argv[0], rb_intern("aspect"));
+
+ VALUE obj = shoes_svghandle_alloc(cSvgHandle);
+ shoes_svghandle *self_t;
+ Data_Get_Struct(obj, shoes_svghandle, self_t);
+
+ GError *gerror = NULL;
+ if (!NIL_P(filename)) {
+ // load it from a file
+ char *path = RSTRING_PTR(filename);
+ self_t->handle = rsvg_handle_new_from_file (path, &gerror);
+ if (self_t->handle == NULL) {
+ self_t->path = NULL;
+ printf("Failed SVG: %s\n", gerror->message);
+ } else self_t->path = strdup(RSTRING_PTR(filename));
+
+ } else if (!NIL_P(fromstring)) {
+ // load it from a string
+ char *data = RSTRING_PTR(fromstring);
+ int len = RSTRING_LEN(fromstring);
+ // being Ruby, those are UTF-8, may not be what rsvg wants (const guint8 *)
+ // Problem for OSX ?
+ self_t->handle = rsvg_handle_new_from_data ((const unsigned char *)data, len, &gerror);
+ if (self_t->handle == NULL) {
+ self_t->data = NULL;
+ printf("Failed SVG: %s\n", gerror->message);
+ } //else self_t->data = strdup(RSTRING_PTR(fromstring));
+
+ } else {
+ // never reached, handled by shoes_svg_new
+ }
+
+ if (!NIL_P(subidObj) && (RSTRING_LEN(subidObj) > 0)) {
+ if (rsvg_handle_has_sub(self_t->handle, RSTRING_PTR(subidObj))) {
+ self_t->subid = strdup(RSTRING_PTR(subidObj));
+ if (!rsvg_handle_get_dimensions_sub(self_t->handle, &self_t->svghdim, self_t->subid))
+ printf("no dim for %s\n", self_t->subid);
+ if (!rsvg_handle_get_position_sub(self_t->handle, &self_t->svghpos, self_t->subid))
+ printf("no pos for %s\n",self_t->subid);
+ } else {
+ printf("not a valid id %s\n",self_t->subid);
+ self_t->subid = NULL;
+ }
+ } else {
+ rsvg_handle_get_dimensions(self_t->handle, &self_t->svghdim);
+ self_t->svghpos.x = self_t->svghpos.y = 0;
+ self_t->subid = NULL;
+ }
+
+ if (NIL_P(aspectObj) || (aspectObj == Qtrue)) {
+ // :aspect => true or not specified, Keep aspect ratio
+ self_t->aspect = 0.0;
+ } else if (aspectObj == Qfalse) {
+ // :aspect => false, Don't keep aspect ratio
+ self_t->aspect = -1.0;
+ } else if (TYPE(aspectObj) == T_FLOAT) {
+ // :aspect => a double (ie 1.33), Don't keep aspect ratio
+ self_t->aspect = NUM2DBL(aspectObj);
+ } else {
+ // fallback on keep aspect ratio
+ self_t->aspect = 0.0;
+ }
+ /*
+ printf("sub x: %i, y: %i, w: %i, h: %i)\n",
+ self_t->svghpos.x, self_t->svghpos.y,
+ self_t->svghdim.width, self_t->svghdim.height);
+ */
+ return obj;
+}
+
+VALUE shoes_svghandle_get_width(VALUE self) {
+ GET_STRUCT(svghandle, self_t);
+ return INT2NUM(self_t->svghdim.width);
+}
+
+VALUE shoes_svghandle_get_height(VALUE self) {
+ GET_STRUCT(svghandle, self_t);
+ return INT2NUM(self_t->svghdim.height);
+}
+
+/* Needed for some odd situations -samples/good-flip.rb */
+VALUE shoes_svghandle_has_group(VALUE self, VALUE group) {
+ shoes_svghandle *handle;
+ Data_Get_Struct(self, shoes_svghandle, handle);
+ if (!NIL_P(group) && (TYPE(group) == T_STRING)) {
+ char *grp = RSTRING_PTR(group);
+ int has = rsvg_handle_has_sub(handle->handle, grp);
+ if (has)
+ return Qtrue;
+ else
+ return Qnil;
+ } else {
+ rb_raise(rb_eArgError, "bad argument, expecting a String \n");
+ }
+}
\ No newline at end of file
diff --git a/shoes/types/svg.h b/shoes/types/svg.h
new file mode 100644
index 00000000..170dc047
--- /dev/null
+++ b/shoes/types/svg.h
@@ -0,0 +1,83 @@
+#include "shoes/ruby.h"
+#include "shoes/canvas.h"
+#include "shoes/app.h"
+#include "shoes/internal.h"
+#include "shoes/world.h"
+#include "shoes/native/native.h"
+
+#ifndef SHOES_SVG_TYPE_H
+#define SHOES_SVG_TYPE_H
+
+/* extern variables necessary to communicate with other parts of Shoes */
+extern VALUE cShoes, cApp, cTypes, cCanvas, cWidget;
+extern shoes_app _shoes_app;
+
+// SvgHandle struct - not a graphical widget
+// new in 3.3.0
+typedef struct _svghandle {
+ RsvgHandle *handle;
+ RsvgDimensionData svghdim;
+ RsvgPositionData svghpos;
+ char *path;
+ char *data;
+ char *subid;
+ double aspect;
+} shoes_svghandle;
+
+//
+// SVG struct
+//
+typedef struct {
+ VALUE parent;
+ VALUE attr;
+ shoes_place place;
+ double scalew;
+ double scaleh;
+ VALUE svghandle;
+ char hover;
+ shoes_transform *st;
+} shoes_svg;
+
+/* each widget should have its own init function */
+void shoes_svg_init();
+
+// ruby (svg)
+VALUE shoes_svg_new(int, VALUE *, VALUE);
+VALUE shoes_svg_alloc(VALUE);
+VALUE shoes_svg_draw(VALUE, VALUE, VALUE);
+VALUE shoes_svg_get_handle(VALUE);
+VALUE shoes_svg_set_handle(VALUE, VALUE);
+VALUE shoes_svg_get_dpi(VALUE);
+VALUE shoes_svg_set_dpi(VALUE, VALUE);
+VALUE shoes_svg_export(VALUE, VALUE);
+VALUE shoes_svg_save(VALUE, VALUE);
+VALUE shoes_svg_show(VALUE);
+VALUE shoes_svg_hide(VALUE);
+VALUE shoes_svg_get_actual_width(VALUE);
+VALUE shoes_svg_get_actual_height(VALUE);
+VALUE shoes_svg_get_actual_left(VALUE);
+VALUE shoes_svg_get_actual_top(VALUE);
+VALUE shoes_svg_get_parent(VALUE);
+VALUE shoes_svg_get_offsetX(VALUE);
+VALUE shoes_svg_get_offsetY(VALUE);
+VALUE shoes_svg_preferred_height(VALUE);
+VALUE shoes_svg_preferred_width(VALUE);
+VALUE shoes_svg_remove(VALUE);
+VALUE shoes_svg_has_group(VALUE, VALUE);
+
+// ruby (svghandle)
+VALUE shoes_svghandle_new(int argc, VALUE *argv, VALUE self);
+VALUE shoes_svghandle_alloc(VALUE);
+VALUE shoes_svghandle_get_width(VALUE);
+VALUE shoes_svghandle_get_height(VALUE);
+VALUE shoes_svghandle_has_group(VALUE, VALUE);
+
+// canvas
+VALUE shoes_canvas_svg(int, VALUE *, VALUE);
+VALUE shoes_svg_motion(VALUE, int, int, char *);
+VALUE shoes_svg_send_click(VALUE, int, int, int);
+void shoes_svg_send_release(VALUE, int, int, int);
+
+VALUE shoes_canvas_svghandle(int, VALUE *, VALUE);
+
+#endif
diff --git a/shoes/types/switch.c b/shoes/types/switch.c
new file mode 100644
index 00000000..498a4d9d
--- /dev/null
+++ b/shoes/types/switch.c
@@ -0,0 +1,69 @@
+#include "shoes/types/native.h"
+#include "shoes/types/switch.h"
+
+// ruby
+VALUE cSwitch;
+
+FUNC_M("+switch", switch, -1);
+
+EVENT_COMMON(control, control, active)
+
+void shoes_switch_init() {
+ cSwitch = rb_define_class_under(cTypes, "Switch", cNative);
+ rb_define_method(cSwitch, "draw", CASTHOOK(shoes_switch_draw), 2);
+ rb_define_method(cSwitch, "active?", CASTHOOK(shoes_switch_get_active), 0);
+ rb_define_method(cSwitch, "active=", CASTHOOK(shoes_switch_set_active),1);
+ rb_define_method(cSwitch, "click", CASTHOOK(shoes_control_active), -1);
+ rb_define_method(cSwitch, "tooltip", CASTHOOK(shoes_control_get_tooltip), 0);
+ rb_define_method(cSwitch, "tooltip=", CASTHOOK(shoes_control_set_tooltip), 1);
+
+ RUBY_M("+switch", switch, -1);
+}
+
+VALUE shoes_switch_draw(VALUE self, VALUE c, VALUE actual) {
+ SETUP_CONTROL(0, 0, FALSE);
+
+ if (RTEST(actual)) {
+ if (self_t->ref == NULL) {
+ self_t->ref = shoes_native_switch(self, canvas, &place, self_t->attr, msg);
+ shoes_control_check_styles(self_t);
+ shoes_native_control_position(self_t->ref, &self_t->place, self, canvas, &place);
+ } else
+ shoes_native_control_repaint(self_t->ref, &self_t->place, canvas, &place);
+ }
+
+ FINISH();
+
+ return self;
+}
+
+VALUE shoes_switch_get_active(VALUE self) {
+ GET_STRUCT(control, self_t);
+ return shoes_native_switch_get_active(self_t->ref);
+}
+
+VALUE shoes_switch_set_active(VALUE self, VALUE activate) {
+ GET_STRUCT(control, self_t);
+ if (self_t->ref != NULL)
+ shoes_native_switch_set_active(self_t->ref, activate == Qtrue);
+
+ return self;
+}
+
+// canvas
+VALUE shoes_canvas_switch(int argc, VALUE *argv, VALUE self) {
+ rb_arg_list args;
+ VALUE _switch;
+
+ SETUP_CANVAS();
+
+ rb_parse_args(argc, argv, "|h", &args);
+
+ if (rb_block_given_p())
+ ATTRSET(args.a[0], active, rb_block_proc());
+
+ _switch = shoes_control_new(cSwitch, args.a[0], self);
+ shoes_add_ele(canvas, _switch);
+
+ return _switch;
+}
diff --git a/shoes/types/switch.h b/shoes/types/switch.h
new file mode 100644
index 00000000..b5212c29
--- /dev/null
+++ b/shoes/types/switch.h
@@ -0,0 +1,38 @@
+#include "shoes/ruby.h"
+#include "shoes/canvas.h"
+#include "shoes/app.h"
+#include "shoes/internal.h"
+#include "shoes/world.h"
+#include "shoes/native/native.h"
+
+#ifndef SHOES_SWITCH_TYPE_H
+#define SHOES_SWITCH_TYPE_H
+
+/* extern variables necessary to communicate with other parts of Shoes */
+extern VALUE cShoes, cApp, cTypes, cCanvas, cWidget;
+extern shoes_app _shoes_app;
+
+SYMBOL_ID(active);
+
+/* Should be automatically available but ruby.c is not sharing enough information */
+//extern VALUE shoes_control_active(int argc, VALUE *argv, VALUE self);
+
+// native forward declarations
+extern SHOES_CONTROL_REF shoes_native_switch(VALUE self, shoes_canvas *canvas, shoes_place *place, VALUE attr, char *msg);
+extern void shoes_native_switch_set_active(SHOES_CONTROL_REF ref, int activate);
+extern VALUE shoes_native_switch_get_active(SHOES_CONTROL_REF ref);
+//extern void shoes_native_activate(GObject *switcher, GParamSpec *pspec, gpointer data);
+
+
+/* each widget should have its own init function */
+void shoes_switch_init();
+
+// ruby
+VALUE shoes_switch_draw(VALUE self, VALUE c, VALUE actual);
+VALUE shoes_switch_get_active(VALUE self);
+VALUE shoes_switch_set_active(VALUE self, VALUE activate);
+
+// canvas
+VALUE shoes_canvas_switch(int argc, VALUE *argv, VALUE self);
+
+#endif
diff --git a/shoes/types/systray.c b/shoes/types/systray.c
new file mode 100644
index 00000000..0f7ec206
--- /dev/null
+++ b/shoes/types/systray.c
@@ -0,0 +1,90 @@
+/* systray
+ * Is not really a widget with things you can modifiy
+*/
+#include "shoes/types/native.h"
+#include "shoes/types/systray.h"
+
+// ruby
+VALUE cSystray;
+
+FUNC_M("+systray", systray, -1);
+
+shoes_systray_init() {
+ cSystray = rb_define_class_under(cTypes, "Systray", cNative);
+ rb_define_alloc_func(cSystray, shoes_systray_alloc);
+ // no methods
+ RUBY_M("+systray", systray, -1);
+}
+
+// canvas
+VALUE shoes_canvas_systray(int argc, VALUE *argv, VALUE self) {
+ VALUE han;
+ han = shoes_systray_new(argc, argv, self);
+ return han;
+}
+
+void shoes_systray_mark(shoes_systray *handle) {
+ // we don't have any Ruby objects to mark.
+}
+
+static void shoes_systray_free(shoes_systray *handle) {
+ if (handle->icon_path) free(handle->icon_path);
+ if (handle->title) free(handle->title);
+ if (handle->message) free(handle->message);
+ RUBY_CRITICAL(SHOE_FREE(handle));
+}
+
+VALUE shoes_systray_alloc(VALUE klass) {
+ VALUE obj;
+ shoes_systray *handle = SHOE_ALLOC(shoes_systray);
+ SHOE_MEMZERO(handle, shoes_systray, 1);
+ obj = Data_Wrap_Struct(klass, NULL, shoes_systray_free, handle);
+ handle->icon_path = NULL;
+ handle->title = NULL;
+ handle->message = NULL;
+ return obj;
+}
+
+VALUE shoes_systray_new(int argc, VALUE *argv, VALUE parent) {
+ // Get Ruby args.
+ VALUE rbtitle, rbmessage, rbpath;
+ if (argc == 1) {
+ rbtitle = shoes_hash_get(argv[0], rb_intern("title"));
+ rbmessage = shoes_hash_get(argv[0], rb_intern("message"));
+ rbpath = shoes_hash_get(argv[0], rb_intern("icon"));
+ } else if (argc == 3) {
+ rbtitle = argv[0];
+ rbmessage = argv[1];
+ rbpath = argv[2];
+ } else {
+ rb_raise(rb_eArgError, "Missing an argument to systray");
+ }
+ char *title = NULL, *message = NULL, *path = NULL;
+
+ /* Alloc the object and init. We do keep a copy of the strings
+ * which will be garbage collected in at some point by Ruby
+ * Assumes the strings and pixbugs in the native are copied
+ * out of our process memory into the Desktop's space.
+ */
+ VALUE obj = shoes_systray_alloc(cSystray);
+ shoes_systray *self_t;
+ Data_Get_Struct(obj, shoes_systray, self_t);
+ Check_Type(rbtitle, T_STRING);
+ if ((!NIL_P(rbtitle)) && (RSTRING_LEN(rbtitle) > 0)) {
+ title = self_t->title = strdup(RSTRING_PTR(rbtitle));
+ }
+ Check_Type(rbmessage, T_STRING);
+ if ((!NIL_P(rbmessage)) && (RSTRING_LEN(rbmessage) > 0)) {
+ message = self_t->message = strdup(RSTRING_PTR(rbmessage));
+ }
+ Check_Type(rbpath, T_STRING);
+ if ((!NIL_P(rbpath)) && (RSTRING_LEN(rbpath) > 0)) {
+ path = self_t->icon_path =strdup(RSTRING_PTR(rbpath));
+ }
+ if (path == NULL || message == NULL || title == NULL) {
+ rb_raise(rb_eArgError, "Bad arguments to systray");
+ }
+ // call the native widget
+ shoes_native_systray(title, message, path);
+ return Qnil;
+}
diff --git a/shoes/types/systray.h b/shoes/types/systray.h
new file mode 100644
index 00000000..80846851
--- /dev/null
+++ b/shoes/types/systray.h
@@ -0,0 +1,31 @@
+#include "shoes/ruby.h"
+#include "shoes/canvas.h"
+#include "shoes/app.h"
+#include "shoes/internal.h"
+#include "shoes/world.h"
+#include "shoes/native/native.h"
+
+#ifndef SHOES_SYSTRAY_TYPE_H
+#define SHOES_SYSTRAY_TYPE_H
+
+/* extern variables necessary to communicate with other parts of Shoes */
+extern VALUE cShoes, cApp, cTypes, cCanvas, cWidget;
+extern shoes_app _shoes_app;
+
+// SvgHandle struct - not a graphical widget
+// new in 3.3.0
+typedef struct _systray {
+ char *icon_path;
+ char *title;
+ char *message;
+} shoes_systray;
+
+
+// ruby (systray)
+VALUE shoes_systray_new(int argc, VALUE *argv, VALUE self);
+VALUE shoes_systray_alloc(VALUE);
+
+// canvas
+VALUE shoes_canvas_systray(int, VALUE *, VALUE);
+
+#endif
diff --git a/shoes/types/text.c b/shoes/types/text.c
new file mode 100644
index 00000000..bc393492
--- /dev/null
+++ b/shoes/types/text.c
@@ -0,0 +1,119 @@
+#include "shoes/types/textblock.h"
+#include "shoes/types/text.h"
+
+// ruby
+VALUE cTextClass, cSpan, cDel, cStrong, cSub, cSup, cCode, cEm, cIns;
+
+FUNC_M(".code", code, -1);
+FUNC_M(".del", del, -1);
+FUNC_M(".em", em, -1);
+FUNC_M(".ins", ins, -1);
+FUNC_M(".span", span, -1);
+FUNC_M(".strong", strong, -1);
+FUNC_M(".sub", sub, -1);
+FUNC_M(".sup", sup, -1);
+
+CLASS_COMMON(text);
+REPLACE_COMMON(text);
+
+MARKUP_DEF(code, INLINE, cCode);
+MARKUP_DEF(del, INLINE, cDel);
+MARKUP_DEF(em, INLINE, cEm);
+MARKUP_DEF(ins, INLINE, cIns);
+MARKUP_DEF(span, INLINE, cSpan);
+MARKUP_DEF(strong, INLINE, cStrong);
+MARKUP_DEF(sub, INLINE, cSub);
+MARKUP_DEF(sup, INLINE, cSup);
+
+void shoes_text_init() {
+ cTextClass = rb_define_class_under(cTypes, "Text", rb_cObject);
+
+ rb_define_alloc_func(cTextClass, shoes_text_alloc);
+ rb_define_method(cTextClass, "app", CASTHOOK(shoes_canvas_get_app), 0);
+ rb_define_method(cTextClass, "contents", CASTHOOK(shoes_text_children), 0);
+ rb_define_method(cTextClass, "children", CASTHOOK(shoes_text_children), 0);
+ rb_define_method(cTextClass, "parent", CASTHOOK(shoes_text_parent), 0);
+ rb_define_method(cTextClass, "style", CASTHOOK(shoes_text_style), -1);
+ rb_define_method(cTextClass, "to_s", CASTHOOK(shoes_text_to_s), 0);
+ rb_define_method(cTextClass, "text", CASTHOOK(shoes_text_children), 0);
+ rb_define_method(cTextClass, "text=", CASTHOOK(shoes_text_replace), -1);
+ rb_define_method(cTextClass, "replace", CASTHOOK(shoes_text_replace), -1);
+
+ cCode = rb_define_class_under(cTypes, "Code", cTextClass);
+ cDel = rb_define_class_under(cTypes, "Del", cTextClass);
+ cEm = rb_define_class_under(cTypes, "Em", cTextClass);
+ cIns = rb_define_class_under(cTypes, "Ins", cTextClass);
+ cSpan = rb_define_class_under(cTypes, "Span", cTextClass);
+ cStrong = rb_define_class_under(cTypes, "Strong", cTextClass);
+ cSub = rb_define_class_under(cTypes, "Sub", cTextClass);
+ cSup = rb_define_class_under(cTypes, "Sup", cTextClass);
+
+ RUBY_M(".code", code, -1);
+ RUBY_M(".del", del, -1);
+ RUBY_M(".em", em, -1);
+ RUBY_M(".ins", ins, -1);
+ RUBY_M(".span", span, -1);
+ RUBY_M(".strong", strong, -1);
+ RUBY_M(".sub", sub, -1);
+ RUBY_M(".sup", sup, -1);
+}
+
+// ruby
+void shoes_text_mark(shoes_text *text) {
+ rb_gc_mark_maybe(text->texts);
+ rb_gc_mark_maybe(text->attr);
+ rb_gc_mark_maybe(text->parent);
+}
+
+void shoes_text_free(shoes_text *text) {
+ RUBY_CRITICAL(free(text));
+}
+
+VALUE shoes_text_check(VALUE texts, VALUE parent) {
+ long i;
+ for (i = 0; i < RARRAY_LEN(texts); i++) {
+ VALUE ele = rb_ary_entry(texts, i);
+ if (rb_obj_is_kind_of(ele, cTextClass)) {
+ shoes_text *text;
+ Data_Get_Struct(ele, shoes_text, text);
+ text->parent = parent;
+ }
+ }
+ return texts;
+}
+
+VALUE shoes_text_to_s(VALUE self) {
+ GET_STRUCT(textblock, self_t);
+ return rb_funcall(self_t->texts, s_to_s, 0);
+}
+
+VALUE shoes_text_new(VALUE klass, VALUE texts, VALUE attr) {
+ shoes_text *text;
+ VALUE obj = shoes_text_alloc(klass);
+ Data_Get_Struct(obj, shoes_text, text);
+ text->hover = 0;
+ text->texts = shoes_text_check(texts, obj);
+ text->attr = attr;
+ return obj;
+}
+
+VALUE shoes_text_alloc(VALUE klass) {
+ VALUE obj;
+ shoes_text *text = SHOE_ALLOC(shoes_text);
+ SHOE_MEMZERO(text, shoes_text, 1);
+ obj = Data_Wrap_Struct(klass, shoes_text_mark, shoes_text_free, text);
+ text->texts = Qnil;
+ text->attr = Qnil;
+ text->parent = Qnil;
+ return obj;
+}
+
+VALUE shoes_text_parent(VALUE self) {
+ GET_STRUCT(text, text);
+ return text->parent;
+}
+
+VALUE shoes_text_children(VALUE self) {
+ GET_STRUCT(text, text);
+ return text->texts;
+}
\ No newline at end of file
diff --git a/shoes/types/text.h b/shoes/types/text.h
new file mode 100644
index 00000000..8aaed0fb
--- /dev/null
+++ b/shoes/types/text.h
@@ -0,0 +1,49 @@
+#include "shoes/ruby.h"
+#include "shoes/canvas.h"
+#include "shoes/app.h"
+#include "shoes/internal.h"
+#include "shoes/world.h"
+#include "shoes/native/native.h"
+
+#ifndef SHOES_TEXT_TYPE_H
+#define SHOES_TEXT_TYPE_H
+
+/* extern variables necessary to communicate with other parts of Shoes */
+extern VALUE cShoes, cApp, cTypes, cCanvas, cWidget;
+extern shoes_app _shoes_app;
+
+SYMBOL_ID(text);
+
+VALUE cTextClass, cSpan, cDel, cStrong, cSub, cSup, cCode, cEm, cIns;
+
+typedef struct {
+ VALUE parent;
+ VALUE attr;
+ VALUE texts;
+ char hover;
+} shoes_text;
+
+/* each widget should have its own init function */
+void shoes_text_init();
+
+// ruby
+void shoes_text_mark(shoes_text *text);
+void shoes_text_free(shoes_text *text);
+VALUE shoes_text_check(VALUE texts, VALUE parent);
+VALUE shoes_text_to_s(VALUE self);
+VALUE shoes_text_new(VALUE klass, VALUE texts, VALUE attr);
+VALUE shoes_text_alloc(VALUE klass);
+VALUE shoes_text_parent(VALUE self);
+VALUE shoes_text_children(VALUE self);
+
+// canvas
+VALUE shoes_canvas_code(int argc, VALUE *argv, VALUE self);
+VALUE shoes_canvas_del(int argc, VALUE *argv, VALUE self);
+VALUE shoes_canvas_em(int argc, VALUE *argv, VALUE self);
+VALUE shoes_canvas_ins(int argc, VALUE *argv, VALUE self);
+VALUE shoes_canvas_span(int argc, VALUE *argv, VALUE self);
+VALUE shoes_canvas_strong(int argc, VALUE *argv, VALUE self);
+VALUE shoes_canvas_sub(int argc, VALUE *argv, VALUE self);
+VALUE shoes_canvas_sup(int argc, VALUE *argv, VALUE self);
+
+#endif
diff --git a/shoes/types/text_link.c b/shoes/types/text_link.c
new file mode 100644
index 00000000..d9377cf7
--- /dev/null
+++ b/shoes/types/text_link.c
@@ -0,0 +1,96 @@
+#include "shoes/types/text.h"
+#include "shoes/types/text_link.h"
+
+// ruby
+VALUE cLink, cLinkText, cLinkHover, cLinkUrl;
+
+FUNC_M(".link", link, -1);
+
+EVENT_COMMON(linktext, text, click);
+EVENT_COMMON(linktext, text, release);
+EVENT_COMMON(linktext, text, hover);
+EVENT_COMMON(linktext, text, leave);
+
+void shoes_text_link_init() {
+ cLink = rb_define_class_under(cTypes, "Link", cTextClass);
+
+ rb_define_method(cTextClass, "click", CASTHOOK(shoes_linktext_click), -1);
+ rb_define_method(cTextClass, "release", CASTHOOK(shoes_linktext_release), -1);
+ rb_define_method(cTextClass, "hover", CASTHOOK(shoes_linktext_hover), -1);
+ rb_define_method(cTextClass, "leave", CASTHOOK(shoes_linktext_leave), -1);
+
+ cLinkHover = rb_define_class_under(cTypes, "LinkHover", cTextClass);
+ cLinkUrl = rb_define_class_under(cTypes, "LinkUrl", rb_cObject);
+
+ RUBY_M(".link", link, -1);
+}
+
+// ruby
+void shoes_link_mark(shoes_link *link) {
+}
+
+void shoes_link_free(shoes_link *link) {
+ RUBY_CRITICAL(free(link));
+}
+
+VALUE shoes_link_new(VALUE ele, int start, int end) {
+ shoes_link *link;
+ VALUE obj = shoes_link_alloc(cLinkUrl);
+ Data_Get_Struct(obj, shoes_link, link);
+ link->ele = ele;
+ link->start = start;
+ link->end = end;
+ return obj;
+}
+
+VALUE shoes_link_alloc(VALUE klass) {
+ VALUE obj;
+ shoes_link *link = SHOE_ALLOC(shoes_link);
+ SHOE_MEMZERO(link, shoes_link, 1);
+ obj = Data_Wrap_Struct(klass, shoes_link_mark, shoes_link_free, link);
+ link->ele = Qnil;
+ return obj;
+}
+
+VALUE shoes_link_at(shoes_textblock *t, VALUE self, int index, int blockhover, VALUE *clicked, char *touch) {
+ char h = 0;
+ VALUE url = Qnil;
+ shoes_text *self_t;
+
+ GET_STRUCT(link, link);
+ Data_Get_Struct(link->ele, shoes_text, self_t);
+ if (blockhover && link->start <= index && link->end >= index) {
+ h = 1;
+ if (clicked != NULL) *clicked = link->ele;
+ url = ATTR(self_t->attr, click);
+ }
+
+ self = link->ele;
+ CHECK_HOVER(self_t, h, touch);
+ t->hover = (t->hover & HOVER_CLICK) | h;
+
+ return url;
+}
+
+// canvas
+VALUE shoes_canvas_link(int argc, VALUE *argv, VALUE self) {
+ long i;
+ VALUE msgs, attr, text;
+ SETUP_CANVAS();
+ msgs = rb_ary_new();
+ attr = Qnil;
+ for (i = 0; i < argc; i++) {
+ if (rb_obj_is_kind_of(argv[i], rb_cHash))
+ attr = argv[i];
+ else
+ rb_ary_push(msgs, argv[i]);
+ }
+
+ if (rb_block_given_p()) {
+ if (NIL_P(attr)) attr = rb_hash_new();
+ rb_hash_aset(attr, ID2SYM(s_click), rb_block_proc());
+ }
+
+ MARKUP_INLINE(cLink);
+ return text;
+}
diff --git a/shoes/types/text_link.h b/shoes/types/text_link.h
new file mode 100644
index 00000000..aaf9f380
--- /dev/null
+++ b/shoes/types/text_link.h
@@ -0,0 +1,44 @@
+#include "shoes/ruby.h"
+#include "shoes/canvas.h"
+#include "shoes/app.h"
+#include "shoes/internal.h"
+#include "shoes/world.h"
+#include "shoes/native/native.h"
+#include "shoes/types/textblock.h"
+
+/*
+ Named text_link{.c,.h} to ensure text{.c,.h} is loaded first in SHOES_TYPES_INIT
+ because link is a subclass of TextClass
+*/
+
+#ifndef SHOES_TEXT_LINK_TYPE_H
+#define SHOES_TEXT_LINK_TYPE_H
+
+/* extern variables necessary to communicate with other parts of Shoes */
+extern VALUE cShoes, cApp, cTypes, cCanvas, cWidget, cTextClass;
+extern shoes_app _shoes_app;
+
+VALUE cLink, cLinkText, cLinkHover, cLinkUrl;
+
+SYMBOL_ID(link);
+
+typedef struct {
+ int start;
+ int end;
+ VALUE ele;
+} shoes_link;
+
+/* each widget should have its own init function */
+void shoes_text_link_init();
+
+// ruby (link url)
+void shoes_link_mark(shoes_link *link);
+void shoes_link_free(shoes_link *link) ;
+VALUE shoes_link_new(VALUE ele, int start, int end);
+VALUE shoes_link_alloc(VALUE klass);
+VALUE shoes_link_at(shoes_textblock *t, VALUE self, int index, int blockhover, VALUE *clicked, char *touch);
+
+// canvas
+VALUE shoes_canvas_link(int argc, VALUE *argv, VALUE self);
+
+#endif
diff --git a/shoes/types/text_view.c b/shoes/types/text_view.c
new file mode 100644
index 00000000..70790aa1
--- /dev/null
+++ b/shoes/types/text_view.c
@@ -0,0 +1,140 @@
+#include "shoes/types/native.h"
+#include "shoes/types/text_view.h"
+
+// text_edit_box is new with 3.2.25
+// text_edit_box has been renamed text_view with 3.3.4
+
+// ruby
+VALUE cTextView;
+
+FUNC_M("+text_view", text_view, -1);
+
+void shoes_text_view_init() {
+ cTextView = rb_define_class_under(cTypes, "TextView", cNative);
+ rb_define_method(cTextView, "text", CASTHOOK(shoes_text_view_get_text), 0);
+ rb_define_method(cTextView, "text=", CASTHOOK(shoes_text_view_set_text), 1);
+ rb_define_method(cTextView, "draw", CASTHOOK(shoes_text_view_draw), 2);
+ rb_define_method(cTextView, "change", CASTHOOK(shoes_control_change), -1);
+ rb_define_method(cTextView, "append", CASTHOOK(shoes_text_view_append), 1);
+ rb_define_method(cTextView, "insert", CASTHOOK(shoes_text_view_insert), -1);
+ rb_define_method(cTextView, "delete", CASTHOOK(shoes_text_view_delete), 2);
+ rb_define_method(cTextView, "get_from", CASTHOOK(shoes_text_view_get), 2);
+ rb_define_method(cTextView, "new_insertion", CASTHOOK(shoes_text_view_create_insertion), 2);
+ rb_define_method(cTextView, "currrent_insertion", CASTHOOK(shoes_text_view_current_insertion), 0);
+ rb_define_method(cTextView, "scroll_to_insertion", CASTHOOK(shoes_text_view_scroll_to_insertion), 1);
+ rb_define_method(cTextView, "scroll_to_end", CASTHOOK(shoes_text_view_scroll_to_end), 0);
+ rb_define_method(cTextView, "tooltip", CASTHOOK(shoes_control_get_tooltip), 0);
+ rb_define_method(cTextView, "tooltip=", CASTHOOK(shoes_control_set_tooltip), 1);
+
+ RUBY_M("+text_view", text_view, -1);
+}
+
+// ruby
+VALUE shoes_text_view_draw(VALUE self, VALUE c, VALUE actual) {
+ SETUP_CONTROL(80, 0, FALSE);
+
+ if (RTEST(actual)) {
+ if (self_t->ref == NULL) {
+ self_t->ref = shoes_native_text_view(self, canvas, &place, self_t->attr, msg);
+ shoes_control_check_styles(self_t);
+ shoes_native_control_position(self_t->ref, &self_t->place, self, canvas, &place);
+ } else
+ shoes_native_control_repaint(self_t->ref, &self_t->place, canvas, &place);
+ }
+
+ FINISH();
+
+ return self;
+
+}
+
+VALUE shoes_text_view_get_text(VALUE self) {
+ GET_STRUCT(control, self_t);
+ if (self_t->ref == NULL) return Qnil;
+ return shoes_native_text_view_get_text(self_t->ref);
+}
+
+VALUE shoes_text_view_set_text(VALUE self, VALUE text) {
+ char *msg = "";
+ GET_STRUCT(control, self_t);
+ if (!NIL_P(text)) {
+ text = shoes_native_to_s(text);
+ ATTRSET(self_t->attr, text, text);
+ msg = RSTRING_PTR(text);
+ }
+ if (self_t->ref != NULL) shoes_native_text_view_set_text(self_t->ref, msg);
+ return text;
+}
+
+VALUE shoes_text_view_append (VALUE self, VALUE text) {
+ char *msg = "";
+ VALUE ret;
+ GET_STRUCT(control, self_t);
+ if (!NIL_P(text)) {
+ text = shoes_native_to_s(text);
+ ATTRSET(self_t->attr, text, text);
+ msg = RSTRING_PTR(text);
+ }
+ if (self_t->ref != NULL)
+ ret = shoes_native_text_view_append(self_t->ref, msg);
+ else
+ ret = text;
+ return ret; //TODO: should return updated internal insertion point
+}
+
+VALUE shoes_text_view_insert (VALUE self, VALUE args) {
+ // parse args
+ return Qnil;
+}
+
+VALUE shoes_text_view_delete( VALUE self, VALUE args) {
+ return args;
+}
+
+VALUE shoes_text_view_get(VALUE self, VALUE args) {
+ return args;
+}
+
+VALUE shoes_text_view_create_insertion(VALUE self, VALUE args) {
+ return args;
+}
+
+VALUE shoes_text_view_current_insertion(VALUE self) {
+ return Qnil;
+}
+
+VALUE shoes_text_view_scroll_to_insertion(VALUE seff, VALUE insert_pt) {
+ return insert_pt; // TODO: wrong
+}
+
+VALUE shoes_text_view_scroll_to_end (VALUE self) {
+ return self; // TODO: Not even wrong
+}
+
+// canvas
+VALUE shoes_canvas_text_view(int argc, VALUE *argv, VALUE self) {
+ rb_arg_list args;
+ VALUE phrase = Qnil, attr = Qnil, text_view;
+ SETUP_CANVAS();
+
+ switch (rb_parse_args(argc, argv, "h,S|h,", &args)) {
+ case 1:
+ attr = args.a[0];
+ break;
+
+ case 2:
+ phrase = args.a[0];
+ attr = args.a[1];
+ break;
+ }
+
+ if (!NIL_P(phrase))
+ ATTRSET(attr, text, phrase);
+
+ if (rb_block_given_p())
+ ATTRSET(attr, change, rb_block_proc());
+
+ text_view = shoes_control_new(cTextView, attr, self);
+ shoes_add_ele(canvas, text_view);
+ return text_view;
+}
diff --git a/shoes/types/text_view.h b/shoes/types/text_view.h
new file mode 100644
index 00000000..3305e2d6
--- /dev/null
+++ b/shoes/types/text_view.h
@@ -0,0 +1,43 @@
+#include "shoes/ruby.h"
+#include "shoes/canvas.h"
+#include "shoes/app.h"
+#include "shoes/internal.h"
+#include "shoes/world.h"
+#include "shoes/native/native.h"
+
+#ifndef SHOES_TEXT_VIEW_TYPE_H
+#define SHOES_TEXT_VIEW_TYPE_H
+
+/* extern variables necessary to communicate with other parts of Shoes */
+extern VALUE cShoes, cApp, cTypes, cCanvas, cWidget;
+extern shoes_app _shoes_app;
+
+/* Should be automatically available but ruby.c is not sharing enough information */
+extern VALUE shoes_control_change(int argc, VALUE *argv, VALUE self);
+
+// native forward declarations
+extern SHOES_CONTROL_REF shoes_native_text_view(VALUE self, shoes_canvas *canvas, shoes_place *place, VALUE attr, char *msg);
+extern VALUE shoes_native_text_view_get_text(SHOES_CONTROL_REF ref);
+extern void shoes_native_text_view_set_text(SHOES_CONTROL_REF ref, char *msg);
+extern VALUE shoes_native_text_view_append(SHOES_CONTROL_REF ref, char *msg);
+
+/* each widget should have its own init function */
+void shoes_text_view_init();
+
+// ruby
+VALUE shoes_text_view_draw(VALUE self, VALUE c, VALUE actual);
+VALUE shoes_text_view_get_text(VALUE self);
+VALUE shoes_text_view_set_text(VALUE self, VALUE text);
+VALUE shoes_text_view_append (VALUE self, VALUE text);
+VALUE shoes_text_view_insert (VALUE self, VALUE args);
+VALUE shoes_text_view_delete( VALUE self, VALUE args);
+VALUE shoes_text_view_get(VALUE self, VALUE args);
+VALUE shoes_text_view_create_insertion(VALUE self, VALUE args);
+VALUE shoes_text_view_current_insertion(VALUE self);
+VALUE shoes_text_view_scroll_to_insertion(VALUE seff, VALUE insert_pt);
+VALUE shoes_text_view_scroll_to_end (VALUE self);
+
+// canvas
+VALUE shoes_canvas_text_view(int, VALUE *, VALUE);
+
+#endif
diff --git a/shoes/types/textblock.c b/shoes/types/textblock.c
new file mode 100644
index 00000000..6e16c305
--- /dev/null
+++ b/shoes/types/textblock.c
@@ -0,0 +1,745 @@
+#include "shoes/types/color.h"
+#include "shoes/types/native.h"
+#include "shoes/types/shape.h"
+#include "shoes/types/text.h"
+#include "shoes/types/text_link.h"
+#include "shoes/types/textblock.h"
+
+// ruby
+VALUE cTextBlock, cPara, cBanner, cTitle, cSubtitle, cTagline, cCaption, cInscription;
+
+FUNC_M("+para", para, -1);
+FUNC_M("+banner", banner, -1);
+FUNC_M("+title", title, -1);
+FUNC_M("+subtitle", subtitle, -1);
+FUNC_M("+tagline", tagline, -1);
+FUNC_M("+caption", caption, -1);
+FUNC_M("+inscription", inscription, -1);
+
+PLACE_COMMON(textblock);
+CLASS_COMMON2(textblock);
+REPLACE_COMMON(textblock);
+
+MARKUP_DEF(para, BLOCK, cPara);
+MARKUP_DEF(banner, BLOCK, cBanner);
+MARKUP_DEF(title, BLOCK, cTitle);
+MARKUP_DEF(subtitle, BLOCK, cSubtitle);
+MARKUP_DEF(tagline, BLOCK, cTagline);
+MARKUP_DEF(caption, BLOCK, cCaption);
+MARKUP_DEF(inscription, BLOCK, cInscription);
+
+static void shoes_textblock_iter_pango(VALUE texts, shoes_textblock *block, shoes_app *app);
+static void shoes_textblock_make_pango(shoes_app *app, VALUE klass, shoes_textblock *block);
+static void shoes_textblock_on_layout(shoes_app *app, VALUE klass, shoes_textblock *block);
+static void shoes_app_style_for(shoes_textblock *block, shoes_app *app, VALUE klass, VALUE oattr, guint start_index, guint end_index);
+
+void shoes_textblock_init() {
+ cTextBlock = rb_define_class_under(cTypes, "TextBlock", rb_cObject);
+
+ rb_define_alloc_func(cTextBlock, shoes_textblock_alloc);
+
+ rb_define_method(cTextBlock, "app", CASTHOOK(shoes_canvas_get_app), 0);
+ rb_define_method(cTextBlock, "contents", CASTHOOK(shoes_textblock_children), 0);
+ rb_define_method(cTextBlock, "children", CASTHOOK(shoes_textblock_children), 0);
+ rb_define_method(cTextBlock, "parent", CASTHOOK(shoes_textblock_get_parent), 0);
+ rb_define_method(cTextBlock, "displace", CASTHOOK(shoes_textblock_displace), 2);
+ rb_define_method(cTextBlock, "draw", CASTHOOK(shoes_textblock_draw), 2);
+ rb_define_method(cTextBlock, "cursor=", CASTHOOK(shoes_textblock_set_cursor), 1);
+ rb_define_method(cTextBlock, "cursor", CASTHOOK(shoes_textblock_get_cursor), 0);
+ rb_define_method(cTextBlock, "cursor_left", CASTHOOK(shoes_textblock_cursorx), 0);
+ rb_define_method(cTextBlock, "cursor_top", CASTHOOK(shoes_textblock_cursory), 0);
+ rb_define_method(cTextBlock, "highlight", CASTHOOK(shoes_textblock_get_highlight), 0);
+ rb_define_method(cTextBlock, "hit", CASTHOOK(shoes_textblock_hit), 2);
+ rb_define_method(cTextBlock, "marker=", CASTHOOK(shoes_textblock_set_marker), 1);
+ rb_define_method(cTextBlock, "marker", CASTHOOK(shoes_textblock_get_marker), 0);
+ rb_define_method(cTextBlock, "move", CASTHOOK(shoes_textblock_move), 2);
+ rb_define_method(cTextBlock, "top", CASTHOOK(shoes_textblock_get_top), 0);
+ rb_define_method(cTextBlock, "left", CASTHOOK(shoes_textblock_get_left), 0);
+ rb_define_method(cTextBlock, "width", CASTHOOK(shoes_textblock_get_width), 0);
+ rb_define_method(cTextBlock, "height", CASTHOOK(shoes_textblock_get_height), 0);
+ rb_define_method(cTextBlock, "remove", CASTHOOK(shoes_basic_remove), 0);
+ rb_define_method(cTextBlock, "to_s", CASTHOOK(shoes_textblock_string), 0);
+ rb_define_method(cTextBlock, "text", CASTHOOK(shoes_textblock_string), 0);
+ rb_define_method(cTextBlock, "text=", CASTHOOK(shoes_textblock_replace), -1);
+ rb_define_method(cTextBlock, "replace", CASTHOOK(shoes_textblock_replace), -1);
+ rb_define_method(cTextBlock, "style", CASTHOOK(shoes_textblock_style_m), -1);
+ rb_define_method(cTextBlock, "hide", CASTHOOK(shoes_textblock_hide), 0);
+ rb_define_method(cTextBlock, "show", CASTHOOK(shoes_textblock_show), 0);
+ rb_define_method(cTextBlock, "toggle", CASTHOOK(shoes_textblock_toggle), 0);
+ rb_define_method(cTextBlock, "click", CASTHOOK(shoes_textblock_click), -1);
+ rb_define_method(cTextBlock, "release", CASTHOOK(shoes_textblock_release), -1);
+ rb_define_method(cTextBlock, "hover", CASTHOOK(shoes_textblock_hover), -1);
+ rb_define_method(cTextBlock, "leave", CASTHOOK(shoes_textblock_leave), -1);
+
+ cPara = rb_define_class_under(cTypes, "Para", cTextBlock);
+ cBanner = rb_define_class_under(cTypes, "Banner", cTextBlock);
+ cTitle = rb_define_class_under(cTypes, "Title", cTextBlock);
+ cSubtitle = rb_define_class_under(cTypes, "Subtitle", cTextBlock);
+ cTagline = rb_define_class_under(cTypes, "Tagline", cTextBlock);
+ cCaption = rb_define_class_under(cTypes, "Caption", cTextBlock);
+ cInscription = rb_define_class_under(cTypes, "Inscription", cTextBlock);
+
+ RUBY_M("+para", para, -1);
+ RUBY_M("+banner", banner, -1);
+ RUBY_M("+title", title, -1);
+ RUBY_M("+subtitle", subtitle, -1);
+ RUBY_M("+tagline", tagline, -1);
+ RUBY_M("+caption", caption, -1);
+ RUBY_M("+inscription", inscription, -1);
+}
+
+// ruby
+VALUE shoes_textblock_draw(VALUE self, VALUE c, VALUE actual) {
+ double crx = 0., cry = 0.;
+ int px, py, pd, li, ld;
+ cairo_t *cr;
+ shoes_canvas *canvas;
+ PangoLayoutLine *last;
+ PangoRectangle crect, lrect;
+
+ VALUE ck = rb_obj_class(c);
+ GET_STRUCT(textblock, self_t);
+ Data_Get_Struct(c, shoes_canvas, canvas);
+ cr = CCR(canvas);
+
+ if (!NIL_P(self_t->attr) && ATTR(self_t->attr, hidden) == Qtrue)
+ return self;
+
+ ATTR_MARGINS(self_t->attr, 4, canvas);
+ if (NIL_P(ATTR(self_t->attr, margin)) && NIL_P(ATTR(self_t->attr, margin_bottom)))
+ bmargin = 12;
+ self_t->place.flags = REL_CANVAS;
+ self_t->place.flags |= NIL_P(ATTR(self_t->attr, left)) && NIL_P(ATTR(self_t->attr, right)) ? 0 : FLAG_ABSX;
+ self_t->place.flags |= NIL_P(ATTR(self_t->attr, top)) && NIL_P(ATTR(self_t->attr, bottom)) ? 0 : FLAG_ABSY;
+ self_t->place.x = ATTR2(int, self_t->attr, left, canvas->cx);
+ self_t->place.y = ATTR2(int, self_t->attr, top, canvas->cy);
+ if (!ORIGIN(canvas->place)) {
+ self_t->place.dx = canvas->place.dx;
+ self_t->place.dy = canvas->place.dy;
+ } else {
+ self_t->place.dx = 0;
+ self_t->place.dy = 0;
+ }
+ self_t->place.dx += PXN(self_t->attr, displace_left, 0, CPW(canvas));
+ self_t->place.dy += PXN(self_t->attr, displace_top, 0, CPH(canvas));
+ self_t->place.w = ATTR2(int, self_t->attr, width, canvas->place.iw - (canvas->cx - self_t->place.x));
+ self_t->place.iw = self_t->place.w - (lmargin + rmargin);
+ ld = ATTR2(int, self_t->attr, leading, 4);
+
+ if (self_t->layout != NULL)
+ g_object_unref(self_t->layout);
+
+ self_t->layout = pango_cairo_create_layout(cr);
+ pd = 0;
+ if (!ABSX(self_t->place) && self_t->place.x == canvas->cx) {
+ if (self_t->place.x - CPX(canvas) > self_t->place.w) {
+ self_t->place.x = CPX(canvas);
+ canvas->cy = self_t->place.y = canvas->endy;
+ } else {
+ if (self_t->place.x > CPX(canvas)) {
+ pd = self_t->place.x - CPX(canvas);
+ pango_layout_set_indent(self_t->layout, pd * PANGO_SCALE);
+ self_t->place.x = CPX(canvas);
+ }
+ }
+ }
+
+ pango_layout_set_width(self_t->layout, self_t->place.iw * PANGO_SCALE);
+ pango_layout_set_spacing(self_t->layout, ld * PANGO_SCALE);
+ shoes_textblock_on_layout(canvas->app, rb_obj_class(self), self_t);
+ pango_layout_set_font_description(self_t->layout, shoes_world->default_font);
+
+ //
+ // Line up the first line with the y-cursor
+ //
+ if (!ABSX(self_t->place) && !ABSY(self_t->place) && pd) {
+ last = pango_layout_get_line(self_t->layout, 0);
+ pango_layout_line_get_pixel_extents(last, NULL, &lrect);
+ if (lrect.width > self_t->place.iw - pd) {
+ pango_layout_set_indent(self_t->layout, 0);
+ self_t->place.x = CPX(canvas);
+ canvas->cy = self_t->place.y = canvas->endy;
+ pd = 0;
+ }
+ }
+ self_t->place.ix = self_t->place.x + lmargin;
+ self_t->place.iy = self_t->place.y + tmargin;
+
+ li = pango_layout_get_line_count(self_t->layout) - 1;
+ last = pango_layout_get_line(self_t->layout, li);
+ pango_layout_line_get_pixel_extents(last, NULL, &lrect);
+ pango_layout_get_pixel_size(self_t->layout, &px, &py);
+
+ if (self_t->cursor != NULL && self_t->cursor->pos != INT_MAX) {
+ int cursor = self_t->cursor->pos;
+ if (cursor < 0) cursor += self_t->text->len + 1;
+ pango_layout_index_to_pos(self_t->layout, cursor, &crect);
+ crx = (self_t->place.ix + self_t->place.dx) + (crect.x / PANGO_SCALE);
+ cry = (self_t->place.iy + self_t->place.dy) + (crect.y / PANGO_SCALE);
+ self_t->cursor->x = (int)crx;
+ self_t->cursor->y = (int)cry;
+ }
+
+ if (RTEST(actual)) {
+ shoes_apply_transformation(cr, self_t->st, &self_t->place, 0);
+ if (shoes_shape_check(cr, &self_t->place)) {
+ cairo_move_to(cr, self_t->place.ix + self_t->place.dx, self_t->place.iy + self_t->place.dy);
+ cairo_set_source_rgb(cr, 0., 0., 0.);
+ pango_cairo_update_layout(cr, self_t->layout);
+ pango_cairo_show_layout(cr, self_t->layout);
+
+ if (self_t->cursor != NULL && self_t->cursor->pos != INT_MAX) {
+ cairo_save(cr);
+ cairo_new_path(cr);
+ cairo_move_to(cr, crx, cry);
+ cairo_line_to(cr, crx, cry + (crect.height / PANGO_SCALE));
+ cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE);
+ cairo_set_source_rgb(cr, 0., 0., 0.);
+ cairo_set_line_width(cr, 1.);
+ cairo_stroke(cr);
+ cairo_restore(cr);
+ }
+ }
+
+ shoes_undo_transformation(cr, self_t->st, &self_t->place, 0);
+ }
+
+ if (li == 0) {
+ self_t->place.iw = px;
+ self_t->place.w = px + lmargin + rmargin;
+ }
+ self_t->place.ih = py;
+ self_t->place.h = py + tmargin + bmargin;
+ INFO("TEXT: %d, %d (%d, %d) / (%d: %d, %d: %d) %d, %d [%d]\n", canvas->cx, canvas->cy,
+ canvas->place.w, canvas->height, self_t->place.x, self_t->place.ix,
+ self_t->place.y, self_t->place.iy, self_t->place.w, self_t->place.h, pd);
+
+ if (!ABSY(self_t->place)) {
+ // newlines have an empty size
+ if (ck != cStack) {
+ if (li == 0) {
+ canvas->cx = self_t->place.x + lrect.x + lrect.width + rmargin + pd;
+ } else {
+ canvas->cy = self_t->place.y + py - lrect.height;
+ if (lrect.width == 0) {
+ canvas->cx = self_t->place.x + lrect.x;
+ } else {
+ canvas->cx = self_t->place.x + lrect.width + rmargin;
+ }
+ }
+ }
+
+ canvas->endy = max(self_t->place.y + self_t->place.h, canvas->endy);
+ canvas->endx = canvas->cx;
+
+ if (ck == cStack || canvas->cx - CPX(canvas) > canvas->width) {
+ canvas->cx = CPX(canvas);
+ canvas->cy = canvas->endy;
+ }
+ if (NIL_P(ATTR(self_t->attr, margin)) && NIL_P(ATTR(self_t->attr, margin_top)))
+ bmargin = lrect.height;
+
+ INFO("CX: (%d, %d) / LRECT: (%d, %d) / END: (%d, %d)\n",
+ canvas->cx, canvas->cy,
+ lrect.x, lrect.width,
+ canvas->endx, canvas->endy);
+ }
+ return self;
+}
+
+static void shoes_app_style_for(shoes_textblock *block, shoes_app *app, VALUE klass, VALUE oattr, guint start_index, guint end_index) {
+ VALUE str = Qnil;
+ VALUE hsh = rb_hash_aref(app->styles, klass);
+ if (NIL_P(hsh) && NIL_P(oattr)) return;
+
+ PangoAttribute *attr = NULL;
+
+ APPLY_STYLE_COLOR(stroke, foreground);
+ APPLY_STYLE_COLOR(fill, background);
+ APPLY_STYLE_COLOR(strikecolor, strikethrough_color);
+ APPLY_STYLE_COLOR(undercolor, underline_color);
+
+ GET_STYLE(font);
+ if (!NIL_P(str)) {
+ if (TYPE(str) == T_STRING) {
+ attr = pango_attr_font_desc_new(pango_font_description_from_string(RSTRING_PTR(str)));
+ }
+ APPLY_ATTR();
+ }
+
+ GET_STYLE(size);
+ if (!NIL_P(str)) {
+ if (TYPE(str) == T_STRING) {
+ if (strncmp(RSTRING_PTR(str), "xx-small", 8) == 0)
+ attr = pango_attr_scale_new(PANGO_SCALE_XX_SMALL);
+ else if (strncmp(RSTRING_PTR(str), "x-small", 7) == 0)
+ attr = pango_attr_scale_new(PANGO_SCALE_X_SMALL);
+ else if (strncmp(RSTRING_PTR(str), "small", 5) == 0)
+ attr = pango_attr_scale_new(PANGO_SCALE_SMALL);
+ else if (strncmp(RSTRING_PTR(str), "medium", 6) == 0)
+ attr = pango_attr_scale_new(PANGO_SCALE_MEDIUM);
+ else if (strncmp(RSTRING_PTR(str), "large", 5) == 0)
+ attr = pango_attr_scale_new(PANGO_SCALE_LARGE);
+ else if (strncmp(RSTRING_PTR(str), "x-large", 7) == 0)
+ attr = pango_attr_scale_new(PANGO_SCALE_X_LARGE);
+ else if (strncmp(RSTRING_PTR(str), "xx-large", 8) == 0)
+ attr = pango_attr_scale_new(PANGO_SCALE_XX_LARGE);
+ else
+ str = rb_funcall(str, s_to_i, 0);
+ }
+ if (TYPE(str) == T_FIXNUM) {
+ int i = NUM2INT(str);
+ if (i > 0)
+ attr = pango_attr_size_new_absolute(ROUND(i * PANGO_SCALE * (96./72.)));
+ }
+ APPLY_ATTR();
+ }
+
+ GET_STYLE(family);
+ if (!NIL_P(str)) {
+ if (TYPE(str) == T_STRING) {
+ attr = pango_attr_family_new(RSTRING_PTR(str));
+ }
+ APPLY_ATTR();
+ }
+
+ GET_STYLE(weight);
+ if (!NIL_P(str)) {
+ if (TYPE(str) == T_STRING) {
+ if (strncmp(RSTRING_PTR(str), "ultralight", 10) == 0)
+ attr = pango_attr_weight_new(PANGO_WEIGHT_ULTRALIGHT);
+ else if (strncmp(RSTRING_PTR(str), "light", 5) == 0)
+ attr = pango_attr_weight_new(PANGO_WEIGHT_LIGHT);
+ else if (strncmp(RSTRING_PTR(str), "normal", 6) == 0)
+ attr = pango_attr_weight_new(PANGO_WEIGHT_NORMAL);
+ else if (strncmp(RSTRING_PTR(str), "semibold", 8) == 0)
+ attr = pango_attr_weight_new(PANGO_WEIGHT_SEMIBOLD);
+ else if (strncmp(RSTRING_PTR(str), "bold", 4) == 0)
+ attr = pango_attr_weight_new(PANGO_WEIGHT_BOLD);
+ else if (strncmp(RSTRING_PTR(str), "ultrabold", 9) == 0)
+ attr = pango_attr_weight_new(PANGO_WEIGHT_ULTRABOLD);
+ else if (strncmp(RSTRING_PTR(str), "heavy", 5) == 0)
+ attr = pango_attr_weight_new(PANGO_WEIGHT_HEAVY);
+ } else if (TYPE(str) == T_FIXNUM) {
+ int i = NUM2INT(str);
+ if (i >= 100 && i <= 900)
+ attr = pango_attr_weight_new((PangoWeight)i);
+ }
+ APPLY_ATTR();
+ }
+
+ GET_STYLE(rise);
+ if (!NIL_P(str)) {
+ if (TYPE(str) == T_STRING)
+ str = rb_funcall(str, s_to_i, 0);
+ if (TYPE(str) == T_FIXNUM) {
+ int i = NUM2INT(str);
+ attr = pango_attr_rise_new(i * PANGO_SCALE);
+ }
+ APPLY_ATTR();
+ }
+
+ GET_STYLE(kerning);
+ if (!NIL_P(str)) {
+ if (TYPE(str) == T_STRING)
+ str = rb_funcall(str, s_to_i, 0);
+ if (TYPE(str) == T_FIXNUM) {
+ int i = NUM2INT(str);
+ attr = pango_attr_letter_spacing_new(i * PANGO_SCALE);
+ }
+ APPLY_ATTR();
+ }
+
+ GET_STYLE(emphasis);
+ if (!NIL_P(str)) {
+ if (TYPE(str) == T_STRING) {
+ if (strncmp(RSTRING_PTR(str), "normal", 6) == 0)
+ attr = pango_attr_style_new(PANGO_STYLE_NORMAL);
+ else if (strncmp(RSTRING_PTR(str), "oblique", 7) == 0)
+ attr = pango_attr_style_new(PANGO_STYLE_OBLIQUE);
+ else if (strncmp(RSTRING_PTR(str), "italic", 6) == 0)
+ attr = pango_attr_style_new(PANGO_STYLE_ITALIC);
+ }
+ APPLY_ATTR();
+ }
+
+ GET_STYLE(strikethrough);
+ if (!NIL_P(str)) {
+ if (TYPE(str) == T_STRING) {
+ if (strncmp(RSTRING_PTR(str), "none", 4) == 0)
+ attr = pango_attr_strikethrough_new(FALSE);
+ else if (strncmp(RSTRING_PTR(str), "single", 6) == 0)
+ attr = pango_attr_strikethrough_new(TRUE);
+ }
+ APPLY_ATTR();
+ }
+
+ GET_STYLE(stretch);
+ if (!NIL_P(str)) {
+ if (TYPE(str) == T_STRING) {
+ if (strncmp(RSTRING_PTR(str), "condensed", 9) == 0)
+ attr = pango_attr_stretch_new(PANGO_STRETCH_CONDENSED);
+ else if (strncmp(RSTRING_PTR(str), "normal", 6) == 0)
+ attr = pango_attr_stretch_new(PANGO_STRETCH_NORMAL);
+ else if (strncmp(RSTRING_PTR(str), "expanded", 8) == 0)
+ attr = pango_attr_stretch_new(PANGO_STRETCH_EXPANDED);
+ }
+ APPLY_ATTR();
+ }
+
+ GET_STYLE(underline);
+ if (!NIL_P(str)) {
+ if (TYPE(str) == T_STRING) {
+ if (strncmp(RSTRING_PTR(str), "none", 4) == 0)
+ attr = pango_attr_underline_new(PANGO_UNDERLINE_NONE);
+ else if (strncmp(RSTRING_PTR(str), "single", 6) == 0)
+ attr = pango_attr_underline_new(PANGO_UNDERLINE_SINGLE);
+ else if (strncmp(RSTRING_PTR(str), "double", 6) == 0)
+ attr = pango_attr_underline_new(PANGO_UNDERLINE_DOUBLE);
+ else if (strncmp(RSTRING_PTR(str), "low", 3) == 0)
+ attr = pango_attr_underline_new(PANGO_UNDERLINE_LOW);
+ else if (strncmp(RSTRING_PTR(str), "error", 5) == 0)
+ attr = pango_attr_underline_new(PANGO_UNDERLINE_ERROR);
+ }
+ APPLY_ATTR();
+ }
+
+ GET_STYLE(variant);
+ if (!NIL_P(str)) {
+ if (TYPE(str) == T_STRING) {
+ if (strncmp(RSTRING_PTR(str), "normal", 6) == 0)
+ attr = pango_attr_variant_new(PANGO_VARIANT_NORMAL);
+ else if (strncmp(RSTRING_PTR(str), "smallcaps", 9) == 0)
+ attr = pango_attr_variant_new(PANGO_VARIANT_SMALL_CAPS);
+ }
+ APPLY_ATTR();
+ }
+}
+
+VALUE shoes_textblock_string(VALUE self) {
+ shoes_canvas *canvas;
+ GET_STRUCT(textblock, self_t);
+ Data_Get_Struct(self_t->parent, shoes_canvas, canvas);
+ if (!self_t->cached || self_t->pattr == NULL)
+ shoes_textblock_make_pango(canvas->app, rb_obj_class(self), self_t);
+ return rb_str_new(self_t->text->str, self_t->text->len);
+}
+
+static void shoes_textblock_iter_pango(VALUE texts, shoes_textblock *block, shoes_app *app) {
+ VALUE v;
+ long i;
+
+ if (NIL_P(texts))
+ return;
+
+ for (i = 0; i < RARRAY_LEN(texts); i++) {
+ v = rb_ary_entry(texts, i);
+ if (rb_obj_is_kind_of(v, cTextClass)) {
+ VALUE tklass = rb_obj_class(v);
+ guint start;
+ shoes_text *text;
+ Data_Get_Struct(v, shoes_text, text);
+
+ start = block->len;
+ shoes_textblock_iter_pango(text->texts, block, app);
+ if ((text->hover & HOVER_MOTION) && tklass == cLink)
+ tklass = cLinkHover;
+ shoes_app_style_for(block, app, tklass, text->attr, start, block->len);
+ if (!block->cached && rb_obj_is_kind_of(v, cLink) && !NIL_P(text->attr)) {
+ rb_ary_push(block->links, shoes_link_new(v, start, block->len));
+ }
+ } else if (rb_obj_is_kind_of(v, rb_cArray)) {
+ shoes_textblock_iter_pango(v, block, app);
+ } else {
+ char *start, *end;
+ v = rb_funcall(v, s_to_s, 0);
+ block->len += (guint)RSTRING_LEN(v);
+ if (!block->cached) {
+ start = RSTRING_PTR(v);
+ if (!g_utf8_validate(start, RSTRING_LEN(v), (const gchar **)&end))
+ shoes_error("not a valid UTF-8 string: %.*s", end - start, start);
+ if (end > start)
+ g_string_append_len(block->text, start, end - start);
+ }
+ }
+ }
+}
+
+static void shoes_textblock_make_pango(shoes_app *app, VALUE klass, shoes_textblock *block) {
+ if (!block->cached) {
+ block->text = g_string_new(NULL);
+ block->links = rb_ary_new();
+ }
+ block->len = 0;
+ block->pattr = pango_attr_list_new();
+
+ shoes_textblock_iter_pango(block->texts, block, app);
+ shoes_app_style_for(block, app, klass, block->attr, 0, block->len);
+
+ if (block->cursor != NULL && block->cursor->pos != INT_MAX &&
+ block->cursor->hi != INT_MAX && block->cursor->pos != block->cursor->hi) {
+ PangoAttribute *attr = pango_attr_background_new(255 * 255, 255 * 255, 0);
+ attr->start_index = min(block->cursor->pos, block->cursor->hi);
+ attr->end_index = max(block->cursor->pos, block->cursor->hi);
+ pango_attr_list_insert(block->pattr, attr);
+ }
+
+ block->cached = 1;
+}
+
+static void shoes_textblock_on_layout(shoes_app *app, VALUE klass, shoes_textblock *block) {
+ char *attr = NULL;
+ VALUE str = Qnil, hsh = Qnil, oattr = Qnil;
+ g_return_if_fail(block != NULL);
+ g_return_if_fail(PANGO_IS_LAYOUT(block->layout));
+
+ oattr = block->attr;
+ hsh = rb_hash_aref(app->styles, klass);
+
+ if (!block->cached || block->pattr == NULL)
+ shoes_textblock_make_pango(app, klass, block);
+ pango_layout_set_text(block->layout, block->text->str, -1);
+ pango_layout_set_attributes(block->layout, block->pattr);
+
+ GET_STYLE(justify);
+ if (!NIL_P(str))
+ pango_layout_set_justify(block->layout, RTEST(str));
+
+ GET_STYLE(align);
+ if (TYPE(str) == T_STRING) {
+ if (strncmp(RSTRING_PTR(str), "left", 4) == 0)
+ pango_layout_set_alignment(block->layout, PANGO_ALIGN_LEFT);
+ else if (strncmp(RSTRING_PTR(str), "center", 6) == 0)
+ pango_layout_set_alignment(block->layout, PANGO_ALIGN_CENTER);
+ else if (strncmp(RSTRING_PTR(str), "right", 5) == 0)
+ pango_layout_set_alignment(block->layout, PANGO_ALIGN_RIGHT);
+ }
+
+ GET_STYLE(wrap);
+ if (TYPE(str) == T_STRING) {
+ if (strncmp(RSTRING_PTR(str), "word", 4) == 0)
+ pango_layout_set_wrap(block->layout, PANGO_WRAP_WORD);
+ else if (strncmp(RSTRING_PTR(str), "char", 4) == 0)
+ pango_layout_set_wrap(block->layout, PANGO_WRAP_CHAR);
+ else if (strncmp(RSTRING_PTR(str), "trim", 4) == 0)
+ pango_layout_set_ellipsize(block->layout, PANGO_ELLIPSIZE_END);
+ }
+}
+
+VALUE shoes_textblock_style_m(int argc, VALUE *argv, VALUE self) {
+ GET_STRUCT(textblock, self_t);
+ VALUE obj = shoes_textblock_style(argc, argv, self);
+ shoes_textblock_uncache(self_t, FALSE);
+ return obj;
+}
+
+void shoes_textblock_mark(shoes_textblock *text) {
+ rb_gc_mark_maybe(text->texts);
+ rb_gc_mark_maybe(text->links);
+ rb_gc_mark_maybe(text->attr);
+ rb_gc_mark_maybe(text->parent);
+}
+
+//
+// Frees the pango attribute list.
+// The `all` flag means the string has changed as well.
+//
+void shoes_textblock_uncache(shoes_textblock *text, unsigned char all) {
+ if (text->pattr != NULL)
+ pango_attr_list_unref(text->pattr);
+ text->pattr = NULL;
+ if (all) {
+ if (text->text != NULL)
+ g_string_free(text->text, TRUE);
+ text->text = NULL;
+ text->cached = 0;
+ }
+}
+
+void shoes_textblock_free(shoes_textblock *text) {
+ shoes_transform_release(text->st);
+ shoes_textblock_uncache(text, TRUE);
+ if (text->cursor != NULL)
+ SHOE_FREE(text->cursor);
+ if (text->layout != NULL)
+ g_object_unref(text->layout);
+ RUBY_CRITICAL(free(text));
+}
+
+VALUE shoes_textblock_new(VALUE klass, VALUE texts, VALUE attr, VALUE parent, shoes_transform *st) {
+ shoes_canvas *canvas;
+ shoes_textblock *text;
+ VALUE obj = shoes_textblock_alloc(klass);
+ Data_Get_Struct(obj, shoes_textblock, text);
+ Data_Get_Struct(parent, shoes_canvas, canvas);
+ text->texts = shoes_text_check(texts, obj);
+ text->attr = attr;
+ text->parent = parent;
+ text->st = shoes_transform_touch(st);
+ return obj;
+}
+
+VALUE shoes_textblock_alloc(VALUE klass) {
+ VALUE obj;
+ shoes_textblock *text = SHOE_ALLOC(shoes_textblock);
+ SHOE_MEMZERO(text, shoes_textblock, 1);
+ obj = Data_Wrap_Struct(klass, shoes_textblock_mark, shoes_textblock_free, text);
+ text->texts = Qnil;
+ text->links = Qnil;
+ text->attr = Qnil;
+ text->parent = Qnil;
+ text->cursor = NULL;
+ return obj;
+}
+
+VALUE shoes_textblock_children(VALUE self) {
+ GET_STRUCT(textblock, text);
+ return text->texts;
+}
+
+static void shoes_textcursor_reset(shoes_textcursor *c) {
+ c->pos = c->hi = c->x = c->y = INT_MAX;
+}
+
+VALUE shoes_textblock_set_cursor(VALUE self, VALUE pos) {
+ GET_STRUCT(textblock, self_t);
+ if (self_t->cursor == NULL) {
+ if (NIL_P(pos)) return Qnil;
+ else shoes_textcursor_reset(self_t->cursor = SHOE_ALLOC(shoes_textcursor));
+ }
+
+ if (NIL_P(pos)) shoes_textcursor_reset(self_t->cursor);
+ else if (pos == ID2SYM(s_marker)) {
+ if (self_t->cursor->hi != INT_MAX) {
+ self_t->cursor->pos = min(self_t->cursor->pos, self_t->cursor->hi);
+ self_t->cursor->hi = INT_MAX;
+ }
+ } else self_t->cursor->pos = NUM2INT(pos);
+ shoes_textblock_uncache(self_t, FALSE);
+ shoes_canvas_repaint_all(self_t->parent);
+ return pos;
+}
+
+VALUE shoes_textblock_get_cursor(VALUE self) {
+ GET_STRUCT(textblock, self_t);
+ if (self_t->cursor == NULL || self_t->cursor->pos == INT_MAX) return Qnil;
+ return INT2NUM(self_t->cursor->pos);
+}
+
+VALUE shoes_textblock_cursorx(VALUE self) {
+ GET_STRUCT(textblock, self_t);
+ if (self_t->cursor == NULL || self_t->cursor->x == INT_MAX) return Qnil;
+ return INT2NUM(self_t->cursor->x);
+}
+
+VALUE shoes_textblock_cursory(VALUE self) {
+ GET_STRUCT(textblock, self_t);
+ if (self_t->cursor == NULL || self_t->cursor->y == INT_MAX) return Qnil;
+ return INT2NUM(self_t->cursor->y);
+}
+
+VALUE shoes_textblock_set_marker(VALUE self, VALUE pos) {
+ GET_STRUCT(textblock, self_t);
+ if (self_t->cursor == NULL) {
+ if (NIL_P(pos)) return Qnil;
+ else shoes_textcursor_reset(self_t->cursor = SHOE_ALLOC(shoes_textcursor));
+ }
+
+ if (NIL_P(pos)) self_t->cursor->hi = INT_MAX;
+ else self_t->cursor->hi = NUM2INT(pos);
+ shoes_textblock_uncache(self_t, FALSE);
+ shoes_canvas_repaint_all(self_t->parent);
+ return pos;
+}
+
+VALUE shoes_textblock_get_marker(VALUE self) {
+ GET_STRUCT(textblock, self_t);
+ if (self_t->cursor == NULL || self_t->cursor->hi == INT_MAX) return Qnil;
+ return INT2NUM(self_t->cursor->hi);
+}
+
+VALUE shoes_textblock_get_highlight(VALUE self) {
+ int marker, start, len;
+ GET_STRUCT(textblock, self_t);
+ if (self_t->cursor == NULL || self_t->cursor->pos == INT_MAX) return Qnil;
+ marker = self_t->cursor->hi;
+ if (marker == INT_MAX) marker = self_t->cursor->pos;
+ start = min(self_t->cursor->pos, marker);
+ len = max(self_t->cursor->pos, marker) - start;
+ return rb_ary_new3(2, INT2NUM(start), INT2NUM(len));
+}
+
+VALUE shoes_find_textblock(VALUE self) {
+ while (!NIL_P(self) && !rb_obj_is_kind_of(self, cTextBlock)) {
+ SETUP_BASIC();
+ self = basic->parent;
+ }
+ return self;
+}
+
+VALUE shoes_textblock_send_hover(VALUE self, int x, int y, VALUE *clicked, char *t) {
+ VALUE url = Qnil;
+ int index, trailing, i, hover;
+ GET_STRUCT(textblock, self_t);
+ if (self_t->layout == NULL || NIL_P(self_t->links)) return Qnil;
+ if (!NIL_P(self_t->attr) && ATTR(self_t->attr, hidden) == Qtrue) return Qnil;
+
+ x -= self_t->place.ix + self_t->place.dx;
+ y -= self_t->place.iy + self_t->place.dy;
+ hover = pango_layout_xy_to_index(self_t->layout, x * PANGO_SCALE, y * PANGO_SCALE, &index, &trailing);
+ if (hover != (self_t->hover & HOVER_MOTION)) {
+ shoes_textblock_uncache(self_t, FALSE);
+ INFO("HOVER (%d, %d) OVER (%d, %d)\n", x, y, self_t->place.ix + self_t->place.dx, self_t->place.iy + self_t->place.dy);
+ }
+ for (i = 0; i < RARRAY_LEN(self_t->links); i++) {
+ VALUE urll = shoes_link_at(self_t, rb_ary_entry(self_t->links, i), index, hover, clicked, t);
+ if (NIL_P(url)) url = urll;
+ }
+
+ return url;
+}
+
+VALUE shoes_textblock_motion(VALUE self, int x, int y, char *t) {
+ VALUE url = shoes_textblock_send_hover(self, x, y, NULL, t);
+ if (!NIL_P(url)) {
+ shoes_canvas *canvas;
+ GET_STRUCT(textblock, self_t);
+ Data_Get_Struct(self_t->parent, shoes_canvas, canvas);
+ shoes_app_cursor(canvas->app, s_link);
+ }
+ return url;
+}
+
+VALUE shoes_textblock_hit(VALUE self, VALUE _x, VALUE _y) {
+ int x = NUM2INT(_x), y = NUM2INT(_y), index, trailing;
+ GET_STRUCT(textblock, self_t);
+ x -= self_t->place.ix + self_t->place.dx;
+ y -= self_t->place.iy + self_t->place.dy;
+ if (x < 0 || x > self_t->place.iw || y < 0 || y > self_t->place.ih)
+ return Qnil;
+ pango_layout_xy_to_index(self_t->layout, x * PANGO_SCALE, y * PANGO_SCALE, &index, &trailing);
+ return INT2NUM(index);
+}
+
+VALUE shoes_textblock_send_click(VALUE self, int button, int x, int y, VALUE *clicked) {
+ VALUE v = Qnil;
+
+ if (button > 0) {
+ GET_STRUCT(textblock, self_t);
+ v = shoes_textblock_send_hover(self, x, y, clicked, NULL);
+ if (self_t->hover & HOVER_MOTION)
+ self_t->hover = HOVER_MOTION | HOVER_CLICK;
+ }
+
+ return v;
+}
+
+void shoes_textblock_send_release(VALUE self, int button, int x, int y) {
+ GET_STRUCT(textblock, self_t);
+ if (button > 0 && (self_t->hover & HOVER_CLICK)) {
+ VALUE proc = ATTR(self_t->attr, release);
+ self_t->hover ^= HOVER_CLICK;
+ if (!NIL_P(proc))
+ shoes_safe_block(self, proc, rb_ary_new3(1, self));
+ }
+}
diff --git a/shoes/types/textblock.h b/shoes/types/textblock.h
new file mode 100644
index 00000000..f7916682
--- /dev/null
+++ b/shoes/types/textblock.h
@@ -0,0 +1,101 @@
+#include "shoes/ruby.h"
+#include "shoes/canvas.h"
+#include "shoes/app.h"
+#include "shoes/internal.h"
+#include "shoes/world.h"
+#include "shoes/native/native.h"
+
+#ifndef SHOES_TEXTBLOCK_TYPE_H
+#define SHOES_TEXTBLOCK_TYPE_H
+
+/* extern variables necessary to communicate with other parts of Shoes */
+extern VALUE cShoes, cApp, cTypes, cCanvas, cWidget;
+extern shoes_app _shoes_app;
+
+VALUE cTextBlock, cPara, cBanner, cTitle, cSubtitle, cTagline, cCaption, cInscription;
+
+typedef struct {
+ int pos, x, y, hi;
+} shoes_textcursor;
+
+typedef struct {
+ VALUE parent;
+ VALUE attr;
+ shoes_place place;
+ VALUE texts;
+ VALUE links;
+ shoes_textcursor *cursor;
+ PangoLayout *layout;
+ PangoAttrList *pattr;
+ GString *text;
+ guint len;
+ char cached, hover;
+ shoes_transform *st;
+} shoes_textblock;
+
+/* each widget should have its own init function */
+void shoes_textblock_init();
+
+// ruby
+VALUE shoes_textblock_draw(VALUE self, VALUE c, VALUE actual);
+VALUE shoes_textblock_string(VALUE self);
+VALUE shoes_textblock_style_m(int argc, VALUE *argv, VALUE self);
+void shoes_textblock_mark(shoes_textblock *text);
+void shoes_textblock_uncache(shoes_textblock *text, unsigned char all);
+void shoes_textblock_free(shoes_textblock *text);
+VALUE shoes_textblock_new(VALUE klass, VALUE texts, VALUE attr, VALUE parent, shoes_transform *st);
+VALUE shoes_textblock_alloc(VALUE klass);
+VALUE shoes_textblock_children(VALUE self);
+VALUE shoes_textblock_set_cursor(VALUE self, VALUE pos);
+VALUE shoes_textblock_get_cursor(VALUE self);
+VALUE shoes_textblock_cursorx(VALUE self);
+VALUE shoes_textblock_cursory(VALUE self);
+VALUE shoes_textblock_set_marker(VALUE self, VALUE pos);
+VALUE shoes_textblock_get_marker(VALUE self);
+VALUE shoes_textblock_get_highlight(VALUE self);
+VALUE shoes_find_textblock(VALUE self);
+VALUE shoes_textblock_send_hover(VALUE self, int x, int y, VALUE *clicked, char *t);
+VALUE shoes_textblock_motion(VALUE self, int x, int y, char *t);
+VALUE shoes_textblock_hit(VALUE self, VALUE _x, VALUE _y);
+VALUE shoes_textblock_send_click(VALUE self, int button, int x, int y, VALUE *clicked);
+void shoes_textblock_send_release(VALUE self, int button, int x, int y);
+
+// canvas
+VALUE shoes_canvas_para(int argc, VALUE *argv, VALUE self);
+VALUE shoes_canvas_banner(int argc, VALUE *argv, VALUE self);
+VALUE shoes_canvas_title(int argc, VALUE *argv, VALUE self);
+VALUE shoes_canvas_subtitle(int argc, VALUE *argv, VALUE self);
+VALUE shoes_canvas_tagline(int argc, VALUE *argv, VALUE self);
+VALUE shoes_canvas_caption(int argc, VALUE *argv, VALUE self);
+VALUE shoes_canvas_inscription(int argc, VALUE *argv, VALUE self);
+
+#define GET_STYLE(name) \
+ attr = NULL; \
+ str = Qnil; \
+ if (!NIL_P(oattr)) str = rb_hash_aref(oattr, ID2SYM(s_##name)); \
+ if (!NIL_P(hsh) && NIL_P(str)) str = rb_hash_aref(hsh, ID2SYM(s_##name))
+
+#define APPLY_ATTR() \
+ if (attr != NULL) { \
+ attr->start_index = start_index; \
+ attr->end_index = end_index; \
+ pango_attr_list_insert_before(block->pattr, attr); \
+ attr = NULL; \
+ }
+
+#define APPLY_STYLE_COLOR(name, func) \
+ GET_STYLE(name); \
+ if (!NIL_P(str)) \
+ { \
+ if (TYPE(str) == T_STRING) \
+ str = shoes_color_parse(cColor, str); \
+ if (rb_obj_is_kind_of(str, cColor)) \
+ { \
+ shoes_color *color; \
+ Data_Get_Struct(str, shoes_color, color); \
+ attr = pango_attr_##func##_new(color->r * 255, color->g * 255, color-> b * 255); \
+ } \
+ APPLY_ATTR(); \
+ }
+
+#endif
diff --git a/shoes/types/timerbase.c b/shoes/types/timerbase.c
new file mode 100644
index 00000000..c038228e
--- /dev/null
+++ b/shoes/types/timerbase.c
@@ -0,0 +1,156 @@
+#include "shoes/types/timerbase.h"
+
+// ruby
+VALUE cTimerBase, cTimer, cEvery, cAnim;
+
+FUNC_M("+animate", animate, -1);
+FUNC_M("+every", every, -1);
+FUNC_M("+timer", timer, -1);
+
+void shoes_timerbase_init() {
+ cTimerBase = rb_define_class_under(cTypes, "TimerBase", rb_cObject);
+
+ rb_define_alloc_func(cTimerBase, shoes_timer_alloc);
+ rb_define_method(cTimerBase, "draw", CASTHOOK(shoes_timer_draw), 2);
+ rb_define_method(cTimerBase, "remove", CASTHOOK(shoes_timer_remove), 0);
+ rb_define_method(cTimerBase, "start", CASTHOOK(shoes_timer_start), 0);
+ rb_define_method(cTimerBase, "stop", CASTHOOK(shoes_timer_stop), 0);
+ rb_define_method(cTimerBase, "toggle", CASTHOOK(shoes_timer_toggle), 0);
+
+ cAnim = rb_define_class_under(cTypes, "Animation", cTimerBase);
+ cEvery = rb_define_class_under(cTypes, "Every", cTimerBase);
+ cTimer = rb_define_class_under(cTypes, "Timer", cTimerBase);
+
+ RUBY_M("+animate", animate, -1);
+ RUBY_M("+every", every, -1);
+ RUBY_M("+timer", timer, -1);
+}
+
+// ruby
+VALUE shoes_timer_draw(VALUE self, VALUE c, VALUE actual) {
+ shoes_canvas *canvas;
+ GET_STRUCT(timer, self_t);
+ Data_Get_Struct(self_t->parent, shoes_canvas, canvas);
+ if (RTEST(actual) && self_t->started == ANIM_NADA) {
+ self_t->frame = 0;
+ shoes_timer_start(self);
+ }
+ return self;
+}
+
+void shoes_timer_call(VALUE self) {
+ GET_STRUCT(timer, timer);
+ shoes_safe_block(timer->parent, timer->block, rb_ary_new3(1, INT2NUM(timer->frame)));
+ timer->frame++;
+
+ if (rb_obj_is_kind_of(self, cTimer)) {
+ timer->ref = 0;
+ timer->started = ANIM_STOPPED;
+ }
+}
+
+void shoes_timer_mark(shoes_timer *timer) {
+ rb_gc_mark_maybe(timer->block);
+ rb_gc_mark_maybe(timer->parent);
+}
+
+void shoes_timer_free(shoes_timer *timer) {
+ RUBY_CRITICAL(free(timer));
+}
+
+VALUE shoes_timer_new(VALUE klass, VALUE rate, VALUE block, VALUE parent) {
+ shoes_timer *timer;
+ VALUE obj = shoes_timer_alloc(klass);
+ Data_Get_Struct(obj, shoes_timer, timer);
+ timer->block = block;
+ if (!NIL_P(rate)) {
+ if (klass == cAnim)
+ timer->rate = 1000 / NUM2INT(rate);
+ else
+ timer->rate = (int)(1000. * NUM2DBL(rate));
+ }
+ if (timer->rate < 1) timer->rate = 1;
+ timer->parent = parent;
+ return obj;
+}
+
+VALUE shoes_timer_alloc(VALUE klass) {
+ VALUE obj;
+ shoes_timer *timer = SHOE_ALLOC(shoes_timer);
+ SHOE_MEMZERO(timer, shoes_timer, 1);
+ obj = Data_Wrap_Struct(klass, shoes_timer_mark, shoes_timer_free, timer);
+ timer->block = Qnil;
+ timer->rate = 1000 / 12; // 12 frames per second
+ timer->parent = Qnil;
+ timer->started = ANIM_NADA;
+ return obj;
+}
+
+VALUE shoes_timer_remove(VALUE self) {
+ GET_STRUCT(timer, self_t);
+ shoes_timer_stop(self);
+ shoes_canvas_remove_item(self_t->parent, self, 0, 1);
+ return self;
+}
+
+VALUE shoes_timer_stop(VALUE self) {
+ GET_STRUCT(timer, self_t);
+ if (self_t->started == ANIM_STARTED) {
+ shoes_canvas *canvas;
+ Data_Get_Struct(self_t->parent, shoes_canvas, canvas);
+ shoes_native_timer_remove(canvas, self_t->ref);
+ self_t->started = ANIM_PAUSED;
+ }
+ return self;
+}
+
+VALUE shoes_timer_start(VALUE self) {
+ GET_STRUCT(timer, self_t);
+ unsigned int interval = self_t->rate;
+ if (self_t->started != ANIM_STARTED) {
+ shoes_canvas *canvas;
+ Data_Get_Struct(self_t->parent, shoes_canvas, canvas);
+ self_t->ref = shoes_native_timer_start(self, canvas, interval);
+ self_t->started = ANIM_STARTED;
+ }
+ return self;
+}
+
+VALUE shoes_timer_toggle(VALUE self) {
+ GET_STRUCT(timer, self_t);
+ return self_t->started == ANIM_STARTED ? shoes_timer_stop(self) : shoes_timer_start(self);
+}
+
+// canvas
+VALUE shoes_canvas_animate(int argc, VALUE *argv, VALUE self) {
+ rb_arg_list args;
+ VALUE anim;
+ SETUP_CANVAS();
+
+ rb_parse_args(argc, argv, "|I&", &args);
+ anim = shoes_timer_new(cAnim, args.a[0], args.a[1], self);
+ rb_ary_push(canvas->app->extras, anim);
+ return anim;
+}
+
+VALUE shoes_canvas_every(int argc, VALUE *argv, VALUE self) {
+ rb_arg_list args;
+ VALUE ev;
+ SETUP_CANVAS();
+
+ rb_parse_args(argc, argv, "|F&", &args);
+ ev = shoes_timer_new(cEvery, args.a[0], args.a[1], self);
+ rb_ary_push(canvas->app->extras, ev);
+ return ev;
+}
+
+VALUE shoes_canvas_timer(int argc, VALUE *argv, VALUE self) {
+ rb_arg_list args;
+ VALUE timer;
+ SETUP_CANVAS();
+
+ rb_parse_args(argc, argv, "|I&", &args);
+ timer = shoes_timer_new(cTimer, args.a[0], args.a[1], self);
+ rb_ary_push(canvas->app->extras, timer);
+ return timer;
+}
\ No newline at end of file
diff --git a/shoes/types/timerbase.h b/shoes/types/timerbase.h
new file mode 100644
index 00000000..65bede64
--- /dev/null
+++ b/shoes/types/timerbase.h
@@ -0,0 +1,53 @@
+#include "shoes/ruby.h"
+#include "shoes/canvas.h"
+#include "shoes/app.h"
+#include "shoes/internal.h"
+#include "shoes/world.h"
+#include "shoes/native/native.h"
+
+#ifndef SHOES_TIMERBASE_TYPE_H
+#define SHOES_TIMERBASE_TYPE_H
+
+/* extern variables necessary to communicate with other parts of Shoes */
+extern VALUE cShoes, cApp, cTypes, cCanvas, cWidget;
+extern shoes_app _shoes_app;
+
+// native forward declarations
+extern SHOES_TIMER_REF shoes_native_timer_start(VALUE self, shoes_canvas *canvas, unsigned int interval);
+extern void shoes_native_timer_remove(shoes_canvas *canvas, SHOES_TIMER_REF ref);
+
+#define ANIM_NADA 0
+#define ANIM_STARTED 1
+#define ANIM_PAUSED 2
+#define ANIM_STOPPED 3
+
+typedef struct {
+ VALUE parent;
+ VALUE block;
+ unsigned int rate, frame;
+ char started;
+ SHOES_TIMER_REF ref;
+} shoes_timer;
+
+/* each widget should have its own init function */
+void shoes_timerbase_init();
+
+// ruby
+VALUE shoes_timer_draw(VALUE self, VALUE c, VALUE actual);
+VALUE shoes_timer_stop(VALUE self);
+VALUE shoes_timer_start(VALUE self);
+VALUE shoes_timer_toggle(VALUE self);
+
+void shoes_timer_call(VALUE self);
+void shoes_timer_mark(shoes_timer *timer);
+void shoes_timer_free(shoes_timer *timer);
+VALUE shoes_timer_new(VALUE klass, VALUE rate, VALUE block, VALUE parent);
+VALUE shoes_timer_alloc(VALUE klass);
+VALUE shoes_timer_remove(VALUE self);
+
+// canvas
+VALUE shoes_canvas_animate(int argc, VALUE *argv, VALUE self);
+VALUE shoes_canvas_every(int argc, VALUE *argv, VALUE self);
+VALUE shoes_canvas_timer(int argc, VALUE *argv, VALUE self);
+
+#endif
diff --git a/shoes/types/types.h b/shoes/types/types.h
new file mode 100644
index 00000000..7a5bd135
--- /dev/null
+++ b/shoes/types/types.h
@@ -0,0 +1,54 @@
+#include "shoes/types/button.h"
+#include "shoes/types/check.h"
+#include "shoes/types/color.h"
+#include "shoes/types/download.h"
+#include "shoes/types/edit_box.h"
+#include "shoes/types/edit_line.h"
+#include "shoes/types/effect.h"
+#include "shoes/types/image.h"
+#include "shoes/types/list_box.h"
+#include "shoes/types/native.h"
+#include "shoes/types/pattern.h"
+#include "shoes/types/plot.h"
+#include "shoes/types/progress.h"
+#include "shoes/types/radio.h"
+#include "shoes/types/shape.h"
+#include "shoes/types/slider.h"
+#include "shoes/types/spinner.h"
+#include "shoes/types/svg.h"
+#include "shoes/types/switch.h"
+#include "shoes/types/systray.h"
+#include "shoes/types/text.h"
+#include "shoes/types/text_link.h"
+#include "shoes/types/text_view.h"
+#include "shoes/types/textblock.h"
+#include "shoes/types/timerbase.h"
+#include "shoes/types/video.h"
+
+#define SHOES_TYPES_INIT \
+ shoes_0_native_type_init(); \
+ shoes_button_init(); \
+ shoes_check_init(); \
+ shoes_color_init(); \
+ shoes_download_init(); \
+ shoes_edit_box_init(); \
+ shoes_edit_line_init(); \
+ shoes_effect_init(); \
+ shoes_image_init(); \
+ shoes_list_box_init(); \
+ shoes_pattern_init(); \
+ shoes_plot_init(); \
+ shoes_progress_init(); \
+ shoes_radio_init(); \
+ shoes_shape_init(); \
+ shoes_slider_init(); \
+ shoes_spinner_init(); \
+ shoes_svg_init(); \
+ shoes_switch_init(); \
+ shoes_systray_init(); \
+ shoes_text_init(); \
+ shoes_text_link_init(); \
+ shoes_text_view_init(); \
+ shoes_textblock_init(); \
+ shoes_timerbase_init(); \
+ shoes_video_init();
diff --git a/shoes/types/video.c b/shoes/types/video.c
new file mode 100644
index 00000000..4ac3a3c4
--- /dev/null
+++ b/shoes/types/video.c
@@ -0,0 +1,270 @@
+#include "shoes/types/video.h"
+#include "shoes/types/native.h"
+#include "shoes/native/native.h"
+#include "shoes/ruby.h"
+
+VALUE cVideo, eVlcError;
+
+FUNC_M("+video", video, -1);
+
+#ifdef VIDEO_C_VLC
+PLACE_COMMON(video)
+CLASS_COMMON(video)
+#endif
+
+void shoes_video_init() {
+ cVideo = rb_define_class_under(cTypes, "Video", rb_cObject);
+
+ rb_define_alloc_func(cVideo, shoes_video_alloc);
+ rb_define_method(cVideo, "draw", CASTHOOK(shoes_video_draw), 2);
+ rb_define_method(cVideo, "parent", CASTHOOK(shoes_video_get_parent), 0);
+ rb_define_method(cVideo, "drawable", CASTHOOK(shoes_video_get_drawable), 0);
+ rb_define_method(cVideo, "drawable_ready?", CASTHOOK(shoes_video_get_realized), 0);
+ rb_define_method(cVideo, "remove", CASTHOOK(shoes_video_remove), 0);
+ rb_define_method(cVideo, "show", CASTHOOK(shoes_video_show), 0);
+ rb_define_method(cVideo, "hide", CASTHOOK(shoes_video_hide), 0);
+ rb_define_method(cVideo, "toggle", CASTHOOK(shoes_video_toggle), 0);
+ rb_define_method(cVideo, "style", CASTHOOK(shoes_video_style), -1);
+ rb_define_method(cVideo, "displace", CASTHOOK(shoes_video_displace), 2);
+ rb_define_method(cVideo, "move", CASTHOOK(shoes_video_move), 2);
+ rb_define_method(cVideo, "width", CASTHOOK(shoes_video_get_width), 0);
+ rb_define_method(cVideo, "height", CASTHOOK(shoes_video_get_height), 0);
+ rb_define_method(cVideo, "left", CASTHOOK(shoes_video_get_left), 0);
+ rb_define_method(cVideo, "top", CASTHOOK(shoes_video_get_top), 0);
+ rb_define_method(cVideo, "tooltip", CASTHOOK(shoes_control_get_tooltip), 0);
+ rb_define_method(cVideo, "tooltip=", CASTHOOK(shoes_control_set_tooltip), 1);
+ rb_const_set(cTypes, rb_intern("VIDEO"), Qtrue);
+
+ eVlcError = rb_define_class_under(cTypes, "VideoError", rb_eStandardError);
+
+ RUBY_M("+video_c", video, -1);
+}
+
+// ruby
+void shoes_video_mark(shoes_video *video) {
+ rb_gc_mark_maybe(video->parent);
+ rb_gc_mark_maybe(video->attr);
+}
+
+
+static void shoes_video_free(shoes_video *video) {
+ RUBY_CRITICAL(SHOE_FREE(video));
+}
+
+VALUE shoes_video_alloc(VALUE klass) {
+ shoes_video *video = SHOE_ALLOC(shoes_video);
+ SHOE_MEMZERO(video, shoes_video, 1);
+
+ VALUE obj = Data_Wrap_Struct(klass, shoes_video_mark, shoes_video_free, video);
+ video->attr = Qnil;
+ video->parent = Qnil;
+ video->realized = 0;
+ return obj;
+}
+
+VALUE shoes_video_new(VALUE attr, VALUE parent) {
+ shoes_video *video;
+ VALUE obj = shoes_video_alloc(cVideo);
+ Data_Get_Struct(obj, shoes_video, video);
+
+ if (NIL_P(attr)) attr = rb_hash_new();
+ video->attr = attr;
+ video->parent = shoes_find_canvas(parent);
+
+ /* getting surface dimensions, first try at video widget, then parent canvas, then video track size */
+ // TODO: this needs review to make sure it does what was intended
+ shoes_canvas *canvas;
+ Data_Get_Struct(video->parent, shoes_canvas, canvas);
+ if ( !RTEST(ATTR(attr, width)) ) {
+ if ( RTEST(ATTR(canvas->attr, width)) ) {
+ ATTRSET(attr, width, ATTR(canvas->attr, width));
+ } else {
+ ATTRSET(attr, width, RTEST(rb_hash_aref(attr, ID2SYM(rb_intern("video_width")))) ?
+ rb_hash_aref(attr, ID2SYM(rb_intern("video_width"))) : INT2NUM(0));
+ }
+ }
+ if ( !RTEST(ATTR(attr, height)) ) {
+ if ( RTEST(ATTR(canvas->attr, height)) ) {
+ ATTRSET(attr, height, ATTR(canvas->attr, height));
+ } else {
+ if (RTEST(rb_hash_aref(attr, ID2SYM(rb_intern("video_height"))))) {
+ ATTRSET(attr, height, rb_hash_aref(attr, ID2SYM(rb_intern("video_height"))));
+ } else ATTRSET(attr, height, INT2NUM(0));
+ /* No dimensions provided, using the video track size, make info avalaible to Shoes */
+ rb_hash_aset(attr, ID2SYM(rb_intern("using_video_dim")), Qtrue);
+ }
+ }
+ video->ref = shoes_native_surface_new(attr, obj);
+ return obj;
+}
+
+/*
+ * Get the drawable area so vlc can draw on it
+ * in ruby side via Fiddle
+ */
+VALUE shoes_video_get_drawable(VALUE self) {
+ shoes_video *self_t;
+ Data_Get_Struct(self, shoes_video, self_t);
+#ifdef SHOES_GTK_WIN32
+ return ULONG2NUM((unsigned long)GDK_WINDOW_HWND(gtk_widget_get_window(self_t->ref)));
+#else
+#ifdef SHOES_QUARTZ
+ return ULONG2NUM((unsigned long)self_t->ref);
+#else
+ return UINT2NUM(GDK_WINDOW_XID(gtk_widget_get_window(self_t->ref)));
+#endif
+#endif
+}
+
+VALUE shoes_video_draw(VALUE self, VALUE c, VALUE actual) {
+ shoes_video *self_t;
+ shoes_place place;
+ shoes_canvas *canvas;
+ Data_Get_Struct(self, shoes_video, self_t);
+ Data_Get_Struct(c, shoes_canvas, canvas);
+
+ shoes_place_decide(&place, c, self_t->attr, canvas->place.iw, canvas->place.ih, REL_CANVAS, TRUE);
+ VALUE ck = rb_obj_class(c); // flow vs stack management in FINISH macro
+
+ if (RTEST(actual)) {
+ if (self_t->init == 0) {
+ self_t->init = 1;
+
+ if (!self_t->ref)
+ self_t->ref = shoes_native_surface_new(self_t->attr, self);
+ shoes_native_control_position(self_t->ref, &self_t->place, self, canvas, &place);
+
+ } else {
+ shoes_native_control_repaint(self_t->ref, &self_t->place, canvas, &place);
+ }
+ }
+ FINISH()
+ return self;
+}
+
+VALUE shoes_video_get_parent(VALUE self) {
+ GET_STRUCT(video, self_t);
+ return self_t->parent;
+}
+
+VALUE shoes_video_get_left(VALUE self) {
+ GET_STRUCT(video, self_t);
+ return INT2NUM(self_t->place.ix + self_t->place.dx);
+}
+
+VALUE shoes_video_get_top(VALUE self) {
+ GET_STRUCT(video, self_t);
+ return INT2NUM(self_t->place.iy + self_t->place.dy);
+}
+
+VALUE shoes_video_get_height(VALUE self) {
+ GET_STRUCT(video, self_t);
+ return INT2NUM(self_t->place.h);
+}
+
+VALUE shoes_video_get_width(VALUE self) {
+ GET_STRUCT(video, self_t);
+ return INT2NUM(self_t->place.w);
+}
+
+VALUE shoes_video_show(VALUE self) {
+ GET_STRUCT(video, self_t);
+ ATTRSET(self_t->attr, hidden, Qfalse);
+ shoes_native_control_show(self_t->ref);
+ shoes_canvas_repaint_all(self_t->parent);
+ return self;
+}
+
+VALUE shoes_video_hide(VALUE self) {
+ GET_STRUCT(video, self_t);
+ ATTRSET(self_t->attr, hidden, Qtrue);
+ shoes_native_control_hide(self_t->ref);
+ shoes_canvas_repaint_all(self_t->parent);
+ return self;
+}
+
+VALUE shoes_video_toggle(VALUE self) {
+ GET_STRUCT(video, self_t);
+ ATTR(self_t->attr, hidden) == Qtrue ?
+ shoes_video_show(self) : shoes_video_hide(self);
+ return self;
+}
+
+VALUE shoes_video_remove(VALUE self) {
+ GET_STRUCT(video, self_t);
+ shoes_canvas *canvas;
+ Data_Get_Struct(self_t->parent, shoes_canvas, canvas);
+
+ rb_ary_delete(canvas->contents, self);
+#ifdef SHOES_QUARTZ
+ shoes_native_surface_remove((CGrafPtr)self_t->ref);
+#else
+ shoes_native_surface_remove(self_t->ref);
+#endif
+ self_t->ref = NULL;
+ shoes_canvas_repaint_all(self_t->parent);
+
+ self_t = NULL;
+ self = Qnil;
+ return Qtrue;
+}
+
+VALUE shoes_video_style(int argc, VALUE *argv, VALUE self) {
+ rb_arg_list args;
+ GET_STRUCT(video, self_t);
+ switch (rb_parse_args(argc, argv, "h,", &args)) {
+ case 1:
+ if (NIL_P(self_t->attr)) self_t->attr = rb_hash_new();
+ rb_funcall(self_t->attr, s_update, 1, args.a[0]);
+ shoes_canvas_repaint_all(self_t->parent);
+ break;
+ case 2:
+ return rb_obj_freeze(rb_obj_dup(self_t->attr));
+ }
+ return self;
+}
+
+VALUE shoes_video_displace(VALUE self, VALUE x, VALUE y) {
+ GET_STRUCT(video, self_t);
+ ATTRSET(self_t->attr, displace_left, x);
+ ATTRSET(self_t->attr, displace_top, y);
+ shoes_canvas_repaint_all(self_t->parent);
+ return self;
+}
+
+VALUE shoes_video_move(VALUE self, VALUE x, VALUE y) {
+ GET_STRUCT(video, self_t);
+ ATTRSET(self_t->attr, left, x);
+ ATTRSET(self_t->attr, top, y);
+ shoes_canvas_repaint_all(self_t->parent);
+ return self;
+}
+
+/* internal method used in fiddle-video protocol
+* letting Shoes know when drawable is avalaible
+*/
+VALUE shoes_video_get_realized(VALUE self) {
+ shoes_video *self_t;
+ Data_Get_Struct(self, shoes_video, self_t);
+
+ return self_t->realized ? Qtrue : Qfalse;
+}
+
+// canvas
+VALUE shoes_canvas_video(int argc, VALUE *argv, VALUE self) {
+ rb_arg_list args;
+ rb_parse_args(argc, argv, "|h", &args);
+ VALUE video = shoes_video_new(args.a[0], self);
+
+ shoes_canvas *canvas;
+ Data_Get_Struct(self, shoes_canvas, canvas);
+ cairo_t *cr;
+ cr = CCR(canvas);
+ if (canvas->insertion <= -1)
+ rb_ary_push(canvas->contents, video);
+ else {
+ rb_ary_insert_at(canvas->contents, canvas->insertion, 0, video);
+ canvas->insertion++;
+ }
+ return video;
+}
diff --git a/shoes/types/video.h b/shoes/types/video.h
new file mode 100644
index 00000000..07f5170d
--- /dev/null
+++ b/shoes/types/video.h
@@ -0,0 +1,61 @@
+#include "shoes/ruby.h"
+#include "shoes/world.h"
+#include "shoes/internal.h"
+#include "shoes/app.h"
+
+#ifndef SHOES_VIDEO_TYPE_H
+#define SHOES_VIDEO_TYPE_H
+
+#define SHOES_VIDEO 1
+
+/* extern variables necessary to communicate with other parts of Shoes */
+extern VALUE cShoes, cApp, cTypes, cCanvas, cWidget;
+extern shoes_app _shoes_app;
+
+typedef struct {
+ VALUE parent;
+ VALUE attr;
+ shoes_place place;
+ SHOES_CONTROL_REF ref;
+ int realized;
+ SHOES_SLOT_OS *slot;
+ int init;
+} shoes_video;
+
+// native forward declarations
+extern SHOES_CONTROL_REF shoes_native_surface_new(VALUE, VALUE);
+extern unsigned long shoes_native_surface_get_window_handle(SHOES_CONTROL_REF);
+extern void shoes_native_surface_position(SHOES_SURFACE_REF, shoes_place *,
+ VALUE, shoes_canvas *, shoes_place *);
+extern void shoes_native_surface_hide(SHOES_SURFACE_REF);
+extern void shoes_native_surface_show(SHOES_SURFACE_REF);
+extern void shoes_native_surface_remove(SHOES_SURFACE_REF);
+
+/* each widget should have its own init function */
+void shoes_video_init();
+
+// ruby
+VALUE shoes_video_alloc(VALUE);
+VALUE shoes_video_new(VALUE, VALUE);
+VALUE shoes_video_draw(VALUE, VALUE, VALUE);
+VALUE shoes_video_get_parent(VALUE);
+VALUE shoes_video_get_drawable(VALUE);
+VALUE shoes_video_get_realized(VALUE);
+VALUE shoes_video_remove(VALUE);
+VALUE shoes_video_show(VALUE);
+VALUE shoes_video_hide(VALUE);
+VALUE shoes_video_toggle(VALUE self);
+VALUE shoes_video_style(int, VALUE*, VALUE);
+VALUE shoes_video_displace(VALUE, VALUE, VALUE);
+VALUE shoes_video_move(VALUE, VALUE, VALUE);
+VALUE shoes_video_get_width(VALUE);
+VALUE shoes_video_get_height(VALUE);
+VALUE shoes_video_get_left(VALUE);
+VALUE shoes_video_get_top(VALUE);
+
+// Canvas
+VALUE shoes_canvas_video(int, VALUE*, VALUE);
+VALUE shoes_canvas_c_video(int, VALUE*, VALUE);
+VALUE shoes_app_c_video(int, VALUE*, VALUE);
+
+#endif
diff --git a/shoes/version.c b/shoes/version.c
new file mode 100644
index 00000000..73082b01
--- /dev/null
+++ b/shoes/version.c
@@ -0,0 +1,21 @@
+#include
+#include "version.h"
+
+void shoes_version_init() {
+ // for compatibily pre 3.2.22
+ rb_const_set(cTypes, rb_intern("RELEASE_NAME"), rb_str_new2(SHOES_RELEASE_NAME));
+ rb_const_set(cTypes, rb_intern("RELEASE_TYPE"), rb_str_new2(SHOES_STYLE));
+ rb_const_set(cTypes, rb_intern("RELEASE_ID"), INT2NUM(SHOES_RELEASE_ID));
+ rb_const_set(cTypes, rb_intern("REVISION"), INT2NUM(SHOES_REVISION));
+ rb_const_set(cTypes, rb_intern("RELEASE_BUILD_DATE"), rb_str_new2(SHOES_BUILD_DATE));
+ rb_const_set(cTypes, rb_intern("VERSION"), rb_str_new2(SHOES_RELEASE_NAME));
+ // post 3.2.22 constants
+ rb_const_set(cTypes, rb_intern("VERSION_NUMBER"), rb_str_new2(SHOES_VERSION_NUMBER));
+ rb_const_set(cTypes, rb_intern("VERSION_MAJOR"), INT2NUM(SHOES_VERSION_MAJOR));
+ rb_const_set(cTypes, rb_intern("VERSION_MINOR"), INT2NUM(SHOES_VERSION_MINOR));
+ rb_const_set(cTypes, rb_intern("VERSION_TINY"), INT2NUM(SHOES_VERSION_TINY));
+ rb_const_set(cTypes, rb_intern("VERSION_NAME"), rb_str_new2(SHOES_VERSION_NAME));
+ rb_const_set(cTypes, rb_intern("VERSION_REVISION"), INT2NUM(SHOES_VERSION_REVISION));
+ rb_const_set(cTypes, rb_intern("VERSION_DATE"), rb_str_new2(SHOES_VERSION_DATE));
+ rb_const_set(cTypes, rb_intern("VERSION_PLATFORM"), rb_str_new2(SHOES_VERSION_PLATFORM));
+}
\ No newline at end of file
diff --git a/shoes/video/video.c b/shoes/video/video.c
deleted file mode 100644
index 5246dff5..00000000
--- a/shoes/video/video.c
+++ /dev/null
@@ -1,374 +0,0 @@
-#include "video.h"
-#include "shoes/native.h"
-#include "shoes/ruby.h"
-
-// from ruby's eval.c
-//
-static inline VALUE
-call_cfunc(HOOK func, VALUE recv, int len, int argc, VALUE *argv)
-{
- if (len >= 0 && argc != len) {
- rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)",
- argc, len);
- }
-
- switch (len) {
- case -2:
- return (*func)(recv, rb_ary_new4(argc, argv));
- case -1:
- return (*func)(argc, argv, recv);
- case 0:
- return (*func)(recv);
- case 1:
- return (*func)(recv, argv[0]);
- case 2:
- return (*func)(recv, argv[0], argv[1]);
- case 3:
- return (*func)(recv, argv[0], argv[1], argv[2]);
- case 4:
- return (*func)(recv, argv[0], argv[1], argv[2], argv[3]);
- case 5:
- return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4]);
- case 6:
- return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4],
- argv[5]);
- case 7:
- return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4],
- argv[5], argv[6]);
- case 8:
- return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4],
- argv[5], argv[6], argv[7]);
- case 9:
- return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4],
- argv[5], argv[6], argv[7], argv[8]);
- case 10:
- return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4],
- argv[5], argv[6], argv[7], argv[8], argv[9]);
- case 11:
- return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4],
- argv[5], argv[6], argv[7], argv[8], argv[9], argv[10]);
- case 12:
- return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4],
- argv[5], argv[6], argv[7], argv[8], argv[9],
- argv[10], argv[11]);
- case 13:
- return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4],
- argv[5], argv[6], argv[7], argv[8], argv[9], argv[10],
- argv[11], argv[12]);
- case 14:
- return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4],
- argv[5], argv[6], argv[7], argv[8], argv[9], argv[10],
- argv[11], argv[12], argv[13]);
- case 15:
- return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4],
- argv[5], argv[6], argv[7], argv[8], argv[9], argv[10],
- argv[11], argv[12], argv[13], argv[14]);
- default:
- rb_raise(rb_eArgError, "too many arguments (%d)", len);
- break;
- }
- return Qnil; /* not reached */
-}
-
-/* from canvas.c */
-VALUE shoes_canvas_video(int argc, VALUE *argv, VALUE self) {
- rb_arg_list args;
- rb_parse_args(argc, argv, "|h", &args);
- VALUE video = shoes_video_new(args.a[0], self);
-
- shoes_canvas *canvas;
- Data_Get_Struct(self, shoes_canvas, canvas);
- cairo_t *cr;
- cr = CCR(canvas);
- if (canvas->insertion <= -1)
- rb_ary_push(canvas->contents, video);
- else {
- rb_ary_insert_at(canvas->contents, canvas->insertion, 0, video);
- canvas->insertion++;
- }
- return video;
-}
-
-void shoes_video_mark(shoes_video *video) {
- rb_gc_mark_maybe(video->parent);
- rb_gc_mark_maybe(video->attr);
-}
-
-
-static void shoes_video_free(shoes_video *video) {
- RUBY_CRITICAL(SHOE_FREE(video));
-}
-
-VALUE shoes_video_alloc(VALUE klass) {
- shoes_video *video = SHOE_ALLOC(shoes_video);
- SHOE_MEMZERO(video, shoes_video, 1);
-
- VALUE obj = Data_Wrap_Struct(klass, shoes_video_mark, shoes_video_free, video);
- video->attr = Qnil;
- video->parent = Qnil;
- video->realized = 0;
- return obj;
-}
-
-VALUE shoes_video_new(VALUE attr, VALUE parent)
-{
- shoes_video *video;
- VALUE obj = shoes_video_alloc(cVideo);
- Data_Get_Struct(obj, shoes_video, video);
-
- if (NIL_P(attr)) attr = rb_hash_new();
- video->attr = attr;
- video->parent = shoes_find_canvas(parent);
-
- /* getting surface dimensions, first try at video widget, then parent canvas, then video track size */
- // TODO: this needs review to make sure it does what was intended
- shoes_canvas *canvas;
- Data_Get_Struct(video->parent, shoes_canvas, canvas);
- if ( !RTEST(ATTR(attr, width)) ) {
- if ( RTEST(ATTR(canvas->attr, width)) ) {
- ATTRSET(attr, width, ATTR(canvas->attr, width));
- }
- else {
- ATTRSET(attr, width, RTEST(rb_hash_aref(attr, ID2SYM(rb_intern("video_width")))) ?
- rb_hash_aref(attr, ID2SYM(rb_intern("video_width"))) : INT2NUM(0));
- }
- }
- if ( !RTEST(ATTR(attr, height)) ) {
- if ( RTEST(ATTR(canvas->attr, height)) ) {
- ATTRSET(attr, height, ATTR(canvas->attr, height));
- }
- else {
- if (RTEST(rb_hash_aref(attr, ID2SYM(rb_intern("video_height"))))) {
- ATTRSET(attr, height, rb_hash_aref(attr, ID2SYM(rb_intern("video_height"))));
- } else ATTRSET(attr, height, INT2NUM(0));
- /* No dimensions provided, using the video track size, make info avalaible to Shoes */
- rb_hash_aset(attr, ID2SYM(rb_intern("using_video_dim")), Qtrue);
- }
- }
- video->ref = shoes_native_surface_new(attr, obj);
- return obj;
-}
-
-/*
- * Get the drawable area so vlc can draw on it
- * in ruby side via Fiddle
- */
-VALUE shoes_video_get_drawable(VALUE self) {
- shoes_video *self_t;
- Data_Get_Struct(self, shoes_video, self_t);
-#ifdef SHOES_GTK_WIN32
- return ULONG2NUM((unsigned long)GDK_WINDOW_HWND(gtk_widget_get_window(self_t->ref)));
-#else
-#ifdef SHOES_QUARTZ
- return ULONG2NUM((unsigned long)self_t->ref);
-#else
- return UINT2NUM(GDK_WINDOW_XID(gtk_widget_get_window(self_t->ref)));
-#endif
-#endif
-}
-
-/* internal method used in fiddle-video protocol
-* letting Shoes know when drawable is avalaible
-*/
-VALUE
-shoes_video_get_realized(VALUE self) {
- shoes_video *self_t;
- Data_Get_Struct(self, shoes_video, self_t);
-
- return self_t->realized ? Qtrue : Qfalse;
-}
-
-/* from ruby.c */
-#define FINISH() \
- if (!ABSY(place)) { \
- canvas->cx += place.w; \
- canvas->cy = place.y; \
- canvas->endx = canvas->cx; \
- canvas->endy = max(canvas->endy, place.y + place.h); \
- } \
- if (ck == cStack) { \
- canvas->cx = CPX(canvas); \
- canvas->cy = canvas->endy; \
- }
-
-VALUE shoes_video_draw(VALUE self, VALUE c, VALUE actual) {
- shoes_video *self_t;
- shoes_place place;
- shoes_canvas *canvas;
- Data_Get_Struct(self, shoes_video, self_t);
- Data_Get_Struct(c, shoes_canvas, canvas);
-
- shoes_place_decide(&place, c, self_t->attr, canvas->place.iw, canvas->place.ih, REL_CANVAS, TRUE);
- VALUE ck = rb_obj_class(c); // flow vs stack management in FINISH macro
-
- if (RTEST(actual)) {
- if (self_t->init == 0) {
- self_t->init = 1;
-
- if (!self_t->ref)
- self_t->ref = shoes_native_surface_new(self_t->attr, self);
- shoes_native_control_position(self_t->ref, &self_t->place, self, canvas, &place);
-
- } else {
- shoes_native_control_repaint(self_t->ref, &self_t->place, canvas, &place);
- }
- }
- FINISH()
- return self;
-}
-
-
-VALUE shoes_video_get_parent(VALUE self) {
- GET_STRUCT(video, self_t);
- return self_t->parent;
-}
-
-VALUE shoes_video_get_left(VALUE self) {
- GET_STRUCT(video, self_t);
- return INT2NUM(self_t->place.ix + self_t->place.dx);
-}
-
-VALUE shoes_video_get_top(VALUE self) {
- GET_STRUCT(video, self_t);
- return INT2NUM(self_t->place.iy + self_t->place.dy);
-}
-
-VALUE shoes_video_get_height(VALUE self) {
- GET_STRUCT(video, self_t);
- return INT2NUM(self_t->place.h);
-}
-
-VALUE shoes_video_get_width(VALUE self) {
- GET_STRUCT(video, self_t);
- return INT2NUM(self_t->place.w);
-}
-
-VALUE shoes_video_show(VALUE self) {
- GET_STRUCT(video, self_t);
- ATTRSET(self_t->attr, hidden, Qfalse);
- shoes_native_control_show(self_t->ref);
- shoes_canvas_repaint_all(self_t->parent);
- return self;
-}
-
-VALUE shoes_video_hide(VALUE self) {
- GET_STRUCT(video, self_t);
- ATTRSET(self_t->attr, hidden, Qtrue);
- shoes_native_control_hide(self_t->ref);
- shoes_canvas_repaint_all(self_t->parent);
- return self;
-}
-
-VALUE shoes_video_toggle(VALUE self) {
- GET_STRUCT(video, self_t);
- ATTR(self_t->attr, hidden) == Qtrue ?
- shoes_video_show(self) : shoes_video_hide(self);
- return self;
-}
-
-VALUE shoes_video_remove(VALUE self) {
- GET_STRUCT(video, self_t);
- shoes_canvas *canvas;
- Data_Get_Struct(self_t->parent, shoes_canvas, canvas);
-
- rb_ary_delete(canvas->contents, self);
-#ifdef SHOES_QUARTZ
- shoes_native_surface_remove((CGrafPtr)self_t->ref);
-#else
- shoes_native_surface_remove(self_t->ref);
-#endif
- self_t->ref = NULL;
- shoes_canvas_repaint_all(self_t->parent);
-
- self_t = NULL;
- self = Qnil;
- return Qtrue;
-}
-
-VALUE shoes_video_style(int argc, VALUE *argv, VALUE self) {
- rb_arg_list args;
- GET_STRUCT(video, self_t);
- switch (rb_parse_args(argc, argv, "h,", &args)) {
- case 1:
- if (NIL_P(self_t->attr)) self_t->attr = rb_hash_new();
- rb_funcall(self_t->attr, s_update, 1, args.a[0]);
- shoes_canvas_repaint_all(self_t->parent);
- break;
- case 2: return rb_obj_freeze(rb_obj_dup(self_t->attr));
- }
- return self;
-}
-
-VALUE shoes_video_displace(VALUE self, VALUE x, VALUE y) {
- GET_STRUCT(video, self_t);
- ATTRSET(self_t->attr, displace_left, x);
- ATTRSET(self_t->attr, displace_top, y);
- shoes_canvas_repaint_all(self_t->parent);
- return self;
-}
-
-VALUE shoes_video_move(VALUE self, VALUE x, VALUE y) {
- GET_STRUCT(video, self_t);
- ATTRSET(self_t->attr, left, x);
- ATTRSET(self_t->attr, top, y);
- shoes_canvas_repaint_all(self_t->parent);
- return self;
- }
-
-/* from CANVAS_DEFS(FUNC_M) in ruby.c */
-VALUE shoes_canvas_c_video(int argc, VALUE *argv, VALUE self) {
- VALUE canvas, obj;
- GET_STRUCT(canvas, self_t);
- char *n = "+video";
- if (rb_ary_entry(self_t->app->nesting, 0) == self ||
- ((rb_obj_is_kind_of(self, cWidget) || self == self_t->app->nestslot) &&
- RARRAY_LEN(self_t->app->nesting) > 0))
- canvas = rb_ary_entry(self_t->app->nesting, RARRAY_LEN(self_t->app->nesting) - 1);
- else
- canvas = self;
- if (!rb_obj_is_kind_of(canvas, cCanvas))
- return ts_funcall2(canvas, rb_intern(n + 1), argc, argv);
- obj = call_cfunc(CASTHOOK(shoes_canvas_video), canvas, -1, argc, argv);
- if (n[0] == '+' && RARRAY_LEN(self_t->app->nesting) == 0) shoes_canvas_repaint_all(self);
- return obj;
-}
-
-VALUE shoes_app_c_video(int argc, VALUE *argv, VALUE self) {
- VALUE canvas;
- char *n = "+video";
- GET_STRUCT(app, app);
- if (RARRAY_LEN(app->nesting) > 0)
- canvas = rb_ary_entry(app->nesting, RARRAY_LEN(app->nesting) - 1);
- else
- canvas = app->canvas;
- if (!rb_obj_is_kind_of(canvas, cCanvas))
- return ts_funcall2(canvas, rb_intern(n + 1), argc, argv);
- return shoes_canvas_c_video(argc, argv, canvas);
-}
-
-// called inside shoes_ruby_init, ruby.c
-void shoes_ruby_video_init() {
-
- /* video_c so we can use method 'video' on ruby side */
- rb_define_method(cCanvas, "+video_c" + 1, CASTHOOK(shoes_canvas_c_video), -1); /* from CANVAS_DEFS(RUBY_M) in ruby.c */
- rb_define_method(cApp, "+video_c" + 1, CASTHOOK(shoes_app_c_video), -1); /**/
-
- cVideo = rb_define_class_under(cTypes, "Video", rb_cObject);
- rb_define_alloc_func(cVideo, shoes_video_alloc);
- rb_define_method(cVideo, "draw", CASTHOOK(shoes_video_draw), 2);
- rb_define_method(cVideo, "parent", CASTHOOK(shoes_video_get_parent), 0);
- rb_define_method(cVideo, "drawable", CASTHOOK(shoes_video_get_drawable), 0);
- rb_define_method(cVideo, "drawable_ready?", CASTHOOK(shoes_video_get_realized), 0);
- rb_define_method(cVideo, "remove", CASTHOOK(shoes_video_remove), 0);
- rb_define_method(cVideo, "show", CASTHOOK(shoes_video_show), 0);
- rb_define_method(cVideo, "hide", CASTHOOK(shoes_video_hide), 0);
- rb_define_method(cVideo, "toggle", CASTHOOK(shoes_video_toggle), 0);
- rb_define_method(cVideo, "style", CASTHOOK(shoes_video_style), -1);
- rb_define_method(cVideo, "displace", CASTHOOK(shoes_video_displace), 2);
- rb_define_method(cVideo, "move", CASTHOOK(shoes_video_move), 2);
- rb_define_method(cVideo, "width", CASTHOOK(shoes_video_get_width), 0);
- rb_define_method(cVideo, "height", CASTHOOK(shoes_video_get_height), 0);
- rb_define_method(cVideo, "left", CASTHOOK(shoes_video_get_left), 0);
- rb_define_method(cVideo, "top", CASTHOOK(shoes_video_get_top), 0);
-
-}
diff --git a/shoes/video/video.h b/shoes/video/video.h
deleted file mode 100644
index c36712e1..00000000
--- a/shoes/video/video.h
+++ /dev/null
@@ -1,52 +0,0 @@
-#include "shoes/ruby.h"
-#include "shoes/world.h"
-#include "shoes/internal.h"
-#include "shoes/app.h"
-
-#ifndef VIDEO_H
-#define VIDEO_H
-
-//#ifdef VIDEO
-
-#define SHOES_VIDEO 1
-
-typedef struct {
- VALUE parent;
- VALUE attr;
- shoes_place place;
- SHOES_CONTROL_REF ref;
- int realized;
- SHOES_SLOT_OS *slot;
- int init;
-} shoes_video;
-
-VALUE cVideo; // ruby.c line 16
-
-
-VALUE shoes_canvas_video(int, VALUE*, VALUE);
-VALUE shoes_canvas_c_video(int, VALUE*, VALUE);
-VALUE shoes_app_c_video(int, VALUE*, VALUE);
-
-VALUE shoes_video_alloc(VALUE);
-VALUE shoes_video_new(VALUE, VALUE);
-VALUE shoes_video_draw(VALUE, VALUE, VALUE);
-VALUE shoes_video_get_parent(VALUE);
-VALUE shoes_video_get_drawable(VALUE);
-VALUE shoes_video_get_realized(VALUE);
-VALUE shoes_video_remove(VALUE);
-VALUE shoes_video_show(VALUE);
-VALUE shoes_video_hide(VALUE);
-VALUE shoes_video_toggle(VALUE self);
-VALUE shoes_video_style(int, VALUE*, VALUE);
-VALUE shoes_video_displace(VALUE, VALUE, VALUE);
-VALUE shoes_video_move(VALUE, VALUE, VALUE);
-VALUE shoes_video_get_width(VALUE);
-VALUE shoes_video_get_height(VALUE);
-VALUE shoes_video_get_left(VALUE);
-VALUE shoes_video_get_top(VALUE);
-
-//#else
-//#define SHOES_VIDEO 0
-//#endif
-
-#endif /* VIDEO_H */
diff --git a/shoes/world.c b/shoes/world.c
index 4260bfd9..59504dfd 100644
--- a/shoes/world.c
+++ b/shoes/world.c
@@ -6,7 +6,7 @@
#include "shoes/ruby.h"
#include "shoes/config.h"
#include "shoes/world.h"
-#include "shoes/native.h"
+#include "shoes/native/native.h"
#include "shoes/internal.h"
#ifdef SHOES_SIGNAL
@@ -15,264 +15,219 @@
#define SHOES_WIN32 // For this file.
#endif
-void
-shoes_sigint()
-{
- shoes_native_quit();
+void shoes_sigint() {
+ shoes_native_quit();
}
#endif
#ifdef __cplusplus
extern "C" {
#endif
-#ifdef SHOES_QUARTZ
+#ifdef SHOES_QUARTZ
extern void shoes_osx_setup_stdout();
#endif
shoes_world_t *shoes_world = NULL;
-shoes_world_t *
-shoes_world_alloc()
-{
- shoes_world_t *world = SHOE_ALLOC(shoes_world_t);
- SHOE_MEMZERO(world, shoes_world_t, 1);
- world->apps = rb_ary_new();
- world->msgs = rb_ary_new();
- world->mainloop = FALSE;
- world->image_cache = st_init_strtable();
- world->blank_image = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 1, 1);
- world->blank_cache = SHOE_ALLOC(shoes_cached_image);
- world->blank_cache->surface = world->blank_image;
- world->blank_cache->pattern = NULL;
- world->blank_cache->width = 1;
- world->blank_cache->height = 1;
- world->blank_cache->mtime = 0;
- world->default_font = pango_font_description_new();
- pango_font_description_set_family(world->default_font, "Arial");
- pango_font_description_set_absolute_size(world->default_font, 14. * PANGO_SCALE * (96./72.));
- rb_gc_register_address(&world->apps);
- rb_gc_register_address(&world->msgs);
- return world;
-}
-
-int
-shoes_world_free_image_cache(char *key, shoes_cache_entry *cached, char *arg)
-{
- if (cached->type != SHOES_CACHE_ALIAS && cached->image != NULL)
- {
- if (cached->image->pattern != NULL)
- cairo_pattern_destroy(cached->image->pattern);
- if (cached->image->surface != shoes_world->blank_image)
- cairo_surface_destroy(cached->image->surface);
- free(cached->image);
- }
- free(cached);
- free(key);
- return ST_CONTINUE;
-}
-
-void
-shoes_world_free(shoes_world_t *world)
-{
- shoes_native_cleanup(world);
- st_foreach(world->image_cache, CASTFOREACH(shoes_world_free_image_cache), 0);
- st_free_table(world->image_cache);
- SHOE_FREE(world->blank_cache);
- cairo_surface_destroy(world->blank_image);
- pango_font_description_free(world->default_font);
- rb_gc_unregister_address(&world->apps);
- rb_gc_unregister_address(&world->msgs);
- if (world != NULL)
- SHOE_FREE(world);
-}
-
-#ifndef RUBY_1_8
-int
-shoes_ruby_embed()
-{
- VALUE v;
- char *argv[] = {"ruby", "-e", "1"};
-
- // TODO delete: char** sysinit_argv = NULL;
- RUBY_INIT_STACK;
+shoes_world_t *shoes_world_alloc() {
+ shoes_world_t *world = SHOE_ALLOC(shoes_world_t);
+ SHOE_MEMZERO(world, shoes_world_t, 1);
+ world->apps = rb_ary_new();
+ world->msgs = rb_ary_new();
+ world->mainloop = FALSE;
+ world->image_cache = st_init_strtable();
+ world->blank_image = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 1, 1);
+ world->blank_cache = SHOE_ALLOC(shoes_cached_image);
+ world->blank_cache->surface = world->blank_image;
+ world->blank_cache->pattern = NULL;
+ world->blank_cache->width = 1;
+ world->blank_cache->height = 1;
+ world->blank_cache->mtime = 0;
+ world->default_font = pango_font_description_new();
+ pango_font_description_set_family(world->default_font, "Arial");
+ pango_font_description_set_absolute_size(world->default_font, 14. * PANGO_SCALE * (96./72.));
+ rb_gc_register_address(&world->apps);
+ rb_gc_register_address(&world->msgs);
+ return world;
+}
+
+int shoes_world_free_image_cache(char *key, shoes_cache_entry *cached, char *arg) {
+ if (cached->type != SHOES_CACHE_ALIAS && cached->image != NULL) {
+ if (cached->image->pattern != NULL)
+ cairo_pattern_destroy(cached->image->pattern);
+ if (cached->image->surface != shoes_world->blank_image)
+ cairo_surface_destroy(cached->image->surface);
+ free(cached->image);
+ }
+ free(cached);
+ free(key);
+ return ST_CONTINUE;
+}
+
+void shoes_world_free(shoes_world_t *world) {
+ shoes_native_cleanup(world);
+ st_foreach(world->image_cache, CASTFOREACH(shoes_world_free_image_cache), 0);
+ st_free_table(world->image_cache);
+ SHOE_FREE(world->blank_cache);
+ cairo_surface_destroy(world->blank_image);
+ pango_font_description_free(world->default_font);
+ rb_gc_unregister_address(&world->apps);
+ rb_gc_unregister_address(&world->msgs);
+ if (world != NULL)
+ SHOE_FREE(world);
+}
+
+int shoes_ruby_embed() {
+ VALUE v;
+ char *argv[] = {"ruby", "-e", "1"};
+ //char *argv[] = {"ruby_engine", "-e", "1"};
+ RUBY_INIT_STACK;
#ifdef SHOES_WIN32
- //ruby_sysinit(0, 0);
+ //ruby_sysinit(0, 0);
#endif
- //printf("starting ruby_init\n");
- ruby_init();
- //printf("back from ruby_init\n");
- v = (VALUE)ruby_options(3, argv);
- //printf("back from ruby_options : %d\n", !FIXNUM_P(v));
- return !FIXNUM_P(v);
+ /* in ruby 2.3+ we need to fake */
+ int zedc = 0;
+ int *zeda = &zedc;
+ ruby_sysinit(&zedc, &zeda);
+ ruby_init();
+ v = (VALUE)ruby_options(3, argv);
+ return !FIXNUM_P(v);
}
-#else
-#define shoes_ruby_embed ruby_init
-#endif
-shoes_code
-shoes_init(SHOES_INIT_ARGS)
-{
- //printf("starting shoes_init\n");
+shoes_code shoes_init(SHOES_INIT_ARGS) {
+ //printf("starting shoes_init\n");
#ifdef SHOES_SIGNAL
- signal(SIGINT, shoes_sigint);
+ signal(SIGINT, shoes_sigint);
#ifndef SHOES_GTK_WIN32
- signal(SIGQUIT, shoes_sigint);
+ signal(SIGQUIT, shoes_sigint);
#endif
#endif
-#ifdef SHOES_QUARTZ
- // init some OSX things our way before Ruby inits.
- // setenv("TERM", "xterm-256color", 1); // mostly harmless, also not needed.
- shoes_osx_setup_stdout();
+#ifdef SHOES_QUARTZ
+ // init some OSX things our way before Ruby inits.
+ shoes_osx_setup_stdout();
#endif
- shoes_ruby_embed();
- //printf("back from shoes_ruby_embed\n");
- shoes_ruby_init();
- //printf("back from shoes_ruby_init\n");
- shoes_world = shoes_world_alloc();
+ shoes_ruby_embed(); // initialize ruby
+ shoes_ruby_init();
+ shoes_world = shoes_world_alloc();
#ifdef SHOES_WIN32
- shoes_world->os.instance = inst;
- shoes_world->os.style = style;
+ shoes_world->os.instance = inst;
+ shoes_world->os.style = style;
#endif
- shoes_native_init();
- //printf("back from shoes_native_init\n");
+ shoes_native_init();
- rb_const_set(cShoes, rb_intern("FONTS"), shoes_font_list());
- return SHOES_OK;
+ rb_const_set(cShoes, rb_intern("FONTS"), shoes_font_list());
+ return SHOES_OK;
}
-void
-shoes_update_fonts(VALUE ary)
-{
+void shoes_update_fonts(VALUE ary) {
#if PANGO_VERSION_MAJOR > 1 || PANGO_VERSION_MINOR >= 22
- pango_cairo_font_map_set_default(NULL);
+ pango_cairo_font_map_set_default(NULL);
#endif
- rb_funcall(rb_const_get(cShoes, rb_intern("FONTS")), rb_intern("replace"), 1, ary);
+ rb_funcall(rb_const_get(cShoes, rb_intern("FONTS")), rb_intern("replace"), 1, ary);
}
-static VALUE
-shoes_load_begin(VALUE v)
-{
- char *bootup = (char *)v;
- return rb_eval_string(bootup);
+static VALUE shoes_load_begin(VALUE v) {
+ char *bootup = (char *)v;
+ return rb_eval_string(bootup);
}
-static VALUE
-shoes_load_exception(VALUE v, VALUE exc)
-{
- return exc;
+static VALUE shoes_load_exception(VALUE v, VALUE exc) {
+ return exc;
}
-shoes_code
-shoes_load(char *path)
-{
- char bootup[SHOES_BUFSIZE];
+shoes_code shoes_load(char *path) {
+ char bootup[SHOES_BUFSIZE];
- if (path)
- {
- sprintf(bootup, "Shoes.visit(%%q<%s>);", path);
+ if (path) {
+ sprintf(bootup, "Shoes.visit(%%q<%s>);", path);
- VALUE v = rb_rescue2(CASTHOOK(shoes_load_begin), (VALUE)bootup, CASTHOOK(shoes_load_exception), Qnil, rb_cObject, 0);
- if (rb_obj_is_kind_of(v, rb_eException))
- {
- shoes_canvas_error(Qnil, v);
- rb_eval_string("Shoes.show_log");
+ VALUE v = rb_rescue2(CASTHOOK(shoes_load_begin), (VALUE)bootup, CASTHOOK(shoes_load_exception), Qnil, rb_cObject, 0);
+ if (rb_obj_is_kind_of(v, rb_eException)) {
+ shoes_canvas_error(Qnil, v);
+ rb_eval_string("Shoes.show_log");
+ }
}
- }
- return SHOES_OK;
+ return SHOES_OK;
}
-void
-shoes_set_argv(int argc, char **argv)
-{
- ruby_set_argv(argc, argv);
+void shoes_set_argv(int argc, char **argv) {
+ ruby_set_argv(argc, argv);
}
#ifdef SHOES_QUARTZ
-static VALUE
-shoes_start_begin(VALUE v)
-{
- char str[128];
- sprintf(str, "$SHOES_URI = Shoes.args!(%d)", osx_cshoes_launch);
- return rb_eval_string(str);
+static VALUE shoes_start_begin(VALUE v) {
+ char str[128];
+ sprintf(str, "$SHOES_URI = Shoes.args!(%d)", osx_cshoes_launch);
+ return rb_eval_string(str);
}
#else
-static VALUE
-shoes_start_begin(VALUE v)
-{
- return rb_eval_string("$SHOES_URI = Shoes.args!");
+static VALUE shoes_start_begin(VALUE v) {
+ return rb_eval_string("$SHOES_URI = Shoes.args!");
}
#endif
-static VALUE
-shoes_start_exception(VALUE v, VALUE exc)
-{
- return exc;
+static VALUE shoes_start_exception(VALUE v, VALUE exc) {
+ return exc;
}
-shoes_code
-shoes_start(char *path, char *uri, int debug)
-{
- shoes_code code = SHOES_OK;
- char bootup[SHOES_BUFSIZE];
- char dbstr[64];
- sprintf(dbstr, "SHOES_DEBUG=%s", (debug ? "true" : "false"));
- rb_eval_string(dbstr);
- int len = shoes_snprintf(bootup,
- SHOES_BUFSIZE,
- "begin;"
- "DIR = File.expand_path(File.dirname(%%q<%s>));"
+shoes_code shoes_start(char *path, char *uri, int debug) {
+ shoes_code code = SHOES_OK;
+ char bootup[SHOES_BUFSIZE];
+ char dbstr[64];
+ sprintf(dbstr, "SHOES_DEBUG=%s", (debug ? "true" : "false"));
+ rb_eval_string(dbstr);
+ int len = shoes_snprintf(bootup,
+ SHOES_BUFSIZE,
+ "begin;"
+ "DIR = File.expand_path(File.dirname(%%q<%s>));"
#ifdef OLD_SHOES
- "$:.replace([DIR+'/ruby/lib/'+(ENV['SHOES_RUBY_ARCH'] || RUBY_PLATFORM), DIR+'/ruby/lib', DIR+'/lib', '.']);"
+ "$:.replace([DIR+'/ruby/lib/'+(ENV['SHOES_RUBY_ARCH'] || RUBY_PLATFORM), DIR+'/ruby/lib', DIR+'/lib', '.']);"
#else
- "$:.unshift(DIR+'/lib');"
- "$:.unshift('.');"
+ "$:.unshift(DIR+'/lib');"
+ "$:.unshift('.');"
#endif
- "require 'shoes';"
- "DIR;"
- "rescue Object => e;"
- "puts(e.message);"
- "end",
- path);
-
- if (len < 0 || len >= SHOES_BUFSIZE)
- {
- QUIT("Path to script is too long.");
- }
+ "require 'shoes';"
+ "DIR;"
+ "rescue Object => e;"
+ "puts(e.message);"
+ "end",
+ path);
+
+ if (len < 0 || len >= SHOES_BUFSIZE) {
+ QUIT("Path to script is too long.");
+ }
- VALUE str = rb_eval_string(bootup);
- if (NIL_P(str))
- return SHOES_QUIT;
+ VALUE str = rb_eval_string(bootup);
+ if (NIL_P(str))
+ return SHOES_QUIT;
- StringValue(str);
- strcpy(shoes_world->path, RSTRING_PTR(str));
+ StringValue(str);
+ strcpy(shoes_world->path, RSTRING_PTR(str));
- char *load_uri_str = NULL;
- VALUE load_uri = rb_rescue2(CASTHOOK(shoes_start_begin), Qnil, CASTHOOK(shoes_start_exception), Qnil, rb_cObject, 0);
- if (!RTEST(load_uri))
- return SHOES_QUIT;
- if (rb_obj_is_kind_of(load_uri, rb_eException))
- {
- QUIT_ALERT(load_uri);
- }
+ char *load_uri_str = NULL;
+ VALUE load_uri = rb_rescue2(CASTHOOK(shoes_start_begin), Qnil, CASTHOOK(shoes_start_exception), Qnil, rb_cObject, 0);
+ if (!RTEST(load_uri))
+ return SHOES_QUIT;
+ if (rb_obj_is_kind_of(load_uri, rb_eException)) {
+ QUIT_ALERT(load_uri);
+ }
- if (rb_obj_is_kind_of(load_uri, rb_cString))
- load_uri_str = RSTRING_PTR(load_uri);
+ if (rb_obj_is_kind_of(load_uri, rb_cString))
+ load_uri_str = RSTRING_PTR(load_uri);
- code = shoes_load(load_uri_str);
- if (code != SHOES_OK)
- goto quit;
+ code = shoes_load(load_uri_str);
+ if (code != SHOES_OK)
+ goto quit;
- code = shoes_app_start(shoes_world->apps, uri);
+ code = shoes_app_start(shoes_world->apps, uri);
quit:
- return code;
+ return code;
}
-shoes_code
-shoes_final()
-{
- rb_funcall(cShoes, rb_intern("clean"), 0);
- shoes_world_free(shoes_world);
- return SHOES_OK;
+shoes_code shoes_final() {
+ rb_funcall(cShoes, rb_intern("clean"), 0);
+ shoes_world_free(shoes_world);
+ return SHOES_OK;
}
#ifdef __cplusplus
diff --git a/shoes/world.h b/shoes/world.h
index 1d945ae2..ce13e969 100644
--- a/shoes/world.h
+++ b/shoes/world.h
@@ -10,24 +10,21 @@
#include "shoes/config.h"
#include "shoes/ruby.h"
#include "shoes/code.h"
-#ifdef VIDEO
-#include "shoes/video/video.h"
-#endif
#ifdef __cplusplus
extern "C" {
#endif
SHOES_EXTERN typedef struct _shoes_world_t {
- SHOES_WORLD_OS os;
- int mainloop;
- char path[SHOES_BUFSIZE];
- VALUE apps, msgs;
- st_table *image_cache;
- guint thread_event;
- cairo_surface_t *blank_image;
- shoes_cached_image *blank_cache;
- PangoFontDescription *default_font;
+ SHOES_WORLD_OS os;
+ int mainloop;
+ char path[SHOES_BUFSIZE];
+ VALUE apps, msgs;
+ st_table *image_cache;
+ guint thread_event;
+ cairo_surface_t *blank_image;
+ shoes_cached_image *blank_cache;
+ PangoFontDescription *default_font;
} shoes_world_t;
extern SHOES_EXTERN shoes_world_t *shoes_world;
@@ -37,7 +34,7 @@ extern SHOES_EXTERN shoes_world_t *shoes_world;
shoes_app *appvar = NULL; \
if (RARRAY_LEN(shoes_world->apps) > 0) \
Data_Get_Struct(rb_ary_entry(shoes_world->apps, 0), shoes_app, appvar)\
-
+
// gtk uses this for mKernel methods - app is optional
// defines 3 variables that callers need to know about. Ick!
#define GTK_APP_VAR(appvar) \
@@ -59,7 +56,7 @@ extern SHOES_EXTERN shoes_world_t *shoes_world;
Data_Get_Struct(actual_app, shoes_app, appvar); \
title_##appvar = RSTRING_PTR(app->title); \
}\
-
+
// no longer used - TODO: remove after testing.
#define ACTUAL_APP_NOPE(appvar) \
@@ -71,14 +68,14 @@ extern SHOES_EXTERN shoes_world_t *shoes_world;
//
// Shoes World
-//
+//
SHOES_EXTERN shoes_world_t *shoes_world_alloc(void);
SHOES_EXTERN void shoes_world_free(shoes_world_t *);
void shoes_update_fonts(VALUE);
//
// Shoes
-//
+//
SHOES_EXTERN shoes_code shoes_init(SHOES_INIT_ARGS);
SHOES_EXTERN shoes_code shoes_load(char *);
SHOES_EXTERN shoes_code shoes_start(char *, char *, int);
diff --git a/static/man-ele-spinner.png b/static/man-ele-spinner.png
new file mode 100644
index 00000000..95a8bb96
Binary files /dev/null and b/static/man-ele-spinner.png differ
diff --git a/static/man-ele-switch.png b/static/man-ele-switch.png
new file mode 100644
index 00000000..489082ec
Binary files /dev/null and b/static/man-ele-switch.png differ
diff --git a/static/manual-en.txt b/static/manual-en.txt
index 85679865..7b59100e 100644
--- a/static/manual-en.txt
+++ b/static/manual-en.txt
@@ -1251,6 +1251,24 @@ The radius of curved corners on each of these rectangular elements. As an
example, if this is set to 6, the corners of the rectangle are given a curve
with a 6-pixel radius.
+=== :dash » a string ===
+
+For: ''arrow, border, line, oval, rect, shape''.
+
+Defines the line style used to draw elements. It can be either:
+
+ * :onedot - Creates dot-dash line.
+ * :nodot - Creates solid line.
+
+If dash style is undefined, ":nodot" is set as default.
+
+{{{
+Shoes.app width: 410, height: 60 do
+ line 10,20,400,20, dash: :onedot, stroke: green, strokewidth: 3
+ line 10,40,400,40, stroke: green, strokewidth: 3
+end
+}}}
+
=== :displace_left » a number ===
For: ''all slots and elements''.
@@ -1472,7 +1490,7 @@ element has a `:rise` of -10 pixels.
=== :scroll » true or false ===
-For: ''flow, stack''.
+For: ''flow, stack, background''.
Establishes this slot as a scrolling slot. If `:scroll => true` is set, the
slot will show a scrollbar if any of its contents go past its height. The
@@ -1480,6 +1498,9 @@ scrollbar will appear and disappear as needed. It will also appear inside the
width of the slot, meaning the slot's width will never change, regardless of
whether there is a scrollbar or not.
+When used on a background instead of a flow or stack the background and set true
+the background will always fill the slot when scrolled. See [[Element.background]].
+
=== :secret » true or false ===
For: ''ask, edit_line''.
@@ -1861,6 +1882,67 @@ Shoes.app do
end
}}}
+=== Mask() » Shoes::Mask ===
+
+Mask is a slot allowing to clip elements outside its own area. The size and frame of the area is defined by a number of Shoes elements - shapes, images and texts.
+
+In the example below there are two same colour slots. The left slot is drawn with a green star
+while the right slot contains the green star used as a clipping mask. Notice how the colour of the star is not taken into account.
+
+{{{
+Shoes.app width: 300, height: 150 do
+ flow width: 0.5, height: 1.0 do
+ background orange
+ star left: 75, top: 75, points: 6, outer: 40, inner: 9, fill: green
+ end
+
+ flow width: 0.5, height: 1.0 do
+ background orange
+ mask do
+ star left: 75, top: 75, points: 6, outer: 40, inner: 9, fill: green
+ end
+ end
+end
+}}}
+
+Next the same setup is used but this time an image is used for clipping.
+
+{{{
+Shoes.app width: 300, height: 150 do
+ flow width: 0.5, height: 1.0 do
+ background orange
+ image "#{DIR}/static/shoes-icon.png", left: 25, top: 25, width: 100
+ end
+
+ flow width: 0.5, height: 1.0 do
+ background orange
+ mask do
+ image "#{DIR}/static/shoes-icon.png", left: 25, top: 25, width: 100
+ end
+ end
+end
+}}}
+
+Texts can be used for their shape too.
+
+{{{
+Shoes.app width: 400, height: 100 do
+ flow width: 0.5, height: 1.0 do
+ background orange
+ title "SHOES!", weight: "ultrabold", align: "center"
+ end
+
+ flow width: 0.5, height: 1.0 do
+ background orange
+ mask do
+ title "SHOES!", weight: "ultrabold", align: "center"
+ end
+ end
+end
+}}}
+
+Check the sample directory for more examples.
+
=== oval(left, top, radius) » Shoes::Shape ===
Draws a circular form at pixel coordinates (left, top) with a width and height
@@ -2101,14 +2183,10 @@ The above animation is shown 24 times per second. If no number is given, the
=== background(pattern) » Shoes::Background ===
-Draws a Background element with a specific color (or pattern.) Patterns can be
-colors, gradients or images. Colors and images will tile across the
+Draws a Background element with a specific color (or pattern.) Patterns can be
+colors, gradients or images. Colors and images will tile across the
background. Gradients stretch to fill the background.
-'''PLEASE NOTE:''' Backgrounds are actual elements, not styles. HTML treats
-backgrounds like styles. Which means every box can only have one background.
-Shoes layers background elements.
-
{{{
#!ruby
Shoes.app do
@@ -2121,16 +2199,90 @@ The above example paints two backgrounds. First, a black background is painted
over the entire app's surface area. Then a 50 pixel white stripe is painted
along the left side.
+Background are reusable and can be copied because they inherit from Pattern.
+
+{{{
+Shoes.app do
+ stack(left: 0, top: 0, width: width / 4, height: height / 4) do
+ @b = background "#{DIR}/static/stripe.png"
+ end
+
+ 4.times do |n|
+ stack(left: n * width / 4, top: n * height / 4, width: width / 4, height: height / 4) do
+ background @b
+ end
+ end
+end
+}}}
+
+Once a background is created it's size and location won't change unless the slot
+is resized. If the slot has a scroll bar it may do what you think. Scroll thru
+this example:
+
+{{{
+Shoes.app(title: "No Scroll", width: 300, height: 400, resizable: true ) do
+ background green
+ @main = stack left: 0.05, top: 0.15, width: 0.9, height: 0.8, scroll: true do
+ background beige
+ 100.times do |i|
+ para "#{i+1} times"
+ end
+ end
+end
+}}}
+
+As of Shoes 3.3.3, You can ask Shoes to be more respectful of scrolling by setting scroll: true
+as this example does
+{{{
+Shoes.app(title: "Scroll", width: 300, height: 400, resizable: true ) do
+ background green
+ @main = stack left: 0.05, top: 0.15, width: 0.9, height: 0.8, scroll: true do
+ background beige, scroll: true
+ 100.times do |i|
+ para "#{i+1} times"
+ end
+ end
+end
+}}}
+
+Be careful when using scroll: true. It may find a scrollbar you didn't want
+to use and it's not Shoes 4 compatible.
+
+'''PLEASE NOTE:''' Backgrounds are actual elements, not styles. HTML treats
+backgrounds like styles. Which means every box can only have one background.
+Shoes layers background elements.
+
=== banner(text) » Shoes::Banner ===
Creates a Banner text block. Shoes automatically styles this text to 48 pixels high.
=== border(text, :strokewidth => a number) » Shoes::Border ===
-Draws a Border element using a specific color (or pattern.) Patterns can be
-colors, gradients or images. Colors and images will tile across the border.
+Draws a Border element using a specific color (or pattern). Patterns can be
+colors, gradients or images. Colors and images will tile across the border.
Gradients stretch to fill the border.
+=== border(pattern) » Shoes::Border ===
+
+Draws a Border element with a specific pattern. Borders are reusable and can be copied
+because they inherit from Pattern.
+
+{{{
+Shoes.app do
+ stack :width => 50, :height => 30 do
+ @b = border red, :strokewidth => 5
+ para "=^.^=", :stroke => green
+ end
+
+ 12.times do |n|
+ stack :left => n * 50, :top => height / 2, :width => 50 do
+ border @b
+ para "=^.^=", :stroke => green
+ end
+ end
+end
+}}}
+
'''PLEASE NOTE:''' Like Backgrounds, Borders are actual elements, not styles.
HTML treats backgrounds and borders like styles. Which means every box can
only have one borders. Shoes layers border and background elements, along with
@@ -2994,6 +3146,38 @@ shape. Or any other number of style settings.
Hides an element if it is shown. Or shows the element, if it is hidden.
+=== tooltip() » a string ===
+
+Returns a string containing the tooltip text from an element.
+
+{{{
+#!ruby
+Shoes.app do
+ button "push me!", tooltip: "push me at your own risk..." do
+ alert("...seriously?")
+ end
+end
+}}}
+
+=== tooltip = a string ===
+
+Set the tooltip text from an element with the given string.
+
+{{{
+Shoes.app do
+ @e = edit_line
+ @b = button "set tooltip" do
+ @e.tooltip = @e.text
+ @b.tooltip = @e.text
+ @b2.tooltip = @e.text
+ end
+ @b2 = button "get tooltip" do
+ @p.text = @b.tooltip
+ end
+ @p = para
+end
+}}}
+
=== top() » a number ===
Gets the pixel position of the top edge of the element.
@@ -3075,26 +3259,6 @@ Or, to paint a fifty pixel column on the right-side of the window:
Since Backgrounds are normal elements as well, see also the start of the
[[Elements]] section for all of its other methods.
-=== to_pattern() » a Shoes::Pattern ===
-
-Yanks out the color, gradient or image used to paint this background and places
-it in a normal Shoes::Pattern object. You can then pass that object to other
-backgrounds and borders. Reuse it as you like.
-
-{{{
-Shoes.app do
- stack(left: 0, top: 0, width: width / 4, height: height / 4) do
- @b = background "#{DIR}/static/stripe.png"
- end
-
- 4.times do |n|
- stack(left: n * width / 4, top: n * height / 4, width: width / 4, height: height / 4) do
- background @b.to_pattern
- end
- end
-end
-}}}
-
== Border ==
A border is a color, gradient or image painted in a line around the edge of any
@@ -3144,28 +3308,6 @@ stays fifty pixels wide regardless of its borders or margins or anything else.
Please also check out the [[Elements]] section for other methods used on borders.
-=== to_pattern() » a Shoes::Pattern ===
-
-Creates a basic pattern object based on the color, gradient or image used to
-paint this border. The pattern may then be re-used in new borders and
-backgrounds.
-
-{{{
-Shoes.app do
- stack :width => 50, :height => 30 do
- @b = border red, :strokewidth => 5
- para "=^.^=", :stroke => green
- end
-
- 12.times do |n|
- stack :left => n * 50, :top => height / 2, :width => 50 do
- border @b.to_pattern
- para "=^.^=", :stroke => green
- end
- end
-end
-}}}
-
== Button ==
Buttons are, you know, push buttons. You click them and they do something.
@@ -3282,6 +3424,17 @@ Okay, let's add to the above example.
So, when the button gets pressed, each of the checks gets asked for its status,
using the `checked?` method.
+You can also set a default `checked` value.
+
+{{{
+#!ruby
+Shoes.app do
+ flow { check; para "Default check (unchecked)" }
+ flow { check checked: false; para "Unchecked check" }
+ flow { check checked: true; para "Checked check" }
+end
+}}}
+
Button methods are listed below, but also see the list of [[Common]] methods,
which all elements respond to.
@@ -3897,6 +4050,78 @@ See [[Styles.state]] style for details.
See [[Styles.state]] style for details.
+== Spinner ==
+
+A Spinner is a widget that allows you display the "I'm busy" rotating
+animated wheel-of-slow !{:margin_left => 100}man-ele-spinner.png!
+
+Here is a sample spinner:
+{{{
+#!ruby
+Shoes.app(width: 200, height: 80) do
+ stack left: 60, top: 20 do
+ spinner width: 80, start: true, tooltip: "waiting for something?"
+ end
+end
+}}}
+
+Spinner methods are listed below, but also see the list of [[Common]] methods,
+which all elements spinner may respond to. The default for a spinner is too
+not aninamte (spin).
+
+Caution: In OSX, this in not a native control so it won't have a tooltip
+
+=== started? » true or false ===
+
+Returns either true or false whether the `spinner` element is started or stopped.
+
+{{{
+#!ruby
+Shoes.app do
+ @s = spinner width: 80
+
+ click do |btn, left, top|
+ @s.started? ? @s.stop : @s.start
+ @p.text = @s.started?
+ end
+
+ @p = para
+end
+}}}
+
+=== start() » self ===
+
+Start a `spinner` element.
+
+=== stop() » self ===
+
+Stop a `spinner` element.
+
+=== tooltip() » a string ===
+
+Returns a string containing the tooltip text from a `spinner` element.
+
+{{{
+#!ruby
+Shoes.app do
+ spinner tooltip: "Not spinning enough?"
+end
+}}}
+
+=== tooltip = a string ===
+
+Set the tooltip text from a `spinner` element with the given string.
+
+{{{
+Shoes.app(:width => 450, :height => 250) do
+ @s = spinner start: true
+
+ every(1) do |count|
+ @s.tooltip = "count #{count}"
+ end
+end
+}}}
+
== Svg ==
In Shoes 3.3 we gained the ability to draw svgs. While they may appear to
@@ -4068,6 +4293,93 @@ the svg image is written.
svg file that is quite small (or quite larger) which may not pass muster for
strict svg parsing.
+== Switch ==
+
+Switch are clickable buttons that can be either on or off. They are fantastic
+for your configuration panel. !{:margin_left => 100}man-ele-switch.png!
+
+Here is a sample switch:
+{{{
+#!ruby
+Shoes.app do
+ switch; para "turn on and off"
+end
+}}}
+
+Switch methods are listed below, but also see the list of [[Common]] methods,
+which all elements respond to.
+
+=== active? » true or false ===
+
+Returns either true or false whether the `switch` element is turned on or off.
+
+{{{
+#!ruby
+Shoes.app do
+ switch.click do |n|
+ @p.text = n.active?
+ end
+ @p = para
+end
+}}}
+
+=== active = true or false ===
+
+Turn on or off a `switch` element.
+
+{{{
+#!ruby
+Shoes.app do
+ @s = switch
+
+ every(1) do
+ @s.active = @s.active? ^ true
+ end
+end
+}}}
+
+=== click() { |self| ... } » self ===
+
+When the switch is clicked, its `click` block is called. The block is handed
+`self`, which is the switch object that was clicked.
+
+{{{
+#!ruby
+Shoes.app do
+ switch.click do |n|
+ alert "switch box clicked, active? #{n.active?}"
+ end
+end
+}}}
+
+Clicks are sent for both switching on and off.
+
+=== tooltip() » a string ===
+
+Returns a string containing the tooltip text from a `switch` element.
+
+{{{
+#!ruby
+Shoes.app do
+ switch tooltip: "Turn the switch on or off" do |n|
+ @p.text = n.tooltip
+ end
+ @p = para
+end
+}}}
+
+=== tooltip = a string ===
+
+Set the tooltip text from a `switch` element with the given string.
+
+{{{
+Shoes.app(:title => "Switching On and Off", :width => 450, :height => 250) do
+ switch do |n|
+ n.tooltip = "Switch is active? #{n.active?}"
+ end
+end
+}}}
+
== Snapshot ==
Shoes can draw an image block into a file instead of on the screen by calling
@@ -4111,6 +4423,55 @@ end
note that the method returns the drawing code (text) of the snapshot, so
you might take further control about details of your svg image for example.
+== Systray ==
+
+Systray allows you to send an icon and a text message to the desktop manager
+which will be shown where the platform decides it should be (systray for Windows),
+Notification area for Linux and OSX. Typically, you would call it for some
+long running process, like a email client that got a new message and you the desktop
+to know about it.
+
+This is not a widget you can modify. There are no methods other than creating it
+and that will return nil (even when it works). There is no guarantee it will work,
+particularly if you call it too often and expect everything to show up. That's up to
+the OS and Desktop manager, not Shoes.
+
+You can call it in two ways, with positional arguments or with a hash of arguments.
+
+
+=== systray , , » nil ===
+
+The first string is the title, the second is the message to display and the
+third string is a file path to the icon. The example below describes the preferred
+way
+
+=== systray title: , message: , icon: » nil ===
+
+You can also use a hash of arguments. The example below is worth some study.
+{{{
+#!ruby
+Shoes.app do
+ stack do
+ para "Press button and look in your system's notification area"
+ ctr = 0;
+ button "Notify" do
+ ctr += 1
+ icp = ''
+ if ctr % 3 != 0
+ icp = "#{DIR}/static/shoes-icon.png"
+ else
+ icp = "#{DIR}/static/shoes-icon-red.png"
+ end
+ systray title: "Shoes Notify", message: "message ##{ctr}", icon: icp
+ end
+ end
+end
+}}}
+
+Notice how we change the message: and every third click, the icon changes.
+Changes to the title: may not appear, depending on your platform so you
+not change change it. All three arguments must be included.
+
== TextBlock ==
The TextBlock object represents a group of text organized as a single element.
@@ -4836,12 +5197,26 @@ Another caution - these are methods of an App instance so you need that object.
Even when they effect more than one instance of App. Shoes creates an 'app'
method in the Shoes.app block that you must use for the following.
+=== app.decorated » true or false ===
+
+Decorations are the title bar and window resize controls.
+
+Returns true or false whether the window has decorations or not. See below
+for the issues involved.
+
+=== app.decorated = true or false ===
+
+Warning: This is highly platform/theme specific. DO NOT assume that if it works
+for you, that it will work for anyone else. It won't work for everyone. OSX for example.
+Combined with fullscreem - you are asking for trouble. Think twice or thrice.
+
+Set window decorations. `true` will display titlebar, and resize buttons and `false` will hide them.
+
=== app.fullscreen » boolean ===
This returns true or false if your script is running in full screen mode
-
-=== app.fullscreen=(Boolean) ===
+=== app.fullscreen = (Boolean) ===
Set fullscreen to true or false. If you do this, you should provide a method
for turning it off. There's nothing more annoying that than a full screen app
@@ -4864,6 +5239,13 @@ Parenthesis are required.
Returns the Shoes url. Be careful. It's a shoes-url so it might not be what
you think.
+=== app.resize width, height » boolean ===
+
+Change the size of the window. You don't want to increase beyond your or
+your users screen size - That could be a problem (crash?). Also it can misbehave if
+you shrink it smaller than the original creation size. Always returns True
+but there is no error checking. Use cautiously.
+
=== app.started? » boolean ===
Is the app completely initiailized?
@@ -4877,6 +5259,27 @@ Returns the current width.
Returns the current height. Perhaps you need it and the width after going fullscreen
to setup your game to the size availavble.
+=== app.opacity » a float number ===
+
+Returns a float number of the current window opacity. The default opacity is `1.0`
+where you see the window without transparency. An opacity of `0.0` is fully transparent window.
+
+=== app.opacity = a float number ===
+
+Set the window opacity with a float number. A fully transparent window has an opacity of `0.0`
+whereas a fully visible window has an opacity of `1.0`.
+
+{{{
+Shoes.app do
+ @b = banner "Opacity\n"
+
+ slider fraction: 1.0 do |n|
+ app.opacity = n.fraction
+ @b.text = "Opacity %.2f\n" % n.fraction
+ end
+end
+}}}
+
=== app.slot » Array ===
For Advanced users: