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

📄 xdnd.c

📁 具有IDE功能的编辑器
💻 C
📖 第 1 页 / 共 4 页
字号:
	    xdnd_send_drop (dnd, dnd->dropper_window, from, time);#else	    xdnd_send_drop (dnd, dnd->dropper_toplevel, from, time);#endif	}	if (!dnd->internal_drag)	    for (;;) {		XAllowEvents (dnd->display, SyncPointer, CurrentTime);		XNextEvent (dnd->display, &xevent);		if (xevent.type == ClientMessage && xevent.xclient.message_type == dnd->XdndFinished) {		    dnd_debug1 ("XdndFinished");#if XDND_VERSION < 3		    if (XDND_FINISHED_TARGET_WIN (&xevent) == dnd->dropper_window) {#endif			dnd_debug2 ("  source correct - exiting event loop, action=%ld", dnd->supported_action);			result = dnd->supported_action;		/* success - so return action to caller */			break;#if XDND_VERSION < 3		    }#endif		} else if (xevent.type == Expose) {		    if (dnd->handle_expose_events)			(*dnd->handle_expose_events) (dnd, &xevent);		} else if (xevent.type == MotionNotify) {		    if (xevent.xmotion.time > time + (dnd->time_out ? dnd->time_out * 1000 : 10000)) {	/* allow a ten second timeout as default */			dnd_debug1 ("timeout - exiting event loop");			break;		    }		} else if (xevent.type == SelectionRequest && xevent.xselectionrequest.selection == dnd->XdndSelection) {/* the target widget is going to request data, so check for SelectionRequest events */		    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);		    }/* don't wait for a XdndFinished event */		    if (!dnd_version_at_least (dnd->dragging_version, 2))			break;		}	    }    } else {	dnd_debug1 ("not ready_to_drop - ungrabbing pointer");    }    XUngrabPointer (dnd->display, CurrentTime);    xdnd_reset (dnd);    return result;}/* returns non-zero if event is handled */int xdnd_handle_drop_events (DndClass * dnd, XEvent * xevent){    int result = 0;    if (xevent->type == SelectionNotify) {	dnd_debug1 ("got SelectionNotify");	if (xevent->xselection.property == dnd->Xdnd_NON_PROTOCOL_ATOM && dnd->stage == XDND_DROP_STAGE_CONVERTING) {	    int error;	    dnd_debug1 ("  property is Xdnd_NON_PROTOCOL_ATOM - getting selection");	    error = xdnd_get_selection (dnd, dnd->dragger_window, xevent->xselection.property, xevent->xany.window);/* error is not actually used, i think future versions of the protocol maybe should return    an error status to the calling window with the XdndFinished client message */	    if (dnd_version_at_least (dnd->dragging_version, 2)) {#if XDND_VERSION >= 3		xdnd_send_finished (dnd, dnd->dragger_window, dnd->dropper_toplevel, error);#else		xdnd_send_finished (dnd, dnd->dragger_window, dnd->dropper_window, error);#endif	        dnd_debug1 ("    sending finished");            }	    xdnd_xfree (dnd->dragger_typelist);	    xdnd_reset (dnd);	    dnd->stage = XDND_DROP_STAGE_IDLE;	    result = 1;	} else {	    dnd_debug1 ("  property is not Xdnd_NON_PROTOCOL_ATOM - ignoring");	}    } else if (xevent->type == ClientMessage) {	dnd_debug2 ("got ClientMessage to xevent->xany.window = %ld", xevent->xany.window);	if (xevent->xclient.message_type == dnd->XdndEnter) {	    dnd_debug2 ("  message_type is XdndEnter, version = %ld", XDND_ENTER_VERSION (xevent));#if XDND_VERSION >= 3	    if (XDND_ENTER_VERSION (xevent) < 3)		return 0;#endif	    xdnd_reset (dnd);	    dnd->dragger_window = XDND_ENTER_SOURCE_WIN (xevent);#if XDND_VERSION >= 3            dnd->dropper_toplevel = xevent->xany.window;	    dnd->dropper_window = 0;     /* enter goes to the top level window only,                                            so we don't really know what the                                            sub window is yet */#else	    dnd->dropper_window = xevent->xany.window;#endif	    xdnd_xfree (dnd->dragger_typelist);	    if (XDND_ENTER_THREE_TYPES (xevent)) {		dnd_debug1 ("    three types only");		xdnd_get_three_types (dnd, xevent, &dnd->dragger_typelist);	    } else {		dnd_debug1 ("    more than three types - getting list");		xdnd_get_type_list (dnd, dnd->dragger_window, &dnd->dragger_typelist);	    }	    if (dnd->dragger_typelist)		dnd->stage = XDND_DROP_STAGE_ENTERED;	    else		dnd_debug1 ("      typelist returned as zero!");	    dnd->dragging_version = XDND_ENTER_VERSION (xevent);	    result = 1;	} else if (xevent->xclient.message_type == dnd->XdndLeave) {#if XDND_VERSION >= 3            if (xevent->xany.window == dnd->dropper_toplevel && dnd->dropper_window)                xevent->xany.window = dnd->dropper_window;#endif	    dnd_debug1 ("  message_type is XdndLeave");	    if (dnd->dragger_window == XDND_LEAVE_SOURCE_WIN (xevent) && dnd->stage == XDND_DROP_STAGE_ENTERED) {		dnd_debug1 ("    leaving");		if (dnd->widget_apply_leave)		    (*dnd->widget_apply_leave) (dnd, xevent->xany.window);		dnd->stage = XDND_DROP_STAGE_IDLE;		xdnd_xfree (dnd->dragger_typelist);		result = 1;                dnd->dropper_toplevel = dnd->dropper_window = 0;	    } else {		dnd_debug1 ("    wrong stage or from wrong window");	    }	} else if (xevent->xclient.message_type == dnd->XdndPosition) {	    dnd_debug2 ("  message_type is XdndPosition to %ld", xevent->xany.window);	    if (dnd->dragger_window == XDND_POSITION_SOURCE_WIN (xevent) && dnd->stage == XDND_DROP_STAGE_ENTERED) {		int want_position;		Atom action;		XRectangle rectangle;                Window last_window;                last_window = dnd->dropper_window;#if XDND_VERSION >= 3/* version 3 gives us the top-level window only. WE have to find the child that the pointer is over: */                if (1 || xevent->xany.window != dnd->dropper_toplevel || !dnd->dropper_window) {                    Window parent, child, new_child = 0;                    dnd->dropper_toplevel = xevent->xany.window;                    parent = dnd->root_window;                    child = dnd->dropper_toplevel;                    for (;;) {                        int xd, yd;                        new_child = 0;                        if (!XTranslateCoordinates (dnd->display, parent, child,                                     XDND_POSITION_ROOT_X (xevent), XDND_POSITION_ROOT_Y (xevent),                                    &xd, &yd, &new_child))                            break;                        if (!new_child)                            break;                        child = new_child;                    }                    dnd->dropper_window = xevent->xany.window = child;	            dnd_debug2 ("   child window translates to %ld", dnd->dropper_window);                } else if (xevent->xany.window == dnd->dropper_toplevel && dnd->dropper_window) {                    xevent->xany.window = dnd->dropper_window;	            dnd_debug2 ("   child window previously found: %ld", dnd->dropper_window);                }#endif		action = dnd->XdndActionCopy;		dnd->supported_action = dnd->XdndActionCopy;		dnd->x = XDND_POSITION_ROOT_X (xevent);		dnd->y = XDND_POSITION_ROOT_Y (xevent);		dnd->time = CurrentTime;		if (dnd_version_at_least (dnd->dragging_version, 1))		    dnd->time = XDND_POSITION_TIME (xevent);		if (dnd_version_at_least (dnd->dragging_version, 1))		    action = XDND_POSITION_ACTION (xevent);#if XDND_VERSION >= 3                if (last_window && last_window != xevent->xany.window)		    if (dnd->widget_apply_leave)		        (*dnd->widget_apply_leave) (dnd, last_window);#endif		dnd->will_accept = (*dnd->widget_apply_position) (dnd, xevent->xany.window, dnd->dragger_window,		action, dnd->x, dnd->y, dnd->time, dnd->dragger_typelist,								  &want_position, &dnd->supported_action, &dnd->desired_type, &rectangle);		dnd_debug2 ("    will accept = %d", dnd->will_accept);#if XDND_VERSION >= 3		dnd_debug2 ("    sending status of %ld", dnd->dropper_toplevel);		xdnd_send_status (dnd, dnd->dragger_window, dnd->dropper_toplevel, dnd->will_accept,				  want_position, rectangle.x, rectangle.y, rectangle.width, rectangle.height, dnd->supported_action);#else		dnd_debug2 ("    sending status of %ld", xevent->xany.window);		xdnd_send_status (dnd, dnd->dragger_window, xevent->xany.window, dnd->will_accept,				  want_position, rectangle.x, rectangle.y, rectangle.width, rectangle.height, dnd->supported_action);#endif		result = 1;	    } else {		dnd_debug1 ("    wrong stage or from wrong window");	    }	} else if (xevent->xclient.message_type == dnd->XdndDrop) {#if XDND_VERSION >= 3            if (xevent->xany.window == dnd->dropper_toplevel && dnd->dropper_window)                xevent->xany.window = dnd->dropper_window;#endif	    dnd_debug1 ("  message_type is XdndDrop");	    if (dnd->dragger_window == XDND_DROP_SOURCE_WIN (xevent) && dnd->stage == XDND_DROP_STAGE_ENTERED) {		dnd->time = CurrentTime;		if (dnd_version_at_least (dnd->dragging_version, 1))		    dnd->time = XDND_DROP_TIME (xevent);		if (dnd->will_accept) {		    dnd_debug1 ("    will_accept is true - converting selectiong");		    dnd_debug2 ("      my window is %ld", dnd->dropper_window);		    dnd_debug2 ("        source window is %ld", dnd->dragger_window);		    xdnd_convert_selection (dnd, dnd->dragger_window, dnd->dropper_window, dnd->desired_type);		    dnd->stage = XDND_DROP_STAGE_CONVERTING;		} else {		    dnd_debug1 ("    will_accept is false - sending finished");		    if (dnd_version_at_least (dnd->dragging_version, 2)) {#if XDND_VERSION >= 3			xdnd_send_finished (dnd, dnd->dragger_window, dnd->dropper_toplevel, 1);#else			xdnd_send_finished (dnd, dnd->dragger_window, xevent->xany.window, 1);#endif                    }		    xdnd_xfree (dnd->dragger_typelist);		    xdnd_reset (dnd);		    dnd->stage = XDND_DROP_STAGE_IDLE;		}		result = 1;	    } else {		dnd_debug1 ("    wrong stage or from wrong window");	    }	}    }    return result;}/*   Following here is a sample implementation: Suppose we want a window   to recieve drops, but do not want to be concerned with setting up all   the DndClass methods. All we then do is call xdnd_get_drop() whenever a   ClientMessage is recieved. If the message has nothing to do with XDND,   xdnd_get_drop quickly returns 0. If it is a XdndEnter message, then   xdnd_get_drop enters its own XNextEvent loop and handles all XDND   protocol messages internally, returning the action requested.   You should pass a desired typelist and actionlist to xdnd_get_type.   These must be null terminated arrays of atoms, or a null pointer   if you would like any action or type to be accepted. If typelist   is null then the first type of the dragging widgets typelist will   be the one used. If actionlist is null, then only XdndActionCopy will   be accepted.   The result is stored in *data, length, type, x and y.   *data must be free'd. */struct xdnd_get_drop_info {    unsigned char *drop_data;    int drop_data_length;    int x, y;    Atom return_type;    Atom return_action;    Atom *typelist;    Atom *actionlist;};static int widget_insert_drop (DndClass * dnd, unsigned char *data, int length, int remaining, Window into, Window from, Atom type){    struct xdnd_get_drop_info *i;    i = (struct xdnd_get_drop_info *) dnd->user_hook1;    if (!i->drop_data) {	i->drop_data = malloc (length);	if (!i->drop_data)	    return 1;	memcpy (i->drop_data, data, length);	i->drop_data_length = length;    } else {	unsigned char *t;	t = malloc (i->drop_data_length + length);	if (!t) {	    free (i->drop_data);	    i->drop_data = 0;	    return 1;	}	memcpy (t, i->drop_data, i->drop_data_length);	memcpy (t + i->drop_data_length, data, length);	free (i->drop_data);	i->drop_data = t;	i->drop_data_length += length;    }    return 0;}static int widget_apply_position (DndClass * dnd, Window widgets_window, Window from,		      Atom action, int x, int y, Time t, Atom * typelist, int *want_position, Atom * supported_action_return, Atom * desired_type,				  XRectangle * rectangle){    int i, j;    struct xdnd_get_drop_info *info;    Atom *dropper_typelist, supported_type = 0;    Atom *supported_actions, supported_action = 0;    info = (struct xdnd_get_drop_info *) dnd->user_hook1;    dropper_typelist = info->typelist;    supported_actions = info->actionlist;    if (dropper_typelist) {/* find a correlation: */	for (j = 0; dropper_typelist[j]; j++) {	    for (i = 0; typelist[i]; i++) {		if (typelist[i] == dropper_typelist[j]) {		    supported_type = typelist[i];		    break;		}	    }	    if (supported_type)		break;	}    } else {/* user did not specify, so return first type */	supported_type = typelist[0];    }/* not supported, so return false */    if (!supported_type)	return 0;    if (supported_actions) {	for (j = 0; supported_actions[j]; j++) {	    if (action == supported_actions[j]) {		supported_action = action;		break;	    }	}    } else {/* user did not specify */	if (action == dnd->XdndActionCopy)	    supported_action = action;    }    if (!supported_action)	return 0;    *want_position = 1;    rectangle->x = rectangle->y = 0;    rectangle->width = rectangle->height = 0;    info->return_action = *supported_action_return = supported_action;    info->return_type = *desired_type = supported_type;    info->x = x;    info->y = y;    return 1;}Atom xdnd_get_drop (Display * display, XEvent * xevent, Atom * typelist, Atom * actionlist,	  unsigned char **data, int *length, Atom * type, int *x, int *y){    Atom action = 0;    static int initialised = 0;    static DndClass dnd;    if (!initialised) {	xdnd_init (&dnd, display);	initialised = 1;    }    if (xevent->type != ClientMessage || xevent->xclient.message_type != dnd.XdndEnter) {	return 0;    } else {	struct xdnd_get_drop_info i;/* setup user structure */	memset (&i, 0, sizeof (i));	i.typelist = actionlist;	i.typelist = typelist;	dnd.user_hook1 = &i;/* setup methods */	dnd.widget_insert_drop = widget_insert_drop;	dnd.widget_apply_position = widget_apply_position;/* main loop */	for (;;) {	    xdnd_handle_drop_events (&dnd, xevent);	    if (dnd.stage == XDND_DROP_STAGE_IDLE)		break;	    XNextEvent (dnd.display, xevent);	}/* return results */	if (i.drop_data) {	    *length = i.drop_data_length;	    *data = i.drop_data;	    action = i.return_action;	    *type = i.return_type;	    *x = i.x;	    *y = i.y;	}    }    return action;}

⌨️ 快捷键说明

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