Fixing our multiple report pixel transfer.
authorsl
Thu, 22 May 2014 21:32:45 +0200
changeset 23d4e164906a1b
parent 22 efa6ff02287c
child 24 c6b5c552980a
Fixing our multiple report pixel transfer.
Implementing support for off screen mode which is now the default.
On screen mode is there for debug pruposes.
inc/FutabaVfd.h
inc/MainWindow.h
src/FutabaVfd.cpp
src/test.cpp
     1.1 --- a/inc/FutabaVfd.h	Thu May 22 16:46:50 2014 +0200
     1.2 +++ b/inc/FutabaVfd.h	Thu May 22 21:32:45 2014 +0200
     1.3 @@ -30,7 +30,6 @@
     1.4  const unsigned short KFutabaProductIdGP1212A01A = 0x100C;
     1.5  const unsigned short KFutabaProductIdGP1212A02A = 0x1013; //Or is it 0x1015
     1.6  
     1.7 -
     1.8  //typedef struct hid_device_info HidDeviceInfo;
     1.9  
    1.10  /**
    1.11 @@ -44,7 +43,6 @@
    1.12  	};
    1.13  
    1.14  
    1.15 -
    1.16  /**
    1.17  Define a generic Futaba VFD command.
    1.18  */
    1.19 @@ -73,8 +71,8 @@
    1.20  class FutabaVfd : public HidDevice
    1.21  	{
    1.22  public:
    1.23 -	virtual int MinBrightness()=0;
    1.24 -	virtual int MaxBrightness()=0;
    1.25 +	virtual int MinBrightness() const=0;
    1.26 +	virtual int MaxBrightness() const=0;
    1.27  	virtual void SetBrightness(int aBrightness)=0;
    1.28  	virtual void Clear()=0;
    1.29  	};
    1.30 @@ -85,10 +83,11 @@
    1.31  class FutabaGraphicVfd : public FutabaVfd
    1.32  	{
    1.33  public:
    1.34 -	virtual int WidthInPixels()=0;
    1.35 -	virtual int HeightInPixels()=0;
    1.36 -	virtual void SetPixel(int aX, int aY, bool aOn)=0;
    1.37 -	virtual void SetAllPixels(bool aOn)=0;
    1.38 +	virtual int WidthInPixels() const=0;
    1.39 +	virtual int HeightInPixels() const=0;
    1.40 +	virtual void SetPixel(unsigned char aX, unsigned char aY, bool aOn)=0;
    1.41 +	virtual void SetAllPixels(unsigned char aOn)=0;
    1.42 +	virtual int FrameBufferSizeInBytes() const=0;
    1.43  	};
    1.44  
    1.45  /**
    1.46 @@ -98,8 +97,8 @@
    1.47  	{
    1.48  public:
    1.49  	//From FutabaVfd
    1.50 -	virtual int MinBrightness(){return 0;};
    1.51 -	virtual int MaxBrightness(){return 5;};
    1.52 +	virtual int MinBrightness() const {return 0;};
    1.53 +	virtual int MaxBrightness() const {return 5;};
    1.54  	};
    1.55  
    1.56  /**
    1.57 @@ -110,26 +109,33 @@
    1.58  class GP1212A01A : public GP1212XXXX
    1.59  	{
    1.60  public:
    1.61 +	GP1212A01A();
    1.62 +	//
    1.63  	int Open();
    1.64  	//From FutabaGraphicVfd
    1.65 -	virtual int WidthInPixels(){return 256;};
    1.66 -	virtual int HeightInPixels(){return 64;};
    1.67 -	virtual void SetPixel(int aX, int aY, bool aOn);
    1.68 -	virtual void SetAllPixels(bool aOn);
    1.69 +	virtual int WidthInPixels() const {return 256;};
    1.70 +	virtual int HeightInPixels() const {return 64;};
    1.71 +	virtual void SetPixel(unsigned char aX, unsigned char aY, bool aOn);
    1.72 +	virtual void SetAllPixels(unsigned char aPattern);
    1.73 +	virtual int FrameBufferSizeInBytes() const {return 2048;}; //256*64/8
    1.74  	//From FutabaVfd
    1.75  	virtual void SetBrightness(int aBrightness);
    1.76  	virtual void Clear();
    1.77  
    1.78  	//Specific to GP1212A01A
    1.79 -	void SetPixelBlock(int aX, int aY, int aHeight, int aSize, unsigned char aValue);
    1.80 -    void SetPixelBlock(int aX, int aY, int aHeight, int aSize, unsigned char* aPixels);
    1.81 +	void SetPixelBlock(unsigned char aX, unsigned char aY, int aHeight, int aSize, unsigned char aValue);
    1.82 +    void SetPixelBlock(unsigned char aX, unsigned char aY, int aHeight, int aSize, unsigned char* aPixels);
    1.83      //
    1.84 -	void SetDisplayPosition(int aX, int aY);
    1.85 +	void SetDisplayPosition(unsigned char aX, unsigned char aY);
    1.86 +	void SwapBuffers();
    1.87      //
    1.88      void RequestId();
    1.89      void RequestFirmwareRevision();
    1.90      void RequestPowerSupplyStatus();
    1.91 -
    1.92 +	//
    1.93 +	void ToggleOffScreenMode();
    1.94 +	bool OffScreenMode() const {return iOffScreenMode;};
    1.95 +	
    1.96  private:
    1.97  	enum DW
    1.98  		{
    1.99 @@ -137,13 +143,21 @@
   1.100          DW2=0xD0
   1.101  		};
   1.102  
   1.103 -	void SetDisplayPosition(DW aDw,int aX, int aY);
   1.104 +	void SetDisplayPosition(DW aDw,unsigned char aX, unsigned char aY);
   1.105 +	unsigned char OffScreenY() const;
   1.106 +	void SendClearCommand();
   1.107 +	void OffScreenTranslation(unsigned char& aX, unsigned char& aY);
   1.108  
   1.109  private:
   1.110 +	unsigned char iDisplayPositionX;
   1.111 +	unsigned char iDisplayPositionY;
   1.112 +	///Off screen mode is the recommended default settings to avoid tearing.
   1.113 +	///Though turning it off can be useful for debugging
   1.114 +	bool iOffScreenMode;
   1.115  	///
   1.116  	//FutabaVfdReport iReport;
   1.117  	///
   1.118 -	unsigned char iPixelBuffer[256][128];
   1.119 +	//unsigned char iPixelBuffer[256][128];
   1.120  	};
   1.121  
   1.122  
     2.1 --- a/inc/MainWindow.h	Thu May 22 16:46:50 2014 +0200
     2.2 +++ b/inc/MainWindow.h	Thu May 22 21:32:45 2014 +0200
     2.3 @@ -41,6 +41,7 @@
     2.4          ID_FUTABA_RESET_PIXEL,
     2.5          ID_FUTABA_SET_ALL_PIXELS,
     2.6          ID_FUTABA_SET_DISPLAY_POSITION,
     2.7 +		ID_FUTABA_TOGGLE_OFF_SCREEN_MODE,
     2.8          ID_SELECT_FONT,
     2.9          ID_LAST
    2.10      };
    2.11 @@ -73,6 +74,7 @@
    2.12      long onFutabaSetPixel(FXObject *sender, FXSelector sel, void *ptr);
    2.13      long onFutabaResetPixel(FXObject *sender, FXSelector sel, void *ptr);
    2.14      long onFutabaSetDisplayPosition(FXObject *sender, FXSelector sel, void *ptr);
    2.15 +	long onFutabaToggleOffScreenMode(FXObject *sender, FXSelector sel, void *ptr);
    2.16      //
    2.17      long onSelectFont(FXObject *sender, FXSelector sel, void *ptr);
    2.18      //
    2.19 @@ -112,6 +114,7 @@
    2.20      FXButton *iButtonResetPixel;
    2.21      FXButton *iButtonSetAllPixels;
    2.22      FXButton *iButtonSetDisplayPosition;
    2.23 +	FXButton *iButtonToggleOffScreenMode;
    2.24      //Font
    2.25      FXButton *iButtonSelectFont;
    2.26  
     3.1 --- a/src/FutabaVfd.cpp	Thu May 22 16:46:50 2014 +0200
     3.2 +++ b/src/FutabaVfd.cpp	Thu May 22 21:32:45 2014 +0200
     3.3 @@ -71,53 +71,50 @@
     3.4  // class GP1212A01A
     3.5  //
     3.6  
     3.7 +GP1212A01A::GP1212A01A():iDisplayPositionX(0),iDisplayPositionY(0),iOffScreenMode(true)
     3.8 +	{
     3.9 +	}
    3.10 +
    3.11  int GP1212A01A::Open()
    3.12  	{
    3.13  	int success = HidDevice::Open(KFutabaVendorId,KFutabaProductIdGP1212A01A,NULL);
    3.14  	if (success)
    3.15  		{
    3.16  		SetNonBlocking(1);
    3.17 +		//Since we can't get our display position we for it to our default
    3.18 +		//This makes sure frames are in sync from the start
    3.19 +		SetDisplayPosition(iDisplayPositionX,iDisplayPositionY);
    3.20  		}
    3.21  	return success;
    3.22  	}
    3.23  
    3.24  /**
    3.25  */
    3.26 -void GP1212A01A::SetPixel(int aX, int aY, bool aOn)
    3.27 +void GP1212A01A::SetPixel(unsigned char aX, unsigned char aY, bool aOn)
    3.28  	{
    3.29  	//Just specify a one pixel block
    3.30  	SetPixelBlock(aX,aY,0x00,0x01,aOn);
    3.31  	}
    3.32  
    3.33  /**
    3.34 +Set all pixels on our screen to the desired value.
    3.35 +This operation is performed off screen to avoid tearing.
    3.36 +@param 8 pixels pattern
    3.37  */
    3.38 -void GP1212A01A::SetAllPixels(bool aOn)
    3.39 +void GP1212A01A::SetAllPixels(unsigned char aPattern)
    3.40  	{
    3.41 -	//One pixel at a time
    3.42 -	/*
    3.43 -	for (int i=0;i<256;i++)
    3.44 -		{
    3.45 -		for (int j=0;j<64;j++)
    3.46 -			{
    3.47 -			SetPixel(i,j,0x01);
    3.48 -			}
    3.49 -		}
    3.50 -	*/
    3.51 +	//With a single buffer
    3.52 +	//unsigned char screen[2048]; //One screen worth of pixels
    3.53 +	//memset(screen,0xFF,sizeof(screen));
    3.54 +	//SetPixelBlock(0,0,63,sizeof(screen),screen);
    3.55  
    3.56 -	//16x16=256 pixels at a time goes much faster
    3.57 -	//TODO: use even larger blocks
    3.58 -	for (int i=0;i<256;i+=16)
    3.59 -		{
    3.60 -		for (int j=0;j<64;j+=16)
    3.61 -			{
    3.62 -			SetPixelBlock(i,j,15,32,(aOn?0xFF:0x00));
    3.63 -			//FXThread::sleep(1000000000);
    3.64 -			}
    3.65 -		}
    3.66 -
    3.67 +	//Using pattern SetPixelBlock variant.
    3.68 +	SetPixelBlock(0,0,63,FrameBufferSizeInBytes(),aPattern);
    3.69  	}
    3.70  
    3.71  /**
    3.72 +Set our screen brightness.
    3.73 +@param The desired brightness level. Must be between MinBrightness and MaxBrightness.
    3.74  */
    3.75  void GP1212A01A::SetBrightness(int aBrightness)
    3.76      {
    3.77 @@ -149,23 +146,36 @@
    3.78  @param The size of our pixel data. Number of pixels divided by 8.
    3.79  @param The value set to 8 pixels used as a pattern.
    3.80  */
    3.81 -void GP1212A01A::SetPixelBlock(int aX, int aY, int aHeight, int aSize, unsigned char aValue)
    3.82 +void GP1212A01A::SetPixelBlock(unsigned char aX, unsigned char aY, int aHeight, int aSize, unsigned char aValue)
    3.83  	{
    3.84 -	//Size must be 63 or below
    3.85 -	FutabaVfdReport report;
    3.86 -	report[0]=0x00; //Report ID
    3.87 -	report[1]=0x08+aSize; //Report length
    3.88 -	report[2]=0x1B; //
    3.89 -	report[3]=0x5B; //
    3.90 -	report[4]=0xF0; //
    3.91 -	report[5]=aX; //X
    3.92 -	report[6]=aY; //Y
    3.93 -	report[7]=aHeight; //Y length before return. Though outside the specs, setting this to zero apparently allows us to modify a single pixel without touching any other.
    3.94 -	report[8]=0x00; //Size of pixel data in bytes (MSB)
    3.95 -	report[9]=aSize; //Size of pixel data in bytes (LSB)
    3.96 -	memset(report.Buffer()+10, aValue, aSize);
    3.97 -	//iOutputReportBuffer[10]=aValue; //Pixel data
    3.98 -	Write(report);
    3.99 +	OffScreenTranslation(aX,aY);
   3.100 +    FutabaVfdReport report;
   3.101 +    report[0]=0x00; //Report ID
   3.102 +    report[1]=(aSize<=report.Size()-10?aSize+0x08:64); //Report length. -10 is for our header first 10 bytes. +8 is for our Futaba header size
   3.103 +    report[2]=0x1B; //Command ID
   3.104 +    report[3]=0x5B; //Command ID
   3.105 +    report[4]=0xF0; //Command ID
   3.106 +    report[5]=aX;   //X
   3.107 +    report[6]=aY;   //Y
   3.108 +    report[7]=aHeight; //Y length before return. Though outside the specs, setting this to zero apparently allows us to modify a single pixel without touching any other.
   3.109 +	report[8]=aSize>>8; //Size of pixel data in bytes (MSB)
   3.110 +	report[9]=aSize;	//Size of pixel data in bytes (LSB)
   3.111 +    int sizeWritten=MIN(aSize,report.Size()-10);
   3.112 +    memset(report.Buffer()+10, aValue, sizeWritten);
   3.113 +    Write(report);
   3.114 +
   3.115 +    int remainingSize=aSize;
   3.116 +    //We need to keep on sending our pixel data until we are done
   3.117 +    while (report[1]==64)
   3.118 +        {
   3.119 +        report.Reset();
   3.120 +        remainingSize-=sizeWritten;
   3.121 +        report[0]=0x00; //Report ID
   3.122 +        report[1]=(remainingSize<=report.Size()-2?remainingSize:64); //Report length, should be 64 or the remaining size
   3.123 +        sizeWritten=(report[1]==64?63:report[1]);
   3.124 +        memset(report.Buffer()+2, aValue, sizeWritten);
   3.125 +        Write(report);
   3.126 +        }
   3.127  	}
   3.128  
   3.129  /**
   3.130 @@ -176,19 +186,20 @@
   3.131  @param The size of our pixel data. Number of pixels divided by 8.
   3.132  @param Pointer to our pixel data.
   3.133  */
   3.134 -void GP1212A01A::SetPixelBlock(int aX, int aY, int aHeight, int aSize, unsigned char* aPixels)
   3.135 +void GP1212A01A::SetPixelBlock(unsigned char aX, unsigned char aY, int aHeight, int aSize, unsigned char* aPixels)
   3.136      {
   3.137 +	OffScreenTranslation(aX,aY);
   3.138      FutabaVfdReport report;
   3.139      report[0]=0x00; //Report ID
   3.140 -    report[1]=0x08+(aSize<=report.Size()-10?aSize:64); //Report length. -10 is for our header first 10 bytes
   3.141 +    report[1]=(aSize<=report.Size()-10?aSize+0x08:64); //Report length. -10 is for our header first 10 bytes. +8 is for our Futaba header size
   3.142      report[2]=0x1B; //Command ID
   3.143      report[3]=0x5B; //Command ID
   3.144      report[4]=0xF0; //Command ID
   3.145      report[5]=aX;   //X
   3.146      report[6]=aY;   //Y
   3.147      report[7]=aHeight; //Y length before return. Though outside the specs, setting this to zero apparently allows us to modify a single pixel without touching any other.
   3.148 -    unsigned short* sizePtr=(unsigned short*)report.Buffer()+8; //Size of pixel data in bytes (MSB)
   3.149 -    *sizePtr=aSize; //Put our size over 2 bytes
   3.150 +	report[8]=aSize>>8; //Size of pixel data in bytes (MSB)
   3.151 +	report[9]=aSize;	//Size of pixel data in bytes (LSB)
   3.152      int sizeWritten=MIN(aSize,report.Size()-10);
   3.153      memcpy(report.Buffer()+10, aPixels, sizeWritten);
   3.154      Write(report);
   3.155 @@ -200,7 +211,7 @@
   3.156          report.Reset();
   3.157          remainingSize-=sizeWritten;
   3.158          report[0]=0x00; //Report ID
   3.159 -        report[1]=(remainingSize<=report.Size()-2?aSize:64); //Report length, should be 64 or the remaining size
   3.160 +        report[1]=(remainingSize<=report.Size()-2?remainingSize:64); //Report length, should be 64 or the remaining size
   3.161          sizeWritten=(report[1]==64?63:report[1]);
   3.162          memcpy(report.Buffer()+2, aPixels+(aSize-remainingSize), sizeWritten);
   3.163          Write(report);
   3.164 @@ -210,9 +221,21 @@
   3.165  
   3.166  /**
   3.167  Clear our display's screen.
   3.168 +This operation is performed off screen to avoid tearing.
   3.169  */
   3.170  void GP1212A01A::Clear()
   3.171  	{
   3.172 +	//Using pattern SetPixelBlock variant.
   3.173 +	//First fill our off screen buffer with the desired values
   3.174 +	SetPixelBlock(0,0,63,FrameBufferSizeInBytes(),(unsigned char)0x00);
   3.175 +	}
   3.176 +
   3.177 +/**
   3.178 +Using this function is advised against as is causes tearing.
   3.179 +Use Clear instead.
   3.180 +*/
   3.181 +void GP1212A01A::SendClearCommand()
   3.182 +	{
   3.183      //1BH,5BH,32H,4AH
   3.184      //Send Clear Display Command
   3.185  	FutabaVfdReport report;
   3.186 @@ -228,7 +251,7 @@
   3.187  /**
   3.188  Change our display position within our buffer.
   3.189  */
   3.190 -void GP1212A01A::SetDisplayPosition(DW aDw,int aX, int aY)
   3.191 +void GP1212A01A::SetDisplayPosition(DW aDw,unsigned char aX, unsigned char aY)
   3.192      {
   3.193      //1BH,5BH,Dw,Px,Py
   3.194      //Send Display Position Settings Command
   3.195 @@ -246,12 +269,48 @@
   3.196  /**
   3.197  Change our display position within our buffer.
   3.198  */
   3.199 -void GP1212A01A::SetDisplayPosition(int aX, int aY)
   3.200 +void GP1212A01A::SetDisplayPosition(unsigned char aX, unsigned char aY)
   3.201  	{
   3.202  	//Specs apparently says both DW should remain the same
   3.203  	//Just don't ask
   3.204      SetDisplayPosition(GP1212A01A::DW1,aX,aY);
   3.205      SetDisplayPosition(GP1212A01A::DW2,aX,aY);
   3.206 +	iDisplayPositionX=aX;
   3.207 +	iDisplayPositionY=aY;
   3.208 +	}
   3.209 +
   3.210 +/**
   3.211 +Provide Y coordinate of our off screen buffer.
   3.212 +*/
   3.213 +unsigned char GP1212A01A::OffScreenY() const
   3.214 +	{
   3.215 +	//Overflowing is fine this is just what we want
   3.216 +	return iDisplayPositionY+HeightInPixels();
   3.217 +	}
   3.218 +
   3.219 +/**
   3.220 +Put our off screen buffer on screen.
   3.221 +On screen buffer goes off screen.
   3.222 +*/
   3.223 +void GP1212A01A::SwapBuffers()
   3.224 +	{
   3.225 +	//Only perform buffer swapping if off screen mode is enabled
   3.226 +	if (OffScreenMode())
   3.227 +		{
   3.228 +		SetDisplayPosition(iDisplayPositionX,OffScreenY());
   3.229 +		}
   3.230 +	}
   3.231 +
   3.232 +/**
   3.233 +Translate the given pixel coordinate according to our off screen mode.
   3.234 +*/
   3.235 +void GP1212A01A::OffScreenTranslation(unsigned char& aX, unsigned char& aY)
   3.236 +	{
   3.237 +	if (OffScreenMode())
   3.238 +		{
   3.239 +		aX+=WidthInPixels()-iDisplayPositionX;
   3.240 +		aY+=HeightInPixels()-iDisplayPositionY;
   3.241 +		}
   3.242  	}
   3.243  /**
   3.244  */
   3.245 @@ -302,4 +361,19 @@
   3.246      report[5]=0x50; //Command ID
   3.247      report[6]=0x4D; //Command ID
   3.248      Write(report);
   3.249 -    }
   3.250 \ No newline at end of file
   3.251 +    }
   3.252 +
   3.253 +
   3.254 +/**
   3.255 +This is for development purposes only.
   3.256 +Production application should stick to off-screen mode to avoid tearing.
   3.257 +*/
   3.258 +void GP1212A01A::ToggleOffScreenMode()
   3.259 +	{
   3.260 +	iOffScreenMode=!iOffScreenMode;
   3.261 +	//Clean up our buffers upon switching modes	
   3.262 +	SetDisplayPosition(0,0);
   3.263 +	Clear();
   3.264 +	SwapBuffers();
   3.265 +	Clear();
   3.266 +	}
   3.267 \ No newline at end of file
     4.1 --- a/src/test.cpp	Thu May 22 16:46:50 2014 +0200
     4.2 +++ b/src/test.cpp	Thu May 22 21:32:45 2014 +0200
     4.3 @@ -44,6 +44,7 @@
     4.4  	FXMAPFUNC(SEL_COMMAND, MainWindow::ID_FUTABA_RESET_PIXEL, MainWindow::onFutabaResetPixel ),
     4.5      FXMAPFUNC(SEL_COMMAND, MainWindow::ID_FUTABA_SET_ALL_PIXELS, MainWindow::onFutabaSetAllPixels ),
     4.6  	FXMAPFUNC(SEL_COMMAND, MainWindow::ID_FUTABA_SET_DISPLAY_POSITION, MainWindow::onFutabaSetDisplayPosition ),
     4.7 +	FXMAPFUNC(SEL_COMMAND, MainWindow::ID_FUTABA_TOGGLE_OFF_SCREEN_MODE, MainWindow::onFutabaToggleOffScreenMode ),	
     4.8      FXMAPFUNC(SEL_COMMAND, MainWindow::ID_SELECT_FONT, MainWindow::onSelectFont ),
     4.9  	FXMAPFUNC(SEL_TIMEOUT, MainWindow::ID_TIMER, MainWindow::onTimeout ),
    4.10  	FXMAPFUNC(SEL_TIMEOUT, MainWindow::ID_MAC_TIMER, MainWindow::onMacTimeout ),
    4.11 @@ -122,6 +123,7 @@
    4.12      //
    4.13      iButtonSetAllPixels = new FXButton(matrix, "Set All Pixels", NULL, this, ID_FUTABA_SET_ALL_PIXELS, BUTTON_NORMAL|LAYOUT_FILL_X);
    4.14      iButtonSetDisplayPosition = new FXButton(matrix, "Set Display Position", NULL, this, ID_FUTABA_SET_DISPLAY_POSITION, BUTTON_NORMAL|LAYOUT_FILL_X);
    4.15 +	iButtonToggleOffScreenMode = new FXButton(matrix, "Switch to on-screen", NULL, this, ID_FUTABA_TOGGLE_OFF_SCREEN_MODE, BUTTON_NORMAL|LAYOUT_FILL_X);
    4.16      //
    4.17  
    4.18  	// Output Group Box
    4.19 @@ -292,6 +294,7 @@
    4.20              iButtonResetPixel->enable();
    4.21              iButtonSetAllPixels->enable();
    4.22              iButtonSetDisplayPosition->enable();
    4.23 +			iButtonToggleOffScreenMode->enable();
    4.24              }
    4.25          }
    4.26      else
    4.27 @@ -318,6 +321,7 @@
    4.28          iButtonResetPixel->disable();
    4.29          iButtonSetAllPixels->disable();
    4.30          iButtonSetDisplayPosition->disable();
    4.31 +		iButtonToggleOffScreenMode->disable();
    4.32          //
    4.33          }
    4.34  
    4.35 @@ -545,6 +549,7 @@
    4.36  MainWindow::onFutabaClearDisplay(FXObject *sender, FXSelector sel, void *ptr)
    4.37  {
    4.38      iVfd01.Clear();
    4.39 +	iVfd01.SwapBuffers();
    4.40  	return 1;
    4.41  }
    4.42  
    4.43 @@ -589,6 +594,7 @@
    4.44  	iTextFieldY->getText().scan("%d",&y);
    4.45      //SetPixel(x,y,0x01);
    4.46      iVfd01.SetPixel(x,y,true);
    4.47 +	iVfd01.SwapBuffers();
    4.48  	return 1;
    4.49  }
    4.50  
    4.51 @@ -602,12 +608,14 @@
    4.52  	iTextFieldY->getText().scan("%d",&y);
    4.53      //SetPixel(x,y,0x00);
    4.54      iVfd01.SetPixel(x,y,false);
    4.55 +	iVfd01.SwapBuffers();
    4.56      return 1;
    4.57  }
    4.58  
    4.59  long MainWindow::onFutabaSetAllPixels(FXObject *sender, FXSelector sel, void *ptr)
    4.60  	{
    4.61 -    iVfd01.SetAllPixels(true);
    4.62 +    iVfd01.SetAllPixels(0xFF);
    4.63 +	iVfd01.SwapBuffers();
    4.64      return 1;
    4.65  	}
    4.66  
    4.67 @@ -626,6 +634,26 @@
    4.68      }
    4.69  
    4.70  
    4.71 +/**
    4.72 +
    4.73 +*/
    4.74 +long MainWindow::onFutabaToggleOffScreenMode(FXObject *sender, FXSelector sel, void *ptr)
    4.75 +    {
    4.76 +    iVfd01.ToggleOffScreenMode();
    4.77 +	if (iVfd01.OffScreenMode())
    4.78 +		{
    4.79 +		iButtonToggleOffScreenMode->setText("Switch to on-screen");
    4.80 +		}
    4.81 +	else
    4.82 +		{
    4.83 +		iButtonToggleOffScreenMode->setText("Switch to off-screen");
    4.84 +		}
    4.85 +    return 1;
    4.86 +    }
    4.87 +
    4.88 +
    4.89 +
    4.90 +
    4.91  long
    4.92  MainWindow::onFutabaReadId(FXObject *sender, FXSelector sel, void *ptr)
    4.93  {