1 /************************************************************************/
2 /* */
3 /* Simple io streams using X11 windows properties. */
4 /* */
5 /************************************************************************/
6
7 # include "appFrameConfig.h"
8
9 # include <stdlib.h>
10
11 # include "sioXprop.h"
12
13 # include <appDebugon.h>
14
15 # ifdef USE_MOTIF
16
17 # include <X11/Xlib.h>
18 # include <X11/Xatom.h>
19
20 # define ADEB(d,a) SDEB(((a)==None?"None":XGetAtomName((d),(a))))
21
22 /************************************************************************/
23 /* */
24 /* Input.. Paste. */
25 /* */
26 /************************************************************************/
27
28 typedef struct XpropPasteStream
29 {
30 Display * xpsDisplay;
31 APP_WINDOW xpsWindow;
32 APP_ATOM xpsProperty;
33 long xpsOffset;
34 long xpsExhausted;
35
36 int xpsDeleteOnClose;
37 } XpropPasteStream;
38
sioXpropPasteClose(void * voidxps)39 static int sioXpropPasteClose( void * voidxps )
40 {
41 XpropPasteStream * xps= (XpropPasteStream *)voidxps;
42
43 if ( xps->xpsDeleteOnClose )
44 {
45 XDeleteProperty( xps->xpsDisplay, xps->xpsWindow, xps->xpsProperty );
46 }
47
48 free( voidxps );
49
50 return 0;
51 }
52
sioInXpropReadBytes(void * voidxps,unsigned char * buffer,unsigned int count)53 static int sioInXpropReadBytes( void * voidxps,
54 unsigned char * buffer,
55 unsigned int count )
56 {
57 XpropPasteStream * xps= (XpropPasteStream *)voidxps;
58
59 Atom typeFound;
60 int formatFound;
61
62 unsigned long itemsReturned;
63 unsigned long itemsLeft;
64 unsigned char * dataReturned;
65
66 int ret;
67
68 if ( xps->xpsExhausted )
69 { return -1; }
70
71 ret= XGetWindowProperty( xps->xpsDisplay, xps->xpsWindow, xps->xpsProperty,
72 xps->xpsOffset/4, count/4, False, AnyPropertyType,
73 &typeFound, &formatFound,
74 &itemsReturned, &itemsLeft, &dataReturned );
75
76 if ( ret != Success )
77 { LLDEB(ret,Success); return -1; }
78 if ( itemsReturned == 0 )
79 { LDEB(itemsReturned); return -1; }
80 if ( formatFound != 8 )
81 { LLDEB(typeFound,formatFound); return -1; }
82
83 memcpy( buffer, dataReturned, itemsReturned );
84 XFree( dataReturned );
85
86 xps->xpsOffset += itemsReturned;
87 if ( itemsLeft == 0 )
88 { xps->xpsExhausted= 1; }
89
90 return itemsReturned;
91 }
92
sioInOpenPaste(APP_WIDGET w,APP_EVENT * event)93 SimpleInputStream * sioInOpenPaste( APP_WIDGET w,
94 APP_EVENT * event )
95 {
96 XSelectionEvent * selEvent= &(event->xselection);
97
98 SimpleInputStream * sis;
99 XpropPasteStream * xps;
100
101 xps= (XpropPasteStream *)malloc( sizeof( XpropPasteStream ) );
102 if ( ! xps )
103 { XDEB(xps); return (SimpleInputStream *)0; }
104
105 xps->xpsDisplay= XtDisplay( w );
106 xps->xpsWindow= XtWindow( w );
107 xps->xpsProperty= selEvent->property;
108 xps->xpsOffset= 0L;
109 xps->xpsExhausted= 0;
110 xps->xpsDeleteOnClose= 1;
111
112 sis= sioInOpen( (void *)xps, sioInXpropReadBytes, sioXpropPasteClose );
113
114 if ( ! sis )
115 { XDEB(sis); free( xps ); return (SimpleInputStream *)0; }
116
117 return sis;
118 }
119
120 /************************************************************************/
121 /* */
122 /* Output.. Copy. */
123 /* */
124 /************************************************************************/
125
126 typedef struct XpropCopyStream
127 {
128 Display * xcsDisplay;
129 APP_WINDOW xcsRequestor;
130 Atom xcsProperty;
131 Atom xcsTarget;
132 int xcsPropMode;
133 } XpropCopyStream;
134
sioXpropCopyClose(void * voidxcs)135 static int sioXpropCopyClose( void * voidxcs )
136 {
137 free( voidxcs );
138
139 return 0;
140 }
141
sioOutCopyWriteBytes(void * voidxcs,const unsigned char * buffer,int count)142 static int sioOutCopyWriteBytes( void * voidxcs,
143 const unsigned char * buffer,
144 int count )
145 {
146 XpropCopyStream * xcs= (XpropCopyStream *)voidxcs;
147
148 XChangeProperty( xcs->xcsDisplay, xcs->xcsRequestor,
149 xcs->xcsProperty, xcs->xcsTarget,
150 8, xcs->xcsPropMode, buffer, count );
151
152 xcs->xcsPropMode= PropModeAppend;
153
154 return count;
155 }
156
sioOutOpenCopy(APP_WIDGET w,APP_EVENT * event)157 SimpleOutputStream * sioOutOpenCopy( APP_WIDGET w,
158 APP_EVENT * event )
159 {
160 XSelectionEvent * selEvent= &(event->xselection);
161 SimpleOutputStream * sos;
162 XpropCopyStream * xcs;
163
164 xcs= (XpropCopyStream *)malloc( sizeof( XpropCopyStream ) );
165 if ( ! xcs )
166 { XDEB(xcs); return (SimpleOutputStream *)0; }
167
168 xcs->xcsDisplay= XtDisplay( w );
169 xcs->xcsRequestor= selEvent->requestor;
170 xcs->xcsProperty= selEvent->property;
171 xcs->xcsTarget= selEvent->target;
172 xcs->xcsPropMode= PropModeReplace;
173
174 sos= sioOutOpen( (void *)xcs, sioOutCopyWriteBytes, sioXpropCopyClose );
175
176 if ( ! sos )
177 { XDEB(sos); free( xcs ); return (SimpleOutputStream *)0; }
178
179 return sos;
180 }
181
182 # endif
183