qemacs-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemacs-commit] qemacs x11.c


From: Charlie Gordon
Subject: [Qemacs-commit] qemacs x11.c
Date: Fri, 07 Feb 2014 07:55:24 +0000

CVSROOT:        /sources/qemacs
Module name:    qemacs
Changes by:     Charlie Gordon <chqrlie>        14/02/07 07:55:22

Modified files:
        .              : x11.c 

Log message:
        add support for wm_delete_window and utf8 clipboard in x11 (Francois 
Revol)

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/qemacs/x11.c?cvsroot=qemacs&r1=1.32&r2=1.33

Patches:
Index: x11.c
===================================================================
RCS file: /sources/qemacs/qemacs/x11.c,v
retrieving revision 1.32
retrieving revision 1.33
diff -u -b -r1.32 -r1.33
--- x11.c       6 Feb 2014 00:26:25 -0000       1.32
+++ x11.c       7 Feb 2014 07:54:27 -0000       1.33
@@ -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;charset=UTF-8", 
False);
+        xa_formats[2] = XInternAtom(display, "text/plain;charset=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)];
+        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,52 @@
                         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((char *)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 +1316,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);



reply via email to

[Prev in Thread] Current Thread [Next in Thread]