Example #1
0
XCTRL_API void set_selection(Display*dpy, char kind, char *sel_buf, Bool utf8)
{
  Atom seltype=selarg_to_seltype(dpy,kind);
  long sel_len=strlen(sel_buf);
  if (seltype == XA_STRING) {
    XStoreBuffer(dpy, (char*)sel_buf, (int)sel_len, 0);
  } else {
    XEvent evt;
    Window win = make_selection_window(dpy);
    Atom target = utf8 ? XA_UTF8_STRING(dpy) : XA_STRING;
    /* FIXME: Should not use CurrentTime per ICCCM section 2.1 */
    XSetSelectionOwner(dpy, seltype, win, CurrentTime);
    while (1) {  /* wait for a SelectionRequest event */
      static uint clear = 0;
      static uint context = XCLIB_XCIN_NONE;
      static ulong sel_pos = 0;
      static Window cwin;
      static Atom pty;
      int finished;
      XNextEvent(dpy, &evt);
      finished = xcin(dpy, &cwin, evt, &pty, target, (uchar*)sel_buf, sel_len, &sel_pos, &context);
      if (evt.type == SelectionClear) { clear = 1; }
      if ((context == XCLIB_XCIN_NONE) && clear) { break; }
      if (finished) { break; }
    }
    XDestroyWindow(dpy,win);
  }
}
Example #2
0
int BC_Clipboard::to_clipboard(const char *data, long len, int clipboard_num)
{
//printf("BC_Clipboard::to_clipboard %d: %d '%*.*s'\n",clipboard_num,len,len,len,data);
	if(clipboard_num == BC_PRIMARY_SELECTION)
	{
		XStoreBuffer(out_display, data, len, clipboard_num);
		return 0;
	}

#ifdef SINGLE_THREAD
	BC_Display::lock_display("BC_Clipboard::to_clipboard");
#else
	XLockDisplay(out_display);
#endif

// Store in local buffer
	if(this->data[clipboard_num] && length[clipboard_num] != len + 1)
	{
		delete [] this->data[clipboard_num];
		this->data[clipboard_num] = 0;
	}

	if(!this->data[clipboard_num])
	{
		length[clipboard_num] = len;
		this->data[clipboard_num] = new char[len + 1];
		memcpy(this->data[clipboard_num], data, len);
		this->data[clipboard_num][len] = 0;
	}

	if(clipboard_num == PRIMARY_SELECTION)
	{
		XSetSelectionOwner(out_display, 
			primary, 
			out_win, 
			CurrentTime);
	}
	else
	if(clipboard_num == SECONDARY_SELECTION)
	{
		XSetSelectionOwner(out_display, 
			secondary, 
			out_win, 
			CurrentTime);
	}


	XFlush(out_display);


#ifdef SINGLE_THREAD
	BC_Display::unlock_display();
#else
	XUnlockDisplay(out_display);
#endif
	return 0;
}
Example #3
0
static int
SetOp(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv)
{
    Tk_Window tkwin = clientData;
    int buffer;
    char *string;
    int length;

    buffer = 0;
    if (objc == 4) {
	if (GetCutNumberFromObj(interp, objv[3], &buffer) != TCL_OK) {
	    return TCL_ERROR;
	}
    }
    string = Tcl_GetStringFromObj(objv[2],  &length);
    XStoreBuffer(Tk_Display(tkwin), string, length + 1, buffer);
    return TCL_OK;
}
Example #4
0
File: xcutsel.c Project: aosm/X11
static void 
StoreBuffer(Widget w, XtPointer client_data, Atom *selection, Atom *type, 
	    XtPointer value, unsigned long *length, int *format)
{

    if (*type == 0 || *type == XT_CONVERT_FAIL || *length == 0) {
#ifdef XKB
	XkbStdBell( XtDisplay(w), XtWindow(w), 0, XkbBI_MinorError );
#else
	XBell( XtDisplay(w), 0 );
#endif
	return;
    }

    XStoreBuffer( XtDisplay(w), (char*)value, (int)(*length),
		  options.buffer );
   
    XtFree(value);
}
Example #5
0
File: TextField.c Project: att/uwin
void EvtMouseTextField(struct XObj *xobj,XButtonEvent *EvtButton)
{
 unsigned int modif;
 int x1,x2,y1,y2,i;
 Window Win1,Win2;
 int PosCurs=0;
 int SizeBuf;
 char *str;
 int NewPos;
 Atom type;
 XEvent event;
 int ButPress=1;
 int format;
 unsigned long longueur,octets_restant;
 unsigned char *donnees=(unsigned char *)"";
 XRectangle rect;

 /* On deplace le curseur a la position de la souris */
 /* On recupere la position de la souris */
 /* We move the cursor at mouse position and we get the mouse position */
 switch (EvtButton->button)
 {
  case Button1:
    XQueryPointer(dpy,*xobj->ParentWin,&Win1,&Win2,&x1,&y1,&x2,&y2,&modif);
    x2=x2-xobj->x;
    PosCurs=0;
    while ((PosCurs<strlen(xobj->title+xobj->value3))&&
	   (x2>XTextWidth(xobj->xfont,xobj->title+xobj->value3,PosCurs)+8))
     PosCurs++;
    DrawPointTxt(xobj,xobj->TabColor[back]);
    xobj->value=PosCurs+xobj->value3;
    xobj->value2=PosCurs+xobj->value3;
    DrawPointTxt(xobj,xobj->TabColor[fore]);
    DrawTextField(xobj);

    while (ButPress)
    {
     XNextEvent(dpy, &event);
     switch (event.type)
     {
      case MotionNotify:
       XQueryPointer(dpy,*xobj->ParentWin,&Win1,&Win2,&x1,&y1,&x2,&y2,&modif);
       x2=x2-xobj->x;
       PosCurs=0;
       while ((PosCurs<strlen(xobj->title+xobj->value3))&&
	      (x2>XTextWidth(xobj->xfont,xobj->title+xobj->value3,PosCurs)+8))
     	PosCurs++;
       /* Limitation de la zone de dessin */
       /* limitation of the drawing zone */
       if (PosCurs>xobj->value2)
       {
        rect.x=XTextWidth(xobj->xfont,xobj->title+xobj->value3,xobj->value2);
        rect.y=0;
        rect.width=XTextWidth(xobj->xfont,xobj->title+xobj->value3,PosCurs+1)
	  -rect.x+1;
        rect.height=xobj->height;
        xobj->value2=PosCurs+xobj->value3;
        DrawTextField(xobj);
       }
       else
       if (PosCurs<xobj->value2)
       {
        rect.x=XTextWidth(xobj->xfont,xobj->title+xobj->value3,PosCurs)-1;
        rect.y=0;
        rect.width=XTextWidth(xobj->xfont,xobj->title+xobj->value3,
			      xobj->value2+1) - rect.x+2;
        rect.height=xobj->height;
        xobj->value2=PosCurs+xobj->value3;
        DrawTextField(xobj);
       }

      break;
      case ButtonRelease:
       ButPress=0;
      break;
     }
    }
    /* Enregistrement de la selection dans le presse papier */
    /* Le programme devient proprietaire de la selection */
    /* selection stuff: get the selection */
    if (xobj->value!=xobj->value2)
    {
     str=(char*)GetText(xobj,xobj->value2);
     for (i=0;i<=7;i++)
      XStoreBuffer(dpy,str,strlen(str),i);
     Scrapt=(char*)realloc((void*)Scrapt,(strlen(str)+2)*sizeof(char));
     Scrapt=strcpy(Scrapt,str);
     free(str);
     x11base->HaveXSelection=True;
     XSetSelectionOwner(dpy,XA_PRIMARY,x11base->win,EvtButton->time);
     SelectOneTextField(xobj);
    }
   break;

   case Button2:			/* Colle le texte */
     /* Si l'application possede pas la selection, elle la demande */
     /* sinon elle lit son presse papier */
     /* read the selection */
    if (!x11base->HaveXSelection)
    {
      /* Demande de la selection */
      /* ask for the selection */
     XConvertSelection(dpy,XA_PRIMARY,XA_STRING,propriete,*xobj->ParentWin,
    			EvtButton->time);
     while (!(XCheckTypedEvent(dpy,SelectionNotify,&event)))
      ;
     if (event.xselection.property!=None)
      if (event.xselection.selection==XA_PRIMARY)
      {
       XGetWindowProperty(dpy,event.xselection.requestor,
			  event.xselection.property,0,8192,False,
			  event.xselection.target,&type,&format,
			  &longueur,&octets_restant,&donnees);
       if (longueur>0)
       {
        Scrapt=(char*)realloc((void*)Scrapt,(longueur+1)*sizeof(char));
        Scrapt=strcpy(Scrapt,(char *)donnees);
        XDeleteProperty(dpy,event.xselection.requestor,
			event.xselection.property);
        XFree(donnees);
       }
      }
     }
    SizeBuf=strlen(Scrapt);
    if (SizeBuf>0)
    {
     NewPos=InsertText(xobj,Scrapt,SizeBuf);
     DrawPointTxt(xobj,xobj->TabColor[back]);
     xobj->value=NewPos;
     xobj->value2=NewPos;
     DrawPointTxt(xobj,xobj->TabColor[fore]);
     DrawTextField(xobj);
     SendMsg(xobj,SingleClic);
    }
    break;

   case Button3:		/* Appuie sur le troisieme bouton */
    XQueryPointer(dpy,*xobj->ParentWin,&Win1,&Win2,&x1,&y1,&x2,&y2,&modif);
    x2=x2-xobj->x;
    PosCurs=0;
    while ((PosCurs<strlen(xobj->title))&&
	   (x2>XTextWidth(xobj->xfont,xobj->title+xobj->value3,PosCurs)+8))
     PosCurs++;
    if ((PosCurs<xobj->value) && (xobj->value<xobj->value2))
      xobj->value=xobj->value2;
    if ((PosCurs>xobj->value) && (xobj->value>xobj->value2))
      xobj->value=xobj->value2;
    xobj->value2=PosCurs+xobj->value3;
    DrawTextField(xobj);

    while (ButPress)
    {
     XNextEvent(dpy, &event);
     switch (event.type)
     {
      case MotionNotify:
       XQueryPointer(dpy,*xobj->ParentWin,&Win1,&Win2,&x1,&y1,&x2,&y2,&modif);
       x2=x2-xobj->x;
       while ((PosCurs<strlen(xobj->title))&&
	      (x2>XTextWidth(xobj->xfont,xobj->title+xobj->value3,PosCurs)+8))
     	PosCurs++;
       if (PosCurs>xobj->value2)
       {
        rect.x=XTextWidth(xobj->xfont,xobj->title+xobj->value3,xobj->value2);
        rect.y=0;
        rect.width=XTextWidth(xobj->xfont,xobj->title+xobj->value3,PosCurs+1)
	  -rect.x+1;
        rect.height=xobj->height;
        xobj->value2=PosCurs;
        DrawTextField(xobj);
       }
       else
       if (PosCurs<xobj->value2)
       {
        rect.x=XTextWidth(xobj->xfont,xobj->title+xobj->value3,PosCurs)-1;
        rect.y=0;
        rect.width=XTextWidth(xobj->xfont,xobj->title+xobj->value3,
			      xobj->value2+1)-rect.x+2;
        rect.height=xobj->height;
        xobj->value2=PosCurs+xobj->value3;
        DrawTextField(xobj);
       }
       PosCurs=0;
      break;
      case ButtonRelease:
       ButPress=0;
      break;
     }
    }
    if (xobj->value!=xobj->value2)
    {
     str=(char*)GetText(xobj,xobj->value2);
     for (i=0;i<=7;i++)
      XStoreBuffer(dpy,str,strlen(str),i);
     Scrapt=(char*)realloc((void*)Scrapt,(strlen(str)+2)*sizeof(char));
     Scrapt=strcpy(Scrapt,str);
     free(str);
     x11base->HaveXSelection=True;
     XSetSelectionOwner(dpy,XA_PRIMARY,x11base->win,EvtButton->time);
    }
   break;
 }
}
Example #6
0
int main(int argc, char **argv)
{
	Display *dpy;
	int i;
	int buffer = -1;
	char *filename = NULL;
	FILE *file = stdin;
	char *buf = NULL;
	char *display_name = "";
	int l = 0;
	int buf_len = 0;
	int limit_check = 1;
	int clear_selection = 0;

	for (i = 1; i < argc; i++) {
		if (argv[i][0] == '-') {
			if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) {
				print_help();
				exit(0);
			} else if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--version") == 0) {
				printf("%s (Window Maker %s)\n", __progname, VERSION);
				exit(0);
			} else if (strcmp(argv[i], "-cutbuffer") == 0 || strcmp(argv[i], "--cutbuffer") == 0) {
				if (i < argc - 1) {
					i++;
					if (sscanf(argv[i], "%i", &buffer) != 1) {
						fprintf(stderr, "%s: could not convert '%s' to int\n",
							__progname, argv[i]);
						exit(1);
					}
					if (buffer < 0 || buffer > 7) {
						fprintf(stderr, "%s: invalid buffer number %i\n", __progname, buffer);
						exit(1);
					}
				} else {
					printf("%s: missing argument for '%s'\n", __progname, argv[i]);
					printf("Try '%s --help' for more information\n", __progname);
					exit(1);
				}
			} else if (strcmp(argv[i], "-display") == 0) {
				if (i < argc - 1) {
					display_name = argv[++i];
				} else {
					printf("%s: missing argument for '%s'\n", __progname, argv[i]);
					printf("Try '%s --help' for more information\n", __progname);
					exit(1);
				}
			} else if (strcmp(argv[i], "-clearselection") == 0
				   || strcmp(argv[i], "--clear-selection") == 0) {
				clear_selection = 1;
			} else if (strcmp(argv[i], "-nolimit") == 0 || strcmp(argv[i], "--no-limit") == 0) {
				limit_check = 0;
			} else {
				printf("%s: invalid argument '%s'\n", __progname, argv[i]);
				printf("Try '%s --help' for more information\n", __progname);
				exit(1);
			}
		} else {
			filename = argv[i];
		}
	}
	if (filename) {
		file = fopen(filename, "rb");
		if (!file) {
			char line[1024];
			sprintf(line, "%s: could not open \"%s\"", __progname, filename);
			perror(line);
			exit(1);
		}
	}

	dpy = XOpenDisplay(display_name);
	XSetErrorHandler(errorHandler);
	if (!dpy) {
		fprintf(stderr, "%s: could not open display \"%s\"\n", __progname, XDisplayName(display_name));
		exit(1);
	}

	if (buffer < 0) {
		Atom *rootWinProps;
		int exists[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
		int i, count;

		/* Create missing CUT_BUFFERs */
		rootWinProps = XListProperties(dpy, DefaultRootWindow(dpy), &count);
		for (i = 0; i < count; i++) {
			switch (rootWinProps[i]) {
			case XA_CUT_BUFFER0:
				exists[0] = 1;
				break;
			case XA_CUT_BUFFER1:
				exists[1] = 1;
				break;
			case XA_CUT_BUFFER2:
				exists[2] = 1;
				break;
			case XA_CUT_BUFFER3:
				exists[3] = 1;
				break;
			case XA_CUT_BUFFER4:
				exists[4] = 1;
				break;
			case XA_CUT_BUFFER5:
				exists[5] = 1;
				break;
			case XA_CUT_BUFFER6:
				exists[6] = 1;
				break;
			case XA_CUT_BUFFER7:
				exists[7] = 1;
				break;
			default:
				break;
			}
		}
		if (rootWinProps) {
			XFree(rootWinProps);
		}
		for (i = 0; i < 8; i++) {
			if (!exists[i]) {
				XStoreBuffer(dpy, "", 0, i);
			}
		}

		XRotateBuffers(dpy, 1);
		buffer = 0;
	}

	while (!feof(file)) {
		char *nbuf;
		char tmp[LINESIZE + 2];
		int nl = 0;

		/*
		 * Use read() instead of fgets() to preserve NULLs, since
		 * especially since there's no reason to read one line at a time.
		 */
		if ((nl = fread(tmp, 1, LINESIZE, file)) <= 0) {
			break;
		}
		if (buf_len == 0) {
			nbuf = malloc(buf_len = l + nl + 1);
		} else if (buf_len < l + nl + 1) {
			/*
			 * To avoid terrible performance on big input buffers,
			 * grow by doubling, not by the minimum needed for the
			 * current line.
			 */
			buf_len = 2 * buf_len + nl + 1;
			/* some realloc implementations don't do malloc if buf==NULL */
			if (buf == NULL) {
				nbuf = malloc(buf_len);
			} else {
				nbuf = realloc(buf, buf_len);
			}
		} else {
			nbuf = buf;
		}
		if (!nbuf) {
			fprintf(stderr, "%s: out of memory\n", __progname);
			exit(1);
		}
		buf = nbuf;
		/*
		 * Don't strcat, since it would make the algorithm n-squared.
		 * Don't use strcpy, since it stops on a NUL.
		 */
		memcpy(buf + l, tmp, nl);
		l += nl;
		if (limit_check && l >= MAXDATA) {
			fprintf
			    (stderr,
			     "%s: too much data in input - more than %d bytes\n"
			     "  use the -nolimit argument to remove the limit check.\n", __progname, MAXDATA);
			exit(1);
		}
	}

	if (clear_selection) {
		XSetSelectionOwner(dpy, XA_PRIMARY, None, CurrentTime);
	}
	if (buf) {
		XStoreBuffer(dpy, buf, l, buffer);
	}
	XFlush(dpy);
	XCloseDisplay(dpy);
	exit(buf == NULL || errno != 0);
}
Example #7
0
void EvtMouseTextField(struct XObj *xobj,XButtonEvent *EvtButton)
{
	unsigned int modif;
	int x1,x2,y1,y2,i;
	Window Win1,Win2;
	int PosCurs=0;
	int SizeBuf;
	char *str;
	int NewPos;
	Atom type;
	XEvent event;
	int ButPress=1;
	int format;
	unsigned long longueur,octets_restant;
	unsigned char *donnees=(unsigned char *)"";
	XRectangle rect;
	int start_pos, selection_pos, curs_pos;

	/* On deplace le curseur a la position de la souris */
	/* On recupere la position de la souris */
	/* We move the cursor at mouse position and we get the mouse position
	 */
	switch (EvtButton->button)
	{
	case Button1:
		FQueryPointer(
			dpy,*xobj->ParentWin,&Win1,&Win2,&x1,&y1,&x2,&y2,
			&modif);
		x2=x2-xobj->x;
		/* see where we clicked */
		PosCurs=0;
		/* byte position of first visible character */
		start_pos = getByteOffsetBoundsCheck(xobj->Ffont, xobj->title,
						     xobj->value3);
		/* cursor offset in bytes */
		curs_pos = 0;
		while ((curs_pos < strlen(xobj->title + start_pos)) &&
		       (x2 > FlocaleTextWidth(
				    xobj->Ffont,xobj->title + start_pos,
				    curs_pos) + 8))
		{
			curs_pos += FlocaleStringNumberOfBytes(
					  xobj->Ffont,
					  xobj->title + start_pos + curs_pos);
			PosCurs++;
		}
		DrawPointTxt(xobj,xobj->TabColor[back]);
		/* set selection start and end where clicked */
		/* first visible char + position clicked */
		xobj->value = PosCurs + xobj->value3;
		xobj->value2 = PosCurs + xobj->value3;
		/* byte offset corresponding to the above */
		start_pos = getByteOffsetBoundsCheck(xobj->Ffont, xobj->title,
						     xobj->value3);
		selection_pos = getByteOffsetBoundsCheck(xobj->Ffont,
							 xobj->title,
							 xobj->value3);
		DrawPointTxt(xobj,xobj->TabColor[fore]);
		DrawTextField(xobj,NULL);

		while (ButPress)
		{
			FNextEvent(dpy, &event);
			switch (event.type)
			{
			case MotionNotify:
				FQueryPointer(
					dpy,*xobj->ParentWin,&Win1,&Win2,&x1,
					&y1,&x2,&y2,&modif);
				x2=x2-xobj->x;
				PosCurs=0;
				curs_pos = 0;
				/* determine how far in the mouse is now */
				while ((curs_pos < strlen(
						xobj->title + start_pos)) &&
				       (x2 >
					FlocaleTextWidth(
						xobj->Ffont,xobj->title+
						start_pos, curs_pos) + 8))
				{
					curs_pos += FlocaleStringNumberOfBytes(
							   xobj->Ffont,
							   xobj->title +
							   start_pos +
							   curs_pos);
					PosCurs++;
				}
				/* Limitation de la zone de dessin */
				/* limitation of the drawing zone */
				/* these 2 if-statements updates current
				   cursor position of the widget if needed */
				if (PosCurs > (xobj->value2 - xobj->value3))
				{
					/* select made "forward" */
					rect.x=
						FlocaleTextWidth(
							xobj->Ffont,
							xobj->title+
							start_pos,
							selection_pos -
							start_pos);
					rect.y=0;
					rect.width=
						FlocaleTextWidth(
							xobj->Ffont,
							xobj->title+
							start_pos,
							curs_pos)
						-rect.x+1;
					rect.height=xobj->height;
					xobj->value2 = PosCurs + xobj->value3;
					DrawTextField(xobj,NULL);
				}
				else if (PosCurs <
					 (xobj->value2 - xobj->value3))
				{
					/* selection made "backwards" */
					rect.x=FlocaleTextWidth(
						xobj->Ffont,
						xobj->title+
						start_pos,
						curs_pos) - 1;
					rect.y=0;
					rect.width=FlocaleTextWidth(
						xobj->Ffont,
						xobj->title+
						start_pos,
						selection_pos - start_pos) -
						rect.x+2;
					rect.height=xobj->height;
					xobj->value2= PosCurs + xobj->value3;
					DrawTextField(xobj,NULL);
				}

				break;
			case ButtonRelease:
				ButPress=0;
				break;
			}
		}

		/* Enregistrement de la selection dans le presse papier */
		/* Le programme devient proprietaire de la selection */
		/* selection stuff: get the selection */
		if (xobj->value != xobj->value2)
		{
			str=(char*)GetText(xobj, xobj->value2);
			for (i=0;i<=7;i++)
				XStoreBuffer(dpy,str,strlen(str),i);
			Scrapt = (char*)realloc(
					(void*)Scrapt,
					(strlen(str)+2)*sizeof(char));
			Scrapt = strcpy(Scrapt,str);
			free(str);
			x11base->HaveXSelection=True;
			XSetSelectionOwner(
				dpy,XA_PRIMARY,x11base->win,EvtButton->time);
			SelectOneTextField(xobj);
		}
		break;

	case Button2:                        /* Colle le texte */
		/* Si l'application possede pas la selection, elle la demande
		 */
		/* sinon elle lit son presse papier */
		/* read the selection */
		if (!x11base->HaveXSelection)
		{
			/* Demande de la selection */
			/* ask for the selection */
			XConvertSelection(
				dpy,XA_PRIMARY,XA_STRING,propriete,
				*xobj->ParentWin, EvtButton->time);
			while (!(FCheckTypedEvent(dpy,SelectionNotify,&event)))
				;
			if (event.xselection.property!=None)
				if (event.xselection.selection==XA_PRIMARY)
				{
					XGetWindowProperty(
						dpy,event.xselection.requestor,
						event.xselection.property,0L,
						8192L,False,
						event.xselection.target,&type,
						&format, &longueur,
						&octets_restant,&donnees);
					if (longueur>0)
					{
						Scrapt=(char*)realloc(
							(void*)Scrapt,
							(longueur+1)*
							sizeof(char));
						Scrapt=strcpy(
							Scrapt,(char *)donnees);
						XDeleteProperty(
							dpy, event.xselection.
							requestor,
							event.xselection.
							property);
						XFree(donnees);
					}
				}
		}
		SizeBuf=strlen(Scrapt);
		if (SizeBuf>0)
		{
			NewPos=InsertText(xobj,Scrapt,SizeBuf);
			DrawPointTxt(xobj,xobj->TabColor[back]);
			xobj->value=NewPos;
			xobj->value2=NewPos;
			DrawPointTxt(xobj,xobj->TabColor[fore]);
			DrawTextField(xobj,NULL);
			SendMsg(xobj,SingleClic);
		}
		break;

	case Button3:                /* Appuie sur le troisieme bouton */
		FQueryPointer(
			dpy,*xobj->ParentWin,&Win1,&Win2,&x1,&y1,&x2,&y2,
			&modif);
		x2=x2-xobj->x;
		PosCurs=0;
		while ((PosCurs<strlen(xobj->title))&&
		       (x2>FlocaleTextWidth(
			       xobj->Ffont,xobj->title+xobj->value3,
			       PosCurs)+8))
			PosCurs++;
		if ((PosCurs<xobj->value) && (xobj->value<xobj->value2))
			xobj->value=xobj->value2;
		if ((PosCurs>xobj->value) && (xobj->value>xobj->value2))
			xobj->value=xobj->value2;
		xobj->value2=PosCurs+xobj->value3;
		DrawTextField(xobj,NULL);

		while (ButPress)
		{
			FNextEvent(dpy, &event);
			switch (event.type)
			{
			case MotionNotify:
				FQueryPointer(
					dpy,*xobj->ParentWin,&Win1,&Win2,&x1,
					&y1,&x2,&y2,&modif);
				x2=x2-xobj->x;
				while ((PosCurs<strlen(xobj->title))&&
				       (x2 >
					FlocaleTextWidth(
						xobj->Ffont,
						xobj->title+xobj->value3,
						PosCurs)+8))
					PosCurs++;
				if (PosCurs>xobj->value2)
				{
					rect.x=
						FlocaleTextWidth(
							xobj->Ffont,
							xobj->title+
							xobj->value3,
							xobj->value2);
					rect.y=0;
					rect.width=
						FlocaleTextWidth(
							xobj->Ffont,
							xobj->title+
							xobj->value3,PosCurs+1)
						-rect.x+1;
					rect.height=xobj->height;
					xobj->value2=PosCurs;
					DrawTextField(xobj,NULL);
				}
				else
					if (PosCurs<xobj->value2)
					{
						rect.x=FlocaleTextWidth(
							xobj->Ffont,
							xobj->title+
							xobj->value3,
							PosCurs)-1;
						rect.y=0;
						rect.width=FlocaleTextWidth(
							xobj->Ffont,
							xobj->title+xobj->
							value3,
							xobj->value2+1)-
							rect.x+2;
						rect.height=xobj->height;
						xobj->value2=
							PosCurs+xobj->value3;
						DrawTextField(xobj,NULL);
					}
				PosCurs=0;
				break;
			case ButtonRelease:
				ButPress=0;
				break;
			}
		}
		if (xobj->value!=xobj->value2)
		{
			str=(char*)GetText(xobj,xobj->value2);
			for (i=0;i<=7;i++)
				XStoreBuffer(dpy,str,strlen(str),i);
			Scrapt=(char*)realloc(
				(void*)Scrapt,(strlen(str)+2)*sizeof(char));
			Scrapt=strcpy(Scrapt,str);
			free(str);
			x11base->HaveXSelection=True;
			XSetSelectionOwner(
				dpy,XA_PRIMARY,x11base->win,EvtButton->time);
		}
		break;
	}
}
Example #8
0
WMScreen *WMCreateScreenWithRContext(Display * display, int screen, RContext * context)
{
	W_Screen *scrPtr;
	XGCValues gcv;
	Pixmap stipple;
	static int initialized = 0;
	static char *atomNames[] = {
		"_GNUSTEP_WM_ATTR",
		"WM_DELETE_WINDOW",
		"WM_PROTOCOLS",
		"CLIPBOARD",
		"XdndAware",
		"XdndSelection",
		"XdndEnter",
		"XdndLeave",
		"XdndPosition",
		"XdndDrop",
		"XdndFinished",
		"XdndTypeList",
		"XdndActionList",
		"XdndActionDescription",
		"XdndStatus",
		"XdndActionCopy",
		"XdndActionMove",
		"XdndActionLink",
		"XdndActionAsk",
		"XdndActionPrivate",
		"_WINGS_DND_MOUSE_OFFSET",
		"WM_STATE",
		"UTF8_STRING",
		"_NET_WM_NAME",
		"_NET_WM_ICON_NAME",
		"_NET_WM_ICON",
	};
	Atom atoms[wlengthof(atomNames)];
	int i;

	if (!initialized) {

		initialized = 1;

		W_ReadConfigurations();

		assert(W_ApplicationInitialized());
	}

	scrPtr = malloc(sizeof(W_Screen));
	if (!scrPtr)
		return NULL;
	memset(scrPtr, 0, sizeof(W_Screen));

	scrPtr->aflags.hasAppIcon = 1;

	scrPtr->display = display;
	scrPtr->screen = screen;
	scrPtr->rcontext = context;

	scrPtr->depth = context->depth;

	scrPtr->visual = context->visual;
	scrPtr->lastEventTime = 0;

	scrPtr->colormap = context->cmap;

	scrPtr->rootWin = RootWindow(display, screen);

	scrPtr->fontCache = WMCreateHashTable(WMStringPointerHashCallbacks);

	scrPtr->xftdraw = XftDrawCreate(scrPtr->display, W_DRAWABLE(scrPtr), scrPtr->visual, scrPtr->colormap);

	/* Create missing CUT_BUFFERs */
	{
		Atom *rootWinProps;
		int exists[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
		int count;

		rootWinProps = XListProperties(display, scrPtr->rootWin, &count);
		for (i = 0; i < count; i++) {
			switch (rootWinProps[i]) {
			case XA_CUT_BUFFER0:
				exists[0] = 1;
				break;
			case XA_CUT_BUFFER1:
				exists[1] = 1;
				break;
			case XA_CUT_BUFFER2:
				exists[2] = 1;
				break;
			case XA_CUT_BUFFER3:
				exists[3] = 1;
				break;
			case XA_CUT_BUFFER4:
				exists[4] = 1;
				break;
			case XA_CUT_BUFFER5:
				exists[5] = 1;
				break;
			case XA_CUT_BUFFER6:
				exists[6] = 1;
				break;
			case XA_CUT_BUFFER7:
				exists[7] = 1;
				break;
			default:
				break;
			}
		}
		if (rootWinProps) {
			XFree(rootWinProps);
		}
		for (i = 0; i < 8; i++) {
			if (!exists[i]) {
				XStoreBuffer(display, "", 0, i);
			}
		}
	}

	scrPtr->ignoredModifierMask = 0;
	{
		int i;
		XModifierKeymap *modmap;
		KeyCode nlock, slock;
		static int mask_table[8] = {
			ShiftMask, LockMask, ControlMask, Mod1Mask,
			Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask
		};
		unsigned int numLockMask = 0, scrollLockMask = 0;

		nlock = XKeysymToKeycode(display, XK_Num_Lock);
		slock = XKeysymToKeycode(display, XK_Scroll_Lock);

		/*
		 * Find out the masks for the NumLock and ScrollLock modifiers,
		 * so that we can bind the grabs for when they are enabled too.
		 */
		modmap = XGetModifierMapping(display);

		if (modmap != NULL && modmap->max_keypermod > 0) {
			for (i = 0; i < 8 * modmap->max_keypermod; i++) {
				if (modmap->modifiermap[i] == nlock && nlock != 0)
					numLockMask = mask_table[i / modmap->max_keypermod];
				else if (modmap->modifiermap[i] == slock && slock != 0)
					scrollLockMask = mask_table[i / modmap->max_keypermod];
			}
		}

		if (modmap)
			XFreeModifiermap(modmap);

		scrPtr->ignoredModifierMask = numLockMask | scrollLockMask | LockMask;
	}

	/* initially allocate some colors */
	WMWhiteColor(scrPtr);
	WMBlackColor(scrPtr);
	WMGrayColor(scrPtr);
	WMDarkGrayColor(scrPtr);

	gcv.graphics_exposures = False;

	gcv.function = GXxor;
	gcv.foreground = W_PIXEL(scrPtr->white);
	if (gcv.foreground == 0)
		gcv.foreground = 1;
	scrPtr->xorGC = XCreateGC(display, W_DRAWABLE(scrPtr), GCFunction
				  | GCGraphicsExposures | GCForeground, &gcv);

	gcv.function = GXxor;
	gcv.foreground = W_PIXEL(scrPtr->gray);
	gcv.subwindow_mode = IncludeInferiors;
	scrPtr->ixorGC = XCreateGC(display, W_DRAWABLE(scrPtr), GCFunction
				   | GCGraphicsExposures | GCForeground | GCSubwindowMode, &gcv);

	gcv.function = GXcopy;
	scrPtr->copyGC = XCreateGC(display, W_DRAWABLE(scrPtr), GCFunction | GCGraphicsExposures, &gcv);

	scrPtr->clipGC = XCreateGC(display, W_DRAWABLE(scrPtr), GCFunction | GCGraphicsExposures, &gcv);

	stipple = XCreateBitmapFromData(display, W_DRAWABLE(scrPtr), STIPPLE_BITS, STIPPLE_WIDTH, STIPPLE_HEIGHT);
	gcv.foreground = W_PIXEL(scrPtr->darkGray);
	gcv.background = W_PIXEL(scrPtr->gray);
	gcv.fill_style = FillStippled;
	gcv.stipple = stipple;
	scrPtr->stippleGC = XCreateGC(display, W_DRAWABLE(scrPtr),
				      GCForeground | GCBackground | GCStipple
				      | GCFillStyle | GCGraphicsExposures, &gcv);

	scrPtr->drawStringGC = XCreateGC(display, W_DRAWABLE(scrPtr), GCGraphicsExposures, &gcv);
	scrPtr->drawImStringGC = XCreateGC(display, W_DRAWABLE(scrPtr), GCGraphicsExposures, &gcv);

	/* we need a 1bpp drawable for the monoGC, so borrow this one */
	scrPtr->monoGC = XCreateGC(display, stipple, 0, NULL);

	scrPtr->stipple = stipple;

	scrPtr->antialiasedText = WINGsConfiguration.antialiasedText;

	scrPtr->normalFont = WMSystemFontOfSize(scrPtr, 0);

	scrPtr->boldFont = WMBoldSystemFontOfSize(scrPtr, 0);

	if (!scrPtr->boldFont)
		scrPtr->boldFont = scrPtr->normalFont;

	if (!scrPtr->normalFont) {
		wwarning(_("could not load any fonts. Make sure your font installation"
			   " and locale settings are correct."));

		return NULL;
	}

	/* create input method stuff */
	W_InitIM(scrPtr);

	scrPtr->checkButtonImageOn = makePixmap(scrPtr, CHECK_BUTTON_ON,
						CHECK_BUTTON_ON_WIDTH, CHECK_BUTTON_ON_HEIGHT, False);

	scrPtr->checkButtonImageOff = makePixmap(scrPtr, CHECK_BUTTON_OFF,
						 CHECK_BUTTON_OFF_WIDTH, CHECK_BUTTON_OFF_HEIGHT, False);

	scrPtr->radioButtonImageOn = makePixmap(scrPtr, RADIO_BUTTON_ON,
						RADIO_BUTTON_ON_WIDTH, RADIO_BUTTON_ON_HEIGHT, False);

	scrPtr->radioButtonImageOff = makePixmap(scrPtr, RADIO_BUTTON_OFF,
						 RADIO_BUTTON_OFF_WIDTH, RADIO_BUTTON_OFF_HEIGHT, False);

	scrPtr->tristateButtonImageOn = makePixmap(scrPtr, TRISTATE_BUTTON_ON,
	                                           TRISTATE_BUTTON_ON_WIDTH, TRISTATE_BUTTON_ON_HEIGHT, False);

	scrPtr->tristateButtonImageOff = makePixmap(scrPtr, TRISTATE_BUTTON_OFF,
	                                            TRISTATE_BUTTON_OFF_WIDTH, TRISTATE_BUTTON_OFF_HEIGHT, False);

	scrPtr->tristateButtonImageTri = makePixmap(scrPtr, TRISTATE_BUTTON_TRI,
	                                            TRISTATE_BUTTON_TRI_WIDTH, TRISTATE_BUTTON_TRI_HEIGHT, False);

	scrPtr->buttonArrow = makePixmap(scrPtr, BUTTON_ARROW, BUTTON_ARROW_WIDTH, BUTTON_ARROW_HEIGHT, False);

	scrPtr->pushedButtonArrow = makePixmap(scrPtr, BUTTON_ARROW2,
					       BUTTON_ARROW2_WIDTH, BUTTON_ARROW2_HEIGHT, False);

	scrPtr->scrollerDimple = makePixmap(scrPtr, SCROLLER_DIMPLE,
					    SCROLLER_DIMPLE_WIDTH, SCROLLER_DIMPLE_HEIGHT, False);

	scrPtr->upArrow = makePixmap(scrPtr, SCROLLER_ARROW_UP,
				     SCROLLER_ARROW_UP_WIDTH, SCROLLER_ARROW_UP_HEIGHT, True);

	scrPtr->downArrow = makePixmap(scrPtr, SCROLLER_ARROW_DOWN,
				       SCROLLER_ARROW_DOWN_WIDTH, SCROLLER_ARROW_DOWN_HEIGHT, True);

	scrPtr->leftArrow = makePixmap(scrPtr, SCROLLER_ARROW_LEFT,
				       SCROLLER_ARROW_LEFT_WIDTH, SCROLLER_ARROW_LEFT_HEIGHT, True);

	scrPtr->rightArrow = makePixmap(scrPtr, SCROLLER_ARROW_RIGHT,
					SCROLLER_ARROW_RIGHT_WIDTH, SCROLLER_ARROW_RIGHT_HEIGHT, True);

	scrPtr->hiUpArrow = makePixmap(scrPtr, HI_SCROLLER_ARROW_UP,
				       SCROLLER_ARROW_UP_WIDTH, SCROLLER_ARROW_UP_HEIGHT, True);

	scrPtr->hiDownArrow = makePixmap(scrPtr, HI_SCROLLER_ARROW_DOWN,
					 SCROLLER_ARROW_DOWN_WIDTH, SCROLLER_ARROW_DOWN_HEIGHT, True);

	scrPtr->hiLeftArrow = makePixmap(scrPtr, HI_SCROLLER_ARROW_LEFT,
					 SCROLLER_ARROW_LEFT_WIDTH, SCROLLER_ARROW_LEFT_HEIGHT, True);

	scrPtr->hiRightArrow = makePixmap(scrPtr, HI_SCROLLER_ARROW_RIGHT,
					  SCROLLER_ARROW_RIGHT_WIDTH, SCROLLER_ARROW_RIGHT_HEIGHT, True);

	scrPtr->popUpIndicator = makePixmap(scrPtr, POPUP_INDICATOR,
					    POPUP_INDICATOR_WIDTH, POPUP_INDICATOR_HEIGHT, True);

	scrPtr->pullDownIndicator = makePixmap(scrPtr, PULLDOWN_INDICATOR,
					       PULLDOWN_INDICATOR_WIDTH, PULLDOWN_INDICATOR_HEIGHT, True);

	scrPtr->checkMark = makePixmap(scrPtr, CHECK_MARK, CHECK_MARK_WIDTH, CHECK_MARK_HEIGHT, True);

	loadPixmaps(scrPtr);

	scrPtr->defaultCursor = XCreateFontCursor(display, XC_left_ptr);

	scrPtr->textCursor = XCreateFontCursor(display, XC_xterm);

	{
		XColor bla;
		Pixmap blank;

		blank = XCreatePixmap(display, scrPtr->stipple, 1, 1, 1);
		XSetForeground(display, scrPtr->monoGC, 0);
		XFillRectangle(display, blank, scrPtr->monoGC, 0, 0, 1, 1);

		scrPtr->invisibleCursor = XCreatePixmapCursor(display, blank, blank, &bla, &bla, 0, 0);
		XFreePixmap(display, blank);
	}

#ifdef HAVE_XINTERNATOMS
	XInternAtoms(display, atomNames, wlengthof(atomNames), False, atoms);
#else
	for (i = 0; i < wlengthof(atomNames); i++) {
		atoms[i] = XInternAtom(display, atomNames[i], False);
	}
#endif

	i = 0;
	scrPtr->attribsAtom = atoms[i++];

	scrPtr->deleteWindowAtom = atoms[i++];

	scrPtr->protocolsAtom = atoms[i++];

	scrPtr->clipboardAtom = atoms[i++];

	scrPtr->xdndAwareAtom = atoms[i++];
	scrPtr->xdndSelectionAtom = atoms[i++];
	scrPtr->xdndEnterAtom = atoms[i++];
	scrPtr->xdndLeaveAtom = atoms[i++];
	scrPtr->xdndPositionAtom = atoms[i++];
	scrPtr->xdndDropAtom = atoms[i++];
	scrPtr->xdndFinishedAtom = atoms[i++];
	scrPtr->xdndTypeListAtom = atoms[i++];
	scrPtr->xdndActionListAtom = atoms[i++];
	scrPtr->xdndActionDescriptionAtom = atoms[i++];
	scrPtr->xdndStatusAtom = atoms[i++];

	scrPtr->xdndActionCopy = atoms[i++];
	scrPtr->xdndActionMove = atoms[i++];
	scrPtr->xdndActionLink = atoms[i++];
	scrPtr->xdndActionAsk = atoms[i++];
	scrPtr->xdndActionPrivate = atoms[i++];

	scrPtr->wmIconDragOffsetAtom = atoms[i++];

	scrPtr->wmStateAtom = atoms[i++];

	scrPtr->utf8String = atoms[i++];
	scrPtr->netwmName = atoms[i++];
	scrPtr->netwmIconName = atoms[i++];
	scrPtr->netwmIcon = atoms[i++];

	scrPtr->rootView = W_CreateRootView(scrPtr);

	scrPtr->balloon = W_CreateBalloon(scrPtr);

	W_InitApplication(scrPtr);

	return scrPtr;
}
Example #9
0
static void handleTextFieldActionEvents(XEvent * event, void *data)
{
	TextField *tPtr = (TextField *) data;
	static Time lastButtonReleasedEvent = 0;
	static Time lastButtonReleasedEvent2 = 0;
	Display *dpy = event->xany.display;

	CHECK_CLASS(data, WC_TextField);

	switch (event->type) {
	case KeyPress:
		if (tPtr->flags.waitingSelection) {
			return;
		}
		if (tPtr->flags.enabled && tPtr->flags.focused) {
			handleTextFieldKeyPress(tPtr, event);
			XDefineCursor(dpy, W_VIEW(tPtr)->window, W_VIEW(tPtr)->screen->invisibleCursor);
			tPtr->flags.pointerGrabbed = 1;
		}
		break;

	case MotionNotify:

		if (tPtr->flags.pointerGrabbed) {
			tPtr->flags.pointerGrabbed = 0;
			XDefineCursor(dpy, W_VIEW(tPtr)->window, W_VIEW(tPtr)->screen->textCursor);
		}
		if (tPtr->flags.waitingSelection) {
			return;
		}

		if (tPtr->flags.enabled && (event->xmotion.state & Button1Mask)) {

			if (tPtr->viewPosition < tPtr->textLen && event->xmotion.x > tPtr->usableWidth) {
				if (WMWidthOfString(tPtr->font,
						    &(tPtr->text[tPtr->viewPosition]),
						    tPtr->cursorPosition - tPtr->viewPosition)
				    > tPtr->usableWidth) {
					tPtr->viewPosition += oneUTF8CharForward(&tPtr->text[tPtr->viewPosition],
										 tPtr->textLen -
										 tPtr->viewPosition);
				}
			} else if (tPtr->viewPosition > 0 && event->xmotion.x < 0) {
				paintCursor(tPtr);
				tPtr->viewPosition += oneUTF8CharBackward(&tPtr->text[tPtr->viewPosition],
									  tPtr->viewPosition);
			}

			tPtr->cursorPosition = pointToCursorPosition(tPtr, event->xmotion.x);

			/* Do not allow text selection in secure textfields */
			if (tPtr->flags.secure) {
				tPtr->selection.position = tPtr->cursorPosition;
			}

			tPtr->selection.count = tPtr->cursorPosition - tPtr->selection.position;

			paintCursor(tPtr);
			paintTextField(tPtr);

		}
		break;

	case ButtonPress:
		if (tPtr->flags.pointerGrabbed) {
			tPtr->flags.pointerGrabbed = 0;
			XDefineCursor(dpy, W_VIEW(tPtr)->window, W_VIEW(tPtr)->screen->textCursor);
			break;
		}

		if (tPtr->flags.waitingSelection) {
			break;
		}

		switch (tPtr->flags.alignment) {
			int textWidth;
		case WARight:
			textWidth = WMWidthOfString(tPtr->font, tPtr->text, tPtr->textLen);
			if (tPtr->flags.enabled && !tPtr->flags.focused) {
				WMSetFocusToWidget(tPtr);
			}
			if (tPtr->flags.focused) {
				tPtr->selection.position = tPtr->cursorPosition;
				tPtr->selection.count = 0;
			}
			if (textWidth < tPtr->usableWidth) {
				tPtr->cursorPosition = pointToCursorPosition(tPtr,
									     event->xbutton.x - tPtr->usableWidth
									     + textWidth);
			} else
				tPtr->cursorPosition = pointToCursorPosition(tPtr, event->xbutton.x);

			paintTextField(tPtr);
			break;

		case WALeft:
			if (tPtr->flags.enabled && !tPtr->flags.focused) {
				WMSetFocusToWidget(tPtr);
			}
			if (tPtr->flags.focused && event->xbutton.button == Button1) {
				tPtr->cursorPosition = pointToCursorPosition(tPtr, event->xbutton.x);
				tPtr->selection.position = tPtr->cursorPosition;
				tPtr->selection.count = 0;
				paintTextField(tPtr);
			}
			if (event->xbutton.button == Button2 && tPtr->flags.enabled) {
				char *text;
				int n;

				if (!WMRequestSelection(tPtr->view, XA_PRIMARY, XA_STRING,
							event->xbutton.time, pasteText, NULL)) {
					text = XFetchBuffer(tPtr->view->screen->display, &n, 0);

					if (text) {
						text[n] = 0;
						WMInsertTextFieldText(tPtr, text, tPtr->cursorPosition);
						XFree(text);
						NOTIFY(tPtr, didChange, WMTextDidChangeNotification,
						       (void *)WMInsertTextEvent);
					}
				} else {
					tPtr->flags.waitingSelection = 1;
				}
			}
			break;
		default:
			break;
		}
		break;

	case ButtonRelease:
		if (tPtr->flags.pointerGrabbed) {
			tPtr->flags.pointerGrabbed = 0;
			XDefineCursor(dpy, W_VIEW(tPtr)->window, W_VIEW(tPtr)->screen->textCursor);
		}
		if (tPtr->flags.waitingSelection) {
			break;
		}

		if (!tPtr->flags.secure && tPtr->selection.count != 0) {
			int start, count;
			XRotateBuffers(dpy, 1);

			count = abs(tPtr->selection.count);
			if (tPtr->selection.count < 0)
				start = tPtr->selection.position - count;
			else
				start = tPtr->selection.position;

			XStoreBuffer(dpy, &tPtr->text[start], count, 0);
		}

		if (!tPtr->flags.secure &&
		    event->xbutton.time - lastButtonReleasedEvent <= WINGsConfiguration.doubleClickDelay) {

			if (event->xbutton.time - lastButtonReleasedEvent2 <=
			    2 * WINGsConfiguration.doubleClickDelay) {
				tPtr->selection.position = 0;
				tPtr->selection.count = tPtr->textLen;
			} else {
				int pos, cnt;
				char *txt;
				pos = tPtr->selection.position;
				cnt = tPtr->selection.count;
				txt = tPtr->text;
				while (pos >= 0) {
					if (txt[pos] == ' ' || txt[pos] == '\t')
						break;
					pos--;
				}
				pos++;

				while (pos + cnt < tPtr->textLen) {
					if (txt[pos + cnt] == ' ' || txt[pos + cnt] == '\t')
						break;
					cnt++;
				}
				tPtr->selection.position = pos;
				tPtr->selection.count = cnt;
			}
			paintTextField(tPtr);

			if (!tPtr->flags.ownsSelection) {
				tPtr->flags.ownsSelection =
				    WMCreateSelectionHandler(tPtr->view,
							     XA_PRIMARY,
							     event->xbutton.time, &selectionHandler, NULL);
			}
		} else if (!tPtr->flags.secure && tPtr->selection.count != 0 && !tPtr->flags.ownsSelection) {
			tPtr->flags.ownsSelection =
			    WMCreateSelectionHandler(tPtr->view,
						     XA_PRIMARY, event->xbutton.time, &selectionHandler, NULL);
		}

		lastButtonReleasedEvent2 = lastButtonReleasedEvent;
		lastButtonReleasedEvent = event->xbutton.time;

		break;
	}
}
Example #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;
}