#!/usr/bin/ruby # encoding: UTF-8 # # xscreensaver sample by Ruby + ruby-gtk2 # # * Ubuntu Linux 20.04 LTS # * Ruby 2.7.0 p0 # * ruby-gtk2 3.4.1-2build1 # * xscreensaver 6.04 require "gtk2" require "logger" # for gtk2 SIGNAL_DRAW = "expose_event" # for gtk3 # SIGNAL_DRAW = "draw" TMOUT = 16 $drawing_area = nil $logger = Logger.new("/tmp/rubysaver-#{ENV["USER"]}.log", "monthly") class RubyXscrApp < Gtk::Window def initialize super set_title "xscreensaver module" signal_connect "destroy" do $logger.warn "EXIT by destroy" Gtk.main_quit end signal_connect "delete-event" do $logger.warn "EXIT by delete-event" Gtk.main_quit false end signal_connect "delete_event" do $logger.warn "EXIT by delete_event" Gtk.main_quit false end realize ident = ENV["XSCREENSAVER_WINDOW"] if not ident.nil? $logger.warn "XSCREENSAVER_WINDOW = #{ident}" self.window = Gdk::Window.foreign_new(ident.to_i(16)) self.window.set_events(Gdk::Event::EXPOSURE_MASK | Gdk::Event::STRUCTURE_MASK) x, y, width, height, depth = self.window.geometry # puts "window = #{self.window}, (x,y,w,h) = #{x}, #{y}, #{width}, #{height}" $logger.warn "window = #{self.window}, (x,y,w,h) = #{x}, #{y}, #{width}, #{height}" set_default_size width, height move(x, y) # set_window_position :center else x, y, width, height, depth = self.window.geometry width, height = 640, 360 set_default_size width, height set_window_position :center puts "window = #{self.window}, (w,h) = #{width}, #{height}" end @x = width / 2 @y = height / 2 @dx = width.to_f / (60 * 1) @dy = height.to_f / (60 * 1.5) $drawing_area = @darea = Gtk::DrawingArea.new @bgcol = Gdk::Color.new(0x2000, 0x4000, 0xa000) @darea.modify_bg(:normal, @bgcol) @darea.set_size_request(width, height) @darea.signal_connect SIGNAL_DRAW do |widget, event| on_draw widget end @fixed = Gtk::Fixed.new @fixed.put(@darea, 0, 0) add(@fixed) show_all end def on_draw(widget) cr = widget.window.create_cairo_context x, y, width, height, depth = widget.window.geometry # update position r = 24 @x += @dx @y += @dy @dx *= -1 if (@x <= r or @x >= width - r) @dy *= -1 if (@y <= r or @y >= height - r) # clear bg cr.set_source_rgb(0.1, 0.3, 0.5) cr.paint # draw circle cr.set_source_rgb(1.0, 0.0, 0.0) cr.arc(@x, @y, r, 0, 2 * Math::PI) cr.fill cr.destroy end end Gtk.init window = RubyXscrApp.new # animation GLib::Timeout.add(TMOUT) do $drawing_area.queue_draw if (not $drawing_area.nil?) true end Gtk.main