How can I take a screenshot on Wayland? - c

Now I need to develop a plug-in that can take screenshots on Ubuntu, CentOS and fedora. I try to write it in Xlib. It can run on Ubuntu and CentOS, but Fedora uses Wayland, and the plug-in that I developed can't work.
Gnome screenshot can work on these platforms, but after reading his source code, I found that it can achieve screenshots by calling other processes, which is hard for me to learn from.
So is there any way I can take a screenshot on Wayland engine?

I get it in using dbus, here is the light code:
method_name = "Screenshot";
method_params = g_variant_new ("(bbs)",
TRUE,
FALSE, /* flash */
filename);
connection = g_application_get_dbus_connection (g_application_get_default ());
g_dbus_connection_call_sync (connection,
"org.gnome.Shell.Screenshot",
"/org/gnome/Shell/Screenshot",
"org.gnome.Shell.Screenshot",
method_name,
method_params,
NULL,
G_DBUS_CALL_FLAGS_NONE,
-1,
NULL,
&error);

Related

How do I check if my executable is running for a service or for a normal program?

I'm developing a win service in using mingw I've been trying for hours
I looked for examples on the internet I used ChatGPT
and nothing it returned works and the few examples I found
had nothing to do with what I wanted
I hope there is some way to do this the
idea and before i create the SERVICE_TABLE_ENTRY i can check if my executable was started
for a windows service,
if yes i create the
SERVICE_TABLE_ENTRY if I don't do anything else.
If your program supports multiple modes then I would suggest using a command line parameter like /service for the service registration.
Alternatively you could check if your process token contains S-1-5-6 (SECURITY_SERVICE_RID) but I'm not sure which Windows version that was introduced.
If you want to check if it's running you should check if the service is running. Check under services by running services.msc and looking for the service you registered.
Some time ago I wrote a simple library to make your program a service (on Windows) or daemon (on *nix):
https://sourceforge.net/projects/daemonservice/
Maybe you can check the source on how it was done there...
I saw a simple way to check this just create SERVICE_TABLE_ENTRY and use StartServiceCtrlDispatcher if it returns an error probably the executable was started like a normal program.
SERVICE_TABLE_ENTRY _dispatcher_entry_table[] =
{
{"", (LPSERVICE_MAIN_FUNCTION)serviceMain},
{NULL, NULL}
};
if (!StartServiceCtrlDispatcher(_dispatcher_entry_table))
{
DWORD __error_code = GetLastError();
if (__error_code == ERROR_FAILED_SERVICE_CONTROLLER_CONNECT)
{
//It's probably a normal program
}
else
{
//handle the errors
}
}

Can not debug kaa_client_create() function

I'm trying to understand kaa endpoint source code, my example is "Datacollection demo".
I'm reading kaa_client_create function, code is below
in main(), I call kaa_client_create function like that:
kaa_client_t *kaa_client = NULL;
printf("[Creat kaa client] %s\n",!kaa_client? "NULL":"not NULL");
kaa_error_t error = kaa_client_create(&kaa_client, NULL);
printf("[Creat kaa client] %s\n",!kaa_client? "NULL":"not NULL");
in kaa_client_create function, I add debug line as follow:
kaa_error_t kaa_client_create(kaa_client_t **kaa_client, kaa_client_props_t *props)
{
printf("I'm here \n");
KAA_RETURN_IF_NIL2(kaa_client, props, KAA_ERR_BADPARAM);
.....
}
result in console is:
[Creat kaa client] NULL
[Creat kaa client] not NULL
Default sample period: 5 seconds
Viettq's first kaa app sampled temperature: 26
Reading the console, I think kaa_client_create function is called, because kaa_client doesn't point to NULL, but why I don't see my debug line "I'm here"?
Could you hep me to understand, what happen ?
My source code here:
https://www.dropbox.com/s/obg68nmon31wdt7/kaa_myfirstproject.tar.gz?dl=0
Extract in ubuntu
source run_all.sh
Thank advance !
Viet
Unfortunately, the DropBox link does not exist any more.
But, from the code snippets you mentioned, it looks like you modified kaa_client_create() function for Econais platform which should not be used on POSIX (Linux Ubuntu as you mentioned).
If my guess is correct, you need to add the printf() to the src/kaa/platform-impl/posix/kaa_client.c file and re-build the client with that change.

