xdnd
This commit is contained in:
parent
1f67ab5d16
commit
4ab7b15747
2 changed files with 169 additions and 24 deletions
|
|
@ -27,20 +27,36 @@ struct _MwLLX11 {
|
|||
unsigned int width;
|
||||
unsigned int height;
|
||||
|
||||
Display* display;
|
||||
Window window;
|
||||
Pixmap pixmap;
|
||||
GC gc;
|
||||
Colormap colormap;
|
||||
Atom wm_delete;
|
||||
Atom wm_protocols;
|
||||
Atom utf8_string;
|
||||
Atom compound_text;
|
||||
Atom text;
|
||||
Atom clipboard;
|
||||
Atom selection;
|
||||
XIM xim;
|
||||
XIC xic;
|
||||
Display* display;
|
||||
Window window;
|
||||
Pixmap pixmap;
|
||||
GC gc;
|
||||
Colormap colormap;
|
||||
Atom wm_delete;
|
||||
Atom wm_protocols;
|
||||
Atom utf8_string;
|
||||
Atom compound_text;
|
||||
Atom text;
|
||||
Atom clipboard;
|
||||
Atom selection;
|
||||
Atom xdnd_type_list;
|
||||
Atom xdnd_selection;
|
||||
Atom xdnd_enter;
|
||||
Atom xdnd_position;
|
||||
Atom xdnd_status;
|
||||
Atom xdnd_leave;
|
||||
Atom xdnd_drop;
|
||||
Atom xdnd_finished;
|
||||
Atom xdnd_action_copy;
|
||||
Atom xdnd_text_uri_list;
|
||||
Atom xdnd_text_plain;
|
||||
Atom xdnd_aware;
|
||||
int xdnd_source;
|
||||
unsigned char xdnd_version;
|
||||
int format;
|
||||
|
||||
XIM xim;
|
||||
XIC xic;
|
||||
|
||||
long clipboard_time;
|
||||
int clipboard_pending; /* 1 if UTF8_STRING, 2 if COMPOUND_TEXT, 3 if TEXT, 4 if STRING, otherwise 0 */
|
||||
|
|
|
|||
|
|
@ -82,6 +82,8 @@ static struct symtbl {
|
|||
void (*XSetICFocus)(XIC);
|
||||
XImage* (*XGetImage)(Display*, Drawable, int, int, unsigned int, unsigned int, unsigned long, int);
|
||||
int (*XRaiseWindow)(Display*, Window);
|
||||
int (*XFlush)(Display*);
|
||||
char* (*XGetAtomName)(Display*, Atom);
|
||||
|
||||
XSizeHints* (*XAllocSizeHints)(void);
|
||||
XVisualInfo* (*XGetVisualInfo)(Display*, long, XVisualInfo*, int*);
|
||||
|
|
@ -186,6 +188,8 @@ static struct symtbl {
|
|||
#define XChangeWindowAttributes xsymtbl.XChangeWindowAttributes
|
||||
#define XGetImage xsymtbl.XGetImage
|
||||
#define XRaiseWindow xsymtbl.XRaiseWindow
|
||||
#define XFlush xsymtbl.XFlush
|
||||
#define XGetAtomName xsymtbl.XGetAtomName
|
||||
|
||||
#if USE_XRENDER
|
||||
#define XRenderFindStandardFormat xsymtbl.XRenderFindStandardFormat
|
||||
|
|
@ -425,6 +429,7 @@ static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) {
|
|||
r->x11.colormap = DefaultColormap(r->x11.display, XDefaultScreen(r->x11.display));
|
||||
r->x11.wm_delete = XInternAtom(r->x11.display, "WM_DELETE_WINDOW", False);
|
||||
r->x11.wm_protocols = XInternAtom(r->x11.display, "WM_PROTOCOLS", False);
|
||||
|
||||
XSetWMProtocols(r->x11.display, r->x11.window, &r->x11.wm_delete, 1);
|
||||
|
||||
r->x11.utf8_string = XInternAtom(r->x11.display, "UTF8_STRING", False);
|
||||
|
|
@ -433,6 +438,22 @@ static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) {
|
|||
r->x11.clipboard = XInternAtom(r->x11.display, "CLIPBOARD", False);
|
||||
r->x11.selection = XInternAtom(r->x11.display, "_MILSKO_SELECTION_", False);
|
||||
|
||||
r->x11.xdnd_type_list = XInternAtom(r->x11.display, "XdndTypeList", False);
|
||||
r->x11.xdnd_selection = XInternAtom(r->x11.display, "XdndSelection", False);
|
||||
r->x11.xdnd_enter = XInternAtom(r->x11.display, "XdndEnter", False);
|
||||
r->x11.xdnd_position = XInternAtom(r->x11.display, "XdndPosition", False);
|
||||
r->x11.xdnd_status = XInternAtom(r->x11.display, "XdndStatus", False);
|
||||
r->x11.xdnd_leave = XInternAtom(r->x11.display, "XdndLeave", False);
|
||||
r->x11.xdnd_drop = XInternAtom(r->x11.display, "XdndDrop", False);
|
||||
r->x11.xdnd_finished = XInternAtom(r->x11.display, "XdndFinished", False);
|
||||
r->x11.xdnd_action_copy = XInternAtom(r->x11.display, "XdndActionCopy", False);
|
||||
r->x11.xdnd_text_uri_list = XInternAtom(r->x11.display, "text/uri-list", False);
|
||||
r->x11.xdnd_text_plain = XInternAtom(r->x11.display, "text/plain", False);
|
||||
r->x11.xdnd_aware = XInternAtom(r->x11.display, "XdndAware", False);
|
||||
r->x11.xdnd_version = 5;
|
||||
r->x11.format = None;
|
||||
XChangeProperty(r->x11.display, r->x11.window, r->x11.xdnd_aware, 4, 32, PropModeReplace, &r->x11.xdnd_version, 1);
|
||||
|
||||
r->x11.clipboard_pending = 0;
|
||||
|
||||
r->x11.gc = XCreateGC(r->x11.display, r->x11.window, 0, NULL);
|
||||
|
|
@ -704,10 +725,15 @@ static void MwLLNextEventImpl(MwLL handle) {
|
|||
|
||||
while(XCheckTypedWindowEvent(handle->x11.display, handle->x11.window, ClientMessage, &ev) || XCheckTypedWindowEvent(handle->x11.display, handle->x11.window, SelectionNotify, &ev) || XCheckWindowEvent(handle->x11.display, handle->x11.window, mask, &ev)) {
|
||||
int render = 0;
|
||||
if(ev.type == Expose) {
|
||||
switch(ev.type) {
|
||||
case Expose:
|
||||
{
|
||||
handle->x11.force_render = 0;
|
||||
render = 1;
|
||||
} else if(ev.type == ButtonPress) {
|
||||
break;
|
||||
};
|
||||
case ButtonPress:
|
||||
{
|
||||
MwMouse p;
|
||||
p.point.x = ev.xbutton.x;
|
||||
p.point.y = ev.xbutton.y;
|
||||
|
|
@ -728,7 +754,10 @@ static void MwLLNextEventImpl(MwLL handle) {
|
|||
#endif
|
||||
|
||||
MwLLDispatch(handle, down, &p);
|
||||
} else if(ev.type == ButtonRelease) {
|
||||
break;
|
||||
};
|
||||
case ButtonRelease:
|
||||
{
|
||||
MwMouse p;
|
||||
p.point.x = ev.xbutton.x;
|
||||
p.point.y = ev.xbutton.y;
|
||||
|
|
@ -745,24 +774,114 @@ static void MwLLNextEventImpl(MwLL handle) {
|
|||
}
|
||||
|
||||
MwLLDispatch(handle, up, &p);
|
||||
} else if(ev.type == ConfigureNotify) {
|
||||
break;
|
||||
};
|
||||
case ConfigureNotify:
|
||||
{
|
||||
if(handle->x11.width != (unsigned int)ev.xconfigure.width || handle->x11.height != (unsigned int)ev.xconfigure.height) {
|
||||
MwLLDispatch(handle, resize, NULL);
|
||||
destroy_pixmap(handle);
|
||||
create_pixmap(handle);
|
||||
render = 1;
|
||||
break;
|
||||
}
|
||||
handle->x11.width = ev.xconfigure.width;
|
||||
handle->x11.height = ev.xconfigure.height;
|
||||
} else if(ev.type == ClientMessage) {
|
||||
};
|
||||
case ClientMessage:
|
||||
{
|
||||
|
||||
if(ev.xclient.message_type == handle->x11.wm_protocols && ev.xclient.data.l[0] == (long)handle->x11.wm_delete) {
|
||||
MwLLDispatch(handle, close, NULL);
|
||||
}
|
||||
} else if(ev.type == FocusIn) {
|
||||
|
||||
if(
|
||||
ev.xclient.message_type == handle->x11.xdnd_enter ||
|
||||
ev.xclient.message_type == handle->x11.xdnd_selection ||
|
||||
ev.xclient.message_type == handle->x11.xdnd_drop) {
|
||||
char* name = XGetAtomName(handle->x11.display, ev.xclient.message_type);
|
||||
|
||||
printf("%s\n", name);
|
||||
|
||||
if(ev.xclient.message_type == handle->x11.xdnd_enter) {
|
||||
Bool list = ev.xclient.data.l[1] & 1;
|
||||
int version = ev.xclient.data.l[1] >> 24;
|
||||
unsigned long count = 0;
|
||||
unsigned char* formats = NULL;
|
||||
handle->x11.xdnd_source = ev.xclient.data.l[0];
|
||||
|
||||
unsigned long i;
|
||||
if(list) {
|
||||
Atom actualType;
|
||||
int32_t actualFormat;
|
||||
unsigned long bytesAfter;
|
||||
|
||||
XGetWindowProperty((Display*)handle->x11.display,
|
||||
handle->x11.xdnd_source,
|
||||
handle->x11.xdnd_type_list,
|
||||
0,
|
||||
LONG_MAX,
|
||||
False,
|
||||
4,
|
||||
&actualType,
|
||||
&actualFormat,
|
||||
&count,
|
||||
&bytesAfter,
|
||||
(unsigned char**)&formats);
|
||||
} else {
|
||||
count = 0;
|
||||
|
||||
if(ev.xclient.data.l[2] != None)
|
||||
formats[count++] = ev.xclient.data.l[2];
|
||||
if(ev.xclient.data.l[3] != None)
|
||||
formats[count++] = ev.xclient.data.l[3];
|
||||
if(ev.xclient.data.l[4] != None)
|
||||
formats[count++] = ev.xclient.data.l[4];
|
||||
}
|
||||
|
||||
for(i = 0; i < count; i++) {
|
||||
if(formats[i] == handle->x11.xdnd_text_uri_list || formats[i] == handle->x11.xdnd_text_plain) {
|
||||
handle->x11.format = formats[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(list) {
|
||||
XFree(formats);
|
||||
}
|
||||
}
|
||||
if(ev.xclient.message_type == handle->x11.xdnd_selection && handle->x11.xdnd_version >= 5) {
|
||||
XEvent reply;
|
||||
reply.xclient.message_type = handle->x11.xdnd_status;
|
||||
|
||||
if(handle->x11.format) {
|
||||
reply.xclient.data.l[1] = 1;
|
||||
if(handle->x11.xdnd_version >= 2)
|
||||
reply.xclient.data.l[4] = handle->x11.xdnd_action_copy;
|
||||
}
|
||||
XSendEvent(handle->x11.display, handle->x11.xdnd_source, False, NoEventMask, &reply);
|
||||
XFlush(handle->x11.display);
|
||||
}
|
||||
if(ev.xclient.message_type == handle->x11.xdnd_drop && handle->x11.xdnd_version >= 5) {
|
||||
printf("whar\n");
|
||||
}
|
||||
|
||||
XFree(name);
|
||||
}
|
||||
break;
|
||||
};
|
||||
case FocusIn:
|
||||
{
|
||||
MwLLDispatch(handle, focus_in, NULL);
|
||||
} else if(ev.type == FocusOut) {
|
||||
break;
|
||||
};
|
||||
case FocusOut:
|
||||
{
|
||||
MwLLDispatch(handle, focus_out, NULL);
|
||||
} else if(ev.type == MotionNotify) {
|
||||
break;
|
||||
};
|
||||
case MotionNotify:
|
||||
{
|
||||
MwPoint p;
|
||||
XWindowAttributes attr;
|
||||
|
||||
|
|
@ -780,7 +899,11 @@ static void MwLLNextEventImpl(MwLL handle) {
|
|||
if(handle->x11.grabbed && (p.x != 0 || p.y != 0)) {
|
||||
XWarpPointer(handle->x11.display, None, handle->x11.window, 0, 0, 0, 0, attr.width / 2, attr.height / 2);
|
||||
}
|
||||
} else if(ev.type == KeyPress || ev.type == KeyRelease) {
|
||||
break;
|
||||
};
|
||||
case KeyPress:
|
||||
case KeyRelease:
|
||||
{
|
||||
int n = -1;
|
||||
char str[512];
|
||||
KeySym sym;
|
||||
|
|
@ -844,7 +967,10 @@ static void MwLLNextEventImpl(MwLL handle) {
|
|||
MwLLDispatch(handle, key_released, &n);
|
||||
}
|
||||
}
|
||||
} else if(ev.type == SelectionNotify) {
|
||||
break;
|
||||
};
|
||||
case SelectionNotify:
|
||||
{
|
||||
handle->x11.clipboard_pending = 0;
|
||||
|
||||
if(ev.xselection.property != None) {
|
||||
|
|
@ -887,6 +1013,7 @@ static void MwLLNextEventImpl(MwLL handle) {
|
|||
|
||||
XDeleteProperty(handle->x11.display, handle->x11.window, handle->x11.selection);
|
||||
}
|
||||
} break;
|
||||
}
|
||||
if(render) {
|
||||
int x, y;
|
||||
|
|
@ -1512,6 +1639,8 @@ static int MwLLX11CallInitImpl(void) {
|
|||
X11_FUNC_LOAD(XSetICFocus);
|
||||
X11_FUNC_LOAD(XGetImage);
|
||||
X11_FUNC_LOAD(XRaiseWindow);
|
||||
X11_FUNC_LOAD(XFlush);
|
||||
X11_FUNC_LOAD(XGetAtomName);
|
||||
|
||||
X11_FUNC_LOAD(XAllocSizeHints);
|
||||
X11_FUNC_LOAD(XGetVisualInfo);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue