Ejemplo n.º 1
0
Archivo: utils.c Proyecto: abudrys/rss
array_t *array_init(int size)
{
	array_t *array = xcmalloc(sizeof(array_t));
	array->a_data = xmalloc(sizeof(void *) * size);
	array->a_count = size;
	return array;
}
Ejemplo n.º 2
0
/* a strdup() implementation since ANSI C doesn't include strdup() */
void *
xcstrdup(const char *string)
{
    void *mem;

    /* allocate a buffer big enough to hold the characters and the
     * null terminator, then copy the string into the buffer
     */
    mem = xcmalloc(strlen(string) + sizeof(char));
    strcpy(mem, string);

    return (mem);
}
Ejemplo n.º 3
0
/* Use XrmParseCommand to parse command line options to option variable */
static void doOptMain (int argc, char *argv[])
{
	/* Initialise resource manager and parse options into database */
	XrmInitialize();
	XrmParseCommand(
		&opt_db,
		opt_tab,
		sizeof(opt_tab) / sizeof(opt_tab[0]),
		XC_NAME,
		&argc,
		argv
	);
  
	/* set output level */
	if (
		XrmGetResource(
			opt_db,
			"xclip.olevel",
			"Xclip.Olevel",
			&rec_typ,
			&rec_val
		)
	)
	{
		/* set verbose flag according to option */
		if (strcmp(rec_val.addr, "S") == 0)
			fverb = OSILENT;
		if (strcmp(rec_val.addr, "Q") == 0)
			fverb = OQUIET;
		if (strcmp(rec_val.addr, "V") == 0)
			fverb = OVERBOSE;
	}
  
	/* set direction flag (in or out) */
	if (
		XrmGetResource(
			opt_db,
			"xclip.direction",
			"Xclip.Direction",
			&rec_typ,
			&rec_val
		)
	)
	{
		if (strcmp(rec_val.addr, "I") == 0)
			fdiri = T;
		if (strcmp(rec_val.addr, "O") == 0)
			fdiri = F;
	}
  
	/* set filter mode */
	if (
		XrmGetResource(
			opt_db,
			"xclip.filter",
			"Xclip.Filter",
			&rec_typ,
			&rec_val
		)
	)
	{
		/* filter mode only allowed in silent mode */
		if (fverb == OSILENT)
			ffilt = T;
	}
  
	/* check for -help and -version */
	if (
		XrmGetResource(
			opt_db,
			"xclip.print",
			"Xclip.Print",
			&rec_typ,
			&rec_val
		)
	)
	{
		if (strcmp(rec_val.addr, "H") == 0)
			prhelp(argv[0]);
		if (strcmp(rec_val.addr, "V") == 0)
			prversion();
	}
  
	/* check for -display */
	if (
		XrmGetResource(
			opt_db,
			"xclip.display",
			"Xclip.Display",
			&rec_typ,
			&rec_val
		)
	)
	{
		sdisp = rec_val.addr;
		if (fverb == OVERBOSE)	/* print in verbose mode only */
			fprintf(stderr, "Display: %s\n", sdisp);
	}
  
	/* check for -loops */
	if (
		XrmGetResource(
			opt_db,
			"xclip.loops",
			"Xclip.Loops",
			&rec_typ,
			&rec_val
		)
	)
	{
		sloop = atoi(rec_val.addr);
		if (fverb == OVERBOSE)	/* print in verbose mode only */
			fprintf(stderr, "Loops: %i\n", sloop);
	}

	/* Read remaining options (filenames) */
	while ( (fil_number + 1) < argc )
	{
		if (fil_number > 0)
		{
			fil_names = xcrealloc(
				fil_names,
				(fil_number + 1) * sizeof(char*)
			);
		} else
		{
			fil_names = xcmalloc(sizeof(char*));
		}
		fil_names[fil_number] = argv[fil_number + 1];
		fil_number++;
	}
}
Ejemplo n.º 4
0
int main (int argc, char *argv[])
{
	/* Declare variables */
	unsigned char *sel_buf;		/* buffer for selection data */
	unsigned long sel_len = 0;	/* length of sel_buf */
	unsigned long sel_all = 0;	/* allocated size of sel_buf */
	Window win;			/* Window */
	XEvent evt;			/* X Event Structures */
	int dloop = 0;			/* done loops counter */

	pid_t pid;			/* child pid if forking */

	/* set up option table. I can't figure out a better way than this to
	 * do it while sticking to pure ANSI C. The option and specifier
	 * members have a type of volatile char *, so they need to be allocated
	 * by strdup or malloc, you can't set them to a string constant at
	 * declare time, this is note pure ANSI C apparently, although it does
	 * work with gcc
	 */
	
	/* loop option entry */
	opt_tab[0].option 	=	xcstrdup("-loops");
	opt_tab[0].specifier	=	xcstrdup(".loops");
	opt_tab[0].argKind	=	XrmoptionSepArg;
	opt_tab[0].value	=	(XPointer) NULL;

	/* display option entry */
	opt_tab[1].option	=	xcstrdup("-display");
	opt_tab[1].specifier	=	xcstrdup(".display");
	opt_tab[1].argKind	=	XrmoptionSepArg;
	opt_tab[1].value	=	(XPointer) NULL;
				
	/* selection option entry */
	opt_tab[2].option 	=	xcstrdup("-selection");
	opt_tab[2].specifier	=	xcstrdup(".selection");
	opt_tab[2].argKind	=	XrmoptionSepArg;
	opt_tab[2].value	=	(XPointer) NULL;
		
	/* filter option entry */
	opt_tab[3].option	=	xcstrdup("-filter");
	opt_tab[3].specifier	=	xcstrdup(".filter");
	opt_tab[3].argKind	=	XrmoptionNoArg;	
	opt_tab[3].value	=	(XPointer) xcstrdup(ST);
		
	/* in option entry */
	opt_tab[4].option	=	xcstrdup("-in");
	opt_tab[4].specifier	=	xcstrdup(".direction");
	opt_tab[4].argKind	=	XrmoptionNoArg;
	opt_tab[4].value	=	(XPointer) xcstrdup("I");
		
	/* out option entry */
	opt_tab[5].option	=	xcstrdup("-out");
	opt_tab[5].specifier	=	xcstrdup(".direction");
	opt_tab[5].argKind	=	XrmoptionNoArg;
	opt_tab[5].value	=	(XPointer) xcstrdup("O");
		
	/* version option entry */
	opt_tab[6].option	=	xcstrdup("-version");
	opt_tab[6].specifier	=	xcstrdup(".print");
	opt_tab[6].argKind	=	XrmoptionNoArg;
	opt_tab[6].value	=	(XPointer) xcstrdup("V");
		
	/* help option entry */
	opt_tab[7].option	=	xcstrdup("-help");
	opt_tab[7].specifier	=	xcstrdup(".print");
	opt_tab[7].argKind	=	XrmoptionNoArg;
	opt_tab[7].value	=	(XPointer) xcstrdup("H");
		
	/* silent option entry */
	opt_tab[8].option	=	xcstrdup("-silent");
	opt_tab[8].specifier	=	xcstrdup(".olevel");
	opt_tab[8].argKind	=	XrmoptionNoArg;
	opt_tab[8].value	=	(XPointer) xcstrdup("S");
		
	/* quiet option entry */
	opt_tab[9].option	=	xcstrdup("-quiet");
	opt_tab[9].specifier	=	xcstrdup(".olevel");
	opt_tab[9].argKind	=	XrmoptionNoArg;
	opt_tab[9].value	=	(XPointer) xcstrdup("Q");
		
	/* verbose option entry */
	opt_tab[10].option	=	xcstrdup("-verbose");
	opt_tab[10].specifier	=	xcstrdup(".olevel");
	opt_tab[10].argKind	=	XrmoptionNoArg;
	opt_tab[10].value	=	(XPointer) xcstrdup("V");

	/* parse command line options */
	doOptMain(argc, argv);
   
	/* Connect to the X server. */
	if ( (dpy = XOpenDisplay(sdisp)) )
	{
		/* successful */
		if (fverb == OVERBOSE)
			fprintf(stderr, "Connected to X server.\n");
	} else
	{
		/* couldn't connect to X server. Print error and exit */
		errxdisplay(sdisp);
	}

	/* parse selection command line option */
	doOptSel();
  
	/* Create a window to trap events */
	win = XCreateSimpleWindow(
		dpy,
		DefaultRootWindow(dpy),
		0,
		0,
		1,
		1,
		0,
		0,
		0
	);

	/* get events about property changes */
	XSelectInput(dpy, win, PropertyChangeMask);
  
	if (fdiri)
	{
		/* in mode */
		sel_all = 16;		/* Reasonable ballpark figure */
		sel_buf = xcmalloc(sel_all * sizeof(char));

		/* Put chars into inc from stdin or files until we hit EOF */
		do {
			if (fil_number == 0)
			{
				/* read from stdin if no files specified */
				fil_handle = stdin;
			} else
			{
				if (
					(fil_handle = fopen(
						fil_names[fil_current],
						"r"
					)) == NULL
				)
				{
					errperror(
						3,
						argv[0],
						": ",
						fil_names[fil_current]
					);
					exit(EXIT_FAILURE);
				} else
				{
					/* file opened successfully. Print
					 * message (verbose mode only).
					 */
					if (fverb == OVERBOSE)
						fprintf(
							stderr,
							"Reading %s...\n",
							fil_names[fil_current]
						);
				}
			}

			fil_current++;
			while (!feof(fil_handle))
			{
				/* If sel_buf is full (used elems =
				 * allocated elems)
				 */
				if (sel_len == sel_all)
				{
					/* double the number of
					 * allocated elements
					 */
					sel_all *= 2;
					sel_buf = (unsigned char *)xcrealloc(
						sel_buf,
						sel_all * sizeof(char)
					);
				}
				sel_len += fread(
					sel_buf + sel_len,
					sizeof(char),
					sel_all - sel_len,
					fil_handle
				);
			}
		} while (fil_current < fil_number);

		/* if there are no files being read from (i.e., input
		 * is from stdin not files, and we are in filter mode,
		 * spit all the input back out to stdout
		 */
		if ((fil_number == 0) && ffilt)
			fwrite(sel_buf, sizeof(char), sel_len, stdout); 
    
		/* take control of the selection so that we receive
		 * SelectionRequest events from other windows
		 */
		XSetSelectionOwner(dpy, sseln, win, CurrentTime);

		/* fork into the background, exit parent process if we
		 * are in silent mode
		 */
		if (fverb == OSILENT)
		{
			pid = fork();
			/* exit the parent process; */
			if (pid)
				exit(EXIT_SUCCESS);
		}

		/* print a message saying what we're waiting for */
		if (fverb > OSILENT)
		{
			if (sloop == 1)
				fprintf(
					stderr,
					"Waiting for one selection request.\n"
				);
				
			if (sloop  < 1)
				fprintf(
					stderr,
					"Waiting for selection requests, Control-C to quit\n"
				);
				
			if (sloop  > 1)
				fprintf(
					stderr,
					"Waiting for %i selection requests, Control-C to quit\n",
					sloop
				);
		}
  
		/* loop and wait for the expected number of
		 * SelectionRequest events
		 */
		while (dloop < sloop || sloop < 1)
		{
			/* print messages about what we're waiting for
			 * if not in silent mode
			 */
			if (fverb > OSILENT)
			{
				if (sloop  > 1)
					fprintf(
						stderr,
						"  Waiting for selection request %i of %i.\n",
						dloop + 1,
						sloop
					);
					
				if (sloop == 1)
					fprintf(
						stderr,
						"  Waiting for a selection request.\n"
					);
					
				if (sloop  < 1)
					fprintf(
						stderr,
						"  Waiting for selection request number %i\n",
						dloop + 1
					);
			}
     
			/* wait for a SelectionRequest event */
			while (1)
			{
				XNextEvent(dpy, &evt);

				/* request for selection, process
				 * with xcin()
				 */
				if (evt.type == SelectionRequest)
					break;

				/* lost ownership of selection, exit */
				if (evt.type == SelectionClear)
					exit(EXIT_SUCCESS);
			}

			/* recieved request, send response with xcin().
			 * xcin() will return a true value if it
			 * received a SelectionClear, in which case
			 * xclip should exit
			 */
			if (xcin(dpy, evt, sel_buf, sel_len))
				exit(EXIT_SUCCESS);

			dloop++;	/* increment loop counter */
		}
	} else
	{
		/* out mode - get selection, print it, free the memory */
		xcout(dpy, win, sseln, &sel_buf, &sel_len);
		if (sel_len)
		{
			/* only print the buffer out, and free it, if it's not
			 * empty
			 */
			fwrite(sel_buf, sizeof(char), sel_len, stdout);
			free(sel_buf);
		}
	}

	/* Disconnect from the X server */
	XCloseDisplay(dpy);

	/* exit */
	return(EXIT_SUCCESS);
}
Ejemplo n.º 5
0
/* Retrieves the contents of a selections. Arguments are:
 *
 * A display that has been opened.
 * 
 * A window
 * 
 * An event to process
 * 
 * The selection to return
 * 
 * The target(UTF8_STRING or XA_STRING) to return 
 *
 * A pointer to a char array to put the selection into.
 * 
 * A pointer to a long to record the length of the char array
 *
 * A pointer to an int to record the context in which to process the event
 *
 * Return value is 1 if the retrieval of the selection data is complete,
 * otherwise it's 0.
 */
int
xcout(Display * dpy,
      Window win,
      XEvent evt, Atom sel, Atom target, unsigned char **txt, unsigned long *len,
      unsigned int *context)
{
    /* a property for other windows to put their selection into */
    static Atom pty;
    static Atom inc;
    Atom pty_type;
    Atom atomUTF8String;
    int pty_format;

    /* buffer for XGetWindowProperty to dump data into */
    unsigned char *buffer;
    unsigned long pty_size, pty_items;

    /* local buffer of text to return */
    unsigned char *ltxt = *txt;

    if (!pty) {
	pty = XInternAtom(dpy, "XCLIP_OUT", False);
    }

    if (!inc) {
	inc = XInternAtom(dpy, "INCR", False);
    }

    switch (*context) {
	/* there is no context, do an XConvertSelection() */
    case XCLIB_XCOUT_NONE:
	/* initialise return length to 0 */
	if (*len > 0) {
	    free(*txt);
	    *len = 0;
	}

	/* send a selection request */
	XConvertSelection(dpy, sel, target, pty, win, CurrentTime);
	*context = XCLIB_XCOUT_SENTCONVSEL;
	return (0);

    case XCLIB_XCOUT_SENTCONVSEL:
	atomUTF8String = XInternAtom(dpy, "UTF8_STRING", False);
	if (evt.type != SelectionNotify)
	    return (0);

	/* fallback to XA_STRING when UTF8_STRING failed */
	if (target == atomUTF8String && evt.xselection.property == None) {
	    *context = XCLIB_XCOUT_FALLBACK;
	    return (0);
	}

	/* find the size and format of the data in property */
	XGetWindowProperty(dpy,
			   win,
			   pty,
			   0,
			   0,
			   False,
			   AnyPropertyType, &pty_type, &pty_format, &pty_items, &pty_size, &buffer);
	XFree(buffer);

	if (pty_type == inc) {
	    /* start INCR mechanism by deleting property */
	    XDeleteProperty(dpy, win, pty);
	    XFlush(dpy);
	    *context = XCLIB_XCOUT_INCR;
	    return (0);
	}

	/* if it's not incr, and not format == 8, then there's
	 * nothing in the selection (that xclip understands,
	 * anyway)
	 */
	if (pty_format != 8) {
	    *context = XCLIB_XCOUT_NONE;
	    return (0);
	}

	/* not using INCR mechanism, just read the property */
	XGetWindowProperty(dpy,
			   win,
			   pty,
			   0,
			   (long) pty_size,
			   False,
			   AnyPropertyType, &pty_type, &pty_format, &pty_items, &pty_size, &buffer);

	/* finished with property, delete it */
	XDeleteProperty(dpy, win, pty);

	/* copy the buffer to the pointer for returned data */
	ltxt = (unsigned char *) xcmalloc(pty_items);
	memcpy(ltxt, buffer, pty_items);

	/* set the length of the returned data */
	*len = pty_items;
	*txt = ltxt;

	/* free the buffer */
	XFree(buffer);

	*context = XCLIB_XCOUT_NONE;

	/* complete contents of selection fetched, return 1 */
	return (1);

    case XCLIB_XCOUT_INCR:
	/* To use the INCR method, we basically delete the
	 * property with the selection in it, wait for an
	 * event indicating that the property has been created,
	 * then read it, delete it, etc.
	 */

	/* make sure that the event is relevant */
	if (evt.type != PropertyNotify)
	    return (0);

	/* skip unless the property has a new value */
	if (evt.xproperty.state != PropertyNewValue)
	    return (0);

	/* check size and format of the property */
	XGetWindowProperty(dpy,
			   win,
			   pty,
			   0,
			   0,
			   False,
			   AnyPropertyType,
			   &pty_type,
			   &pty_format, &pty_items, &pty_size, (unsigned char **) &buffer);

	if (pty_format != 8) {
	    /* property does not contain text, delete it
	     * to tell the other X client that we have read
	     * it and to send the next property
	     */
	    XFree(buffer);
	    XDeleteProperty(dpy, win, pty);
	    return (0);
	}

	if (pty_size == 0) {
	    /* no more data, exit from loop */
	    XFree(buffer);
	    XDeleteProperty(dpy, win, pty);
	    *context = XCLIB_XCOUT_NONE;

	    /* this means that an INCR transfer is now
	     * complete, return 1
	     */
	    return (1);
	}

	XFree(buffer);

	/* if we have come this far, the propery contains
	 * text, we know the size.
	 */
	XGetWindowProperty(dpy,
			   win,
			   pty,
			   0,
			   (long) pty_size,
			   False,
			   AnyPropertyType,
			   &pty_type,
			   &pty_format, &pty_items, &pty_size, (unsigned char **) &buffer);

	/* allocate memory to accommodate data in *txt */
	if (*len == 0) {
	    *len = pty_items;
	    ltxt = (unsigned char *) xcmalloc(*len);
	}
	else {
	    *len += pty_items;
	    ltxt = (unsigned char *) xcrealloc(ltxt, *len);
	}

	/* add data to ltxt */
	memcpy(&ltxt[*len - pty_items], buffer, pty_items);

	*txt = ltxt;
	XFree(buffer);

	/* delete property to get the next item */
	XDeleteProperty(dpy, win, pty);
	XFlush(dpy);
	return (0);
    }

    return (0);
}
Ejemplo n.º 6
0
int main (int argc, char *argv[])
{
	/* Declare variables */
	char *seltxt;			/* selection text string */
	unsigned long stelems = 0;	/* number of used elements in seltxt */
	unsigned long stalloc = 0;	/* size of seltxt */
	Window win;			/* Window */
	XEvent evt;			/* X Event Structures */
	int dloop = 0;			/* done loops counter */

	pid_t pid;			/* child pid if forking */

	/* parse command line options */
	doOptMain(argc, argv);
   
	/* Connect to the X server. */
	if ( (dpy = XOpenDisplay(sdisp)) )
	{
		/* successful */
		if (fverb == OVERBOSE)
			fprintf(stderr, "Connected to X server.\n");
	} else
	{
		/* couldn't connect to X server. Print error and exit */
		errxdisplay(sdisp);
	}

	/* parse selection command line option */
	doOptSel(argc, argv);
  
	/* Create a window to trap events */
	win = XCreateSimpleWindow(
		dpy,
		DefaultRootWindow(dpy),
		0,
		0,
		1,
		1,
		0,
		0,
		0
	);

	/* get events about property changes */
	XSelectInput(dpy, win, PropertyChangeMask);
  
	if (fdiri)
	{
		/* in mode */
		stalloc = 16;  /* Reasonable ballpark figure */
		seltxt = xcmalloc(stalloc);

		/* Put chars into inc from stdin or files until we hit EOF */
		do {
			
			if (fil_number == 0)
			{
				/* read from stdin if no files specified */
				fil_handle = stdin;
			} else
			{
				/* open the current file for reading */
				if (
					(fil_handle = fopen(
						fil_names[fil_current],
						"r"
					)) == NULL
				)
				{
					errperror(
						argv[0],
						": ",
						fil_names[fil_current]
					);
					exit(EXIT_FAILURE);
				} else
				{
					/* file opened successfully. Print
					 * message (verbose mode only).
					 */
					if (fverb == OVERBOSE)
						fprintf(
							stderr,
							"Reading %s...\n",
							fil_names[fil_current]
						);
				}
			}
			fil_current++;
			while (!feof(fil_handle))
			{
				int n = 0;

				/* If in is full (used elems =
				 * allocated elems)
				 */
				if (stelems == stalloc)
				{
					/* double the number of
					 * allocated elements
					 */
					stalloc *= 2 + 1;
					seltxt = (char *)xcrealloc(
						seltxt,
						stalloc * sizeof(char)
					);
				}
				n = fread(
					seltxt + stelems,
					1,
					stalloc - stelems,
					fil_handle
				);
	
				stelems += n;
				seltxt[stelems] = '\0';
			}
		} while (fil_current < fil_number);

		/* if there are no files being read from (i.e., input
		 * is from stdin not files, and we are in filter mode,
		 * spit all the input back out to stdout
		 */
		if ((fil_number == 0) && ffilt)
			printf(seltxt);
    
		/* take control of the selection so that we receive
		 * SelectionRequest events from other windows
		 */
		XSetSelectionOwner(dpy, sseln, win, CurrentTime);

		/* fork into the background, exit parent process if we
		 * are in silent mode
		 */
		if (fverb == OSILENT)
		{
			pid = fork();
			/* exit the parent process; */
			if (pid)
				exit(EXIT_SUCCESS);
		}

		/* print a message saying what we're waiting for */
		if (fverb > OSILENT)
		{
			if (sloop == 1)
				fprintf(
					stderr,
					"Waiting for one selection request.\n"
				);
				
			if (sloop  < 1)
				fprintf(
					stderr,
					"Waiting for selection requests, Control-C to quit\n"
				);
				
			if (sloop  > 1)
				fprintf(
					stderr,
					"Waiting for %i selection requests, Control-C to quit\n",
					sloop
				);
		}
  
		/* loop and wait for the expected number of
		 * SelectionRequest events
		 */
		while (dloop < sloop || sloop < 1)
		{
			/* print messages about what we're waiting for
			 * if not in silent mode
			 */
			if (fverb > OSILENT)
			{
				if (sloop  > 1)
					fprintf(
						stderr,
						"  Waiting for selection request %i of %i.\n",
						dloop + 1,
						sloop
					);
					
				if (sloop == 1)
					fprintf(
						stderr,
						"  Waiting for a selection request.\n"
					);
					
				if (sloop  < 1)
					fprintf(
						stderr,
						"  Waiting for selection request number %i\n",
						dloop + 1
					);
			}
     
			/* wait for a SelectionRequest event */
			while (1)
			{
				XNextEvent(dpy, &evt);

				/* request for selection, process
				 * with xcin()
				 */
				if (evt.type == SelectionRequest)
					break;

				/* lost ownership of selection, exit */
				if (evt.type == SelectionClear)
					exit(EXIT_SUCCESS);
			}

			/* recieved request, send response with xcin().
			 * xcin() will return a true value if it
			 * received a SelectionClear, in which case
			 * xclip should exit
			 */
			if (xcin(dpy, win, evt, seltxt))
				exit(EXIT_SUCCESS);

			dloop++;	/* increment loop counter */
		}
	} else
	{
		/* out mode - get selection, print it, free the memory */
		seltxt = xcout(dpy, win, sseln);
		printf(seltxt);
		free(seltxt);
	}

	/* Disconnect from the X server */
	XCloseDisplay(dpy);

	/* exit */
	return(EXIT_SUCCESS);
}
Ejemplo n.º 7
0
/* return selection data */
char *xcout (Display *dpy, Window win, Atom sel)
{
	Atom		pty, inc, pty_type;
	int		pty_format;
	XEvent		evt;
	char		*txt;
	char		*rtn_str;
	unsigned int	rtn_siz = 0;

	unsigned char	*data;
	unsigned long	pty_items, pty_size;

	/* Two new window properties for transferring the selection */
	pty = XInternAtom(dpy, "XCLIP_OUT",	False);
	inc = XInternAtom(dpy, "INCR",		False);

	/* send a selection request */
	XConvertSelection(
		dpy,
		sel,
		XA_STRING,
		pty,
		win,
		CurrentTime
	);

	/* wait for a SelectionNotify in response to our request */
	while (1)
	{
		XNextEvent(dpy, &evt);
		if (evt.type == SelectionNotify || evt.type == None )
			break;
	}

	/* quit if there is nothing in the selection */
	if (evt.type == None)
		return(rtn_str);
    
	/* find out the size and format of the data in property */
	XGetWindowProperty(
		dpy,
		win,
		pty,
		0,
		0,
		False,
		AnyPropertyType,
		&pty_type,
		&pty_format,
		&pty_items,
		&pty_size,
		&data
	);

	if (pty_format == 8)
	{
		/* not using INCR mechanism, just read and print the property */
		XGetWindowProperty(
			dpy,
			win,
			pty,
			0,
			pty_size,
			False,
			AnyPropertyType,
			&pty_type,
			&pty_format,
			&pty_items,
			&pty_size,
			(unsigned char **)&txt
		);

		/* finished with property, delete it */
		XDeleteProperty(dpy, win, pty);

		/* make a copy of the selection string, then free it */
		rtn_str = strdup(txt);
		XFree(txt);

	} else if (pty_type == inc)
	{
		/* Using INCR mechanism, start by deleting the property */
		XDeleteProperty(dpy, win, pty);
		
		while (1)
		{
			/* To use the INCR method, we basically delete the
			 * property with the selection in it, wait for an
			 * event indicating that the property has been created,
			 * then read it, delete it, etc.
			 */

			/* flush to force any pending XDeleteProperty calls
			 * from the previous running of the loop, get the next
			 * event in the event queue
			 */
			XFlush(dpy);
			XNextEvent(dpy, &evt);

			/* skip unless is a property event */
			if (evt.type != PropertyNotify)
				continue;

			/* skip unless the property has a new value */
			if (evt.xproperty.state != PropertyNewValue)
				continue;
	
			/* check size and format of the property */
			XGetWindowProperty(
				dpy,
				win,
				pty,
				0,
				0,
				False,
				AnyPropertyType,
				&pty_type,
				&pty_format,
				&pty_items,
				&pty_size,
				(unsigned char **)&txt
			);

			if (pty_format != 8){
				/* property does not contain text, delete it
				 * to tell the other X client that we have read
				 * it and to send the next property */
				XDeleteProperty(dpy, win, pty);
				continue;
			}

			if (pty_size == 0){
				/* no more data, exit from loop */
				XDeleteProperty(dpy, win, pty);
				break;
			}

			/* if we have come this far, the propery contains
			 * text, we know the size.
			 */
			XGetWindowProperty(
				dpy,
				win,
				pty,
				0,
				pty_size,
				False,
				AnyPropertyType,
				&pty_type,
				&pty_format,
				&pty_items,
				&pty_size,
				(unsigned char **)&txt
			);
			
			/* allocate memory to ammodate date in rtn_str */
			if (rtn_siz == 0)
			{
				rtn_siz = pty_items;
				rtn_str = (char *)xcmalloc(rtn_siz);
			} else
			{
				rtn_siz += pty_items;
				rtn_str = (char *)xcrealloc(rtn_str, rtn_siz);
			}
			
			/* add data to return_str */
			strncat(rtn_str, txt, pty_items);
			
			/* delete property to get the next item */
			XDeleteProperty(dpy, win, pty);
		}
	}
	return(rtn_str);
}
Ejemplo n.º 8
0
/* send selection data in response to a request returns 0 */
int xcin (Display *dpy, Window win, XEvent rev, char *txt)
{
	unsigned int			incr = F;	/* incr mode flag */
	XEvent				res;		/* response to event */
	Atom				inc;
	unsigned int			selc = F;	/* SelClear event */

	if (rev.type == SelectionClear)
		return(1);
	
	/* send only continue if this is a SelectionRequest event */
	if (rev.type != SelectionRequest)
		return(0);
	
	/* test whether to use INCR or not */
	if ( strlen(txt) > XC_CHUNK )
	{
		incr = T;
		inc = XInternAtom(dpy, "INCR", False);
	}

	/* put the data into an property */
	if (incr)
	{
		/* send INCR response */
		XChangeProperty(
			dpy,
			rev.xselectionrequest.requestor,
			rev.xselectionrequest.property,
			inc,
			32,
			PropModeReplace,
			0,
			0
		);

		/* With the INCR mechanism, we need to know when the
		 * requestor window changes (deletes) its properties
		 */
		XSelectInput(
			dpy,
			rev.xselectionrequest.requestor,
			PropertyChangeMask
		);
	} else 
	{
		/* send data all at once (not using INCR) */
		XChangeProperty(
			dpy,
			rev.xselectionrequest.requestor,
			rev.xselectionrequest.property,
			XA_STRING,
			8,
			PropModeReplace,
			(unsigned char*) txt,
			strlen(txt)
		);
	}
	
	/* set values for the response event */
	res.xselection.property  = rev.xselectionrequest.property;
	res.xselection.type      = SelectionNotify;
	res.xselection.display   = rev.xselectionrequest.display;
	res.xselection.requestor = rev.xselectionrequest.requestor;
	res.xselection.selection = rev.xselectionrequest.selection;
	res.xselection.target    = rev.xselectionrequest.target;
	res.xselection.time      = rev.xselectionrequest.time;

	/* send the response event */
	XSendEvent(dpy, rev.xselectionrequest.requestor, 0, 0, &res);
	XFlush(dpy);

	if (incr)
	{
		unsigned int sel_pos = 0; /* position in sel_str */
		unsigned int sel_end = 0;
		char *chk_str;

		chk_str = (char *)xcmalloc(XC_CHUNK);

		while (1)
		{
			unsigned int chk_pos = 0;

			while (1)
			{
				XEvent	spe;

				XNextEvent(dpy, &spe);
				if (spe.type == SelectionClear)
				{
					selc = T;
					continue;
				}
				if (spe.type != PropertyNotify)
					continue;
				if (spe.xproperty.state == PropertyDelete)
					break;
			}
	    

			if (!sel_end)
			{
				for (chk_pos=0; chk_pos<=XC_CHUNK; chk_pos++)
				{
					if (txt[sel_pos] == (char)NULL)
					{
						sel_end = 1;
						break;
					}
					chk_str[chk_pos] = txt[sel_pos];
					sel_pos++;
				}
			}

			if (chk_pos)
			{
				XChangeProperty(
					dpy,
					rev.xselectionrequest.requestor,
					rev.xselectionrequest.property,
					XA_STRING,
					8,
					PropModeReplace,
					chk_str,
					chk_pos
				);
			} else
			{
				XChangeProperty(
					dpy,
					rev.xselectionrequest.requestor,
					rev.xselectionrequest.property,
					XA_STRING,
					8,
					PropModeReplace,
					0,
					0	
				);
			}
			XFlush(dpy);

			/* no more chars to send, break out of the loop */
			if (!chk_pos)
				break;
		}
	}
	return(selc);
}
Ejemplo n.º 9
0
Archivo: utils.c Proyecto: abudrys/rss
hash_t *hash_init()
{
	hash_t *hash = xcmalloc(sizeof(hash_t));
	return hash;
}
Ejemplo n.º 10
0
static int
doIn(Window win, const char *progname)
{
    unsigned char *sel_buf;	/* buffer for selection data */
    unsigned long sel_len = 0;	/* length of sel_buf */
    unsigned long sel_all = 0;	/* allocated size of sel_buf */
    XEvent evt;			/* X Event Structures */
    int dloop = 0;		/* done loops counter */

    /* in mode */
    sel_all = 16;		/* Reasonable ballpark figure */
    sel_buf = xcmalloc(sel_all * sizeof(char));

    /* Put chars into inc from stdin or files until we hit EOF */
    do {
	if (fil_number == 0) {
	    /* read from stdin if no files specified */
	    fil_handle = stdin;
	}
	else {
	    if ((fil_handle = fopen(fil_names[fil_current], "r")) == NULL) {
		errperror(3, progname, ": ", fil_names[fil_current]
		    );
		return EXIT_FAILURE;
	    }
	    else {
		/* file opened successfully. Print
		 * message (verbose mode only).
		 */
		if (fverb == OVERBOSE)
		    fprintf(stderr, "Reading %s...\n", fil_names[fil_current]
			);
	    }
	}

	fil_current++;
	while (!feof(fil_handle)) {
	    /* If sel_buf is full (used elems =
	     * allocated elems)
	     */
	    if (sel_len == sel_all) {
		/* double the number of
		 * allocated elements
		 */
		sel_all *= 2;
		sel_buf = (unsigned char *) xcrealloc(sel_buf, sel_all * sizeof(char)
		    );
	    }
	    sel_len += fread(sel_buf + sel_len, sizeof(char), sel_all - sel_len, fil_handle);
	}
    } while (fil_current < fil_number);

    /* if there are no files being read from (i.e., input
     * is from stdin not files, and we are in filter mode,
     * spit all the input back out to stdout
     */
    if ((fil_number == 0) && ffilt) {
	fwrite(sel_buf, sizeof(char), sel_len, stdout);
	fclose(stdout);
    }

    /* Handle cut buffer if needed */
    if (sseln == XA_STRING) {
	XStoreBuffer(dpy, (char *) sel_buf, (int) sel_len, 0);
	return EXIT_SUCCESS;
    }

    /* take control of the selection so that we receive
     * SelectionRequest events from other windows
     */
    /* FIXME: Should not use CurrentTime, according to ICCCM section 2.1 */
    XSetSelectionOwner(dpy, sseln, win, CurrentTime);

    /* fork into the background, exit parent process if we
     * are in silent mode
     */
    if (fverb == OSILENT) {
	pid_t pid;

	pid = fork();
	/* exit the parent process; */
	if (pid)
	    exit(EXIT_SUCCESS);
    }

    /* print a message saying what we're waiting for */
    if (fverb > OSILENT) {
	if (sloop == 1)
	    fprintf(stderr, "Waiting for one selection request.\n");

	if (sloop < 1)
	    fprintf(stderr, "Waiting for selection requests, Control-C to quit\n");

	if (sloop > 1)
	    fprintf(stderr, "Waiting for %i selection requests, Control-C to quit\n", sloop);
    }

    /* Avoid making the current directory in use, in case it will need to be umounted */
    chdir("/");

    /* loop and wait for the expected number of
     * SelectionRequest events
     */
    while (dloop < sloop || sloop < 1) {
	/* print messages about what we're waiting for
	 * if not in silent mode
	 */
	if (fverb > OSILENT) {
	    if (sloop > 1)
		fprintf(stderr, "  Waiting for selection request %i of %i.\n", dloop + 1, sloop);

	    if (sloop == 1)
		fprintf(stderr, "  Waiting for a selection request.\n");

	    if (sloop < 1)
		fprintf(stderr, "  Waiting for selection request number %i\n", dloop + 1);
	}

	/* wait for a SelectionRequest event */
	while (1) {
	    static unsigned int clear = 0;
	    static unsigned int context = XCLIB_XCIN_NONE;
	    static unsigned long sel_pos = 0;
	    static Window cwin;
	    static Atom pty;
	    int finished;

	    XNextEvent(dpy, &evt);

	    finished = xcin(dpy, &cwin, evt, &pty, target, sel_buf, sel_len, &sel_pos, &context);

	    if (evt.type == SelectionClear)
		clear = 1;

	    if ((context == XCLIB_XCIN_NONE) && clear)
		return EXIT_SUCCESS;

	    if (finished)
		break;
	}

	dloop++;		/* increment loop counter */
    }

    return EXIT_SUCCESS;
}