mirror of
				https://github.com/hyperion-project/hyperion.ng.git
				synced 2025-03-01 10:33:28 +00:00 
			
		
		
		
	Update X11Grabber.cpp
Former-commit-id: 08b227fba33ca0f6974f10b085cf57c18e716428
This commit is contained in:
		| @@ -17,98 +17,114 @@ X11Grabber::X11Grabber(int cropLeft, int cropRight, int cropTop, int cropBottom, | ||||
|     _x11Display(nullptr), | ||||
|     _screenWidth(0), | ||||
|     _screenHeight(0), | ||||
|     _croppedWidth(0), | ||||
|     _croppedHeight(0), | ||||
|     _image(0,0) | ||||
| { | ||||
|     _imageResampler.setHorizontalPixelDecimation(horizontalPixelDecimation); | ||||
|     _imageResampler.setVerticalPixelDecimation(verticalPixelDecimation); | ||||
|     _imageResampler.setCropping(0, 0, 0, 0); // cropping is performed by XGetImage | ||||
|     _imageResampler.setCropping(0, 0, 0, 0); // cropping is performed by XShmGetImage | ||||
| } | ||||
|  | ||||
| X11Grabber::~X11Grabber() | ||||
| { | ||||
|     if (_x11Display != nullptr) | ||||
|     { | ||||
| 	freeResources(); | ||||
|         XCloseDisplay(_x11Display); | ||||
|     } | ||||
| } | ||||
|  | ||||
| int X11Grabber::open() | ||||
| void X11Grabber::freeResources() | ||||
| { | ||||
|     const char * display_name = nullptr; | ||||
|     _x11Display = XOpenDisplay(display_name); | ||||
|     // Cleanup allocated resources of the X11 grab | ||||
|     XShmDetach(_x11Display, &_shminfo); | ||||
|     XDestroyImage(_xImage); | ||||
|     shmdt(_shminfo.shmaddr); | ||||
|     shmctl(_shminfo.shmid, IPC_RMID, 0); | ||||
| } | ||||
|  | ||||
| void X11Grabber::setupResources() | ||||
| { | ||||
|     _xImage = XShmCreateImage(_x11Display, _windowAttr.visual, | ||||
|                 _windowAttr.depth, ZPixmap, NULL, &_shminfo, | ||||
|                 _croppedWidth, _croppedHeight); | ||||
|      | ||||
|     _shminfo.shmid = shmget(IPC_PRIVATE, _xImage->bytes_per_line * _xImage->height, IPC_CREAT|0777); | ||||
|     _shminfo.shmaddr = _xImage->data = (char*)shmat(_shminfo.shmid,0,0); | ||||
|     _shminfo.readOnly = False; | ||||
|      | ||||
|     XShmAttach(_x11Display, &_shminfo); | ||||
| } | ||||
|  | ||||
| bool X11Grabber::Setup() | ||||
| { | ||||
|     _x11Display = XOpenDisplay(NULL); | ||||
|     if (_x11Display == nullptr) | ||||
|     { | ||||
|         std::cerr << "Failed to open the default X11-display" << std::endl; | ||||
|         return -1; | ||||
|     } | ||||
|       std::cerr << "Unable to open display"; | ||||
|       if (getenv("DISPLAY")) | ||||
| 	std::cerr <<  " " << std::string(getenv("DISPLAY")) << std::endl; | ||||
|       else | ||||
| 	std::cerr << ". DISPLAY environment variable not set" << std::endl; | ||||
|       return false; | ||||
|      } | ||||
|       | ||||
|     _window = DefaultRootWindow(_x11Display); | ||||
|  | ||||
|     return 0; | ||||
| } | ||||
|     return true; | ||||
|  } | ||||
|  | ||||
| Image<ColorRgb> & X11Grabber::grab() | ||||
| { | ||||
|     if (_x11Display == nullptr) | ||||
|     { | ||||
|         open(); | ||||
|     } | ||||
|  | ||||
|     updateScreenDimensions(); | ||||
|      | ||||
|     Xscreen = DefaultScreenOfDisplay(_x11Display); | ||||
|  | ||||
|     const unsigned croppedWidth  = _screenWidth - _cropLeft - _cropRight; | ||||
|     const unsigned croppedHeight = _screenHeight - _cropTop - _cropBottom; | ||||
|      | ||||
|     xImage = XShmCreateImage(_x11Display,   DefaultVisualOfScreen(Xscreen), | ||||
| 				  DefaultDepthOfScreen(Xscreen), | ||||
| 				  ZPixmap, NULL, &shminfo, | ||||
| 				  croppedWidth, croppedHeight); | ||||
|      | ||||
|     shminfo.shmid = shmget(IPC_PRIVATE, xImage->bytes_per_line * xImage->height, IPC_CREAT|0777); | ||||
|     shminfo.shmaddr = xImage->data = (char*)shmat(shminfo.shmid,0,0); | ||||
|     shminfo.readOnly = False; | ||||
|      | ||||
|     XShmAttach(_x11Display, &shminfo); | ||||
|  | ||||
|     // Capture the current screen | ||||
|     XShmGetImage(_x11Display, DefaultRootWindow(_x11Display), xImage, _cropLeft, _cropTop, 0x00FFFFFF); | ||||
|     if (xImage == nullptr) | ||||
|     XShmGetImage(_x11Display, _window, _xImage, _cropLeft, _cropTop, 0x00FFFFFF); | ||||
|     if (_xImage == nullptr) | ||||
|     { | ||||
|         std::cerr << "Grab failed" << std::endl; | ||||
|         return _image; | ||||
|     } | ||||
|  | ||||
|     _imageResampler.processImage(reinterpret_cast<const uint8_t *>(xImage->data), xImage->width, xImage->height, xImage->bytes_per_line, PIXELFORMAT_BGR32, _image); | ||||
|  | ||||
|     // Cleanup allocated resources of the X11 grab | ||||
|     XShmDetach(_x11Display, &shminfo); | ||||
|     XDestroyImage(xImage); | ||||
|     shmdt (shminfo.shmaddr); | ||||
|     shmctl(shminfo.shmid, IPC_RMID, 0); | ||||
|     _imageResampler.processImage(reinterpret_cast<const uint8_t *>(_xImage->data), _xImage->width, _xImage->height, _xImage->bytes_per_line, PIXELFORMAT_BGR32, _image); | ||||
|  | ||||
|     return _image; | ||||
| } | ||||
|  | ||||
| int X11Grabber::updateScreenDimensions() | ||||
| { | ||||
|     XWindowAttributes window_attributes_return; | ||||
|     const Status status = XGetWindowAttributes(_x11Display, DefaultRootWindow(_x11Display), &window_attributes_return); | ||||
|     const Status status = XGetWindowAttributes(_x11Display, _window, &_windowAttr); | ||||
|     if (status == 0) | ||||
|     { | ||||
|         std::cerr << "Failed to obtain window attributes" << std::endl; | ||||
|         return -1; | ||||
|     } | ||||
|  | ||||
|     if (_screenWidth == unsigned(window_attributes_return.width) && _screenHeight == unsigned(window_attributes_return.height)) | ||||
|     if (_screenWidth == unsigned(_windowAttr.width) && _screenHeight == unsigned(_windowAttr.height)) | ||||
|     { | ||||
|         // No update required | ||||
|         return 0; | ||||
|     } | ||||
|      | ||||
|     std::cout << "Update of screen resolution: [" << _screenWidth << "x" << _screenHeight <<"] => "; | ||||
|     _screenWidth  = window_attributes_return.width; | ||||
|     _screenHeight = window_attributes_return.height; | ||||
|  | ||||
|     if (_screenWidth || _screenHeight) | ||||
|       freeResources(); | ||||
|      | ||||
|     _screenWidth  = _windowAttr.width; | ||||
|     _screenHeight = _windowAttr.height; | ||||
|      | ||||
|     std::cout << "[" << _screenWidth << "x" << _screenHeight <<"]" << std::endl; | ||||
|      | ||||
|     if (_screenWidth > unsigned(_cropLeft + _cropRight)) | ||||
|       _croppedWidth  = _screenWidth - _cropLeft - _cropRight; | ||||
|     else | ||||
|       _croppedWidth  = _screenWidth; | ||||
|      | ||||
|     if (_screenHeight > unsigned(_cropTop + _cropBottom)) | ||||
|       _croppedHeight = _screenHeight - _cropTop - _cropBottom; | ||||
|     else | ||||
|       _croppedHeight = _screenHeight; | ||||
|      | ||||
|     setupResources(); | ||||
|  | ||||
|     return 0; | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user