<commit_before>/*      $Id: irxevent.c,v 5.9 2002/06/24 18:35:20 lirc Exp $      */

/****************************************************************************
 ** irxevent.c **************************************************************
 ****************************************************************************
 *
 * irxevent  - infra-red xevent sender
 *
 * <NAME>  <<EMAIL>>
 * small modifications by <NAME> <<EMAIL>>
 *
 * irxevent is based on irexec (Copyright (C) 1998 <NAME>)
 * and irx.c (no copyright notice found)
 *
 *  =======
 *  HISTORY
 *  =======
 *
 * 0.1 
 *     -Initial Release
 *
 * 0.2 
 *     -no more XWarpPointer... sending Buttonclicks to off-screen
 *      applications works becaus i also fake the EnterNotify and LeaveNotify
 *     -support for keysymbols rather than characters... so you can use
 *      Up or Insert or Control_L ... maybe you could play xquake than :*)
 *
 * 0.3
 *     -bugfix for looking for subwindows of non existing windows 
 *     -finaly a README file
 *
 * 0.3a (done by <NAME>)
 *     -read from a shared .lircrc file 
 *     -changes to comments
 *     (chris, was that all you changed?)
 *
 * 0.4
 *     -fake_timestamp() to solve gqmpeg problems 
 *     -Shift Control and other mod-keys may work. (can't check it right now)
 *      try ctrl-c or shift-Page_up or whatever ...
 *      modifiers: shift, caps, ctrl, alt, meta, numlock, mod3, mod4, scrlock
 *     -size of 'char *keyname' changed from 64 to 128 to allow all mod-keys. 
 *     -updated irxevent.README
 *
 * 0.4.1
 *     -started to make smaller version steps :-)
 *     -Use "CurrentWindow" as window name to send events to the window
 *      that -you guessed it- currently has the focus.
 *
 * 0.4.2
 *     -fixed a stupid string bug in key sending.
 *     -updated irxevent.README to be up to date with the .lircrc format.
 *
 * 0.4.3
 *     -changed DEBUG functions to actually produce some output :)
 *
 * 0.5.0
 *     -fixed finding subwindows recursively
 *     -added xy_Key (though xterm and xemacs still don't like me)
 *     -added compilation patch from <NAME> 
 *      <<EMAIL>> for compiling on systems 
 * 	without strsep() (like some solaris)
 *
 *
 * see http://www.wh9.tu-dresden.de/~heinrich/lirc/irxevent/irxevent.keys
 * for a the key names. (this one is for you Pablo :-) )
 *
 * for more information see the irxevent.README file
 *
 */

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

#include <errno.h>
#include <unistd.h>
#include <getopt.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/stat.h>
#include <sys/types.h>

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <sys/time.h>
#include <unistd.h>

#include "lirc_client.h"

/* #define DEBUG */
#ifdef DEBUG
void debugprintf(char *format_str, ...)
{
        va_list ap;
        va_start(ap,format_str);
        vfprintf(stderr,format_str,ap);
        va_end(ap);
}
#else
void debugprintf(char *format_str, ...)
{
}
#endif


struct keymodlist_t {
        char *name;
        Mask mask;
};
static struct keymodlist_t keymodlist[]=
{
  {"SHIFT",   ShiftMask},
  {"CAPS",    LockMask},
  {"CTRL",    ControlMask},
  {"ALT",     Mod1Mask},{"META",    Mod1Mask},
  {"NUMLOCK", Mod2Mask},
  {"MOD3",    Mod3Mask},  /* I don't have a clue what key maps to this. */
  {"MOD4",    Mod4Mask},  /* I don't have a clue what key maps to this. */
  {"SCRLOCK", Mod5Mask},
  {NULL,0},
};

const char *key_delimiter ="-";
const char *active_window_name ="CurrentWindow";
const char *root_window_name ="RootWindow";


char *progname;
Display *dpy;
Window root;
XEvent xev;
Window w,subw;

Time fake_timestamp()
     /*seems that xfree86 computes the timestamps like this     */
     /*strange but it relies on the *1000-32bit-wrap-around     */
     /*if anybody knows exactly how to do it, please contact me */
{
  int  tint;
  struct timeval  tv;
  struct timezone tz; /* is not used since ages */
  gettimeofday(&tv,&tz);
  tint=(int)tv.tv_sec*1000;
  tint=tint/1000*1000;
  tint=tint+tv.tv_usec/1000;
  return (Time)tint;
}

Window find_window(Window top,char *name)
{
  char *wname,*iname;
  XClassHint xch;
  Window *children,foo;
  int revert_to_return;
  unsigned int nc;
  if (!strcmp(active_window_name,name)){
    XGetInputFocus(dpy, &foo, &revert_to_return);
    return(foo);
  }  else if (!strcmp(root_window_name,name)){
    return(root);
  }
  /* First the base case */
  if (XFetchName(dpy,top,&wname)){
    if (!strncmp(wname,name,strlen(name)))  {
      XFree(wname);
      debugprintf("found it by wname %x \n",top);
      return(top);  /* found it! */
    };
    XFree(wname);
  };

  if(XGetIconName(dpy,top,&iname)){
    if (!strncmp(iname,name,strlen(name)))  {
      XFree(iname);
      debugprintf("found it by iname %x \n",top);
      return(top);  /* found it! */
    };
    XFree(iname);
  };

  if(XGetClassHint(dpy,top,&xch))  {
    if(!strcmp(xch.res_class,name))  {
      XFree(xch.res_name); XFree(xch.res_class);
      debugprintf("res_class '%s' res_name '%s' %x \n", xch.res_class,xch.res_name,top);
      return(top);  /* found it! */
    };
    if(!strcmp(xch.res_name,name))  {
      XFree(xch.res_name); XFree(xch.res_class);
      debugprintf("res_class '%s' res_name '%s' %x \n", xch.res_class,xch.res_name,top);
      return(top);  /* found it! */
    };
    XFree(xch.res_name); XFree(xch.res_class);
  };

  if(!XQueryTree(dpy,top,&foo,&foo,&children,&nc) || children==NULL) {
    return(0);  /* no more windows here */
  };

  /* check all the sub windows */
  for(;nc>0;nc--)  {
    top = find_window(children[nc-1],name);
    if(top) break;  /* we found it somewhere */
  };
  if(children!=NULL) XFree(children);
  return(top);
}

Window find_sub_sub_window(Window top,int *x, int *y)
{
  Window base;
  Window *children,foo,target=0;
  unsigned int nc,
    rel_x,rel_y,width,height,border,depth,
    new_x=1,new_y=1,
    targetsize=1000000;

  base=top;
  if (!base) {return base;};
  if(!XQueryTree(dpy,base,&foo,&foo,&children,&nc) || children==NULL) {
    return(base);  /* no more windows here */
  };
  debugprintf("found subwindows %d\n",nc);

  /* check if we hit a sub window and find the smallest one */
  for(;nc>0;nc--)  {
    if(XGetGeometry(dpy, children[nc-1], &foo, &rel_x, &rel_y, 
		    &width, &height, &border, &depth)){
      if ((rel_x<=*x)&&(*x<=rel_x+width)&&(rel_y<=*y)&&(*y<=rel_y+height)){
	debugprintf("found a subwindow %x +%d +%d  %d x %d   \n",children[nc-1], rel_x,rel_y,width,height);
	if ((width*height)<targetsize){
	  target=children[nc-1];
	  targetsize=width*height;
	  new_x=*x-rel_x;
	  new_y=*y-rel_y;
	  /*bull's eye ...*/
	  target=find_sub_sub_window(target,&new_x,&new_y);
	}
      }	
    }
  };
  if(children!=NULL) XFree(children);
  if (target){
    *x=new_x;
    *y=new_y;
    return target;
  }else
    return base;
}



Window find_sub_window(Window top,char *name,int *x, int *y)
{
  Window base;
  Window *children,foo,target=0;
  unsigned int nc,
    rel_x,rel_y,width,height,border,depth,
    new_x=1,new_y=1,
    targetsize=1000000;

  base=find_window(top, name);
  if (!base) {return base;};
  if(!XQueryTree(dpy,base,&foo,&foo,&children,&nc) || children==NULL) {
    return(base);  /* no more windows here */
  };
  debugprintf("found subwindows %d\n",nc);

  /* check if we hit a sub window and find the smallest one */
  for(;nc>0;nc--)  {
    if(XGetGeometry(dpy, children[nc-1], &foo, &rel_x, &rel_y, 
		    &width, &height, &border, &depth)){
      if ((rel_x<=*x)&&(*x<=rel_x+width)&&(rel_y<=*y)&&(*y<=rel_y+height)){
	debugprintf("found a subwindow %x +%d +%d  %d x %d   \n",children[nc-1], rel_x,rel_y,width,height);
	if ((width*height)<targetsize){
	  target=children[nc-1];
	  targetsize=width*height;
	  new_x=*x-rel_x;
	  new_y=*y-rel_y;
	  /*bull's eye ...*/
	  target=find_sub_sub_window(target,&new_x,&new_y);
	}
      }	
    }
  };
  if(children!=NULL) XFree(children);
  if (target){
    *x=new_x;
    *y=new_y;
    return target;
  }else
    return base;
}


void make_button(int button,int x,int y,XButtonEvent *xev)
{
  xev->type = ButtonPress;
  xev->display=dpy;
  xev->root=root;
  xev->subwindow=None;
  xev->time=fake_timestamp();
  xev->x=x;xev->y=y;
  xev->x_root=1; xev->y_root=1;
  xev->state=0;
  xev->button=button;
  xev->same_screen=True;

  return;
}

void make_key(char *keyname,int x, int y,XKeyEvent *xev)
{
  char *part, *part2;
  struct keymodlist_t *kmlptr;
#ifndef HAVE_STRSEP
  char tmpkeyname[128];
  strncpy(tmpkeyname,keyname,128);
#endif
  part2=malloc(128);

  xev->type = KeyPress;
  xev->display=dpy;
  xev->root=root;
  xev->subwindow = None;
  xev->time=fake_timestamp();
  xev->x=x; xev->y=y;
  xev->x_root=1; xev->y_root=1;
  xev->same_screen = True;

  xev->state=0;
#ifdef HAVE_STRSEP
  while ((part=strsep(&keyname, key_delimiter)))
#else
  while ((part=strtok(tmpkeyname, key_delimiter)))
#endif
    {
      part2=strncpy(part2,part,128);
      //      debugprintf("-   %s \n",part);
      kmlptr=keymodlist;
      while (kmlptr->name)
	{
	  //	  debugprintf("--  %s %s \n", kmlptr->name, part);
	  if (!strcasecmp(kmlptr->name, part))
	    xev->state|=kmlptr->mask;
	  kmlptr++;
	}
      //      debugprintf("--- %s \n",part);
    } 
  //  debugprintf("*** %s \n",part);
  //  debugprintf("*** %s \n",part2);
  xev->keycode=XKeysymToKeycode(dpy,XStringToKeysym(part2));
  debugprintf("state 0x%x, keycode 0x%x\n",xev->state, xev->keycode);
  free(part2);
  return ;
}

void sendfocus(Window w,int in_out)
{<commit_msg>replaced nice but broken code by ugly but working code<commit_after>/*      $Id: irxevent.c,v 5.10 2003/02/13 16:09:08 lirc Exp $      */

/****************************************************************************
 ** irxevent.c **************************************************************
 ****************************************************************************
 *
 * irxevent  - infra-red xevent sender
 *
 * <NAME>  <<EMAIL>>
 * small modifications by <NAME> <<EMAIL>>
 *
 * irxevent is based on irexec (Copyright (C) 1998 <NAME>)
 * and irx.c (no copyright notice found)
 *
 *  =======
 *  HISTORY
 *  =======
 *
 * 0.1 
 *     -Initial Release
 *
 * 0.2 
 *     -no more XWarpPointer... sending Buttonclicks to off-screen
 *      applications works becaus i also fake the EnterNotify and LeaveNotify
 *     -support for keysymbols rather than characters... so you can use
 *      Up or Insert or Control_L ... maybe you could play xquake than :*)
 *
 * 0.3
 *     -bugfix for looking for subwindows of non existing windows 
 *     -finaly a README file
 *
 * 0.3a (done by <NAME>)
 *     -read from a shared .lircrc file 
 *     -changes to comments
 *     (chris, was that all you changed?)
 *
 * 0.4
 *     -fake_timestamp() to solve gqmpeg problems 
 *     -Shift Control and other mod-keys may work. (can't check it right now)
 *      try ctrl-c or shift-Page_up or whatever ...
 *      modifiers: shift, caps, ctrl, alt, meta, numlock, mod3, mod4, scrlock
 *     -size of 'char *keyname' changed from 64 to 128 to allow all mod-keys. 
 *     -updated irxevent.README
 *
 * 0.4.1
 *     -started to make smaller version steps :-)
 *     -Use "CurrentWindow" as window name to send events to the window
 *      that -you guessed it- currently has the focus.
 *
 * 0.4.2
 *     -fixed a stupid string bug in key sending.
 *     -updated irxevent.README to be up to date with the .lircrc format.
 *
 * 0.4.3
 *     -changed DEBUG functions to actually produce some output :)
 *
 * 0.5.0
 *     -fixed finding subwindows recursively
 *     -added xy_Key (though xterm and xemacs still don't like me)
 *     -added compilation patch from <NAME> 
 *      <<EMAIL>> for compiling on systems 
 * 	without strsep() (like some solaris)
 *
 *
 * see http://www.wh9.tu-dresden.de/~heinrich/lirc/irxevent/irxevent.keys
 * for a the key names. (this one is for you Pablo :-) )
 *
 * for more information see the irxevent.README file
 *
 */

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

#include <errno.h>
#include <unistd.h>
#include <getopt.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/stat.h>
#include <sys/types.h>

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <sys/time.h>
#include <unistd.h>

#include "lirc_client.h"

/* #define DEBUG */
#ifdef DEBUG
void debugprintf(char *format_str, ...)
{
        va_list ap;
        va_start(ap,format_str);
        vfprintf(stderr,format_str,ap);
        va_end(ap);
}
#else
void debugprintf(char *format_str, ...)
{
}
#endif


struct keymodlist_t {
        char *name;
        Mask mask;
};
static struct keymodlist_t keymodlist[]=
{
  {"SHIFT",   ShiftMask},
  {"CAPS",    LockMask},
  {"CTRL",    ControlMask},
  {"ALT",     Mod1Mask},{"META",    Mod1Mask},
  {"NUMLOCK", Mod2Mask},
  {"MOD3",    Mod3Mask},  /* I don't have a clue what key maps to this. */
  {"MOD4",    Mod4Mask},  /* I don't have a clue what key maps to this. */
  {"SCRLOCK", Mod5Mask},
  {NULL,0},
};

const char *key_delimiter ="-";
const char *active_window_name ="CurrentWindow";
const char *root_window_name ="RootWindow";


char *progname;
Display *dpy;
Window root;
XEvent xev;
Window w,subw;

Time fake_timestamp()
     /*seems that xfree86 computes the timestamps like this     */
     /*strange but it relies on the *1000-32bit-wrap-around     */
     /*if anybody knows exactly how to do it, please contact me */
{
  int  tint;
  struct timeval  tv;
  struct timezone tz; /* is not used since ages */
  gettimeofday(&tv,&tz);
  tint=(int)tv.tv_sec*1000;
  tint=tint/1000*1000;
  tint=tint+tv.tv_usec/1000;
  return (Time)tint;
}

Window find_window(Window top,char *name)
{
  char *wname,*iname;
  XClassHint xch;
  Window *children,foo;
  int revert_to_return;
  unsigned int nc;
  if (!strcmp(active_window_name,name)){
    XGetInputFocus(dpy, &foo, &revert_to_return);
    return(foo);
  }  else if (!strcmp(root_window_name,name)){
    return(root);
  }
  /* First the base case */
  if (XFetchName(dpy,top,&wname)){
    if (!strncmp(wname,name,strlen(name)))  {
      XFree(wname);
      debugprintf("found it by wname %x \n",top);
      return(top);  /* found it! */
    };
    XFree(wname);
  };

  if(XGetIconName(dpy,top,&iname)){
    if (!strncmp(iname,name,strlen(name)))  {
      XFree(iname);
      debugprintf("found it by iname %x \n",top);
      return(top);  /* found it! */
    };
    XFree(iname);
  };

  if(XGetClassHint(dpy,top,&xch))  {
    if(!strcmp(xch.res_class,name))  {
      XFree(xch.res_name); XFree(xch.res_class);
      debugprintf("res_class '%s' res_name '%s' %x \n", xch.res_class,xch.res_name,top);
      return(top);  /* found it! */
    };
    if(!strcmp(xch.res_name,name))  {
      XFree(xch.res_name); XFree(xch.res_class);
      debugprintf("res_class '%s' res_name '%s' %x \n", xch.res_class,xch.res_name,top);
      return(top);  /* found it! */
    };
    XFree(xch.res_name); XFree(xch.res_class);
  };

  if(!XQueryTree(dpy,top,&foo,&foo,&children,&nc) || children==NULL) {
    return(0);  /* no more windows here */
  };

  /* check all the sub windows */
  for(;nc>0;nc--)  {
    top = find_window(children[nc-1],name);
    if(top) break;  /* we found it somewhere */
  };
  if(children!=NULL) XFree(children);
  return(top);
}

Window find_sub_sub_window(Window top,int *x, int *y)
{
  Window base;
  Window *children,foo,target=0;
  unsigned int nc,
    rel_x,rel_y,width,height,border,depth,
    new_x=1,new_y=1,
    targetsize=1000000;

  base=top;
  if (!base) {return base;};
  if(!XQueryTree(dpy,base,&foo,&foo,&children,&nc) || children==NULL) {
    return(base);  /* no more windows here */
  };
  debugprintf("found subwindows %d\n",nc);

  /* check if we hit a sub window and find the smallest one */
  for(;nc>0;nc--)  {
    if(XGetGeometry(dpy, children[nc-1], &foo, &rel_x, &rel_y, 
		    &width, &height, &border, &depth)){
      if ((rel_x<=*x)&&(*x<=rel_x+width)&&(rel_y<=*y)&&(*y<=rel_y+height)){
	debugprintf("found a subwindow %x +%d +%d  %d x %d   \n",children[nc-1], rel_x,rel_y,width,height);
	if ((width*height)<targetsize){
	  target=children[nc-1];
	  targetsize=width*height;
	  new_x=*x-rel_x;
	  new_y=*y-rel_y;
	  /*bull's eye ...*/
	  target=find_sub_sub_window(target,&new_x,&new_y);
	}
      }	
    }
  };
  if(children!=NULL) XFree(children);
  if (target){
    *x=new_x;
    *y=new_y;
    return target;
  }else
    return base;
}



Window find_sub_window(Window top,char *name,int *x, int *y)
{
  Window base;
  Window *children,foo,target=0;
  unsigned int nc,
    rel_x,rel_y,width,height,border,depth,
    new_x=1,new_y=1,
    targetsize=1000000;

  base=find_window(top, name);
  if (!base) {return base;};
  if(!XQueryTree(dpy,base,&foo,&foo,&children,&nc) || children==NULL) {
    return(base);  /* no more windows here */
  };
  debugprintf("found subwindows %d\n",nc);

  /* check if we hit a sub window and find the smallest one */
  for(;nc>0;nc--)  {
    if(XGetGeometry(dpy, children[nc-1], &foo, &rel_x, &rel_y, 
		    &width, &height, &border, &depth)){
      if ((rel_x<=*x)&&(*x<=rel_x+width)&&(rel_y<=*y)&&(*y<=rel_y+height)){
	debugprintf("found a subwindow %x +%d +%d  %d x %d   \n",children[nc-1], rel_x,rel_y,width,height);
	if ((width*height)<targetsize){
	  target=children[nc-1];
	  targetsize=width*height;
	  new_x=*x-rel_x;
	  new_y=*y-rel_y;
	  /*bull's eye ...*/
	  target=find_sub_sub_window(target,&new_x,&new_y);
	}
      }	
    }
  };
  if(children!=NULL) XFree(children);
  if (target){
    *x=new_x;
    *y=new_y;
    return target;
  }else
    return base;
}


void make_button(int button,int x,int y,XButtonEvent *xev)
{
  xev->type = ButtonPress;
  xev->display=dpy;
  xev->root=root;
  xev->subwindow=None;
  xev->time=fake_timestamp();
  xev->x=x;xev->y=y;
  xev->x_root=1; xev->y_root=1;
  xev->state=0;
  xev->button=button;
  xev->same_screen=True;

  return;
}

void make_key(char *keyname,int x, int y,XKeyEvent *xev)
{
  char *part, *part2;
  struct keymodlist_t *kmlptr;

  part2=malloc(128);

  xev->type = KeyPress;
  xev->display=dpy;
  xev->root=root;
  xev->subwindow = None;
  xev->time=fake_timestamp();
  xev->x=x; xev->y=y;
  xev->x_root=1; xev->y_root=1;
  xev->same_screen = True;

  xev->state=0;
#ifdef HAVE_STRSEP
  while ((part=strsep(&keyname, key_delimiter)))
#else
  while ((part=strtok(keyname, key_delimiter)) && ((keyname=NULL)==NULL))
#endif
    {
      part2=strncpy(part2,part,128);
      //      debugprintf("-   %s \n",part);
      kmlptr=keymodlist;
      while (kmlptr->name)
	{
	  //	  debugprintf("--  %s %s \n", kmlptr->name, part);
	  if (!strcasecmp(kmlptr->name, part))
	    xev->state|=kmlptr->mask;
	  kmlptr++;
	}
      //      debugprintf("--- %s \n",part);
    } 
  //  debugprintf("*** %s \n",part);
  //  debugprintf("*** %s \n",part2);
  xev->keycode=XKeysymToKeycode(dpy,XStringToKeysym(part2));
  debugprintf("state 0x%x, keycode 0x%x\n",xev->state, xev->keycode);
  free(part2);
  return ;
}

void sendfocus(Window w,int in_out)
{
{'fraction_non_alphanumeric': 0.18658511083228774, 'fraction_numerical': 0.014899623588456713, 'mean_word_length': 3.3346929526399274, 'pattern_counts': {'":': 0, '<': 77, '<?xml version=': 0, '>': 125, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3693947', 'n_tokens_mistral': 7592, 'n_tokens_neox': 7304, 'n_words': 1648}