3
# examples/draw.py -- protocol test application.
5
# Copyright (C) 2000 Peter Liljenberg <petli@ctrl-c.liu.se>
7
# This program is free software; you can redistribute it and/or modify
8
# it under the terms of the GNU General Public License as published by
9
# the Free Software Foundation; either version 2 of the License, or
10
# (at your option) any later version.
12
# This program is distributed in the hope that it will be useful,
13
# but WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU General Public License for more details.
17
# You should have received a copy of the GNU General Public License
18
# along with this program; if not, write to the Free Software
19
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25
# Change path so we find Xlib
26
sys.path.insert(1, os.path.join(sys.path[0], '..'))
29
from Xlib.protocol import display
30
from Xlib.protocol.request import *
32
# Application window (only one)
34
def __init__(self, display):
38
# Find which screen to open the window on
39
self.screen = self.d.info.roots[self.d.default_screen]
41
# Allocate ids to the window and gc
42
self.window = self.d.allocate_resource_id()
43
self.gc = self.d.allocate_resource_id()
46
CreateWindow(self.d, None,
47
self.screen.root_depth,
54
# special attribute values
55
background_pixel = self.screen.white_pixel,
56
event_mask = (X.ExposureMask |
57
X.StructureNotifyMask |
61
colormap = X.CopyFromParent)
63
# Create a gc for drawing
64
CreateGC(self.d, None,
68
# special attribute values
69
foreground = self.screen.black_pixel,
70
background = self.screen.white_pixel)
72
# Map the window, making it visible
73
MapWindow(self.d, None, self.window)
75
# Main loop, handling events
80
e = self.d.next_event()
82
# Window has been destroyed, quit
83
if e.type == X.DestroyNotify:
86
# Some part of the window has been exposed,
87
# redraw all the objects.
88
if e.type == X.Expose:
89
for o in self.objects:
92
# Left button pressed, start to draw
93
if e.type == X.ButtonPress and e.detail == 1:
94
current = Movement(self, e)
95
self.objects.append(current)
97
# Left button released, finish drawing
98
if e.type == X.ButtonRelease and e.detail == 1 and current:
102
# Mouse movement with button pressed, draw
103
if e.type == X.MotionNotify and current:
106
# A drawed objects, consisting of either a single
107
# romboid, or two romboids connected by a winding line
110
def __init__(self, win, ev):
113
self.left = ev.event_x - 5
114
self.right = ev.event_x + 5
115
self.top = ev.event_y - 5
116
self.bottom = ev.event_y + 5
119
self.lines = [(ev.event_x, ev.event_y)]
121
self.first = Romboid(self.win, ev)
124
def motion(self, ev):
125
# Find all the mouse coordinates since the
126
# last event received
128
r = GetMotionEvents(self.win.d,
129
window = self.win.window,
133
# Record the previous last coordinate, and append
134
# the new coordinates
136
firstline = len(self.lines) - 1
139
# Discard the first coordinate if that is identical to
140
# the last recorded coordinate
143
if (pos.x, pos.y) == self.lines[-1]:
144
events = r.events[1:]
148
# Append all coordinates
163
self.lines.append((x, y))
165
# Append the event coordinate, if that is different from the
166
# last movement coordinate
167
if (ev.event_x, ev.event_y) != self.lines[-1]:
168
self.lines.append((ev.event_x, ev.event_y))
170
# Draw a line between the new coordinates
171
PolyLine(self.win.d, None,
175
self.lines[firstline:])
179
def finish(self, ev):
181
if len(self.lines) > 1:
182
self.last = Romboid(self.win, ev)
184
self.left = min(ev.event_x - 5, self.left)
185
self.right = max(ev.event_x + 5, self.right)
186
self.top = min(ev.event_y - 5, self.top)
187
self.bottom = max(ev.event_y + 5, self.bottom)
189
def expose(self, ev):
190
# We should check if this object is in the exposed
191
# area, but I can't be bothered right now, so just
192
# redraw on the last Expose in every batch
197
# Redraw all the lines
198
PolyLine(self.win.d, None,
206
# A romboid, drawed around the Movement endpoints
208
def __init__(self, win, ev):
215
# Draw the segments of the romboid
216
PolyLine(self.win.d, None,
220
[(self.x, self.y - 5),
227
if __name__ == '__main__':
228
Window(display.Display()).loop()