示例#1
0
文件: xutil.c 项目: astrotycoon/grace
int x11_init(GraceApp *gapp)
{
    X11Stuff *xstuff = gapp->gui->xstuff;
    XGCValues gc_val;
    long mrsize;
    int max_path_limit;
    
    xstuff->screennumber = DefaultScreen(xstuff->disp);
    xstuff->root = RootWindow(xstuff->disp, xstuff->screennumber);
 
    xstuff->gc = DefaultGC(xstuff->disp, xstuff->screennumber);
    
    xstuff->depth = DisplayPlanes(xstuff->disp, xstuff->screennumber);

    /* init colormap */
    xstuff->cmap = DefaultColormap(xstuff->disp, xstuff->screennumber);
    /* redefine colormap, if needed */
    if (gapp->gui->install_cmap == CMAP_INSTALL_ALWAYS) {
        xstuff->cmap = XCopyColormapAndFree(xstuff->disp, xstuff->cmap);
        gapp->gui->private_cmap = TRUE;
    }
    
    /* set GCs */
    if (gapp->gui->invert) {
        gc_val.function = GXinvert;
    } else {
        gc_val.function = GXxor;
    }
    gcxor = XCreateGC(xstuff->disp, xstuff->root, GCFunction, &gc_val);

    /* XExtendedMaxRequestSize() appeared in X11R6 */
#if XlibSpecificationRelease > 5
    mrsize = XExtendedMaxRequestSize(xstuff->disp);
#else
    mrsize = 0;
#endif
    if (mrsize <= 0) {
        mrsize = XMaxRequestSize(xstuff->disp);
    }
    max_path_limit = (mrsize - 3)/2;
    if (max_path_limit < get_max_path_limit(grace_get_canvas(gapp->grace))) {
        char buf[128];
        sprintf(buf,
            "Setting max drawing path length to %d (limited by the X server)",
            max_path_limit);
        errmsg(buf);
        set_max_path_limit(grace_get_canvas(gapp->grace), max_path_limit);
    }
    
    xstuff->dpi = rint(MM_PER_INCH*DisplayWidth(xstuff->disp, xstuff->screennumber)/
        DisplayWidthMM(xstuff->disp, xstuff->screennumber));

    return RETURN_SUCCESS;
}
示例#2
0
static void handleSelectionRequest(XSelectionRequestEvent ev) {
    static long chunk_size;
    static Atom targets;
    int sel_len = 0;
    int x, y;
    unsigned char *dst = cutBuffer;

    XEvent res;

    sortSelectionCorners();
    //printf("cx1=%d\n", cx1);
    for (y = cy1; y <= cy2; y++) {
        for (x = cx1; x <= cx2; x++) {
            *dst++ = bws[y * selected_model->text_width + x];
            sel_len++;
        }
        *dst++ = 0x0a;
        sel_len++;
    }

    if (!targets) {
        targets = XInternAtom(display, "TARGETS", False);
    }
    if (!chunk_size) {
        chunk_size = XExtendedMaxRequestSize(display) / 4;
        if (!chunk_size) {
            chunk_size = XMaxRequestSize(display) / 4;
        }
    }
    sel_len = sel_len > chunk_size ? chunk_size : sel_len;

    XChangeProperty(display, ev.requestor, ev.property, XA_STRING, 8,
    PropModeReplace, cutBuffer, sel_len);

    res.xselection.property = ev.property;
    res.xselection.type = SelectionNotify;
    res.xselection.display = ev.display;
    res.xselection.requestor = ev.requestor;
    res.xselection.selection = ev.selection;
    res.xselection.target = ev.target;
    res.xselection.time = ev.time;

    XSendEvent(display, ev.requestor, 0, 0, &res);
    XFlush(display);
}
示例#3
0
/* put data into a selection, in response to a SelecionRequest event from
 * another window (and any subsequent events relating to an INCR transfer).
 *
 * Arguments are:
 *
 * A display
 * 
 * A window
 * 
 * The event to respond to
 * 
 * A pointer to an Atom. This gets set to the property nominated by the other
 * app in it's SelectionRequest. Things are likely to break if you change the
 * value of this yourself.
 * 
 * The target(UTF8_STRING or XA_STRING) to respond to
 *
 * A pointer to an array of chars to read selection data from.
 * 
 * The length of the array of chars.
 *
 * In the case of an INCR transfer, the position within the array of chars
 * that is being processed.
 *
 * The context that event is the be processed within.
 */
