rb_sdl2 0.1.0

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.
Files changed (67) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +5 -0
  3. data/LICENSE.txt +17 -0
  4. data/README.md +40 -0
  5. data/lib/rb_sdl2/audio/audio_allowed_changes.rb +17 -0
  6. data/lib/rb_sdl2/audio/audio_buffer.rb +49 -0
  7. data/lib/rb_sdl2/audio/audio_device.rb +44 -0
  8. data/lib/rb_sdl2/audio/audio_format.rb +23 -0
  9. data/lib/rb_sdl2/audio/audio_spec.rb +29 -0
  10. data/lib/rb_sdl2/audio.rb +132 -0
  11. data/lib/rb_sdl2/clipboard.rb +44 -0
  12. data/lib/rb_sdl2/cpu_info.rb +39 -0
  13. data/lib/rb_sdl2/cursor/color_cursor.rb +19 -0
  14. data/lib/rb_sdl2/cursor/cursor_class.rb +24 -0
  15. data/lib/rb_sdl2/cursor/cursor_pointer.rb +12 -0
  16. data/lib/rb_sdl2/cursor/default_cursor.rb +18 -0
  17. data/lib/rb_sdl2/cursor/system_cursor.rb +45 -0
  18. data/lib/rb_sdl2/cursor.rb +39 -0
  19. data/lib/rb_sdl2/display.rb +103 -0
  20. data/lib/rb_sdl2/display_mode.rb +35 -0
  21. data/lib/rb_sdl2/error.rb +9 -0
  22. data/lib/rb_sdl2/event/event_filter.rb +83 -0
  23. data/lib/rb_sdl2/event/event_queue.rb +137 -0
  24. data/lib/rb_sdl2/event/event_type.rb +271 -0
  25. data/lib/rb_sdl2/event.rb +161 -0
  26. data/lib/rb_sdl2/filesystem.rb +40 -0
  27. data/lib/rb_sdl2/hint.rb +24 -0
  28. data/lib/rb_sdl2/keyboard/key_mod.rb +37 -0
  29. data/lib/rb_sdl2/keyboard/keyboard_state.rb +34 -0
  30. data/lib/rb_sdl2/keyboard.rb +50 -0
  31. data/lib/rb_sdl2/message_box.rb +121 -0
  32. data/lib/rb_sdl2/mouse/global_mouse.rb +18 -0
  33. data/lib/rb_sdl2/mouse/mouse_button.rb +24 -0
  34. data/lib/rb_sdl2/mouse/mouse_class.rb +33 -0
  35. data/lib/rb_sdl2/mouse/mouse_wheel.rb +53 -0
  36. data/lib/rb_sdl2/mouse/relative_mouse.rb +12 -0
  37. data/lib/rb_sdl2/mouse/window_mouse.rb +17 -0
  38. data/lib/rb_sdl2/mouse.rb +74 -0
  39. data/lib/rb_sdl2/palette.rb +70 -0
  40. data/lib/rb_sdl2/pixel_format_enum.rb +73 -0
  41. data/lib/rb_sdl2/platform.rb +7 -0
  42. data/lib/rb_sdl2/power_info.rb +36 -0
  43. data/lib/rb_sdl2/rect.rb +14 -0
  44. data/lib/rb_sdl2/ref_count_pointer.rb +20 -0
  45. data/lib/rb_sdl2/rw_ops/rw_operator.rb +102 -0
  46. data/lib/rb_sdl2/rw_ops.rb +124 -0
  47. data/lib/rb_sdl2/screen_saver.rb +11 -0
  48. data/lib/rb_sdl2/sdl.rb +32 -0
  49. data/lib/rb_sdl2/surface/blend_mode.rb +41 -0
  50. data/lib/rb_sdl2/surface/pixel_format.rb +89 -0
  51. data/lib/rb_sdl2/surface.rb +244 -0
  52. data/lib/rb_sdl2/text_input.rb +15 -0
  53. data/lib/rb_sdl2/timer.rb +22 -0
  54. data/lib/rb_sdl2/version.rb +13 -0
  55. data/lib/rb_sdl2/video.rb +25 -0
  56. data/lib/rb_sdl2/window/dialog.rb +19 -0
  57. data/lib/rb_sdl2/window/display.rb +85 -0
  58. data/lib/rb_sdl2/window/grab.rb +23 -0
  59. data/lib/rb_sdl2/window/hit_test.rb +52 -0
  60. data/lib/rb_sdl2/window/position.rb +38 -0
  61. data/lib/rb_sdl2/window/shape.rb +76 -0
  62. data/lib/rb_sdl2/window/size.rb +59 -0
  63. data/lib/rb_sdl2/window/window_flags.rb +78 -0
  64. data/lib/rb_sdl2/window.rb +242 -0
  65. data/lib/rb_sdl2.rb +53 -0
  66. data/rb_sdl2.gemspec +19 -0
  67. metadata +135 -0
@@ -0,0 +1,103 @@
1
+ module RbSDL2
2
+ class Display
3
+ class << self
4
+ def displays
5
+ count = ::SDL2.SDL_GetNumVideoDisplays
6
+ raise RbSDL2Error if count < 0
7
+ count.times.map { |num| Display.new(num) }
8
+ end
9
+ end
10
+
11
+ def initialize(num)
12
+ @num = num
13
+ end
14
+
15
+ def bounds
16
+ rect = Rect.new
17
+ err = ::SDL2.SDL_GetDisplayBounds(index, rect)
18
+ raise RbSDL2Error if err < 0
19
+ rect.to_a
20
+ end
21
+
22
+ require_relative 'display_mode'
23
+
24
+ def closest_display_mode(**display_mode)
25
+ mode ||= DisplayMode.new(**display_mode)
26
+ closest = DisplayMode.new
27
+ err = ::SDL2.SDL_GetClosestDisplayMode(self, mode, closest)
28
+ raise RbSDL2Error if err.null?
29
+ closest
30
+ # 利用可能なディスプレイモードが検索され, 要求と最も近いモードがclosestに代入される.
31
+ # modeのformatとrefresh_rateが0の場合, デスクトップのモードとなる.
32
+ # モードは, サイズを最優先で検索し, ピクセル形式は次の優先度となる.
33
+ # そして最後に更新周期をチェックする. 利用可能なモードが要求に対して小さすぎる場合, NULLを戻す.
34
+ end
35
+
36
+ def current_display_mode
37
+ obj = DisplayMode.new
38
+ err = ::SDL2.SDL_GetCurrentDisplayMode(index, obj)
39
+ raise RbSDL2Error if err < 0
40
+ obj
41
+ end
42
+
43
+ def desktop_display_mode
44
+ obj = DisplayMode.new
45
+ err = ::SDL2.SDL_GetDesktopDisplayMode(index, obj)
46
+ raise RbSDL2Error if err < 0
47
+ obj
48
+ end
49
+
50
+ def display_modes
51
+ num = ::SDL2.SDL_GetNumDisplayModes(index)
52
+ raise RbSDL2Error if num < 0
53
+ num.times.map do |mode_index|
54
+ obj = DisplayMode.new
55
+ err = ::SDL2.SDL_GetDisplayMode(index, mode_index, obj)
56
+ raise RbSDL2Error if err < 0
57
+ obj
58
+ end
59
+ end
60
+
61
+ # ディスプレイピクセルの斜め、水平、垂直方向の DPI を配列で戻す。
62
+ def dpi
63
+ d_h_v_dpi = Array.new(3) { ::FFI::MemoryPointer.new(:float) }
64
+ err = ::SDL2.SDL_GetDisplayDPI(index, *d_h_v_dpi)
65
+ raise RbSDL2Error if err < 0
66
+ d_h_v_dpi.map { |v| v.read_float }
67
+ end
68
+
69
+ def index = @num
70
+ alias to_int index
71
+
72
+ def inspect
73
+ "#<#{self.class.name} name=#{name.inspect} bounds=#{bounds} dpi=#{dpi}>"
74
+ end
75
+
76
+ def name
77
+ ptr = ::SDL2.SDL_GetDisplayName(index)
78
+ raise RbSDL2Error if ptr.null?
79
+ ptr.read_string.force_encoding(Encoding::UTF_8)
80
+ end
81
+ alias to_s name
82
+
83
+ def orientation = ::SDL2.SDL_GetDisplayOrientation(index)
84
+
85
+ module DisplayOrientation
86
+ def flipped_landscape? = ::SDL2::SDL_ORIENTATION_LANDSCAPE_FLIPPED == orientation
87
+
88
+ def flipped_portrait? = ::SDL2::SDL_ORIENTATION_PORTRAIT_FLIPPED == orientation
89
+
90
+ def landscape? = ::SDL2::SDL_ORIENTATION_LANDSCAPE == orientation
91
+
92
+ def portrait? = ::SDL2::SDL_ORIENTATION_PORTRAIT == orientation
93
+ end
94
+ include DisplayOrientation
95
+
96
+ def usable_bounds
97
+ rect = Rect.new
98
+ err = ::SDL2.SDL_GetDisplayUsableBounds(index, rect)
99
+ raise RbSDL2Error if err < 0
100
+ rect.to_a
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,35 @@
1
+ module RbSDL2
2
+ class DisplayMode
3
+ def initialize(format: 0, h: 0, height: h, refresh_rate: 0, w: 0, width: w)
4
+ @st = ::SDL2::SDL_DisplayMode.new
5
+ @st[:format] = PixelFormatEnum.to_num(format)
6
+ @st[:w] = width
7
+ @st[:h] = height
8
+ @st[:refresh_rate] = refresh_rate
9
+ end
10
+
11
+ def format = @st[:format]
12
+
13
+ require_relative 'pixel_format_enum'
14
+ include PixelFormatEnum
15
+
16
+ def inspect
17
+ "#<#{self.class.name} pixel_format_name=#{pixel_format_name} w=#{w} h=#{h}\
18
+ refresh_rate=#{refresh_rate}>"
19
+ end
20
+
21
+ def width = @st[:w]
22
+
23
+ alias w width
24
+
25
+ def height = @st[:h]
26
+
27
+ alias h height
28
+
29
+ def refresh_rate = @st[:refresh_rate]
30
+
31
+ def to_h = {format: format, w: w, h: h, refresh_rate: refresh_rate}
32
+
33
+ def to_ptr = @st.to_ptr
34
+ end
35
+ end
@@ -0,0 +1,9 @@
1
+ module RbSDL2
2
+ module Error
3
+ class << self
4
+ def clear = ::SDL2.SDL_ClearError
5
+
6
+ def message = ::SDL2.SDL_GetError.read_string
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,83 @@
1
+ module RbSDL2
2
+ class Event
3
+ class EventFilter < ::FFI::Function
4
+ @filter_callback = nil, nil
5
+ @filter_mutex = Mutex.new
6
+
7
+ class << self
8
+ def filter_callback_set(obj, userdata = nil)
9
+ func = if Proc === obj
10
+ # イベントを削除する時にイベントメンバーのポインターを開放(Event#clear)する。
11
+ new { |event| obj.call(event) || (event.clear; nil) }
12
+ else
13
+ obj
14
+ end
15
+ # func, userdata の対の関係を保つ。
16
+ @filter_mutex.synchronize do
17
+ ::SDL2.SDL_SetEventFilter(func, userdata)
18
+ @filter_callback = [func, userdata]
19
+ end
20
+ [obj, userdata]
21
+ end
22
+
23
+ # SDL にフィルターコールバック関数が設定されている場合に true を戻す。
24
+ def filter_callback_defined?
25
+ _func_userdata = Array.new(2) { ::FFI::MemoryPointer.new(:pointer) }
26
+ # SDL_GetEventFilter はコールバックのポインター関数が NULL の場合に SDL_FALSE となる。
27
+ # userdata ポインターが設定されていても SDL_GetEventFilter の戻り値に関与しない。
28
+ ::SDL2.SDL_GetEventFilter(*_func_userdata) == ::SDL2::SDL_TRUE
29
+ end
30
+ end
31
+
32
+ @watch_callbacks = []
33
+ @watch_mutex = Mutex.new
34
+
35
+ class << self
36
+ def add_watch_callback(obj, userdata = nil)
37
+ func = if Proc === obj
38
+ new(&obj)
39
+ else
40
+ obj
41
+ end
42
+ obj_userdata = [obj, userdata]
43
+ @watch_mutex.synchronize do
44
+ ::SDL2.SDL_AddEventWatch(func, userdata)
45
+ @watch_callbacks << [obj_userdata, func]
46
+ end
47
+ obj_userdata
48
+ end
49
+
50
+ def remove_watch_callback(obj, userdata = nil)
51
+ obj_userdata = [obj, userdata]
52
+ @watch_mutex.synchronize do
53
+ idx = @watch_callbacks.index { |obj| obj.first == obj_userdata }
54
+ if idx
55
+ _, func = @watch_callbacks.delete_at(idx)
56
+ ::SDL2.SDL_DelEventWatch(func, userdata)
57
+ end
58
+ end
59
+ obj_userdata
60
+ end
61
+ end
62
+
63
+ require 'delegate'
64
+
65
+ # 引数ブロックへはコールバック実行時に Event のインスタンス(のデリゲーター)が与えられる。
66
+ # 与えられた Event インスタンスは引数ブロック終了後に nil に変化する(デリゲート先を変更している)。
67
+ # SDL がイベントコールバックへ与えるイベントへのポインターがイベントキューの一部を直接指しているため
68
+ # コールバックを抜けた後にイベント内容の永続性が保証ができない(たぶん別のイベント内容になるだろう)。
69
+ # 引数ブロックに与えられたオブジェクトをスコープ外に持ち出しても安全である。
70
+ # オブジェクトではなくイベントの内容をスコープ外に持ち出したい場合は
71
+ # 与えられたオブジェクトをコピー(clone, dup)すればよい。
72
+ def initialize
73
+ # typedef int (SDLCALL * SDL_EventFilter) (void *userdata, SDL_Event * event);
74
+ super(:int, [:pointer, :pointer]) do |_userdata, ptr|
75
+ obj = SimpleDelegator.new(Event.to_ptr(ptr))
76
+ yield(obj) ? 1 : 0
77
+ ensure
78
+ obj.__setobj__(nil)
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,137 @@
1
+ module RbSDL2
2
+ class Event
3
+ module EventQueue
4
+ class << self
5
+ require_relative 'event_type'
6
+
7
+ def clear
8
+ # type が ::SDL2::SDL_DROPFILE, ::SDL2::SDL_DROPTEXT の場合に
9
+ # イベントに含まれる file メンバーのポインターが開放されない。そのため Ruby 側で開放処理を行う。
10
+ event = Event.new
11
+ while peep(event, ::SDL2::SDL_GETEVENT,
12
+ type: ::SDL2::SDL_DROPFILE..::SDL2::SDL_DROPTEXT) > 0
13
+ event.clear
14
+ end
15
+ ::SDL2.SDL_FlushEvents(*EventType.minmax)
16
+ end
17
+
18
+ def count(type: nil) = peep(nil, ::SDL2::SDL_PEEKEVENT, type: type)
19
+ alias length count
20
+ alias size count
21
+
22
+ def deq(non_block = false, type: nil)
23
+ event = Event.new
24
+ while peep(event, ::SDL2::SDL_GETEVENT, type: type) == 0
25
+ raise ThreadError, Error.message if non_block
26
+ end
27
+ event
28
+ end
29
+
30
+ # ブロックにはイベントキューにあるイベントが渡される。
31
+ # ブロックへ渡されるイベントはコピーされたものでありブロックの外へ持ち出すことができる。
32
+ # このメソッドは SDL のイベントキューをロックする。
33
+ def each = block_given? ? reject! { |event| yield(event.dup); true } : to_enum
34
+
35
+ def empty? = length == 0
36
+
37
+ # イベントキューが一杯の時に 例外
38
+ def enq(event, non_block = false)
39
+ event_copy(event) do |copy|
40
+ while peep(copy, ::SDL2::SDL_ADDEVENT) == 0
41
+ raise ThreadError, Error.message if non_block
42
+ end
43
+ event
44
+ end
45
+ end
46
+
47
+ private def event_copy(event)
48
+ copy = event.dup
49
+ yield(copy).tap do
50
+ # 成功した場合はメンバーポインターはキューにコピーされた。
51
+ # ブロックの実行が成功したらメンバーポインターの開放を防ぐ。
52
+ if event.drop_file? || event.drop_text?
53
+ copy.to_ptr.autorelease = false
54
+ ::SDL2.SDL_free(copy)
55
+ end
56
+ end
57
+ end
58
+
59
+ private def main_thread!
60
+ if Thread.main != Thread.current
61
+ raise ThreadError, "the current thread is not the main thread"
62
+ end
63
+ end
64
+
65
+ private def peep(event, action, type: nil)
66
+ min_type, max_type = case type
67
+ when nil
68
+ EventType.minmax
69
+ when Range
70
+ type.minmax
71
+ else
72
+ [type, type]
73
+ end
74
+ num = ::SDL2.SDL_PeepEvents(event, event ? 1 : 0, action, min_type, max_type)
75
+ raise RbSDL2Error if num < 0
76
+ num
77
+ end
78
+
79
+ def poll
80
+ main_thread!
81
+ event = Event.new
82
+ ::SDL2::SDL_PollEvent(event).nonzero? && event
83
+ end
84
+ alias get poll
85
+
86
+ def pump
87
+ main_thread!
88
+ ::SDL2.SDL_PumpEvents
89
+ end
90
+
91
+ # イベントをキューに入れる。enq との違いは push ではイベントコールバックを起動する。
92
+ # イベントがキューに入った場合は引数のイベントを戻す。フィルターされた場合は nil を戻す。
93
+ # キューに入れることを失敗したら例外が発生する。
94
+ def push(event)
95
+ event_copy(event) do |copy|
96
+ num = ::SDL2.SDL_PushEvent(copy)
97
+ if num > 0
98
+ event
99
+ elsif num == 0
100
+ nil
101
+ else
102
+ raise RbSDL2Error
103
+ end
104
+ end
105
+ end
106
+
107
+ def quit?
108
+ pump
109
+ ::SDL2.SDL_HasEvent(::SDL2::SDL_QUIT) == ::SDL2::SDL_TRUE
110
+ end
111
+
112
+ require_relative 'event_filter'
113
+
114
+ # ブロックへ与えられたイベントは外に持ち出すことはできない。
115
+ # このメソッドは SDL のイベントキューをロックする。
116
+ # ブロックの戻り値が false の場合、イベントはキューから取り除かれる。
117
+ # userdata に渡されたオブジェクトはポインターに変換可能なものである必要がある。
118
+ def reject!(userdata = nil)
119
+ func = EventFilter.new { |event| yield(event) || (event.clear; nil) }
120
+ ::SDL2.SDL_FilterEvents(func, userdata)
121
+ end
122
+
123
+ def wait(sec = nil)
124
+ main_thread!
125
+ event = Event.new
126
+ if sec.nil?
127
+ ::SDL2::SDL_WaitEvent(event).nonzero? && event
128
+ elsif sec >= 0
129
+ ::SDL2::SDL_WaitEventTimeout(event, sec * 1000).nonzero? && event
130
+ else
131
+ raise ArgumentError
132
+ end
133
+ end
134
+ end
135
+ end
136
+ end
137
+ end
@@ -0,0 +1,271 @@
1
+ # frozen_string_literal: true
2
+ module RbSDL2
3
+ class Event
4
+ module EventType
5
+ RANGE = ::SDL2::SDL_FIRSTEVENT..::SDL2::SDL_LASTEVENT
6
+ EVENT_TYPES = RANGE.first.succ...::SDL2::SDL_LASTEVENT
7
+ COMMON_EVENT_TYPES = EVENT_TYPES.first...::SDL2::SDL_USEREVENT
8
+ USER_EVENT_TYPES = ::SDL2::SDL_USEREVENT...EVENT_TYPES.last
9
+
10
+ default_type = -> (_, key) do
11
+ case key
12
+ when 0 then :common
13
+ when COMMON_EVENT_TYPES then :common
14
+ when USER_EVENT_TYPES then :user
15
+ else raise KeyError, "(#{key})"
16
+ end
17
+ end
18
+
19
+ MEMBER_MAP = Hash.new(&default_type).merge!(
20
+ ::SDL2::SDL_AUDIODEVICEADDED => :adevice,
21
+ ::SDL2::SDL_AUDIODEVICEREMOVED => :adevice,
22
+ ::SDL2::SDL_DISPLAYEVENT => :display,
23
+ ::SDL2::SDL_KEYDOWN => :key,
24
+ ::SDL2::SDL_KEYUP => :key,
25
+ ::SDL2::SDL_CONTROLLERAXISMOTION => :caxis,
26
+ ::SDL2::SDL_CONTROLLERBUTTONDOWN => :cbutton,
27
+ ::SDL2::SDL_CONTROLLERBUTTONUP => :cbutton,
28
+ ::SDL2::SDL_CONTROLLERDEVICEADDED => :cdevice,
29
+ ::SDL2::SDL_CONTROLLERDEVICEREMAPPED => :cdevice,
30
+ ::SDL2::SDL_CONTROLLERDEVICEREMOVED => :cdevice,
31
+ ::SDL2::SDL_CONTROLLERSENSORUPDATE => :csensor,
32
+ ::SDL2::SDL_CONTROLLERTOUCHPADDOWN => :ctouchpad,
33
+ ::SDL2::SDL_CONTROLLERTOUCHPADMOTION => :ctouchpad,
34
+ ::SDL2::SDL_CONTROLLERTOUCHPADUP => :ctouchpad,
35
+ ::SDL2::SDL_DOLLARGESTURE => :dgesture,
36
+ ::SDL2::SDL_DOLLARRECORD => :dgesture,
37
+ ::SDL2::SDL_DROPBEGIN => :drop,
38
+ ::SDL2::SDL_DROPCOMPLETE => :drop,
39
+ ::SDL2::SDL_DROPFILE => :drop,
40
+ ::SDL2::SDL_DROPTEXT => :drop,
41
+ ::SDL2::SDL_FINGERDOWN => :tfinger,
42
+ ::SDL2::SDL_FINGERMOTION => :tfinger,
43
+ ::SDL2::SDL_FINGERUP => :tfinger,
44
+ ::SDL2::SDL_JOYAXISMOTION => :jaxis,
45
+ ::SDL2::SDL_JOYBALLMOTION => :jball,
46
+ ::SDL2::SDL_JOYBUTTONDOWN => :jbutton,
47
+ ::SDL2::SDL_JOYBUTTONUP => :jbutton,
48
+ ::SDL2::SDL_JOYDEVICEADDED => :jdevice,
49
+ ::SDL2::SDL_JOYDEVICEREMOVED => :jdevice,
50
+ ::SDL2::SDL_JOYHATMOTION => :jhat,
51
+ ::SDL2::SDL_MOUSEBUTTONDOWN => :button,
52
+ ::SDL2::SDL_MOUSEBUTTONUP => :button,
53
+ ::SDL2::SDL_MOUSEMOTION => :motion,
54
+ ::SDL2::SDL_MOUSEWHEEL => :wheel,
55
+ ::SDL2::SDL_MULTIGESTURE => :mgesture,
56
+ ::SDL2::SDL_QUIT => :quit,
57
+ ::SDL2::SDL_SENSORUPDATE => :sensor,
58
+ ::SDL2::SDL_SYSWMEVENT => :syswm,
59
+ ::SDL2::SDL_TEXTEDITING => :edit,
60
+ ::SDL2::SDL_TEXTINPUT => :text,
61
+ ::SDL2::SDL_WINDOWEVENT => :window,
62
+ ).freeze
63
+
64
+ default_name = -> (_, key) do
65
+ case key
66
+ when 0 then ""
67
+ when COMMON_EVENT_TYPES then "common_event"
68
+ when USER_EVENT_TYPES then "user_event"
69
+ else raise KeyError, "(#{key})"
70
+ end
71
+ end
72
+
73
+ @name_map = Hash.new(&default_name).merge!(
74
+ ::SDL2::SDL_APP_DIDENTERBACKGROUND => "app_did_enter_background",
75
+ ::SDL2::SDL_APP_DIDENTERFOREGROUND => "app_did_enter_foreground",
76
+ ::SDL2::SDL_APP_LOWMEMORY => "app_low_memory",
77
+ ::SDL2::SDL_APP_TERMINATING => "app_terminating",
78
+ ::SDL2::SDL_APP_WILLENTERBACKGROUND => "app_will_enter_background",
79
+ ::SDL2::SDL_APP_WILLENTERFOREGROUND => "app_will_enter_foreground",
80
+ ::SDL2::SDL_AUDIODEVICEADDED => "audio_device_added",
81
+ ::SDL2::SDL_AUDIODEVICEREMOVED => "audio_device_removed",
82
+ ::SDL2::SDL_CLIPBOARDUPDATE => "clipboard_update",
83
+ ::SDL2::SDL_CONTROLLERAXISMOTION => "controller_axis_motion",
84
+ ::SDL2::SDL_CONTROLLERBUTTONDOWN => "controller_button_down",
85
+ ::SDL2::SDL_CONTROLLERBUTTONUP => "controller_button_up",
86
+ ::SDL2::SDL_CONTROLLERDEVICEADDED => "controller_device_added",
87
+ ::SDL2::SDL_CONTROLLERDEVICEREMAPPED => "controller_device_remapped",
88
+ ::SDL2::SDL_CONTROLLERDEVICEREMOVED => "controller_device_removed",
89
+ ::SDL2::SDL_CONTROLLERSENSORUPDATE => "controller_sensor_update",
90
+ ::SDL2::SDL_CONTROLLERTOUCHPADDOWN => "controller_touchpad_down",
91
+ ::SDL2::SDL_CONTROLLERTOUCHPADMOTION => "controller_touchpad_motion",
92
+ ::SDL2::SDL_CONTROLLERTOUCHPADUP => "controller_touchpad_up",
93
+ ::SDL2::SDL_DISPLAYEVENT => "display_event",
94
+ ::SDL2::SDL_DOLLARGESTURE => "dollar_gesture",
95
+ ::SDL2::SDL_DOLLARRECORD => "dollar_record",
96
+ ::SDL2::SDL_DROPBEGIN => "drop_begin",
97
+ ::SDL2::SDL_DROPCOMPLETE => "drop_complete",
98
+ ::SDL2::SDL_DROPFILE => "drop_file",
99
+ ::SDL2::SDL_DROPTEXT => "drop_text",
100
+ ::SDL2::SDL_FINGERDOWN => "finger_down",
101
+ ::SDL2::SDL_FINGERUP => "finger_up",
102
+ ::SDL2::SDL_FINGERMOTION => "finger_motion",
103
+ ::SDL2::SDL_JOYAXISMOTION => "joy_axis_motion",
104
+ ::SDL2::SDL_JOYBALLMOTION => "joy_ball_motion",
105
+ ::SDL2::SDL_JOYBUTTONDOWN => "joy_button_down",
106
+ ::SDL2::SDL_JOYBUTTONUP => "joy_button_up",
107
+ ::SDL2::SDL_JOYDEVICEADDED => "joy_device_added",
108
+ ::SDL2::SDL_JOYDEVICEREMOVED => "joy_device_removed",
109
+ ::SDL2::SDL_JOYHATMOTION => "joy_hat_motion",
110
+ ::SDL2::SDL_KEYDOWN => "key_down",
111
+ ::SDL2::SDL_KEYUP => "key_up",
112
+ ::SDL2::SDL_KEYMAPCHANGED => "keymap_changed",
113
+ ::SDL2::SDL_LOCALECHANGED => "locale_changed",
114
+ ::SDL2::SDL_MULTIGESTURE => "multi_gesture",
115
+ ::SDL2::SDL_MOUSEBUTTONDOWN => "mouse_button_down",
116
+ ::SDL2::SDL_MOUSEBUTTONUP => "mouse_button_up",
117
+ ::SDL2::SDL_MOUSEMOTION => "mouse_motion",
118
+ ::SDL2::SDL_MOUSEWHEEL => "mouse_wheel",
119
+ ::SDL2::SDL_QUIT => "quit",
120
+ ::SDL2::SDL_RENDER_DEVICE_RESET => "render_device_reset",
121
+ ::SDL2::SDL_RENDER_TARGETS_RESET => "render_targets_reset",
122
+ ::SDL2::SDL_SENSORUPDATE => "sensor_update",
123
+ ::SDL2::SDL_SYSWMEVENT => "sys_wm_event",
124
+ ::SDL2::SDL_TEXTEDITING => "text_editing",
125
+ ::SDL2::SDL_TEXTINPUT => "text_input",
126
+ ::SDL2::SDL_WINDOWEVENT => "window_event",
127
+ )
128
+
129
+ @mutex = Mutex.new
130
+
131
+ class << self
132
+ def define_user_event(name = "user_event")
133
+ @mutex.synchronize do
134
+ num = ::SDL2::SDL_RegisterEvents(1)
135
+ if num == 0xFFFFFFFF
136
+ raise RbSDL2Error, "unable to register user events because too many requests"
137
+ end
138
+ @name_map[num] = name
139
+ num
140
+ end
141
+ end
142
+
143
+ def disable(type) = ::SDL2.SDL_EventState(type, ::SDL2::SDL_DISABLE) == ::SDL2::SDL_ENABLE
144
+
145
+ def enable(type) = ::SDL2.SDL_EventState(type, ::SDL2::SDL_ENABLE) == ::SDL2::SDL_DISABLE
146
+
147
+ def ignore?(type) = ::SDL2.SDL_EventState(type, ::SDL2::SDL_QUERY) == ::SDL2::SDL_IGNORE
148
+
149
+ def minmax = RANGE.minmax
150
+
151
+ def to_name(num) = @name_map[num]
152
+
153
+ def to_num(obj)
154
+ num = @name_map.key(obj.to_s)
155
+ raise ArgumentError unless num
156
+ num
157
+ end
158
+
159
+ def to_type(num) = MEMBER_MAP[num]
160
+ end
161
+
162
+ def app_did_enter_background? = ::SDL2::SDL_APP_DIDENTERBACKGROUND == type
163
+
164
+ def app_did_enter_foreground? = ::SDL2::SDL_APP_DIDENTERFOREGROUND == type
165
+
166
+ def app_low_memory? = ::SDL2::SDL_APP_LOWMEMORY == type
167
+
168
+ def app_terminating? = ::SDL2::SDL_APP_TERMINATING == type
169
+
170
+ def app_will_enter_background? = ::SDL2::SDL_APP_WILLENTERBACKGROUND == type
171
+
172
+ def app_will_enter_foreground? = ::SDL2::SDL_APP_WILLENTERFOREGROUND == type
173
+
174
+ def audio_device_added? = ::SDL2::SDL_AUDIODEVICEADDED == type
175
+
176
+ def audio_device_removed? = ::SDL2::SDL_AUDIODEVICEREMOVED == type
177
+
178
+ def clipboard_update? = ::SDL2::SDL_CLIPBOARDUPDATE == type
179
+
180
+ def controller_axis_motion? = ::SDL2::SDL_CONTROLLERAXISMOTION == type
181
+
182
+ def controller_button_down? = ::SDL2::SDL_CONTROLLERBUTTONDOWN == type
183
+
184
+ def controller_button_up? = ::SDL2::SDL_CONTROLLERBUTTONUP == type
185
+
186
+ def controller_device_added? = ::SDL2::SDL_CONTROLLERDEVICEADDED == type
187
+
188
+ def controller_device_remapped? = ::SDL2::SDL_CONTROLLERDEVICEREMAPPED == type
189
+
190
+ def controller_device_removed? = ::SDL2::SDL_CONTROLLERDEVICEREMOVED == type
191
+
192
+ def controller_sensor_update? = ::SDL2::SDL_CONTROLLERSENSORUPDATE == type
193
+
194
+ def controller_touchpad_down? = ::SDL2::SDL_CONTROLLERTOUCHPADDOWN == type
195
+
196
+ def controller_touchpad_motion? = ::SDL2::SDL_CONTROLLERTOUCHPADMOTION == type
197
+
198
+ def controller_touchpad_up? = ::SDL2::SDL_CONTROLLERTOUCHPADUP == type
199
+
200
+ def display_event? = ::SDL2::SDL_DISPLAYEVENT == type
201
+
202
+ def dollar_gesture? = ::SDL2::SDL_DOLLARGESTURE == type
203
+
204
+ def dollar_record? = ::SDL2::SDL_DOLLARRECORD == type
205
+
206
+ def drop_begin? = ::SDL2::SDL_DROPBEGIN == type
207
+
208
+ def drop_complete? = ::SDL2::SDL_DROPCOMPLETE == type
209
+
210
+ def drop_file? = ::SDL2::SDL_DROPFILE == type
211
+
212
+ def drop_text? = ::SDL2::SDL_DROPTEXT == type
213
+
214
+ def finger_down? = ::SDL2::SDL_FINGERDOWN == type
215
+
216
+ def finger_up? = ::SDL2::SDL_FINGERUP == type
217
+
218
+ def finger_motion? = ::SDL2::SDL_FINGERMOTION == type
219
+
220
+ def joy_axis_motion? = ::SDL2::SDL_JOYAXISMOTION == type
221
+
222
+ def joy_ball_motion? = ::SDL2::SDL_JOYBALLMOTION == type
223
+
224
+ def joy_button_down? = ::SDL2::SDL_JOYBUTTONDOWN == type
225
+
226
+ def joy_button_up? = ::SDL2::SDL_JOYBUTTONUP == type
227
+
228
+ def joy_device_added? = ::SDL2::SDL_JOYDEVICEADDED == type
229
+
230
+ def joy_device_removed? = ::SDL2::SDL_JOYDEVICEREMOVED == type
231
+
232
+ def joy_hat_motion? = ::SDL2::SDL_JOYHATMOTION == type
233
+
234
+ def key_down? = ::SDL2::SDL_KEYDOWN == type
235
+
236
+ def key_up? = ::SDL2::SDL_KEYUP == type
237
+
238
+ def keymap_changed? = ::SDL2::SDL_KEYMAPCHANGED == type
239
+
240
+ def locale_changed? = ::SDL2::SDL_LOCALECHANGED == type
241
+
242
+ def multi_gesture? = ::SDL2::SDL_MULTIGESTURE == type
243
+
244
+ def mouse_button_down? = ::SDL2::SDL_MOUSEBUTTONDOWN == type
245
+
246
+ def mouse_button_up? = ::SDL2::SDL_MOUSEBUTTONUP == type
247
+
248
+ def mouse_motion? = ::SDL2::SDL_MOUSEMOTION == type
249
+
250
+ def mouse_wheel? = ::SDL2::SDL_MOUSEWHEEL == type
251
+
252
+ def quit? = ::SDL2::SDL_QUIT == type
253
+
254
+ def render_device_reset? = ::SDL2::SDL_RENDER_DEVICE_RESET == type
255
+
256
+ def render_targets_reset? = ::SDL2::SDL_RENDER_TARGETS_RESET == type
257
+
258
+ def sensor_update? = ::SDL2::SDL_SENSORUPDATE == type
259
+
260
+ def sys_wm_event? = ::SDL2::SDL_SYSWMEVENT == type
261
+
262
+ def text_editing? = ::SDL2::SDL_TEXTEDITING == type
263
+
264
+ def text_input? = ::SDL2::SDL_TEXTINPUT == type
265
+
266
+ def user_event? = USER_EVENT_TYPES === type
267
+
268
+ def window_event? = ::SDL2::SDL_WINDOWEVENT == type
269
+ end
270
+ end
271
+ end