static void
imxCrtcDPMS(xf86CrtcPtr crtc, int mode)
{
   /**
    * Turns the crtc on/off, or sets intermediate power levels if available.
    *
    * Unsupported intermediate modes drop to the lower power setting.  If the
    * mode is DPMSModeOff, the crtc must be disa be safe to call mode_set.
    */

	/* Access the associated screen info. */
	ScrnInfoPtr pScrn = crtc->scrn;

	/* Access the frame buffer driver */
	int fd = fbdevHWGetFD(pScrn);
	if (-1 != fd) {

		/* Enable power */
		if (DPMSModeOn == mode) {

			ioctl(fd, FBIOBLANK, FB_BLANK_UNBLANK);

		/* Unsupported intermediate modes drop to lower power setting */
		} else {

			ioctl(fd, FBIOBLANK, FB_BLANK_NORMAL);
		}
	}
}
예제 #2
0
void RkDispHardwareCursor_Init(ScreenPtr pScreen)
{
    xf86CursorInfoPtr InfoPtr;
    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
    FBDevPtr pMxv = FBDEVPTR(pScrn);
    pMxv->RkHWC = NULL;
    int fd;

    fd = fbdevHWGetFD(pScrn);
    if (fd <= 0){
    	ERRMSG("DispHardwareCursor_Init fd error");
    	return;
    }

    if (!(InfoPtr = xf86CreateCursorInfoRec())) {
    	ERRMSG("DispHardwareCursor_Init: xf86CreateCursorInfoRec() failed");
        return;
    }

    InfoPtr->ShowCursor = ShowCursor;
    InfoPtr->HideCursor = HideCursor;
    InfoPtr->SetCursorPosition = SetCursorPosition;
    InfoPtr->SetCursorColors = SetCursorColors;
    InfoPtr->LoadCursorImage = LoadCursorImage;
    InfoPtr->MaxWidth = 32;
    InfoPtr->MaxHeight = 32;
//    InfoPtr->RealizeCursor
    InfoPtr->Flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP | HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1;

    if (!xf86InitCursor(pScreen, InfoPtr)) {
    	ERRMSG("DispHardwareCursor_Init: xf86InitCursor(pScreen, InfoPtr) failed");
        xf86DestroyCursorInfoRec(InfoPtr);
        goto err;
    }

    pMxv->RkHWC = calloc(1, sizeof(RkDispHWCRec));
    if (!pMxv->RkHWC) {
    	ERRMSG("DispHardwareCursor_Init: calloc failed");
        xf86DestroyCursorInfoRec(InfoPtr);
        goto err;
    }
    RkDispHWCPtr HWC = pMxv->RkHWC;

    INFMSG("HWCursor activated");
    HWC->hwcursor = InfoPtr;
    HWC->fb_fd = fd;
    return;
//******************not ok*************
err:
    xf86DestroyCursorInfoRec(InfoPtr);
}
static DisplayModePtr
imxDisplayGetModes(ScrnInfoPtr pScrn, const char* fbDeviceName)
{
	FILE* fpModes = NULL;
	int fdDev = -1;
	DisplayModePtr modesList = NULL;
	Bool savedVarScreenInfo = FALSE;
	struct fb_var_screeninfo fbVarScreenInfo;

	/* Access the frame buffer device. */
	fdDev = fbdevHWGetFD(pScrn);
	if (-1 == fdDev) {

		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
	   		"frame buffer device not available or initialized\n");
		goto errorGetModes;
	}

	/* Query the FB variable screen info */
	if (-1 == ioctl(fdDev, FBIOGET_VSCREENINFO, &fbVarScreenInfo)) {

		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
			"unable to get FB VSCREENINFO for current mode: %s\n",
			strerror(errno));
		goto errorGetModes;
	}
	savedVarScreenInfo = TRUE;

	/* Create the name of the sysnode file that contains the */
	/* names of all the frame buffer modes. */
	char sysnodeName[80];
	sprintf(sysnodeName, "/sys/class/graphics/%s/modes", fbDeviceName);
	fpModes = fopen(sysnodeName, "r");
	if (NULL == fpModes) {

		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
	   		"unable to open sysnode '%s':%s \n",
			sysnodeName, strerror(errno));
		goto errorGetModes;
	}

	/* Create name for the frame buffer device. */
	char fullDeviceName[80];
	strcpy(fullDeviceName, "/dev/");
	strcat(fullDeviceName, fbDeviceName);

	/* Turn on frame buffer blanking. */
	if (-1 == ioctl(fdDev, FBIOBLANK, FB_BLANK_NORMAL)) {

		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
	   		"unable to blank frame buffer device '%s': %s\n",
			fullDeviceName, strerror(errno));
		goto errorGetModes;
	}

	xf86DrvMsg(pScrn->scrnIndex, X_INFO,
		"printing discovered frame buffer '%s' supported modes:\n",
		fbDeviceName);

	/* Iterate over all the modes in the frame buffer list. */
	char modeName[80];
	while (NULL != fgets(modeName, sizeof(modeName), fpModes)) {

		imxRemoveTrailingNewLines(modeName);

		/* Attempt to set the mode */
		if (!imxDisplaySetMode(pScrn, fbDeviceName, modeName)) {

			xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
	   			"unable to set frame buffer mode '%s'\n",
				modeName);
			continue;
		}

		DisplayModePtr mode =
			imxDisplayGetCurrentMode(pScrn, fdDev, modeName);

		if ((NULL != mode) &&
			(mode->HDisplay > 0) &&
				(mode->VDisplay > 0)) {

			xf86PrintModeline(pScrn->scrnIndex, mode);
			modesList = xf86ModesAdd(modesList, mode);
		}
	}

	/* Add current builtin mode */
	DisplayModePtr builtinMode = imxDisplayGetBuiltinMode(pScrn);
	xf86PrintModeline(pScrn->scrnIndex, builtinMode);
	modesList = xf86ModesAdd(modesList, builtinMode);

