[comp.windows.x] XPutImage monochrome image to color screen

kml@sunset.cis.ufl.edu (Kevin Lahey) (04/26/89)

XPutImage appears to do some strange things when attempting to 
display monochrome images of the XYBitmap format on a display of 
depth greater than one.

I'm running X11R3 with the Purdue speedups on various Sun3s running SunOS 4.0.
I'm using twm, and trying to use the Athena widgets and the toolkit.

I create a core widget inside a viewport widget.  I set up to get Expose
events.  When I increase the size of the window or scroll it using the
scroll bars, I get the expose event, which is the correct size,
and I call XPutImage with the x, y, width and height values from the event.
The image gets updated correctly, then a vertical white band is drawn on the
image, generally near the edges of the image which have just been re-drawn.
This only happens on the color screens; the program works perfectly
on screens of depth one.  It also works fine when I am refreshing the entire
image;  for instance, if I iconify the window, then de-iconify it, the
image looks fine.  It only screws up when it is trying to update only a part
of the image.

I have a work-around -- namely, I create a pixmap, XPutImage to the
pixmap, and then do an XCopyPlane to the window.  However, this doesn't
strike me as elegant or clever;  I should like to be able to use XPutImage
to write to either color or monochrome screens.

Thanks,
Kevin
--
Kevin Lahey                  UUCP: ...gatech!uflorida!beach.cis.ufl.edu!kml
University of Florida, CIS   Internet: kml@beach.cis.ufl.edu
Whenever you find that you are on the side of the majority,
it is time to reform.  -- Mark Twain

rws@EXPO.LCS.MIT.EDU (04/26/89)

    The image gets updated correctly, then a vertical white band is drawn on
    the image, generally near the edges of the image which have just been
    re-drawn.

You are almost certainly going to have to post a simple complete program to
demonstrate the problem, either to xbugs or xpert.  There's seldom any better
way to understand what's going on.

kml@MANATEE.CIS.UFL.EDU (Kevin Lahey) (04/27/89)

/*
 * A sample program to demonstrate my XPutImage problems.  This program is
 * written using Xt, but I got the same sort of error when I used XPutImage
 * with just strictly X programming;  i.e., I don't think it is a
 * toolkit problem. 
 *
 * The problem:  the program has no trouble displaying on a monochrome screen,
 * but on a color screen, I get strange results:  the image is displayed
 * correctly, completely, but as soon as it is displayed, a vertical white
 * band is drawn on the image.  This doesn't happen every time, but mostly
 * when I change the horizontal dimensions of the window, either with the
 * scroll bars or by changing the size of the window from the window manager.
 *
 * I'm running SunOS 4.0 on Sun3s and X11R3 with Purdue speedups.
 * I tried to make this example program minimalistic while still
 * retaining the same behavior as my program.  With luck, I just missed
 * something subtle, and this isn't an X problem, although the program xim
 * hinted at this problem in the README and xviewsun contains a workaround,
 * but no comments.
 *
 * I appreciate mailed as well as posted responces:
 * Kevin Lahey                  UUCP: ...gatech!uflorida!beach.cis.ufl.edu!kml
 * University of Florida, CIS   Internet: kml@beach.cis.ufl.edu
 */

#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <X11/Shell.h>
#include <X11/Core.h>
#include <X11/Viewport.h>

void	event_proc ();

Display	*display;
Widget	shell,
	view,
	canvas;
XImage	*image;

main (argc, argv)
int	argc;
char	**argv;
{
	int			width = 400, height = 500;
	XWindowAttributes	window_attributes;
	XtAppContext		app_context;
	Arg			arg_list [4];

	XtSetArg(arg_list [0], XtNwidth, 200);
	XtSetArg(arg_list [1], XtNheight, 200);
	XtSetArg(arg_list [2], XtNallowVert, True);
	XtSetArg(arg_list [3], XtNallowHoriz, True);

	XtToolkitInitialize ();
	app_context = XtCreateApplicationContext ();
	display = XtOpenDisplay (app_context, NULL, "Sample", "xdemo",
				 NULL, 0, &argc, argv);
	shell = XtAppCreateShell ("Sample", "xdemo", 
				  applicationShellWidgetClass, 
				  display, NULL, 0);

	view = XtCreateManagedWidget ("view", viewportWidgetClass,
				      shell, arg_list, 4); 
	XtSetArg(arg_list [0], XtNwidth, width);
	XtSetArg(arg_list [1], XtNheight, height);
	canvas = XtCreateManagedWidget ("canvas", widgetClass,
					view, arg_list, 2);
	
	XtAddEventHandler (canvas, ExposureMask, False, event_proc, 0);
	XtRealizeWidget (shell);

	create_image (width, height);

	XtAppMainLoop (app_context);
}


/*
 * Create a quick and dirty sample image for display.
 */

create_image (width, height)
int	width, height;
{
	int	i,
		bytes_wide;
	char	*data;

	data = (char *) malloc (width * height);

	for (i = 0; i < width / 8; i++)
		data [i] = 204;
	for (i = 0; i < width / 8; i++)
		data [i + width / 8] = 51;
	for (i = 0; i < height / 2; i++)
		bcopy (data, data + i * width / 4, width / 4);

	image = XCreateImage (display, 
			      XDefaultVisualOfScreen(XtScreen(canvas)),
			      1, XYBitmap, 0, data, width, height,
			      8, width / 8);

}

/*
 * Handle the exposure event.
 */

void
event_proc (w, client_data, event)
Widget	w;
caddr_t	client_data;
XExposeEvent	*event;
{
	if (event->type == Expose) {
		printf ("At X = %d Y = %d width = %d height = %d\n",
			event->x, event->y, event->width, event->height);
		XPutImage (display, XtWindow(w), 
			   XDefaultGCOfScreen (XtScreen(canvas)),
			   image, event->x, event->y, event->x, event->y, 
			   event->width, event->height);
	}
}