Create OpenGL core profile under GLFW

How do I create a core profile using GLFW and OpenGL? I'm currently running Mesa 10.0.2 which should support OpenGL 3.3 in a core profile and 3.0 in a non-core profile.
Currently this is what I'm trying to do.
glfwOpenWindowHint(GLFW_FSAA_SAMPLES, 4);
glfwOpenWindowHint(GLFW_OPENGL_VERSION_MAJOR, 3);
glfwOpenWindowHint(GLFW_OPENGL_VERSION_MINOR, 3);
glfwOpenWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
// Create context
if( !glfwOpenWindow( 1024, 768, 0,0,0,0, 32,0, GLFW_WINDOW ) )
{
fprintf( stderr, "Failed to create context\n" );
glfwTerminate();
return -1;
}
I found this to be largely a GLFW version issue as genpfault and Brett Hale pointed out. Once I ported the offending code to GLFW 3 the issue disappeared. I also updated to a newer version of the GLM library. For those who are playing with opengl-tutorial.org, I suggest taking it as an exercise to rewrite the code using updated libraries as the ones supplied are very old at this point.

Create openGL context in linux console(Raspbian)

I want to make a minimal visual display in console with openGL, but as far as my knowledge goes there has to be a window system involved(glut, glfw, sdl, etc..).
I've seen omxplayer build a graphic environment(I just assume it is openGL or something similar, so please correct me if I'm wrong) from console, in order to save some processing power, and make movies watchable in the PI.
I'm just wondering how do they do it? Is there some literature in the topic? I'm mostly interested in solutions in C/C++, but any language with these capabilities would be great to know about!
I scavenged through the source code, but couldn't really find a clue about this particular task. Any help or pointer would be appreciated!
Note: the Raspberry Pi does OpenGL ES, not OpenGL.
You can find examples of making console based OpenGL ES applications in the VideoCore SDK:
/opt/vc/src/hello_pi
I'm not sure what you mean by "window system", especially as you mention SDL. You can absolutely use SDL + OpenGL ES in the console. That's what the Quake3 port (and the Quake2 port I made) uses.
It uses the EGL native platform interface.
Here's some code from the SubtitleRenderer class:
void SubtitleRenderer::initialize_vg() {
// get an EGL display connection
display_ = eglGetDisplay(EGL_DEFAULT_DISPLAY);
ENFORCE(display_);
// initialize the EGL display connection
ENFORCE(eglInitialize(display_, NULL, NULL));
// get an appropriate EGL frame buffer configuration
static const EGLint attribute_list[] = {
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_ALPHA_SIZE, 8,
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_NONE
};
EGLConfig config{};
EGLint num_config{};
ENFORCE(eglChooseConfig(display_, attribute_list, &config, 1, &num_config));

Why am I getting Error Code 6 on StartService?

For my purposes, I need to write a kernel mode driver for Windows. Currently I am attempting to make it work under Windows 7 x64.
I created a simple project in Visual Studio 2012 with default code for a KMDF driver. I compiled the code with test-signing on. The driver was compiled and signed.
I also have Test-Signing ON enabled as clearly displayed on the bottom left corner of my Desktop.
Upon trying to start the driver as a service, I always get an Error Code 6: Invalid Handle error.(I have since simplified the code to just try and start it but still did not work;default code did not work either)
Basically, I am having the same problem as the question asked here
https://stackoverflow.com/questions/12080157/startservice-error-6
unfortunately he was never answered. I tried the provided solution, but it didn't help either.
My code that tries to start the driver is
int _cdecl main(void)
{
HANDLE hSCManager;
HANDLE hService;
SERVICE_STATUS ss;
hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
printf("Load Driver\n");
if(hSCManager)
{
printf("Create Service\n");
hService = CreateService(hSCManager, "Example",
"Example Driver",
SERVICE_ALL_ACCESS | SERVICE_START | DELETE | SERVICE_STOP ,
SERVICE_KERNEL_DRIVER,
SERVICE_DEMAND_START,
SERVICE_ERROR_IGNORE,
"\\path\\to\\driver\\KMDFDriver1.sys",
NULL, NULL, NULL, NULL, NULL);
if(!hService)
{
hService = OpenService(hSCManager, "Example",
SERVICE_ALL_ACCESS | SERVICE_START | DELETE | SERVICE_STOP);
if(!hService)
{
// If initial startup of the driver failed, it will fail here.
process_error();
return 0;
}
}
if(hService)
{
printf("Start Service\n");
if(StartService(hService, 0, NULL) == 0)
{
// Start service ALWAYS returns 0. Only when executed for the first time. Next time it fails on OpenService.
process_error();
printf("Did not start!\n");
}
printf("Press Enter to close service\r\n");
getchar();
ControlService(hService, SERVICE_CONTROL_STOP, &ss);
DeleteService(hService);
CloseServiceHandle(hService);
}
CloseServiceHandle(hSCManager);
}
return 0;
}
And this is the driver code
DRIVER_INITIALIZE DriverEntry;
#ifdef ALLOC_PRAGMA
#pragma alloc_text (INIT, DriverEntry)
#endif
NTSTATUS
DriverEntry(
_In_ PDRIVER_OBJECT DriverObject,
_In_ PUNICODE_STRING RegistryPath
)
{
WDF_DRIVER_CONFIG config;
NTSTATUS status;
DbgPrint("Hello World!\n");
WDF_DRIVER_CONFIG_INIT(&config,
NULL
);
config.DriverInitFlags = WdfDriverInitNonPnpDriver;
status = WdfDriverCreate(DriverObject,
RegistryPath,
WDF_NO_OBJECT_ATTRIBUTES,
&config,
WDF_NO_HANDLE
);
if (!NT_SUCCESS(status)) {
KdPrint( ("WdfDriverCreate failed with "
"status 0x%x\n", status));
}
return status;
}
The function process_error() is a wrapper around GetLastError() which in addition to providing the numeric value, displays a text version of the error code.
I have exhausted all options provided to me to solve this issue. A google search revealed only one occurrence of this problem, and the question was asked here.
What could the problem be?
Extra notes: The driver was compiled with Visual Studio 2012 Ultimate, while my startup code was compiled with MinGW-W64(using GCC). But the startup code shouldn't matter as much as the driver.
Extra notes 2: After wondering for a long time what could be wrong I started thinking if it's the test-sign certificate, because I tried driver source code provided from MSDN, and upon successful compilation, I still got ERROR_INVALID_HANDLE(Error Code 6) when trying to start it.
I have still not found a solution.
I tracked this down to the project settings of the driver. The KMDF versions were missing from the project.
Adjust the following (under Driver Model Settings):
- KMDF Version Major = 1
- KMDF Version Minor = 9
Hit OK, recompile, and reinstall. Worked for me!
A few thoughts:
You're using HANDLE hSCManager && HANDLE hService, they should be declared as SC_HANDLE
http://msdn.microsoft.com/en-us/library/windows/desktop/ms682450(v=vs.85).aspx
"lpBinaryPathName [in, optional]
The fully qualified path to the service binary file. If the path contains a space, it must be quoted so that it is correctly interpreted. For example, "d:\my share\myservice.exe" should be specified as "\"d:\my share\myservice.exe\"".
Try using the full path to the driver
I had the same problem with starting my kernel driver:
startservice failed 6:
the handle is invalid
Turned out that the "classID GUID" of the driver was the same as that of an other one (found out through device manager, looking in events showed different driver names).
Used an online generator to make a new GUID and replaced the one that's in the .inf file of the project (in VS, not any texteditor or some).
After a rebuild and deployment on target machine everything worked fine.
Hope this helps...
Run visual studio with admin privilege
Your call to OpenSCManager() is only asking for SC_MANAGER_CREATE_SERVICE permission by itself, which is not enough for OpenService() or StartService() to succeed.

Resources