| 
			
			
			
			 ( ͡° ͜ʖ ͡°){ʇlnɐɟ ƃǝs}Týr 
			
			
			
		
			
				
			
			
			
				 
				Posts: 6,586 
				Karma: 6299993 
				Join Date: Jun 2012 
				Location: uti gratia usura (Yao ying da ying; Mo ying da yieng) 
				
				
				Device: PW-WIFI|K5-3G+WIFI| K4|K3-3G|DXG|K2| Rooted Nook Touch 
				
				
				     
			 					
		
	 | 
	
	
	
		
		
		
		
		
			
			https://dl.dropboxusercontent.com/u/15900420/PW-pump
EXPERIMENTAL inversion pump for the PW.
 
replaces need for eips. fixes colors.
 
just run it in parallel with the viewer.
 
[root@kindle root]#  /mnt/us/PW-pump
	Quote: 
	
	
		
			
				using XRandR: screen size = 758x1024, rotation = UR 
EPDC fbdev is /dev/fb0 
1: (x,y)=(0,0) (w,h)=(758,1024) 
2: (x,y)=(338,572) (w,h)=(78,46) 
3: (x,y)=(338,572) (w,h)=(161,46) 
4: (x,y)=(420,572) (w,h)=(164,46) 
5: (x,y)=(505,572) (w,h)=(79,46) 
6: (x,y)=(256,420) (w,h)=(328,198) 
7: (x,y)=(420,420) (w,h)=(79,46) 
8: (x,y)=(588,572) (w,h)=(79,46) 
9: (x,y)=(588,522) (w,h)=(79,96) 
10: (x,y)=(588,420) (w,h)=(79,148) 
11: (x,y)=(588,420) (w,h)=(79,46) 
12: (x,y)=(420,522) (w,h)=(79,46) 
13: (x,y)=(420,522) (w,h)=(79,96)
			
		 | 
	 
	 
 
POSSIBLE ERRORS:
 
 /mnt/us #  /mnt/us/PW-pump
	Quote: 
	
	
		
			
				 using XRandR: screen size = 758x1024, rotation = UR EPDC fbdev is /dev/fb0  
15: (x,y)=(172,268) (w,h)=(327,300) 
16: (x,y)=(420,472) (w,h)=(79,46) 
17: (x,y)=(450,730) (w,h)=(71,71) 
18: (x,y)=(130,943) (w,h)=(426,71) 
19: (x,y)=(2,2) (w,h)=(748,1012) 
Error in ioctl(MXCFB_SEND_UPDATE) call 
/dev/fb0: Cannot allocate memory
			
		 | 
	 
	 
 at which point it will bomb out...
 
meh, it's experimental.  currently I'm just testing it.
 
As you can see from the screen shot the image /thinks/ it is still b&w...  
but on the screen you see the correct colour inversion.
 
: )
 
Other then me breaking it this is the work of seaniko, Freescale and Hawhill. 
And probably a bunch of other people too...
 
