/* x11_render.c -- Rendering for X11
   Copyright (C) 1993, 1994 John Harper <jsh@ukc.ac.uk>

   This file is part of Jade.

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

   Jade 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with Jade; see the file COPYING.  If not, write to
   the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */

#include "jade.h"
#include "jade_protos.h"

_PR void x11_handle_gexposures(VW *);
_PR void x11_handle_expose(VW *, XExposeEvent *);
_PR void sys_scroll_vw(VW *, long);

static Bool
gex_pred(Display *dpy, XEvent *ev, XPointer arg)
{
    return((ev->type == NoExpose) || (ev->type == GraphicsExpose));
}
void
x11_handle_gexposures(VW *vw)
{
    XEvent ev;
    do {
	POS start, end;
	unsigned int x1, y1, x2, y2;
	XIfEvent(x11_display, &ev, gex_pred, (XPointer)NULL);
	if(ev.type == NoExpose)
	    return;
	x1 = ev.xgraphicsexpose.x;
	y1 = ev.xgraphicsexpose.y;
	x2 = x1 + ev.xgraphicsexpose.width;
	y2 = y1 + ev.xgraphicsexpose.height;
	if(y2 >= vw->vw_MessageLineY)
	{
	    y2 = vw->vw_MessageLineY - 1;
	    draw_message_line(vw);
	    if(vw->vw_Message)
		redraw_message(vw, vw->vw_Message, strlen(vw->vw_Message));
	    else
		redraw_message(vw, "", 0);
	    if(y1 >= vw->vw_MessageLineY)
		continue;
	}
	start.pos_Col = ((x1 - vw->vw_XStartPix) / vw->vw_FontX)
	    + vw->vw_StartCol;
	start.pos_Line = ((y1 - vw->vw_YStartPix) / vw->vw_FontY)
	    + vw->vw_StartLine;
	end.pos_Col = (((x2 - 1)- vw->vw_XStartPix) / vw->vw_FontX)
	    + vw->vw_StartCol;
	end.pos_Line = (((y2 - 1) - vw->vw_YStartPix) / vw->vw_FontY)
	    + vw->vw_StartLine;
	redraw_rect(vw, &start, &end, FALSE);
    } while(ev.xgraphicsexpose.count > 0);
}

void
x11_handle_expose(VW *vw, XExposeEvent *ev)
{
    POS start, end;
    unsigned int x1, y1, x2, y2;
    x1 = ev->x;
    y1 = ev->y;
    x2 = x1 + ev->width;
    y2 = y1 + ev->height;
    if(y2 >= vw->vw_MessageLineY)
    {
	y2 = vw->vw_MessageLineY - 1;
	draw_message_line(vw);
	if(vw->vw_Message)
	    redraw_message(vw, vw->vw_Message, strlen(vw->vw_Message));
	else
	    redraw_message(vw, "", 0);
	if(y1 >= vw->vw_MessageLineY)
	    return;
    }
    /*
     * Special case of whole window being redrawn
     */
    if((x1 == 0) && (y1 == 0) && (x2 >= vw->vw_XEndPix)
       && (y2 >= (vw->vw_MessageLineY - 1)))
	redraw_all(vw);
    else
    {
	start.pos_Col = ((x1 - vw->vw_XStartPix) / vw->vw_FontX)
	    + vw->vw_StartCol;
	start.pos_Line = ((y1 - vw->vw_YStartPix) / vw->vw_FontY)
	    + vw->vw_StartLine;
	end.pos_Col = (((x2 - 1)- vw->vw_XStartPix) / vw->vw_FontX)
	    + vw->vw_StartCol;
	end.pos_Line = (((y2 - 1) - vw->vw_YStartPix) / vw->vw_FontY)
	    + vw->vw_StartLine;
	redraw_rect(vw, &start, &end, TRUE);
    }
}

/*
 * Scrolls the view `lines' towards line 0,
 */
void
sys_scroll_vw(VW *vw, long lines)
{
    int xsrc, ysrc, xwth, yht, xdst, ydst;
    xsrc = vw->vw_XStartPix;
    xwth = vw->vw_XWidthPix;
    xdst = vw->vw_XStartPix;
    if(lines > 0)
    {
	ysrc = vw->vw_YStartPix + (lines * vw->vw_FontY);
	yht  = vw->vw_YHeightPix - (lines * vw->vw_FontY);
	ydst = vw->vw_YStartPix;
	XCopyArea(x11_display, vw->vw_Window, vw->vw_Window,
		  vw->vw_WindowSys.ws_TextFontGC,
		  xsrc, ysrc,
		  xwth, yht,
		  xdst, ydst);
	x11_handle_gexposures(vw);
	XClearArea(x11_display, vw->vw_Window,
		   xsrc, vw->vw_YStartPix + yht,
		   xwth, ysrc - ydst,
		   False);
    }
    else if(lines < 0)
    {
	lines = 0 - lines;
	ysrc = vw->vw_YStartPix;
	yht  = vw->vw_YHeightPix - (lines * vw->vw_FontY);
	ydst = vw->vw_YStartPix + (lines * vw->vw_FontY);
	XCopyArea(x11_display, vw->vw_Window, vw->vw_Window,
		  vw->vw_WindowSys.ws_TextFontGC,
		  xsrc, ysrc,
		  xwth, yht,
		  xdst, ydst);
	x11_handle_gexposures(vw);
	XClearArea(x11_display, vw->vw_Window,
		   xsrc, ysrc,
		   xwth, ydst - ysrc,
		   False);
    }
}
