Exemplo n.º 1
0
ULONG APIENTRY
DrvGetModes(
   IN HANDLE hDriver,
   IN ULONG cjSize,
   OUT DEVMODEW *pdm)
{
   ULONG ModeCount;
   ULONG ModeInfoSize;
   PVIDEO_MODE_INFORMATION ModeInfo, ModeInfoPtr;
   ULONG OutputSize;

   ModeCount = GetAvailableModes(hDriver, &ModeInfo, &ModeInfoSize);
   if (ModeCount == 0)
   {
      return 0;
   }

   if (pdm == NULL)
   {
      EngFreeMem(ModeInfo);
      return ModeCount * sizeof(DEVMODEW);
   }

   /*
    * Copy the information about supported modes into the output buffer.
    */

   OutputSize = 0;
   ModeInfoPtr = ModeInfo;

   while (ModeCount-- > 0)
   {
      if (ModeInfoPtr->Length == 0)
      {
         ModeInfoPtr = (PVIDEO_MODE_INFORMATION)(((ULONG_PTR)ModeInfoPtr) + ModeInfoSize);
         continue;
      }

      memset(pdm, 0, sizeof(DEVMODEW));
      memcpy(pdm->dmDeviceName, DEVICE_NAME, sizeof(DEVICE_NAME));
      pdm->dmSpecVersion =
      pdm->dmDriverVersion = DM_SPECVERSION;
      pdm->dmSize = sizeof(DEVMODEW);
      pdm->dmDriverExtra = 0;
      pdm->dmBitsPerPel = ModeInfoPtr->NumberOfPlanes * ModeInfoPtr->BitsPerPlane;
      pdm->dmPelsWidth = ModeInfoPtr->VisScreenWidth;
      pdm->dmPelsHeight = ModeInfoPtr->VisScreenHeight;
      pdm->dmDisplayFrequency = ModeInfoPtr->Frequency;
      pdm->dmDisplayFlags = 0;
      pdm->dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT |
                      DM_DISPLAYFREQUENCY | DM_DISPLAYFLAGS;

      ModeInfoPtr = (PVIDEO_MODE_INFORMATION)(((ULONG_PTR)ModeInfoPtr) + ModeInfoSize);
      pdm = (LPDEVMODEW)(((ULONG_PTR)pdm) + sizeof(DEVMODEW));
      OutputSize += sizeof(DEVMODEW);
   }

   EngFreeMem(ModeInfo);
   return OutputSize;
}
Exemplo n.º 2
0
int main(int argc, char* argv[])
{
	struct filter filter;

	filter.include_all = false;
	filter.include_supported = true;
	filter.include_unsupported = false;
	filter.include_text = true;
	filter.include_graphics = true;
	// TODO: HACK: The kernel log printing requires either text mode or 32-bit
	// graphics. For now, just filter away anything but 32-bit graphics.
	filter.minbpp = 32;
	filter.maxbpp = 32;
	filter.minxres = 0;
	filter.maxxres = SIZE_MAX;
	filter.minyres = 0;
	filter.maxyres = SIZE_MAX;
	filter.minxchars = 0;
	filter.maxxchars = SIZE_MAX;
	filter.minychars = 0;
	filter.maxychars = SIZE_MAX;

	const char* argv0 = argv[0];
	for ( int i = 1; i < argc; i++ )
	{
		const char* arg = argv[i];
		if ( arg[0] != '-' || !arg[1] )
			break; // Intentionally not continue.
		argv[i] = NULL;
		if ( !strcmp(arg, "--") )
			break;
		if ( arg[1] != '-' )
		{
			char c;
			while ( (c = *++arg) ) switch ( c )
			{
			default:
				fprintf(stderr, "%s: unknown option -- '%c'\n", argv0, c);
				help(stderr, argv0);
				exit(1);
			}
		}
		else if ( !strcmp(arg, "--help") )
			help(stdout, argv0), exit(0);
		else if ( !strcmp(arg, "--version") )
			version(stdout, argv0), exit(0);
		else if ( BOOL_PARAMETER("show-all", &filter.include_all) ) { }
		else if ( BOOL_PARAMETER("show-supported", &filter.include_supported) ) { }
		else if ( BOOL_PARAMETER("show-unsupported", &filter.include_unsupported) ) { }
		else if ( BOOL_PARAMETER("show-text", &filter.include_text) ) { }
		else if ( BOOL_PARAMETER("show-graphics", &filter.include_graphics) ) { }
		else if ( MINMAX_PARAMETER("bpp", &filter.minbpp, &filter.maxbpp) ) { }
		else if ( MINMAX_PARAMETER("width", &filter.minxres, &filter.maxxres) ) { }
		else if ( MINMAX_PARAMETER("height", &filter.minyres, &filter.maxyres) ) { }
		else
		{
			fprintf(stderr, "%s: unknown option: %s\n", argv0, arg);
			help(stderr, argv0);
			exit(1);
		}
	}

	compact_arguments(&argc, &argv);

	size_t num_modes = 0;
	struct dispmsg_crtc_mode* modes = GetAvailableModes(&num_modes);
	if ( !modes )
		error(1, errno, "Unable to detect available video modes");

	if ( !num_modes )
	{
		fprintf(stderr, "No video modes are currently available.\n");
		fprintf(stderr, "Try make sure a device driver exists and is activated.\n");
		exit(11);
	}

	filter_modes(modes, &num_modes, &filter);
	if ( !num_modes )
	{
		fprintf(stderr, "No video mode remains after filtering away unwanted modes.\n");
		fprintf(stderr, "Try make sure the desired device driver is loaded and is configured correctly.\n");
		exit(12);
	}

	int num_modes_display_length = 1;
	for ( size_t i = num_modes; 10 <= i; i /= 10 )
		num_modes_display_length++;

	int mode_set_error = 0;
	size_t selection;
	bool decided;
	bool first_render;
	struct wincurpos render_at;
retry_pick_mode:
	selection = 0;
	decided = false;
	first_render = true;
	memset(&render_at, 0, sizeof(render_at));
	while ( !decided )
	{
		fflush(stdout);

		struct winsize ws;
		if ( tcgetwinsize(1, &ws) != 0 )
		{
			ws.ws_col = 80;
			ws.ws_row = 25;
		}

		struct wincurpos wcp;
		if ( tcgetwincurpos(1, &wcp) != 0 )
		{
			wcp.wcp_col = 1;
			wcp.wcp_row = 1;
		}

		size_t off = 1; // The "Please select ..." line at the top.
		if ( mode_set_error )
			off++;

		size_t entries_per_page = ws.ws_row - off;
		size_t page = selection / entries_per_page;
		size_t from = page * entries_per_page;
		size_t how_many_available = num_modes - from;
		size_t how_many = entries_per_page;
		if ( how_many_available < how_many )
			how_many = how_many_available;
		size_t lines_on_screen = off + how_many;

		if ( first_render )
		{
			while ( wcp.wcp_row && ws.ws_row - (wcp.wcp_row + 1) < lines_on_screen )
			{
				printf("\e[S");
				printf("\e[%juH", 1 + (uintmax_t) wcp.wcp_row);
				wcp.wcp_row--;
				wcp.wcp_col = 1;
			}
			render_at = wcp;
			first_render = false;
		}

		printf("\e[m");
		printf("\e[%juH", 1 + (uintmax_t) render_at.wcp_row);
		printf("\e[2K");

		if ( mode_set_error )
			printf("Error: Could not set desired mode: %s\n", strerror(mode_set_error));
		printf("Please select one of these video modes or press ESC to abort.\n");

		for ( size_t i = 0; i < how_many; i++ )
		{
			size_t index = from + i;
			size_t screenline = off + index - from;
			const char* color = index == selection ? "\e[31m" : "\e[m";
			printf("\e[%zuH", 1 + render_at.wcp_row + screenline);
			printf("%s", color);
			printf("\e[2K");
			printf(" [%-*zu] ", num_modes_display_length, index);
			if ( modes[i].control & DISPMSG_CONTROL_VALID )
				printf("%u x %u x %u",
					modes[i].fb_format,
					modes[i].view_xres,
					modes[i].view_yres);
			else if ( modes[i].control & DISPMSG_CONTROL_OTHER_RESOLUTIONS )
				printf("(enter a custom resolution)");
			else
				printf("(unknown video device feature)");
			printf("\e[m");
		}

		printf("\e[J");
		fflush(stdout);

		unsigned int oldtermmode;
		if ( gettermmode(0, &oldtermmode) < 0 )
			error(1, errno, "gettermmode");

		if ( settermmode(0, TERMMODE_KBKEY | TERMMODE_UNICODE | TERMMODE_SIGNAL) < 0 )
			error(1, errno, "settermmode");

		bool redraw = false;
		while ( !redraw && !decided )
		{
			uint32_t codepoint;
			ssize_t numbytes = read(0, &codepoint, sizeof(codepoint));
			if ( numbytes < 0 )
				error(1, errno, "read");

			int kbkey = KBKEY_DECODE(codepoint);
			if ( kbkey )
			{
				switch ( kbkey )
				{
				case KBKEY_ESC:
					if ( settermmode(0, oldtermmode) < 0 )
						error(1, errno, "settermmode");
					printf("\n");
					exit(10);
					break;
				case KBKEY_UP:
					if ( selection )
						selection--;
					else
						selection = num_modes -1;
					redraw = true;
					break;
				case KBKEY_DOWN:
					if ( selection + 1 == num_modes )
						selection = 0;
					else
						selection++;
					redraw = true;
					break;
				case KBKEY_ENTER:
					if ( settermmode(0, oldtermmode) < 0 )
						error(1, errno, "settermmode");
					fgetc(stdin);
					printf("\n");
					decided = true;
					break;
				}
			}
			else
			{
				if ( L'0' <= codepoint && codepoint <= '9' )
				{
					uint32_t requested = codepoint - '0';
					if ( requested < num_modes )
					{
						selection = requested;
						redraw = true;
					}
				}
			}
		}

		if ( settermmode(0, oldtermmode) < 0 )
			error(1, errno, "settermmode");
	}

	struct dispmsg_crtc_mode mode = modes[selection];
	if ( mode.control & DISPMSG_CONTROL_OTHER_RESOLUTIONS )
	{
		uintmax_t req_bpp;
		uintmax_t req_width;
		uintmax_t req_height;
		while ( true )
		{
			printf("Enter video mode [BPP x WIDTH x HEIGHT]: ");
			fflush(stdout);
			if ( scanf("%ju x %ju x %ju", &req_bpp, &req_width, &req_height) != 3 )
			{
				fgetc(stdin);
				fflush(stdin);
				continue;
			}
			fgetc(stdin);
			break;
		}
		mode.fb_format = req_bpp;
		mode.view_xres = req_width;
		mode.view_yres = req_height;
		mode.control &= ~DISPMSG_CONTROL_OTHER_RESOLUTIONS;
		mode.control |= DISPMSG_CONTROL_VALID;
	}

	if ( !SetCurrentMode(mode) )
	{
		error(0, mode_set_error = errno, "Unable to set video mode %ju x %ju x %ju",
			(uintmax_t) mode.fb_format,
			(uintmax_t) mode.view_xres,
			(uintmax_t) mode.view_yres);
		goto retry_pick_mode;
	}

	if ( 1 < argc )
	{
		execvp(argv[1], argv + 1);
		error(127, errno, "`%s'", argv[1]);
	}

	return 0;
}
Exemplo n.º 3
0
BOOL
IntInitScreenInfo(
   PPDEV ppdev,
   LPDEVMODEW pDevMode,
   PGDIINFO pGdiInfo,
   PDEVINFO pDevInfo)
{
   ULONG ModeCount;
   ULONG ModeInfoSize;
   PVIDEO_MODE_INFORMATION ModeInfo, ModeInfoPtr, SelectedMode = NULL;
   VIDEO_COLOR_CAPABILITIES ColorCapabilities;
/* hack 
   LOGFONTW SystemFont = {16, 7, 0, 0, 700, 0, 0, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, VARIABLE_PITCH | FF_DONTCARE, L"System"};
   LOGFONTW AnsiVariableFont = {12, 9, 0, 0, 400, 0, 0, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_STROKE_PRECIS, PROOF_QUALITY, VARIABLE_PITCH | FF_DONTCARE, L"MS Sans Serif"};
   LOGFONTW AnsiFixedFont = {12, 9, 0, 0, 400, 0, 0, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_STROKE_PRECIS, PROOF_QUALITY, FIXED_PITCH | FF_DONTCARE, L"Courier"};
*/
   ULONG Temp;

   /*
    * Call miniport to get information about video modes.
    */

   ModeCount = GetAvailableModes(ppdev->hDriver, &ModeInfo, &ModeInfoSize);
   if (ModeCount == 0)
   {
      return FALSE;
   }

   /*
    * Select the video mode depending on the info passed in pDevMode.
    */

   if (pDevMode->dmPelsWidth == 0 && pDevMode->dmPelsHeight == 0 &&
       pDevMode->dmBitsPerPel == 0 && pDevMode->dmDisplayFrequency == 0)
   {
      ModeInfoPtr = ModeInfo;
      while (ModeCount-- > 0)
      {
         if (ModeInfoPtr->Length == 0)
         {
            ModeInfoPtr = (PVIDEO_MODE_INFORMATION)
               (((PUCHAR)ModeInfoPtr) + ModeInfoSize);
            continue;
         }
         SelectedMode = ModeInfoPtr;
         break;
      }
   }
   else
   {
      ModeInfoPtr = ModeInfo;
      while (ModeCount-- > 0)
      {
         if (ModeInfoPtr->Length > 0 &&
	     pDevMode->dmPelsWidth == ModeInfoPtr->VisScreenWidth &&
             pDevMode->dmPelsHeight == ModeInfoPtr->VisScreenHeight &&
             pDevMode->dmBitsPerPel == (ModeInfoPtr->BitsPerPlane *
                                        ModeInfoPtr->NumberOfPlanes) &&
             pDevMode->dmDisplayFrequency == ModeInfoPtr->Frequency)
         {
            SelectedMode = ModeInfoPtr;
            break;
         }

         ModeInfoPtr = (PVIDEO_MODE_INFORMATION)
            (((PUCHAR)ModeInfoPtr) + ModeInfoSize);
      }
   }

   if (SelectedMode == NULL)
   {
      EngFreeMem(ModeInfo);
      return FALSE;
   }

   /*
    * Fill in the GDIINFO data structure with the information returned from
    * the kernel driver.
    */

   ppdev->ModeIndex = SelectedMode->ModeIndex;
   ppdev->ScreenWidth = SelectedMode->VisScreenWidth;
   ppdev->ScreenHeight = SelectedMode->VisScreenHeight;
   ppdev->ScreenDelta = SelectedMode->ScreenStride;
   ppdev->BitsPerPixel = SelectedMode->BitsPerPlane * SelectedMode->NumberOfPlanes;

   ppdev->MemWidth = SelectedMode->VideoMemoryBitmapWidth;
   ppdev->MemHeight = SelectedMode->VideoMemoryBitmapHeight;

   ppdev->RedMask = SelectedMode->RedMask;
   ppdev->GreenMask = SelectedMode->GreenMask;
   ppdev->BlueMask = SelectedMode->BlueMask;

   pGdiInfo->ulVersion = GDI_DRIVER_VERSION;
   pGdiInfo->ulTechnology = DT_RASDISPLAY;
   pGdiInfo->ulHorzSize = SelectedMode->XMillimeter;
   pGdiInfo->ulVertSize = SelectedMode->YMillimeter;
   pGdiInfo->ulHorzRes = SelectedMode->VisScreenWidth;
   pGdiInfo->ulVertRes = SelectedMode->VisScreenHeight;
   pGdiInfo->ulPanningHorzRes = SelectedMode->VisScreenWidth;
   pGdiInfo->ulPanningVertRes = SelectedMode->VisScreenHeight;
   pGdiInfo->cBitsPixel = SelectedMode->BitsPerPlane;
   pGdiInfo->cPlanes = SelectedMode->NumberOfPlanes;
   pGdiInfo->ulVRefresh = SelectedMode->Frequency;
   pGdiInfo->ulBltAlignment = 1;
   pGdiInfo->ulLogPixelsX = pDevMode->dmLogPixels;
   pGdiInfo->ulLogPixelsY = pDevMode->dmLogPixels;
   pGdiInfo->flTextCaps = TC_RA_ABLE;
   pGdiInfo->flRaster = 0;
   pGdiInfo->ulDACRed = SelectedMode->NumberRedBits;
   pGdiInfo->ulDACGreen = SelectedMode->NumberGreenBits;
   pGdiInfo->ulDACBlue = SelectedMode->NumberBlueBits;
   pGdiInfo->ulAspectX = 0x24;
   pGdiInfo->ulAspectY = 0x24;
   pGdiInfo->ulAspectXY = 0x33;
   pGdiInfo->xStyleStep = 1;
   pGdiInfo->yStyleStep = 1;
   pGdiInfo->denStyleStep = 3;
   pGdiInfo->ptlPhysOffset.x = 0;
   pGdiInfo->ptlPhysOffset.y = 0;
   pGdiInfo->szlPhysSize.cx = 0;
   pGdiInfo->szlPhysSize.cy = 0;

   /*
    * Try to get the color info from the miniport.
    */

   if (!EngDeviceIoControl(ppdev->hDriver, IOCTL_VIDEO_QUERY_COLOR_CAPABILITIES,
                           NULL, 0, &ColorCapabilities,
                           sizeof(VIDEO_COLOR_CAPABILITIES), &Temp))
   {
      pGdiInfo->ciDevice.Red.x = ColorCapabilities.RedChromaticity_x;
      pGdiInfo->ciDevice.Red.y = ColorCapabilities.RedChromaticity_y;
      pGdiInfo->ciDevice.Green.x = ColorCapabilities.GreenChromaticity_x;
      pGdiInfo->ciDevice.Green.y = ColorCapabilities.GreenChromaticity_y;
      pGdiInfo->ciDevice.Blue.x = ColorCapabilities.BlueChromaticity_x;
      pGdiInfo->ciDevice.Blue.y = ColorCapabilities.BlueChromaticity_y;
      pGdiInfo->ciDevice.AlignmentWhite.x = ColorCapabilities.WhiteChromaticity_x;
      pGdiInfo->ciDevice.AlignmentWhite.y = ColorCapabilities.WhiteChromaticity_y;
      pGdiInfo->ciDevice.AlignmentWhite.Y = ColorCapabilities.WhiteChromaticity_Y;
      if (ColorCapabilities.AttributeFlags & VIDEO_DEVICE_COLOR)
      {
         pGdiInfo->ciDevice.RedGamma = ColorCapabilities.RedGamma;
         pGdiInfo->ciDevice.GreenGamma = ColorCapabilities.GreenGamma;
         pGdiInfo->ciDevice.BlueGamma = ColorCapabilities.BlueGamma;
      }
      else
      {
         pGdiInfo->ciDevice.RedGamma = ColorCapabilities.WhiteGamma;
         pGdiInfo->ciDevice.GreenGamma = ColorCapabilities.WhiteGamma;
         pGdiInfo->ciDevice.BlueGamma = ColorCapabilities.WhiteGamma;
      }
   }
   else
   {
      pGdiInfo->ciDevice.Red.x = 6700;
      pGdiInfo->ciDevice.Red.y = 3300;
      pGdiInfo->ciDevice.Green.x = 2100;
      pGdiInfo->ciDevice.Green.y = 7100;
      pGdiInfo->ciDevice.Blue.x = 1400;
      pGdiInfo->ciDevice.Blue.y = 800;
      pGdiInfo->ciDevice.AlignmentWhite.x = 3127;
      pGdiInfo->ciDevice.AlignmentWhite.y = 3290;
      pGdiInfo->ciDevice.AlignmentWhite.Y = 0;
      pGdiInfo->ciDevice.RedGamma = 20000;
      pGdiInfo->ciDevice.GreenGamma = 20000;
      pGdiInfo->ciDevice.BlueGamma = 20000;
   }

   pGdiInfo->ciDevice.Red.Y = 0;
   pGdiInfo->ciDevice.Green.Y = 0;
   pGdiInfo->ciDevice.Blue.Y = 0;
   pGdiInfo->ciDevice.Cyan.x = 0;
   pGdiInfo->ciDevice.Cyan.y = 0;
   pGdiInfo->ciDevice.Cyan.Y = 0;
   pGdiInfo->ciDevice.Magenta.x = 0;
   pGdiInfo->ciDevice.Magenta.y = 0;
   pGdiInfo->ciDevice.Magenta.Y = 0;
   pGdiInfo->ciDevice.Yellow.x = 0;
   pGdiInfo->ciDevice.Yellow.y = 0;
   pGdiInfo->ciDevice.Yellow.Y = 0;
   pGdiInfo->ciDevice.MagentaInCyanDye = 0;
   pGdiInfo->ciDevice.YellowInCyanDye = 0;
   pGdiInfo->ciDevice.CyanInMagentaDye = 0;
   pGdiInfo->ciDevice.YellowInMagentaDye = 0;
   pGdiInfo->ciDevice.CyanInYellowDye = 0;
   pGdiInfo->ciDevice.MagentaInYellowDye = 0;
   pGdiInfo->ulDevicePelsDPI = 0;
   pGdiInfo->ulPrimaryOrder = PRIMARY_ORDER_CBA;
   pGdiInfo->ulHTPatternSize = HT_PATSIZE_4x4_M;
   pGdiInfo->flHTFlags = HT_FLAG_ADDITIVE_PRIMS;

   pDevInfo->flGraphicsCaps = 0;
/* hack 
   pDevInfo->lfDefaultFont = SystemFont;
   pDevInfo->lfAnsiVarFont = AnsiVariableFont;
   pDevInfo->lfAnsiFixFont = AnsiFixedFont;
*/
   pDevInfo->cFonts = 0;
   pDevInfo->cxDither = 0;
   pDevInfo->cyDither = 0;
   pDevInfo->hpalDefault = 0;
   pDevInfo->flGraphicsCaps2 = 0;

   if (ppdev->BitsPerPixel == 8)
   {
      pGdiInfo->ulNumColors = 20;
      pGdiInfo->ulNumPalReg = 1 << ppdev->BitsPerPixel;
      pGdiInfo->ulHTOutputFormat = HT_FORMAT_8BPP;
      pDevInfo->flGraphicsCaps |= GCAPS_PALMANAGED;
      pDevInfo->iDitherFormat = BMF_8BPP;
      /* Assuming palette is orthogonal - all colors are same size. */
      ppdev->PaletteShift = 8 - pGdiInfo->ulDACRed;
   }
   else
   {
      pGdiInfo->ulNumColors = (ULONG)(-1);
      pGdiInfo->ulNumPalReg = 0;
      switch (ppdev->BitsPerPixel)
      {
         case 16:
            pGdiInfo->ulHTOutputFormat = HT_FORMAT_16BPP;
            pDevInfo->iDitherFormat = BMF_16BPP;
            break;

         case 24:
            pGdiInfo->ulHTOutputFormat = HT_FORMAT_24BPP;
            pDevInfo->iDitherFormat = BMF_24BPP;
            break;

         default:
            pGdiInfo->ulHTOutputFormat = HT_FORMAT_32BPP;
            pDevInfo->iDitherFormat = BMF_32BPP;
      }
   }

   EngFreeMem(ModeInfo);
   return TRUE;
}