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.