how to write mouse program in linux - c

I have tried to write a program which will detect the mouse movement. But it is showing error while running in linux environment. i also want to implement the program where if user move the mouse in x axis for different distance like 2cm, 4 cm then it will print some statement. how can i initialize the mouse in linux and get the cursur point coordinate(x,y) while user move mouse.
#include <dos.h>
#include <graphics.h>
union REGS in, out;
void detect_mouse ()
{
in.x.ax = 0;
int86 (0X33,&in,&out); //invoke interrupt
if (out.x.ax == 0)
printf ("\nMouse Failed To Initialize");
else
printf ("\nMouse was Succesfully Initialized");
}
void showmouse_graphics ()
{
int gdriver = DETECT, gmode, errorcode;
initgraph(&gdriver, &gmode, "c:\\tc\\bgi");
in.x.ax = 1;
int86 (0X33,&in,&out);
getch ();
closegraph ();
}
void detect ()
{
int button;
while (!kbhit () )
{
in.x.ax = 3;
int86 (0X33,&in,&out);
button=out.x.bx&7
switch(button)
{
case 1:
print(“left button pressed\n”);
break;
case 2:
print(“right button pressed\n”);
break;
case 4:
print(“middle button pressed\n”);
break;
case 3:
print(“left and right button pressed\n”);
break;
case 5:
print(“left and middle button pressed\n”);
break;
case 6:
print(“right and middle button pressed\n”);
break;
case 7:
print(“all the three buttons pressed\n”);
break;
default:
print(“No button pressed\n”);
}
delay (200); // Otherwise due to quick computer response 100s of words will get print
}
}
void hide_mouse ()
{
in.x.ax = 2;
int86 (0X33,&in,&out);
}
int main ()
{
detect_mouse ();
showmouse_graphics ();
detect ();
hide_mouse ();
return 0;
}

You are using dos.h which is a header available for MS/PC-DOS, not available in Linux. It's my strong belief that it doesn't even compile under gcc in Linux.

Related

I want key `A` to be held for at least three seconds without a break. Make sure that is the case

