This patch adds UTF-8 clipboard support, and includes the previous uncommitted wm_delete patch.
François.
Index: x11.c =================================================================== RCS file: /sources/qemacs/qemacs/x11.c,v retrieving revision 1.32 diff -u -r1.32 x11.c --- x11.c 6 Feb 2014 00:26:25 -0000 1.32 +++ x11.c 6 Feb 2014 21:44:01 -0000 @@ -55,6 +55,7 @@ static Display *display; static int xscreen; static Window window; +static Atom wm_delete_window; static GC gc, gc_pixmap; static XWindowAttributes attr; static int event_mask; @@ -319,6 +320,9 @@ XNFocusWindow, window, NULL); + wm_delete_window = XInternAtom (display, "WM_DELETE_WINDOW", False); + XSetWMProtocols (display, window, &wm_delete_window, 1); + gc = XCreateGC(display, window, 0, NULL); #ifdef CONFIG_XFT renderDraw = XftDrawCreate(display, window, attr.visual, @@ -1074,6 +1078,7 @@ QEmacsState *qs = &qe_state; Window w; Atom prop; + Atom utf8; long nread; unsigned char *data; Atom actual_type; @@ -1089,7 +1094,8 @@ /* use X11 selection (Will be pasted when receiving SelectionNotify event) */ prop = XInternAtom(display, "VT_SELECTION", False); - XConvertSelection(display, XA_PRIMARY, XA_STRING, + utf8 = XInternAtom(display, "UTF8_STRING", False); + XConvertSelection(display, XA_PRIMARY, utf8, prop, window, CurrentTime); /* XXX: add timeout too if the target application is not well @@ -1110,7 +1116,7 @@ AnyPropertyType, &actual_type, &actual_fmt, &nitems, &bytes_after, &data) != Success) || - (actual_type != XA_STRING)) { + (actual_type != utf8)) { XFree(data); break; } @@ -1129,6 +1135,7 @@ static void selection_send(XSelectionRequestEvent *rq) { static Atom xa_targets = None; + static Atom xa_formats[] = { None, None, None, None }; QEmacsState *qs = &qe_state; unsigned char *buf; XEvent ev; @@ -1136,6 +1143,12 @@ if (xa_targets == None) xa_targets = XInternAtom(display, "TARGETS", False); + if (xa_formats[0] == None) { + xa_formats[0] = XInternAtom(display, "UTF8_STRING", False); + xa_formats[1] = XInternAtom(display, "text/plain;charse=UTF-8", False); + xa_formats[2] = XInternAtom(display, "text/plain;charse=utf-8", False); + xa_formats[3] = XA_STRING; + } ev.xselection.type = SelectionNotify; ev.xselection.property = None; @@ -1146,11 +1159,13 @@ ev.xselection.time = rq->time; if (rq->target == xa_targets) { - unsigned int target_list[2]; + unsigned int target_list[1 + countof(xa_formats)]; + unsigned int i; /* indicate which are supported types */ target_list[0] = xa_targets; - target_list[1] = XA_STRING; + for (i = 0; i < countof(xa_formats); i++) + target_list[i + 1] = xa_formats[i]; XChangeProperty(display, rq->requestor, rq->property, xa_targets, 8*sizeof(target_list[0]), PropModeReplace, @@ -1171,6 +1186,50 @@ XA_STRING, 8, PropModeReplace, buf, b->total_size); qe_free(&buf); + } else if (rq->target == xa_formats[0] || rq->target == xa_formats[1] + || rq->target == xa_formats[2]) { + int len; + /* get qemacs yank buffer */ + + b = qs->yank_buffers[qs->yank_current]; + if (!b) + return; + buf = qe_malloc_array(unsigned char, b->total_size); + if (!buf) + return; + eb_read(b, 0, buf, b->total_size); + len = b->total_size; + + /* if not UTF-8 we must convert to it */ + if (!(b->flags & BF_UTF8)) { + struct CharsetDecodeState st; + unsigned char *utf_buf, *p; + + utf_buf = qe_malloc_array(unsigned char, b->total_size * 6); + if (!utf_buf) { + qe_free(&buf); + return; + } + + charset_decode_init(&st, b->charset, b->eol_type); + st.p = buf; + p = utf_buf; + for (;;) { + int c = st.decode_func(&st); + if (c == 0) + break; + p += utf8_encode(p, c); + } + + qe_free(&buf); + len = p - utf_buf; + buf = utf_buf; + } + + XChangeProperty(display, rq->requestor, rq->property, + rq->target, 8, PropModeReplace, + buf, len); + qe_free(&buf); } ev.xselection.property = rq->property; XSendEvent(display, rq->requestor, False, 0, &ev); @@ -1255,6 +1314,22 @@ while (XPending(display)) { XNextEvent(display, &xev); switch (xev.type) { + case ClientMessage: + if ((Atom)xev.xclient.data.l[0] == wm_delete_window) { + // cancel pending operation + ev->key_event.type = QE_KEY_EVENT; + ev->key_event.key = KEY_CTRL('g'); + qe_handle_event(ev); + + // simulate C-x C-c + ev->key_event.type = QE_KEY_EVENT; + ev->key_event.key = KEY_CTRL('x'); + qe_handle_event(ev); + ev->key_event.type = QE_KEY_EVENT; + ev->key_event.key = KEY_CTRL('c'); + qe_handle_event(ev); + } + break; case ConfigureNotify: if (term_resize(s, xev.xconfigure.width, xev.xconfigure.height)) { qe_expose_set(s, rgn, 0, 0, s->width, s->height);
_______________________________________________ Qemacs-devel mailing list Qemacs-devel@nongnu.org https://lists.nongnu.org/mailman/listinfo/qemacs-devel