John Levon wrote:

> On Tue, May 04, 2004 at 10:05:24AM +0100, Angus Leeming wrote:
> 
>> enabled XWorkArea to use the conventional X11 drawing model. (John,
>> do you have it archived, else I'll have to trawl the archives to
>> dig it out.)
> 
> Sorry, long since lost

No worries. I found 'em. Attached are patches against current cvs of
both xforms and lyx. Would you cast your eagle eye over them?

Some sample lyxerr messages, where 'expose' is XScreen::expose and
'paint' is XWorkArea::paint, invoked from the
XWorkArea::work_area_handler which is in turn called by the XForms
library. I'm particularly happy with '27x3+133+412'

expose 633x752+0+0
paint 633x752+0+0
work_area_handler, recevied X11 expose event 633x752+0+0
paint 633x752+0+0
work_area_handler, recevied X11 expose event 160x3+0+412
paint 160x3+0+412
work_area_handler, recevied X11 expose event 690x885+0+0
paint 690x885+0+0
work_area_handler, recevied X11 expose event 27x3+133+412
paint 27x3+133+412
work_area_handler, recevied X11 expose event 137x3+0+412
paint 137x3+0+412
work_area_handler, recevied X11 expose event 371x473+0+412

Note, however, that clicking anywhere on the screen still results in:
expose 633x752+0+0
which seems ridiculous. I guess, hwoever, that this is the same for
all frontends?

Also the flicker is still painfully visible.

-- 
Angus
Index: src/frontends/xforms/XWorkArea.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/frontends/xforms/XWorkArea.C,v
retrieving revision 1.44
diff -u -p -r1.44 XWorkArea.C
--- src/frontends/xforms/XWorkArea.C	4 May 2004 09:05:21 -0000	1.44
+++ src/frontends/xforms/XWorkArea.C	4 May 2004 11:18:36 -0000
@@ -172,8 +172,9 @@ of the XForms frontend. Angus 4 May, 200
 	XGCValues val;
 
 	val.function = GXcopy;
+	val.graphics_exposures = false;
 	copy_gc = XCreateGC(fl_get_display(), RootWindow(fl_get_display(), 0),
-			    GCFunction, &val);
+			    GCFunction | GCGraphicsExposures, &val);
 }
 
 
@@ -185,15 +186,17 @@ XWorkArea::~XWorkArea()
 }
 
 