errorGetModes:

	/* Close file with list of modes. */
	if (NULL != fpModes) {

		fclose(fpModes);
	}

	/* Restore FB back to the current mode */
	if (savedVarScreenInfo) {

		if (-1 == ioctl(fdDev, FBIOPUT_VSCREENINFO, &fbVarScreenInfo)) {
	
			xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
				"unable to restore FB VSCREENINFO: %s\n",
				strerror(errno));
		}
	}

	/* Turn off frame buffer blanking */
	if (-1 != fdDev) {

		ioctl(fdDev, FBIOBLANK, FB_BLANK_UNBLANK);
	}

	/* Remove any duplicate modes found. */
	modesList = xf86PruneDuplicateModes(modesList);

	return modesList;
}
static Bool
imxDisplaySetMode(ScrnInfoPtr pScrn, const char* fbDeviceName,
			const char* modeName)
{
	/* Access driver private screen data */
	ImxPtr imxPtr = IMXPTR(pScrn);
	
	/* Access display private screen data */
	ImxDisplayPtr fPtr = IMXDISPLAYPTR(imxPtr);

	/* Can only change the mode if not builtin. */
	if (!imxDisplayIsBuiltinMode(modeName)) {

		/* Create the name of the sysnode file that contains the */
		/* name of the currently selected mode. */
		char sysnodeName[80];
		sprintf(sysnodeName, "/sys/class/graphics/%s/mode",
				fbDeviceName);
		int fd = open(sysnodeName, O_RDWR);
		if (-1 == fd) {

			xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
				"unable to open sysnode '%s':%s\n",
				sysnodeName, strerror(errno));
			return FALSE;
		}

		/* Make sure mode name has a newline at end on the write. */
		char validModeName[80];
		strcpy(validModeName, modeName);
		strcat(validModeName, "\n");

		/* Write the desired mode name */
		if (-1 == write(fd, validModeName, strlen(validModeName))) {
			
			xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
				"unable to write '%s' to sysnode '%s': %s\n",
				validModeName, sysnodeName, strerror(errno));
			return FALSE;
		}

		close(fd);
	}

	/* Access the fd for the FB driver */
	int fdDev = fbdevHWGetFD(pScrn);

	/* Query the FB fixed screen info */
	struct fb_fix_screeninfo fbFixScreenInfo;
	if (-1 == ioctl(fdDev, FBIOGET_FSCREENINFO, &fbFixScreenInfo)) {

		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
			"unable to get FSCREENINFO for mode '%s': %s\n",
			modeName, strerror(errno));
		return FALSE;
	}
		
	/* Query the FB variable screen info */
	struct fb_var_screeninfo fbVarScreenInfo;
	if (-1 == ioctl(fdDev, FBIOGET_VSCREENINFO, &fbVarScreenInfo)) {

		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
			"unable to get VSCREENINFO for mode '%s': %s\n",
			modeName, strerror(errno));
		return FALSE;
	}
		
	/* If the shadow memory is allocated, then we have some */
	/* adjustments to do. */
	if (fPtr->fbShadowAllocated) {

		/* How many bytes from start of 1st buffer to start */
		/* of 2nd buffer? */
		const int offsetBytes =
			imxPtr->fbMemoryStart2 - imxPtr->fbMemoryStart;

		/* What should the yoffset by to start of 2nd buffer? */
		const int yoffset = offsetBytes / fbFixScreenInfo.line_length;

		/* What should virtual resolution be adjusted to */
		/* based on the 2 buffers? */
		const int vyres = yoffset * 2;

		fbVarScreenInfo.xoffset = 0;
		fbVarScreenInfo.yoffset = yoffset;
		fbVarScreenInfo.yres_virtual = vyres;

	/* If the shadow memory is not allocated, then we need to */
	/* reset any FB pan display back to (0,0). */
	} else {

		fbVarScreenInfo.xoffset = 0;
		fbVarScreenInfo.yoffset = 0;

	}
	
	/* Make the adjustments to the variable screen info. */
	if (-1 == ioctl(fdDev, FBIOPUT_VSCREENINFO, &fbVarScreenInfo)) {

		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
			"unable to set VSCREENINFO for mode '%s': %s\n",
			modeName, strerror(errno));
		return FALSE;
	}

	return TRUE;
}
Bool
imxDisplayStartScreenInit(int scrnIndex, ScreenPtr pScreen)
{
	ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
	ImxPtr fPtr = IMXPTR(pScrn);

	if (!xf86SetDesiredModes(pScrn)) {

		xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "mode initialization failed\n");
		return FALSE;
	}

