=begin
	Ruby X11 Client Library
	Copyright 2001 by Mathieu Bouchard

	X11/Event.rb: Event and Error classes

	$Id: Event.rb,v 1.33 2001/07/02 22:40:43 matju Exp $

	This library is free software; you can redistribute it and/or
	modify it under the terms of the GNU Lesser General Public
	License as published by the Free Software Foundation; either
	version 2 of the License, or (at your option) any later version.

	This library is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
	Lesser General Public License for more details.

	You should have received a copy of the GNU Lesser General Public
	License along with this library; if not, write to the Free Software
	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

=end

require "X11/Base"

module X11
#--------------------------------#

class KBPREvent < Event; fields_are \
	[:key, Uint8, :in_header], # key or button
	[:time, TimeStamp],
	[:root,  Window],
	[:event, Window],
	[:child, Any.of Window,None],
	[:root_point, Point],
	[:event_point, Point],
	[:state, KeyButMask],
	[:same_screen, Bool]

#	alias button key
	def button; key; end
end

class KeyPressEvent      < KBPREvent; code_is 2; fields_are *superclass.fields; end
class KeyReleaseEvent    < KBPREvent; code_is 3; fields_are *superclass.fields; end
class ButtonPressEvent   < KBPREvent; code_is 4; fields_are *superclass.fields; end
class ButtonReleaseEvent < KBPREvent; code_is 5; fields_are *superclass.fields; end

class MotionNotifyEvent < Event
	code_is 6
	fields_are \
	[:detail, MotionNotifyDetail, :in_header],
	[:time, TimeStamp],
	[:root,  Window],
	[:event, Window],
	[:child, Any.of Window,None],
	[:root_point,  Point],
	[:event_point, Point],
	[:state, KeyButMask],
	[:same_screen, Bool]
end

class ELNotifyEvent < Event
	fields_are \
	[:detail, CrossingNotifyDetail, :in_header],
	[:time, TimeStamp],
	[:root,  Window],
	[:event, Window],
	[:child, Any.of Window,None],
	[:root_point,  Point],
	[:event_point, Point],
	[:state, KeyButMask],
	[:mode, CrossingNotifyMode],
	[:same_screen_and_focus, Uint8]

	def focus      ; same_screen_and_focus[0]; end
	def same_screen; same_screen_and_focus[1]; end
end

class EnterNotifyEvent < ELNotifyEvent; code_is 7; fields_are *superclass.fields; end
class LeaveNotifyEvent < ELNotifyEvent; code_is 8; fields_are *superclass.fields; end

class FIOEvent < Event
	fields_are \
	[:detail,FocusDetail,:in_header],
	[:event, Window],
	[:mode, FocusMode]
end

class FocusInEvent  < FIOEvent; code_is 9 ; fields_are *superclass.fields; end
class FocusOutEvent < FIOEvent; code_is 10; fields_are *superclass.fields; end

class KeymapNotifyEvent < Event
	code_is 11
# !@#$
# weird: 31 bytes
#	fields_are []
end

class ExposeEvent < Event
	code_is 12
	fields_are \
	[:window, Window],
	[:rectangle, Rectangle],
	[:count, Uint16]
end

class GraphicsExposureEvent < Event
	code_is 13
	fields_are \
	[:drawable, Drawable],
	[:rectangle, Rectangle],
	[:minor_opcode, Uint16],
	[:count, Uint16],
	[:major_opcode, Uint8]
end

class NoExposureEvent < Event
	code_is 14
	fields_are \
	[:drawable, Drawable],
	[:minor_opcode, Uint16],
	[:major_opcode, Uint8]
end

class VisibilityNotifyEvent < Event
	code_is 15
	fields_are \
	[:window, Window],
	[:state, VisibilityState]
end

class CreateNotifyEvent < Event
	code_is 16
	fields_are \
	[:parent, Window],
	[:window, Window],
	[:rectangle, Rectangle],
	[:border_width, Uint16],
	[:override_redirect, Bool]
end

class DestroyNotifyEvent < Event
	code_is 17
	fields_are \
	[:event,  Window],
	[:window, Window]
end

class UnmapNotifyEvent < Event
	code_is 18
	fields_are \
	[:event,  Window],
	[:window, Window],
	[:from_configure, Bool]
end

class MapNotifyEvent < Event
	code_is 19
	fields_are \
	[:event,  Window],
	[:window, Window],
	[:override_redirect, Bool]
