Why console cannot catch mouse event after using function system()? - c

When I use the function system(), I cannot catch any mouse event.
I have already know system() function is a shell command, but why using this command will block catching mouse event?
#include <windows.h>
#include <stdio.h>
int main()
{
HANDLE ConsoleWin;
INPUT_RECORD eventMsg;
DWORD Pointer;
//system("mode con cols=140 lines=40"); //after using this function,I cannot catch any mouse event
while (1)
{
ConsoleWin = GetStdHandle(STD_INPUT_HANDLE);//Get the console window
ReadConsoleInput(ConsoleWin, &eventMsg, 1, &Pointer);//Read input msg
if (eventMsg.EventType == MOUSE_EVENT && eventMsg.Event.MouseEvent.dwButtonState == FROM_LEFT_1ST_BUTTON_PRESSED) {
printf("Left button clicked.");
}
else if (eventMsg.EventType == MOUSE_EVENT && eventMsg.Event.MouseEvent.dwButtonState == RIGHTMOST_BUTTON_PRESSED) {
printf("Right button clicked.");
}
}
return 0;
}

system() executes a new cmd.exe which resets many console flags. After each "system" you should restore console options this way:
DWORD mode;
GetConsoleMode(ConsoleWin, &mode);
system("...your command...");
SetConsoleMode(ConsoleWin, mode);
By the way, your program may have the same problem even without executing any system(). It relies on default console settings, which in turn depend on system settings and user preferences. I suggest you to add this code at the beginning of your program:
DWORD mode;
GetConsoleMode(ConsoleWin, &mode);
mode |= ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT | ENABLE_EXTENDED_FLAGS;
SetConsoleMode(ConsoleWin, mode);

Related

macOS: Override Modifier Key with CGEventTap

So I recently spilled some water on my macbook pro keyboard, and my left command and option keys no longer function. Apple wants me to mail it in for repairs, which I don't have time for right now. So I thought I'd override the right command key to serve as left control seeing as the left command key still works.
I adapted the following from a keylogger gist I found:
#include <stdio.h>
#import <Carbon/Carbon.h>
#import <ApplicationServices/ApplicationServices.h>
CGEventRef loggerCallback(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void* context)
{
if (type == kCGEventFlagsChanged && CGEventGetIntegerValueField(event, kCGKeyboardEventKeycode) == 54 /* right cmd key */) {
printf(
"TEST: %d %llu\n",
type,
CGEventGetIntegerValueField(event, kCGKeyboardEventKeycode)
);
CGKeyCode virtualKey = 0x3B; // kVK_Control (left control);
CGEventRef override = CGEventCreateCopy(event);
CGEventSetIntegerValueField(override, kCGKeyboardEventKeycode, virtualKey);
return override;
}
return event;
}
int main(int argc, const char * argv[])
{
CFMachPortRef tap;
if ((tap = CGEventTapCreate(kCGHIDEventTap,
kCGHeadInsertEventTap,
0, kCGEventMaskForAllEvents,
loggerCallback, NULL)) == NULL) {
printf("Failed ot create event tap\n");
exit(1);
}
CFRunLoopSourceRef runLoopSource;
if ((runLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, tap, 0)) == NULL) {
printf("Failed to create run loop source\n");
exit(1);
}
CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopCommonModes);
CGEventTapEnable(tap, true);
CFRunLoopRun();
return 0;
}
Now the event tap works correctly, and it does intercept keyboard events ( I can see TEST 12 54 printed to the console), but the key is still behaving as command and not control. According to the documentation for CGEventTapCallback, the callback may return:
A newly-constructed event. After the new event has been passed back to the event system, the new event will be released along with the original event.
Passing in kCGHeadInsertEventTap as the tap location should ensure my event tap is inserted at the head of the handler list. Am I doing something wrong here or is it just not possible to modify events like this?
#Willeke was correct in their comment. Although I was correctly overriding the event, what I really needed to do was use the keydown/keyup events to keep track of when the right command key is pressed. I could then use that flag to intercept other keypress events, remove the command modifier, and insert the control modifier flag use bitwise operators. However, the simple solution here to this problem comes from the documentation link they provided:
hidutil property --set '{"UserKeyMapping":[{"HIDKeyboardModifierMappingSrc":0x7000000E7,"HIDKeyboardModifierMappingDst":0x7000000E0}]}'

ncurses window close on trigger keyboard arrow [duplicate]

