Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't snarf/exchange from sam to any mac program #93

Open
mikerosenberg opened this issue Oct 12, 2018 · 12 comments
Open

Can't snarf/exchange from sam to any mac program #93

mikerosenberg opened this issue Oct 12, 2018 · 12 comments

Comments

@mikerosenberg
Copy link

I can exchange/paste from any mac program into sam, but not the opposite. I've tried every combination of snarfselection and xquartz pasteboard settings. Using high sierra and latest xquartz. Other x programs (xterm) work fine both ways. So I think it's a bug in sam. Exchange is pulling from the mac clipboard, but won't push to it.

@TobiasKarnat
Copy link

I had the same problem on Windows (with WSL + VcXsrv), I could not exchange to Win programs.
Please try the following patch, maybe it fixes sam for you on Mac as well.

diff -urN sam/libXg/gwin.c sam/libXg/gwin.c
--- sam/libXg/gwin.c	2019-09-04 16:49:39.787344298 +0200
+++ sam/libXg/gwin.c	2019-09-04 16:51:12.022520177 +0200
@@ -7,6 +7,8 @@
 #include <X11/Xatom.h>
 #include <X11/XKBlib.h>
 #include <X11/keysym.h>
+#include <X11/Xmu/Atoms.h>
+#include <X11/Xmu/StdSel.h>
 
 #include "GwinP.h"
 #include "libgint.h"