-void XWorkArea::redraw(int width, int height)
+void XWorkArea::updateGeometry(int width, int height)
 {
 	static int cur_width = -1;
 	static int cur_height = -1;
 
 	if (cur_width == width && cur_height == height && workareapixmap) {
+#if 0
 		XCopyArea(fl_get_display(),
 			  getPixmap(), getWin(), copy_gc,
 			  0, 0, width, height, xpos(), ypos());
+#endif
 		return;
 	}
 
@@ -219,6 +222,19 @@ void XWorkArea::redraw(int width, int he
 }
 
 
+void XWorkArea::paint(int x, int y, int w, int h)
+{
+//	lyxerr[Debug::WORKAREA] << "Workarea event: paint"
+	lyxerr << "paint " << w << 'x' << h
+		<< '+' << x << '+' << y << endl;
+	updateGeometry(workWidth(), workHeight());
+	XCopyArea(fl_get_display(),
+		  getPixmap(), getWin(),
+		  copy_gc, x, y, w, h,
+		  work_area->x + x, work_area->y + y);
+}
+
+
 void XWorkArea::setScrollbarParams(int height, int pos, int line_height)
 {
 	// we need to cache this for scroll_cb
@@ -289,12 +305,27 @@ int XWorkArea::work_area_handler(FL_OBJE
 
 	switch (event) {
 
-	case FL_DRAW:
+	case FL_DRAW: {
 		if (!area->work_area || !area->work_area->form->visible)
 			return 1;
-		lyxerr[Debug::WORKAREA] << "Workarea event: DRAW" << endl;
-		area->redraw(area->workWidth(), area->workHeight());
+
+		if (ev) {
+//			lyxerr[Debug::WORKAREA]
+			lyxerr << "work_area_handler, recevied X11 "
+				"expose event "
+			       << ev->xexpose.width << 'x'
+			       << ev->xexpose.height << '+'
+			       << ev->xexpose.x << '+'
+			       << ev->xexpose.y << endl;
+
+			area->paint(ev->xexpose.x, ev->xexpose.y,
+				    ev->xexpose.width, ev->xexpose.height);
+		} else
+			area->paint(0, 0,
+				    area->workWidth(), area->workHeight());
+		
 		break;
+	}
 
 	case FL_PUSH:
 		if (!ev || ev->xbutton.button == 0) break;
Index: src/frontends/xforms/XWorkArea.h
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/frontends/xforms/XWorkArea.h,v
retrieving revision 1.25
diff -u -p -r1.25 XWorkArea.h
--- src/frontends/xforms/XWorkArea.h	28 Apr 2004 17:22:05 -0000	1.25
+++ src/frontends/xforms/XWorkArea.h	4 May 2004 11:18:37 -0000
@@ -65,7 +65,10 @@ public:
 private:
 	/// generate the pixmap, and copy backing pixmap to it,
 	/// and send resize event if needed
-	void redraw(int, int);
+	void updateGeometry(int, int);
+
+	///
+	void paint(int x, int y, int w, int h);
 
 	/// GC used for copying to the screen
 	GC copy_gc;
Index: src/frontends/xforms/xscreen.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/frontends/xforms/xscreen.C,v
retrieving revision 1.24
diff -u -p -r1.24 xscreen.C
--- src/frontends/xforms/xscreen.C	15 Sep 2003 15:20:19 -0000	1.24
+++ src/frontends/xforms/xscreen.C	4 May 2004 11:18:37 -0000
@@ -153,13 +153,18 @@ void XScreen::removeCursor()
 
 void XScreen::expose(int x, int y, int w, int h)
 {
-	lyxerr[Debug::GUI] << "expose " << w << 'x' << h
+//	lyxerr[Debug::GUI] << "expose " << w << 'x' << h
+	lyxerr << "expose " << w << 'x' << h
 		<< '+' << x << '+' << y << endl;
-	XCopyArea(fl_get_display(),
-		  owner_.getPixmap(),
-		  owner_.getWin(),
-		  gc_copy,
-		  x, y, w, h,
-		  x + owner_.xpos(),
-		  y + owner_.ypos());
+	XEvent ev;
+ 
+	ev.type = Expose;
+	ev.xexpose.window = owner_.getWin();
+	ev.xexpose.x = x;
+	ev.xexpose.y = y;
+	ev.xexpose.width = w;
+	ev.xexpose.height = h;
+	ev.xexpose.count = 0;
+ 
+	XSendEvent(fl_get_display(), owner_.getWin(), False, 0, &ev);
 }
Index: ChangeLog
===================================================================
RCS file: /cvsroot/xforms/xforms/ChangeLog,v
retrieving revision 1.93
diff -u -p -r1.93 ChangeLog
--- ChangeLog	3 May 2004 12:00:28 -0000	1.93
+++ ChangeLog	4 May 2004 09:59:43 -0000
@@ -1,3 +1,23 @@
+2004-05-04  Angus Leeming  <[EMAIL PROTECTED]>
+
+	The original patch, posted to the xforms list on June 21, 2002,
+	appears to have got lost. Archived here:
+	http://bob.usuhs.mil/mailserv/list-archives/xforms-archive/0285.html
+
+	Pass the associated (XEvent * xev) to fl_handle_object on an FL_DRAW
+	event. This XEvent * is not used at all by any of xforms' "native"
+	widgets, but an FL_FREE object is able to make use of this info to
+	redraw only the part of the window that has changed. 
+ 
+	* forms.c (fl_handle_form): pass the XEvent on an FL_DRAW event.
+
+	* objects.c (redraw_marked): pass the XEvent to fl_handle_object.
+	(mark_for_redraw): new, static function containing all but the
+	'redraw_marked' call of the original fl_redraw_form.
+	(fl_redraw_form): refactored code. Functionality unchanged.
+	(fl_redraw_form_using_xevent): identical to fl_redraw_form, except
+	that it passes the XEvent on to redraw_marked.
+
 2004-05-02  Angus Leeming  <[EMAIL PROTECTED]>
 
 	* lib/flresource.c (get_command_name): squash valgrind warning
Index: lib/forms.c
===================================================================
RCS file: /cvsroot/xforms/xforms/lib/forms.c,v
retrieving revision 1.10
diff -u -p -r1.10 forms.c
--- lib/forms.c	21 Nov 2003 13:23:23 -0000	1.10
+++ lib/forms.c	4 May 2004 09:59:45 -0000
@@ -54,6 +54,8 @@ static int do_x_only;
 
 static int fl_XLookupString(XKeyEvent *, char *, int, KeySym *);
 
+void fl_redraw_form_using_xevent(FL_FORM *, int, XEvent *);
+
 
 #define SHORT_PAUSE          10	/* check_form wait             */
 
@@ -1372,7 +1374,7 @@ fl_handle_form(FL_FORM * form, int event
     {
 
     case FL_DRAW:		/* form must be redrawn */
-	fl_redraw_form(form);
+	fl_redraw_form_using_xevent(form, key, xev);
 	break;
     case FL_ENTER:		/* Mouse did enter the form */
 	fl_mouseobj = obj;
Index: lib/objects.c
===================================================================
RCS file: /cvsroot/xforms/xforms/lib/objects.c,v
retrieving revision 1.9
diff -u -p -r1.9 objects.c
--- lib/objects.c	9 Sep 2003 00:28:25 -0000	1.9
+++ lib/objects.c	4 May 2004 09:59:46 -0000
@@ -1270,7 +1270,7 @@ object_is_clipped(FL_OBJECT * ob)
  */
 
 static void
-redraw_marked(FL_FORM * form)
+redraw_marked(FL_FORM * form, int key, XEvent * xev)
 {
     FL_OBJECT *ob;
 
@@ -1309,7 +1309,7 @@ redraw_marked(FL_FORM * form)
 		fl_set_text_clipping(ob->x, ob->y, ob->w, ob->h);
 	    }
 
-	    fl_handle_object(ob, FL_DRAW, 0, 0, 0, 0);
+	    fl_handle_object(ob, FL_DRAW, 0, 0, key, xev);
 
 	    if ((ob->objclass == FL_FREE || ob->clip) && !fl_perm_clip)
 	    {
@@ -1354,26 +1354,40 @@ fl_redraw_object(FL_OBJECT * obj)
 
     /* if obj is a child object and the parent is not visible, do nothing */
     if (obj->visible && (!obj->is_child || obj->parent->visible))
-	redraw_marked(obj->form);
+	redraw_marked(obj->form, 0, 0);
 
 }
 
-/* Draws a form */
-void
-fl_redraw_form(FL_FORM * form)
+/* Marks all objects for redraw */
+static void
+mark_for_redraw(FL_FORM * form)
 {
     FL_OBJECT *ob;
 
     if (form == NULL)
     {
-	fl_error("fl_redraw_form", "Drawing NULL form.");
+	fl_error("mark_for_redraw", "Drawing NULL form.");
 	return;
     }
 
     for (ob = form->first; ob; ob = ob->next)
 	ob->redraw = 1;
+}
 
-    redraw_marked(form);
+/* Draws a form */
+void
+fl_redraw_form(FL_FORM * form)
+{
+    mark_for_redraw(form);
+    redraw_marked(form, 0, 0);
+}
+
+/* Draws a form */
+void
+fl_redraw_form_using_xevent(FL_FORM * form, int key, XEvent * xev)
+{
+    mark_for_redraw(form);
+    redraw_marked(form, key, xev);
 }
 
 /* Disables drawing of form */
@@ -1407,7 +1421,7 @@ fl_unfreeze_form(FL_FORM * form)
     form->frozen--;
 
     if (form->frozen == 0)
-	redraw_marked(form);
+	redraw_marked(form, 0, 0);
 }
 
 /*-----------------------------------------------------------------------

Reply via email to