[PATCH] fix OLPC #296

Gonzalo Odiard godiard at gmail.com
Sun May 30 23:56:59 EDT 2010


---
 Area.py    |   29 +++++++++++++++++++++-
 Desenho.py |   78
++++++++++++++++++++++++-----------------------------------
 2 files changed, 60 insertions(+), 47 deletions(-)

diff --git a/Area.py b/Area.py
index 44edebb..e81fcdc 100644
--- a/Area.py
+++ b/Area.py
@@ -176,6 +176,11 @@ class Area(gtk.DrawingArea):
         ##Shapes will be filled or not?
         self.fill = True

+        # variables to show the tool shape
+        self.drawing = False
+        self.x_cursor = 0
+        self.y_cursor = 0
+

     def setup(self, width, height):
         """Configure the Area object."""
@@ -256,8 +261,22 @@ class Area(gtk.DrawingArea):

widget.window.draw_drawable(self.gc,self.pixmap_temp,area[0],area[1],area[0],area[1],area[2],area[3])
         else:

widget.window.draw_drawable(self.gc,self.pixmap,area[0],area[1],area[0],area[1],area[2],area[3])
+            self.show_tool_shape(widget)
         return False

+    def show_tool_shape(self,widget):
+        """
+        Show the shape of the tool selected for pencil, brush, rainbow and
eraser
+        """
+        if self.tool['name'] in ['pencil','eraser','brush','rainbow']:
+            if not self.drawing:
+                size = self.tool['line size']
+                if self.tool['line shape'] == 'circle':
+                    widget.window.draw_arc(self.gc_brush, False,
self.x_cursor - size/2, self.y_cursor - size/2, size, size, 0, 360*64)
+                else:
+                    widget.window.draw_rectangle(self.gc_brush, False,
self.x_cursor - size/2, self.y_cursor - size/2, size, size)
+
+
     def mousedown(self,widget,event):
         """Make the Area object (GtkDrawingArea) recognize that the mouse
button has been pressed.

@@ -304,14 +323,17 @@ class Area(gtk.DrawingArea):
                 self.last = []
                 self.d.eraser(widget, coords, self.last, self.line_size,
self.tool['line shape'])
                 self.last = coords
+                self.drawing = True
             elif self.tool['name'] == 'brush':
                 self.last = []
                 self.d.brush(widget, coords, self.last, self.line_size,
self.tool['line shape'])
                 self.last = coords
+                self.drawing = True
             elif self.tool['name'] == 'rainbow':
                 self.last = []
                 self.d.rainbow(widget, coords, self.last,
self.rainbow_counter,self.line_size, self.tool['line shape'])
                 self.last = coords
+                self.drawing = True
             elif self.tool['name'] == 'polygon':
                 self.configure_line(self.line_size)
                 if self.polygon_start == False:
@@ -347,6 +369,8 @@ class Area(gtk.DrawingArea):
         y = event.y
         state = event.state

+        self.x_cursor,self.y_cursor = int(x), int(y)
+
         coords = int(x), int(y)

         if state & gtk.gdk.BUTTON1_MASK and self.pixmap != None:
@@ -419,6 +443,8 @@ class Area(gtk.DrawingArea):
                     self.configure_line(self.line_size)
                     self.d.heart(widget,coords,True,self.tool['fill'])
         else:
+            if self.tool['name'] in ['brush','eraser','rainbow','pencil'] :
+                widget.queue_draw()
             if self.tool['name'] == 'marquee-rectangular' and self.selmove:
                 size = self.pixmap_sel.get_size()
                 xi = self.orig_x
@@ -520,10 +546,11 @@ class Area(gtk.DrawingArea):
                 self.d.heart(widget,coords,False,self.tool['fill'])
                 self.enableUndo(widget)

-        if self.tool['name'] == 'brush' or self.tool['name'] == 'eraser' or
self.tool['name'] == 'rainbow' or self.tool['name'] == 'pencil' :
+        if self.tool['name'] in ['brush','eraser','rainbow','pencil'] :
             self.last = []
             widget.queue_draw()
             self.enableUndo(widget)
+            self.drawing = False
         self.desenha = False

     def undo(self):
diff --git a/Desenho.py b/Desenho.py
index e5ecf48..c9a134b 100644
--- a/Desenho.py
+++ b/Desenho.py
@@ -110,20 +110,8 @@ class Desenho:

         """
         widget.desenha = False
-        if(shape == 'circle'):
-            widget.pixmap.draw_arc(widget.gc_eraser, True, coords[0],
coords[1], size, size, 0, 360*64)
-            if last:
-                widget.gc_eraser.set_line_attributes(size,
gtk.gdk.LINE_SOLID, gtk.gdk.CAP_ROUND, gtk.gdk.JOIN_ROUND)
-
widget.pixmap.draw_line(widget.gc_eraser,last[0]+size/2,last[1]+size/2,coords[0]+size/2,coords[1]+size/2)
-                widget.gc_eraser.set_line_attributes(0, gtk.gdk.LINE_SOLID,
gtk.gdk.CAP_ROUND, gtk.gdk.JOIN_ROUND)
-        if(shape == 'square'):
-            widget.pixmap.draw_rectangle(widget.gc_eraser, True, coords[0],
coords[1], size, size)
-            if last:
-                points = [coords, last, (last[0]+size,last[1]+size),
(coords[0]+size,coords[1]+size)]
-                widget.pixmap.draw_polygon(widget.gc_eraser,True,points)
-                points = [(last[0]+size,last[1]),
(coords[0]+size,coords[1]), (coords[0],coords[1]+size),
(last[0],last[1]+size)]
-                widget.pixmap.draw_polygon(widget.gc_eraser,True,points)
-        widget.queue_draw()
+        self._trace(widget,widget.gc_eraser, coords, last, size, shape)
+        #widget.queue_draw()

     def brush(self, widget, coords, last, size = 5, shape = 'circle'):
         """Paint with brush.
@@ -137,28 +125,9 @@ class Desenho:

         """
         widget.desenha = False
-        if(shape == 'circle'):
-            widget.pixmap.draw_arc(widget.gc_brush, True, coords[0],
coords[1], size, size, 0, 360*64)
-            if last:
-                widget.gc_brush.set_line_attributes(size,
gtk.gdk.LINE_SOLID, gtk.gdk.CAP_ROUND, gtk.gdk.JOIN_ROUND)
-
widget.pixmap.draw_line(widget.gc_brush,last[0]+size/2,last[1]+size/2,coords[0]+size/2,coords[1]+size/2)
-                widget.gc_brush.set_line_attributes(0, gtk.gdk.LINE_SOLID,
gtk.gdk.CAP_ROUND, gtk.gdk.JOIN_ROUND)
-        if(shape == 'square'):
-            widget.pixmap.draw_rectangle(widget.gc_brush, True, coords[0],
coords[1], size, size)
-            if last:
-                points = [coords, last, (last[0]+size,last[1]+size),
(coords[0]+size,coords[1]+size)]
-                widget.pixmap.draw_polygon(widget.gc_brush,True,points)
-                points = [(last[0]+size,last[1]),
(coords[0]+size,coords[1]), (coords[0],coords[1]+size),
(last[0],last[1]+size)]
-                widget.pixmap.draw_polygon(widget.gc_brush,True,points)
+        self._trace(widget,widget.gc_brush, coords, last, size, shape)
+