I've been trying to find a solution to this for quite a while; I cannot get my terminal window to recognize the keypad.
Here is my code:
while (1){
if (cmd != ERR) {
printw("Controls: LEFT/RIGHT and SPACEBAR (Q TO QUIT)");
if (cmd == ' '){
// Stuff
}
else if (cmd == KEY_LEFT){
// Stuff
}
else if (cmd == KEY_RIGHT){
// Stuff
}
else if (cmd == 'q'){
// Stuff
}
refresh();
}
cmd = getchar();
}
It recognizes that I am entering space (case 1) or "q" (case 4), but it will not recognize the built in curses macros. I'm using regular C, not C++ for this. Any suggestions?
Those constants are only returned by getch() if you enable the keypad.
The function signature is:
int keypad(WINDOW *win, bool bf)
keypad(win, true) enables the keypad and keypad(win, false) disables it. win is a pointer to the window where getch() is being called.
As mentioned by Alexandre Bell, keypad has to be enabled. Enable it for the default window or the window you are working with.
keypad(stdscr, TRUE); //Enables keypad for default window
If you are still having trouble getting it to work, make sure you are using an int datatype with getch(). The function prototype for getch() is:
int getch(void);
If you are using a char datatype for the return value of getch(), then it will not be large enough to fit the return value of special characters and you will get garbage values back.

Without creating a window, is it possible to detect the current XCB modifier state?

I use the Xkb sticky option, and I would like to write a program that emits some text to stdout when the modifier key state changes, e.g. when Ctrl is "active" regardless of whether the physical Ctrl key is pressed. I want this program to be able to work without creating a visible X window and leaving it open, as that would obstruct my use of other applications.
Is this possible using the Xkb, XkbCommon, Xlib and/or XCB libraries? I tried using XNextEvent as suggested in the Xkb spec, but this function just blocks forever.
My full attempt at an implementation is here, but this is the relevant portion:
#include <X11/X.h>
#include <X11/Xlib.h>
#include <X11/XKBlib.h>
/* Various X and Xkb data that are often needed together */
typedef struct ExtensionInfo {
Display* display; /* An X display */
int base_event_code; /* Integer code offset for Xkb events */
int base_err_code; /* Integer code offset for Xkb errors */
int xkb_version_major; /* Dual-purpose version indicator; see XkbOpenDisplay(3) */
int xkb_version_minor; /* Dual-purpose version indicator; see XkbOpenDisplay(3) */
int xkb_reason; /* Error reason if XkbOpenDisplay fails, or success reason */
} ExtensionInfo;
int main(int argc, char *argv[]) {
ExtensionInfo *extension_info;
XkbEvent xkb_event;
extension_info->display = XkbOpenDisplay(
/* NULL here is allowed by XkbOpenDisplay but not mentioned explicitly
* in the XkbOpenDisplay man page - it defaults to $DISPLAY */
NULL,
&(extension_info->base_event_code),
&(extension_info->base_err_code),
&(extension_info->xkb_version_major),
&(extension_info->xkb_version_minor),
&(extension_info->xkb_reason)
);
const unsigned long int xkb_details_mask = (
XkbModifierBaseMask |
XkbModifierStateMask |
XkbModifierLatchMask |
XkbModifierLockMask
);
bool xkb_initialized = XkbSelectEventDetails(
extension_info->display,
XkbUseCoreKbd,
XkbStateNotifyMask,
xkb_details_mask,
xkb_details_mask
);
printf("Waiting...\n");
XNextEvent(extension_info->display, &xkb_event.core);
printf("Done.\n");
}
In general yes, it's perfectly possible to call any kind of X11 requests which need a Window handle (eg. for getting or setting the selection) without popping a window on the screen -- by creating an InputOnly window.
But for Xkb* you don't even need that. In the posted snippet, your problem is that you're not calling XkbSelectEvents at all, so no Xkb events will be delivered to your X11 client.
The little example below does get an event whenever the state changes:
#include <X11/Xlib.h>
#include <X11/XKBlib.h>
#include <err.h>
int main(void){
Display *dpy; int xkb_event;
if(!(dpy = XkbOpenDisplay(0, &xkb_event, 0, 0, 0, 0)))
errx(1, "cannot open display '%s'", XDisplayName(0));
XkbSelectEvents(dpy, XkbUseCoreKbd, XkbStateNotifyMask,
XkbStateNotifyMask);
for(;;){
XkbEvent e; XNextEvent(dpy, &e.core);
if(e.type == xkb_event && e.any.xkb_type == XkbStateNotify)
warnx("xkb state changed!");
}
}

No console key up event while shift key is pressed

I have a piece of code that will read a key event from the console using the ReadConsoleInput function. It works mostly, except that it fails to read when a button is released while the shift key is pressed.
I wrote the most minimal example code I could. What it does right now is reads whether the 'a' key is pressed or not and displays it to the screen. If you run it and press 'a' you get
41[down]
41[up]
if you run it and hold down the shift key before pressing 'a', all you get is
41[down]
and you will not get a key up event until you release the shift key and press 'a' again.
Here is my code:
#include <stdlib.h>
#include <stdio.h>
#include <Windows.h>
#include <Tchar.h>
int main()
{
HANDLE rhnd = GetStdHandle(STD_INPUT_HANDLE);
while(1)
{
INPUT_RECORD buf[128];
DWORD Events = 0;
DWORD EventsRead = 0;
GetNumberOfConsoleInputEvents(rhnd, &Events);
if(Events == 0)continue;
int i;
for(i=0;i<sizeof(buf);++i)//clear buf in case ReadConsoleInput doesn't do it for me, probably unnecessary
((char *)buf)[i]=0;
ReadConsoleInput(rhnd, buf, 128, &(EventsRead));
for(i=0;i<128;++i)//I would just loop while i<EventsRead but this ensures there are not extra elements (a little paranoid, I know)
{
if(buf[i].EventType == KEY_EVENT && (buf[i].Event.KeyEvent.wVirtualKeyCode & 0xff) == 0x41 /*keycode for 'a' button -- you can remove this condition to see the results for all key presses*/)
{
printf("%x",buf[i].Event.KeyEvent.wVirtualKeyCode);
if(buf[i].Event.KeyEvent.bKeyDown)
{
printf("[down]\n");
}
else //if this else gets executed it's what I'm calling a key up event
//this conditional should only be reached if either 'a' is pressed or 'a' was just released
//and the else should only be executed if it was just released
{
printf("[up]\n");
}
}
}
}
}
Any ideas on why this is happening and how to fix it
Compiled on windows 10 using gcc (MinGW-64) and also using Visual Studio 15

How can I catch the timeout exception in a third dll function,I use c language in Windows

How can I catch the timeout exception in a third dll function,I use c language in Windows
I want to catch a timeout Exception while call a thirdly dll function, you know the function takes a long while, and I need it return a value in limited time, if it doesn't return in the time, I will give it a default value.
I have to look for so much infomation about but it doesn't work.
I get the two point:
1.use the alarm function in ,but it only work in Linux,I can't use it in Windows even I use the MinGW standerd GCC complier.
2.use the timeSetEvent function in and the setjmp/longjmp function in ,the three function maybe so closed to take it work.but I use them caused the programe dump,windows pops a DialogMessage say something wrong.
I give the code and the picture like this :
`
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <setjmp.h>
jmp_buf j;
/**
* 时间中断函数
*/
void PASCAL OneMilliSecondProc(UINT wTimerID, UINT msg, DWORD dwUser, DWORD dwl, DWORD dw2) {
printf("Timout!\n");
longjmp(j,1);
}
int longTimeFunction(){
while (1) {
printf("operating...\n");
Sleep(1000);
}
return 0;
}
int main(){
HANDLE hHandle;
UINT wTimerRes_1ms;//定义时间间隔
UINT wAccuracy; //定义分辨率
UINT TimerID_1ms; //定义定时器句柄
wTimerRes_1ms = 5000;
if((TimerID_1ms = timeSetEvent(
wTimerRes_1ms,
wAccuracy,
(LPTIMECALLBACK)OneMilliSecondProc, // 回调函数
(DWORD)(1), // 用户传送到回调函数的数据;
TIME_PERIODIC//周期调用定时处理函数
)) == 0) {
printf("start!!!!!!!!!!!\n");
} else {
printf("end!!!!!!!!!!!\n");
}
int temp = 0;
if(setjmp(j) == 0){
temp = longTimeFunction();
}else{
printf("xxxxxx...\n");
temp = -1;
}
printf("%d\n", temp);
return 0;
}
`
Unlike UNIX signals, timeSetEvent doesn't interrupt a thread, the callback runs in parallel and longjmping across threads is undefined behavior.
Concerning your actual question, this is a bad idea. Such an abortion could leave the library in an inconsistent state.
Instead, try to get the library vendor to offer an API that accepts a timeout, or use another library that already supports it.

Resources