(It's gpl so I think I need to include the source) 
Header:  https://github.com/hwhw/kindlevncvie...nclude/mxcfb.h
Spoiler: 
 
	Code: 
	/*
 * Copyright (C) 2010-2011 Freescale Semiconductor, Inc. All Rights Reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * 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 for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 *
 */
/*
 * @file mxc_epdc_x11_fb_test.c
 *
 * @brief MXC EPDC unit test applicationi for framebuffer updates
 * based on X11 changes to its root window
 *
 */
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <poll.h>
#include <X11/Xlib.h>
#include <X11/extensions/Xdamage.h>
#include <X11/extensions/Xrandr.h>
#include <linux/fb.h>
#include "mxcfb.h"
#include <sys/ioctl.h>
#include <time.h>
#define INIT_UPDATE_MARKER      0x12345678
static int kbhit(void)
{
	struct pollfd pollfd;
	pollfd.fd = 0;
	pollfd.events = POLLIN;
	pollfd.revents = 0;
	return poll(&pollfd, 1, 0);
}
int main (int argc, char* argv[])
{
	/* Declare and init variables used after cleanup: goto. */
	Display* xDisplay = NULL;
	Damage xDamageScreen = 0;
	int fd = -1;
	XRRScreenConfiguration* xrrScreenConfig = NULL;
	/* Open the X display */
	xDisplay = XOpenDisplay(NULL);
	if (NULL == xDisplay)
	{
		printf("\nError: unable to open X display\n");
		goto cleanup;
	}
	/* Acess the root window for the display. */
	Window xRootWindow = XDefaultRootWindow(xDisplay);
	if (0 == xRootWindow)
	{
		printf("\nError: unable to access root window for screen\n");
		goto cleanup;
	}
	/* Access the XRandR screen configuration. */
	xrrScreenConfig = XRRGetScreenInfo(xDisplay, xRootWindow);
	if (NULL == xrrScreenConfig)
	{
		printf("\nError: unable to query XRandR screen config\n");
		goto cleanup;
	}
	/* Query the list of XRandR configured screen sizes. */
	int xrrSizeListCount;
	XRRScreenSize* xrrSizeList =
		XRRConfigSizes(xrrScreenConfig, &xrrSizeListCount);
	/* Query the current XRandR screen rotation and which screen size */
	/* is currently being used. */
	Rotation xrrRotate;
	int xrrSizeIndex =
		XRRConfigCurrentConfiguration( xrrScreenConfig, &xrrRotate);
	const int screenWidth = xrrSizeList[xrrSizeIndex].width;
	const int screenHeight = xrrSizeList[xrrSizeIndex].height;
	/* Display XRandR information */
	printf("using XRandR: screen size = %dx%d, rotation = ",
		screenWidth, screenHeight);
	int fbRotate = -1;
	if (RR_Rotate_0 & xrrRotate)
	{
		printf("UR\n");
		fbRotate = FB_ROTATE_UR;
	}
	else if (RR_Rotate_90 & xrrRotate)
	{
		printf("CW\n");
		fbRotate = FB_ROTATE_CW;
	}
	else if (RR_Rotate_180 & xrrRotate)
	{
		printf("UD\n");
		fbRotate = FB_ROTATE_UD;
	}
	else if (RR_Rotate_270 & xrrRotate)
	{
		printf("CCW\n");
		fbRotate = FB_ROTATE_CCW;
	}
	else
	{
		printf("???\n");
	}
	if (-1 == fbRotate)
	{
		printf("\nError: unsupported XRandR rotation = 0x%04x\n",
			xrrRotate);
		goto cleanup;
	}
	/* Query the damage extension associated with this display. */
	int xDamageEventBase;
	int xDamageErrorBase;
	if (!XDamageQueryExtension(xDisplay, &xDamageEventBase, &xDamageErrorBase))
	{
		printf("\nError: unable to query XDamage extension\n");
		goto cleanup;
	}
	/* Setup to receive damage notification on the main screen */
	/* each time the bounding box increases until it is reset. */
	xDamageScreen =
		XDamageCreate(xDisplay, xRootWindow,
			XDamageReportBoundingBox);
	if (0 == xDamageScreen)
	{
		printf("\nError: unable to setup X damage on display screen\n");
		goto cleanup;
	}
	/* Find the EPDC FB device */
	char fbDevName[10] = "/dev/fb";
	int fbDevNum = 0;
	struct fb_fix_screeninfo fbFixScreenInfo;
	do {
		/* Close previously opened fbdev */
		if (fd >= 0)
		{
			close(fd);
			fd = -1;
		}
		/* Open next fbdev */
		fbDevName[7] = '0' + (fbDevNum++);
		fd = open(fbDevName, O_RDWR, 0);
		if (fd < 0)
		{
			printf("Error in opening fb device\n");
			perror(fbDevName);
			goto cleanup;
		}
		/* Query fbdev fixed screen info. */
		if (0 > ioctl(fd, FBIOGET_FSCREENINFO, &fbFixScreenInfo))
		{
			printf("Error in ioctl(FBIOGET_FSCREENINFFO) call\n");
			perror(fbDevName);
			goto cleanup;
		}
    
	} while (0 != strcmp(fbFixScreenInfo.id, "mxc_epdc_fb"));
	printf("EPDC fbdev is %s\n", fbDevName);
	/* Query fbdev var screen info. */
	struct fb_var_screeninfo fbVarScreenInfo;
	if (0 > ioctl(fd, FBIOGET_VSCREENINFO, &fbVarScreenInfo))
	{
		printf("Error in ioctl(FBIOGET_VSCREENINFO) call\n");
		perror(fbDevName);
		goto cleanup;
	}
	/* Force EPDC to initialize */
	fbVarScreenInfo.activate = FB_ACTIVATE_FORCE;
	if (0 > ioctl(fd, FBIOPUT_VSCREENINFO, &fbVarScreenInfo))
	{
		printf("Error in ioctl(FBIOPUT_VSCREENINFO) call\n");
		perror(fbDevName);
		goto cleanup;
	}
	/* Put EPDC into region update mode. */
	int mxcfbSetAutoUpdateMode = AUTO_UPDATE_MODE_REGION_MODE;
	if (0 > ioctl(fd, MXCFB_SET_AUTO_UPDATE_MODE, &mxcfbSetAutoUpdateMode))
	{
		printf("Error in ioctl(MXCFB_SET_AUTO_UPDATE_MODE) call\n");
		perror(fbDevName);
		goto cleanup;
	}
        /* Set EPDC update scheme. */
        int mxcfbSetUpdateScheme = UPDATE_SCHEME_SNAPSHOT;
        if (0 > ioctl(fd, MXCFB_SET_UPDATE_SCHEME, &mxcfbSetUpdateScheme))
        {
                printf("Error in ioctl(MXCFB_SET_UPDATE_SCHEME) call\n");
                perror(fbDevName);
                goto cleanup;
        }
	/* Setup waveform modes. */
        struct mxcfb_waveform_modes mxcfbWaveformModes;
	/* Common properties for EPDC screen update */
	struct mxcfb_update_data mxcfbUpdateData;
        mxcfbUpdateData.update_region.left = 0;
        mxcfbUpdateData.update_region.width = 0x2F6;
        mxcfbUpdateData.update_region.top = 0;
        mxcfbUpdateData.update_region.height = 0x400;
        mxcfbUpdateData.update_mode = UPDATE_MODE_PARTIAL;
        mxcfbUpdateData.waveform_mode = WAVEFORM_MODE_GL16;
        mxcfbUpdateData.update_marker = 1;
        mxcfbUpdateData.flags = EPDC_FLAG_ENABLE_INVERSION;
                if (0 > ioctl(fd, MXCFB_SEND_UPDATE, &mxcfbUpdateData))
                {
                        printf("Error in ioctl(MXCFB_SEND_UPDATE) call\n");
                        perror(fbDevName);
                        goto cleanup;
                }
	int numPanelUpdates = 0;
	while (1)
	{
		int numDamageUpdates = 0;
		int updateLeft, updateRight;
		int updateTop, updateBottom;
		while (XPending(xDisplay))
		{
			XEvent xEvent;
			XNextEvent(xDisplay, &xEvent);
			if ((XDamageNotify+xDamageEventBase) == xEvent.type)
			{
				XDamageNotifyEvent* xDamageNotifyEvent =
					(XDamageNotifyEvent*)&xEvent;
				int left = xDamageNotifyEvent->area.x;
				int top = xDamageNotifyEvent->area.y;
				int right = left + xDamageNotifyEvent->area.width;
				int bottom = top + xDamageNotifyEvent->area.height;
				if (numDamageUpdates++ > 0)
				{
					if (left < updateLeft)
					{
						updateLeft = left;
					}
					if (right > updateRight)
					{
						updateRight = right;
					}
					if (top < updateTop)
					{
						updateTop = top;
					}
					if (bottom > updateBottom)
					{
						updateBottom = bottom;
					}
				}
				else
				{
					updateLeft = left;
					updateTop = top;
					updateRight = right;
					updateBottom = bottom;
				}
			}
		
		}
			usleep (30000);  // Bit of grace time.
		/* Send accum bound rect updates to EPDC */
		mxcfbUpdateData.update_marker = ++numPanelUpdates;
		if (FB_ROTATE_UR == fbRotate)
		{
			mxcfbUpdateData.update_region.left = 0;
			mxcfbUpdateData.update_region.top = 0;
mxcfbUpdateData.update_region.width = 758 ; // screenWidth;
mxcfbUpdateData.update_region.height = 1024 ;// screenHeight;
		}
		else if (FB_ROTATE_UD == fbRotate)
		{
			mxcfbUpdateData.update_region.left = 0;
			mxcfbUpdateData.update_region.top = 0;
			mxcfbUpdateData.update_region.width =
				screenWidth - updateLeft;
			mxcfbUpdateData.update_region.height =
				screenHeight - updateTop;
		}
		else if (FB_ROTATE_CW == fbRotate)
		{
			mxcfbUpdateData.update_region.left = 0;
			mxcfbUpdateData.update_region.top = 0;
			mxcfbUpdateData.update_region.width =
				screenWidth - updateTop;
			mxcfbUpdateData.update_region.height =
				updateRight;
		}
		else if (FB_ROTATE_CCW == fbRotate)
		{
			mxcfbUpdateData.update_region.left = 0;
			mxcfbUpdateData.update_region.top = 0;
			mxcfbUpdateData.update_region.width =
				updateBottom;
			mxcfbUpdateData.update_region.height =
				screenHeight - updateLeft;
		}
		else
		{
			continue;
		}
		if (0 > ioctl(fd, MXCFB_SEND_UPDATE, &mxcfbUpdateData))
		{
			printf("Error in ioctl(MXCFB_SEND_UPDATE) call\n");
			perror(fbDevName);
			goto cleanup;
		}
		/* Display what getting updated */
		printf("%d: (x,y)=(%d,%d) (w,h)=(%d,%d)\n",
			numPanelUpdates,
			updateLeft, updateTop,
			updateRight - updateLeft,
			updateBottom - updateTop);
		/* Clear the damage update bounding box */
		XDamageSubtract(xDisplay, xDamageScreen, None, None);
		/* Wait for previous EPDC update to finish */
		if (0 > ioctl(fd, MXCFB_WAIT_FOR_UPDATE_COMPLETE,
				&mxcfbUpdateData.update_marker))
		{
			printf("Error in ioctl(MXCFB_WAIT_FOR_UPDATE_COMPLETE) call\n");
			perror(fbDevName);
			goto cleanup;
		}
		
	}
cleanup:
	if (fd >= 0)
	{
		close(fd);
		fd = -1;
	}
	if (NULL != xrrScreenConfig)
	{
		XRRFreeScreenConfigInfo(xrrScreenConfig);
		xrrScreenConfig = NULL;
	}
	if (0 != xDamageScreen)
	{
		XDamageDestroy(xDisplay, xDamageScreen);
		xDamageScreen = 0;
	}
	if (NULL != xDisplay)
	{
		XCloseDisplay(xDisplay);
		xDisplay = NULL;
	}
	return 0;
}
  
 
		 
		
	
		
		
			
		
		
		
		
		
		
		
		
		
		
		
		
			
				  
				
					
						Last edited by twobob; 11-05-2013 at 10:49 PM.
					
					
				
			
		
		
	
	 |