int
xcin(Display * dpy,
     Window * win,
     XEvent evt,
     Atom * pty, Atom target, unsigned char *txt, unsigned long len, unsigned long *pos,
     unsigned int *context)
{
    unsigned long chunk_len;	/* length of current chunk (for incr
				 * transfers only)
				 */
    XEvent res;			/* response to event */
    static Atom inc;
    static Atom targets;
    static long chunk_size;

    if (!targets) {
	targets = XInternAtom(dpy, "TARGETS", False);
    }

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

    /* We consider selections larger than a quarter of the maximum
       request size to be "large". See ICCCM section 2.5 */
    if (!chunk_size) {
	chunk_size = XExtendedMaxRequestSize(dpy) / 4;
	if (!chunk_size) {
	    chunk_size = XMaxRequestSize(dpy) / 4;
	}
    }

    switch (*context) {
    case XCLIB_XCIN_NONE:
	if (evt.type != SelectionRequest)
	    return (0);

	/* set the window and property that is being used */
	*win = evt.xselectionrequest.requestor;
	*pty = evt.xselectionrequest.property;

	/* reset position to 0 */
	*pos = 0;

	/* put the data into an property */
	if (evt.xselectionrequest.target == targets) {
	    Atom types[2] = { targets, target };

	    /* send data all at once (not using INCR) */
	    XChangeProperty(dpy,
			    *win,
			    *pty,
			    XA_ATOM,
			    32, PropModeReplace, (unsigned char *) types,
			    (int) (sizeof(types) / sizeof(Atom))
		);
	}
	else if (len > chunk_size) {
	    /* send INCR response */
	    XChangeProperty(dpy, *win, *pty, inc, 32, PropModeReplace, 0, 0);

	    /* With the INCR mechanism, we need to know
	     * when the requestor window changes (deletes)
	     * its properties
	     */
	    XSelectInput(dpy, *win, PropertyChangeMask);

	    *context = XCLIB_XCIN_INCR;
	}
	else {
	    /* send data all at once (not using INCR) */
	    XChangeProperty(dpy,
			    *win,
			    *pty, target, 8, PropModeReplace, (unsigned char *) txt, (int) len);
	}

	/* Perhaps FIXME: According to ICCCM section 2.5, we should
	   confirm that XChangeProperty succeeded without any Alloc
	   errors before replying with SelectionNotify. However, doing
	   so would require an error handler which modifies a global
	   variable, plus doing XSync after each XChangeProperty. */

	/* set values for the response event */
	res.xselection.property = *pty;
	res.xselection.type = SelectionNotify;
	res.xselection.display = evt.xselectionrequest.display;
	res.xselection.requestor = *win;
	res.xselection.selection = evt.xselectionrequest.selection;
	res.xselection.target = evt.xselectionrequest.target;
	res.xselection.time = evt.xselectionrequest.time;

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

	/* if len < chunk_size, then the data was sent all at
	 * once and the transfer is now complete, return 1
	 */
	if (len > chunk_size)
	    return (0);
	else
	    return (1);

	break;

    case XCLIB_XCIN_INCR:
	/* length of current chunk */

	/* ignore non-property events */
	if (evt.type != PropertyNotify)
	    return (0);

	/* ignore the event unless it's to report that the
	 * property has been deleted
	 */
	if (evt.xproperty.state != PropertyDelete)
	    return (0);

	/* set the chunk length to the maximum size */
	chunk_len = chunk_size;

	/* if a chunk length of maximum size would extend
	 * beyond the end ot txt, set the length to be the
	 * remaining length of txt
	 */
	if ((*pos + chunk_len) > len)
	    chunk_len = len - *pos;

	/* if the start of the chunk is beyond the end of txt,
	 * then we've already sent all the data, so set the
	 * length to be zero
	 */
	if (*pos > len)
	    chunk_len = 0;

	if (chunk_len) {
	    /* put the chunk into the property */
	    XChangeProperty(dpy,
			    *win, *pty, target, 8, PropModeReplace, &txt[*pos], (int) chunk_len);
	}
	else {
	    /* make an empty property to show we've
	     * finished the transfer
	     */
	    XChangeProperty(dpy, *win, *pty, target, 8, PropModeReplace, 0, 0);
	}
	XFlush(dpy);

	/* all data has been sent, break out of the loop */
	if (!chunk_len)
	    *context = XCLIB_XCIN_NONE;

	*pos += chunk_size;

	/* if chunk_len == 0, we just finished the transfer,
	 * return 1
	 */
	if (chunk_len > 0)
	    return (0);
	else
	    return (1);
	break;
    }
    return (0);
}
示例#4
0
文件: xctrl.c 项目: ld-test/xctrl
/* Put data into a selection, in response to a SelecionRequest event from
 * another window (and any subsequent events relating to an INCR transfer).
 *
 * Arguments are:
 *   A display
 *   A window
 *   The event to respond to
 *   A pointer to an Atom. This gets set to the property nominated by the other
 *     app in it's SelectionRequest. Things are likely to break if you change the
 *     value of this yourself.
 *   The target (UTF8_STRING or XA_STRING) to respond to
 *   A pointer to an array of chars to read selection data from.
 *   The length of the array of chars.
 *   In case of an INCR transfer, the position within the array of chars that's being processed.
 *   The context that event is the be processed within.
 */
static int xcin( Display*dpy, Window*win, XEvent evt, Atom*prop, 
                   Atom trg, uchar*txt, ulong len, ulong*pos, uint *ctx )
{
  ulong chunk_len;  /* length of current chunk (for incr transfers only) */
  XEvent resp;      /* response to event */
  static Atom inc;
  static Atom targets;
  static long chunk_size;
  if (!targets) { targets = XInternAtom(dpy, "TARGETS", False); }
  if (!inc) { inc = XInternAtom(dpy, "INCR", False); }
  /* Treat selections larger than 1/4 of the max request size as "large" per ICCCM sect. 2.5 */
  if (!chunk_size) {
    chunk_size = XExtendedMaxRequestSize(dpy) / 4;
    if (!chunk_size) { chunk_size = XMaxRequestSize(dpy) / 4; }
  }
  switch (*ctx) {
    case XCLIB_XCIN_NONE: {
      if (evt.type != SelectionRequest) { return (0); }
      *win = evt.xselectionrequest.requestor;
      *prop = evt.xselectionrequest.property;
      *pos = 0;
      if (evt.xselectionrequest.target == targets) {   /* put the data into an property */
        Atom types[2];
        int size=(int)(sizeof(types)/sizeof(Atom));
        types[0]=targets;
        types[1]=trg;
        /* send data all at once (not using INCR) */
        XChangeProperty(dpy,*win,*prop,XA_ATOM,32,PropModeReplace,(uchar*)types,size);
      } else if (len > chunk_size) {
        XChangeProperty(dpy,*win,*prop,inc,32,PropModeReplace,0,0); /* send INCR response */
        /* With INCR, we need to know when requestor window changes/deletes properties */
        XSelectInput(dpy, *win, PropertyChangeMask);
        *ctx = XCLIB_XCIN_INCR;
      } else {
        XChangeProperty(dpy,*win,*prop,trg,8,PropModeReplace,(uchar*)txt,(int)len); /* All, not INCR */
      }

      /* FIXME? According to ICCCM section 2.5, we should confirm that X ChangeProperty
         succeeded without any Alloc errors before replying with SelectionNotify. 
         However, doing so would require an error handler which modifies a global
         variable, plus doing XSync after each X ChangeProperty. */
      resp.xselection.property = *prop;
      resp.xselection.type = SelectionNotify;
      resp.xselection.display = evt.xselectionrequest.display;
      resp.xselection.requestor = *win;
      resp.xselection.selection = evt.xselectionrequest.selection;
      resp.xselection.target = evt.xselectionrequest.target;
      resp.xselection.time = evt.xselectionrequest.time;
      XSendEvent(dpy, evt.xselectionrequest.requestor, 0, 0, &resp); /* send response event */
      XFlush(dpy);
      return (len > chunk_size) ? 0 : 1; /* if data sent all at once, transfer is complete. */
      break;
    }
    case XCLIB_XCIN_INCR: { 
      if (evt.type != PropertyNotify) { return (0); } /* ignore non-property events */
      if (evt.xproperty.state != PropertyDelete) { return (0); }   /* only interest in deleted props */
      chunk_len = chunk_size; /* set length to max size */
      /* if a max-sized chunk length would extend past end, set length to remaining txt length */
      if ((*pos + chunk_len) > len) { chunk_len = len - *pos; }

      /* if start of chunk is beyond end of txt, then we've sent all data, so set length to zero */
      if (*pos > len) { chunk_len = 0; }
      if (chunk_len) {  /* put chunk into property */
        XChangeProperty(dpy,*win,*prop,trg,8,PropModeReplace,&txt[*pos],(int)chunk_len);
      } else {
        XChangeProperty(dpy,*win,*prop,trg,8,PropModeReplace,0,0); /* empty prop shows we're done */
      }
      XFlush(dpy);
      if (!chunk_len) { *ctx = XCLIB_XCIN_NONE; }   /* all data is sent, break out of the loop */
      *pos += chunk_size;
      return (chunk_len==0) ? 1 : 0; /* chunk_len == 0 means we finished the transfer. */
      break;
    }
  }
  return (0);
}