I've been trying to create a simple program using libevdev to make a virtual device that will simply move the mouse by 50 points on the X axis every second. The program runs just fine, however Xorg won't recognize the newly created virtual device.
I suppose it's going to be something trivial, but I cannot figure out what.
Xorgs' logs say:
[ 5860.310] (II) config/udev: Adding input device test device Mouse (/dev/input/event18)
[ 5860.310] (II) No input driver specified, ignoring this device.
[ 5860.310] (II) This device may have been added with another device file.
The program:
#include <libevdev/libevdev.h>
#include <libevdev/libevdev-uinput.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
static void check(int i) {
if (i < 0) {
printf("%s\n", strerror(-i));
exit(1);
}
}
int main() {
struct libevdev* evdev = libevdev_new();
libevdev_set_name(evdev, "test device Mouse");
libevdev_set_id_vendor(evdev, 0x1);
libevdev_set_id_product(evdev, 0x1);
libevdev_set_id_version(evdev, 0x1);
libevdev_set_id_bustype(evdev, BUS_USB);
check(libevdev_enable_event_type(evdev, EV_REL));
check(libevdev_enable_event_code(evdev, EV_REL, REL_X, NULL));
check(libevdev_enable_event_code(evdev, EV_REL, REL_Y, NULL));
check(libevdev_enable_event_code(evdev, EV_SYN, SYN_REPORT, NULL));
struct libevdev_uinput* uinput;
check(libevdev_uinput_create_from_device(evdev, LIBEVDEV_UINPUT_OPEN_MANAGED, &uinput));
for (int i = 0; i < 1000; i++) {
check(libevdev_uinput_write_event(uinput, EV_REL, REL_X, 50));
check(libevdev_uinput_write_event(uinput, EV_SYN, SYN_REPORT, 0));
sleep(1);
}
}
What am I doing wrong?
The issue was that mouse buttons need to be enabled for mouse movements to work.
Adding these lines fixes the issue:
check(libevdev_enable_event_type(evdev, EV_KEY));
check(libevdev_enable_event_code(evdev, EV_KEY, BTN_LEFT, NULL));
check(libevdev_enable_event_code(evdev, EV_KEY, BTN_RIGHT, NULL));
Related
I'm writing a method for keyboard handling where I'm passing the key unicodes and firing keystrokes using the XTestFakeKeyEvent Method of X11. Now my issue is that after the opening the display, if the very first Character I send is in Uppercase, it still is typed in lowercase. So provided is the minimal implementation.
Compiled using command: gcc typekeys.c -o typekeys.exe -lX11 -lXtst
#include <stdio.h>
#include <stdbool.h>
#include <X11/extensions/XTest.h>
#include <X11/XKBlib.h>
#include <X11/Xlib.h>
static Display *mainDisplay = NULL;
Display *XGetMainDisplayK(void) {
if (mainDisplay == NULL) {
mainDisplay = XOpenDisplay(NULL);
if (mainDisplay == NULL) {
printf("\nCould not open main display");
}
}
return mainDisplay;
}
void toggleKeySym(unsigned int key){
KeySym sym;
Display *dpy;
dpy = XGetMainDisplayK();
sym=key;
printf("\nKeysym recieved:%u \n",key);
int min, max, numcodes;
XDisplayKeycodes(dpy, &min, &max);
KeySym *keysym;
keysym = XGetKeyboardMapping(dpy, min, max-min+1, &numcodes);
keysym[(max-min-1)*numcodes]=sym;
XChangeKeyboardMapping(dpy, min, numcodes, keysym, (max-min));
XFree(keysym);
XFlush(dpy);
unsigned int code;
printf("Keysym value:%d \n",sym);
code=XKeysymToKeycode(dpy, sym);
printf("Code Generated:%u. \n",code);
XTestFakeKeyEvent(dpy, code, True, CurrentTime);
XTestFakeKeyEvent(dpy, code, False, CurrentTime);
XSync(dpy, false);
XFlush(dpy);
}
void main(){
printf("Start \n");
toggleKeySym(65);
toggleKeySym(65);
printf("Done.\n");
}
The problem is XKeysymToKeycode(dpy, sym);:
If you look at the output of your program, you will see that it outputs something like this:
Code Generated:38.
...
Code Generated:254.
At least on my computer it behaves this way.
(By the way: I can only reproduce the problem the first time after logging off from my computer and logging on again.)
However, your program should write the same value twice because the same key code (254) is pressed.
This means that XKeysymToKeycode(dpy, sym); has returned the wrong value.
The reason is that XKeysymToKeycode() works the following way:
The XOpenDisplay() function calls XGetKeyboardMapping() reading the keyboard information to some "internal" variable (of the type KeySym *); the information in the "internal" variable is then used by XKeysymToKeycode().
The "internal" variable is updated later - maybe during XSync(). However, it seems that the "internal" variable is not updated before XKeysymToKeycode() is called the first time, so XKeysymToKeycode() returns the information still based on the old value of the "internal" variable.
However, you know that you have changed the symbol generated by the key max-1, so you know that code should have the value max-1. Therefore, calling XKeysymToKeycode() is not necessary at all.
I am developing an OS kernel. I am facing a problem that till a particular size of the kernel - 8KB it runs perfectly but as it gets just a little over 8KB, it starts behaving abnormally. The clear screen function doesn't work, the scrolling function doesn't work etc.
I am using the bochs emulator with a 1.44MB floppy configuration.
My code working correctly is -
#include "functions.h"
#include "stdint.h"
#include "stddef.h"
#include "../drivers/colors.h"
void delay();
char getScancode();
void main()
{
/*Declarations*/
char* str = "Welcome to MyOS v0.2.4 By Anish Sharma 2017";
char* status = "Welcome Anish Sharma";
uint8_t i = 0;
for(i=0;i<80;i++)
putChar(' ',i,24,STATUS_COLOR);
write_string_line(STATUS_COLOR,status,24);
clrscr();
print("The KERNEL has been loaded successfully at 0x1000 (memory address)");
print(str);
print(">>>");
update_cursor(3,2);
for(i=0;i<80;i++)
{
putChar(0xdb,i,3,i);
}
for(i=0;i<80;i++)
{
putChar(0xdb,i,4,i);
}
for(i=0;i<80;i++)
{
putChar(0xdb,i,5,i);
}
for(i=0;i<80;i++)
{
putChar(0xdb,i,6,i);
}
for(i=0;i<80;i++)
{
putChar(0xdb,i,3,i);
}
}
The output is -
Adding just another -
for(i=0;i<80;i++)
{
putChar(0xdb,i,3,i);
}
The output is -
Can anyone tell me what is causing this problem?
I'm trying to code a program that gets the % of a laptop battery and then displays a CMD showing a message (for example: 10% -> "Low battery!").
I've tried to google it, and it seems they all tried with C++ or C#.
Can anybody help me with C, please?
Edit: thanks zakinster for your reply. Shouldn't it look something like this? This code ain't working.
#include <Windows.h>
#include <Winbase.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main() {
SYSTEM_POWER_STATUS status;
GetSystemPowerStatus(&status);
unsigned char battery = status.BatteryLifePercent;
printf("%s", battery);
}
GetSystemPowerStatus from the Win32 API should provide the information you need :
SYSTEM_POWER_STATUS status;
if(GetSystemPowerStatus(&status)) {
unsigned char battery = status.BatteryLifePercent;
/* battery := 0..100 or 255 if unknown */
if(battery == 255) {
printf("Battery level unknown !");
}
else {
printf("Battery level : %u%%.", battery);
}
}
else {
printf("Cannot get the power status, error %lu", GetLastError());
}
See the documentation of the SYSTEM_POWER_STATUS structure for a complete list of contained information.
This is a follow-up to How to insert synthetic mouse events into X11 input queue
I'm trying to create a program that takes input from an external device and generates mouse clicks so that GTK+ will get and handle the events as if they mouse click happened normally.
Seems I can use a GdkEventButton structure:
https://developer.gnome.org/gdk/stable/gdk-Event-Structures.html#GdkEventButton
But I'm not sure how to determine the values to enter for each field. I'm looking for a small snippet of sample code or advice from somebody that has used gtk_event_put() with a GdkEventButton structure.
EDIT: If anybody knows a different or better way than my answer, please let me know.
There is another way, but this way I'm going to present, involve the use of pure X11, although seeing your question's tags, an answer that uses X11 is acceptable too.
That said, let me start by introducing the function where all happens, one thing, I'm going to be a bit verbose, in case of some other people that don't understand how use this function.
void
mouse_click(Display *display, int x, int y, int click_type, struct timeval *t);
display structure previously returned by XOpenDisplay() that contains all the information about the X server.
x the x coordinate of the pointer relative to the root of the screen.
y the y coordinate of the pointer relative to the root of the screen.
click_type the type of the click. For this answer, either MOUSE_RIGHT_CLICK or MOUSE_LEFT_CLICK
t timeval structure, specified the time interval the click should remain pressed.
Implementation
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <sys/types.h>
#include <sys/select.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#define portable_usleep(t) select(0, NULL, NULL,NULL, t)
enum { MOUSE_RIGHT_CLICK, MOUSE_LEFT_CLICK };
void
mouse_click(Display *display, int x, int y, int click_type, struct timeval *t)
{
Window root;
XEvent event;
root = DefaultRootWindow(display);
XWarpPointer(display, None, root, 0, 0, 0, 0, x, y);
memset(&event, 0, sizeof(event));
event.xbutton.type = ButtonPress;
event.xbutton.button = click_type;
event.xbutton.same_screen = True;
XQueryPointer(display, root, &event.xbutton.root, &event.xbutton.window,
&event.xbutton.x_root, &event.xbutton.y_root,
&event.xbutton.x, &event.xbutton.y, &event.xbutton.state);
event.xbutton.subwindow = event.xbutton.window;
while(event.xbutton.subwindow) {
event.xbutton.window = event.xbutton.subwindow;
XQueryPointer(display, event.xbutton.window,&event.xbutton.root,
&event.xbutton.subwindow, &event.xbutton.x_root,
&event.xbutton.y_root, &event.xbutton.x, &event.xbutton.y,
&event.xbutton.state);
}
if(XSendEvent(display, PointerWindow, True, 0xfff, &event)==0)
fprintf(stderr, "XSendEvent()\n");
XFlush(display);
portable_usleep(t); /* keeps the click pressed */
event.type = ButtonRelease;
event.xbutton.state = 0x100;
if(XSendEvent(display, PointerWindow, True, 0xfff, &event)==0)
fprintf(stderr, "XSendEvent()\n");
XFlush(display);
}
Well, this function it's pretty straight forward, for example, left click at position 500,645 button pressed for half a second, this is how:
int
main(void)
{
int x;
int y;
Display *display;
struct timeval t;
display = XOpenDisplay(NULL);
if(!display) {
fprintf(stderr, "Can't open display!\n");
exit(EXIT_FAILURE);
}
x = 500;
y = 645;
t.tv_sec = 0;
t.tv_usec = 500000; /* 0.5 secs */
mouse_click(display, x, y, MOUSE_LEFT_CLICK, &t);
XCloseDisplay(display);
return 0;
}
Compile
$ gcc -o click click.c -lX11
After some research I was able to learn that GTK+/GDK 2.14 and newer have some functions for creating automated testing suites for GTK+ applications.
I was able to use gdk_test_simulate_button to simulate mouse clicks. This may not be the optimum solution, but right now it appears to work well.
i am trying to get a screenshot of the screen or a window. I tried using functions from X11
and it works fine. The problem is that getting the pixels from XImage takes a lot of time.
Than i tried to look for some answers on how to do it using openGL. Here's what i've got:
#include <stdlib.h>
#include <stdio.h>
#include <cstdio>
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glx.h>
#include <X11/Xlib.h>
int main(int argc, char **argv)
{
int width=1200;
int height=800;
//_____________________________----
Display *dpy;
Window root;
GLint att[] = { GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, None };
XVisualInfo *vi;
GLXContext glc;
dpy = XOpenDisplay(NULL);
if ( !dpy ) {
printf("\n\tcannot connect to X server\n\n");
exit(0);
}
root = DefaultRootWindow(dpy);
vi = glXChooseVisual(dpy, 0, att);
if (!vi) {
printf("\n\tno appropriate visual found\n\n");
exit(0);
}
glXMakeCurrent(dpy, root, glc);
glc = glXCreateContext(dpy, vi, NULL, GL_TRUE);
printf("vendor: %s\n", (const char*)glGetString(GL_VENDOR));
//____________________________________________
glXMakeCurrent(dpy, root, glc);
glEnable(GL_DEPTH_TEST);
GLubyte* pixelBuffer = new GLubyte[sizeof(GLubyte)*width*height*3*3];
glReadBuffer(GL_FRONT);
GLint ReadBuffer;
glGetIntegerv(GL_READ_BUFFER,&ReadBuffer);
glPixelStorei(GL_READ_BUFFER,GL_RGB);
GLint PackAlignment;
glGetIntegerv(GL_PACK_ALIGNMENT,&PackAlignment);
glPixelStorei(GL_PACK_ALIGNMENT,1);
glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_INT, pixelBuffer);
int i;
for (i=0;i<100;i++) printf("%u\n",((unsigned int *)pixelBuffer)[i]);
return 0;
}
when i run the program it returns an error:
X Error of failed request: BadAccess (attempt to access private resource denied)
Major opcode of failed request: 199 ()
Minor opcode of failed request: 26
Serial number of failed request: 20
Current serial number in output stream: 20
if i comment the line with glXMakeCurrent(dpy, root, glc); before glc = glXCreateContext(dpy, vi, NULL, GL_TRUE); it returns no erros, but all the pixels are 0.
How should i go about this problem? I am new to openGL and maybe i am missing something important here. Maybe also another way of getting pixels from the screen or specific window exists?
I don't think what you are trying to do is possible. You can't use OpenGL to read pixels from window you don't own and which probably don't even use OpenGL. You need to stick to X11.
If you have XImage you can get raw pixels from ximage->data. Just make sure you are reading it in correct format.
http://tronche.com/gui/x/xlib/graphics/images.html
You can use XShmGetImage, but you have to query the extensions of the X11 server first, to make sure MIT-SHM extension is available. You also need to know how to setup and use a shared memory segment for this.
Querying the Extension:
http://git.videolan.org/?p=ffmpeg.git;a=blob;f=libavdevice/x11grab.c#l224
Getting the image:
http://git.videolan.org/?p=ffmpeg.git;a=blob;f=libavdevice/x11grab.c#l537
The following runs once at 140 fps on my platform. xcb_image_get() (called with XCB_IMAGE_FORMAT_Z_PIXMAP) will store all pixels in ximg->data, pixel by pixel. On my platform, each pixel is 32 bits, each channel is 8 bits, and there's 3 channels (to 8 bits per pixel are unused).
/*
gcc ss.c -o ss -lxcb -lxcb-image && ./ss
*/
#include <stdio.h>
#include <xcb/xcb_image.h>
xcb_screen_t* xcb_get_screen(xcb_connection_t* connection){
const xcb_setup_t* setup = xcb_get_setup(connection); // I think we don't need to free/destroy this!
return xcb_setup_roots_iterator(setup).data;
}
void xcb_image_print(xcb_image_t* ximg){
printf("xcb_image_print() Printing a (%u,%u) `xcb_image_t` of %u bytes\n\n", ximg->height, ximg->width, ximg->size);
for(int i=0; i < ximg->size; i += 4){
printf(" ");
printf("%02x", ximg->data[i+3]);
printf("%02x", ximg->data[i+2]);
printf("%02x", ximg->data[i+1]);
printf("%02x", ximg->data[i+0]);
}
puts("\n");
}
int main(){
// Connect to the X server
xcb_connection_t* connection = xcb_connect(NULL, NULL);
xcb_screen_t* screen = xcb_get_screen(connection);
// Get pixels!
xcb_image_t* ximg = xcb_image_get(connection, screen->root, 0, 0, screen->width_in_pixels, screen->height_in_pixels, 0xffffffff, XCB_IMAGE_FORMAT_Z_PIXMAP);
// ... Now all pixels are in ximg->data!
xcb_image_print(ximg);
// Clean-up
xcb_image_destroy(ximg);
xcb_disconnect(connection);
}