import ctypes as c from PIL import Image def capture(display_name,dest,window=None): x=c.CDLL('libX11.so.6') x.XOpenDisplay.argtypes=[c.c_char_p];x.XOpenDisplay.restype=c.c_void_p x.XDefaultRootWindow.argtypes=[c.c_void_p];x.XDefaultRootWindow.restype=c.c_ulong x.XGetGeometry.argtypes=[c.c_void_p,c.c_ulong,c.POINTER(c.c_ulong),c.POINTER(c.c_int),c.POINTER(c.c_int),c.POINTER(c.c_uint),c.POINTER(c.c_uint),c.POINTER(c.c_uint),c.POINTER(c.c_uint)] class XI(c.Structure): _fields_=[('width',c.c_int),('height',c.c_int),('xoffset',c.c_int),('format',c.c_int),('data',c.c_void_p),('byte_order',c.c_int),('bitmap_unit',c.c_int),('bitmap_bit_order',c.c_int),('bitmap_pad',c.c_int),('depth',c.c_int),('bytes_per_line',c.c_int),('bits_per_pixel',c.c_int),('red_mask',c.c_ulong),('green_mask',c.c_ulong),('blue_mask',c.c_ulong)] x.XGetImage.argtypes=[c.c_void_p,c.c_ulong,c.c_int,c.c_int,c.c_uint,c.c_uint,c.c_ulong,c.c_int];x.XGetImage.restype=c.POINTER(XI) x.XDestroyImage.argtypes=[c.POINTER(XI)];x.XCloseDisplay.argtypes=[c.c_void_p] d=x.XOpenDisplay(display_name.encode()) if not d:raise RuntimeError('Cannot open verified private display') root=window or x.XDefaultRootWindow(d);r=c.c_ulong();xx=c.c_int();yy=c.c_int();w=c.c_uint();h=c.c_uint();bw=c.c_uint();depth=c.c_uint() if not x.XGetGeometry(d,root,c.byref(r),c.byref(xx),c.byref(yy),c.byref(w),c.byref(h),c.byref(bw),c.byref(depth)):raise RuntimeError('No root geometry') im=x.XGetImage(d,root,0,0,w.value,h.value,c.c_ulong(-1).value,2) if not im:raise RuntimeError('No private screenshot') v=im.contents assert v.bits_per_pixel==32 and v.byte_order==0 and (v.red_mask,v.green_mask,v.blue_mask)==(0xff0000,0xff00,0xff) Image.frombytes('RGB',(w.value,h.value),c.string_at(v.data,v.bytes_per_line*h.value),'raw','BGRX',v.bytes_per_line).save(dest) x.XDestroyImage(im);x.XCloseDisplay(d)