Simulate CAPS LOCK press in Xlib - keyboard-events

How do I simulate a CAPS LOCK on and off depress using Xlib?

#include <X11/X.h>
#include <X11/Xlib.h>
#include <X11/keysym.h>
#include <X11/extensions/XTest.h>
// Function: Click Key (press and release key)
void click_key( Display* p_display , KeyCode keycode ) {
XTestFakeKeyEvent( p_display , keycode , True , 0 ); // key press event
XTestFakeKeyEvent( p_display , keycode , False , 0 ); // key release event
XFlush( p_display );
return;
}
// Main
int main() {
Display* p_display = XOpenDisplay( NULL );
KeySym keysym = XK_VoidSymbol;
KeyCode keycode = NoSymbol;
keysym = XK_Caps_Lock;
keycode = XKeysymToKeycode( p_display , keysym );
click_key( p_display , keycode ); // activates CapsLock
click_key( p_display , keycode ); // deactivates CapsLock
XCloseDisplay( p_display );
return 0;
}
http://tronche.com/gui/x/xlib/
http://xopendisplay.hilltopia.ca/index.html

#include "stdio.h"
#include "X11/Xlib.h"
#include "X11/keysym.h"
#include "time.h"
Display *display=NULL;
unsigned int keycode;
int main ()
{
display = XOpenDisplay(NULL);
keycode = XKeysymToKeycode(display, XK_Caps_Lock);
printf ("\npressed\n");
XTestFakeKeyEvent(display, keycode, True, CurrentTime);
XFlush(display);
printf ("\nreleased\n");
XTestFakeKeyEvent(display, keycode, False, CurrentTime);
XFlush(display);
sleep(3);
/* type something here */
printf ("\npressed\n");
XTestFakeKeyEvent(display, keycode, True, CurrentTime);
XFlush(display);
printf ("\nreleased\n");
XTestFakeKeyEvent(display, keycode, False, CurrentTime);
XFlush(display);
sleep(3);
return 0;
}
Replace " " -s with < > for header files.
and compile using
gcc main.c -lX11 -lXtst
Posted above solution in my blog

Related

SDL_TTF, Render Modes are identical in quality

I have a click based game to code, and It contains some text that need to be rendererd in real-time,I tried to render the text with TTF_RenderText_Solid() , TTF_RenderText_Shaded(),TTF_RenderText_Blended() but they all render the same poor quality text. I have tried to change the BlendMode of the renderer, Surface and Texture, but still the same result, You might think it is because of using the same surface over and over, but I am sure it's not that.
screenshot
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_ttf.h>
#define Title "Test"
#define font01 "src/fonts/Roboto-Regular.ttf"
#define font01_size 48
typedef struct {
SDL_Texture *txtu;
SDL_Rect rect;
SDL_Color clr;
char* text;
} text_t;
int main(int argc,char* argv[])
{
SDL_Init(SDL_INIT_EVERYTHING);
TTF_Init();
SDL_Window *window = SDL_CreateWindow(Title,SDL_WINDOWPOS_CENTERED,SDL_WINDOWPOS_CENTERED,480,720,SDL_WINDOW_OPENGL);
SDL_Renderer *renderer = SDL_CreateRenderer(window,-1,SDL_RENDERER_ACCELERATED|SDL_RENDERER_TARGETTEXTURE);
TTF_Font *font1 = TTF_OpenFont(font01,font01_size);
SDL_SetRenderDrawBlendMode(renderer,SDL_BLENDMODE_BLEND);
SDL_Surface *Load_srfc = NULL;
SDL_SetSurfaceBlendMode(Load_srfc,SDL_BLENDMODE_BLEND);
//SDL_CreateTexture(renderer,SDL_PIXELFORMAT_RGBA8888,SDL_TEXTUREACCESS_TARGET,480,720);
SDL_SetRenderDrawColor(renderer,0,0,0,255);
SDL_RenderFillRect(renderer,NULL);
SDL_Delay(500);
text_t text1 = {NULL,{0,0,220,60},{255,255,255,240},"015:32.665 ms"};
text_t text2 = {NULL,{20,70,220,60},{255,255,255,240},"015:32.665 ms"};
text_t text3 = {NULL,{40,140,220,60},{255,255,255,240},"015:32.665 ms"};
Load_srfc = TTF_RenderText_Solid(font1,text1.text,text1.clr);
text1.txtu = SDL_CreateTextureFromSurface(renderer,Load_srfc);
SDL_SetTextureBlendMode(text1.txtu,SDL_BLENDMODE_BLEND);
SDL_FreeSurface(Load_srfc); Load_srfc=NULL;
SDL_RenderCopy(renderer,text1.txtu,NULL,&text1.rect);
SDL_RenderPresent(renderer);
SDL_Delay(500);
SDL_Color back = {240,30,50,245};
Load_srfc = TTF_RenderText_Shaded(font1,text2.text,text2.clr,back);
text2.txtu = SDL_CreateTextureFromSurface(renderer,Load_srfc);
SDL_SetTextureBlendMode(text2.txtu,SDL_BLENDMODE_BLEND);
SDL_FreeSurface(Load_srfc); Load_srfc=NULL;
SDL_RenderCopy(renderer,text2.txtu,NULL,&text2.rect);
SDL_RenderPresent(renderer);
SDL_Delay(500);
Load_srfc = TTF_RenderText_Blended(font1,text3.text,text3.clr);
text3.txtu = SDL_CreateTextureFromSurface(renderer,Load_srfc);
SDL_SetTextureBlendMode(text2.txtu,SDL_BLENDMODE_BLEND);
SDL_FreeSurface(Load_srfc); Load_srfc=NULL;
SDL_RenderCopy(renderer,text3.txtu,NULL,&text3.rect);
SDL_RenderPresent(renderer);
bool quit=0;
while(!quit)
{
SDL_Event evt;
while (SDL_PollEvent(&evt))
{
if(evt.type == SDL_QUIT ||
(evt.type == SDL_WINDOWEVENT && evt.window.event == SDL_WINDOWEVENT_CLOSE) ||
(evt.type == SDL_KEYDOWN && evt.key.keysym.sym == SDLK_ESCAPE)) {
quit = 1;
}
}
}
SDL_DestroyTexture(text1.txtu);
SDL_DestroyTexture(text2.txtu);
SDL_DestroyTexture(text3.txtu);
SDL_FreeSurface(Load_srfc);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
TTF_Quit();
SDL_Quit();
}

How XTestFakeKeyEvent combines events?

I need to send Shift+A keystrokes to get capital A. The only problem: I can't use XTestFakeKeyEvent (because it's an extension) and I don't want to pass Shift through an event.state (if possible). I tried 4 calls to XSendEvent which doesn't work. So I wonder: how XTestFakeKeyEvent does the same thing?
P.S: "my" code
// Send a fake keystroke event to an X window.
// by Adam Pierce - http://www.doctort.org/adam/
#include <X11/Xlib.h>
#include <X11/keysym.h>
// Function to create a keyboard event
XKeyEvent createKeyEvent(Display *display, Window &win,
Window &winRoot, bool press,
int keycode, int modifiers)
{
XKeyEvent event;
event.display = display;
event.window = win;
event.root = winRoot;
event.subwindow = None;
event.time = CurrentTime;
event.x = 1;
event.y = 1;
event.x_root = 1;
event.y_root = 1;
event.same_screen = True;
event.keycode = XKeysymToKeycode(display, keycode);
event.state = modifiers; // I know here I can pass Shift explicitly
// But is there a better way?
if(press)
event.type = KeyPress;
else
event.type = KeyRelease;
return event;
}
main()
{
// Obtain the X11 display.
Display *display = XOpenDisplay(0);
if(display == NULL)
return -1;
// Get the root window for the current display.
Window winRoot = XDefaultRootWindow(display);
// Find the window which has the current keyboard focus.
Window winFocus;
int revert;
XGetInputFocus(display, &winFocus, &revert);
// Send a fake key press event to the window.
XKeyEvent event = createKeyEvent(display, winFocus, winRoot, true, XK_A, 0);
XSendEvent(event.display, event.window, True, KeyPressMask, (XEvent *)&event);
// Send a fake key press event to the window.
event = createKeyEvent(display, winFocus, winRoot, true, XK_Shift_L, 0);
XSendEvent(event.display, event.window, True, KeyPressMask, (XEvent *)&event);
// Send a fake key release event to the window.
event = createKeyEvent(display, winFocus, winRoot, false, XK_Shift_L, 0);
XSendEvent(event.display, event.window, True, KeyPressMask, (XEvent *)&event);
// Send a fake key release event to the window.
event = createKeyEvent(display, winFocus, winRoot, false, XK_A, 0);
XSendEvent(event.display, event.window, True, KeyPressMask, (XEvent *)&event);
// Done.
XCloseDisplay(display);
return 0;
}

Why does this SDL2 program slow down?

I have a problem with this program that reads audio data from an input device and displays a line representing the volume level. It starts ok then a few seconds later it starts lagging. It worked without slow downs until I tried to add some code to add image display functionality, which didn't work so I removed it, but now it the program doesn't work properly. I've removed most of the program functionality which I'll add back if I fix it. The CPU and GPU usage remains low so no problems there. If I switch to Software Mode it seems to work. I'm on Windows using MinGW-w64.
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <SDL2/SDL.h>
#include <math.h>
int SCREEN_WIDTH = 1024; //default
int SCREEN_HEIGHT = 768; //default
int FULLSCREEN = 0;
SDL_Renderer *rend;
//#define SOFTWARE_RENDER
//#define VSYNC_ON
#define PROGRAM_NAME "My Game"
#ifdef SOFTWARE_RENDER
#define RENDERER SDL_RENDERER_SOFTWARE
#else
#define RENDERER SDL_RENDERER_ACCELERATED
#endif
#if !defined(SOFTWARE_RENDER) && defined(VSYNC_ON)
#define VSYNC SDL_RENDERER_PRESENTVSYNC
#else
#define VSYNC 0
#endif
////https://wiki.libsdl.org/SDL_AudioSpec#callback
void audioInCallback(void *userdata, Uint8 *stream,int len)
{
float *floatStream = (float*)stream;
if (stream == NULL)
{
puts("Stream is NULL.");
return;
}
SDL_SetRenderDrawColor(rend, 0, 0, 0, 255);
SDL_RenderClear(rend);
SDL_SetRenderDrawColor(rend, 255, 255, 255, 255);
float avg = 0;
for (int i=0;i<len;i++)
avg += fabs(floatStream[i]);
avg /= len;
SDL_RenderDrawLine(rend, 0,
SCREEN_HEIGHT/2 + round(SCREEN_HEIGHT/2.0 * avg),
SCREEN_WIDTH,
SCREEN_HEIGHT/2 + round(SCREEN_HEIGHT/2.0 * avg)
);
return;
}
int main(int argv, char *argc[])
{
int bufferSize = 8;
SDL_Window* window = NULL;
rend = NULL;
SDL_Event event;
bool loopIsActive = true;
SDL_AudioSpec want, have;
SDL_AudioDeviceID dev;
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) != 0)
{
printf("Unable to initialize SDL: %s", SDL_GetError());
return 1;
}
if( (window = SDL_CreateWindow( PROGRAM_NAME, SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH,
SCREEN_HEIGHT, SDL_WINDOW_SHOWN )) == NULL )
{
printf("Window could not be created! %s\n", SDL_GetError());
SDL_Quit();
return 0;
}
if ( (rend = SDL_CreateRenderer(window, -1, RENDERER | VSYNC)) == NULL )
{
printf("Error creating renderer. %s\n", SDL_GetError());
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
int count = SDL_GetNumAudioDevices(1);
for (int i=0;i<count;i++)
{
printf("%d. %s\n", i, SDL_GetAudioDeviceName(i, 1));
}
SDL_memset(&want, 0, sizeof(want)); /* or SDL_zero(want) */
want.freq = 44100;
want.format = AUDIO_S16;
want.channels = 1;
want.samples = pow(2,bufferSize);
want.callback = audioInCallback;
dev = SDL_OpenAudioDevice(NULL, 1, &want, &have, SDL_AUDIO_ALLOW_FORMAT_CHANGE);
if (dev == 0)
printf("Failed to open audio: %s", SDL_GetError());
else
{
printf("have.samples = %u\n", have.samples);
printf("Opened device %s\nAudio format: ", SDL_GetAudioDeviceName(0, 1));
if (SDL_AUDIO_ISFLOAT(have.format))
printf("%d-bit %s\n", SDL_AUDIO_BITSIZE(have.format), SDL_AUDIO_ISFLOAT(have.format) ? "float" :
SDL_AUDIO_ISSIGNED(have.format) ? "signed" : "unsigned");
SDL_PauseAudioDevice(dev, 0); /* start audio playing. */
}
while (loopIsActive == true)
{
while (SDL_PollEvent(&event))
{
switch (event.type)
{
case SDL_QUIT:
loopIsActive = false;
break;
case SDL_KEYDOWN:
if (event.key.keysym.scancode == SDL_SCANCODE_ESCAPE)
{
loopIsActive = false;
}
break;
}
}
SDL_RenderPresent(rend);
SDL_Delay(16);
}
if (dev != 0) SDL_CloseAudioDevice(dev);
SDL_DestroyRenderer(rend);
SDL_DestroyWindow(window);
SDL_Quit();
puts("Hello world!");
return 0;
}
Don't try to do SDL_Renderer operations in a different thread like the one the audio callback is typically called from. As #keltar pointed out this is prohibited by SDL:
These functions must be called from the main thread.
Instead, bundle up the audio samples via your favorite method for rendering on the main thread (sorry for the C++, not much of a C guy re: threading primitives):
#include <SDL.h>
#include <vector>
#include <atomic>
#include <iostream>
// triple-buffering logic stol^H^H^H^Hborrowed from:
// https://stackoverflow.com/questions/49352853
std::vector< float >* g_ProducerBuffer;
std::vector< float >* g_ConsumerBuffer;
std::atomic< std::vector< float >* > g_CurrentBuffer;
void audioInCallback( void* userdata, Uint8* stream, int len )
{
const float* floatStream = reinterpret_cast< float* >( stream );
for( auto& sample : *g_ProducerBuffer )
{
sample = *floatStream;
floatStream++;
}
// post new buffer
g_ProducerBuffer = g_CurrentBuffer.exchange( g_ProducerBuffer );
}
int main( int argc, char** argv )
{
SDL_Init( SDL_INIT_EVERYTHING );
SDL_SetHint( SDL_HINT_RENDER_VSYNC, "1" );
//SDL_SetHint( SDL_HINT_RENDER_DRIVER, "software" );
Uint32 flags = SDL_WINDOW_SHOWN;
SDL_Window* window = nullptr;
SDL_Renderer* renderer = nullptr;
SDL_CreateWindowAndRenderer( 1024, 768, flags, &window, &renderer );
// dump device names
int count = SDL_GetNumAudioDevices( 1 );
for( int i = 0; i < count; i++ )
{
std::cout << i << ": " << SDL_GetAudioDeviceName( i, 1 ) << '\n';
}
SDL_AudioSpec spec = { 0 };
spec.freq = 44100;
spec.format = AUDIO_F32LSB;
spec.channels = 1;
spec.samples = 1024;
spec.callback = audioInCallback;
const unsigned int deviceIndex = 0;
const std::string deviceName = SDL_GetAudioDeviceName( deviceIndex, 1 );
SDL_AudioDeviceID dev = SDL_OpenAudioDevice( deviceName.c_str(), 1, &spec, nullptr, 0 );
// set up audio buffers
std::vector< float > buffers[ 3 ];
buffers[ 0 ].resize( spec.samples );
buffers[ 1 ].resize( spec.samples );
buffers[ 2 ].resize( spec.samples );
g_ProducerBuffer = &buffers[ 0 ];
g_ConsumerBuffer = &buffers[ 1 ];
g_CurrentBuffer = &buffers[ 2 ];
// start audio capture
SDL_PauseAudioDevice( dev, 0 );
bool running = true;
while( running )
{
SDL_Event ev;
while( running && SDL_PollEvent( &ev ) )
{
if( SDL_QUIT == ev.type ||
SDL_KEYDOWN == ev.type && SDL_SCANCODE_ESCAPE == ev.key.keysym.scancode )
{
running = false;
}
}
SDL_SetRenderDrawColor( renderer, 0, 0, 0, 255 );
SDL_RenderClear( renderer );
// grab latest audio buffer
// (this *seems* to work on my system but I'm not 100% sure it's correct)
while( !g_CurrentBuffer.compare_exchange_weak( g_ConsumerBuffer, g_ConsumerBuffer ) );
// draw audio sample waveform
std::vector< SDL_Point > points( g_ConsumerBuffer->size() );
for( size_t i = 0; i < g_ConsumerBuffer->size(); ++i )
{
const int x = static_cast< int >( i );
const int y = static_cast< int >( (*g_ConsumerBuffer)[ i ] * 200 + 768 / 2 );
points[ i ] = SDL_Point{ x, y };
}
SDL_SetRenderDrawColor( renderer, 255, 255, 255, 255 );
SDL_RenderDrawLines( renderer, points.data(), points.size() );
SDL_RenderPresent( renderer );
}
SDL_CloseAudioDevice( dev );
SDL_DestroyRenderer( renderer );
SDL_DestroyWindow( window );
SDL_Quit();
return 0;
}

Power on button test for shutting down using c

I am using the below app when ever I press cpu`` power on button my application as to pause for few min like 5 min for that I used below app.the problem is I used sleep(300000) for stoping few min but the operation is not performing whenever I press power button please let me know if any on
#include <windows.h>
#include <stdio.h>
#include <pthread.h>
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>
#define SHUTDOWN_TEST
FILE *fp;
BOOL CtrlHandler( DWORD fdwCtrlType )
{
time_t rawtime;
struct tm * timeinfo;
time (&rawtime);
timeinfo = localtime (&rawtime);
switch( fdwCtrlType )
{
// Handle the CTRL-C signal.
case CTRL_C_EVENT:
printf( "Ctrl-C event\n\n" );
Beep( 750, 300 );
return( TRUE );
// CTRL-CLOSE: confirm that the user wants to exit.
case CTRL_CLOSE_EVENT:
Beep( 600, 200 );
printf( "Ctrl-Close event\n\n" );
return( TRUE );
// Pass other signals to the next handler.
case CTRL_BREAK_EVENT:
Beep( 900, 200 );
printf( "Ctrl-Break event\n\n" );
return FALSE;
case CTRL_LOGOFF_EVENT:
Beep( 1000, 200 );
printf( "Ctrl-Logoff event\n\n" );
return FALSE;
case CTRL_SHUTDOWN_EVENT:
printf( "Ctrl-Shutdown event\n\n" );
while(1)
{
Sleep(300000);
}
Beep( 750, 500 );
return FALSE;
default:
return FALSE;
}
}
int main( void )
{
fp = (fopen("C:\\shutdown.txt","w"));
#ifdef SHUTDOWN_TEST
if( SetConsoleCtrlHandler((PHANDLER_ROUTINE) CtrlHandler, TRUE ) )
{
printf( "\nThe Control Handler is installed.\n" );
printf( "\n -- Now try pressing Ctrl+C or Ctrl+Break, or" );
printf( "\n try logging off or closing the console...\n" );
printf( "\n(...waiting in a loop for events...)\n\n" );
while( 1 ){
printf("I am running\n");
Sleep(3000) ;
}
}
else
{
printf( "\nERROR: Could not set control handler");
return 1;
}
fclose(fp);
#else
if (pid = fork())
{
if( SetConsoleCtrlHandler((PHANDLER_ROUTINE) CtrlHandler, TRUE ) )
{
printf( "\nThe Control Handler is installed.\n" );
printf( "\n -- Now try pressing Ctrl+C or Ctrl+Break, or" );
printf( "\n try logging off or closing the console...\n" );
printf( "\n(...waiting in a loop for events...)\n\n" );
while( 1 ){
// printf("I am running\n");
// Sleep(3000) ;
}
}
}
else
{
}
#endif
return 0;
}
Blocking the System shutdown can not be done inside such a handler. Since Windows Vista there is a new API.
Use ShutdownBlockReasonCreate
You can use GetConsoleWindow to get the requested window handle.
Read this link to see the changes since Vista.

With SFML 1.6, what is the best way to count button presses?

For Example:
int count;
//Code to count key presses here
sf::String String("You have pressed a key this many times: " + count );
I already know how to convert the int to a string and insert it.
Use events:
#include <SFML/Graphics.hpp>
int main()
{
// Create the main window
sf::RenderWindow window(sf::VideoMode(800, 600), "SFML window");
int count = 0;
while (window.IsOpened())
{
sf::Event event;
while (window.GetEvent(event))
{
if (event.Type == sf::Event::Closed)
window.Close();
if (event.Type == sf::Event::KeyPressed && event.Key.Code == sf::Key::A)
++count;
}
window.Clear();
// Do whatever you want with count.
window.Display();
}
return 0;
}

Resources