bool
x_handle_dnd_message (struct frame *f, const XClientMessageEvent *event,
- struct x_display_info *dpyinfo, struct input_event *bufp)
+ struct x_display_info *dpyinfo, struct input_event *bufp,
+ bool root_window_coords, int root_x, int root_y)
{
Lisp_Object vec;
Lisp_Object frame;
unsigned char *data = (unsigned char *) event->data.b;
int idata[5];
ptrdiff_t i;
+ Window child_return;
for (i = 0; i < dpyinfo->x_dnd_atoms_length; ++i)
if (dpyinfo->x_dnd_atoms[i] == event->message_type) break;
event->format,
size));
- x_relative_mouse_position (f, &x, &y);
+ if (!root_window_coords)
+ x_relative_mouse_position (f, &x, &y);
+ else
+ XTranslateCoordinates (dpyinfo->display,
+ dpyinfo->root_window,
+ FRAME_X_WINDOW (f),
+ root_x, root_y,
+ &x, &y, &child_return);
+
bufp->kind = DRAG_N_DROP_EVENT;
bufp->frame_or_window = frame;
bufp->timestamp = CurrentTime;
}
#endif
+/* Extract the root window coordinates from the client message EVENT
+ if it is a message that we already understand. Return false if the
+ event was not understood. */
+static bool
+x_coords_from_dnd_message (struct x_display_info *dpyinfo,
+ XEvent *event, int *x_out, int *y_out)
+{
+ if (event->type != ClientMessage)
+ return false;
+
+ if (event->xclient.message_type == dpyinfo->Xatom_XdndPosition)
+ {
+ if (event->xclient.format != 32)
+ return false;
+
+ *x_out = (((unsigned long) event->xclient.data.l[2]) >> 16
+ & 0xffff);
+ *y_out = (event->xclient.data.l[2] & 0xffff);
+
+ return true;
+ }
+
+ return false;
+}
+
/* Handles the XEvent EVENT on display DPYINFO.
*FINISH is X_EVENT_GOTO_OUT if caller should stop reading events.
GdkEvent *copy = NULL;
GdkDisplay *gdpy = gdk_x11_lookup_xdisplay (dpyinfo->display);
#endif
+ int dx, dy;
USE_SAFE_ALLOCA;
*finish = X_EVENT_NORMAL;
{
case ClientMessage:
{
+ int rc;
+
if (x_dnd_in_progress
&& FRAME_DISPLAY_INFO (x_dnd_frame) == dpyinfo
&& event->xclient.message_type == dpyinfo->Xatom_XdndStatus)
f = any;
if (!f)
goto OTHER;
- if (x_handle_dnd_message (f, &event->xclient, dpyinfo, &inev.ie))
+
+ /* These values are always used initialized, but GCC doesn't
+ know that. */
+ dx = 0;
+ dy = 0;
+
+ rc = x_coords_from_dnd_message (dpyinfo, (XEvent *) event,
+ &dx, &dy);
+
+ if (x_handle_dnd_message (f, &event->xclient, dpyinfo, &inev.ie,
+ rc, dx, dy))
*finish = X_EVENT_DROP;
}
break;
extern bool x_handle_dnd_message (struct frame *,
const XClientMessageEvent *,
struct x_display_info *,
- struct input_event *);
+ struct input_event *,
+ bool, int, int);
extern int x_check_property_data (Lisp_Object);
extern void x_fill_property_data (Display *,
Lisp_Object,