libui 0.0.4.alpha → 0.0.5.alpha
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
![build](https://github.com/kojix2/libui/workflows/build/badge.svg)
|
2
4
|
[![Gem Version](https://badge.fury.io/rb/libui.svg)](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
|