I want key A to be held for at least three seconds without a break. If the key press is interrupted, the three-second period should apply again.
This is my previous program. Unfortunately, while the timer() procedure is running, the program does not notice anything about the release of the button or pressing it again.
My question to you is: what can I do?
I want to stay in C.
My IDE is Microsoft Visual Studio Community 2019, version 16.11.2.
I work with Windows 10.
#pragma warning(disable : 4996) // Visual Studio doesn't want to see old functions like ‘scanf’.
#include <stdio.h>
#include <Windows.h>
#include <cstdint>
#include <time.h>
bool supposed_to_run = true;
VOID KeyEventProc(KEY_EVENT_RECORD);
long long waited = 0ll;
time_t Time_of_the_keydown_event;
bool triggered = false;
void timer()
{
Time_of_the_keydown_event;
time_t _to = time(&_to) + 3ll;
do
{
Time_of_the_keydown_event = time(&Time_of_the_keydown_event);
} while (Time_of_the_keydown_event < _to && triggered);
}
void Logic(INPUT_RECORD rec)
{
if (rec.Event.KeyEvent.wVirtualKeyCode == 0)
{
return;
}
if (!rec.Event.KeyEvent.bKeyDown)
{
triggered = false;
return;
}
switch (rec.Event.KeyEvent.wVirtualKeyCode)
{
case VK_SHIFT:
break;
case VK_CONTROL:
break;
case VK_SPACE:
break;
case VK_LEFT:
break;
case VK_UP:
break;
case VK_RIGHT:
break;
case VK_DOWN:
break;
case 0x41: /*A*/
triggered = true;
timer();
printf("A\n");
break;
case 0x51: /*Q*/
break;
case 0x5A: /*Z*/
supposed_to_run = false;
break;
default:
break;
}
}
int main(void)
{
INPUT_RECORD rec{};
HANDLE hConInp = GetStdHandle(STD_INPUT_HANDLE);
DWORD ReadCount = 0;
//Change_size_position_and_color();
while (supposed_to_run)
{
ReadConsoleInput(hConInp, &rec, 1, &ReadCount);
Logic(rec);
}
// end program
printf("\nProgramm wird beendet. Dr\x81 \bcken Sie eine Taste und \x27 \bEnter\x27 \b.\n");
getchar();
return 0;
}
I recommend that you use the function WaitForSingleObject. That function allows you to wait for new console input to become available, and also allows you to specify a timeout, which should be 3 seconds in your case.
Depending on the return value of that function, you will know whether new console input has occurred or whether the timeout has expired.
switch ( WaitForSingleObject( hConInp, 3000 ) )
{
case WAIT_OBJECT_0:
//handle new console input
//ReadConsoleInput will not block if called now
break;
case WAIT_TIMEOUT:
//handle timeout
break;
default:
//handle error
}
However, this solution has one problem. While holding down the key, the key will automatically repeat, generating new input events. Therefore, the timeout of 3 seconds will probably never expire (unless you have configured your operating system to have a very long repeat delay).
Therefore, you will have to ignore these key down events and call WaitForSingleObject again, but this time not with a timeout of 3 seconds again. Instead, the new timeout should be the remaining time of the original 3 seconds.
In your code, you are using the ISO C function time. However, this function has a precision of only one second, which may not be accurate enough. Therefore, you may want to use the platform-specific function GetTickCount instead.
I believe I was able to get your program to work, by making the changes mentioned above. Here is my code:
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdbool.h>
bool supposed_to_run = true;
bool triggered = false;
bool require_release = false;
DWORD remaining_timeout;
void Logic( INPUT_RECORD *p_rec )
{
//only handle keyboard events
if ( p_rec->EventType != KEY_EVENT )
return;
if (!p_rec->Event.KeyEvent.bKeyDown)
{
if ( triggered )
{
printf( "removing trigger\n" );
triggered = false;
}
else if ( require_release && p_rec->Event.KeyEvent.wVirtualKeyCode == 0x41 )
{
printf( "key has been released and timeout may now be triggered again\n" );
require_release = false;
}
return;
}
switch (p_rec->Event.KeyEvent.wVirtualKeyCode)
{
case VK_SHIFT:
break;
case VK_CONTROL:
break;
case VK_SPACE:
break;
case VK_LEFT:
break;
case VK_UP:
break;
case VK_RIGHT:
break;
case VK_DOWN:
break;
case 0x41: /*A*/
if ( !triggered && !require_release )
{
printf( "triggering timeout\n" );
triggered = true;
remaining_timeout = 3000;
}
break;
case 0x51: /*Q*/
break;
case 0x5A: /*Z*/
supposed_to_run = false;
break;
default:
break;
}
}
int main(void)
{
INPUT_RECORD rec;
HANDLE hConInp = GetStdHandle(STD_INPUT_HANDLE);
DWORD ReadCount;
while (supposed_to_run)
{
if ( triggered )
{
bool timeout_expired = false;
DWORD start_time = GetTickCount();
switch ( WaitForSingleObject( hConInp, remaining_timeout ) )
{
case WAIT_OBJECT_0:
break;
case WAIT_TIMEOUT:
timeout_expired = true;
break;
default:
fprintf( stderr, "unexpected error!" );
exit( EXIT_FAILURE );
}
DWORD time_expired = GetTickCount() - start_time;
if ( !timeout_expired )
{
//It is possible that WaitForSingleObject did not report
//a timeout, but that GetTickCount now reports that the
//timeout expired. We should consider this also a timeout.
if ( time_expired >= remaining_timeout )
timeout_expired = true;
}
if ( timeout_expired )
{
triggered = false;
require_release = true;
printf( "A\n" );
continue;
}
else
{
remaining_timeout -= time_expired;
}
}
ReadConsoleInput( hConInp, &rec, 1, &ReadCount );
Logic( &rec );
}
return 0;
}
After the user holds down the key A for three seconds, it will display that character on the screen. Afterwards, a new timeout will not be triggered until the user releases the key and then presses it again.

C and SDL quit from function

