LINUX.ORG.RU

Как отобразить интерактивное x11 приложение в X11 3D программе

 , ,


0

2

TLDR: https://github.com/collinalexbell/HackMatrix/raw/master/images/header_img.png

Всезнающий лор, ищу практической помощи (советов)

Я хочу написать 3D графическое приложение (X11), в котором можно отобразить окно графического терминала (lxterm, gnome-terminal, etc).

Как оно в теории работает, я примерно понимаю. Отрисовываем xterm в области вне экрана, запускаем тред с трансляцией пикселей в отрисованной области, внутрь нашего приложения

Как правильно прокидывать нажатия на клавиши и хоткеи в графическом приложении, чтобы они (нажатия) передавались терминалу ?

Как правильно перехватывать выделение текста в терминале? Например в терминале мне нужно скопировать вывод комнады в буфер обмена?

Мой главный вопрос, что посоветуете использовать для 3D движка (я не хочу изобретать велосипед) и как по «дешевому» пробросить внутрь 3D приложения терминал (или другое GUI приложение) с перехватом ввода, и кликов мышки.

Была попытка реализовать это на godot, почти получилось, но много подводных камней.



Последнее исправление: gagarin0 (всего исправлений: 4)
Ответ на: комментарий от Irma

там тоже преобразование обычного терминала в картинку.

Преобразование х11 окна в картинку это давно решенная задача, достаточно отрисовывать х11 окно за пределами экрана и у Xorg сервера спрашивать пиксели рендеринга.

Вопрос со звездочкой как правильно пропихивать в приложение нажатие кнопок, это очевидный XSendEvent, но там много подводных камней.

Как выделять текст в таком приложение - тоже одна большая загадка

gagarin0
() автор топика

для прокидывания событий, напрямую, в xorg приложению (xterm), видимо надо использовать что-то в духе,

void allow_input_passthrough (Window w) {
    XserverRegion region = XFixesCreateRegion (g_display, NULL, 0);

    //XFixesSetWindowShapeRegion (g_display, w, ShapeBounding, 0, 0, 0);
    XFixesSetWindowShapeRegion (g_display, w, ShapeInput, 0, 0, region);

    XFixesDestroyRegion (g_display, region);
}

в этом случае фейковый XSendEvent не нужен

gagarin0
() автор топика
Последнее исправление: gagarin0 (всего исправлений: 1)

Какой-то бред предлагают и советуют, какие-то области вне экрана. Тебе нужно реализовать в своём приложении X Server, X window system для этого и придумали же. И отрисовка, и обмен сообщениями, и работа с клипбордом и даже drag&drop после этого будут тривиальными и без костылей.

anonymous
()
Ответ на: комментарий от anonymous

Тебе нужно реализовать в своём приложении X Server

в начале я тоже думал что так проще сделать, но от этого в итоге отказался, это просто не нужно.

Какой-то бред предлагают и советуют, какие-то области вне экрана.

расскажи это разработчикам OBS Studio

gagarin0
() автор топика
Ответ на: комментарий от Merionet

в итоге да, я хочу получить WM

но пока задача стоит написать приложение, которое может отображать другое приложение, и пропихивать в него события

я так понимаю что мне нужно использовать что-то вроде

imgui + xlib

что-то в духе такого

https://github.com/rdbo/imgui-overlay/blob/master/overlay/main.cpp

int render_callback(struct window_info *winfo, GLFWwindow *glfw_window, void *arg) {
        Display *display = (Display *)arg;
	if (!init) {
		ImGuiContext *ctx = ImGui::CreateContext();
		ImGui::SetCurrentContext(ctx);
		ImGui_ImplGlfw_InitForOpenGL(glfw_window, true);
		ImGui_ImplOpenGL2_Init();
		init = true;
	}

	ImGui_ImplOpenGL2_NewFrame();
	ImGui_ImplGlfw_NewFrame();

	ImGui::NewFrame();

	glfwSetWindowAttrib(glfw_window, GLFW_MOUSE_PASSTHROUGH, GLFW_FALSE);
	glfwSetWindowAttrib(glfw_window, GLFW_MOUSE_PASSTHROUGH, GLFW_TRUE);
	
	ImGui::Render();
	int display_w, display_h;
        glfwGetFramebufferSize(glfw_window, &display_w, &display_h);
        glViewport(0, 0, display_w, display_h);
        glClearColor(0, 0, 0, 0);
        glClear(GL_COLOR_BUFFER_BIT);
	ImGui_ImplOpenGL2_RenderDrawData(ImGui::GetDrawData())
}
gagarin0
() автор топика
Последнее исправление: gagarin0 (всего исправлений: 1)
Ответ на: комментарий от firkax

wm

К Window Management я точно приду, но позже

В целом сейчас вырисовывается такой MVP:

  • создать canvas

  • нарисовать пустой «прямоугольник»

  • определить win_id, используя xlib координаты нужного окна (xterm)

  • вызвать Xorg API, и создать регион, указав что все события в этом регионе будут перенаправляться в win_id

    XserverRegion region = XFixesCreateRegion (g_display, NULL, 0);
    XFixesSetWindowShapeRegion (g_display, w, ShapeInput, 0, 0, region);
  • в event_loop:
  1. через xlib получать «битмап стрим» у Xorg нужного окна (win_id)

  2. рендерить этот битмапы в «прямоугольник»

за основу возьму imgui

а точнее вот этот «модуль» в котором реализованы mindmap карты

https://github.com/thedmd/imgui-node-editor

либо

https://github.com/azula1A89/mindmap

gagarin0
() автор топика
Последнее исправление: gagarin0 (всего исправлений: 3)
Ответ на: комментарий от DumLemming

