pure-x11 0.0.9 → 0.0.12
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/CLAUDE.md +47 -0
- data/Gemfile.lock +1 -1
- data/README.md +10 -0
- data/example/query_pointer.rb +40 -0
- data/example/query_pointer_simple.rb +25 -0
- data/lib/X11/display.rb +12 -0
- data/lib/X11/form.rb +51 -16
- data/lib/X11/version.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a54ae04997fddd16eaeea021a1b8141649b94c01fc4da4172395432fb119b768
|
4
|
+
data.tar.gz: 67a426e9ecd3befd4e4d33c74a63a2504b1aff720c6a871cdf69c9900637b7eb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4c71571ad6cb34be6d9aa6d60871bba90efcc29931829035c93a11f7de9fa45741e4851179b03bf00ba2eff7aad26f2362c1323f35bf2f3f34eb2f787ca0a3f4
|
7
|
+
data.tar.gz: 3b727bf9aa3be18791b50178a64766626655ce8c48f743333e142fe3b2cece7c4ecbb65a78e77dd54ea7c5ebb11959493ffcd1e265d247acc34e63a423ede4c8
|
data/CLAUDE.md
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
# Ruby X11 Development Guidelines
|
2
|
+
|
3
|
+
## Build Commands
|
4
|
+
- Install dependencies: `bundle install`
|
5
|
+
- Run all tests: `rake test`
|
6
|
+
- Run single test: `ruby test/specific_test.rb`
|
7
|
+
|
8
|
+
## Code Style
|
9
|
+
- Indentation: 2 spaces
|
10
|
+
- Naming: snake_case for methods/variables, CamelCase for classes
|
11
|
+
- Constants: ALL_CAPS or CamelCase (matching X11 protocol names)
|
12
|
+
- Methods: One-line with `=` for simple methods (Ruby 3 syntax)
|
13
|
+
- Error handling: Custom X11 error hierarchy (X11::BasicError, etc.)
|
14
|
+
- Imports: require_relative for internal files, require for gems
|
15
|
+
|
16
|
+
## Organization
|
17
|
+
- Core functionality in lib/X11.rb
|
18
|
+
- Components in lib/X11/ directory
|
19
|
+
- Protocol definitions using DSL in form.rb
|
20
|
+
- Test files in test/ directory with _test.rb suffix
|
21
|
+
|
22
|
+
## Testing
|
23
|
+
- Uses Minitest::Spec syntax: `_(object).must_equal expected`
|
24
|
+
- Tests require helper.rb which sets up the environment
|
25
|
+
- Mock objects for testing sockets/connections
|
26
|
+
|
27
|
+
## Documentation
|
28
|
+
- Comments for complex logic
|
29
|
+
- Reference X11 protocol documentation when implementing specs
|
30
|
+
|
31
|
+
## Adding X11 Protocol Requests
|
32
|
+
1. Define request form in lib/X11/form.rb:
|
33
|
+
```ruby
|
34
|
+
class XRenderFreePicture < BaseForm
|
35
|
+
field :req_type, Uint8
|
36
|
+
field :render_req_type, Uint8, value: 7
|
37
|
+
field :request_length, Uint16, value: 2
|
38
|
+
field :picture, Uint32
|
39
|
+
end
|
40
|
+
```
|
41
|
+
2. Add helper method in lib/X11/display.rb:
|
42
|
+
```ruby
|
43
|
+
def render_free_picture(picture)
|
44
|
+
write_request(Form::XRenderFreePicture.new(render_opcode, picture))
|
45
|
+
end
|
46
|
+
```
|
47
|
+
3. Update X11::VERSION in lib/X11/version.rb after adding new functionality
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -9,6 +9,16 @@ upstread everything.
|
|
9
9
|
This library is based off of Mathieu Bouchard's work on his RubyX11 project,
|
10
10
|
and Richard Ramsdens excellent start on Ruby-X11.
|
11
11
|
|
12
|
+
Current known use (all mine...):
|
13
|
+
|
14
|
+
* [RubyWM](https://github.com/vidarh/rubywm) - Pure Ruby window manager
|
15
|
+
* [Skrift-X11](https://github.com/vidarh/skrift-x11) - X11 integration for pure Ruby Truetype font rendering
|
16
|
+
* Rebar - not yet published wm toolbar
|
17
|
+
* RubyTerm (name TBD) - not yet published version of Ruby terminal
|
18
|
+
|
19
|
+
If you're thinking of using pure-x11, drop me a note and I'll start being more
|
20
|
+
cautious about breaking changes ;)
|
21
|
+
|
12
22
|
Contributors
|
13
23
|
------------
|
14
24
|
|
@@ -0,0 +1,40 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require_relative '../lib/X11'
|
3
|
+
|
4
|
+
display = X11::Display.new
|
5
|
+
root = display.screens.first.root
|
6
|
+
|
7
|
+
# Create a simple window
|
8
|
+
window = display.create_window(
|
9
|
+
100, 100, 400, 300,
|
10
|
+
depth: 24,
|
11
|
+
values: { X11::Form::CWBackPixel => 0xFFFFFF }
|
12
|
+
)
|
13
|
+
|
14
|
+
# Select input events (pointer motion)
|
15
|
+
display.select_input(window, X11::Form::PointerMotionMask)
|
16
|
+
|
17
|
+
# Map the window (make it visible)
|
18
|
+
display.map_window(window)
|
19
|
+
|
20
|
+
# Wait for window to be visible
|
21
|
+
sleep(0.5)
|
22
|
+
|
23
|
+
puts "Window created. Moving your mouse over the window will display coordinates."
|
24
|
+
puts "Press Ctrl+C to exit."
|
25
|
+
|
26
|
+
# Main event loop
|
27
|
+
display.run do |event|
|
28
|
+
case event
|
29
|
+
when X11::Form::MotionNotify
|
30
|
+
# Query pointer position relative to window
|
31
|
+
pointer = display.query_pointer(window)
|
32
|
+
puts "Pointer position:"
|
33
|
+
puts " Window: (#{pointer.win_x}, #{pointer.win_y})"
|
34
|
+
puts " Root: (#{pointer.root_x}, #{pointer.root_y})"
|
35
|
+
puts " Child: #{pointer.child == 0 ? 'None' : pointer.child}"
|
36
|
+
puts " Mask: #{pointer.mask.to_s(16)}"
|
37
|
+
puts " Same screen: #{pointer.same_screen}"
|
38
|
+
puts "--------------------"
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require_relative '../lib/X11'
|
3
|
+
|
4
|
+
# Create display connection
|
5
|
+
display = X11::Display.new
|
6
|
+
|
7
|
+
# Get root window of first screen
|
8
|
+
root = display.screens.first.root
|
9
|
+
|
10
|
+
puts "Move your mouse around and watch the coordinates update."
|
11
|
+
puts "Press Ctrl+C to exit."
|
12
|
+
|
13
|
+
# Loop and query pointer position every 0.1 seconds
|
14
|
+
loop do
|
15
|
+
pointer = display.query_pointer(root)
|
16
|
+
|
17
|
+
system("clear") # Clear terminal
|
18
|
+
puts "Pointer position relative to root window:"
|
19
|
+
puts " Root coordinates: (#{pointer.root_x}, #{pointer.root_y})"
|
20
|
+
puts " Window under pointer: #{pointer.child == 0 ? 'None' : pointer.child}"
|
21
|
+
puts " Button/modifier mask: #{pointer.mask.to_s(16)}"
|
22
|
+
puts " Same screen: #{pointer.same_screen}"
|
23
|
+
|
24
|
+
sleep(0.1)
|
25
|
+
end
|
data/lib/X11/display.rb
CHANGED
@@ -541,6 +541,10 @@ module X11
|
|
541
541
|
def create_pixmap(depth, drawable, w,h)
|
542
542
|
new_id.tap{|pid| write_request(Form::CreatePixmap.new(depth, pid, drawable, w,h)) }
|
543
543
|
end
|
544
|
+
|
545
|
+
def free_pixmap(pixmap)
|
546
|
+
write_request(Form::FreePixmap.new(pixmap))
|
547
|
+
end
|
544
548
|
|
545
549
|
# XRender
|
546
550
|
|
@@ -651,6 +655,14 @@ module X11
|
|
651
655
|
write_request(Form::XRenderCreateSolidFill.new(render_opcode,fill,color))
|
652
656
|
fill
|
653
657
|
end
|
658
|
+
|
659
|
+
def render_free_picture(picture)
|
660
|
+
write_request(Form::XRenderFreePicture.new(render_opcode, picture))
|
661
|
+
end
|
662
|
+
|
663
|
+
def query_pointer(window)
|
664
|
+
write_sync(Form::QueryPointer.new(window), Form::QueryPointerReply)
|
665
|
+
end
|
654
666
|
|
655
667
|
private
|
656
668
|
|
data/lib/X11/form.rb
CHANGED
@@ -215,6 +215,10 @@ module X11
|
|
215
215
|
## X11 Packet Defintions
|
216
216
|
##
|
217
217
|
|
218
|
+
class Reply < BaseForm
|
219
|
+
field :reply, Uint8
|
220
|
+
end
|
221
|
+
|
218
222
|
class ClientHandshake < BaseForm
|
219
223
|
field :byte_order, Uint8
|
220
224
|
unused 1
|
@@ -458,6 +462,27 @@ module X11
|
|
458
462
|
field :request_length, Uint16, value: 2
|
459
463
|
field :window, Window
|
460
464
|
end
|
465
|
+
|
466
|
+
class QueryPointer < BaseForm
|
467
|
+
field :opcode, Uint8, value: 38
|
468
|
+
unused 1
|
469
|
+
field :request_length, Uint16, value: 2
|
470
|
+
field :window, Window
|
471
|
+
end
|
472
|
+
|
473
|
+
class QueryPointerReply < Reply
|
474
|
+
field :same_screen, Bool
|
475
|
+
field :sequence_number, Uint16
|
476
|
+
field :reply_length, Uint32
|
477
|
+
field :root, Window
|
478
|
+
field :child, Window
|
479
|
+
field :root_x, Int16
|
480
|
+
field :root_y, Int16
|
481
|
+
field :win_x, Int16
|
482
|
+
field :win_y, Int16
|
483
|
+
field :mask, Uint16
|
484
|
+
unused 6
|
485
|
+
end
|
461
486
|
|
462
487
|
class ChangeSaveSet < BaseForm
|
463
488
|
field :opcode, Uint8, value: 6
|
@@ -553,10 +578,6 @@ module X11
|
|
553
578
|
field :name, String8, :string
|
554
579
|
end
|
555
580
|
|
556
|
-
class Reply < BaseForm
|
557
|
-
field :reply, Uint8
|
558
|
-
end
|
559
|
-
|
560
581
|
class InternAtomReply < Reply
|
561
582
|
unused 1
|
562
583
|
field :sequence_number, Uint16
|
@@ -694,6 +715,13 @@ module X11
|
|
694
715
|
field :width, Uint16
|
695
716
|
field :height, Uint16
|
696
717
|
end
|
718
|
+
|
719
|
+
class FreePixmap < BaseForm
|
720
|
+
field :opcode, Uint8, value: 54
|
721
|
+
unused 1
|
722
|
+
field :request_length, Uint16, value: 2
|
723
|
+
field :pixmap, Pixmap
|
724
|
+
end
|
697
725
|
|
698
726
|
class Str < BaseForm
|
699
727
|
field :name, Uint8, :length, value: ->(str) { str.name.length }
|
@@ -875,18 +903,18 @@ module X11
|
|
875
903
|
# FIXME: Events have quite a bit of redundancy, but unfortunately
|
876
904
|
# BaseForm can't handle subclassing well.
|
877
905
|
|
878
|
-
Shift
|
879
|
-
Lock
|
880
|
-
Control =
|
881
|
-
Mod1
|
882
|
-
Mod2
|
883
|
-
Mod3
|
884
|
-
Mod4
|
885
|
-
Mod5
|
886
|
-
Button1 =
|
887
|
-
Button2 =
|
888
|
-
Button3 =
|
889
|
-
Button4 =
|
906
|
+
Shift = 0x0001
|
907
|
+
Lock = 0x0002
|
908
|
+
Control = 0x0004
|
909
|
+
Mod1 = 0x0008
|
910
|
+
Mod2 = 0x0010
|
911
|
+
Mod3 = 0x0020
|
912
|
+
Mod4 = 0x0040
|
913
|
+
Mod5 = 0x0080
|
914
|
+
Button1 = 0x0100
|
915
|
+
Button2 = 0x0200
|
916
|
+
Button3 = 0x0400
|
917
|
+
Button4 = 0x0800
|
890
918
|
Button5 = 0x1000
|
891
919
|
|
892
920
|
class Event < BaseForm
|
@@ -1217,5 +1245,12 @@ module X11
|
|
1217
1245
|
field :fill, Uint32
|
1218
1246
|
field :color, XRenderColor
|
1219
1247
|
end
|
1248
|
+
|
1249
|
+
class XRenderFreePicture < BaseForm
|
1250
|
+
field :req_type, Uint8
|
1251
|
+
field :render_req_type, Uint8, value: 7
|
1252
|
+
field :request_length, Uint16, value: 2
|
1253
|
+
field :picture, Uint32
|
1254
|
+
end
|
1220
1255
|
end
|
1221
1256
|
end
|
data/lib/X11/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pure-x11
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.12
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Vidar Hokstad
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2025-04-05 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: Pure Ruby X11 bindings
|
15
15
|
email:
|
@@ -19,6 +19,7 @@ extensions: []
|
|
19
19
|
extra_rdoc_files: []
|
20
20
|
files:
|
21
21
|
- ".gitignore"
|
22
|
+
- CLAUDE.md
|
22
23
|
- Gemfile
|
23
24
|
- Gemfile.lock
|
24
25
|
- LICENSE.txt
|
@@ -27,6 +28,8 @@ files:
|
|
27
28
|
- docs/protocol.pdf
|
28
29
|
- example/client_message.rb
|
29
30
|
- example/genie.png
|
31
|
+
- example/query_pointer.rb
|
32
|
+
- example/query_pointer_simple.rb
|
30
33
|
- example/test.rb
|
31
34
|
- lib/X11.rb
|
32
35
|
- lib/X11/auth.rb
|