I use C and SDL 2.0, but i have a problem, this(when you click on the window's "x" it quits):
void function(SDL_Surface *screen) {
SDL_Event event;
bool quit=false;
while (!quit) {
SDL_WaitEvent(&event);
switch (event.type) {
case...
case SDL_QUIT:
quit = true;
break;
}
}
This is working, but not well. If this is in a function like this, it quits only to the main(), so I need to click on "x" again to quit from the whole program.
How can I solve it? (I want to quit from the whole program everytime, does not matter if it's in a function or not).
As already mentioned in comments you, most probably, have multiple event handling loops, which is usually incorrect design. You game general layout should be something like:
int main(int argc, char* argv[]) {
// do initialize stuff
bool run = true;
SDL_Event evt;
// game loop
while (run) {
// process OS events
while(SDL_PollEvent(&evt) != 0) {
switch (evt.type) {
case SDL_QUIT:
run = false;
break;
}
}
update();
render();
}
// clean up
SDL_Quit();
return 0;
}

stm32F4 7-segment display

I have a problem with programming quad 7-segment display. I don't know how to make all multiplexed chars blinking.
I'm programming in CooCox
multiplexing code (interrupt):
void TIM2_IRQHandler(){
if (TIM_GetITStatus(TIM2,TIM_IT_Update)) {
TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
GPIO_ResetBits(GPIOC,15); //turn off all display cells
switch (disp) {
case 1:
decodeCharacters(digits[(alarm.RTC_AlarmTime.RTC_Minutes-time.RTC_Minutes)%10]); //called method decoding chars
break;
case 2:
decodeCharacters(digits[(alarm.RTC_AlarmTime.RTC_Seconds-time.RTC_Seconds)/10]);
break;
case 3:
decodeCharacters(digits[(alarm.RTC_AlarmTime.RTC_Seconds-time.RTC_Seconds)%10]);
break;
default:
decodeCharacters(digits[(alarm.RTC_AlarmTime.RTC_Minutes-time.RTC_Minutes)/10]);
break;
}
GPIO_ToggleBits(GPIOC,1<<disp); //turn on display cell
disp = (disp+1)%4;
}
}
where "disp" is unsigned integer.
I understand that you have a code that displays time and you want to make your digits blinking.
First thing that you need to do is to check how often your interrupt handler occurs. Then inside this handler you can create a static variable which will count time, e.g.
static unsigned int blinkCounter = 0;
if( blinkCounter < 500 )
{
/* Turn off the display */
}
else
{
/* Most of your current handler code */
}
if( blinkCounter > 1000 )
{
blinkCounter = 0;
}
blinkCounter++;

Issue with keyboard detection using SDL2 library for 2 players in C

This is my first time using SDL2 library. When I push W and S (handling the first player position) hold them, and then I push UP on my keyboard, nothing happens. Curious is that other buttons work just fine while I am holding the W and S buttons.
The same thing happens when I do it the opposite way (holding the UP and DOWN buttons...).
Header file:
/**
* Header file for theGame.
*
*/
#include <SDL2/SDL_ttf.h>
// macro definitions
#define HEIGHT 540
#define WIDTH 960
#define SPEED 300
#define MAXBULLETS 1000
#define BULLETSPEED 700
// structs definitions
typedef struct{
bool up, down, left, right, up2, down2, left2, right2;
bool p1Shooting, p2Shooting;
} Action;
typedef struct{
int x;
int y;
bool walking, shooting, alive, facingLeft;
int currentSprite;
int hp;
SDL_Texture *sheetTexture;
} Man;
typedef struct{
int x, y;
bool display; // is it on the screen
bool goingRight;
} Bullet;
typedef struct{
Man *p_p1;
Man *p_p2;
Bullet *bullets;
Action *action;
SDL_Texture *bulletTexture;
int frames;
} gameState;
/**
* Function detects keyboard actions.
*/
void eventsDetection(SDL_Event *event, Action *action, bool *running);
//other stuff
void renderStuff(SDL_Renderer *renderer, gameState game);
void logicStuff(gameState game);
int isInWindow(int x, int y);
void drawText(SDL_Renderer *renderer, char *text, int x, int y);
The problematic function:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <SDL2/SDL_timer.h>
#include <SDL2/SDL_ttf.h>
#include "theGame.h"
void eventsDetection(SDL_Event *event, Action *p_action, bool *running)
{
switch(event->type)
{
case SDL_QUIT:
*running = false;
break;
case SDL_KEYDOWN:
switch (event->key.keysym.scancode)
{
case SDL_SCANCODE_W:
p_action->up = true;
break;
case SDL_SCANCODE_S:
p_action->down = true;
break;
case SDL_SCANCODE_D:
p_action->right = true;
break;
case SDL_SCANCODE_A:
p_action->left = true;
break;
case SDL_SCANCODE_SPACE:
p_action->p1Shooting = true;
break;
}
break;
case SDL_KEYUP:
switch (event->key.keysym.scancode)
{
case SDL_SCANCODE_W:
p_action->up = false;
break;
case SDL_SCANCODE_S:
p_action->down = false;
break;
case SDL_SCANCODE_D:
p_action->right = false;
break;
case SDL_SCANCODE_A:
p_action->left = false;
break;
case SDL_SCANCODE_SPACE:
p_action->p1Shooting = false;
break;
}
break;
}
switch(event->type)
{
case SDL_QUIT:
*running = false;
break;
case SDL_KEYDOWN:
switch (event->key.keysym.scancode)
{
case SDL_SCANCODE_UP:
p_action->up2 = true;
break;
case SDL_SCANCODE_DOWN:
p_action->down2 = true;
break;
case SDL_SCANCODE_RIGHT:
p_action->right2 = true;
break;
case SDL_SCANCODE_LEFT:
p_action->left2 = true;
break;
case SDL_SCANCODE_P:
p_action->p2Shooting = true;
break;
}
break;
case SDL_KEYUP:
switch (event->key.keysym.scancode)
{
case SDL_SCANCODE_UP:
p_action->up2 = false;
break;
case SDL_SCANCODE_DOWN:
p_action->down2 = false;
break;
case SDL_SCANCODE_RIGHT:
p_action->right2 = false;
break;
case SDL_SCANCODE_LEFT:
p_action->left2 = false;
break;
case SDL_SCANCODE_P:
p_action->p2Shooting = false;
break;
}
break;
}
/*printf("----------------------\nACTIONS\n"
"1p: %d up, %d down, %d left, %d right\n"
"2p: %d up, %d down, %d left, %d right\n",
p_action->up,p_action->down,p_action->left,p_action->right,
p_action->up2,p_action->down2,p_action->left2,p_action->right2
);*/
}
And finally important part of main:
// Animation loop
while(running)
{
// events processing
while(SDL_PollEvent(&event))
{
eventsDetection(&event, p_action, &running);
}
// logic stuff
logicStuff(game);
// rendering
renderStuff(renderer, game);
// Show what was drawn
SDL_RenderPresent(renderer);
game.frames = game.frames + 1;
} // end of animation loop
Thank you very much for help.
It's has nothing to do with SDL, it's your keyboard. A common keyboard doesn't handle more than 2-3 keys at the same time and only if the keys are not on the same line or column. More info on wiki

Moving a square in SDL2 using C

I'm unable to move the rectangle I made in the program. There is no error message in the compiler when I run the program. Can you please tell me what I missed out in the keyboard event. Other event that I assigned to the window works fine. Thanks (an example will also be helpful).
#include <SDL.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
SDL_Window *o;
SDL_Renderer *r;
SDL_Event e;
int i = 1;
SDL_Rect q;
SDL_Init(SDL_INIT_VIDEO);
o = SDL_CreateWindow("Game test",
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
1024,
800,
SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE);
r = SDL_CreateRenderer(o, -1,SDL_RENDERER_ACCELERATED);
SDL_SetRenderDrawColor(r,0,0,255,255);
SDL_RenderClear(r);
//Creating a box
q.x=475;
q.y=700;
q.h=50;
q.w=50;
SDL_SetRenderDrawColor(r,0,0,0,255);
SDL_RenderFillRect(r,&q);
//SDL_Delay(10);
SDL_RenderPresent(r);
while(i)
{
while(SDL_PollEvent(&e) !=0)
{
if(e.type == SDL_QUIT)
i=0;
else if(e.type == SDL_KEYDOWN)
{
switch(e.key.keysym.sym)
{
case SDLK_ESCAPE:
case SDLK_q:
i=0;
break;
case SDLK_UP:
q.y -=10;
SDL_Delay(11);
break;
case SDLK_DOWN:
q.y +=10;
SDL_Delay(11);
break;
case SDLK_RIGHT:
q.x +=10;
SDL_Delay(11);
break;
case SDLK_LEFT:
q.x -=10;
SDL_Delay(11);
break;
default:
break;
}
}
}
}
SDL_DestroyWindow(o);
SDL_DestroyRenderer(r);
SDL_Quit();
return 0;
}
You are only rendering the contents of the window before you enter your event loop. Since you never redraw the contents in the event loop, it's not very strange that no changes happen.
In SDL, you need to constantly redraw the window to see any changes you make. Since you only call the redraw function once, you only see what's happening in the very first moment of the window's creation. You simply need to add a redraw call inside of the loop, and it'll show you moving the rectangle as expected.

Resources