Created
September 20, 2012 14:23
-
-
Save skydark/3756245 to your computer and use it in GitHub Desktop.
以前在智器Q5/V5上配合Openbox时自己胡乱写的一个东西,推荐用xdotool替代。#C #X
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* sendevent | |
* A Simple Wraper to Send XEvent | |
* usage: | |
* sendevent key|mouse [-modifier] name | |
* | |
* Start : 2010/3/6 | |
* Last : 2010/3/24 | |
* | |
* Copyright (c) 2010 Skydark Chen <skydark2 [at] gmail.com> | |
* | |
* Permission is hereby granted, free of charge, to any person | |
* obtaining a copy of this software and associated documentation | |
* files (the "Software"), to deal in the Software without | |
* restriction, including without limitation the rights to use, | |
* copy, modify, merge, publish, distribute, sublicense, and/or sell | |
* copies of the Software, and to permit persons to whom the | |
* Software is furnished to do so, subject to the following | |
* conditions: | |
* | |
* The above copyright notice and this permission notice shall be | |
* included in all copies or substantial portions of the Software. | |
* | |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES | |
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT | |
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | |
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
* OTHER DEALINGS IN THE SOFTWARE. | |
*/ | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <X11/Xlib.h> | |
const char MOD_TABLE[] = { 's', 'l', 'c', 'a', '\0', }; | |
const char MOUSE_TABLE[][7] = { "left", "middle", "right", "up", "down", "", }; | |
/* Give me a string like asc, I will told you it is Alt+Shift+Ctrl, | |
* by give you a num like 8+1+4=0x0d */ | |
int string_to_modifier(const char *str) | |
{ | |
int ret = 0, i; | |
const char *msym; | |
while (*str != '\0') { | |
i = 1; | |
msym = MOD_TABLE; | |
while (*msym != '\0') { | |
if (*msym++ == *str) { | |
ret += i; | |
break; | |
} | |
i *= 2; | |
} | |
str++; | |
} | |
return ret; | |
} | |
void show_eg_and_exit(const int ret) | |
{ | |
printf("sendevent key|mouse [-modifier] name\n"); | |
printf("Eg. : sendevent key -ca f \n"); | |
printf(" It means Send Ctrl+Alt+f\n"); | |
exit(ret); | |
} | |
Display* open_display(void) | |
{ | |
Display *display; | |
if (!getenv("DISPLAY")) | |
display = XOpenDisplay(":0"); | |
else | |
display = XOpenDisplay(NULL); | |
if (!display) { | |
fprintf(stderr, "Can't open display!\n"); | |
exit(1); | |
} | |
return display; | |
} | |
void send_event_key_click(const char * str, const int mod) | |
{ | |
Display *display; | |
KeySym ksym; | |
KeyCode kcode; | |
XEvent event; | |
Window focus; | |
int stat; | |
display = open_display(); | |
if (!(ksym = XStringToKeysym(str))) { | |
fprintf(stderr, "Can not convert keysym's name : %s\n", str); | |
show_eg_and_exit(2); | |
} | |
if (!(kcode = XKeysymToKeycode(display, ksym))) { | |
fprintf(stderr, "Can not convert keysym %s to keycode!\n", str); | |
show_eg_and_exit(2); | |
} | |
XGetInputFocus(display, &focus, &stat); | |
event.xkey.type = KeyPress; | |
event.xkey.send_event = True; | |
event.xkey.display = display; | |
event.xkey.window = focus; | |
event.xkey.root = DefaultRootWindow(display); | |
event.xkey.subwindow = None; | |
event.xkey.time = CurrentTime; | |
event.xkey.x = 0; | |
event.xkey.y = 0; | |
event.xkey.x_root = 0; | |
event.xkey.y_root = 0; | |
event.xkey.state = mod; | |
event.xkey.keycode = kcode; | |
event.xkey.same_screen = True ; | |
XSendEvent(display, | |
focus, | |
False, | |
KeyPressMask | KeyReleaseMask, | |
&event); | |
event.xkey.type = KeyRelease; | |
XSendEvent(display, | |
focus, | |
False, | |
KeyPressMask | KeyReleaseMask, | |
&event); | |
XFlush(display); | |
XSync(display, False); | |
} | |
void send_event_mouse_click(const char * str, const int mod) | |
{ | |
Display *display; | |
unsigned int btn = 0; | |
XEvent event; | |
Window root, child, dwin, tmp; | |
int rx,ry,dx,dy; | |
unsigned int mask; | |
display = open_display(); | |
/* The method of this part is similar to 'string_to_modifier', | |
* but I don't want to fix it right now, what a lazy boy! = = */ | |
while ( (MOUSE_TABLE[btn][0] != '\0') && | |
strcmp(&MOUSE_TABLE[btn][0], str) ) | |
btn++; | |
if (MOUSE_TABLE[btn][0] == '\0') { | |
fprintf(stderr, "Unknown mouse button's name : %s\n", str); | |
show_eg_and_exit(2); | |
} | |
btn++; | |
XQueryPointer(display, DefaultRootWindow(display), | |
&root, &child, &rx, &ry, &dx, &dy, &mask); | |
// Where is our mouse? I am as pool as possible...=.=|| | |
do { | |
XTranslateCoordinates(display, root, child, | |
rx, ry, &dx, &dy, &dwin); | |
} while (tmp = dwin, dwin = child, child = tmp); | |
event.xbutton.type = ButtonPress; | |
event.xbutton.send_event = True; | |
event.xbutton.display = display; | |
event.xbutton.window = dwin; | |
event.xbutton.root = root; | |
event.xbutton.subwindow = None; | |
event.xbutton.time = CurrentTime; | |
event.xbutton.x = dx; | |
event.xbutton.y = dy; | |
event.xbutton.x_root = rx; | |
event.xbutton.y_root = ry; | |
event.xbutton.state = mod; | |
event.xbutton.button = btn; | |
event.xbutton.same_screen = True ; | |
XSendEvent(display, | |
dwin, | |
False, | |
ButtonPressMask | ButtonReleaseMask, | |
&event); | |
event.xbutton.type = ButtonRelease; | |
XSendEvent(display, | |
dwin, | |
False, | |
ButtonPressMask | ButtonReleaseMask, | |
&event); | |
XFlush(display); | |
XSync(display, False); | |
} | |
int main(int argc, char **argv) | |
{ | |
int mod = 0; | |
char * detail = NULL; | |
if (argc < 3) show_eg_and_exit(0); | |
if (*argv[2]=='-') { | |
if (argc < 4) show_eg_and_exit(2); | |
mod = string_to_modifier(argv[2]+1); | |
detail = argv[3]; | |
} else detail = argv[2]; | |
if (!strcmp(argv[1],"key")) | |
send_event_key_click(detail, mod); | |
else if (!strcmp(argv[1],"mouse")) | |
send_event_mouse_click(detail, mod); | |
else show_eg_and_exit(2); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment