gst_video_overlay_set_window_handle from GTK# - c

I trying to display video in GTK# using Gstreamer via P/Invoke(on Ubuntu). I tried to use many code samples but nothing is working. Here is one of them:
GTK# code:
[DllImport("libgstTestDLL.so", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public extern static int play_file (StringBuilder path, IntPtr win);
...
play_file (new StringBuilder ().Append ("file:///home/user/Downloads/test.mp4"), screen.GdkWindow.Handle);
C code:
void play_file(char* path, void* hwnd_ptr){
GdkWindow* gdkWin = (GdkWindow*)hwnd_ptr;
pipeline = gst_element_factory_make("playbin", "player");
g_object_set (G_OBJECT (pipeline), "uri", path, NULL);
gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(pipeline), GDK_WINDOW_XID(gdkWin));
gst_element_set_state(pipeline, GST_STATE_PLAYING);
}
After executing play_file function my GTK# app just closes.
How can I correctly use play_file in GTK# and what I need to execute from play_file function in C to display video in GTK# application?

I found solution.
I linked my shared library with libgstvideo-1.0.so using this:
target_link_libraries(${PROJECT_NAME} gstvideo-1.0). Full description of the solution available here.

Related

Why is ID2D1Factory::GetDesktopDpi obsolete?

I'm following a direct2d tutorial and when I compile the code I get an error that a function is obsolete and that I should replace it, I look for ways to replace the function with the solutions that visual studio gives me (before publishing in stackoverflow) but it doesn't work, or I don't know how to call them.
main.cpp
// Because the CreateWindow function takes its size in pixels,
// obtain the system DPI and use it to scale the window size.
FLOAT dpiX, dpiY;
// The factory returns the current system DPI. This is also the value it will use
// to create its own windows.
m_pDirect2dFactory->GetDesktopDpi(&dpiX, &dpiY);
// Create the window.
m_hwnd = CreateWindow(
L"D2DDemoApp",
L"Direct2D Demo App",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
static_cast<UINT>(ceil(640.f * dpiX / 96.f)),
static_cast<UINT>(ceil(480.f * dpiY / 96.f)),
NULL,
NULL,
HINST_THISCOMPONENT,
this
);
error
1>------ Build started: Project: entt, Configuration: Debug x64 ------
1>Using triplet "x64-windows-static" from "C:\Users\Jule\vcpkg\installed\x64-windows-static\"
1>main.cpp
1>C:\Users\Jule\source\repos\entt\entt\main.cpp(154,27): error C4996: 'ID2D1Factory::GetDesktopDpi': Deprecated. Use DisplayInformation::LogicalDpi for Windows Store Apps or GetDpiForWindow for desktop apps.
1>Done building project "entt.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
tutorial: https://learn.microsoft.com/en-us/windows/win32/direct2d/direct2d-quickstart
I just went through this tutorial myself and ran into the same issue. The solution provided by #Julio Enrique in the comments is correct. However, I didn't realize at first he replaced both dpiX and dpiY with x, so it didn't work for me. As a result, I found an even simpler drop and replacement fix for this example tutorial. For others experiencing this issue, try the following fix:
// obtain the system DPI and use it to scale the window size.
FLOAT dpiX, dpiY;
// The following will return the current system DPI. This is the value used
// to create a window with the correct dimensions.
dpiX = (FLOAT) GetDpiForWindow (GetDesktopWindow ());
dpiY = dpiX;
// Create the window.
m_hwnd = CreateWindow(
L"D2DDemoApp",
L"Direct2D Demo App",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
static_cast<UINT>(ceil(640.f * dpiX / 96.f)),
static_cast<UINT>(ceil(480.f * dpiY / 96.f)),
NULL,
NULL,
HINST_THISCOMPONENT,
this
);
hr = m_hwnd ? S_OK : E_FAIL;
if (SUCCEEDED(hr))
{
ShowWindow(m_hwnd, SW_SHOWNORMAL);
UpdateWindow(m_hwnd);
}
Also pointed out by #Julio Enrique, make sure to link the required Direct2D library (i.e. d2d1.lib) either in the Visual Studio linker options or via the following pragma:
#pragma comment(lib, "d2d1.lib")
Going forward, in order to prevent others from experiencing this issue in the future when reading the posted tutorial documentation, I have submitted a Pull Request to fix the documentation on the Microsoft website.

Automate Chrome with window handle

I am working on a project in c which i am trying to simulate chrome browsing.
my only difficult is to find a way to get links position on screen after i receive a handle to chrome window. anyone knows how to get the links position??
i am familiar with selenium and managed to do so in python but i require to do so in c too.
any ideas?
int wmain()
{
HWND hwnd = NULL;
for (;;)
{
hwnd = FindWindowEx(0, hwnd, L"Chrome_WidgetWin_1", 0);
if (!hwnd)
break;
////Get Links position
}

Embed video in application (Linphone C API)

I'm trying to embed video in desktop application using Linphone C API.
By default, if to use samples from tutorial during call video window appears in separate window.
Could you please tell me, how to insert this video in my desktop application?
All I found seems helpful in Linphone C API reference, function:
linphone_core_set_native_video_window_id
Description:
Set the native video window id where the video is to be displayed.
For MacOS, Linux, Windows: if not set or zero the core will create
its own window, unless the special id -1 is given.
Could it be helpful? How to use it?
Here is the function from linphone SDK to get window handle:
void *get_native_handle(GdkWindow *gdkw){
#ifdef GDK_WINDOWING_X11
return (void *)GDK_WINDOW_XID(gdkw);
#elif defined(WIN32)
return (void *)GDK_WINDOW_HWND(gdkw);
#elif defined(__APPLE__)
return (void *)gdk_quartz_window_get_nsview(gdkw);
#endif
g_warning("No way to get the native handle from gdk window");
return 0;
}
Here is few lines of code:
GtkWidget *video_window, *window;
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
video_window = gtk_drawing_area_new();
unsigned long *videoID;
videoID = malloc(sizeof(unsigned long));
*videoID = get_native_handle(gtk_widget_get_window(video_window));
linphone_core_set_native_video_window_id(lc, *videoID);
Worked for me!

Problems writing up WebBrowser COM events

I'm developing a project that needs to show HTML that is returned by a third party service. I am currently using a WPF WebBrowser to show this output. However this creates a potential security problem in the eyes of my customers. When focus is set to this control you can open any webpage by using CTRL+O or open Internet Explorer by using Ctrl+N. My application is targeted for a kiosk-like environment (Terminal Services).
In the past I've used the WinForms WebBrowser control and was able to sink into the events through COM, however those tactics don't seem to work with the WPF version. My development partners are adamant that we develop a pure WPF application instead of mixing in the WinForms option.
Has anyone had success getting to the IWebBrowserEvets2COM interface of the WPF WebBrowser? I have been able cast the WebBrowser.Document to an IWebBrowser, but haven't got to where I need.
Please help me tap into the events so that I can stop the user from creating new windows and other events that might cause "security" problems for my clients. Or is there a better control out there to do the rendering of HTML and basic navigation?
Thanks in advance,
Jerod
You can try to use Windows hooks here. Find browser window and install proper keyboard hooks for it. This externals should be helpful for you:
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, IntPtr windowTitle);
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
private static extern IntPtr SetWindowsHookEx(Int32 idHook, HookProc lpfn, IntPtr hInstance, Int32 threadId);
And here is a sample how to use those, but you have to implement KeyboardHookProcedure according to your needs.
private IntPtr FindExplorerWindow()
{
IntPtr wnd = Browser.Handle;
if (wnd != IntPtr.Zero)
{
wnd = FindWindowEx(wnd, IntPtr.Zero, "Shell DocObject View", IntPtr.Zero);
if (wnd != IntPtr.Zero)
{
wnd = FindWindowEx(wnd, IntPtr.Zero, "Internet Explorer_Server", IntPtr.Zero);
return wnd;
}
}
return IntPtr.Zero;
}
private void InstallHook()
{
if (_hHook.ToInt32() > 0) return;
IntPtr wnd = FindExplorerWindow();
if (wnd != IntPtr.Zero)
{
if (_hookProc == null)
{
_hookProc = new HookProc(KeyboardHookProcedure);
}
_hHook = SetWindowsHookEx(WH_KEYBOARD, _hookProc, (IntPtr)0, GetCurrentThreadId());
}
}
Good luck!

How to add an Icon to an application built with Eclipse Galileo C and MinGW?

I've read a lot about how to add an icon to an application built with Visual Studio, but I have no idea how to do this with Eclipse Galileo / C / MinGW.
Can anyone write a description, or give me a link ta a description ?
In Windows, the icons as well as some other elements (cursors, bitmaps, ...) have to be specified in a resource file, which once compiled will be linked to the program.
First an example on how to add an icon to a Windows program which will illustrate it's use within Eclipse. Here is a simple program that just creates a window, look at the time we fill the WNDCLASSEX, the icon of the application is referenced there:
resources.h - this file may be used to assign a value to a resource identifier, and so use the value instead:
#define AppIcon 101
The next file is the resources file, you may create it manually or from within Eclipse as well, to create it in Eclipse, right click the directory you want it to be (in this case is src) and select New -> File. There write the name you want and click Finish. To edit it from within Eclipse right click it and select Open with -> Text Editor.
resources.rc - the icon will be specified here:
#include "resources.h"
// The icon path I used will be needed by Eclipse.
// If you want to use back-slashes you have to scape them (\\ instead of \):
AppIcon ICON "../src/icon.ico"
demoicon.c - the file containing the code of the program:
#include <windows.h>
#include "resources.h"
const char *ClassName = "DemoIcon";
// Declaration of the window procedure, to be used in the WNDCLASSEX struct:
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrev, LPSTR lpCmdLine, int nShowCmd) {
WNDCLASSEX wc;
HWND hWnd;
MSG msg;
// Filling the structure:
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WindowProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
// Remember this just loads 32x32, use LoadImage() instead for other dimensions (16x16, 48x48, ...):
wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(AppIcon));
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW);
wc.lpszMenuName = NULL;
wc.lpszClassName = ClassName;
// Here we'll use LoadImage, as we need a 16x16 mini icon:
wc.hIconSm = LoadImage(hInstance,MAKEINTRESOURCE(AppIcon),IMAGE_ICON,16,16, LR_DEFAULTCOLOR);
// Registering the class:
if(!RegisterClassEx(&wc)) {
MessageBox(NULL,
"Could not register window.",
"Error",
MB_ICONEXCLAMATION | MB_OK);
return -1;
}
// Create the window using the "MainWindow" class:
hWnd = CreateWindowEx(WS_EX_WINDOWEDGE,
ClassName,
"Demo Icon",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
200,
150,
NULL,
NULL,
hInstance,
NULL);
// If the window was not created show error and exit:
if(hWnd == NULL) {
MessageBox(NULL,
"Could not create window.",
"Error",
MB_ICONEXCLAMATION | MB_OK);
return -1;
}
// Set the windows show state, to show it:
ShowWindow(hWnd, nShowCmd);
// Draw the window:
UpdateWindow(hWnd);
// Retrieve messages from the message queue:
while(GetMessage(&msg, NULL, 0, 0) > 0) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
// Implementation of the window procedure, will handle the messages:
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
switch(uMsg) {
case WM_CLOSE:
DestroyWindow(hWnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
return 0;
}
Now, in your Eclipse project source directory make sure you have all the files (in the example the 3 files mentioned before and the icon file).
After that go to Project -> Properties.
There, go to C/C++ Build -> Settings -> Build Steps tab.
There you'll see Pre-build steps -> Command. The command you fill in there will be executed before the compilation starts, so you'll tell it to compile the resource file. As you are using MinGW the resource compiler is windres:
windres ../src/resources.rc -o ../Resources/resources.o
As you can see I'll be placing the compiled resource file in a directory called Resources, you may leave it where you want (and so the name of the file, it doesn't have to be named resources.rc).
Now go to the Tool Settings tab.
There, go to MinGW C Linker -> Miscellaneous, and in other objects add the object file created before, in this case you should add:
Resources/resources.o
As this is a Windows app, add the option -mwindows to the linker flags at the top of the same tab.
Done, when building your project Eclipse will compile the resource file first and then link the generated object as any other object file of your project.
I hope it's clear enough to read through this.
Eclipse isn't set to look at resource files. BUG. So they also have steps to add it to processing. Here are the steps for June. [http://wiki.eclipse.org/CDT/User/FAQ#How_to_handle_Resource-Script-Files_.27.2A.rc.27_with_CDT.3F][1]
How to handle Resource-Script-Files '*.rc' with CDT?
Currently handling of windres.exe with CDT is not possible. You can not add the .rc file to the project to be compiled and linked with automatically. This is already raised as a bug in bugzilla.
One way is to create a Pre-Build Step. Under menue
Project | Properties | C/C++-Build | Settings | Build Steps | Pre-Build Steps
fill in the command-line:
windres --use-temp-file -i..\MyProject.rc -o..\MyProject_rc\MyProject_rc.o
Make the object known to the linker. Under menue
Project | Properties | C/C++-Build | Settings
Tool Settings | MinGW C++ Linker | Miscellaneous | Other Objects
click the icon 'Add', fill in the line:
"C:\MyWorkspace\MyProject\MyProject_rc\MyProject_rc.o"
'MyWorkspace' and 'MyProject' replace with whatever is fitting for your purpose.
You have to add the folder .\MyProject_rc before you build.
The path to windres.exe must be known to eclipse.
The way I did it was by creating a file
icon.rc
#define AppIcon 101
AppIcon ICON "../icon.ico"
Then invoke windres via command prompt with
windres my.rc -O coff -o my.res
It'll compile several files for you -- keep the one called icon.res and rename it as libicon.a. Finally include it in your program by adding it as a library under
Project -> Properties -> Build -> Settings -> C++ Linker -> Libraries
(make sure you tell Eclipse where to find the file using the library paths section underneath).
Hope this helps!
I zip up all of the icons I want to use within the project first. Then
Rename the .zip to a .jar
Create a resource folder if you havent got one already (I use "lib")
Then place the jar file inside the resource folder.
Then one simple addition to the project properties:
by right clicking and Configure "Java Build Path" - select the Libraries tab. Click on the Add JARs button and add the icons.jar to the libraries - then save.
Now its easy to allocate the desired image icon inside the Window Builder editor for example as the jar containing your icons appears within the Image Selection mode chooser within the Classpath resource list. Everything works as it should and compiles fine.

Resources