embed a X11 window in a gtk+3 widget - c

I would like to embed a simple X11 window in a gtk widget.
I have found this gist https://gist.github.com/pastapojken/69f1e223fd926425f7ae770a95ec79a2 which does almost but not quite what I am looking for: It allows to add gtk widgets inside an X window, not the contrary.
I don't know if I am being clear as I am quite a newbie in both X11 and gtk. So here is a quick schema:
So is this even possible, any advice on how to make this work ? I feel like all I need to do is inherit from GtkWidget and set its GdkWindow to a wrapper of the XID like this:
win = gdk_x11_window_foreign_new_for_display(display, xid);
gtk_widget_set_window(myWidget, win);
But I was not sucessful this way, all I get is two top level windows as shown below.
I am running Fedora 32 on X11, NOT wayland
thanks!

Related

Gtk Window to Gdk Surface in GTK4

I was wondering how I could get the X11 window ID for a Gtk Window in gtk4. I have seen other answers before regarding gtk3, but they don't seem to work in the latest gtk4. I found gdk_x11_surface_get_xid, but I can't pass a GtkWidget to that. I tried using the GDK_SURFACE cast, but I get:
invalid cast from 'GtkApplicationWindow' to 'GdkSurface'
Is there any way to resolve this, and get the x11 window id from a GtkWindow?

XCB xcb_window_t VS xcb_drawable_t

I'm trying to learn XCB through this link and write a little "library" so I don't forget what to do each time. I'm at the point where I have a window open and I'm almost ready to start drawing things. However something has confused me, in some of the earlier examples they use xcb_window_t but in the new ones the make the "window" variable a xcb_drawable_t. I just went with it before but now I'm at the section "Simple window operations" and the functions seem to use xcb_window_t as inputs. Can these be used interchangeably, or do they need to be their own thing?
There are two kinds of drawables in X11: Windows and pixmaps.
Put differently: A window is a drawable and a pixmap is a drawable. Nothing else is a drawable.
Every function that accepts a xcb_drawable_t can be called with either a window or a pixmap. Functions that want a window only accept xcb_window_t.

Why this BitBlt example doesn't work anymore?

I'm currently getting back to some Windows Programming using Petzold's book (5th edition).
I compiled the following example using BitBlt and it doesn't work as it is supposed to.
It should copy the Window's icon of (CxSource, CySource) size and replicate it on the whole window's surface.
What happens, in reality, using Windows 7 is that the bitmap below the window gets sourced and copied into the drawing surface i.e. hdcClient.
I don't understand why it behaves like this knowing that it's clear the DC passed to BitBlt is hdcWindow, which refers to a device context obtained via a GetWindowDC(hwnd) of the current application.
I first thought it was due to the fact the transparency mode is enabled by default, but deactivating it doesn't change anything. BitBlt seems to always take the surface below the application Window!
I don't get it! :)
Anyone knows why it works that way and how to fix it?
Making screenshots with BitBlt() did not exactly get any easier since the addition of the DWM (Desktop Window Manager, aka Aero). Petzold's sample code suffers from a subtle timing issue, it is making the screenshot too soon. It does so while Aero is still busy animating the frame, fading it into view. So you see what is behind the window, possibly already partly faded depending on how quickly the first WM_PAINT message is generated.
You can easily fix it by disabling the effect:
#include <windows.h>
#include <dwmapi.h>
#pragma comment(lib, "dwmapi.lib")
And after the CreateWindow() call:
BOOL disabled = TRUE;
DwmSetWindowAttribute(hwnd, DWMWA_TRANSITIONS_FORCEDISABLED, &disabled, sizeof(disabled));
Another tricky detail is that the first BitBlt matters, the DWM returns a cached copy afterwards that is not correctly invalidated by the animation.
This gets grittier when you need a screenshot of a window that belongs to another process. But that was already an issue before Aero, you had to wait long enough to ensure that the window was fully painted. Notable perhaps is the perf of BitBlt(), it gets bogged-down noticeably by having to do job of composing the final image from the window back-buffers. Lots of questions about that at SO, without happy answers.
It is not supposed to copy the windows icon, it is supposed to copy the windows titlebar part where the icon is located.
There are some issues with this (now 20 year old code):
GetSystemMetrics values cannot be used for window related dimensions anymore since GetSystemMetrics returns the classic sizes, not the Visual Style sizes.
Depending on the Windows version, the DWM might define the window size as something larger than your window (where it draws the window shadow and other effects).
Your example works OK on XP:
(There is a small problem because the titlebar is not square (unlike Windows 98/2000 that this example was designed for) so you see a issue in the top left where it is just white. I also modified the example slightly so it varies the HDC source location)
On a modern version of Windows it seems like the DWM or something is not able to properly emulate a simple window DC and parts of the shadow/border/effects area is part of the DC:
I don't know how to fix this but the example is pretty useless anyway, if you want to draw the window icon you should draw the HICON with DrawIconEx. If you want to draw custom non-client area stuff then you need to find more recent examples, not something that only supports the classic theme.