я не настоящий сварщик, вероятно буду делать так (через Xcomposite)

  Window root = RootWindow(display, screen);
  setWMProps(root);
  XCompositeRedirectSubwindows(display, RootWindow(display, screen),
                                 CompositeRedirectAutomatic);
gagarin0
() автор топика

Нашел буквально что мне нужно для опытов

https://github.com/rdbo/imgui-overlay

к сожалению у меня не работает, показывается очень маленькое окно (буквально 1 пиксель) с которым я ничего не могу поделать

Если есть более опытные товарищи, попробуйте запустить на своем окружении

gagarin0
() автор топика
Последнее исправление: gagarin0 (всего исправлений: 2)
  • запускаешь фейковый X11 типа Xvfb
  • переопределяешь DISPLAY для приложения
  • своим кодом биндишься на этот второй X11 и получаешь все евенты и грабишь корованы картинку
  • рисуешь куда угодно там 3D не нужен
  • пиши код бл/т

сразу фиксирую - либо ты пишешь свой X11, либо юзаешь другой X11, либо не X11.

anonymous2 ★★★★★
()
Последнее исправление: anonymous2 (всего исправлений: 2)

TLDR: https://github.com/collinalexbell/HackMatrix/raw/master/images/header_img.png

Я хочу написать 3D графическое приложение (X11), в котором можно отобразить окно графического терминала (lxterm, gnome-terminal, etc).

Проблема в том, что ты завязался на говно (X11) и не можешь найти решения для своей хотелки. А между прочим в Qt то что у тебя на скрине было возможно сделать парой сотней строк ещё в 2007 году:

https://code.qt.io/cgit/%7bnon-gerrit%7d/qt-labs/wolfenqt.git/tree/

EXL ★★★★★
()
Последнее исправление: EXL (всего исправлений: 1)
Ответ на: комментарий от gagarin0

Qt это как резиновые перчатки при работе с биологическими отходами.

Благодаря Qt ты можешь не касаться иксокалового кода, поскольку смелые и отважные люди в спецкостюмах уже сделали это за тебя.

EXL ★★★★★
()
Последнее исправление: EXL (всего исправлений: 1)
Ответ на: комментарий от gagarin0

Не стоит воспринимать мой совет в штыки, ведь я всё-таки попытался хотя бы немного сохранить твоё время и нервы.

Я прекрасно понимаю, что программирование под X11 (Xlib, xcb, Xm/Motif) делает человека очень раздражительным из-за послевкусия и осознания потраченного в пустую времени и сил.

Моя вина в том, что я пришёл в этот тред со своим ценным советом слишком поздно, так как каловые массы иксокода, с которыми ты случайно соприкоснулся, уже озлобили тебя.

EXL ★★★★★
()
Последнее исправление: EXL (всего исправлений: 2)
Ответ на: комментарий от EXL

во-первых, спасибо за попытки помочь сэкономить мои ресурсы!

во-вторых, мне очень жаль что вы получили негативный опыт с X11 и пытаетесь теперь везде об этом заявить, просто отпустите ситуацию, жизнь как говорится на этом не закачивается

gagarin0
() автор топика
Ответ на: комментарий от gagarin0

Так или иначе иксы сейчас уже переходят в разряд легаси, не так далёк тот день как твоя программа будет работать через прослойку xwayland, которая возможно и не будет установлена по-умолчанию. Оно точно нужно?

anonymous
()
Ответ на: комментарий от gagarin0

Сдаётся что ни X11 ни вялые не работают в 3-d проекциях.

но пока задача стоит написать приложение, которое может отображать другое приложение, и пропихивать в него события

по шагам - во первых отобразить другое приложение..это xvfb,xnest чтобы запустить и «perspective transform» чтобы результат показать в своём криво-угольнике. Так как там просто-матрицы 4x4 наверное можно сделать исключительно open-gl`ом или конвеерами.

Мышиные эвенты соответсвенно это преобразование наоборот. Фокус придётся следить вручную, copy-paste тоже.

PS/ Qt,Gtk,Wx дружно вместе пролетают - тут чем ниже уровень, тем быстрее и с меньшими ошибками будет работать.

MKuznetsov ★★★★★
()
Ответ на: комментарий от firkax

Компиз был, metisse был (и выглядел как сабж), помню это все добро в мандряке 2006 шло на дисках

ТС, лови https://web.archive.org/web/20220305145334/http://insitu.lri.fr/metisse/

upcFrost ★★★★★
()
Последнее исправление: upcFrost (всего исправлений: 1)
Ответ на: комментарий от upcFrost

Хочешь metisse свелосипедить?

нагуглил видео https://www.youtube.com/watch?v=dxsUKX6xXyE

да, но нет

Игрался с ним лет 12 назад

какие впечатления?

gagarin0
() автор топика
Последнее исправление: gagarin0 (всего исправлений: 1)
Ответ на: комментарий от gagarin0

Видео не показывает даже 1/3 того что оно умело. Как раз вращать окна в трех измерениях как у тебя на картинке это одна из его основных фишек.

какие впечатления?

Ну, для школьника было прикольно. А так бесполезно. Как и компиз и все вот это вот

Ещё посмотри SphereXP. Да, оно под венду, но мне кажется это тоже плюс-минус то что ты хочешь. Вот оно кстати вместе со шлемом было довольно занятно

Я почему советую все это - оно работало на очень старых машинах. То что ты сейчас налепишь на годоте будет раз в 50 тормознее

upcFrost ★★★★★
()
Последнее исправление: upcFrost (всего исправлений: 1)