Skip to content

Instantly share code, notes, and snippets.

@skydark
Created September 20, 2012 14:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save skydark/3756245 to your computer and use it in GitHub Desktop.
Save skydark/3756245 to your computer and use it in GitHub Desktop.
以前在智器Q5/V5上配合Openbox时自己胡乱写的一个东西,推荐用xdotool替代。#C #X
/*
* 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