sven

Artifact [26df470be5]
Login

Artifact [26df470be5]

Artifact 26df470be500e5f25ad8b6e536d62834d23aa942:


/* Sven multimedia keyboard deamon
 * xlib.c
 *
 * Copyright (C) 2005 Eugene Morenko(More)
 * mailto: more@irpin.com
 * web: http://sven.linux.kiev.ua/
 * icq:325697438
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
 
 #include <X11/X.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/XKBlib.h>
#include <X11/Xlibint.h>
#include <X11/Xatom.h>
#include <X11/keysym.h>
#include <gdk/gdkx.h>
#include <gtk/gtk.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <errno.h>
#include <signal.h>
#include <unistd.h>

#include "sven.h"
#include "xlib.h"
#include "utils.h"
#include "grabkeyboard.h"

/**************************************************************************************/
static gchar *get_property (Display *disp, Window win, /*{{{*/
        Atom xa_prop_type, gchar *prop_name, unsigned long *size) 
{
    Atom xa_prop_name;
    Atom xa_ret_type;
    int ret_format;
    unsigned long ret_nitems;
    unsigned long ret_bytes_after;
    unsigned long tmp_size;
    unsigned char *ret_prop;
    gchar *ret;
    
    xa_prop_name = XInternAtom(disp, prop_name, False);
    
    /* MAX_PROPERTY_VALUE_LEN / 4 explanation (XGetWindowProperty manpage):
     *
     * long_length = Specifies the length in 32-bit multiples of the
     *               data to be retrieved.
     */
    if (XGetWindowProperty(disp, win, xa_prop_name, 0, MAX_PROPERTY_VALUE_LEN / 4, False,
            xa_prop_type, &xa_ret_type, &ret_format,     
            &ret_nitems, &ret_bytes_after, &ret_prop) != Success) {
        printf("Cannot get %s property.\n", prop_name);
        return NULL;
    }
  
    if (xa_ret_type != xa_prop_type) {
        printf("Invalid type of %s property.\n", prop_name);
        XFree(ret_prop);
        return NULL;
    }

    /* null terminate the result to make string handling easier */
    tmp_size = (ret_format / 8) * ret_nitems;
    ret = g_malloc(tmp_size + 1);
    memcpy(ret, ret_prop, tmp_size);
    ret[tmp_size] = '\0';

    if (size) {
        *size = tmp_size;
    }
    
    XFree(ret_prop);
    return ret;
}/*}}}*/


/* Find child work sven, and kill if found*/
static void selection_get_func (GtkClipboard *clipboard, GtkSelectionData *selection_data,
		guint info, gpointer user_data_or_owner)
{
}

static void selection_clear_func (GtkClipboard *clipboard, gpointer user_data_or_owner)
{
	return;
}

gboolean sven_get_lock (gpointer data)
{
	Sven *sven = (Sven *)data;
	gboolean result = FALSE;
	GtkClipboard *clipboard;
	Atom clipboard_atom = gdk_x11_get_xatom_by_name (SELECTION_NAME);
	static const GtkTargetEntry targets[] = 
	{
		{ SELECTION_NAME, 0, 0 }
	};

	XGrabServer (GDK_DISPLAY());

	if (XGetSelectionOwner (GDK_DISPLAY(), clipboard_atom) != None)
		goto out;

	clipboard = gtk_clipboard_get (gdk_atom_intern (SELECTION_NAME, FALSE));

	if (!gtk_clipboard_set_with_data  (clipboard, targets,
				G_N_ELEMENTS (targets),
				selection_get_func,
				selection_clear_func, NULL))
	{
		g_free(clipboard);
		goto out;
	}

	result = TRUE;

out:
	XUngrabServer (GDK_DISPLAY());
	gdk_flush();
	
	return result;
}

