[comp.windows.x] Fix to allow Sun 3/110s to use the X windows system

cdh@bfly-vax.bbn.COM.UUCP (03/13/87)

Hi all,

The following two modifications permit the X server to work on the Sun
3/110 color display as well as on the Sun 3/50 and 3/160 monochrome and
color displays.  It should also work with the Sun 3/110 grey scale
monitor, but I have not verified that since we don't own one.

Sun 3/110 owners, rejoice and enjoy!

Carl


VERSIONS TO WHICH THIS APPLIES

* X release 10 version 3 (I'll try version 4 when I get a chance)
* Sun OS release 3.2 (you need 3.2 for the new ioctls for the 3/110)


THE PROBLEM

The reason the existing Sun library for X does not work on the Sun
3/110 is that the 3/110 frame buffer is not compatible with the frame
buffer used in 3/160 color displays.  It differs in three specific
ways:

	1) it has emulation modes of other frame buffers (monochrome
	   appears to be the only example,
	2) it has two new ioctls, FBIOGATTR and FBSIOATTR, associated
	   with setting and reading the emulation modes and the real
	   attributes of the buffer,
	2) it is a memory based frame buffer and does not have the
	   fancy rasterop hardware that the cg2 for the 3/160 does.

The strange thing about the 110 is that it *prefers* to run in
emulation mode; that's the mode it starts up in and that's the mode it
stays in unless you change it.

The other problem was that the cg4 board used in the 3/110 is the
first color board Sun has produced that uses mem_batchrop for doing
its batch raster operations.  The bw2 monochrome also uses this
operation, and this caused the following problem:

The libsun library for X optimizes the mem_batchrop and cg2_batchrop
operations for higher speed than those provided by Sun (yay!).  The
way that it does this is it defines new routines for mem_batchrop and
cg2_batchrop in text.c and lets the linker substitute these routines
into the dispatch tables contained in libpixrect.a for the specific
devices.  The bad part is that the X-optimized mem_batchrop
only deals with monochrome frame buffers and the cg2_batchrop only
deals with color displays with rasterop hardware.  The bug that
occurred in linking this in with the cg4 stuff is that the
mem_batchrop that only does monochrome got linked into the dispatch
table for the 3/110 color display.


THE SOLUTION

The solution is simple:  upon display initialization, we get the
attributes of the display.  If the display claims to be monochrome, we
try an FBIOGATTR ioctl to see if this might perchance be a 3/110
running in emulation mode (remember, it comes up in emulation mode!).
If it is, we turn off emulation, reget the frame buffer parameters and
go on our merry way.

I also renamed the X-optimized routine mem_batchrop to Xmem_batchop.
This prevents it from being put in the cg4 dispatch table and the bw2
dispatch table.  Since it is no longer linked into the bw2 dispatch
table, we have to put it in there at run time.  Therefore, if we
believe that we are a monochrome display AND the FBIOGATTR ioctl fails
(implying that we must be a garden-variety bw2 monochrome display),
then we patch the batchrop entry of the dispatch table for the bw2
display buffer to point to Xmem_batchrop and continue.


BUGS

This fix depends upon the cg4 being the only board that does
FBIOGATTRs.  Clearly this will change next time that Sun brings out
yet another type of frame buffer.  Maybe it will be retrofitted to the
old frame buffers in a later release.  All I know is that it works
properly in Sun 3.2.  I'm open to suggestions as to other ways to
determine what kind of display I'm running on independent of emulation modes.

The Sun-supplied mem_batchrop is kind of slow compared to the
monochrome and cg2-based color versions; however, this may just be a
result of using a straight memory-based frame buffer with no hardware
assist.


CODE

Here are the diffs:

-------------------
X/libsun/initial.c
-------------------

