接上一篇文章《X11 Xlib截屏问题及深入分析一 —— 源码位置》,链接为:

X11 Xlib截屏问题及深入分析一 —— 源码位置_蓝天居士的博客-CSDN博客

上一篇文章讲到了源码包的内容,本文看一下几个接口函数对应的位置。再次列出应用源码:

#include <stdio.h>
#include <stdlib.h>
#include <X11/Xlib.h>int main(int argc, char *argv[])
{Display *display = XOpenDisplay(NULL);if(!display){printf("XOpenDisplay failed\n");return -1;}int screen_num = DefaultScreen(display);printf("default screen_num is: %d\n", screen_num);int screen_width = DisplayWidth(display, screen_num);int screen_height = DisplayHeight(display, screen_num);printf("screen_width: %d, screen_height: %d\n", screen_width, screen_height);Window root_win = RootWindow(display, screen_num);if(!root_win){printf("can not get root window\n");return -1;}Window disp_win = XCreateSimpleWindow(display, root_win, 0, 0, screen_width, screen_height, 1, 0, 0) ;if(!disp_win){printf("can not get snapshot display window\n");return -1;}XMapWindow(display, disp_win);XImage *img = XGetImage(display, root_win, 0, 0, screen_width, screen_height, ~0, ZPixmap);  XPutImage(display, disp_win, DefaultGC(display, screen_num), img, 0, 0, 0, 0, screen_width, screen_height);char c = getchar();//XDestroyImage(img);XCloseDisplay(display);printf("screen_snapshot finished\n");return 0;
}

由以上代码可以看到,总共调用了几个接口函数:

  • XOpenDisplay
  • XCloseDisplay
  • XCreateSimpleWindow
  • XMapWindow
  • XGetImage
  • XPutImage

下边分别列出各个接口函数对应源码。

  • XOpenDisplay源码

XOpenDisplay函数对应的源码在src/OpenDis.c中。如下所示:

/** Connects to a server, creates a Display object and returns a pointer to* the newly created Display back to the caller.*/
Display *
XOpenDisplay (register _Xconst char *display)
{register Display *dpy;     /* New Display object being created. */register int i;int j, k;         /* random iterator indexes */char *display_name;        /* pointer to display name */char *setup = NULL;       /* memory allocated at startup */int iscreen;           /* screen number */xConnSetupPrefix prefix; /* prefix information */int vendorlen;          /* length of vendor string */union {xConnSetup *setup;char *failure;char *vendor;xPixmapFormat *sf;xWindowRoot *rp;xDepth *dp;xVisualType *vp;} u;              /* proto data returned from server */long setuplength;  /* number of bytes in setup message */long usedbytes = 0;     /* number of bytes we have processed */unsigned long mask;long int conn_buf_size;char *xlib_buffer_size;/** If the display specifier string supplied as an argument to this* routine is NULL or a pointer to NULL, read the DISPLAY variable.*/if (display == NULL || *display == '\0') {if ((display_name = getenv("DISPLAY")) == NULL) {/* Oops! No DISPLAY environment variable - error. */return(NULL);}}else {/* Display is non-NULL, copy the pointer */display_name = (char *)display;}/** Set the default error handlers.  This allows the global variables to* default to NULL for use with shared libraries.*/if (_XErrorFunction == NULL) (void) XSetErrorHandler (NULL);if (_XIOErrorFunction == NULL) (void) XSetIOErrorHandler (NULL);/** Attempt to allocate a display structure. Return NULL if allocation fails.*/if ((dpy = Xcalloc(1, sizeof(Display))) == NULL) {return(NULL);}if ((dpy->display_name = strdup(display_name)) == NULL) {OutOfMemory(dpy);return(NULL);}/** Call the Connect routine to get the transport connection object.* If NULL is returned, the connection failed.*/if(!_XConnectXCB(dpy, display, &iscreen)) {OutOfMemory(dpy);return NULL;}/* Initialize as much of the display structure as we can.* Initialize pointers to NULL so that XFreeDisplayStructure will* work if we run out of memory before we finish initializing.*/dpy->keysyms      = (KeySym *) NULL;dpy->modifiermap  = NULL;dpy->lock_meaning    = NoSymbol;dpy->keysyms_per_keycode = 0;dpy->xdefaults      = (char *)NULL;dpy->scratch_length  = 0L;dpy->scratch_buffer    = NULL;dpy->key_bindings    = NULL;dpy->ext_procs       = (_XExtension *)NULL;dpy->ext_data     = (XExtData *)NULL;dpy->ext_number  = 0;dpy->event_vec[X_Error] = _XUnknownWireEvent;dpy->event_vec[X_Reply] = _XUnknownWireEvent;dpy->wire_vec[X_Error]  = _XUnknownNativeEvent;dpy->wire_vec[X_Reply]  = _XUnknownNativeEvent;for (i = KeyPress; i < LASTEvent; i++) {dpy->event_vec[i]     = _XWireToEvent;dpy->wire_vec[i]    = NULL;}for (i = LASTEvent; i < 128; i++) {dpy->event_vec[i]  = _XUnknownWireEvent;dpy->wire_vec[i]   = _XUnknownNativeEvent;}dpy->resource_id    = 0;dpy->db         = (struct _XrmHashBucketRec *)NULL;dpy->cursor_font = None;dpy->flags       = 0;dpy->async_handlers = NULL;dpy->screens     = NULL;dpy->vendor      = NULL;dpy->buffer      = NULL;dpy->atoms       = NULL;dpy->error_vec       = NULL;dpy->context_db      = NULL;dpy->free_funcs      = NULL;dpy->pixmap_format   = NULL;dpy->cms.clientCmaps = NULL;dpy->cms.defaultCCCs = NULL;dpy->cms.perVisualIntensityMaps = NULL;dpy->im_filters       = NULL;dpy->bigreq_size = 0;dpy->lock       = NULL;dpy->lock_fns        = NULL;dpy->qfree       = NULL;dpy->next_event_serial_num = 1;dpy->im_fd_info       = NULL;dpy->im_fd_length    = 0;dpy->conn_watchers  = NULL;dpy->watcher_count   = 0;dpy->filedes        = NULL;dpy->flushes     = NULL;dpy->xcmisc_opcode   = 0;dpy->xkb_info       = NULL;dpy->exit_handler_data   = NULL;/** Setup other information in this display structure.*/dpy->vnumber = X_PROTOCOL;dpy->resource_alloc = _XAllocID;dpy->idlist_alloc = _XAllocIDs;dpy->synchandler = NULL;dpy->savedsynchandler = NULL;X_DPY_SET_REQUEST(dpy, 0);X_DPY_SET_LAST_REQUEST_READ(dpy, 0);dpy->default_screen = iscreen;  /* Value returned by ConnectDisplay */dpy->last_req = (char *)&_dummy_request;dpy->error_threads = NULL;dpy->exit_handler = _XDefaultIOErrorExit;/* Initialize the display lock */if (InitDisplayLock(dpy) != 0) {OutOfMemory (dpy);return(NULL);}if (!_XPollfdCacheInit(dpy)) {OutOfMemory (dpy);return(NULL);}/* Set up the output buffers. */
#ifndef XLIBDEFAULTBUFSIZE
#define XLIBDEFAULTBUFSIZE 16384 /* 16k */
#endif
#ifndef XLIBMINBUFSIZE
#define XLIBMINBUFSIZE BUFSIZE /* old default buffer size */
#endifxlib_buffer_size = getenv("XLIBBUFFERSIZE");#ifdef __sun /* Backwards compatibility for old Solaris libX11 name */if (xlib_buffer_size == NULL)xlib_buffer_size = getenv("XSUNBUFFERSIZE");
#endifif (xlib_buffer_size == NULL)conn_buf_size = XLIBDEFAULTBUFSIZE;elseconn_buf_size = 1024 * strtol(xlib_buffer_size, NULL, 10);if (conn_buf_size < XLIBMINBUFSIZE)conn_buf_size = XLIBMINBUFSIZE;if ((dpy->bufptr = dpy->buffer = Xcalloc(1, conn_buf_size)) == NULL) {OutOfMemory (dpy);return(NULL);}dpy->xcb->real_bufmax = dpy->buffer + conn_buf_size;dpy->bufmax = dpy->buffer;/* Set up the input event queue and input event queue parameters. */dpy->head = dpy->tail = NULL;dpy->qlen = 0;/* Set up free-function record */if ((dpy->free_funcs = Xcalloc(1, sizeof(_XFreeFuncRec))) == NULL) {OutOfMemory (dpy);return(NULL);}{const struct xcb_setup_t *xcbsetup = xcb_get_setup(dpy->xcb->connection);memcpy(&prefix, xcbsetup, sizeof(prefix));setuplength = prefix.length << 2;setup = (char *) xcbsetup;setup += SIZEOF(xConnSetupPrefix);u.setup = (xConnSetup *) setup;}/** Check if the reply was long enough to get any information out of it.*/usedbytes = sz_xConnSetup;if (setuplength < usedbytes ) {fprintf (stderr, "Xlib: Broken initial reply: Too short (%ld)\n", setuplength);OutOfMemory(dpy);return (NULL);}/** We succeeded at authorization, so let us move the data into* the display structure.*/dpy->proto_major_version= prefix.majorVersion;dpy->proto_minor_version= prefix.minorVersion;dpy->release         = u.setup->release;dpy->resource_base    = u.setup->ridBase;dpy->resource_mask    = u.setup->ridMask;dpy->min_keycode  = u.setup->minKeyCode;dpy->max_keycode   = u.setup->maxKeyCode;dpy->motion_buffer = u.setup->motionBufferSize;dpy->nformats        = u.setup->numFormats;dpy->nscreens      = u.setup->numRoots;dpy->byte_order      = u.setup->imageByteOrder;dpy->bitmap_unit   = u.setup->bitmapScanlineUnit;dpy->bitmap_pad        = u.setup->bitmapScanlinePad;dpy->bitmap_bit_order   = u.setup->bitmapBitOrder;dpy->max_request_size  = u.setup->maxRequestSize;mask = dpy->resource_mask;dpy->resource_shift  = 0;if (!mask){fprintf (stderr, "Xlib: connection to \"%s\" invalid setup\n",dpy->display_name);OutOfMemory(dpy);return (NULL);}while (!(mask & 1)) {dpy->resource_shift++;mask = mask >> 1;}dpy->resource_max = (dpy->resource_mask >> dpy->resource_shift) - 5;
/** now extract the vendor string...  String must be null terminated,* padded to multiple of 4 bytes.*//* Check for a sane vendor string length */if (u.setup->nbytesVendor > 256) {OutOfMemory(dpy);return (NULL);}dpy->vendor = Xmalloc(u.setup->nbytesVendor + 1);if (dpy->vendor == NULL) {OutOfMemory(dpy);return (NULL);}vendorlen = u.setup->nbytesVendor;/** validate setup length*/usedbytes += (vendorlen + 3) & ~3;if (setuplength < usedbytes) {fprintf (stderr, "Xlib: Broken initial reply: Too short (%ld)\n", setuplength);OutOfMemory(dpy);return (NULL);}u.setup = (xConnSetup *) (((char *) u.setup) + sz_xConnSetup);(void) strncpy(dpy->vendor, u.vendor, (size_t) vendorlen);dpy->vendor[vendorlen] = '\0';vendorlen = (vendorlen + 3) & ~3;  /* round up */u.vendor += vendorlen;/** Now iterate down setup information.....*/dpy->pixmap_format = Xcalloc(dpy->nformats, sizeof(ScreenFormat));if (dpy->pixmap_format == NULL) {OutOfMemory (dpy);return(NULL);}
/** First decode the Z axis Screen format information.*/usedbytes += dpy->nformats * sz_xPixmapFormat;if (setuplength < usedbytes) {fprintf (stderr, "Xlib: Broken initial reply: Too short (%ld)\n", setuplength);OutOfMemory (dpy);return(NULL);}for (i = 0; i < dpy->nformats; i++) {register ScreenFormat *fmt = &dpy->pixmap_format[i];fmt->depth = u.sf->depth;fmt->bits_per_pixel = u.sf->bitsPerPixel;fmt->scanline_pad = u.sf->scanLinePad;fmt->ext_data = NULL;u.sf = (xPixmapFormat *) (((char *) u.sf) + sz_xPixmapFormat);}/** next the Screen structures.*/dpy->screens = Xcalloc(dpy->nscreens, sizeof(Screen));if (dpy->screens == NULL) {OutOfMemory (dpy);return(NULL);}/** Now go deal with each screen structure.*/for (i = 0; i < dpy->nscreens; i++) {register Screen *sp = &dpy->screens[i];VisualID root_visualID;usedbytes += sz_xWindowRoot;if (setuplength < usedbytes) {fprintf (stderr, "Xlib: Broken initial reply: Too short (%ld)\n", setuplength);OutOfMemory (dpy);return(NULL);}root_visualID = u.rp->rootVisualID;sp->display      = dpy;sp->root      = u.rp->windowId;sp->cmap        = u.rp->defaultColormap;sp->white_pixel = u.rp->whitePixel;sp->black_pixel = u.rp->blackPixel;sp->root_input_mask = u.rp->currentInputMask;sp->width        = u.rp->pixWidth;sp->height      = u.rp->pixHeight;sp->mwidth     = u.rp->mmWidth;sp->mheight      = u.rp->mmHeight;sp->min_maps    = u.rp->minInstalledMaps;sp->max_maps    = u.rp->maxInstalledMaps;sp->backing_store= u.rp->backingStore;sp->save_unders = u.rp->saveUnders;sp->root_depth  = u.rp->rootDepth;sp->ndepths     = u.rp->nDepths;sp->ext_data   = NULL;u.rp = (xWindowRoot *) (((char *) u.rp) + sz_xWindowRoot);
/** lets set up the depth structures.*/sp->depths = Xcalloc(sp->ndepths, sizeof(Depth));if (sp->depths == NULL) {OutOfMemory (dpy);return(NULL);}/** for all depths on this screen.*/for (j = 0; j < sp->ndepths; j++) {Depth *dp = &sp->depths[j];usedbytes += sz_xDepth;if (setuplength < usedbytes) {fprintf (stderr, "Xlib: Broken initial reply: Too short (%ld)\n", setuplength);OutOfMemory (dpy);return(NULL);}dp->depth = u.dp->depth;dp->nvisuals = u.dp->nVisuals;u.dp = (xDepth *) (((char *) u.dp) + sz_xDepth);if (dp->nvisuals > 0) {dp->visuals = Xcalloc(dp->nvisuals, sizeof(Visual));if (dp->visuals == NULL) {OutOfMemory (dpy);return(NULL);}for (k = 0; k < dp->nvisuals; k++) {register Visual *vp = &dp->visuals[k];usedbytes += sz_xVisualType;if (setuplength < usedbytes) {fprintf (stderr, "Xlib: Broken initial reply: Too short (%ld)\n", setuplength);OutOfMemory (dpy);return(NULL);}vp->visualid  = u.vp->visualID;vp->class   = u.vp->class;vp->bits_per_rgb= u.vp->bitsPerRGB;vp->map_entries  = u.vp->colormapEntries;vp->red_mask = u.vp->redMask;vp->green_mask   = u.vp->greenMask;vp->blue_mask  = u.vp->blueMask;vp->ext_data    = NULL;u.vp = (xVisualType *) (((char *) u.vp) +sz_xVisualType);}if (dp->depth == 32 && getenv ("XLIB_SKIP_ARGB_VISUALS")){Xfree (dp->visuals);dp->visuals = NULL;dp->nvisuals = 0;}} else {dp->visuals = (Visual *) NULL;}}sp->root_visual = _XVIDtoVisual(dpy, root_visualID);}if(usedbytes != setuplength){/* Sanity check, shouldn't happen. */fprintf(stderr, "Xlib: Did not parse entire setup message: ""parsed: %ld, message: %ld\n",usedbytes, setuplength);OutOfMemory(dpy);return(NULL);}/** Now start talking to the server to setup all other information...*//** Make sure default screen is legal.*/if (iscreen >= dpy->nscreens) {OutOfMemory(dpy);return(NULL);}/** get availability of large requests*/dpy->bigreq_size = xcb_get_maximum_request_length(dpy->xcb->connection);if(dpy->bigreq_size <= dpy->max_request_size)dpy->bigreq_size = 0;/** Set up other stuff clients are always going to use.*/for (i = 0; i < dpy->nscreens; i++) {register Screen *sp = &dpy->screens[i];XGCValues values;values.foreground = sp->black_pixel;values.background = sp->white_pixel;if ((sp->default_gc = XCreateGC (dpy, sp->root,GCForeground|GCBackground,&values)) == NULL) {OutOfMemory(dpy);return (NULL);}}
/** call into synchronization routine so that all programs can be* forced synchronous*/(void) XSynchronize(dpy, _Xdebug);/** get the resource manager database off the root window.*/LockDisplay(dpy);{xGetPropertyReply reply;xGetPropertyReq *req;GetReq (GetProperty, req);req->window = RootWindow(dpy, 0);req->property = XA_RESOURCE_MANAGER;req->type = XA_STRING;req->delete = False;req->longOffset = 0;req->longLength = 100000000L;if (_XReply (dpy, (xReply *) &reply, 0, xFalse)) {if (reply.format == 8 && reply.propertyType == XA_STRING &&(reply.nItems + 1 > 0) &&(reply.nItems <= req->longLength * 4) &&(dpy->xdefaults = Xmalloc (reply.nItems + 1))) {_XReadPad (dpy, dpy->xdefaults, reply.nItems);dpy->xdefaults[reply.nItems] = '\0';}else if (reply.propertyType != None)_XEatDataWords(dpy, reply.length);}}UnlockDisplay(dpy);#ifdef MOTIFBC{extern Display *_XHeadOfDisplayList;_XHeadOfDisplayList = dpy;}
#endif
#ifdef XKBXkbUseExtension(dpy,NULL,NULL);
#endif
/** and return successfully*/return(dpy);
}
  • XCloseDisplay源码