int sven_kill_lock (gpointer data)
{
	Sven *sven = (Sven *)data;
	unsigned long *pid;
	Window wind;
	Atom clipboard_atom = gdk_x11_get_xatom_by_name (SELECTION_NAME);

	XGrabServer (GDK_DISPLAY());

	wind=XGetSelectionOwner (GDK_DISPLAY(), clipboard_atom);
	
	if (wind != None)
	{
		/* pid */
        	pid =  (unsigned long *)get_property(GDK_DISPLAY(),wind,XA_CARDINAL, "_NET_WM_PID", NULL);
	}

	if(pid>0)
	{
		gchar *output = NULL;
		gchar *temp = NULL;
	
		temp=g_strdup_printf("kill %-6lu", pid ? *pid : 0);
		g_spawn_command_line_sync(temp,NULL,&output,NULL,NULL);
		if(g_strcasecmp(output,"")!=0)
			printf("Not Kill Sven children\n");
		else
			 printf("Kill Sven Pid: %-6lu \n", pid ? *pid : 0);
		g_free(temp);temp=NULL;
		g_free(output);output=NULL;
	}
	 
	XUngrabServer (GDK_DISPLAY());
	gdk_flush();
	
	XFree(pid);
	
	sven_get_lock(sven);
	return 1;
}
/*************************************************************************/
/* modifer */

static char * modifier_string [] = {"Control", "Shift", "Alt","Win"};
static char * modifier_string_mouse [] = {"Mouse Left", "Mouse Center","Mouse Right","Scrool Up","Scrool Down","Scrool Left","Scrool Right"};

int DellModifier (unsigned int modifier)
{
	int mod = 0;

	if (modifier & ControlMask )
		mod += ControlMask;
  
	if (modifier & ShiftMask)
		mod += ShiftMask;

	if (modifier & Mod1Mask)
		mod += Mod1Mask;

	if (modifier & Mod4Mask)
		mod += Mod4Mask;
	
	return mod;
}
int AddCapsModifier (unsigned int modifier)
{
	int mod = DellModifier(modifier);

	mod += LockMask;
	return mod;
}
int AddNumModifier (unsigned int modifier)
{
	int mod = DellModifier(modifier);

	mod += Mod2Mask;
	return mod;
}
int AddCapsNumModifier (unsigned int modifier)
{
	int mod = DellModifier(modifier);

	mod += LockMask;
	mod += Mod2Mask;
	return mod;
}

int ModifierToString (unsigned int modifier, char * str)
{
	str[0] = '\0';
	int n=0;
	if (modifier & ControlMask )
	{
		if (str[0])
		strcat (str, "+");
		strcat (str, modifier_string[0]);
		n++;
	}
  
	if (modifier & ShiftMask)
	{
		if (str[0])
		strcat (str, "+");
		strcat (str, modifier_string[1]);
		n++;
	}

	if (modifier & Mod1Mask)
	{
		if (str[0])
		strcat (str, "+");
		strcat (str, modifier_string[2]);
		n++;
	}
	if (modifier & Mod4Mask)
	{
		if (str[0])
		strcat (str, "+");
		strcat (str, modifier_string[3]);
		n++;
	}
     return n;
}
int StringToModifier_Key (char * str,unsigned int * modifier)
{
	int key=0;
	gchar *temp;
 
	temp=strtok(str,"+");
	*modifier=0;
	
	while(temp!=NULL)
	{
		if (strcasecmp (temp, "control") == 0)
		  *modifier += ControlMask;
		else if (strcasecmp (temp, "shift") == 0)
		  *modifier += ShiftMask;
		else if (strcasecmp (temp, "mod1") == 0 || strcasecmp (temp, "alt") == 0)
		  *modifier += Mod1Mask;
		else if (strcasecmp (temp, "mod4") == 0 || strcasecmp (temp, "win") == 0)
		  *modifier += Mod4Mask;
		else
		{
			if(atoi(temp)!=0)
				 key=atoi(temp);
			else
			{
				key =XKeysymToKeycode(GDK_DISPLAY(),XStringToKeysym (temp));
				if (key == 0)
					break;
				temp=strtok(NULL,"+");
				    continue;
			}
		}
		temp=strtok(NULL,"+");
	}
	g_free(temp);
	temp=NULL;
	
	return key;
}