@@ -488,12 +490,35 @@
 SendSel(Widget w, Atom *sel, Atom *target, Atom *rtype, XtPointer *ans,
         uint64_t *anslen, int *ansfmt)
 {
-    GwinWidget gw = (GwinWidget)w;
-    XTextProperty p = {0};
-    char *ls[2] = {NULL, NULL};
+    Display* d = XtDisplay(w);
+
+    if (*target == XA_TARGETS(d)){
+        XSelectionRequestEvent* req =
+        XtGetSelectionRequest(w, *sel, (XtRequestId)NULL);
+
+        Atom* targetP;
+        Atom* std_targets;
+        unsigned long std_length;
+        XmuConvertStandardSelection(w, req->time, sel, target, rtype,
+                        (XPointer *)&std_targets, &std_length,
+                        ansfmt);
+        *ans = (XtPointer)XtMalloc(sizeof(Atom)*(std_length + 1));
+        targetP = *(Atom**)ans;
+        *targetP++ = XA_STRING;
+        *anslen = std_length + (targetP - (*(Atom **) ans));
+        memmove( (char*)targetP, (char*)std_targets, sizeof(Atom)*std_length);
+        XtFree((char*)std_targets);
+        *rtype = XA_ATOM;
+        *ansfmt = 32;
+        return true;
+    }
 
     if ((*target == XA_STRING) ||
         (*target == XInternAtom(_dpy, "UTF8_STRING", 0))){
+        GwinWidget gw = (GwinWidget)w;
+        XTextProperty p = {0};
+        char *ls[2] = {NULL, NULL};
+
         ls[0] = gw->gwin.selection? gw->gwin.selection : "";
         if (XmbTextListToTextProperty(_dpy, ls, 1, XUTF8StringStyle, &p) != Success)
             return false;
diff -urN sam/samterm/Makefile sam/samterm/Makefile
--- sam/samterm/Makefile	2019-09-04 16:49:39.795344574 +0200
+++ sam/samterm/Makefile	2019-09-04 16:51:34.483293498 +0200
@@ -15,7 +15,7 @@
 
 #	set this if your X libraries are in different locations
 #	or if you need extra libraries to load with X11 applications
-XLIBS=-lXt -lX11 -lXft -lXi
+XLIBS=-lXt -lX11 -lXft -lXi -lXmu
 
 CFLAGS+=$(INCS) $(STANDARDS) $(INCLUDES)
 

@TobiasKarnat
Copy link

My optimized version of the patch

diff -urN sam/libXg/gwin.c sam/libXg/gwin.c
--- sam/libXg/gwin.c	2019-09-05 19:58:44.982208690 +0200
+++ sam/libXg/gwin.c	2019-09-05 20:00:09.889502801 +0200
@@ -7,6 +7,7 @@
 #include <X11/Xatom.h>
 #include <X11/XKBlib.h>
 #include <X11/keysym.h>
+#include <X11/Xmu/Atoms.h>
 
 #include "GwinP.h"
 #include "libgint.h"
@@ -488,12 +489,25 @@
 SendSel(Widget w, Atom *sel, Atom *target, Atom *rtype, XtPointer *ans,
         uint64_t *anslen, int *ansfmt)
 {
-    GwinWidget gw = (GwinWidget)w;
-    XTextProperty p = {0};
-    char *ls[2] = {NULL, NULL};
+    Display* d = XtDisplay(w);
+
+    if (*target == XA_TARGETS(d)){
+        Atom* targets = (Atom*)XtMalloc(sizeof(Atom));
+        *targets = XA_STRING;
+
+        *rtype = XA_ATOM;
+        *ans = (XtPointer)targets;
+        *anslen = 1;
+        *ansfmt = 32;
+        return true;
+    }
 
     if ((*target == XA_STRING) ||
         (*target == XInternAtom(_dpy, "UTF8_STRING", 0))){
+        GwinWidget gw = (GwinWidget)w;
+        XTextProperty p = {0};
+        char *ls[2] = {NULL, NULL};
+
         ls[0] = gw->gwin.selection? gw->gwin.selection : "";
         if (XmbTextListToTextProperty(_dpy, ls, 1, XUTF8StringStyle, &p) != Success)
             return false;
diff -urN sam/samterm/Makefile sam/samterm/Makefile
--- sam/samterm/Makefile	2019-09-05 19:58:44.984208721 +0200
+++ sam/samterm/Makefile	2019-09-05 19:58:52.471322835 +0200
@@ -15,7 +15,7 @@
 
 #	set this if your X libraries are in different locations
 #	or if you need extra libraries to load with X11 applications
-XLIBS=-lXt -lX11 -lXft -lXi
+XLIBS=-lXt -lX11 -lXft -lXi -lXmu
 
 CFLAGS+=$(INCS) $(STANDARDS) $(INCLUDES)
 

@mikerosenberg
Copy link
Author

mikerosenberg commented Sep 6, 2019 via email

@TobiasKarnat
Copy link

TobiasKarnat commented Sep 6, 2019

Could you try (uint32_t instead of uint64_t and cast to const char*)?:

SelCallback(Widget w, XtPointer cldata, Atom *sel, Atom *seltype,
    XtPointer val, uint32_t *len, int *fmt)

    gw->gwin.selection = strdup((const char*)p.value);

SendSel(Widget w, Atom *sel, Atom *target, Atom *rtype, XtPointer *ans,
        uint32_t *anslen, int *ansfmt)

        *ans = (XtPointer) XtNewString((const char*)p.value);

@mikerosenberg
Copy link
Author

mikerosenberg commented Sep 6, 2019 via email

@TobiasKarnat
Copy link

Strange, uint64_t is unsigned long long and uint32_t is unsigned int on mac.
https://stackoverflow.com/a/11603907

But we need unsigned long, sorry I don't know the C99 type for mac:

SelCallback(Widget w, XtPointer cldata, Atom *sel, Atom *seltype,
XtPointer val, unsigned long *len, int *fmt)

SendSel(Widget w, Atom *sel, Atom *target, Atom *rtype, XtPointer *ans,
unsigned long *anslen, int *ansfmt)

@mikerosenberg
Copy link
Author

mikerosenberg commented Sep 6, 2019 via email

@TobiasKarnat
Copy link

Did it crash before adding the cast? Sorry I'm a systems engineer and not a programmer.
Do you have .xsession-errors also available under mac? Maybe there are more information.

@mikerosenberg
Copy link
Author

mikerosenberg commented Sep 6, 2019 via email

@mikerosenberg
Copy link
Author

mikerosenberg commented Sep 9, 2019 via email

@deadpixi
Copy link
Owner

Sorry for the late response, everyone. Personal and work obligations have been...obligating.

I'm happy to help, but I don't have a Mac.

@mikerosenberg Could you paste the warnings you get with the latest code?

@TobiasKarnat Thanks for all your help on this issue.

X is finicky about types and sizes, unfortunately. I was too hasty on C99-ifying the code, I think. I'll see if I can adapt the patches above to something that's a bit more X11-type aware. It may be a day or two, though.

@mikerosenberg
Copy link
Author

mikerosenberg commented Sep 10, 2019 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants