0.5-r1
This is very simple program which is passing defined key code to Ventrilo program running on Wine. This way the user is able to use push to talk button with Ventrilo on Linux. Without it Ventrilo running on wine is aware on keys your are pressing only if the Ventrilo window has focus in system, when it lost focus you loose the abilty to use PTT.
The provided here ebuild installs this helper program along side with the patch I created. I wrote the patch addressing an issue I had. Many ventrilo servers are putting people in AFK status, removing them from current channel if Ventrilo is unable recognize any keys that are being pressed in system. This simple application is passing only one key, and only if you want to talk. If you do not talk at all it's possible (that was my issue) you will be kicked off from channel you ware in to AFK channel. My patch is doing simple thing insted of passing just one event (Capital A keycode) to Ventrilo window when you are using PTT button patched program will send a second key event (Capital B key code) for every event generated by choosen device. That should prevent putting you at AFK channel as long as you are using your device (mouse or keyboard).
--- a/ventriloctrl-0.5/ventriloctrl.c 2008-08-23 10:23:03.000000000 +0200 +++ b/ventriloctrl-0.5/ventriloctrl.c 2009-06-20 01:40:40.000000000 +0200 @@ -16,6 +16,7 @@ /* Configuration */ #define SIMULATEKEY XK_A // Simulate Key Press #define VENTRILO "Ventrilo" // Ventrilo Window Name +#define OTHERKEY XK_B //Key send to Ventrillo if other key is being pressed /* Global Variables */ Display *display; @@ -54,14 +55,14 @@ { // Variables int i; - + // Get the "Window" Tree Window root; Window parent; Window *children = 0; unsigned int childrenCount = 0; XQueryTree(display, parentWindow, &root, &parent, &children, &childrenCount); - + // Crawl the "Window" Tree char *window_name = 0; Window *window = 0; @@ -74,7 +75,7 @@ } XFree(window_name); } - + // Crawl the Child and Look For "windowName" window = find_window(display, children[i], windowName); if (window != 0) { @@ -82,10 +83,10 @@ return window; } } - + // Free the Children! lol if (children != 0) XFree(children); - + // Return return 0; } @@ -94,42 +95,43 @@ { // Usage printf("\n"); - + // Initialize "Display" display = XOpenDisplay(0); if (display == NULL) { printf("Error: Could not open display!\n"); return 1; } - + // Initialize Root "Window" window = XDefaultRootWindow(display); if (!window) { printf("Error: Could not grab root window!\n"); return 2; } - + // Initialize Ventrilo "Window" windowVentrilo = find_window(display, window, VENTRILO); if (!windowVentrilo) { printf("Error: Could not find Ventrilo window!\n"); return 3; } - + // Convert Key String to Number unsigned int key = atoi(argv[2]); unsigned int simulatekey = XKeysymToKeycode(display, SIMULATEKEY); - + unsigned int otherkey = XKeysymToKeycode(display, OTHERKEY); + // Open the Input int device = open(argv[1], O_RDONLY); - + // Loop struct input_event ev; XKeyEvent event; while (ventrilo_still_running()) { // Read from the Input read(device, &ev, sizeof(struct input_event)); - + // Check Input if (ev.type == 1 && ev.code == key) { // Simulate Key Press/Release @@ -141,8 +143,18 @@ } XFlush(display); } + else if (ev.type == 1 && ev.code != key) { + // Send other key (this should prevent putting the user on afk status) + event = create_key_event(display, *windowVentrilo, window, ev.value, otherkey, 0); + if (ev.value == 1) { + XSendEvent(event.display, event.window, True, KeyPressMask, (XEvent *) &event); + } else { + XSendEvent(event.display, event.window, True, KeyReleaseMask, (XEvent *) &event); + } + XFlush(display); + } } - + // Return return 0; } @@ -156,20 +168,20 @@ printf("then execute the command listed.\n"); printf("Press Ctrl+C when finished.\n"); printf("\n"); - + // Open the Input int device = open(argv[1], O_RDONLY); - + // Loop struct input_event ev; while (1) { // Read from the Input read(device, &ev, sizeof(struct input_event)); - + // Print the Command if (ev.type == 1 && ev.value == 1) printf("%s %s %i\n", argv[0], argv[1], ev.code); } - + // Return return 0; } @@ -180,7 +192,7 @@ // Programs if(argc == 2) return findkey(argc, argv); // Find Key if(argc == 3) return ventriloctl(argc, argv); // Ventrilo Ctrl - + // Usage printf("\n"); printf("Usage: %s <device> [key]\n", argv[0]); @@ -188,7 +200,7 @@ printf("Running this program without 'key' specified\n"); printf("will run the 'FindKey' sub-program.\n"); printf("\n"); - + // Return return 0; }
You can access the patch file on my svn server by following this link.
To jest bardzo prosty program, który przekazuje zdefiniowane kody klawiszy do okna programu Ventrilo działającego pod Wine. Dzięki temu użytkownik może używać przycisku PTT (wciśnij aby mówić) z programem Ventrilo na Linuxie. Bez tego programu Ventrilo działające pod wine ma świadomość tego, że wciskasz klawisze tylko jeśli okno programu Ventrilo ma fokus w systemie, kiedy traci fokus ty tracisz możliwość używanie funkcji PTT.
Dostępny tutaj ebuild instaluje ten program pomocniczy wraz z patczem, który stworzyłem. Napisałem patcz, który rozwiązuje problem jaki napotkałem. Wiele serwerów ventrilo przełącza użytkowników do statusu AFK, usuwając ich z kanału, w którym byli. Jeśli Ventrilo nie może rozpoznać generowanych w systemie zdarzeń dla urządzeń wejściowych. Ta prosta aplikacja przekazuje tylko jeden kod klawisza i robi to tylko jeśli chcesz mówić. Jeśli nie mówisz wcale, jest możliwe (i to był mój problem), że zostaniesz wyrzucony z kanału, w którym aktualnie jesteś i przełączony do kanału AFK (z dala od klawiatury). Mój patch zmienia jedną rzecz, zamiast przekazywać tylko jedno zdarzenie (kod klawisza duże A) do okna ventrilo, kiedy użytkownik wciska wybrany klawisz PTT, spatczowany program wyśle drugie zdarzenie (kod klawisza duże B) dla każdego zdarzenia wygenerowanego przez wybrane urządzenie. To powinno wykluczyć przełączanie cię do kanału AFK tak długo jak długo używasz urządzenia wejściowego (myszy lub klawiatury).
--- a/ventriloctrl-0.5/ventriloctrl.c 2008-08-23 10:23:03.000000000 +0200 +++ b/ventriloctrl-0.5/ventriloctrl.c 2009-06-20 01:40:40.000000000 +0200 @@ -16,6 +16,7 @@ /* Configuration */ #define SIMULATEKEY XK_A // Simulate Key Press #define VENTRILO "Ventrilo" // Ventrilo Window Name +#define OTHERKEY XK_B //Key send to Ventrillo if other key is being pressed /* Global Variables */ Display *display; @@ -54,14 +55,14 @@ { // Variables int i; - + // Get the "Window" Tree Window root; Window parent; Window *children = 0; unsigned int childrenCount = 0; XQueryTree(display, parentWindow, &root, &parent, &children, &childrenCount); - + // Crawl the "Window" Tree char *window_name = 0; Window *window = 0; @@ -74,7 +75,7 @@ } XFree(window_name); } - + // Crawl the Child and Look For "windowName" window = find_window(display, children[i], windowName); if (window != 0) { @@ -82,10 +83,10 @@ return window; } } - + // Free the Children! lol if (children != 0) XFree(children); - + // Return return 0; } @@ -94,42 +95,43 @@ { // Usage printf("\n"); - + // Initialize "Display" display = XOpenDisplay(0); if (display == NULL) { printf("Error: Could not open display!\n"); return 1; } - + // Initialize Root "Window" window = XDefaultRootWindow(display); if (!window) { printf("Error: Could not grab root window!\n"); return 2; } - + // Initialize Ventrilo "Window" windowVentrilo = find_window(display, window, VENTRILO); if (!windowVentrilo) { printf("Error: Could not find Ventrilo window!\n"); return 3; } - + // Convert Key String to Number unsigned int key = atoi(argv[2]); unsigned int simulatekey = XKeysymToKeycode(display, SIMULATEKEY); - + unsigned int otherkey = XKeysymToKeycode(display, OTHERKEY); + // Open the Input int device = open(argv[1], O_RDONLY); - + // Loop struct input_event ev; XKeyEvent event; while (ventrilo_still_running()) { // Read from the Input read(device, &ev, sizeof(struct input_event)); - + // Check Input if (ev.type == 1 && ev.code == key) { // Simulate Key Press/Release @@ -141,8 +143,18 @@ } XFlush(display); } + else if (ev.type == 1 && ev.code != key) { + // Send other key (this should prevent putting the user on afk status) + event = create_key_event(display, *windowVentrilo, window, ev.value, otherkey, 0); + if (ev.value == 1) { + XSendEvent(event.display, event.window, True, KeyPressMask, (XEvent *) &event); + } else { + XSendEvent(event.display, event.window, True, KeyReleaseMask, (XEvent *) &event); + } + XFlush(display); + } } - + // Return return 0; } @@ -156,20 +168,20 @@ printf("then execute the command listed.\n"); printf("Press Ctrl+C when finished.\n"); printf("\n"); - + // Open the Input int device = open(argv[1], O_RDONLY); - + // Loop struct input_event ev; while (1) { // Read from the Input read(device, &ev, sizeof(struct input_event)); - + // Print the Command if (ev.type == 1 && ev.value == 1) printf("%s %s %i\n", argv[0], argv[1], ev.code); } - + // Return return 0; } @@ -180,7 +192,7 @@ // Programs if(argc == 2) return findkey(argc, argv); // Find Key if(argc == 3) return ventriloctl(argc, argv); // Ventrilo Ctrl - + // Usage printf("\n"); printf("Usage: %s <device> [key]\n", argv[0]); @@ -188,7 +200,7 @@ printf("Running this program without 'key' specified\n"); printf("will run the 'FindKey' sub-program.\n"); printf("\n"); - + // Return return 0; }
Możesz uzyskać dostęp do pliku z patchem na moim serwerze svn podążając za tym linkiem.
# Copyright 1999-2010 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 # $Header: $ KardasA EAPI="2" inherit eutils DESCRIPTION="Ventrilo on Wine PTT button controller" HOMEPAGE="" SRC_URI="http://www.calebgray.com/uploads/ventriloctrl/${P}.zip" SLOT="0" LICENSE="as-is" RESTRICT="mirror" KEYWORDS="~amd64 ~x86" IUSE="" DEPEND="" RDEPEND="${DEPEND}" src_prepare() { epatch "${FILESDIR}"/prevent_afk.patch } src_install() { exeinto /usr/bin doexe "${PN}" dodoc README LICENCE }