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);
}
/*-----------------------------------------------------------------------