SDL_Surface into GTK Window

I'm currently making a project in my IT School and I work with SDL (The project is image processing and stuff like that), and currently I just display the image with SDL without interface (buttons etc...). I know a little bit about GTK so I want to know if I can display an image (here a SDL_Surface) into a GTK window
I made some research but nothing was very clear...
Thank you !
Drawing widgets using SDL
Drawing widgets(menu, buttons etc) using SDL drawing functions and handling actions by tracking the cursor position during the occurrence of event(on which item the cursor was while the event was performed).
This becomes very complicated and would be better to use an existing GUI library with some simple hacks. You can find code example for drawing a button here.
Copying SDL surface into target GUI widget
This involves copying pixel by pixel(predefined functions might be available to do the same, gdk_draw_rgb_image in case of gtk) of the sdl surface into target gui widget(can be a drawingArea in case of GTK).
Merging SDL window into a GUI widget
In X11 and win32 systems each windows are given with a window id and by default sdl and gtk would have separate window id resulting two different windows, we can exploit SDL_CreateWindowFrom function to use single window for sdl and gtk in which we will force both the libraries to use a single window id.
You can find similar question here.
GTK Plug and Socket
Plug and Socket enables embeeding widget from one process to another. GTK will create a socket and pass the socket id to SDL and SDL would create window from that socket ID.
Event loop handling:
After merging SDL with GTK you might find gtk and sdl have their own event loops hence handling events might not be as expected. To solve that issue you can handle
events in GTK and propagate the event to SDL using SDL_PushEvent function and vice versa in case you are using user defined events.
.
.
static SDL_Event SDLevent;
switch(event->keyval)
{
case GDK_KEY_m:
SDLevent.type = SDL_KEYUP;
SDLevent.key.keysym.sym = SDLK_m;
SDL_PushEvent(&SDLevent);
break;
.
.
.
This link has a nice explanation for above methods.

How to set the position of stage or window using clutter1.0?

How to set the position of the stage or window using clutter1.0? Just like in opengl glutInitWindowPosition(0, 500). Thanks...
Clutter does not provide a wrapper around windowing system specific API: the Stage, as a scene graph element, is defined to always be at (0, 0), so you cannot use the ClutterActor set_position() method on it.
if you're on X11, you can use the X11 API to move a stage Window, e.g.:
Display *xdpy = clutter_x11_get_default_display ();
Window xwin = clutter_x11_stage_get_window (stage);
XMoveWindow (xdpy, xwin, 0, 500);
obviously, there's the whole thorny issue of manual window placement in X11: you should not really do that, and you should defer to the window manager to actually position your windows.
on Windows, you can get the WHND of the Stage window using clutter_win32_get_stage_window() and use SetWindowPos() similarly to how it works on X11.
on OS X is a bit trickier, as Clutter does not expose the NSWindow nor the NSView used by the Stage, as of yet, so you'll have to hack a bit inside Clutter.

Resources