Я новичок не только в Xlib, но и в программировании интерфейса Linux.
Я пытаюсь решить общую задачу (которая не так часто, как кажется, так как я не могу найти надежный пример) рисования содержимого одного окна в другое.
Однако я столкнулся с серьезными проблемами с производительностью и ищу решение, которое я мог бы использовать, чтобы сделать программу быстрее и надежнее.
Теперь я предоставлю некоторую информацию о ходе выполнения программы, так как я не уверен, что выбранный дизайн программы был правильным, возможно, есть некоторые ошибки при использовании Xlib.
Программа получает идентификатор (тип окна «Xlib») активного окна (называется SrcWin отныне) надлежащим образом (не идентификаторы виджетов какой-либо программы, а реально видимое окно, где рисуется весь контент), сначала он использует XGetInputFocus
чтобы сфокусировать окно, а затем перебирает окна, используя XQueryTree
в то время как дочерний элемент корневого окна найден, он использует XmuClientWindow
функция для получения именованного окна (если оно еще не найдено).
Затем с помощью XGetWindowAttributes
он получает ширину и высоту SrcWin которые оба использовали в XCreateSimpleWindow
функция для создания нового окна (называется TrgWin) того же размера.
Некоторые события зарегистрированы для нового окна TrgWin, такие как Нажатие клавиши а также разоблачать с помощью XSelectInput
функция.
Графический контекст создается следующим образом:
GC gc = DefaultGC (Display, ScreenCount (Display) - 1);
Теперь бесконечный цикл запущен, в этом цикле select
вызывается функция для ожидания какого-либо события в X-соединении или для тайм-аута (struct timeval
).
После этого программа пытается получить изображение из SrcWin с помощью:
XImage *xi;
xi = XGetImage (Display, SrcWin, 0, 0, SrcWinWidth, SrcWinHeight, AllPlanes, ZPixmap);
и если изображение было успешно получено, оно помещается в TrgWin:
if (xi)
{
XPutImage (Display, TrgWin, gc, xi, 0, 0, 0, 0, SrcWinWidth, SrcWinHeight);
XFree (xi);
}
тогда ожидающие события обрабатываются, если они:
while (XPending (Display))
{
XNextEvent (Display, &XEvent);
/* some event processing using switch(XEvent.type){} */
}
Как уже упоминалось выше, программа работает почти так, как ожидалось. Но я столкнулся с серьезными проблемами производительности при попытке заставить эту программу извлекать контент SrcWin в TrgWin каждые 40 мс (это временное значение, с событиями оно может быть быстрее), на ядре i5-3337U для этой программы требуется 21% процессорного времени и почти 20% для процесса Xorg, чтобы нарисовать одно окно 683 * 752 в другое то же самое размер.
С моей точки зрения, было бы замечательно, если бы я смог отобразить область памяти с пикселями SrcWin в соответствующую область памяти TrgWin, но я не очень хорош в программировании на Xlib, и я сомневаюсь, что это возможно с стандартные функции Xlib.
1) Однако я запустил среду KDE, чтобы проверить ее переключатель окон, и все эскизы окон отображаются в окне переключателя окон в реальном времени без какой-либо серьезной загрузки процессора. Как это сделать?
2) Где-то упоминается механизм XShmGetImage + XShmPutImage — лучше ли это для моей программы, чем XGetImage + XPutImage?
3) Также я увидел, что в QT и GTK есть такая вещь, как «повреждение окна», это события, относящиеся к инструментарию, или это эквивалент Xlib?
4) Я понимал события «повреждения окна» в QT и GTK как сигналы beign, отправляемые после любых изменений в буфере изображения окна, так что все, что приводит к изменению хотя бы одного пикселя в окне, также генерирует такое событие? Было бы здорово иметь что-то подобное в Xlib, так как я мог бы избавиться от непрерывного изменения содержимого TrgWin каждые 40 мс, даже если в SrcWin не было никаких изменений.
5) Должен ли я пойти с GTK +, чтобы сделать вещи проще?
Заранее спасибо за ответы и извините за тонны текста.
Задача ещё не решена.