end

class MapRequestEvent < Event
	code_is 20
	fields_are \
	[:parent, Window],
	[:window, Window]
end

class ReparentNotifyEvent < Event
	code_is 21
	fields_are \
	[:event,  Window],
	[:window, Window],
	[:parent, Window],
	[:point, Point],
	[:override_redirect, Bool]
end

class ConfigureNotifyEvent < Event
	code_is 22
	fields_are \
	[:event,  Window],
	[:window, Window],
	[:above_sibling, Any.of Window,None],
	[:rectangle, Rectangle],
	[:border_width, Uint16],
	[:override_redirect, Bool]
end

class ConfigureRequestEvent < Event
	code_is 23
	fields_are \
	[:stack_mode, StackMode, :in_header],
	[:parent, Window],
	[:window, Window],
	[:sibling, Any.of Window,None],
	[:rectangle, Rectangle],
	[:border_width, Uint16],
	[:value_mask, Uint16]
end

class GravityNotifyEvent < Event
	code_is 24
	fields_are \
	[:event,  Window],
	[:window, Window],
	[:point, Point]
end

class ResizeRequestEvent < Event
	code_is 25
	fields_are \
	[:window, Window],
	[:size,   Size]
end

class CirculateNREvent < Event
	fields_are \
	[:event,  Window],
	[:window, Window],
	[:place, CirculatePlace]
end

class CirculateNotifyEvent  < CirculateNREvent; code_is 26; fields_are *superclass.fields; end
class CirculateRequestEvent < CirculateNREvent; code_is 27; fields_are *superclass.fields; end

class PropertyNotifyEvent < Event
	code_is 28
	fields_are \
	[:window, Window],
	[:atom, Atom],
	[:time, TimeStamp],
	[:state, PropertyNotifyState]
end

class SelectionClearEvent < Event
	code_is 29
	fields_are \
	[:time, TimeStamp],
	[:owner, Window],
	[:selection, Atom]
end

class SelectionRequestEvent < Event
	code_is 30
	fields_are \
	[:time, Any.of TimeStamp,CurrentTime],
	[:owner, Window],
	[:requestor, Window],
	[:selection, Atom],
	[:target, Atom],
	[:property, Any.of Atom,None]
end

class SelectionNotifyEvent < Event
	code_is 31
	fields_are \
	[:time, TimeStamp],
	[:requestor, Window],
	[:selection, Atom],
	[:target, Atom],
	[:property, Any.of Atom,None]
end

class ColormapNotifyEvent < Event
	code_is 32
	fields_are \
	[:window, Window],
	[:colormap, Any.of Colormap,None],
	[:new, Bool],
	[:state, ColormapNotifyState]
end

class ClientMessageEvent < Event
	code_is 33
	fields_are \
	[:format, Uint8, :in_header],
	[:window, Window],
	[:tipe, Atom],
	[:data0, Uint32],
	[:data1, Uint32],
	[:data2, Uint32],
	[:data3, Uint32],
	[:data4, Uint32]
end

class MappingNotifyEvent < Event
	code_is 34
	fields_are \
	[:request, MappingNotifyRequest],
	[:first_keycode, Uint8],
	[:count, Uint8]
end

#--------------------------------#

xbad = [:bad_xid, XID]
ErrorMap = [
	nil,
	[  :RequestError, nil],
	[    :ValueError, :bad_value],
	[   :WindowError, xbad],
	[   :PixmapError, xbad],
	[     :AtomError, xbad],
	[   :CursorError, xbad],
	[     :FontError, xbad],
	[    :MatchError, nil],
	[ :DrawableError, xbad],
	[   :AccessError, xbad],
	[    :AllocError, xbad],
	[ :ColormapError, xbad],
	[ :GContextError, xbad],
	[ :IDChoiceError, xbad],
	[   :LengthError, nil],
	[ :ImplementationError, nil]]

class XError
	attr_accessor :error_code

	def initialize(code)
		@error_code,@sequence,@stuff1,@minor,@major = code.unpack("xCSLSC")
		if not ErrorMap[@error_code] then
			raise "Unknown Error Code: #{error_code}"
		end
	end

	def to_s
		name, = ErrorMap[error_code]
		"\#<%s min=%d maj=%d arg=0x%08x seq=%04x %s>" %
		[type,@minor,@major,@stuff1,@sequence,name]; end
	def inspect; to_s; end
end

#--------------------------------#
end # of module X11