-        if last:
-            x = min(coords[0], last[0])
-            width = max(coords[0], last[0]) - x
-            y = min(coords[1], last[1])
-            height = max(coords[1], last[1]) - y
-            widget.queue_draw_area(x, y, width+size, height+size) # We add
size to avoid drawing dotted lines
-        else:
-            widget.queue_draw()

     def rainbow(self, widget, coords, last, color, size = 5, shape =
'circle'):
         """Paint with rainbow.
@@ -190,23 +159,40 @@ class Desenho:

         widget.gc_rainbow.set_foreground(rainbow_colors[color])
         widget.desenha = False
+        self._trace(widget,widget.gc_rainbow, coords, last, size, shape)
+
+
+    def _trace(self, widget,gc, coords, last, size, shape):
         if(shape == 'circle'):
-            widget.pixmap.draw_arc(widget.gc_rainbow, True, coords[0],
coords[1], size, size, 0, 360*64)
+            widget.pixmap.draw_arc(gc, True, coords[0] - size/2, coords[1]
- size/2, size, size, 0, 360*64)
             if last:
-                widget.gc_rainbow.set_line_attributes(size,
gtk.gdk.LINE_SOLID, gtk.gdk.CAP_ROUND, gtk.gdk.JOIN_ROUND)
-
widget.pixmap.draw_line(widget.gc_rainbow,last[0]+size/2,last[1]+size/2,coords[0]+size/2,coords[1]+size/2)
-                widget.gc_rainbow.set_line_attributes(0,
gtk.gdk.LINE_SOLID, gtk.gdk.CAP_ROUND, gtk.gdk.JOIN_ROUND)
+                gc.set_line_attributes(size, gtk.gdk.LINE_SOLID,
gtk.gdk.CAP_ROUND, gtk.gdk.JOIN_ROUND)
+                widget.pixmap.draw_line(gc, last[0], last[1], coords[0],
coords[1])
+                gc.set_line_attributes(0, gtk.gdk.LINE_SOLID,
gtk.gdk.CAP_ROUND, gtk.gdk.JOIN_ROUND)
         if(shape == 'square'):
+            widget.pixmap.draw_rectangle(gc, True, coords[0] - size/2,
coords[1] - size/2, size, size)
             if last:
-                widget.pixmap.draw_rectangle(widget.gc_rainbow, True,
last[0], last[1], size, size)
-                points = [coords, last, (last[0]+size,last[1]+size),
(coords[0]+size,coords[1]+size)]
-                widget.pixmap.draw_polygon(widget.gc_rainbow,True,points)
-                points = [(last[0]+size,last[1]),
(coords[0]+size,coords[1]), (coords[0],coords[1]+size),
(last[0],last[1]+size)]
-                widget.pixmap.draw_polygon(widget.gc_rainbow,True,points)
-            widget.pixmap.draw_rectangle(widget.gc_rainbow, True,
coords[0], coords[1], size, size)
-        widget.queue_draw()
+                points = [(last[0] - size/2,last[1] - size/2), (coords[0] -
size/2, coords[1] - size/2),
+                            (coords[0] + size/2, coords[1] + size/2) ,
(last[0] + size/2,last[1] + size/2)]
+                widget.pixmap.draw_polygon(gc,True,points)
+                points = [(last[0] + size/2,last[1] - size/2), (coords[0] +
size/2, coords[1] - size/2),
+                            (coords[0] - size/2, coords[1] + size/2) ,
(last[0] - size/2,last[1] + size/2)]
+                widget.pixmap.draw_polygon(gc,True,points)
+
+
+        if last:
+            x = min(coords[0], last[0])
+            width = max(coords[0], last[0]) - x
+            y = min(coords[1], last[1])
+            height = max(coords[1] , last[1]) - y
+            widget.queue_draw_area(x-size, y-size, width+size*2,
height+size*2) # We add size to avoid drawing dotted lines
+        else:
+            widget.queue_draw()
+


+
+
     def square(self, widget, event, coords, temp, fill):
         """Draw a square.

-- 
1.6.6.1

--000e0cd3b23c2be9890487dbff4f
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

This patch change:<br>* Show the shape and the size with the pencil, brush,=
 eraser and rainbow.<br>* Center this tools at the cursor coordinates<br>I =
think it&#39;s more usable than before.<br>My idea is enable the change of =
the size of the selected tool from the unused keys whith the circles in the=
 XO.<br>
<br>There are other bugs related like OLPC #8864 and OLPC #2154 <br><br>Sor=
ry, the comment say OLC 296, but its Sugarlabs #296<br><br>Gonzalo<br><br><=
br><br><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=
=3D"border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; p=
adding-left: 1ex;">

2. =A0doesn&#39;t properly fix <a href=3D"http://sugarlabs.org" target=3D"_=
blank">sugarlabs.org</a> #296, some additional tuning of<br>
coordinates may be needed; drawing effect still appears at an offset,<br>
</blockquote></div><br><br><br>From 91f7f7e3ad0311c030c18052654f061f3df3e1d=
f Mon Sep 17 00:00:00 2001<br>From: Gonzalo Odiard &lt;<a href=3D"mailto:go=
diard at gmail.com">godiard at gmail.com</a>&gt;<br>Date: Mon, 31 May 2010 00:56:=
59 -0300<br>
Subject: [PATCH] fix OLPC #296<br><br>---<br>=A0Area.py=A0=A0=A0 |=A0=A0 29=
 +++++++++++++++++++++-<br>=A0Desenho.py |=A0=A0 78 +++++++++++++++++++++++=