XCloseDisplay函数对应的源码在src/ClDisplay.c中。如下所示:

/** XCloseDisplay - XSync the connection to the X Server, close the connection,* and free all associated storage.  Extension close procs should only free* memory and must be careful about the types of requests they generate.*/int
XCloseDisplay (register Display *dpy)
{register _XExtension *ext;register int i;if (!(dpy->flags & XlibDisplayClosing)){dpy->flags |= XlibDisplayClosing;for (i = 0; i < dpy->nscreens; i++) {register Screen *sp = &dpy->screens[i];XFreeGC (dpy, sp->default_gc);}if (dpy->cursor_font != None) {XUnloadFont (dpy, dpy->cursor_font);}XSync(dpy, 1);  /* throw away pending events, catch errors *//* call out to any extensions interested */for (ext = dpy->ext_procs; ext; ext = ext->next) {if (ext->close_display)(*ext->close_display)(dpy, &ext->codes);}/* if the closes generated more protocol, sync them up */if (X_DPY_GET_REQUEST(dpy) != X_DPY_GET_LAST_REQUEST_READ(dpy))XSync(dpy, 1);}xcb_disconnect(dpy->xcb->connection);_XFreeDisplayStructure (dpy);return 0;
}

由于源码已经比较长了,为了方便理解和阅读,把余下的函数放到下一篇中。

