libui 0.0.4.alpha → 0.0.5.alpha
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +5 -1
- data/lib/libui.rb +49 -12
- data/lib/libui/ffi.rb +89 -12
- data/lib/libui/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9942c95097af2b3c542472fa3e144e040cf3f9c0ef253e891d87b79b93070e77
|
4
|
+
data.tar.gz: a69a733f1cd1dd2274c601422a2cb3a5b91d762055d73fc3e9e9f59e6f11c919
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 47d42cfbc47996ad411f0ba9e6634378fa2bd088d84bc4179698c4ad3c049a7ce8e75218c8fd93538362d01961c9ca4d278aa2c60a5074a1fea532d4b22841b8
|
7
|
+
data.tar.gz: 25c390450f42ff51ee05a9f5c7c9409c16860ac1ae3351e0d85aa30ad1d753f7cad2e1091ff9193bdf85cb21d77c344fbe1acdb5e429746e9d69574b59388379
|
data/README.md
CHANGED
@@ -1,7 +1,9 @@
|
|
1
1
|
# libui
|
2
|
+
|
3
|
+

|
2
4
|
[](https://badge.fury.io/rb/libui)
|
3
5
|
|
4
|
-
[libui](https://github.com/andlabs/libui) - a portable GUI library -for Ruby
|
6
|
+
:radio_button: [libui](https://github.com/andlabs/libui) - a portable GUI library -for Ruby
|
5
7
|
|
6
8
|
## Installation
|
7
9
|
|
@@ -9,6 +11,8 @@
|
|
9
11
|
gem install libui --pre
|
10
12
|
```
|
11
13
|
|
14
|
+
The libui gem package contains the official release of the libui shared library version 4.1 for Windows, Mac, and Linux.
|
15
|
+
|
12
16
|
## Usage
|
13
17
|
|
14
18
|
See [examples](https://github.com/kojix2/libui/tree/main/examples) directory.
|
data/lib/libui.rb
CHANGED
@@ -9,31 +9,68 @@ module LibUI
|
|
9
9
|
attr_accessor :ffi_lib
|
10
10
|
end
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
12
|
+
lib_name = case RbConfig::CONFIG['host_os']
|
13
|
+
when /mswin|msys|mingw|cygwin|bccwin|wince|emc/
|
14
|
+
'libui.dll'
|
15
|
+
when /darwin|mac os/
|
16
|
+
'libui.dylib'
|
17
|
+
else
|
18
|
+
'libui.so'
|
19
|
+
end
|
20
|
+
|
21
|
+
self.ffi_lib = if ENV['LIBUIDIR'] && !ENV['LIBUIDIR'].empty?
|
22
|
+
File.expand_path(lib_name, ENV['LIBUIDIR'])
|
23
|
+
else
|
24
|
+
File.expand_path("../vendor/#{lib_name}", __dir__)
|
22
25
|
end
|
23
26
|
|
24
27
|
require_relative 'libui/ffi'
|
25
28
|
|
26
29
|
class << self
|
27
|
-
FFI.
|
30
|
+
FFI.func_map.each_key do |original_method_name|
|
31
|
+
# Convert snake_case to CamelCase.
|
28
32
|
name = original_method_name.delete_prefix('ui')
|
29
33
|
.gsub(/::/, '/')
|
30
34
|
.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
|
31
35
|
.gsub(/([a-z\d])([A-Z])/, '\1_\2')
|
32
36
|
.tr('-', '_')
|
33
37
|
.downcase
|
34
|
-
|
38
|
+
|
39
|
+
func = FFI.func_map[original_method_name]
|
40
|
+
|
41
|
+
define_method(name) do |*args, &blk|
|
42
|
+
# Assume that block is the last argument.
|
43
|
+
args << blk if blk
|
44
|
+
|
45
|
+
# The proc object is converted to a Closure::BlockCaller object.
|
46
|
+
args.map!.with_index do |arg, idx|
|
47
|
+
if arg.is_a?(Proc)
|
48
|
+
# The types of the function arguments are recorded beforehand.
|
49
|
+
# See the monkey patch in ffi.rb.
|
50
|
+
Fiddle::Closure::BlockCaller.new(*func.inner_functions[idx][1..2], &arg)
|
51
|
+
else
|
52
|
+
arg
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# Make it possible to omit the last nil. This may be an over-optimization.
|
57
|
+
siz = func.argtype.size - 1
|
58
|
+
args[siz] = nil if args.size == siz
|
59
|
+
|
35
60
|
FFI.public_send(original_method_name, *args)
|
36
61
|
end
|
37
62
|
end
|
63
|
+
|
64
|
+
module CustomMethods
|
65
|
+
def init(opt = FFI::InitOptions.malloc)
|
66
|
+
i = super(opt)
|
67
|
+
unless i.size.zero?
|
68
|
+
warn 'error'
|
69
|
+
warn UI.free_init_error(init)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
prepend CustomMethods
|
38
75
|
end
|
39
76
|
end
|
data/lib/libui/ffi.rb
CHANGED
@@ -2,6 +2,81 @@
|
|
2
2
|
|
3
3
|
require 'fiddle/import'
|
4
4
|
|
5
|
+
module Fiddle
|
6
|
+
# Change the Function to hold a little more information.
|
7
|
+
# FIXME: Give inner_function a better name.
|
8
|
+
class Function
|
9
|
+
attr_accessor :inner_functions, :argtype
|
10
|
+
end
|
11
|
+
|
12
|
+
module Importer
|
13
|
+
def parse_signature(signature, tymap = nil)
|
14
|
+
tymap ||= {}
|
15
|
+
ret, func, args = split_signature(signature)
|
16
|
+
symname = func
|
17
|
+
ctype = parse_ctype(ret, tymap)
|
18
|
+
inner_funcs = [] # Added
|
19
|
+
argtype = split_arguments(args).collect.with_index do |arg, idx| # Added with_index
|
20
|
+
# Check if it is a function pointer or not
|
21
|
+
if arg =~ /\(\*.*\)\(.*\)/ # Added
|
22
|
+
# From the arguments, create a notation that looks like a function declaration
|
23
|
+
# int(*f)(int *, void *) -> int f(int *, void *)
|
24
|
+
func_arg = arg.sub('(*', ' ').sub(')', '') # Added
|
25
|
+
# Use Fiddle's parse_signature method again.
|
26
|
+
inner_funcs[idx] = parse_signature(func_arg) # Added
|
27
|
+
end # Added
|
28
|
+
parse_ctype(arg, tymap)
|
29
|
+
end
|
30
|
+
# Added inner_funcs. Original method return only 3 values.
|
31
|
+
[symname, ctype, argtype, inner_funcs]
|
32
|
+
end
|
33
|
+
|
34
|
+
# refactored
|
35
|
+
def split_signature(signature)
|
36
|
+
case compact(signature)
|
37
|
+
when /^(?:[\w*\s]+)\(\*(\w+)\((.*?)\)\)(?:\[\w*\]|\(.*?\));?$/
|
38
|
+
func = Regexp.last_match(1)
|
39
|
+
args = Regexp.last_match(2)
|
40
|
+
[TYPE_VOIDP, func, args]
|
41
|
+
when /^([\w*\s]+[*\s])(\w+)\((.*?)\);?$/
|
42
|
+
ret = Regexp.last_match(1).strip
|
43
|
+
func = Regexp.last_match(2)
|
44
|
+
args = Regexp.last_match(3)
|
45
|
+
[ret, func, args]
|
46
|
+
else
|
47
|
+
raise("can't parse the function prototype: #{signature}")
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def extern(signature, *opts)
|
52
|
+
symname, ctype, argtype, inner_funcs = parse_signature(signature, type_alias)
|
53
|
+
opt = parse_bind_options(opts)
|
54
|
+
f = import_function(symname, ctype, argtype, opt[:call_type])
|
55
|
+
|
56
|
+
f.inner_functions = inner_funcs # Added
|
57
|
+
f.argtype = argtype # Added
|
58
|
+
|
59
|
+
name = symname.gsub(/@.+/, '')
|
60
|
+
@func_map[name] = f
|
61
|
+
# define_method(name){|*args,&block| f.call(*args,&block)}
|
62
|
+
begin
|
63
|
+
/^(.+?):(\d+)/ =~ caller.first
|
64
|
+
file = Regexp.last_match(1)
|
65
|
+
line = Regexp.last_match(2).to_i
|
66
|
+
rescue StandardError
|
67
|
+
file, line = __FILE__, __LINE__ + 3
|
68
|
+
end
|
69
|
+
module_eval(<<-EOS, file, line)
|
70
|
+
def #{name}(*args, &block)
|
71
|
+
@func_map['#{name}'].call(*args,&block)
|
72
|
+
end
|
73
|
+
EOS
|
74
|
+
module_function(name)
|
75
|
+
f
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
5
80
|
module LibUI
|
6
81
|
module FFI
|
7
82
|
extend Fiddle::Importer
|
@@ -13,20 +88,12 @@ module LibUI
|
|
13
88
|
end
|
14
89
|
|
15
90
|
class << self
|
16
|
-
attr_reader :
|
91
|
+
attr_reader :func_map
|
17
92
|
|
18
|
-
# Improved extern method.
|
19
|
-
# 1. Ignore functions that cannot be attached.
|
20
|
-
# 2. Available function (names) are stored in @ffi_methods.
|
21
93
|
def try_extern(signature, *opts)
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
@ffi_methods << func.name
|
26
|
-
func
|
27
|
-
rescue StandardError => e
|
28
|
-
warn "#{e.class.name}: #{e.message}"
|
29
|
-
end
|
94
|
+
extern(signature, *opts)
|
95
|
+
rescue StandardError => e
|
96
|
+
warn "#{e.class.name}: #{e.message}"
|
30
97
|
end
|
31
98
|
end
|
32
99
|
|
@@ -401,6 +468,11 @@ module LibUI
|
|
401
468
|
|
402
469
|
try_extern 'uiAttribute *uiNewUnderlineColorAttribute(uiUnderlineColor u, double r, double g, double b, double a)'
|
403
470
|
try_extern 'void uiAttributeUnderlineColor(const uiAttribute *a, uiUnderlineColor *u, double *r, double *g, double *b, double *alpha)'
|
471
|
+
|
472
|
+
# uiOpenTypeFeatures
|
473
|
+
|
474
|
+
typealias 'uiOpenTypeFeaturesForEachFunc', 'void*'
|
475
|
+
|
404
476
|
try_extern 'uiOpenTypeFeatures *uiNewOpenTypeFeatures(void)'
|
405
477
|
try_extern 'void uiFreeOpenTypeFeatures(uiOpenTypeFeatures *otf)'
|
406
478
|
try_extern 'uiOpenTypeFeatures *uiOpenTypeFeaturesClone(const uiOpenTypeFeatures *otf)'
|
@@ -410,6 +482,11 @@ module LibUI
|
|
410
482
|
try_extern 'void uiOpenTypeFeaturesForEach(const uiOpenTypeFeatures *otf, uiOpenTypeFeaturesForEachFunc f, void *data)'
|
411
483
|
try_extern 'uiAttribute *uiNewFeaturesAttribute(const uiOpenTypeFeatures *otf)'
|
412
484
|
try_extern 'const uiOpenTypeFeatures *uiAttributeFeatures(const uiAttribute *a)'
|
485
|
+
|
486
|
+
# uiAttributedString
|
487
|
+
|
488
|
+
typealias 'uiAttributedStringForEachAttributeFunc', 'void*'
|
489
|
+
|
413
490
|
try_extern 'uiAttributedString *uiNewAttributedString(const char *initialString)'
|
414
491
|
try_extern 'void uiFreeAttributedString(uiAttributedString *s)'
|
415
492
|
try_extern 'const char *uiAttributedStringString(const uiAttributedString *s)'
|
data/lib/libui/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: libui
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5.alpha
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- kojix2
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-12-
|
11
|
+
date: 2020-12-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|