This is SqViewMegaPixel.m in view mode; [Download] [Up]
/******************************************************************************
FILE
SqViewMegaPixel.m
DESCRIPTION
NeXTstep user Interface for Squeak.
This view is a subclass of SqView that map the whole NeXT MegaPixel Display
screen. It is faster than SqView since it directly access the video buffer,
but it's activated only in full screen mode.
AUTHOR
<PJB> Pascal J. Bourguignon
MODIFICATIONS
1998/07/03 <PJB> Creation.
LEGAL
Copyright Pascal J. Bourguignon 1998 - 1998
This program is free software; you can redistribute it and/or
modify it under the terms of the version 2 of the GNU General Public
License as published by the Free Software Foundation.
This program 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
hereafter for more details.
******************************************************************************/
#import "SqViewMegaPixel.h"
#import "SqApplication.h"
#import <string.h>
#ifdef mc68000
#define SqViewMegaPixel_isPossible
#else
#undef SqViewMegaPixel_isPossible
#endif
#ifdef SqViewMegaPixel_isPossible
#import <bsd/dev/m68k/video.h>
#endif
#import <driverkit/displayDefs.h> // shamelessly reusing IODisplayInfo struct.
#define debug(a)
@implementation SqViewMegaPixel
static IODisplayInfo* displayInfo=0;
/*
int width;
int height;
int totalWidth;
int rowBytes;
int refreshRate; // unused here.
void* frameBuffer;
IOBitsPerPixel bitsPerPixel; // assumed to be IO_2BitsPerPixel.
IOColorSpace colorSpace; // assumed to be IO_OneIsBlackColorSpace.
IOPixelEncoding pixelEncoding; // assumed to be "KK".
unsigned int flags; // unused here.
void* parameters; // unused here.
*/
+initialize
{
#ifdef SqViewMegaPixel_isPossible
static IODisplayInfo displayInfoRec;
int fd=open("/dev/vid0",O_RDWR,0);
int vid_base=0;
if(fd>=0){
if(ioctl(fd,DKIOCGADDR,&vid_base)<0){
vid_base=0;
}
close(fd); // May be we should not close it now?
}
if(vid_base==0){
displayInfo=0;
}else{
displayInfoRec.width=VIDEO_W;
displayInfoRec.height=VIDEO_H;
/*
We cannot use VIDEO_MW because dma_chip is only available
to kernel code. We should do a loadable driver to access and
publish it. May be these data are available thru the
DKIOCGFBINFO ioctl, but then, it's not documented anywhere.
That's the joys of proprietary software. LONG LIFE GNU & LINUX!
*/
displayInfoRec.totalWidth=VIDEO_W;
displayInfoRec.rowBytes=VIDEO_W/NPPB;
displayInfoRec.refreshRate=0;
displayInfoRec.frameBuffer=(void*)vid_base;
displayInfoRec.bitsPerPixel=IO_2BitsPerPixel;
displayInfoRec.colorSpace=IO_OneIsWhiteColorSpace;
strcpy(displayInfoRec.pixelEncoding,"KK");
displayInfoRec.flags=0;
displayInfoRec.parameters=0;
displayInfo=&(displayInfoRec);
}
#else
displayInfo=0;
#endif
return(self);
}//initialize;
+(BOOL)thereIsTheSlightestChanceOfHavingAMegaPixelDisplay
{
#ifdef SqViewMegaPixel_isPossible
/*
Since there is no documented way to learn what kind of
buffer /dev/vid0:DKIOCGADDR will return, let's be extremely
conservative.
*/
const NXScreen* screens;
int screen_count;
if(displayInfo==0){
return(NO);
}
[NXApp getScreens:&screens count:&screen_count];
if(screen_count>1){
// Ok, one of them may be a MegaPixel Display, but in doubt...
return(NO);
}
if(screens[0].depth!=NX_TwoBitGrayDepth){
return(NO);
}
if((screens[0].screenBounds.size.width!=displayInfo->width)
||(screens[0].screenBounds.size.height!=displayInfo->height)){
return(NO);
}
// Ok, let's reluctantly return YES.
return(YES);
#else
return(NO);
#endif
}//thereIsTheSlightestChanceOfHavingAMegaPixelDisplay;
-(id)initFrame:(const NXRect*)frameRect
{
self=[super initFrame:frameRect];
if(self!=0){
megaPixelIsActive=NO;
}
return(self);
}//initFrame:;
-(void)setColorEntry:(int)i red:(int)r green:(int)g blue:(int)b
{
[super setColorEntry:i red:r green:g blue:b];
mp_colorMap2Gray[i]=3-colorMap2Gray[i];
}//setColorEntry:red:green:blue:;
-(void)initializeSqueakColorMap
{
mp_Two_to_Two=(unsigned char*)malloc(sizeof(unsigned char)*256);
mp_colorMap2Gray=(unsigned char*)malloc(sizeof(unsigned char)*256);
{
unsigned char map[]={
/*transparent:*/ 0x01,
/*black:*/ 0x03,
/*white:*/ 0x00,
/*half gray:*/ 0x02};
int i,j,k,l;
for(i=0;i<4;i++){
for(j=0;j<4;j++){
for(k=0;k<4;k++){
for(l=0;l<4;l++){
mp_Two_to_Two[(i<<6)|(j<<4)|(k<<2)|l]=
(map[i]<<6)|(map[j]<<4)|(map[k]<<2)|map[l];
}
}
}
}
}
[super initializeSqueakColorMap];
}//initializeSqueakColorMap;
-(id)free
{
return([super free]);
}//free;
-(void)redisplayAfterUnhide
{
if(megaPixelIsActive){
[self updateWholeDisplay];
}else{
[super redisplayAfterUnhide];
}
}//redisplayAfterUnhide;
-(int)ioForceDisplayUpdate
{
if(!megaPixelIsActive){
return([super ioForceDisplayUpdate]);
}
[NXApp ioProcessEvents];
return(0);
}//ioForceDisplayUpdate;
-(int)ioSetFullScreen:(int)fullScreen
{
[super ioSetFullScreen:fullScreen];
if(displayInfo!=0){
megaPixelIsActive=isFullScreen;
}else{
megaPixelIsActive=NO;
}
return(0);
}//ioSetFullScreen:;
-(void)copyPixels_1_to_2:(void*)srcBits
srcPixelWidth:(int)srcPixelWidth
left:(int)left right:(int)right
top:(int)top bottom:(int)bottom
{
debug(int dummy=fprintf(stderr,"%s\n",sel_getName(_cmd));\
int fummy=fflush(stderr);)
static unsigned char One_to_Two[16]={
0x00,0x03,0x0c,0x0f,
0x30,0x33,0x3c,0x3f,
0xc0,0xc3,0xcc,0xcf,
0xf0,0xf3,0xfc,0xff
};
unsigned char* sBits=srcBits;
unsigned char* dBits=displayInfo->frameBuffer;
int dRow;
int sRowSlots;
int minY;
int maxY;
int minX;
int maxX;
int srcY;
if((srcPixelWidth%8)!=0){
fprintf(stderr,"It would be better to have srcPixelWidth%%8==0 "
"instead of %d.\n",srcPixelWidth);
return;
}
sRowSlots=srcPixelWidth/8;
left=left&(~7);
right=(right+7)&(~7);
minY=top*sRowSlots;
maxY=bottom*sRowSlots;
minX=left/8;
maxX=right/8;
PShidecursor();NXPing();
dBits=dBits+(top*displayInfo->rowBytes)+(left/4); // assuming 2-bpp.
dRow=0;
for(srcY=minY;srcY<maxY;srcY+=sRowSlots){
int maxXY=srcY+maxX;
int srcX;
int i=dRow;
for(srcX=srcY+minX;srcX<maxXY;srcX++){
unsigned char src=sBits[srcX];
dBits[i++]=One_to_Two[src>>4];
dBits[i++]=One_to_Two[src&0xf];
}
dRow+=displayInfo->rowBytes;
}
PSshowcursor();
}//copyPixels_1_to_2:srcPixelWidth:left:right:top:bottom:;
-(void)copyPixels_2_to_2:(void*)srcBits
srcPixelWidth:(int)srcPixelWidth
left:(int)left right:(int)right
top:(int)top bottom:(int)bottom
{
debug(int dummy=fprintf(stderr,"%s\n",sel_getName(_cmd));\
int fummy=fflush(stderr);)
unsigned char* sBits=srcBits;
unsigned char* dBits=displayInfo->frameBuffer;
int dRow;
unsigned char* map=mp_Two_to_Two;
int sRowSlots;
int minY;
int maxY;
int minX;
int maxX;
int srcY;
if((srcPixelWidth%4)!=0){
fprintf(stderr,"It would be better to have srcPixelWidth%%4==0 "
"instead of %d.\n",srcPixelWidth);
return;
}
sRowSlots=srcPixelWidth/4;
left=left&(~3);
right=(right+3)&(~3);
minY=top*sRowSlots;
maxY=bottom*sRowSlots;
minX=left/4;
maxX=right/4;
PShidecursor();NXPing();
dBits=dBits+(top*displayInfo->rowBytes)+(left/4); // assuming 2-bpp.
dRow=0;
for(srcY=minY;srcY<maxY;srcY+=sRowSlots){
int maxXY=srcY+maxX;
int srcX;
int i=dRow;
for(srcX=srcY+minX;srcX<maxXY;srcX++){
dBits[i++]=map[sBits[srcX]];
}
dRow+=displayInfo->rowBytes;
}
PSshowcursor();
}//copyPixels_2_to_2:srcPixelWidth:left:right:top:bottom:;
-(void)copyPixels_8_to_2:(void*)srcBits
srcPixelWidth:(int)srcPixelWidth
left:(int)left right:(int)right
top:(int)top bottom:(int)bottom
{
debug(int dummy=fprintf(stderr,"%s\n",sel_getName(_cmd));\
int fummy=fflush(stderr);)
unsigned char* sBits=srcBits;
unsigned char* dBits=displayInfo->frameBuffer;
int dRow;
unsigned char* map=mp_colorMap2Gray;
int sRowSlots;
int minY;
int maxY;
int minX;
int maxX;
int srcY;
sRowSlots=srcPixelWidth;
left=left&(~3);
right=(right+3)&(~3);
minY=top*sRowSlots;
maxY=bottom*sRowSlots;
minX=left;
maxX=right;
PShidecursor();NXPing();
dBits=dBits+(top*displayInfo->rowBytes)+(left/4); // assuming 2-bpp.
dRow=0;
for(srcY=minY;srcY<maxY;srcY+=sRowSlots){
int maxXY=srcY+maxX;
int srcX;
int i=dRow;
for(srcX=srcY+minX;srcX<maxXY;srcX+=4){
dBits[i++]=(map[sBits[srcX]]<<6)
|(map[sBits[srcX+1]]<<4)
|(map[sBits[srcX+2]]<<2)
|(map[sBits[srcX+3]]);
}
dRow+=displayInfo->rowBytes;
}
PSshowcursor();
}//copyPixels_8_to_2:srcPixelWidth:left:right:top:bottom:;
-(int)ioShowDisplayBitsIndex:(int)bInd
width:(int)w height:(int)h depth:(int)d
affectedLeft:(int)l affectedRight:(int)r
affectedTop:(int)t affectedBottom:(int)b
{
debug(int dummy=fprintf(stderr,"%s\n",sel_getName(_cmd));\
int fummy=fflush(stderr);)
debug(int dumm2=fprintf(stderr,"%22x%6d%7d%6d%13d%14d%12d%15d\n",\
bitsIndex,width,height,depth,\
left,right,top,bottom);)
if(!megaPixelIsActive){
return([super ioShowDisplayBitsIndex:bInd
width:w height:h depth:d
affectedLeft:l affectedRight:r
affectedTop:t affectedBottom:b]);
}
if(![[self window]isVisible]){
return(0);
}
if((r<=l)||(b<=t)){
return(1);
}
lastBitsIndex=bInd;
lastWidth=w;
lastHeight=h;
lastDepth=d;
NX_DURING
switch(d){
case 1:
[self copyPixels_1_to_2:(void*)bInd srcPixelWidth:w
left:l right:r top:t bottom:b];
break;
case 2:
[self copyPixels_2_to_2:(void*)bInd srcPixelWidth:w
left:l right:r top:t bottom:b];
break;
case 8:
[self copyPixels_8_to_2:(void*)bInd srcPixelWidth:w
left:l right:r top:t bottom:b];
break;
default:
[super ioShowDisplayBitsIndex:bInd
width:w height:h depth:d
affectedLeft:l affectedRight:r
affectedTop:t affectedBottom:b];
}
NX_HANDLER
fprintf(stderr,"An exception is caught in [%s %s]: "
"code=%d data1=0x%x data2=0x%x\n",
"SqViewMegaPixel",sel_getName(_cmd),NXLocalHandler.code,
(unsigned int)NXLocalHandler.data1,
(unsigned int)NXLocalHandler.data2);
NX_ENDHANDLER
return(0);
}//ioShowDisplayBitsIndex:width:affectedLeft:affectedRight:...;
@end // SqViewMegaPixel.
/*** SqViewMegaPixel.m / Thu Aug 27 23:20:49 MET 1998 / PJB ***/
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.