X11 Xlib截屏问题及深入分析二 —— 源码实现1相关推荐

  1. Spectacle/Flameshot/X11 Xlib截屏问题现象及解决方法

    最近一个时期可以看到我的博客文章都是围绕系统截屏展开的,从Spectale到FlameShot再到X11/Xlib,及至最近的libX11,都是在设法找到工作中遇到的一个比较严重的Bug的根源--截屏 ...

  2. X11 Xlib截屏代码所遇问题及初步分析

    综合了两篇博客中的例程并做一定修改,得到了基于X11 Xlib的截屏代码. 两篇博客链接分别如下: X11 截图与鼠标事件-SkyMei777-ChinaUnix博客 xlib实现截图报错-编程语言- ...

  3. 深入分析Ribbon源码分析

    本文来分析下Ribbon源码 文章目录 Ribbon源码分析 负载均衡器 AbstractLoadBalancer BaseLoadBalancer DynamicServerListLoadBala ...

  4. 录屏工具Gif软件 附带源码

    录制完可以快速一键复制录好的 GIF 文件添加图片.很多软件复制的 GIF 有兼容性问题,例如到浏览器编辑器粘贴,或在 QQ 里粘贴 --会出现无效像,动画变静态图像,上传报错等问题.Gif123 复 ...

  5. qcustomplot圆_QCustomplot使用分享(二) 源码解读

    一.头文件概述 从这篇文章开始,我们将正式的进入到QCustomPlot的实践学习中来,首先我们先来学习下QCustomPlot的类图,如果下载了QCustomPlot源码的同学可以自己去QCusto ...

  6. QCustomplot(二) 源码解读

    阅读目录 一.头文件概述 二.一个简单的示例 三.示例下载 四.相关文章 回到顶部 一.头文件概述 从这篇文章开始,我们将正式的进入到QCustomPlot的实践学习中来,首先我们先来学习下QCust ...

  7. ​​​​Java毕设项目智慧公寓系统演示录屏2021计算机(附源码+系统+数据库+LW)

    Java毕设项目智慧公寓系统演示录屏2021计算机(附源码+系统+数据库+LW) 项目运行 环境配置: Jdk1.8 + Tomcat8.5 + Mysql + HBuilderX(Webstorm也 ...

  8. IOS手机全屏长按识别二维码HTML代码

    代码段作用讲解: 1. 二维码的全屏样式, opacity: 0; 透明样式, touch-callout: none; -webkit-touch-callout: none; -ms-touch- ...

  9. 海康威视道闸进出口LED屏DS-TVL224系列开发C#源码

    1.类库源码: using System; using System.Collections.Generic; using System.Drawing; using System.Linq; usi ...

最新文章

  1. TCP连接的建立和终止
  2. 如何设计一个好的数据结构?
  3. 第十期 华为拓扑-OSPF配置
  4. 将Windows 8.1 系统窗口背景设置成淡绿色?
  5. HDU - 2825 Wireless Password(AC自动机+状压dp)
  6. 在没有XML的情况下测试Spring和Hibernate
  7. 利用scipy包计算表格线的峰值,还原表格得到表格结构
  8. SpringAop通知
  9. Android第五十二期 - 云之讯的代码混淆
  10. 不能注册DLL/OCX:RegSvr32失败 0x5
  11. DTCC参会归来有感
  12. C# 死循环等待方式
  13. 编写java判断闰年_Java 判断闰年代码实例
  14. 严昊:25岁接手世界500强企业,公司一年净赚80亿
  15. 25. Green Living 绿色生活
  16. 软件工程与计算机科学的区别
  17. 有软件负载均衡,也有硬件负载均衡,选择哪个?
  18. threejs(webgl)-shader入门教程(1)
  19. Java基础之刨根问底第6集——集合与List
  20. 【优化求解】基于PESA—II实现多目标优化求解matlab源码

热门文章

  1. SQL Server 查看被锁的表
  2. fastadmin 子账号看不到菜单,菜单没有查看,编辑等选项
  3. Android圆盘控件,DiscView 圆盘控件 动态展示百分比等数据 @codeKK Android开源站
  4. 小米平板android版本,小米平板系统是什么?小米平板能升级安卓4.2吗?
  5. 视频点播RTMP推流直播流媒体服务二次开发集成接口
  6. 视频教程-Python数据分析与案例教程:分析人口普查数据-Python
  7. 面试时,没有谈薪资,叫回去等通知,还有机会吗
  8. 2面之后说等HR通知,等不到怎么办
  9. Hadoop 集群项目(类似百度网盘)
  10. 开发人员必知的5个CI/CD工具