⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xdnd.c

📁 具有IDE功能的编辑器
💻 C
📖 第 1 页 / 共 4 页
字号:
    unsigned long nitems;    unsigned char *s = 0;    if (prop == None)	return 1;    nread = 0;    if (XGetWindowProperty	(dnd->display, insert, prop, 0, 8, False, AnyPropertyType, &actual_type, &actual_fmt,	 &nitems, &bytes_after, &s) != Success) {	XFree (s);	return 1;    }    XFree (s);    if (actual_type != XInternAtom (dnd->display, "INCR", False))	return paste_prop_internal (dnd, from, insert, prop, True);    XDeleteProperty (dnd->display, insert, prop);    gettimeofday (&tv_start, 0);    for (;;) {	long t;	fd_set r;	XEvent xe;	if (XCheckMaskEvent (dnd->display, PropertyChangeMask, &xe)) {	    if (xe.type == PropertyNotify && xe.xproperty.state == PropertyNewValue) {/* time between arrivals of data */		gettimeofday (&tv_start, 0);		if (paste_prop_internal (dnd, from, insert, prop, True))		    break;	    }	} else {	    tv.tv_sec = 0;	    tv.tv_usec = 10000;	    FD_ZERO (&r);	    FD_SET (ConnectionNumber (dnd->display), &r);	    select (ConnectionNumber (dnd->display) + 1, &r, 0, 0, &tv);	    if (FD_ISSET (ConnectionNumber (dnd->display), &r))		continue;	}	gettimeofday (&tv, 0);	t = (tv.tv_sec - tv_start.tv_sec) * 1000000L + (tv.tv_usec - tv_start.tv_usec);/* no data for five seconds, so quit */	if (t > 5000000L)	    return 1;    }    return 0;}int outside_rectangle (int x, int y, XRectangle * r){    return (x < r->x || y < r->y || x >= r->x + r->width || y >= r->y + r->height);}/* avoids linking with the maths library */static float xdnd_sqrt (float x){    float last_ans, ans = 2, a;    if (x <= 0.0)	return 0.0;    do {	last_ans = ans;	ans = (ans + x / ans) / 2;	a = (ans - last_ans) / ans;	if (a < 0.0)	    a = (-a);    } while (a > 0.001);    return ans;}#define print_marks print_win_marks(from,__FILE__,__LINE__);/* returns action on success, 0 otherwise */Atom xdnd_drag (DndClass * dnd, Window from, Atom action, Atom * typelist){    XEvent xevent, xevent_temp;    Window over_window = 0, last_window = 0;#if XDND_VERSION >= 3    Window last_dropper_toplevel = 0;    int internal_dropable = 1;#endif    int n;    DndCursor *cursor;    float x_mouse, y_mouse;    int result = 0, dnd_aware;    if (!typelist)	dnd_warning ("xdnd_drag() called with typelist = 0");/* first wait until the mouse moves more than five pixels */    do {	XNextEvent (dnd->display, &xevent);	if (xevent.type == ButtonRelease) {	    dnd_debug1 ("button release - no motion");	    XSendEvent (dnd->display, xevent.xany.window, 0, ButtonReleaseMask, &xevent);	    return 0;	}    } while (xevent.type != MotionNotify);    x_mouse = (float) xevent.xmotion.x_root;    y_mouse = (float) xevent.xmotion.y_root;    if (!dnd->drag_threshold)	dnd->drag_threshold = 4.0;    for (;;) {	XNextEvent (dnd->display, &xevent);	if (xevent.type == MotionNotify)	    if (xdnd_sqrt ((x_mouse - xevent.xmotion.x_root) * (x_mouse - xevent.xmotion.x_root) +			   (y_mouse - xevent.xmotion.y_root) * (y_mouse - xevent.xmotion.y_root)) > dnd->drag_threshold)		break;	if (xevent.type == ButtonRelease) {	    XSendEvent (dnd->display, xevent.xany.window, 0, ButtonReleaseMask, &xevent);	    return 0;	}    }    dnd_debug1 ("moved 5 pixels - going to drag");    n = array_length (typelist);    if (n > XDND_THREE)	xdnd_set_type_list (dnd, from, typelist);    xdnd_reset (dnd);    dnd->stage = XDND_DRAG_STAGE_DRAGGING;    for (cursor = &dnd->cursors[0]; cursor->width; cursor++)	if (cursor->action == action)	    break;    if (!cursor->width)	cursor = &dnd->cursors[0];/* the mouse has been dragged a little, so this is a drag proper */    if (XGrabPointer (dnd->display, dnd->root_window, False,		      ButtonMotionMask | PointerMotionMask | ButtonPressMask | ButtonReleaseMask,		      GrabModeAsync, GrabModeAsync, None,		      cursor->cursor, CurrentTime) != GrabSuccess)	dnd_debug1 ("Unable to grab pointer");    while (xevent.xany.type != ButtonRelease) {	XAllowEvents (dnd->display, SyncPointer, CurrentTime);	XNextEvent (dnd->display, &xevent);	switch (xevent.type) {	case Expose:	    if (dnd->handle_expose_events)		(*dnd->handle_expose_events) (dnd, &xevent);	    break;	case EnterNotify:/* this event is not actually reported, so we find out by ourselves from motion events */	    break;	case LeaveNotify:/* this event is not actually reported, so we find out by ourselves from motion events */	    break;	case ButtonRelease:/* done, but must send a leave event */	    dnd_debug1 ("ButtonRelease - exiting event loop");	    break;	case MotionNotify:	    dnd_aware = 0;	    dnd->dropper_toplevel = 0;	    memcpy (&xevent_temp, &xevent, sizeof (xevent));            xevent.xmotion.subwindow = xevent.xmotion.window;            {		Window root_return, child_return;		int x_temp, y_temp;		unsigned int mask_return;		while (XQueryPointer (dnd->display, xevent.xmotion.subwindow, &root_return, &child_return,				      &x_temp, &y_temp, &xevent.xmotion.x,				      &xevent.xmotion.y, &mask_return)) {#if XDND_VERSION >= 3		    if (!dnd_aware) {			if ((dnd_aware = xdnd_is_dnd_aware (dnd, xevent.xmotion.subwindow, &dnd->dragging_version, typelist))) {			    dnd->dropper_toplevel = xevent.xmotion.subwindow;			    xevent.xmotion.x_root = x_temp;			    xevent.xmotion.y_root = y_temp;			}                    }#else		    xevent.xmotion.x_root = x_temp;		    xevent.xmotion.y_root = y_temp;#endif		    if (!child_return)			goto found_descendent;		    xevent.xmotion.subwindow = child_return;		}		break;	    }	  found_descendent:/* last_window is just for debug purposes */	    if (last_window != xevent.xmotion.subwindow) {		dnd_debug2 ("window crossing to %ld", xevent.xmotion.subwindow);		dnd_debug2 ("  current window is %ld", over_window);		dnd_debug3 ("     last_window = %ld, xmotion.subwindow = %ld", last_window, xevent.xmotion.subwindow);#if XDND_VERSION >= 3		dnd_debug3 ("     dropper_toplevel = %ld, last_dropper_toplevel.subwindow = %ld", dnd->dropper_toplevel, last_dropper_toplevel);#endif		dnd_debug3 ("     dnd_aware = %d, dnd->options & XDND_OPTION_NO_HYSTERESIS = %ld", dnd_aware, (long) dnd->options & XDND_OPTION_NO_HYSTERESIS);	    }#if XDND_VERSION < 3/* is the new window dnd aware? if not stay in the old window */	    if (over_window != xevent.xmotion.subwindow &&		last_window != xevent.xmotion.subwindow &&		(		    (dnd_aware = xdnd_is_dnd_aware (dnd, xevent.xmotion.subwindow, &dnd->dragging_version, typelist))		    ||		    (dnd->options & XDND_OPTION_NO_HYSTERESIS)		))#else            internal_dropable = 1;            if (dnd->widget_exists && (*dnd->widget_exists) (dnd, xevent.xmotion.subwindow))                if (!xdnd_is_dnd_aware (dnd, xevent.xmotion.subwindow, &dnd->dragging_version, typelist))                    internal_dropable = 0;	    dnd_debug3 ("dnd->dropper_toplevel = %ld, last_dropper_toplevel = %ld\n", dnd->dropper_toplevel, last_dropper_toplevel);	    if ((dnd->dropper_toplevel != last_dropper_toplevel ||		last_window != xevent.xmotion.subwindow) && internal_dropable &&		(		    (dnd_aware)		    ||		    (dnd->options & XDND_OPTION_NO_HYSTERESIS)		))#endif	    {/* leaving window we were over */		if (over_window) {		    if (dnd->stage == XDND_DRAG_STAGE_ENTERED) {			dnd_debug1 ("got leave at right stage");			dnd->stage = XDND_DRAG_STAGE_DRAGGING;			if (dnd->internal_drag) {			    dnd_debug1 ("  our own widget");			    if (dnd->widget_apply_leave)				(*dnd->widget_apply_leave) (dnd, over_window);			} else {			    dnd_debug1 ("  not our widget - sending XdndLeave");#if XDND_VERSION < 3			    xdnd_send_leave (dnd, over_window, from);#else                            if (dnd->dropper_toplevel != last_dropper_toplevel) {			        xdnd_send_leave (dnd, last_dropper_toplevel, from);			    } else {				dnd_debug1 ("    not sending leave --> dnd->dropper_toplevel == last_dropper_toplevel");			    }#endif			}			dnd->internal_drag = 0;			dnd->dropper_window = 0;			dnd->ready_to_drop = 0;		    } else {			dnd_debug1 ("got leave at wrong stage - ignoring");		    }		}/* entering window we are currently over */		over_window = xevent.xmotion.subwindow;		if (dnd_aware) {		    dnd_debug1 ("  is dnd aware");		    dnd->stage = XDND_DRAG_STAGE_ENTERED;		    if (dnd->widget_exists && (*dnd->widget_exists) (dnd, over_window))			dnd->internal_drag = 1;		    if (dnd->internal_drag) {			dnd_debug1 ("    our own widget");		    } else {			dnd_debug2 ("    not our widget - sending XdndEnter to %ld", over_window);#if XDND_VERSION < 3			xdnd_send_enter (dnd, over_window, from, typelist);#else                        if (dnd->dropper_toplevel != last_dropper_toplevel)			    xdnd_send_enter (dnd, dnd->dropper_toplevel, from, typelist);#endif		    }		    dnd->want_position = 1;		    dnd->ready_to_drop = 0;		    dnd->rectangle.width = dnd->rectangle.height = 0;		    dnd->dropper_window = over_window;/* we want an additional motion event in case the pointer enters and then stops */		    XSendEvent (dnd->display, from, 0, ButtonMotionMask, &xevent_temp);		    XSync (dnd->display, 0);		}#if XDND_VERSION >= 3		last_dropper_toplevel = dnd->dropper_toplevel;#endif/* we are now officially in a new window */	    } else {/* got here, so we are just moving `inside' the same window */		if (dnd->stage == XDND_DRAG_STAGE_ENTERED) {		    dnd->supported_action = dnd->XdndActionCopy;		    dnd_debug1 ("got motion at right stage");		    dnd->x = xevent.xmotion.x_root;		    dnd->y = xevent.xmotion.y_root;		    if (dnd->want_position || outside_rectangle (dnd->x, dnd->y, &dnd->rectangle)) {			dnd_debug1 ("  want position and outside rectangle");			if (dnd->internal_drag) {			    dnd_debug1 ("    our own widget");			    dnd->ready_to_drop = (*dnd->widget_apply_position) (dnd, over_window, from,										action, dnd->x, dnd->y, xevent.xmotion.time, typelist,										&dnd->want_position, &dnd->supported_action, &dnd->desired_type, &dnd->rectangle);			    /* if not ready, keep sending positions, this check is repeated below for XdndStatus from external widgets */			    if (!dnd->ready_to_drop) {				dnd->want_position = 1;				dnd->rectangle.width = dnd->rectangle.height = 0;			    }			    dnd_debug2 ("      return action=%ld", dnd->supported_action);			} else {#if XDND_VERSION < 3			    dnd_debug3 ("    not our own widget - sending XdndPosition to %ld, action %ld", over_window, action);			    xdnd_send_position (dnd, over_window, from, action, dnd->x, dnd->y, xevent.xmotion.time);#else			    dnd_debug3 ("    not our own widget - sending XdndPosition to %ld, action %ld", dnd->dropper_toplevel, action);			    xdnd_send_position (dnd, dnd->dropper_toplevel, from, action, dnd->x, dnd->y, xevent.xmotion.time);#endif			}		    } else if (dnd->want_position) {			dnd_debug1 ("  inside rectangle");		    } else {			dnd_debug1 ("  doesn't want position");		    }		}	    }	    last_window = xevent.xmotion.subwindow;	    break;	case ClientMessage:	    dnd_debug1 ("ClientMessage recieved");	    if (xevent.xclient.message_type == dnd->XdndStatus && !dnd->internal_drag) {		dnd_debug1 ("  XdndStatus recieved");		if (dnd->stage == XDND_DRAG_STAGE_ENTERED #if XDND_VERSION < 3                        && XDND_STATUS_TARGET_WIN (&xevent) == dnd->dropper_window#endif                ) {		    dnd_debug1 ("    XdndStatus stage correct, dropper window correct");		    dnd->want_position = XDND_STATUS_WANT_POSITION (&xevent);		    dnd->ready_to_drop = XDND_STATUS_WILL_ACCEPT (&xevent);		    dnd->rectangle.x = XDND_STATUS_RECT_X (&xevent);		    dnd->rectangle.y = XDND_STATUS_RECT_Y (&xevent);		    dnd->rectangle.width = XDND_STATUS_RECT_WIDTH (&xevent);		    dnd->rectangle.height = XDND_STATUS_RECT_HEIGHT (&xevent);		    dnd->supported_action = dnd->XdndActionCopy;		    if (dnd_version_at_least (dnd->dragging_version, 2))			dnd->supported_action = XDND_STATUS_ACTION (&xevent);		    dnd_debug3 ("      return action=%ld, ready=%d", dnd->supported_action, dnd->ready_to_drop);		    /* if not ready, keep sending positions, this check is repeated above for internal widgets */		    if (!dnd->ready_to_drop) {			dnd->want_position = 1;			dnd->rectangle.width = dnd->rectangle.height = 0;		    }		    dnd_debug3 ("      rectangle = (x=%d, y=%d, ", dnd->rectangle.x, dnd->rectangle.y);		    dnd_debug4                               ("w=%d, h=%d), want_position=%d\n", dnd->rectangle.width, dnd->rectangle.height, dnd->want_position);		}#if XDND_VERSION < 3                else if (XDND_STATUS_TARGET_WIN (&xevent) != dnd->dropper_window) {		    dnd_debug3 ("    XdndStatus XDND_STATUS_TARGET_WIN (&xevent) = %ld, dnd->dropper_window = %ld", XDND_STATUS_TARGET_WIN (&xevent), dnd->dropper_window);		}#endif                else {		    dnd_debug2 ("    XdndStatus stage incorrect dnd->stage = %d", dnd->stage);                }	    }	    break;	case SelectionRequest:{/* the target widget MAY request data, so wait for SelectionRequest */		int length = 0;		unsigned char *data = 0;		dnd_debug1 ("SelectionRequest - getting widget data");		(*dnd->widget_get_data) (dnd, from, &data, &length, xevent.xselectionrequest.target);		if (data) {		    dnd_debug1 ("  sending selection");		    xdnd_selection_send (dnd, &xevent.xselectionrequest, data, length);		    xdnd_xfree (data);		}	    }	    break;	}    }    if (dnd->ready_to_drop) {	Time time;	dnd_debug1 ("ready_to_drop - sending XdndDrop");	time = xevent.xbutton.time;	if (dnd->internal_drag) {/* we are dealing with our own widget, no need to send drop events, just put the data straight */	    int length = 0;	    unsigned char *data = 0;	    if (dnd->widget_insert_drop) {		(*dnd->widget_get_data) (dnd, from, &data, &length, dnd->desired_type);		if (data) {		    if (!(*dnd->widget_insert_drop) (dnd, data, length, 0, dnd->dropper_window, from, dnd->desired_type)) {			result = dnd->supported_action;		/* success - so return action to caller */			dnd_debug1 ("  inserted data into widget - success");		    } else {			dnd_debug1 ("  inserted data into widget - failed");		    }		    xdnd_xfree (data);		} else {		    dnd_debug1 ("  got data from widget, but data is null");		}	    }	} else {	    xdnd_set_selection_owner (dnd, from, dnd->desired_type);#if XDND_VERSION < 3

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -