Related
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <iostream>
#include <string.h>
int main(){
int fd;
size_t size;
char name[]="aaa.fifо";
umask(0) ;
if (mknod(name, S_IFIFO | 0666, 0) < 0){
printf("Can\'t create FIFO\n");
_exit(-1);
}
if ((fd = open(name, O_WRONLY)) < 0){
printf("Can\'t open FIFO for writing\n");
_exit(-1);
}
char message[60];
while(true){
message[0] = 0;
std::cin.clear();
std::cin >> message;
if(!strcmp(message,"exit"))
{
printf("Exit to programm\n");
break;
}
size = write(fd, message, 60);
if (size < strlen(message)) {
printf("Can\'t write all string to FIFO\n");
_exit(-1);
}
}
close(fd);
return 0;
}
By typing, I realized that the problem arises when calling open ().
When I remove the loop the same trouble Even if cout at the beginning of main write nothing works, but when you remove the lines from open () everything works as it should
I realized that the problem arises when calling open ().
Some process must open the FIFO for reading, then your open() continues.
So I was browsing the Internet for a project and stumbled upon this piece of code. It runs perfectly until the point you enter a website(include "www" :P) and press Enter and then boom! The program terminates, no error message, nothing.
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <graphics.h>
#include <dos.h>
#include <string.h>
void initialize_graphics_mode();
int get_key();
void draw();
union REGS i, o;
main()
{
int key, i = 0, xpos, ypos, button;
char arr[200], temp[5], *ptr;
char a[] = "C:\\Progra~1\\Mozill~1\\firefox ";
strcpy(arr,a);
i = strlen(a);
initialize_graphics_mode();
draw();
while(1)
{
if(kbhit())
key = get_key();
if((key>=97&&key<=122)||(key>=65&&key<=90)||key==46||key==47||key==63)
{
arr[i] = key;
sprintf(temp,"%c",arr[i]);
outtext(temp);
if(getx()>470)
{
clearviewport();
moveto(5,2);
}
i++;
}
else if ( key == 13 )
{
arr[i] = '\0';
system(arr);
break;
}
else if ( key == 27 )
{
closegraph();
exit(EXIT_SUCCESS);
}
if(button==1&&xpos>=150&&xpos<=480&&ypos>=300&&ypos<=330)
{
system("C:\\Progra~1\\Mozill~1\\firefox programmingsimplified.com");
break;
}
key = -1;
}
closegraph();
return 0;
}
void initialize_graphics_mode()
{
int gd = DETECT, gm, errorcode;
initgraph(&gd,&gm,"C:\\TURBOC3\\BGI");
errorcode = graphresult();
if( errorcode != grOk )
{
printf("Graphics error : %s\n",grapherrormsg(errorcode));
printf("Press any key to exit...\n");
getch();
exit(EXIT_FAILURE);
}
}
int get_key()
{
i.h.ah = 0;
int86(22,&i,&o);
return( o.h.al );
}
void draw()
{
settextstyle(SANS_SERIF_FONT,HORIZ_DIR,2);
outtextxy(275,11,"Web Browser");
outtextxy(155,451,"<a> href=http://www.programmingsimplified.com"">www.programmingsimplified.com</a>");
outtextxy(5,105,"Enter URL : ");
rectangle(120,100,600,130);
setviewport(121,101,599,129,1);
moveto(5,1);
}
Could someone help me in understanding why this happens? and possibly a fix for this?
NOTE: + It is supposed to work if you have Mozilla Firefox. If you have any other browser, please edit the code accordingly.
I am running this on Turbo C++, what would I have to do in order to convert this code for Dev-C++?
Thanks in advance.
P.S: I'm new to C++ so elaborate as much as possible.
I have code that sends HELLO WORLD:$ from my PC to COM6 to a TIVAC board. I have confirmed through IAR that the board receives the right message. Note that $ is the terminating character.
I have it set up on the TIVAC board to echo the same message through UART and have confirmed manually through Putty that the echo is correct. However when using this following program which sends the same message and listens for the echo I get weird characters in the echo as shown in this image:
It might be an error in the encoding but how do I fix that?
#include <string>
#include <windows.h>
#include <conio.h>
#include <stdio.h>
#include <io.h>
#include <stdlib.h>
#include <iostream>
#include <winbase.h>
#include <tchar.h>
HANDLE GetSerialPort(char *);
void delay();
int main(void)
{
//
COMMTIMEOUTS timeouts;
HANDLE h1;
char h1_buffer[] = {"HELLO WORLD:$"};
char h2_buffer[24];
DWORD byteswritten, bytesread;
char c1[] = {"COM6"};
char c2[] = {"COM6"};
h1 = GetSerialPort(c1);
timeouts.ReadIntervalTimeout = 1;
timeouts.ReadTotalTimeoutMultiplier = 1;
timeouts.ReadTotalTimeoutConstant = 1;
timeouts.WriteTotalTimeoutMultiplier = 1;
timeouts.WriteTotalTimeoutConstant = 1;
WriteFile(h1, h1_buffer, strlen(h1_buffer), &byteswritten, NULL);
do
{
bool exit = FALSE;
ReadFile(h1, h2_buffer, strlen(h2_buffer) + 1, &bytesread, NULL);
if(bytesread)
{
h2_buffer[strlen(h2_buffer)] = '\0';
std::string mystring(h2_buffer);
std::cout << "String is : " << mystring << "\n" ;
printf("GOT IT %d\n", strlen(h2_buffer));
ReadFile(h1, h2_buffer, strlen(h2_buffer) + 1, &bytesread, NULL);
printf("%s\n", h2_buffer);
printf("GOT IT %d\n", strlen(h2_buffer));
}
else
{
char stop;
printf("Nothing read\n");
printf("Do you want to exit? ");
scanf(" %c", stop);
if(stop == 'N' || stop == 'n')
{
exit = TRUE;
}
}
}while(1);
printf("EXIT ");
CloseHandle(h1);
}
HANDLE GetSerialPort(char *p)
{
HANDLE hSerial;
hSerial = CreateFile(p,GENERIC_READ | GENERIC_WRITE, 0,0,OPEN_EXISTING,0, 0);
DCB dcbSerialParams = {0};
dcbSerialParams.DCBlength=sizeof(dcbSerialParams);
dcbSerialParams.BaudRate=CBR_115200;
dcbSerialParams.StopBits=ONESTOPBIT;
dcbSerialParams.Parity=NOPARITY;
dcbSerialParams.fParity = 0;
dcbSerialParams.ByteSize=DATABITS_8;
dcbSerialParams.fDtrControl = 0;
dcbSerialParams.fRtsControl = 0;
return hSerial;
}
void delay ()
{
int i = 1000000000;
printf("In delay\n");
while(i>0)
{
i--;
}
}
Many problems in this code.
Calling strlen() on uninitialised memory will give undefined behaviour.
You don't check for a partial write on the WriteFile() call.
Don't check the return value on ReadFile()
Call strlen() on the data received from ReadFile() instead of using bytesread.
Etc.
You should not be using strlen() on data you get from somewhere else like this -- you should be checking your data and paying attention to the byte counts from your I/O calls.
I tried to write a program which hooks keyboard messages to pronounce the name of each key whenever it is pressed in Ubuntu (KDE); without interfering with normal action of keyboard in programs (just announcing the key name).
This is my program:
#include <X11/Xlib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
using namespace std;
void SendPressKeyEvent(Display *display, XKeyEvent xkey)
{
Window current_focus_window;
int current_focus_revert;
XGetInputFocus(display, ¤t_focus_window, ¤t_focus_revert);
xkey.type = KeyPress;
xkey.display = display;
xkey.window = current_focus_window;
xkey.root = DefaultRootWindow(display);
xkey.subwindow = None;
xkey.time = 1000 * time(0);
xkey.x = 0;
xkey.y = 0;
xkey.x_root = 0;
xkey.y_root = 0;
xkey.same_screen = True;
XSendEvent(display, InputFocus, True, KeyPressMask, (XEvent *)(&xkey));
}
void SendReleaseKeyEvent(Display *display, XKeyEvent xkey)
{
Window current_focus_window;
int current_focus_revert;
XGetInputFocus(display, ¤t_focus_window, ¤t_focus_revert);
xkey.type = KeyRelease;
xkey.display = display;
xkey.window = current_focus_window;
xkey.root = DefaultRootWindow(display);
xkey.subwindow = None;
xkey.time = 1000 * time(0);
xkey.x = 0;
xkey.y = 0;
xkey.x_root = 0;
xkey.y_root = 0;
xkey.same_screen = True;
XSendEvent(display, InputFocus, True, KeyReleaseMask, (XEvent *)(&xkey));
}
void *TaskCode(void* arg)
{
switch(*(int*)arg)
{
case 38:
system("espeak -v en " "\"a\"");
}
return 0;
}
int main()
{
Display *display = XOpenDisplay(0);
if(display == 0)
exit(1);
XGrabKeyboard(display, DefaultRootWindow(display), True, GrabModeAsync, GrabModeAsync, CurrentTime);
XEvent event;
while(true)
{
XNextEvent(display, &event);
if(event.type == Expose)
{
}
if(event.type == KeyPress)
{
SendPressKeyEvent(display,event.xkey);
if(event.xkey.keycode == 38)
{
pthread_t thread;
int thread_arg = event.xkey.keycode;
pthread_create(&thread,0, TaskCode, (void*) &thread_arg);
}
}
if(event.type == KeyRelease)
SendReleaseKeyEvent(display,event.xkey);
}
XCloseDisplay(display);
}
This program is just for the key a which can be extended to other keys.
But when this program is running, some programs (e.g. Chromium) do not show the blinker (cursor) in their edit boxes. Also all KDE hotkeys become disabled.
How can this be fixed?
Here's my quick and dirty example
#include <X11/X.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <stdio.h>
#include <ctype.h>
int main ()
{
Display* d = XOpenDisplay(NULL);
Window root = DefaultRootWindow(d);
Window curFocus;
char buf[17];
KeySym ks;
XComposeStatus comp;
int len;
int revert;
XGetInputFocus (d, &curFocus, &revert);
XSelectInput(d, curFocus, KeyPressMask|KeyReleaseMask|FocusChangeMask);
while (1)
{
XEvent ev;
XNextEvent(d, &ev);
switch (ev.type)
{
case FocusOut:
printf ("Focus changed!\n");
printf ("Old focus is %d\n", (int)curFocus);
if (curFocus != root)
XSelectInput(d, curFocus, 0);
XGetInputFocus (d, &curFocus, &revert);
printf ("New focus is %d\n", (int)curFocus);
if (curFocus == PointerRoot)
curFocus = root;
XSelectInput(d, curFocus, KeyPressMask|KeyReleaseMask|FocusChangeMask);
break;
case KeyPress:
printf ("Got key!\n");
len = XLookupString(&ev.xkey, buf, 16, &ks, &comp);
if (len > 0 && isprint(buf[0]))
{
buf[len]=0;
printf("String is: %s\n", buf);
}
else
{
printf ("Key is: %d\n", (int)ks);
}
}
}
}
It's not reliable but most of the time it works. (It is showing keys I'm typing into this box right now). You may investigate why it does fail sometimes ;) Also it cannot show hotkeys in principle. Hotkeys are grabbed keys, and only one client can get a grabbed key. Absolutely nothing can be done here, short of loading a special X11 extension designed for this purpose (e.g. XEvIE).
Thanks to n.m.'s answer and parsa's comment, this is my final code:
#include <X11/Xlib.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
void* TaskCode(void* parg)
{
int keycode = *((int*)parg);
cout<< "\n\n" << keycode << "\n\n";
if(keycode == XKeysymToKeycode(XOpenDisplay(0),'a'))
system("espeak -v en " "\"a\"");
delete (int*)parg;
return 0;
}
void Action(int keycode)
{
pthread_t thread;
pthread_attr_t attrs;
pthread_attr_init(&attrs);
pthread_attr_setdetachstate(&attrs,PTHREAD_CREATE_DETACHED);
pthread_attr_setstacksize(&attrs, 1000);
int* pthread_arg = new int;
*pthread_arg = keycode;
pthread_create(&thread,&attrs, TaskCode, (void*) pthread_arg);
}
int MyX11ErrorHandler(Display *, XErrorEvent *error_event)
{
cout << "\n\n" "An X11-Functions error occured. Probably the focused window was closed.""\n"
"This error will be ignored." "\n";
cout<< "error_code: " << (unsigned)error_event -> error_code << "\n";
cout<< "minor_code: " << (unsigned)error_event -> minor_code << "\n";
cout<< "request_code: " << (unsigned)error_event -> request_code << "\n";
cout<< "resourceid: " << error_event -> resourceid << "\n";
cout<< "serial; " << error_event -> serial << "\n";
cout<< "type: " << error_event -> type << "\n\n";
return 0;
}
int main()
{
Display* display = XOpenDisplay(0);
Window root = DefaultRootWindow(display);
Window current_focus_window;
int revert;
XSetErrorHandler(MyX11ErrorHandler);
XGetInputFocus(display, ¤t_focus_window, &revert);
XSelectInput(display,current_focus_window,KeyPressMask | KeyReleaseMask | FocusChangeMask);
while(true)
{
XEvent event;
XNextEvent(display, &event);
switch (event.type)
{
case FocusOut:
if(current_focus_window != root)
XSelectInput(display, current_focus_window, 0);
XGetInputFocus(display, ¤t_focus_window, &revert);
if(current_focus_window == PointerRoot)
current_focus_window = root;
XSelectInput(display, current_focus_window, KeyPressMask|KeyReleaseMask|FocusChangeMask);
break;
case KeyPress:
Action(event.xkey.keycode);
break;
}
}
}
Add these to a Qt Creator's project .pro file:
LIBS += -lX11
LIBS += -lpthread
LIBS += -lXtst
Any improvement suggestions is appreciated.
To archive I also add my final code with grabbing:
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
using namespace std;
void* TaskCode(void* parg)
{
int keycode = *((int*)parg);
cout<< "\n\n" << keycode << "\n\n";
system("espeak -v en " "\"a\"");
delete (int*)parg;
return 0;
}
void SendKeyEvent(Display *display, XEvent event)
{
Window current_focus_window;
XKeyEvent& xkey = event.xkey;
int current_focus_revert;
XGetInputFocus(display, ¤t_focus_window, ¤t_focus_revert);
xkey.state = Mod2Mask;
XSendEvent(display, InputFocus, True, xkey.type, (XEvent *)(&event));
}
int GrabKey(Display* display, Window grab_window, int keycode)
{
unsigned int modifiers = Mod2Mask; // numlock on
//Window grab_window = DefaultRootWindow(display);
Bool owner_events = True;
int pointer_mode = GrabModeAsync;
int keyboard_mode = GrabModeAsync;
XGrabKey(display, keycode, modifiers, grab_window, owner_events, pointer_mode, keyboard_mode);
return keycode;
}
void UngrabKey(Display* display, Window grab_window, int keycode)
{
unsigned int modifiers = Mod2Mask; // numlock on
// Window grab_window = DefaultRootWindow(display);
XUngrabKey(display,keycode,modifiers,grab_window);
}
void Action(int keycode)
{
pthread_t thread;
int* pthread_arg = new int;
*pthread_arg = keycode;
pthread_create(&thread,0, TaskCode, (void*) pthread_arg);
}
int main()
{
Display* display = XOpenDisplay(0);
Window root = DefaultRootWindow(display);
XEvent event;
int keycode = XKeysymToKeycode(display,'a');
GrabKey(display,root,keycode);
XSelectInput(display, root, KeyPressMask | KeyReleaseMask);
while(true)
{
XNextEvent(display, &event);
switch(event.type)
{
case KeyPress:
Action(event.xkey.keycode);
case KeyRelease:
SendKeyEvent(display,event);
default:
break;
}
}
XCloseDisplay(display);
}
Everything is good except that, unlike the code in question, it ignores language layout. Pressing a types a whatever regradless of language layout!
As an alternative to listening to X events, it's also possible to listen to Linux input events directly: https://stackoverflow.com/a/27693340/21501
This has the benefit that it's possible to modify the event stream in-flight, and block, edit or generate input events.
The proper way to listen to all events is using the X Record Extension Library, part of libXtst, apparently installed on pretty much every X system. It is documented here, but as the docs are patchy, you will need to browse previous implementations of this. Here is a nice working demo, and here is a more capable and complete implementation.
A simplified version of the first example is included below.
#include <stdio.h>
#include <X11/XKBlib.h>
#include <X11/extensions/record.h>
void key_pressed_cb(XPointer arg, XRecordInterceptData *d);
int scan(int verbose) {
XRecordRange* rr;
XRecordClientSpec rcs;
XRecordContext rc;
Display *dpy = XOpenDisplay(NULL);
rr = XRecordAllocRange();
rr->device_events.first = KeyPress;
rr->device_events.last = ButtonReleaseMask;
rcs = XRecordAllClients;
rc = XRecordCreateContext (dpy, 0, &rcs, 1, &rr, 1);
XFree (rr);
XRecordEnableContext(dpy, rc, key_pressed_cb, NULL);
}
void key_pressed_cb(XPointer arg, XRecordInterceptData *d) {
if (d->category != XRecordFromServer)
return;
int key = ((unsigned char*) d->data)[1];
int type = ((unsigned char*) d->data)[0] & 0x7F;
int repeat = d->data[2] & 1;
if(!repeat) {
switch (type) {
case KeyPress:
printf("key press %d\n", key);
break;
case KeyRelease:
printf("key release %d\n", key);
break;
case ButtonPress:
printf("button press %d\n", key);
break;
case ButtonRelease:
printf("button release %d\n", key);
break;
default:
break;
}
}
XRecordFreeData (d);
}
int main() {
scan(True);
return 0;
}
gcc -o x1 x1.c -lX11 -lXtst
I am using this code to read mouse events from the dev/input/event* in linux .
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <linux/input.h>
#include <fcntl.h>
#define MOUSEFILE "/dev/input/event4"
int main()
{
int fd;
struct input_event ie;
if((fd = open(MOUSEFILE, O_RDONLY)) == -1) {
perror("opening device");
exit(EXIT_FAILURE);
}
while(read(fd, &ie, sizeof(struct input_event))) {
printf("time %ld.%06ld\ttype %d\tcode %d\tvalue %d\n",
ie.time.tv_sec, ie.time.tv_usec, ie.type, ie.code, ie.value);
}
return 0;
}
It gives me the results in the format :
time 1342517261.840285 type 2 code 0 value -1
'time' is the timestamp, it returns the time at which the event happened.
'code' is event code, for example REL_X or KEY_BACKSPACE, complete
list is in include/linux/input.h.
'value' is the value the event carries. Either a relative change for
EV_REL, absolute new value for EV_ABS (joysticks ...), or 0 for EV_KEY for
release, 1 for keypress and 2 for autorepeat.
when i click , i get the event but i don't get the position of the mouse on the screen , what is the way to get the position of the mouse on screen .
Edit 1:So as it turns out that i have to use the relative co-ordinates to get the mouse co-ordinates .I believe this is a common requirement so there might be libraries/pre-existing code that you can use to get the co-ordinates. Any info on this topic will be very useful .
Edit2 : SOLUTION
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <linux/input.h>
#include <fcntl.h>
#include <X11/Xlib.h>
#define MOUSEFILE "/dev/input/event4"
int main()
{
int fd;
struct input_event ie;
Display *dpy;
Window root, child;
int rootX, rootY, winX, winY;
unsigned int mask;
dpy = XOpenDisplay(NULL);
XQueryPointer(dpy,DefaultRootWindow(dpy),&root,&child,
&rootX,&rootY,&winX,&winY,&mask);
if((fd = open(MOUSEFILE, O_RDONLY)) == -1) {
perror("opening device");
exit(EXIT_FAILURE);
}
while(read(fd, &ie, sizeof(struct input_event))) {
if (ie.type == 2) {
if (ie.code == 0) {
XQueryPointer(dpy,DefaultRootWindow(dpy),&root,&child,
&rootX,&rootY,&winX,&winY,&mask);
//rootX += ie.value;
}
else if (ie.code == 1) {
XQueryPointer(dpy,DefaultRootWindow(dpy),&root,&child,
&rootX,&rootY,&winX,&winY,&mask);
// rootY += ie.value;
}
printf("time%ld.%06ld\tx %d\ty %d\n",
ie.time.tv_sec, ie.time.tv_usec, rootX, rootY);
} else
printf("time %ld.%06ld\ttype %d\tcode %d\tvalue %d\n",
ie.time.tv_sec, ie.time.tv_usec, ie.type, ie.code, ie.value);
}
return 0;
}
XQueryPointer seems more convenient solution . Thanks , #perreal for the guidance .
You can get the initial position from X11, and use relative coordinates to track the pointer:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <linux/input.h>
#include <fcntl.h>
#include <X11/Xlib.h>
#define MOUSEFILE "/dev/input/event6"
int main()
{
int fd;
struct input_event ie;
Display *dpy;
Window root, child;
int rootX, rootY, winX, winY;
unsigned int mask;
dpy = XOpenDisplay(NULL);
XQueryPointer(dpy,DefaultRootWindow(dpy),&root,&child,
&rootX,&rootY,&winX,&winY,&mask);
if((fd = open(MOUSEFILE, O_RDONLY)) == -1) {
perror("opening device");
exit(EXIT_FAILURE);
}
while(read(fd, &ie, sizeof(struct input_event))) {
if (ie.type == 2) {
if (ie.code == 0) { rootX += ie.value; }
else if (ie.code == 1) { rootY += ie.value; }
printf("time%ld.%06ld\tx %d\ty %d\n",
ie.time.tv_sec, ie.time.tv_usec, rootX, rootY);
} else if (ie.type == 1) {
if (ie.code == 272 ) {
printf("Mouse button ");
if (ie.value == 0)
printf("released!!\n");
if (ie.value == 1)
printf("pressed!!\n");
} else {
printf("time %ld.%06ld\ttype %d\tcode %d\tvalue %d\n",
ie.time.tv_sec, ie.time.tv_usec, ie.type, ie.code, ie.value);
}
}
return 0;
}
A mouse only sends relative movement, not absolute position. You have to keep track of it yourself, and when you receive a mouse-button event you have to check your own coordinates for the position.