#if 0
	if (!fbdevHWModeInit(pScrn, pScrn->currentMode)) {

		xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "mode initialization failed\n");
		return FALSE;
	}
	pScrn->displayWidth =
		fbdevHWGetLineLength(pScrn) / (pScrn->bitsPerPixel / 8);
#else
	pScrn->vtSema = TRUE;

	/* Access the fd for the FB driver */
	int fdDev = fbdevHWGetFD(pScrn);
	if (-1 == fdDev) {
		return FALSE;
	}

	/* Access from fix screen info */
	struct fb_fix_screeninfo fbFixScreenInfo;
	if (-1 == ioctl(fdDev, FBIOGET_FSCREENINFO, &fbFixScreenInfo)) {

		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
			"ioctl error on FBIOGET_FSCREENINFO: %s\n",
			strerror(errno));
		return FALSE;
	}
	int lineLength = fbFixScreenInfo.line_length;
		
	/* Access from var screen info */
	struct fb_var_screeninfo fbVarScreenInfo;
	if (-1 == ioctl(fdDev, FBIOGET_VSCREENINFO, &fbVarScreenInfo)) {

		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
			"ioctl error on FBIOGET_VSCREENINFO: %s\n",
			strerror(errno));
		return FALSE;
	}
	if (lineLength <= 0) {
		lineLength = fbVarScreenInfo.xres_virtual *
				fbVarScreenInfo.bits_per_pixel / 8;
	}

	pScrn->displayWidth = lineLength / (pScrn->bitsPerPixel / 8);

	if ((TrueColor == pScrn->defaultVisual) ||
		(DirectColor == pScrn->defaultVisual)) {

		pScrn->offset.red   = fbVarScreenInfo.red.offset;
		pScrn->offset.green = fbVarScreenInfo.green.offset;
		pScrn->offset.blue  = fbVarScreenInfo.blue.offset;

		pScrn->mask.red   = ((1 << fbVarScreenInfo.red.length) - 1) << fbVarScreenInfo.red.offset;
		pScrn->mask.green = ((1 << fbVarScreenInfo.green.length) - 1) << fbVarScreenInfo.green.offset;
		pScrn->mask.blue  = ((1 << fbVarScreenInfo.blue.length) - 1) << fbVarScreenInfo.blue.offset;
	}
#endif

	xf86SaveScreen(pScreen, SCREEN_SAVER_ON);

	return TRUE;
}