+-----------------------------------<br>=A02 files changed, 60 insertions(+=
), 47 deletions(-)<br>
<br>diff --git a/Area.py b/Area.py<br>index 44edebb..e81fcdc 100644<br>--- =
a/Area.py<br>+++ b/Area.py<br>@@ -176,6 +176,11 @@ class Area(gtk.DrawingAr=
ea):<br>=A0=A0=A0=A0=A0=A0=A0=A0 ##Shapes will be filled or not?<br>=A0=A0=
=A0=A0=A0=A0=A0=A0 self.fill =3D True<br>
=A0<br>+=A0=A0=A0=A0=A0=A0=A0 # variables to show the tool shape<br>+=A0=A0=
=A0=A0=A0=A0=A0 self.drawing =3D False<br>+=A0=A0=A0=A0=A0=A0=A0 self.x_cur=
sor =3D 0<br>+=A0=A0=A0=A0=A0=A0=A0 self.y_cursor =3D 0<br>+<br>=A0<br>=A0=
=A0=A0=A0 def setup(self, width, height):<br>=A0=A0=A0=A0=A0=A0=A0=A0 &quot=
;&quot;&quot;Configure the Area object.&quot;&quot;&quot;<br>
@@ -256,8 +261,22 @@ class Area(gtk.DrawingArea):<br>=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0=A0 widget.window.draw_drawable(self.gc,self.pixmap_temp,area[0=
],area[1],area[0],area[1],area[2],area[3])<br>=A0=A0=A0=A0=A0=A0=A0=A0 else=
:<br>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 widget.window.draw_drawable(self.=
gc,self.pixmap,area[0],area[1],area[0],area[1],area[2],area[3])<br>
+=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 self.show_tool_shape(widget)=A0=A0=A0 <b=
r>=A0=A0=A0=A0=A0=A0=A0=A0 return False<br>=A0<br>+=A0=A0=A0 def show_tool_=
shape(self,widget):<br>+=A0=A0=A0=A0=A0=A0=A0 &quot;&quot;&quot; <br>+=A0=
=A0=A0=A0=A0=A0=A0 Show the shape of the tool selected for pencil, brush, r=
ainbow and eraser<br>
+=A0=A0=A0=A0=A0=A0=A0 &quot;&quot;&quot;<br>+=A0=A0=A0=A0=A0=A0=A0 if self=
.tool[&#39;name&#39;] in [&#39;pencil&#39;,&#39;eraser&#39;,&#39;brush&#39;=
,&#39;rainbow&#39;]:<br>+=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 if not self.draw=
ing:<br>+=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 size =3D self.tool[&=
#39;line size&#39;]<br>
+=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 if self.tool[&#39;line shape=
&#39;] =3D=3D &#39;circle&#39;:<br>+=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0=A0=A0 widget.window.draw_arc(self.gc_brush, False, self.x_curs=
or - size/2, self.y_cursor - size/2, size, size, 0, 360*64)<br>+=A0=A0=A0=
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 else:<br>
+=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 widget.window.dr=
aw_rectangle(self.gc_brush, False, self.x_cursor - size/2, self.y_cursor - =
size/2, size, size)<br>+<br>+<br>=A0=A0=A0=A0 def mousedown(self,widget,eve=
nt):<br>=A0=A0=A0=A0=A0=A0=A0=A0 &quot;&quot;&quot;Make the Area object (Gt=
kDrawingArea) recognize that the mouse button has been pressed.<br>
=A0<br>@@ -304,14 +323,17 @@ class Area(gtk.DrawingArea):<br>=A0=A0=A0=A0=
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 self.last =3D []<br>=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 self.d.eraser(widget, coords, self.last, sel=
f.line_size, self.tool[&#39;line shape&#39;])<br>=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0=A0=A0=A0=A0 self.last =3D coords<br>
+=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 self.drawing =3D True<br>=A0=
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 elif self.tool[&#39;name&#39;] =3D=3D &#3=
9;brush&#39;:<br>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 self.last=
 =3D []<br>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 self.d.brush(wi=
dget, coords, self.last, self.line_size, self.tool[&#39;line shape&#39;])<b=
r>
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 self.last =3D coords<br>+=
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 self.drawing =3D True<br>=A0=
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 elif self.tool[&#39;name&#39;] =3D=3D &#3=
9;rainbow&#39;:<br>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 self.la=
st =3D []<br>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 self.d.rainbo=
w(widget, coords, self.last, self.rainbow_counter,self.line_size, self.tool=
[&#39;line shape&#39;])<br>
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 self.last =3D coords<br>+=
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 self.drawing =3D True<br>=A0=
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 elif self.tool[&#39;name&#39;] =3D=3D &#3=
9;polygon&#39;:<br>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 self.co=
nfigure_line(self.line_size)<br>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0 if self.polygon_start =3D=3D False:<br>
@@ -347,6 +369,8 @@ class Area(gtk.DrawingArea):<br>=A0=A0=A0=A0=A0=A0=A0=
=A0 y =3D event.y<br>=A0=A0=A0=A0=A0=A0=A0=A0 state =3D event.state<br>=A0<=
br>+=A0=A0=A0=A0=A0=A0=A0 self.x_cursor,self.y_cursor =3D int(x), int(y)<br=
>+<br>=A0=A0=A0=A0=A0=A0=A0=A0 coords =3D int(x), int(y)<br>=A0=A0=A0=A0=A0=
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 <br>
=A0=A0=A0=A0=A0=A0=A0=A0 if state &amp; gtk.gdk.BUTTON1_MASK and self.pixma=
p !=3D None:<br>@@ -419,6 +443,8 @@ class Area(gtk.DrawingArea):<br>=A0=A0=
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 self.configure_line(=
self.line_size)<br>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0 self.d.heart(widget,coords,True,self.tool[&#39;fill&#39;])<br>
=A0=A0=A0=A0=A0=A0=A0=A0 else:<br>+=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 if sel=
f.tool[&#39;name&#39;] in [&#39;brush&#39;,&#39;eraser&#39;,&#39;rainbow&#3=
9;,&#39;pencil&#39;] :<br>+=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 wi=
dget.queue_draw()<br>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 if self.tool[&#39=
;name&#39;] =3D=3D &#39;marquee-rectangular&#39; and self.selmove:<br>
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 size =3D self.pixmap_sel.g=
et_size()<br>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 xi =3D self.o=
rig_x<br>@@ -520,10 +546,11 @@ class Area(gtk.DrawingArea):<br>=A0=A0=A0=A0=
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 self.d.heart(widget,coords,False,self.=
tool[&#39;fill&#39;])<br>
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 self.enableUndo(widget)<br=
>=A0<br>-=A0=A0=A0=A0=A0=A0=A0 if self.tool[&#39;name&#39;] =3D=3D &#39;bru=
sh&#39; or self.tool[&#39;name&#39;] =3D=3D &#39;eraser&#39; or self.tool[&=
#39;name&#39;] =3D=3D &#39;rainbow&#39; or self.tool[&#39;name&#39;] =3D=3D=
 &#39;pencil&#39; :<br>
+=A0=A0=A0=A0=A0=A0=A0 if self.tool[&#39;name&#39;] in [&#39;brush&#39;,&#3=
9;eraser&#39;,&#39;rainbow&#39;,&#39;pencil&#39;] :<br>=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0=A0=A0 self.last =3D []<br>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
 widget.queue_draw() <br>=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 self.enableUn=
do(widget)<br>
+=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 self.drawing =3D False<br>=A0=A0=A0=A0=
=A0=A0=A0=A0 self.desenha =3D False<br>=A0=A0=A0=A0=A0=A0=A0=A0 <br>=A0=A0=
=A0=A0 def undo(self):<br>diff --git a/Desenho.py b/Desenho.py<br>index e5e=
cf48..c9a134b 100644<br>--- a/Desenho.py<br>+++ b/Desenho.py<br>@@ -110,20 =
+110,8 @@ class Desenho:<br>
=A0<br>=A0=A0=A0=A0=A0=A0=A0=A0 &quot;&quot;&quot;<br>=A0=A0=A0=A0=A0=A0=A0=
=A0 widget.desenha =3D False<br>-=A0=A0=A0=A0=A0=A0=A0 if(shape =3D=3D &#39=
;circle&#39;):<br>-=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 widget.pixmap.draw_arc=
(widget.gc_eraser, True, coords[0], coords[1], size, size, 0, 360*64)<br>
-=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 if last:<br>-=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0=A0=A0 widget.gc_eraser.set_line_attributes(size, gtk.gdk.LINE_=
SOLID, gtk.gdk.CAP_ROUND, gtk.gdk.JOIN_ROUND)<br>-=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0=A0=A0=A0 widget.pixmap.draw_line(widget.gc_eraser,last[0]+size=
/2,last[1]+size/2,coords[0]+size/2,coords[1]+size/2)<br>
-=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 widget.gc_eraser.set_line_at=
tributes(0, gtk.gdk.LINE_SOLID, gtk.gdk.CAP_ROUND, gtk.gdk.JOIN_ROUND)<br>-=
=A0=A0=A0=A0=A0=A0=A0 if(shape =3D=3D &#39;square&#39;):<br>-=A0=A0=A0=A0=
=A0=A0=A0=A0=A0=A0=A0 widget.pixmap.draw_rectangle(widget.gc_eraser, True, =
coords[0], coords[1], size, size)<br>
-=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 if last:<br>-=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0=A0=A0 points =3D [coords, last, (last[0]+size,last[1]+size), (=
coords[0]+size,coords[1]+size)]<br>-=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0 widget.pixmap.draw_polygon(widget.gc_eraser,True,points)<br>-=A0=A0=
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 points =3D [(last[0]+size,last[1]),=
 (coords[0]+size,coords[1]), (coords[0],coords[1]+size), (last[0],last[1]+s=
ize)]<br>
-=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 widget.pixmap.draw_polygon(w=
idget.gc_eraser,True,points)<br>-=A0=A0=A0=A0=A0=A0=A0 widget.queue_draw()<=
br>+=A0=A0=A0=A0=A0=A0=A0 self._trace(widget,widget.gc_eraser, coords, last=
, size, shape)<br>+=A0=A0=A0=A0=A0=A0=A0 #widget.queue_draw()<br>=A0=A0=A0=
=A0=A0=A0=A0=A0 <br>
=A0=A0=A0=A0 def brush(self, widget, coords, last, size =3D 5, shape =3D &#=
39;circle&#39;):<br>=A0=A0=A0=A0=A0=A0=A0=A0 &quot;&quot;&quot;Paint with b=
rush.<br>@@ -137,28 +125,9 @@ class Desenho:<br>=A0<br>=A0=A0=A0=A0=A0=A0=
=A0=A0 &quot;&quot;&quot;<br>=A0=A0=A0=A0=A0=A0=A0=A0 widget.desenha =3D Fa=
lse<br>
-=A0=A0=A0=A0=A0=A0=A0 if(shape =3D=3D &#39;circle&#39;):<br>-=A0=A0=A0=A0=
=A0=A0=A0=A0=A0=A0=A0 widget.pixmap.draw_arc(widget.gc_brush, True, coords[=
0], coords[1], size, size, 0, 360*64)<br>-=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
 if last:<br>-=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 widget.gc_brush=
.set_line_attributes(size, gtk.gdk.LINE_SOLID, gtk.gdk.CAP_ROUND, gtk.gdk.J=
OIN_ROUND)<br>
-=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 widget.pixmap.draw_line(widg=
et.gc_brush,last[0]+size/2,last[1]+size/2,coords[0]+size/2,coords[1]+size/2=
)<br>-=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 widget.gc_brush.set_lin=
e_attributes(0, gtk.gdk.LINE_SOLID, gtk.gdk.CAP_ROUND, gtk.gdk.JOIN_ROUND)<=
br>
-=A0=A0=A0=A0=A0=A0=A0 if(shape =3D=3D &#39;square&#39;):<br>-=A0=A0=A0=A0=
=A0=A0=A0=A0=A0=A0=A0 widget.pixmap.draw_rectangle(widget.gc_brush, True, c=
oords[0], coords[1], size, size)<br>-=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 if l=
ast:<br>-=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 points =3D [coords, =
last, (last[0]+size,last[1]+size), (coords[0]+size,coords[1]+size)]<br>
-=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 widget.pixmap.draw_polygon(w=
idget.gc_brush,True,points)<br>-=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0 points =3D [(last[0]+size,last[1]), (coords[0]+size,coords[1]), (coords=
[0],coords[1]+size), (last[0],last[1]+size)]<br>-=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0=A0=A0=A0 widget.pixmap.draw_polygon(widget.gc_brush,True,point=
s)<br>
+=A0=A0=A0=A0=A0=A0=A0 self._trace(widget,widget.gc_brush, coords, last, si=
ze, shape)<br>+<br>=A0<br>-=A0=A0=A0=A0=A0=A0=A0 if last:<br>-=A0=A0=A0=A0=
=A0=A0=A0=A0=A0=A0=A0 x =3D min(coords[0], last[0])<br>-=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0=A0 width =3D max(coords[0], last[0]) - x<br>-=A0=A0=A0=A0=A0=
=A0=A0=A0=A0=A0=A0 y =3D min(coords[1], last[1])<br>
-=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 height =3D max(coords[1], last[1]) - y<b=
r>-=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 widget.queue_draw_area(x, y, width+siz=
e, height+size) # We add size to avoid drawing dotted lines<br>-=A0=A0=A0=
=A0=A0=A0=A0 else:<br>-=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 widget.queue_draw(=
)<br>
=A0<br>=A0=A0=A0=A0 def rainbow(self, widget, coords, last, color, size =3D=
 5, shape =3D &#39;circle&#39;):<br>=A0=A0=A0=A0=A0=A0=A0=A0 &quot;&quot;&q=
uot;Paint with rainbow.<br>@@ -190,23 +159,40 @@ class Desenho:<br>=A0<br>=
=A0=A0=A0=A0=A0=A0=A0=A0 widget.gc_rainbow.set_foreground(rainbow_colors[co=
lor])<br>
=A0=A0=A0=A0=A0=A0=A0=A0 widget.desenha =3D False<br>+=A0=A0=A0=A0=A0=A0=A0=
 self._trace(widget,widget.gc_rainbow, coords, last, size, shape)<br>+<br>+=
<br>+=A0=A0=A0 def _trace(self, widget,gc, coords, last, size, shape):<br>=
=A0=A0=A0=A0=A0=A0=A0=A0 if(shape =3D=3D &#39;circle&#39;):<br>
-=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 widget.pixmap.draw_arc(widget.gc_rainbow=
, True, coords[0], coords[1], size, size, 0, 360*64)<br>+=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0=A0 widget.pixmap.draw_arc(gc, True, coords[0] - size/2, coords=
[1] - size/2, size, size, 0, 360*64)<br>
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 if last:<br>-=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0=A0=A0=A0 widget.gc_rainbow.set_line_attributes(size, gtk.gdk.L=
INE_SOLID, gtk.gdk.CAP_ROUND, gtk.gdk.JOIN_ROUND)<br>-=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0=A0=A0=A0=A0 widget.pixmap.draw_line(widget.gc_rainbow,last[0]+=
size/2,last[1]+size/2,coords[0]+size/2,coords[1]+size/2)<br>
-=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 widget.gc_rainbow.set_line_a=
ttributes(0, gtk.gdk.LINE_SOLID, gtk.gdk.CAP_ROUND, gtk.gdk.JOIN_ROUND)<br>=
+=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 gc.set_line_attributes(size,=
 gtk.gdk.LINE_SOLID, gtk.gdk.CAP_ROUND, gtk.gdk.JOIN_ROUND)<br>
+=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 widget.pixmap.draw_line(gc, =
last[0], last[1], coords[0], coords[1])<br>+=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0=A0 gc.set_line_attributes(0, gtk.gdk.LINE_SOLID, gtk.gdk.CAP_R=
OUND, gtk.gdk.JOIN_ROUND)<br>=A0=A0=A0=A0=A0=A0=A0=A0 if(shape =3D=3D &#39;=
square&#39;):<br>
+=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 widget.pixmap.draw_rectangle(gc, True, c=
oords[0] - size/2, coords[1] - size/2, size, size)<br>=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0=A0 if last:<br>-=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 =
widget.pixmap.draw_rectangle(widget.gc_rainbow, True, last[0], last[1], siz=
e, size)<br>
-=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 points =3D [coords, last, (l=
ast[0]+size,last[1]+size), (coords[0]+size,coords[1]+size)]<br>-=A0=A0=A0=
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 widget.pixmap.draw_polygon(widget.gc_r=
ainbow,True,points)<br>-=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 point=
s =3D [(last[0]+size,last[1]), (coords[0]+size,coords[1]), (coords[0],coord=
s[1]+size), (last[0],last[1]+size)]<br>
-=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 widget.pixmap.draw_polygon(w=
idget.gc_rainbow,True,points)<br>-=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 widget.=
pixmap.draw_rectangle(widget.gc_rainbow, True, coords[0], coords[1], size, =
size)<br>-=A0=A0=A0=A0=A0=A0=A0 widget.queue_draw()<br>+=A0=A0=A0=A0=A0=A0=
=A0=A0=A0=A0=A0=A0=A0=A0=A0 points =3D [(last[0] - size/2,last[1] - size/2)=
, (coords[0] - size/2, coords[1] - size/2), <br>
+=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0 (coords[0] + size/2, coords[1] + size/2) , (last[0] + size/2,last=
[1] + size/2)]<br>+=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 widget.pix=
map.draw_polygon(gc,True,points)<br>+=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0 points =3D [(last[0] + size/2,last[1] - size/2), (coords[0] + siz=
e/2, coords[1] - size/2), <br>
+=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=
=A0=A0=A0 (coords[0] - size/2, coords[1] + size/2) , (last[0] - size/2,last=
[1] + size/2)]<br>+=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 widget.pix=
map.draw_polygon(gc,True,points)<br>+<br>+<br>+=A0=A0=A0=A0=A0=A0=A0 if las=
t:<br>+=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 x =3D min(coords[0], last[0])<br>
+=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 width =3D max(coords[0], last[0]) - x<br=
>+=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 y =3D min(coords[1], last[1])<br>+=A0=
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 height =3D max(coords[1] , last[1]) - y<br>+=
=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 widget.queue_draw_area(x-size, y-size, wi=
dth+size*2, height+size*2) # We add size to avoid drawing dotted lines<br>
+=A0=A0=A0=A0=A0=A0=A0 else:<br>+=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 widget.q=
ueue_draw()<br>+<br>=A0<br>=A0=A0=A0=A0 <br>+<br>+<br>=A0=A0=A0=A0 def squa=
re(self, widget, event, coords, temp, fill):<br>=A0=A0=A0=A0=A0=A0=A0=A0 &q=
uot;&quot;&quot;Draw a square.<br>=A0<br>-- <br>1.6.6.1<br><br>

--000e0cd3b23c2be9890487dbff4f--
--000e0cd3b23c2be9900487dbff51
Content-Type: application/octet-stream; name="0001-fix-OLPC-296.patch"
Content-Disposition: attachment; filename="0001-fix-OLPC-296.patch"
Content-Transfer-Encoding: base64
X-Attachment-Id: f_g9us25f60

RnJvbSA5MWY3ZjdlM2FkMDMxMWMwMzBjMTgwNTI2NTRmMDYxZjNkZjNlMWRmIE1vbiBTZXAgMTcg
MDA6MDA6MDAgMjAwMQpGcm9tOiBHb256YWxvIE9kaWFyZCA8Z29kaWFyZEBnbWFpbC5jb20+CkRh
dGU6IE1vbiwgMzEgTWF5IDIwMTAgMDA6NTY6NTkgLTAzMDAKU3ViamVjdDogW1BBVENIXSBmaXgg
T0xQQyAjMjk2CgotLS0KIEFyZWEucHkgICAgfCAgIDI5ICsrKysrKysrKysrKysrKysrKysrKy0K
IERlc2VuaG8ucHkgfCAgIDc4ICsrKysrKysrKysrKysrKysrKysrKysrKy0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAyIGZpbGVzIGNoYW5nZWQsIDYwIGluc2VydGlvbnMoKyks
IDQ3IGRlbGV0aW9ucygtKQoKZGlmZiAtLWdpdCBhL0FyZWEucHkgYi9BcmVhLnB5CmluZGV4IDQ0
ZWRlYmIuLmU4MWZjZGMgMTAwNjQ0Ci0tLSBhL0FyZWEucHkKKysrIGIvQXJlYS5weQpAQCAtMTc2
LDYgKzE3NiwxMSBAQCBjbGFzcyBBcmVhKGd0ay5EcmF3aW5nQXJlYSk6CiAgICAgICAgICMjU2hh
cGVzIHdpbGwgYmUgZmlsbGVkIG9yIG5vdD8KICAgICAgICAgc2VsZi5maWxsID0gVHJ1ZQogCisg
ICAgICAgICMgdmFyaWFibGVzIHRvIHNob3cgdGhlIHRvb2wgc2hhcGUKKyAgICAgICAgc2VsZi5k
cmF3aW5nID0gRmFsc2UKKyAgICAgICAgc2VsZi54X2N1cnNvciA9IDAKKyAgICAgICAgc2VsZi55
X2N1cnNvciA9IDAKKwogCiAgICAgZGVmIHNldHVwKHNlbGYsIHdpZHRoLCBoZWlnaHQpOgogICAg
ICAgICAiIiJDb25maWd1cmUgdGhlIEFyZWEgb2JqZWN0LiIiIgpAQCAtMjU2LDggKzI2MSwyMiBA
QCBjbGFzcyBBcmVhKGd0ay5EcmF3aW5nQXJlYSk6CiAgICAgICAgICAgICB3aWRnZXQud2luZG93
LmRyYXdfZHJhd2FibGUoc2VsZi5nYyxzZWxmLnBpeG1hcF90ZW1wLGFyZWFbMF0sYXJlYVsxXSxh
cmVhWzBdLGFyZWFbMV0sYXJlYVsyXSxhcmVhWzNdKQogICAgICAgICBlbHNlOgogICAgICAgICAg
ICAgd2lkZ2V0LndpbmRvdy5kcmF3X2RyYXdhYmxlKHNlbGYuZ2Msc2VsZi5waXhtYXAsYXJlYVsw
XSxhcmVhWzFdLGFyZWFbMF0sYXJlYVsxXSxhcmVhWzJdLGFyZWFbM10pCisgICAgICAgICAgICBz
ZWxmLnNob3dfdG9vbF9zaGFwZSh3aWRnZXQpICAgIAogICAgICAgICByZXR1cm4gRmFsc2UKIAor
ICAgIGRlZiBzaG93X3Rvb2xfc2hhcGUoc2VsZix3aWRnZXQpOgorICAgICAgICAiIiIgCisgICAg
ICAgIFNob3cgdGhlIHNoYXBlIG9mIHRoZSB0b29sIHNlbGVjdGVkIGZvciBwZW5jaWwsIGJydXNo
LCByYWluYm93IGFuZCBlcmFzZXIKKyAgICAgICAgIiIiCisgICAgICAgIGlmIHNlbGYudG9vbFsn
bmFtZSddIGluIFsncGVuY2lsJywnZXJhc2VyJywnYnJ1c2gnLCdyYWluYm93J106CisgICAgICAg
ICAgICBpZiBub3Qgc2VsZi5kcmF3aW5nOgorICAgICAgICAgICAgICAgIHNpemUgPSBzZWxmLnRv
b2xbJ2xpbmUgc2l6ZSddCisgICAgICAgICAgICAgICAgaWYgc2VsZi50b29sWydsaW5lIHNoYXBl
J10gPT0gJ2NpcmNsZSc6CisgICAgICAgICAgICAgICAgICAgIHdpZGdldC53aW5kb3cuZHJhd19h
cmMoc2VsZi5nY19icnVzaCwgRmFsc2UsIHNlbGYueF9jdXJzb3IgLSBzaXplLzIsIHNlbGYueV9j
dXJzb3IgLSBzaXplLzIsIHNpemUsIHNpemUsIDAsIDM2MCo2NCkKKyAgICAgICAgICAgICAgICBl
bHNlOgorICAgICAgICAgICAgICAgICAgICB3aWRnZXQud2luZG93LmRyYXdfcmVjdGFuZ2xlKHNl
bGYuZ2NfYnJ1c2gsIEZhbHNlLCBzZWxmLnhfY3Vyc29yIC0gc2l6ZS8yLCBzZWxmLnlfY3Vyc29y
IC0gc2l6ZS8yLCBzaXplLCBzaXplKQorCisKICAgICBkZWYgbW91c2Vkb3duKHNlbGYsd2lkZ2V0
LGV2ZW50KToKICAgICAgICAgIiIiTWFrZSB0aGUgQXJlYSBvYmplY3QgKEd0a0RyYXdpbmdBcmVh
KSByZWNvZ25pemUgdGhhdCB0aGUgbW91c2UgYnV0dG9uIGhhcyBiZWVuIHByZXNzZWQuCiAKQEAg
LTMwNCwxNCArMzIzLDE3IEBAIGNsYXNzIEFyZWEoZ3RrLkRyYXdpbmdBcmVhKToKICAgICAgICAg
ICAgICAgICBzZWxmLmxhc3QgPSBbXQogICAgICAgICAgICAgICAgIHNlbGYuZC5lcmFzZXIod2lk
Z2V0LCBjb29yZHMsIHNlbGYubGFzdCwgc2VsZi5saW5lX3NpemUsIHNlbGYudG9vbFsnbGluZSBz
aGFwZSddKQogICAgICAgICAgICAgICAgIHNlbGYubGFzdCA9IGNvb3JkcworICAgICAgICAgICAg
ICAgIHNlbGYuZHJhd2luZyA9IFRydWUKICAgICAgICAgICAgIGVsaWYgc2VsZi50b29sWyduYW1l
J10gPT0gJ2JydXNoJzoKICAgICAgICAgICAgICAgICBzZWxmLmxhc3QgPSBbXQogICAgICAgICAg
ICAgICAgIHNlbGYuZC5icnVzaCh3aWRnZXQsIGNvb3Jkcywgc2VsZi5sYXN0LCBzZWxmLmxpbmVf
c2l6ZSwgc2VsZi50b29sWydsaW5lIHNoYXBlJ10pCiAgICAgICAgICAgICAgICAgc2VsZi5sYXN0
ID0gY29vcmRzCisgICAgICAgICAgICAgICAgc2VsZi5kcmF3aW5nID0gVHJ1ZQogICAgICAgICAg
ICAgZWxpZiBzZWxmLnRvb2xbJ25hbWUnXSA9PSAncmFpbmJvdyc6CiAgICAgICAgICAgICAgICAg
c2VsZi5sYXN0ID0gW10KICAgICAgICAgICAgICAgICBzZWxmLmQucmFpbmJvdyh3aWRnZXQsIGNv
b3Jkcywgc2VsZi5sYXN0LCBzZWxmLnJhaW5ib3dfY291bnRlcixzZWxmLmxpbmVfc2l6ZSwgc2Vs
Zi50b29sWydsaW5lIHNoYXBlJ10pCiAgICAgICAgICAgICAgICAgc2VsZi5sYXN0ID0gY29vcmRz
CisgICAgICAgICAgICAgICAgc2VsZi5kcmF3aW5nID0gVHJ1ZQogICAgICAgICAgICAgZWxpZiBz
ZWxmLnRvb2xbJ25hbWUnXSA9PSAncG9seWdvbic6CiAgICAgICAgICAgICAgICAgc2VsZi5jb25m
aWd1cmVfbGluZShzZWxmLmxpbmVfc2l6ZSkKICAgICAgICAgICAgICAgICBpZiBzZWxmLnBvbHln
b25fc3RhcnQgPT0gRmFsc2U6CkBAIC0zNDcsNiArMzY5LDggQEAgY2xhc3MgQXJlYShndGsuRHJh
d2luZ0FyZWEpOgogICAgICAgICB5ID0gZXZlbnQueQogICAgICAgICBzdGF0ZSA9IGV2ZW50LnN0
YXRlCiAKKyAgICAgICAgc2VsZi54X2N1cnNvcixzZWxmLnlfY3Vyc29yID0gaW50KHgpLCBpbnQo
eSkKKwogICAgICAgICBjb29yZHMgPSBpbnQoeCksIGludCh5KQogICAgICAgICAgICAgICAgICAg
ICAgICAgCiAgICAgICAgIGlmIHN0YXRlICYgZ3RrLmdkay5CVVRUT04xX01BU0sgYW5kIHNlbGYu
cGl4bWFwICE9IE5vbmU6CkBAIC00MTksNiArNDQzLDggQEAgY2xhc3MgQXJlYShndGsuRHJhd2lu
Z0FyZWEpOgogICAgICAgICAgICAgICAgICAgICBzZWxmLmNvbmZpZ3VyZV9saW5lKHNlbGYubGlu
ZV9zaXplKQogICAgICAgICAgICAgICAgICAgICBzZWxmLmQuaGVhcnQod2lkZ2V0LGNvb3JkcyxU
cnVlLHNlbGYudG9vbFsnZmlsbCddKQogICAgICAgICBlbHNlOgorICAgICAgICAgICAgaWYgc2Vs
Zi50b29sWyduYW1lJ10gaW4gWydicnVzaCcsJ2VyYXNlcicsJ3JhaW5ib3cnLCdwZW5jaWwnXSA6
CisgICAgICAgICAgICAgICAgd2lkZ2V0LnF1ZXVlX2RyYXcoKQogICAgICAgICAgICAgaWYgc2Vs
Zi50b29sWyduYW1lJ10gPT0gJ21hcnF1ZWUtcmVjdGFuZ3VsYXInIGFuZCBzZWxmLnNlbG1vdmU6
CiAgICAgICAgICAgICAgICAgc2l6ZSA9IHNlbGYucGl4bWFwX3NlbC5nZXRfc2l6ZSgpCiAgICAg
ICAgICAgICAgICAgeGkgPSBzZWxmLm9yaWdfeApAQCAtNTIwLDEwICs1NDYsMTEgQEAgY2xhc3Mg
QXJlYShndGsuRHJhd2luZ0FyZWEpOgogICAgICAgICAgICAgICAgIHNlbGYuZC5oZWFydCh3aWRn
ZXQsY29vcmRzLEZhbHNlLHNlbGYudG9vbFsnZmlsbCddKQogICAgICAgICAgICAgICAgIHNlbGYu
ZW5hYmxlVW5kbyh3aWRnZXQpCiAKLSAgICAgICAgaWYgc2VsZi50b29sWyduYW1lJ10gPT0gJ2Jy
dXNoJyBvciBzZWxmLnRvb2xbJ25hbWUnXSA9PSAnZXJhc2VyJyBvciBzZWxmLnRvb2xbJ25hbWUn
XSA9PSAncmFpbmJvdycgb3Igc2VsZi50b29sWyduYW1lJ10gPT0gJ3BlbmNpbCcgOgorICAgICAg
ICBpZiBzZWxmLnRvb2xbJ25hbWUnXSBpbiBbJ2JydXNoJywnZXJhc2VyJywncmFpbmJvdycsJ3Bl
bmNpbCddIDoKICAgICAgICAgICAgIHNlbGYubGFzdCA9IFtdCiAgICAgICAgICAgICB3aWRnZXQu
cXVldWVfZHJhdygpIAogICAgICAgICAgICAgc2VsZi5lbmFibGVVbmRvKHdpZGdldCkKKyAgICAg
ICAgICAgIHNlbGYuZHJhd2luZyA9IEZhbHNlCiAgICAgICAgIHNlbGYuZGVzZW5oYSA9IEZhbHNl
CiAgICAgICAgIAogICAgIGRlZiB1bmRvKHNlbGYpOgpkaWZmIC0tZ2l0IGEvRGVzZW5oby5weSBi
L0Rlc2VuaG8ucHkKaW5kZXggZTVlY2Y0OC4uYzlhMTM0YiAxMDA2NDQKLS0tIGEvRGVzZW5oby5w
eQorKysgYi9EZXNlbmhvLnB5CkBAIC0xMTAsMjAgKzExMCw4IEBAIGNsYXNzIERlc2VuaG86CiAK
ICAgICAgICAgIiIiCiAgICAgICAgIHdpZGdldC5kZXNlbmhhID0gRmFsc2UKLSAgICAgICAgaWYo
c2hhcGUgPT0gJ2NpcmNsZScpOgotICAgICAgICAgICAgd2lkZ2V0LnBpeG1hcC5kcmF3X2FyYyh3
aWRnZXQuZ2NfZXJhc2VyLCBUcnVlLCBjb29yZHNbMF0sIGNvb3Jkc1sxXSwgc2l6ZSwgc2l6ZSwg
MCwgMzYwKjY0KQotICAgICAgICAgICAgaWYgbGFzdDoKLSAgICAgICAgICAgICAgICB3aWRnZXQu
Z2NfZXJhc2VyLnNldF9saW5lX2F0dHJpYnV0ZXMoc2l6ZSwgZ3RrLmdkay5MSU5FX1NPTElELCBn
dGsuZ2RrLkNBUF9ST1VORCwgZ3RrLmdkay5KT0lOX1JPVU5EKQotICAgICAgICAgICAgICAgIHdp
ZGdldC5waXhtYXAuZHJhd19saW5lKHdpZGdldC5nY19lcmFzZXIsbGFzdFswXStzaXplLzIsbGFz
dFsxXStzaXplLzIsY29vcmRzWzBdK3NpemUvMixjb29yZHNbMV0rc2l6ZS8yKQotICAgICAgICAg
ICAgICAgIHdpZGdldC5nY19lcmFzZXIuc2V0X2xpbmVfYXR0cmlidXRlcygwLCBndGsuZ2RrLkxJ
TkVfU09MSUQsIGd0ay5nZGsuQ0FQX1JPVU5ELCBndGsuZ2RrLkpPSU5fUk9VTkQpCi0gICAgICAg
IGlmKHNoYXBlID09ICdzcXVhcmUnKToKLSAgICAgICAgICAgIHdpZGdldC5waXhtYXAuZHJhd19y
ZWN0YW5nbGUod2lkZ2V0LmdjX2VyYXNlciwgVHJ1ZSwgY29vcmRzWzBdLCBjb29yZHNbMV0sIHNp
emUsIHNpemUpCi0gICAgICAgICAgICBpZiBsYXN0OgotICAgICAgICAgICAgICAgIHBvaW50cyA9
IFtjb29yZHMsIGxhc3QsIChsYXN0WzBdK3NpemUsbGFzdFsxXStzaXplKSwgKGNvb3Jkc1swXStz
aXplLGNvb3Jkc1sxXStzaXplKV0KLSAgICAgICAgICAgICAgICB3aWRnZXQucGl4bWFwLmRyYXdf
cG9seWdvbih3aWRnZXQuZ2NfZXJhc2VyLFRydWUscG9pbnRzKQotICAgICAgICAgICAgICAgIHBv
aW50cyA9IFsobGFzdFswXStzaXplLGxhc3RbMV0pLCAoY29vcmRzWzBdK3NpemUsY29vcmRzWzFd
KSwgKGNvb3Jkc1swXSxjb29yZHNbMV0rc2l6ZSksIChsYXN0WzBdLGxhc3RbMV0rc2l6ZSldCi0g
ICAgICAgICAgICAgICAgd2lkZ2V0LnBpeG1hcC5kcmF3X3BvbHlnb24od2lkZ2V0LmdjX2VyYXNl
cixUcnVlLHBvaW50cykKLSAgICAgICAgd2lkZ2V0LnF1ZXVlX2RyYXcoKQorICAgICAgICBzZWxm
Ll90cmFjZSh3aWRnZXQsd2lkZ2V0LmdjX2VyYXNlciwgY29vcmRzLCBsYXN0LCBzaXplLCBzaGFw
ZSkKKyAgICAgICAgI3dpZGdldC5xdWV1ZV9kcmF3KCkKICAgICAgICAgCiAgICAgZGVmIGJydXNo
KHNlbGYsIHdpZGdldCwgY29vcmRzLCBsYXN0LCBzaXplID0gNSwgc2hhcGUgPSAnY2lyY2xlJyk6
CiAgICAgICAgICIiIlBhaW50IHdpdGggYnJ1c2guCkBAIC0xMzcsMjggKzEyNSw5IEBAIGNsYXNz
IERlc2VuaG86CiAKICAgICAgICAgIiIiCiAgICAgICAgIHdpZGdldC5kZXNlbmhhID0gRmFsc2UK
LSAgICAgICAgaWYoc2hhcGUgPT0gJ2NpcmNsZScpOgotICAgICAgICAgICAgd2lkZ2V0LnBpeG1h
cC5kcmF3X2FyYyh3aWRnZXQuZ2NfYnJ1c2gsIFRydWUsIGNvb3Jkc1swXSwgY29vcmRzWzFdLCBz
aXplLCBzaXplLCAwLCAzNjAqNjQpCi0gICAgICAgICAgICBpZiBsYXN0OgotICAgICAgICAgICAg
ICAgIHdpZGdldC5nY19icnVzaC5zZXRfbGluZV9hdHRyaWJ1dGVzKHNpemUsIGd0ay5nZGsuTElO
RV9TT0xJRCwgZ3RrLmdkay5DQVBfUk9VTkQsIGd0ay5nZGsuSk9JTl9ST1VORCkKLSAgICAgICAg
ICAgICAgICB3aWRnZXQucGl4bWFwLmRyYXdfbGluZSh3aWRnZXQuZ2NfYnJ1c2gsbGFzdFswXStz
aXplLzIsbGFzdFsxXStzaXplLzIsY29vcmRzWzBdK3NpemUvMixjb29yZHNbMV0rc2l6ZS8yKQot
ICAgICAgICAgICAgICAgIHdpZGdldC5nY19icnVzaC5zZXRfbGluZV9hdHRyaWJ1dGVzKDAsIGd0
ay5nZGsuTElORV9TT0xJRCwgZ3RrLmdkay5DQVBfUk9VTkQsIGd0ay5nZGsuSk9JTl9ST1VORCkK
LSAgICAgICAgaWYoc2hhcGUgPT0gJ3NxdWFyZScpOgotICAgICAgICAgICAgd2lkZ2V0LnBpeG1h
cC5kcmF3X3JlY3RhbmdsZSh3aWRnZXQuZ2NfYnJ1c2gsIFRydWUsIGNvb3Jkc1swXSwgY29vcmRz
WzFdLCBzaXplLCBzaXplKQotICAgICAgICAgICAgaWYgbGFzdDoKLSAgICAgICAgICAgICAgICBw
b2ludHMgPSBbY29vcmRzLCBsYXN0LCAobGFzdFswXStzaXplLGxhc3RbMV0rc2l6ZSksIChjb29y
ZHNbMF0rc2l6ZSxjb29yZHNbMV0rc2l6ZSldCi0gICAgICAgICAgICAgICAgd2lkZ2V0LnBpeG1h
cC5kcmF3X3BvbHlnb24od2lkZ2V0LmdjX2JydXNoLFRydWUscG9pbnRzKQotICAgICAgICAgICAg
ICAgIHBvaW50cyA9IFsobGFzdFswXStzaXplLGxhc3RbMV0pLCAoY29vcmRzWzBdK3NpemUsY29v
cmRzWzFdKSwgKGNvb3Jkc1swXSxjb29yZHNbMV0rc2l6ZSksIChsYXN0WzBdLGxhc3RbMV0rc2l6
ZSldCi0gICAgICAgICAgICAgICAgd2lkZ2V0LnBpeG1hcC5kcmF3X3BvbHlnb24od2lkZ2V0Lmdj
X2JydXNoLFRydWUscG9pbnRzKQorICAgICAgICBzZWxmLl90cmFjZSh3aWRnZXQsd2lkZ2V0Lmdj
X2JydXNoLCBjb29yZHMsIGxhc3QsIHNpemUsIHNoYXBlKQorCiAKLSAgICAgICAgaWYgbGFzdDoK
LSAgICAgICAgICAgIHggPSBtaW4oY29vcmRzWzBdLCBsYXN0WzBdKQotICAgICAgICAgICAgd2lk
dGggPSBtYXgoY29vcmRzWzBdLCBsYXN0WzBdKSAtIHgKLSAgICAgICAgICAgIHkgPSBtaW4oY29v
cmRzWzFdLCBsYXN0WzFdKQotICAgICAgICAgICAgaGVpZ2h0ID0gbWF4KGNvb3Jkc1sxXSwgbGFz
dFsxXSkgLSB5Ci0gICAgICAgICAgICB3aWRnZXQucXVldWVfZHJhd19hcmVhKHgsIHksIHdpZHRo
K3NpemUsIGhlaWdodCtzaXplKSAjIFdlIGFkZCBzaXplIHRvIGF2b2lkIGRyYXdpbmcgZG90dGVk
IGxpbmVzCi0gICAgICAgIGVsc2U6Ci0gICAgICAgICAgICB3aWRnZXQucXVldWVfZHJhdygpCiAK
ICAgICBkZWYgcmFpbmJvdyhzZWxmLCB3aWRnZXQsIGNvb3JkcywgbGFzdCwgY29sb3IsIHNpemUg
PSA1LCBzaGFwZSA9ICdjaXJjbGUnKToKICAgICAgICAgIiIiUGFpbnQgd2l0aCByYWluYm93LgpA
QCAtMTkwLDIzICsxNTksNDAgQEAgY2xhc3MgRGVzZW5obzoKIAogICAgICAgICB3aWRnZXQuZ2Nf
cmFpbmJvdy5zZXRfZm9yZWdyb3VuZChyYWluYm93X2NvbG9yc1tjb2xvcl0pCiAgICAgICAgIHdp
ZGdldC5kZXNlbmhhID0gRmFsc2UKKyAgICAgICAgc2VsZi5fdHJhY2Uod2lkZ2V0LHdpZGdldC5n
Y19yYWluYm93LCBjb29yZHMsIGxhc3QsIHNpemUsIHNoYXBlKQorCisKKyAgICBkZWYgX3RyYWNl
KHNlbGYsIHdpZGdldCxnYywgY29vcmRzLCBsYXN0LCBzaXplLCBzaGFwZSk6CiAgICAgICAgIGlm
KHNoYXBlID09ICdjaXJjbGUnKToKLSAgICAgICAgICAgIHdpZGdldC5waXhtYXAuZHJhd19hcmMo
d2lkZ2V0LmdjX3JhaW5ib3csIFRydWUsIGNvb3Jkc1swXSwgY29vcmRzWzFdLCBzaXplLCBzaXpl
LCAwLCAzNjAqNjQpCisgICAgICAgICAgICB3aWRnZXQucGl4bWFwLmRyYXdfYXJjKGdjLCBUcnVl
LCBjb29yZHNbMF0gLSBzaXplLzIsIGNvb3Jkc1sxXSAtIHNpemUvMiwgc2l6ZSwgc2l6ZSwgMCwg
MzYwKjY0KQogICAgICAgICAgICAgaWYgbGFzdDoKLSAgICAgICAgICAgICAgICB3aWRnZXQuZ2Nf
cmFpbmJvdy5zZXRfbGluZV9hdHRyaWJ1dGVzKHNpemUsIGd0ay5nZGsuTElORV9TT0xJRCwgZ3Rr
Lmdkay5DQVBfUk9VTkQsIGd0ay5nZGsuSk9JTl9ST1VORCkKLSAgICAgICAgICAgICAgICB3aWRn
ZXQucGl4bWFwLmRyYXdfbGluZSh3aWRnZXQuZ2NfcmFpbmJvdyxsYXN0WzBdK3NpemUvMixsYXN0
WzFdK3NpemUvMixjb29yZHNbMF0rc2l6ZS8yLGNvb3Jkc1sxXStzaXplLzIpCi0gICAgICAgICAg
ICAgICAgd2lkZ2V0LmdjX3JhaW5ib3cuc2V0X2xpbmVfYXR0cmlidXRlcygwLCBndGsuZ2RrLkxJ
TkVfU09MSUQsIGd0ay5nZGsuQ0FQX1JPVU5ELCBndGsuZ2RrLkpPSU5fUk9VTkQpCisgICAgICAg
ICAgICAgICAgZ2Muc2V0X2xpbmVfYXR0cmlidXRlcyhzaXplLCBndGsuZ2RrLkxJTkVfU09MSUQs
IGd0ay5nZGsuQ0FQX1JPVU5ELCBndGsuZ2RrLkpPSU5fUk9VTkQpCisgICAgICAgICAgICAgICAg
d2lkZ2V0LnBpeG1hcC5kcmF3X2xpbmUoZ2MsIGxhc3RbMF0sIGxhc3RbMV0sIGNvb3Jkc1swXSwg
Y29vcmRzWzFdKQorICAgICAgICAgICAgICAgIGdjLnNldF9saW5lX2F0dHJpYnV0ZXMoMCwgZ3Rr
Lmdkay5MSU5FX1NPTElELCBndGsuZ2RrLkNBUF9ST1VORCwgZ3RrLmdkay5KT0lOX1JPVU5EKQog
ICAgICAgICBpZihzaGFwZSA9PSAnc3F1YXJlJyk6CisgICAgICAgICAgICB3aWRnZXQucGl4bWFw
LmRyYXdfcmVjdGFuZ2xlKGdjLCBUcnVlLCBjb29yZHNbMF0gLSBzaXplLzIsIGNvb3Jkc1sxXSAt
IHNpemUvMiwgc2l6ZSwgc2l6ZSkKICAgICAgICAgICAgIGlmIGxhc3Q6Ci0gICAgICAgICAgICAg
ICAgd2lkZ2V0LnBpeG1hcC5kcmF3X3JlY3RhbmdsZSh3aWRnZXQuZ2NfcmFpbmJvdywgVHJ1ZSwg
bGFzdFswXSwgbGFzdFsxXSwgc2l6ZSwgc2l6ZSkKLSAgICAgICAgICAgICAgICBwb2ludHMgPSBb
Y29vcmRzLCBsYXN0LCAobGFzdFswXStzaXplLGxhc3RbMV0rc2l6ZSksIChjb29yZHNbMF0rc2l6
ZSxjb29yZHNbMV0rc2l6ZSldCi0gICAgICAgICAgICAgICAgd2lkZ2V0LnBpeG1hcC5kcmF3X3Bv
bHlnb24od2lkZ2V0LmdjX3JhaW5ib3csVHJ1ZSxwb2ludHMpCi0gICAgICAgICAgICAgICAgcG9p
bnRzID0gWyhsYXN0WzBdK3NpemUsbGFzdFsxXSksIChjb29yZHNbMF0rc2l6ZSxjb29yZHNbMV0p
LCAoY29vcmRzWzBdLGNvb3Jkc1sxXStzaXplKSwgKGxhc3RbMF0sbGFzdFsxXStzaXplKV0KLSAg
ICAgICAgICAgICAgICB3aWRnZXQucGl4bWFwLmRyYXdfcG9seWdvbih3aWRnZXQuZ2NfcmFpbmJv
dyxUcnVlLHBvaW50cykKLSAgICAgICAgICAgIHdpZGdldC5waXhtYXAuZHJhd19yZWN0YW5nbGUo
d2lkZ2V0LmdjX3JhaW5ib3csIFRydWUsIGNvb3Jkc1swXSwgY29vcmRzWzFdLCBzaXplLCBzaXpl
KQotICAgICAgICB3aWRnZXQucXVldWVfZHJhdygpCisgICAgICAgICAgICAgICAgcG9pbnRzID0g
WyhsYXN0WzBdIC0gc2l6ZS8yLGxhc3RbMV0gLSBzaXplLzIpLCAoY29vcmRzWzBdIC0gc2l6ZS8y
LCBjb29yZHNbMV0gLSBzaXplLzIpLCAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY29v
cmRzWzBdICsgc2l6ZS8yLCBjb29yZHNbMV0gKyBzaXplLzIpICwgKGxhc3RbMF0gKyBzaXplLzIs
bGFzdFsxXSArIHNpemUvMildCisgICAgICAgICAgICAgICAgd2lkZ2V0LnBpeG1hcC5kcmF3X3Bv
bHlnb24oZ2MsVHJ1ZSxwb2ludHMpCisgICAgICAgICAgICAgICAgcG9pbnRzID0gWyhsYXN0WzBd
ICsgc2l6ZS8yLGxhc3RbMV0gLSBzaXplLzIpLCAoY29vcmRzWzBdICsgc2l6ZS8yLCBjb29yZHNb
MV0gLSBzaXplLzIpLCAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY29vcmRzWzBdIC0g
c2l6ZS8yLCBjb29yZHNbMV0gKyBzaXplLzIpICwgKGxhc3RbMF0gLSBzaXplLzIsbGFzdFsxXSAr
IHNpemUvMildCisgICAgICAgICAgICAgICAgd2lkZ2V0LnBpeG1hcC5kcmF3X3BvbHlnb24oZ2Ms
VHJ1ZSxwb2ludHMpCisKKworICAgICAgICBpZiBsYXN0OgorICAgICAgICAgICAgeCA9IG1pbihj
b29yZHNbMF0sIGxhc3RbMF0pCisgICAgICAgICAgICB3aWR0aCA9IG1heChjb29yZHNbMF0sIGxh
c3RbMF0pIC0geAorICAgICAgICAgICAgeSA9IG1pbihjb29yZHNbMV0sIGxhc3RbMV0pCisgICAg
ICAgICAgICBoZWlnaHQgPSBtYXgoY29vcmRzWzFdICwgbGFzdFsxXSkgLSB5CisgICAgICAgICAg
ICB3aWRnZXQucXVldWVfZHJhd19hcmVhKHgtc2l6ZSwgeS1zaXplLCB3aWR0aCtzaXplKjIsIGhl
aWdodCtzaXplKjIpICMgV2UgYWRkIHNpemUgdG8gYXZvaWQgZHJhd2luZyBkb3R0ZWQgbGluZXMK
KyAgICAgICAgZWxzZToKKyAgICAgICAgICAgIHdpZGdldC5xdWV1ZV9kcmF3KCkKKwogCiAgICAg
CisKKwogICAgIGRlZiBzcXVhcmUoc2VsZiwgd2lkZ2V0LCBldmVudCwgY29vcmRzLCB0ZW1wLCBm
aWxsKToKICAgICAgICAgIiIiRHJhdyBhIHNxdWFyZS4KIAotLSAKMS42LjYuMQoK
--000e0cd3b23c2be9900487dbff51--


More information about the Sugar-devel mailing list