我正在使用XShm扩展来在Linux中绘制和操作图像.
为了没有屏幕闪烁,我在调用XScmPutImage之后立即传递send_event = TRUE给XShmPutImageXIfEvent然后等待事件.
这样,我正在使图像绘制阻塞,以便在窗口表面上显示之前不更改图像.
通常一切正常.但有时候,当我进行密集的图像绘制时,似乎事件永远不会出现并且绘图过程会挂起.
哪里可以看到问题?是否使用适合此任务的XIfEvent?事件如何从消息队列中消失?
是否有可能XShmPutImage不发送事件(如果send_event = TRUE)或发送不同于ShmCompletion某些情况的事件?(例如某些内部错误或其他什么?)
编辑:
经过一些研究,我发现只有当窗口管理器向窗口集中生成事件时才会发生这种挂起.例如,当我通过拖动角落调整窗口大小时.
EDIT2:
我尝试了几种方法来解决这个问题,但没有成功.最后我被迫使用一些超时并在一段时间后取消等待.但当然这是肮脏的黑客攻击,无论如何我想解决它.
那么,如果send_event = TRUE,XShmPutImage不发送事件的原因是什么,或者该事件是否可能从消息队列中消失?
EDIT3:
这是有问题的代码(FASM):
cinvoke XShmPutImage, ......, TRUE
.loop:
lea eax, [.event]
cinvoke XCheckTypedEvent, [Display], [ShmCompletionEvent], eax
test eax, eax
jz .loop ; there is no message
Run Code Online (Sandbox Code Playgroud)
注意:无论事件检查是否挂起,XShmPutImage总是返回TRUE,所以我没有在它之后进行错误检查.
EDIT4:
因为请求我发布了绘图函数的整个代码.该代码使用了FASM的一些宏库,但至少这些想法是明确的(我希望)
请注意,此代码包含限制事件仅等待20毫秒的变通代码.没有这个超时,等待循环就会永远挂起.通过XShmGetEventBase按照Xshm文档中的建议调用来获取XShm事件的编号.
; Draws the image on a OS provided window surface.
proc DrawImageRect, .where, .pImage, .xDst, .yDst, .xSrc, .ySrc, .width, .height
.event XEvent
rb 256
begin
pushad …Run Code Online (Sandbox Code Playgroud) 我在Xlib中实现了一个水平分割器小部件.当用户点击并拖动分割条时,我试图抓住鼠标(这样用户就可以动态移动分割,从而调整分割条两侧的窗口大小).
我XGrabPointer()在接到左键单击后使用,希望所有未来的鼠标移动(拖动)都将转移到拆分器窗口,直到释放左键.
不幸的是,它似乎并没有像那样工作.如果用户拖得太快并且鼠标指针进入分割两侧的一个窗口,则MotionEvent消息将转移到该(子)窗口而不是分割器窗口.
我做错了什么?我的XGrabPointer()电话如下:
::XGrabPointer(mDisplay, window, True,
ButtonPressMask |
ButtonReleaseMask |
PointerMotionMask |
FocusChangeMask |
EnterWindowMask |
LeaveWindowMask,
GrabModeAsync,
GrabModeAsync,
RootWindow(mDisplay, DefaultScreen(mDisplay)),
None,
CurrentTime);
Run Code Online (Sandbox Code Playgroud) 请告诉我是否有用于Xorg/Linux平台的OSD 屏幕显示程序或技术,它可以以比pango更丰富的方式呈现XML,至少支持align属性和多个span或div元素,因此它可以显示多个列.
到目前为止我检查了什么:
gnome-osd-client呈现XML,但gnome-osd-client提供非常简单的XML pango
osd_cat但它不带任何XML.
navit有一些使用osd的OSM数据XML,但难以理解.
如果没有这样的osd程序,请告诉我
具有不同后端支持的HTML渲染器可以编程为使用OSD显示.
来自在后端使用osd的其他现有包(如navit)的相关源可用于呈现此类XML.
我的问题是我实际上使用了pango,但它不够灵活,无法满足我在多列中显示XML的需求.
我正在将一些代码从Windows移植到XLib.在windows代码中,我可以通过调用InvalidateRect然后处理相应的WM_PAINT消息来强制重绘.但是,我无法在X11/XLib中找到如何执行此操作.我看到有Expose消息但不确定是否是同一件事.
如果重要,我需要这样做以强制窗口以特定帧速率渲染基于OpenGL的程序.
我正在尝试在 macOS 上安装 Cairo/Xlib,但无法正常工作
cmake -G "Xcode" --config 调试 "-DCMAKE_BUILD_TYPE=Debug" ../.
CMake Error:
Xcode 1.5 not supported.
CMake Error: Could not create named generator Xcode
Generators
* Unix Makefiles = Generates standard UNIX makefiles.
Ninja = Generates build.ninja files.
Ninja Multi-Config = Generates build-<Config>.ninja files.
Xcode = Generate Xcode project files.
CodeBlocks - Ninja = Generates CodeBlocks project files.
CodeBlocks - Unix Makefiles = Generates CodeBlocks project files.
CodeLite - Ninja = Generates CodeLite project files.
CodeLite - Unix Makefiles …Run Code Online (Sandbox Code Playgroud) 以下代码如何删除窗口边框?
//note the struct is declared elsewhere, is here just for clarity.
//code is from [http://tonyobryan.com/index.php?article=9][1]
typedef struct Hints
{
unsigned long flags;
unsigned long functions;
unsigned long decorations;
long inputMode;
unsigned long status;
} Hints;
//code to remove decoration
Hints hints;
Atom property;
hints.flags = 2;
hints.decorations = 0;
property = XInternAtom(display, "_MOTIF_WM_HINTS", true);
XChangeProperty(display,window,property,property,32,PropModeReplace,(unsigned char *)&hints,5);
XMapWindow(display, window);
Run Code Online (Sandbox Code Playgroud)
到目前为止,我已经收集到Atom是一种类似于Window和Display的标识符,但我无法弄清楚Hints结构或"_MOTIF_WM_HINTS"的来源.谁能为我解释所有这些代码?在此先感谢,ell.
我正在编写一个Xlib应用程序,我希望窗口居中.我已经习惯XMoveWindow了(desktopWidth - width) / 2, (desktopHeight - height) / 2它,它大致在正确的位置.
然而问题是宽度和高度是客户区域,而不是总面积.有什么方法让我得到窗口的总面积?
我需要使用,Xlib因为我正在使用Glx和OpenGL.我不想使用SDL,也没有庞大的图形库.
我知道可以和GLX一起使用Xlib和OpenGL(我自己在C中完成了).
问题是,我如何在python中执行此操作?该OpenGL模块具有GLX功能[ 文档 ],但它似乎使用C类型,我不知道(也没有,似乎是其他人)如何使用PyOpenGL的xlib类型.
我也试过ctypes直接使用和加载库,但在尝试使用Xlib头文件中定义的C宏时遇到(明显的)问题,比如DefaultRootWindow.
我错过了一些明显的东西,比如PyOpenGL有自己的xlib实现,或者如果没有一些(编译的)模块编写,这是不可能的?
我需要为没有连接真实显示器的虚拟GPU设备显示基于RAM的帧缓冲.我所拥有的是在RGB32格式的DRM_IOCTL_MODE_MAP_DUMB之后的mmap'ed内存块.目前我正在使用通过XShmCreatePixmap()创建的MIT-SHM共享像素图,如下所示:
shminfo.shmid = shmget(IPC_PRIVATE, bytes, IPC_CREAT|0777);
shminfo.readOnly = False;
shminfo.shmaddr = shmat(shminfo.shmid, 0, 0);
shmctl(shminfo.shmid, IPC_RMID, 0);
XShmAttach(dpy, &shminfo);
XShmCreatePixmap(dpy, window, shminfo.shmaddr, &shminfo, width, height, 24);
Run Code Online (Sandbox Code Playgroud)
然后简单地说
while (1) {
struct timespec ts = {0, 999999999L / 30};
nanosleep(&ts, NULL);
memcpy(shminfo.shmaddr, mem, bytes);
XCopyArea(dpy, pixmap, window, gc, 0, 0, width, height, 0, 0);
XFlush(dpy);
}
Run Code Online (Sandbox Code Playgroud)
所以它每秒循环30次,在XCopyArea之后执行memcpy.问题是它在强大的机器上使用了大量的CPU:50%.有没有更好的方法?我可以想到两个可能的改进:
摆脱memcpy并将mmap的内存传递给MIT-SHM,但看起来MIT-SHM API不支持这一点.
获取某种"内容已更改"通知以摆脱愚蠢的睡眠(但我没有找到任何合适的东西).
有任何想法吗?
更新:瓶颈是'memcpy',如果删除CPU使用率可以忽略不计.问题似乎是没有办法分享以前mmap的内存(如果我正确理解API)所以我每次都被迫复制整个缓冲区.我也尝试过glDrawPixels()和SDL曲面,两者看起来都比MIT-SHM慢.
更新:事实证明MIT-SHM不适合这样的任务.它的主要目的是创建缓冲区并以X IPC的开销写入(渲染)它.我不需要编写任何东西,只需将现有缓冲区"转发"到X.在这种情况下,共享像素图,共享图像和常规X图像(XCreateImage)之间没有性能差异.
结论:到目前为止,我还没有找到允许渲染现有缓冲区的API,无需每次都复制数据.
我需要在QT小部件中显示原始图像.我在帧缓冲区上运行X11,因此OpenGL不可用.
图像和帧缓冲都是相同的格式 - RGB565,但如果需要,我可以将其更改为任何其他格式.我不需要混合或缩放.我只需按原样显示像素.
我正在使用QPainter :: drawImage,但它将QImage转换为QPixmap,这种转换似乎非常慢.它也得到了Xrender的支持,我认为在Xrender中支持混合需要不必要的开销,我并不需要
有没有更好的方法?如果它在QT中不可用,我可以使用Xlib或任何其他库或协议.我可以修改驱动程序,X服务器或其他任何东西.