241a242,280
> 	}
> 
> 
> 	/*
> 	 * Now we do some fixing up for distinguishing the Sun 3/110 color
> 	 * display from a monochrome Sun 3/50 display.
> 	 */
> 
> 	if (fbt.fb_type == FBTYPE_SUN2BW) /* is it a BW display? */
> 	{				/* yes, might be a 3/110 in */
> 	      				/* emulation mode */
> 		struct fbgattr AttBuf;	/* for reading 3/110 attributes */
> 		if (ioctl(fd, FBIOGATTR, &AttBuf) >= 0)
> 					/* supports get attributes */
> 		{			/* must be Sun 3/110 type machine */
> 			AttBuf.sattr.emu_type = FBTYPE_SUN4COLOR;
> 		      			/* tell display not to emulate */
> 			if (ioctl(fd, FBIOSATTR, &AttBuf.sattr) < 0)
> 			{
> 				fprintf (stderr,"Can't FBIOSATTR on %s\n",
> 					 sc.scr_fbname);
> 				return (-1);
> 			}
> 			if (ioctl(fd, FBIOGTYPE, &fbt) < 0)
> 			{		/* now redo FIOGTYPE */
> 				fprintf(stderr, "Can't FBIOGTYPE on %s\n",
> 					sc.scr_fbname);
> 				return (-1);
> 			}
> 		}
> 		else			/* This is not 3/110, must be */
> 		{			/* SUN2BW; patch his mem_batchrop */
> 		      			/* to be Xmem_batchrop */
> 			extern Xmem_batchrop();
> 			extern struct pixrectops bw2_ops;
> 			struct pixrectops *ptr = &bw2_ops;
> 
> 			ptr->pro_batchrop = Xmem_batchrop;
> 		}

-----------------
X/libsun/text.c
----------------

344,345c344,345
< 
< mem_batchrop(dst, op, src, count)
---
>    
> Xmem_batchrop(dst, op, src, count)

david@sun.uucp (David DiGiacomo) (03/16/87)

In article <8703140051.AA20492@ATHENA> cdh@bfly-vax.bbn.COM writes:
>The following two modifications permit the X server to work on the Sun
>3/110 color display...
>
>Sun 3/110 owners, rejoice and enjoy!

Don't rejoice yet -- the given changes are not sufficient to get X
running properly in color on the 3/110!

>The strange thing about the 110 is that it *prefers* to run in
>emulation mode; that's the mode it starts up in and that's the mode it
>stays in unless you change it.

This is not too strange -- it has to default to bw2 emulation mode
because there is no way to go back in time and insert mode-changing code
in old binaries.  It is *not* necessary to change the the emulation mode
to run color applications, so it should be left alone unless you have a
very good reason.

>The libsun library for X optimizes the mem_batchrop and cg2_batchrop
>operations for higher speed than those provided by Sun (yay!).  The
>way that it does this is it defines new routines for mem_batchrop and
>cg2_batchrop in text.c and lets the linker substitute these routines
>into the dispatch tables contained in libpixrect.a for the specific
>devices.

Partially correct.  The reason for the modified mem_batchrop was better
performance, but the X version of cg2_batchrop has *different semantics*
than the pixrect library version.

>THE SOLUTION
>
>The solution is simple:  upon display initialization, we get the
>attributes of the display.  If the display claims to be monochrome, we
>try an FBIOGATTR ioctl to see if this might perchance be a 3/110
>running in emulation mode (remember, it comes up in emulation mode!).
>If it is, we turn off emulation, reget the frame buffer parameters and
>go on our merry way.

This solution is too complicated.  There is no need to do any frame
buffer ioctls in InitDisplay since all the information needed is encoded
in the pixrect "PixRect".  Here is the code I have been using:

	Display = pw_open(vsdev);
	PixRect = Display->pw_pixrect;
	info->id = PixRect->pr_depth > 1 ? XDEV_SUN2COLOR : XDEV_SUN2BW;
	info->planes = PixRect->pr_depth;
	info->entries = 1 << PixRect->pr_depth;
	if (PixRect->pr_depth == 1)
		pw_reversevideo(Display,0,1);

(The info->id isn't used for anything so it doesn't have to be exactly
right.)

>I also renamed the X-optimized routine mem_batchrop to Xmem_batchop.
>This prevents it from being put in the cg4 dispatch table and the bw2
>dispatch table.  Since it is no longer linked into the bw2 dispatch
>table, we have to put it in there at run time...

I think you will find the performance of the mem_batchrop in the release
3.2 and later pixrect library adequate.  However, if you still want to
patch in the hacked X version do it this way:

	if (PixRect->pr_depth == 1 && !MP_NOTMPR(PixRect))
		Pixrect->pr_ops->pro_batchrop = Xmem_batchrop;

>BUGS

The most important bug was omitted -- it doesn't work!  The cursor and
text code relies on the modified semantics of the supplied cg2_batchrop.
The batchrop functions in the pixrect library (including mem_batchrop)
follow (documented) pixrect semantics.

-- 
David DiGiacomo  {decvax, ihnp4, ucbvax}!sun!david  david@sun.arpa
Sun Microsystems, Mt. View, CA  (415) 691-7495

cdh@BFLY-VAX.BBN.COM (03/17/87)

David,

Sorry to hear you don't think my changes are sufficient.  Note that
they do work here on our 110 under 3.2.

> This is not too strange -- it has to default to bw2 emulation mode
> because there is no way to go back in time and insert mode-changing code
> in old binaries.  It is *not* necessary to change the the emulation mode
> to run color applications, so it should be left alone unless you have a
> very good reason.

X does have a very good reason; it wants to do a FBIOGTYPE to find out
what kind of display it is running on.  The 3/110 hands back 2 and a
depth of 1, which means that all the following setup will believe that
it is running on a monochrome display.  The only way I've found to
make FBIOGTYPE return correct values for the display type is to tell
it to change the emulation mode to 8.  If you have other ways that are
nicely device independent, it would be nice to hear them.

> This solution is too complicated.  There is no need to do any frame
> buffer ioctls in InitDisplay since all the information needed is encoded
> in the pixrect "PixRect".  Here is the code I have been using:
> 	Display = pw_open(vsdev);
> 	PixRect = Display->pw_pixrect;
> 	info->id = PixRect->pr_depth > 1 ? XDEV_SUN2COLOR : XDEV_SUN2BW;
>	info->planes = PixRect->pr_depth;
> 	info->entries = 1 << PixRect->pr_depth;
>	if (PixRect->pr_depth == 1)
>		pw_reversevideo(Display,0,1);
> 
> (The info->id isn't used for anything so it doesn't have to be exactly
> right.)

Perhaps I'm just slow, but this doesn't look like it will work to me.  
The PixRect->pr_depth I got returned without the ioctls was always 1
on the 3/110.  Therefore, the code you represent would just set the
display up so that it was a true monochrome display.  Not exactly what
you want.

> The most important bug was omitted -- it doesn't work!  The cursor and
> text code relies on the modified semantics of the supplied cg2_batchrop.
> The batchrop functions in the pixrect library (including mem_batchrop)
> follow (documented) pixrect semantics.

Perhaps you can point out to me what doesn't work.  I've been using my
mods here and not had any real trouble with either text or cursor
displays.  (I take that back; the foreground and backgrounds for text
have not been perfect, but I've assumed that was my own clumsiness in
setting them up).

I do apologize to people if my proposed solution was incorrect.  Our
3/110 was delivered with *NO* documentation on the display buffer and
with no indication that it was incompatible with the cg2.  When X
didn't run on it, we were faced with having it always be monochrome or
doing something to make it work.  I did something to make it work, and
thought other people might benefit.  I will gladly accept simpler or
more elegant solutions provided that someone has gone to the time and
effort to test them before posting.

Carl