char* GetNameMouseButton (unsigned int button)
{
	if(button>=6 || button==-1 || button==0)
		return g_strdup_printf("%d",button);
	else
	return modifier_string_mouse[button-1];
}

int ModifierToStringMouse (unsigned int modifier, char * str)
{
	str[0] = '\0';
	int n=0;


	if (modifier & ControlMask )
	{
		if (str[0])
		strcat (str, "+");
		strcat (str, modifier_string[0]);
		n++;
	}
  
	if (modifier & ShiftMask)
	{
		if (str[0])
		strcat (str, "+");
		strcat (str, modifier_string[1]);
		n++;
	}

	if (modifier & Mod1Mask)
	{
		if (str[0])
		strcat (str, "+");
		strcat (str, modifier_string[2]);
		n++;
	}
	if (modifier & Mod4Mask)
	{
		if (str[0])
		strcat (str, "+");
		strcat (str, modifier_string[3]);
		n++;
	}
	if (modifier & Button1Mask)
	{
		if (str[0])
		strcat (str, "+");
		strcat (str, modifier_string_mouse[0]);
		n++;
	}
	if (modifier & Button2Mask)
	{
		if (str[0])
		strcat (str, "+");
		strcat (str, modifier_string_mouse[1]);
		n++;
	}
	if (modifier & Button3Mask)
	{
		if (str[0])
		strcat (str, "+");
		strcat (str, modifier_string_mouse[2]);
		n++;
	}
	if (modifier & Button4Mask)
	{
		if (str[0])
		strcat (str, "+");
		strcat (str, modifier_string_mouse[3]);
		n++;
	}
	if (modifier & Button5Mask)
	{
		if (str[0])
		strcat (str, "+");
		strcat (str, modifier_string_mouse[4]);
		n++;
	}
	if (modifier & AnyModifier)
	{
		if (str[0])
		strcat (str, "+");
		strcat (str, modifier_string_mouse[7]);
		n++;
	}
     return n;
}

int StringToModifier_Mouse (char * str,unsigned int * modifier)
{
	int key=0;
	gchar *temp;
 
	temp=strtok(str,"+");
	*modifier=0;
	
	while(temp!=NULL)
	{
		if (strcasecmp (temp, "control") == 0)
		  *modifier += ControlMask;
		else if (strcasecmp (temp, "shift") == 0)
		  *modifier += ShiftMask;
		else if (strcasecmp (temp, "mod1") == 0 || strcasecmp (temp, "alt") == 0)
		  *modifier += Mod1Mask;
		else if (strcasecmp (temp, "mod4") == 0 || strcasecmp (temp, "win") == 0)
		  *modifier += Mod4Mask;
		else if (strcasecmp (temp, "mouse left") == 0)
		{
		  *modifier += Button1Mask;
		  key=1;
		}
		else if (strcasecmp (temp, "mouse center") == 0)
		{
		  *modifier += Button2Mask;
		  key=2;
		}
		else if (strcasecmp (temp, "mouse right") == 0)
		{
		  *modifier += Button3Mask;
		  key=3;
		}
		else if (strcasecmp (temp, "scrool up") == 0)
		{
		  *modifier += Button4Mask;
		  key=4;
		}
		else if (strcasecmp (temp, "scrool down") == 0)
		{
		  *modifier += Button5Mask;
		  key=5;
		}
		else if (strcasecmp (temp, "scrool left") == 0)
		{
		  key=6;
		}
		else if (strcasecmp (temp, "scrool right") == 0)
		{
		  key=7;
		}
		else
		 {
		    key=atoi(temp);
		 }

		temp=strtok(NULL,"+");
	}
	g_free(temp);
	
	return key;
}