2 Copyright © 1995-2018, The AROS Development Team. All rights reserved.
5 Desc: Conclip CLI command
8 /******************************************************************************
16 CONCLIP [ [UNIT | CLIPUNIT] <unitnumber>] [OFF]
20 CLIPUNIT=UNIT/N, ON/S, OFF/S
28 Enable clipboard cut/copy/paste functionality in console windows
29 and string gadgets. This enables the use of a system global clipboard.
33 CLIPUNIT=UNIT -- the number associated to the clipboard exchange unit
34 ON/S -- Activates conclip (default unit will be set to 1)
35 OFF/S -- Deactivates Conclip
45 This will set the global clipboard unit to 1. The available clipboards
46 can be checked in clips: dirDir Clips:
56 ******************************************************************************//*****************************************************************************************/
58 #include <aros/asmcall.h>
60 #include <intuition/intuition.h>
61 #include <intuition/sghooks.h>
62 #include <intuition/classusr.h>
63 #include <libraries/iffparse.h>
64 #include <devices/inputevent.h>
65 #include <datatypes/textclass.h>
66 #include <utility/hooks.h>
67 #include <proto/exec.h>
68 #include <proto/dos.h>
69 #include <proto/intuition.h>
70 #include <proto/iffparse.h>
71 #include <proto/alib.h>
72 #include <proto/utility.h>
78 #include <aros/debug.h>
80 /*****************************************************************************************/
82 #define ARG_TEMPLATE "CLIPUNIT=UNIT/N,OFF/S"
83 #define ARG_CLIPUNIT 0
87 /*****************************************************************************************/
90 #define CODE_PASTE 'V'
92 const TEXT version
[] = "$VER: Conclip 42.2 (27.5.2018)\n";
101 /*****************************************************************************************/
103 const STRPTR CONCLIP_TASKNAME
= "« ConClip »";
104 const STRPTR CONCLIP_PORTNAME
= "ConClip.rendezvous";
106 /*****************************************************************************************/
108 static struct MsgPort
*progport
;
109 static struct Hook edithook
, *oldedithook
;
110 static struct Task
*progtask
;
111 static ULONG clipunit
, portmask
;
115 /*****************************************************************************************/
117 static void cleanup(STRPTR msg
)
119 if (msg
) Printf("ConClip: %s\n", msg
);
121 if (oldedithook
) SetEditHook(oldedithook
);
122 if (progport
) DeletePort(progport
);
125 /*****************************************************************************************/
127 static void init(void)
129 progtask
= FindTask(NULL
);
130 ((struct Process
*)progtask
)->pr_WindowPtr
= (APTR
)-1;
133 /*****************************************************************************************/
135 static BOOL
getarguments(void)
137 struct RDArgs
*myargs
;
138 IPTR args
[NUM_ARGS
] = {0, 0};
140 if (!(myargs
= ReadArgs(ARG_TEMPLATE
, args
, NULL
)))
142 Fault(IoErr(), 0, s
, 255);
147 if (args
[ARG_CLIPUNIT
]) clipunit
= (ULONG
)(*(IPTR
*)args
[ARG_CLIPUNIT
]);
148 if (args
[ARG_OFF
]) off
= args
[ARG_OFF
] ? TRUE
: FALSE
;
154 /*****************************************************************************************/
156 static BOOL
checkport(void)
159 progport
= FindPort(CONCLIP_PORTNAME
);
162 if (off
) Signal(progport
->mp_SigTask
, SIGBREAKF_CTRL_C
);
168 progport
= CreatePort(CONCLIP_PORTNAME
, 1);
173 cleanup("Could not create MsgPort!");
177 portmask
= 1L << progport
->mp_SigBit
;
181 /*****************************************************************************************/
183 AROS_UFH3(ULONG
, conclipeditfunc
,
184 AROS_UFHA(struct Hook
*, hook
, A0
),
185 AROS_UFHA(struct SGWork
*, sgw
, A2
),
186 AROS_UFHA(ULONG
*, command
, A1
)
191 struct MsgPort
*port
, replyport
;
192 struct MyEditHookMsg msg
;
193 BOOL calloldhook
= TRUE
;
199 D(bug("ConClip/conclipeditfunc: is SGH_KEY\n"));
201 if (sgw
->IEvent
->ie_Qualifier
& IEQUALIFIER_RCOMMAND
)
203 D(bug("ConClip/conclipeditfunc: qualifier RCOMMAND okay\n"));
205 switch(ToUpper(sgw
->Code
))
208 if (!sgw
->NumChars
) break;
212 D(bug("ConClip/conclipeditfunc: key = %c\n", toupper(sgw
->Code
)));
214 if ((port
= FindPort(CONCLIP_PORTNAME
)))
218 memset( &replyport
, 0, sizeof( replyport
) );
219 replyport
.mp_Node
.ln_Type
= NT_MSGPORT
;
220 replyport
.mp_Flags
= PA_SIGNAL
;
221 replyport
.mp_SigBit
= SIGB_SINGLE
;
222 replyport
.mp_SigTask
= FindTask(NULL
);
223 NewList(&replyport
.mp_MsgList
);
225 msg
.msg
.mn_Node
.ln_Type
= NT_MESSAGE
;
226 msg
.msg
.mn_ReplyPort
= &replyport
;
227 msg
.msg
.mn_Length
= sizeof(msg
);
229 msg
.code
= ToUpper(sgw
->Code
);
232 if ((msg
.code
== CODE_COPY
) || (sgw
->NumChars
< sgw
->StringInfo
->MaxChars
- 1))
234 SetSignal(0, SIGF_SINGLE
);
235 PutMsg(port
, &msg
.msg
);
236 WaitPort(&replyport
);
239 if (msg
.code
== CODE_PASTE
)
241 WORD len
= strlen(sgw
->WorkBuffer
);
243 if (len
!= sgw
->NumChars
)
246 sgw
->EditOp
= EO_BIGCHANGE
;
247 sgw
->Actions
= SGA_USE
| SGA_REDISPLAY
;
252 } /* if (msg.code == CODE_COPY) */
254 } /* if ((port = FindPort(CONCLIP_PORTNAME))) */
258 } /* switch(ToUpper(sgw->Code)) */
260 } /* if (sgw->IEvent->ie_Qualifier & IEQUALIFIER_RCOMMAND) */
263 } /* switch (*command) */
265 if (calloldhook
) retcode
= CallHookPkt(oldedithook
, sgw
, command
);
272 /*****************************************************************************************/
274 static void installedithook(void)
276 edithook
.h_Entry
= (HOOKFUNC
)AROS_ASMSYMNAME(conclipeditfunc
);
277 edithook
.h_SubEntry
= NULL
;
278 edithook
.h_Data
= NULL
;
280 oldedithook
= SetEditHook(&edithook
);
283 /*****************************************************************************************/
284 /*****************************************************************************************/
285 /*****************************************************************************************/
287 static void savetoclipboard(struct SGWork
*sgw
)
289 struct IFFHandle
*iff
;
291 if((iff
= AllocIFF()))
293 if((iff
->iff_Stream
= (IPTR
)OpenClipboard(clipunit
)))
296 if(!OpenIFF(iff
,IFFF_WRITE
))
298 if(!PushChunk(iff
, ID_FTXT
, ID_FORM
, IFFSIZE_UNKNOWN
))
300 if(!PushChunk(iff
, ID_FTXT
, ID_CHRS
, IFFSIZE_UNKNOWN
))
302 WriteChunkBytes(iff
, sgw
->WorkBuffer
, sgw
->NumChars
);
306 } /* if(!PushChunk(iff, ID_FTXT, ID_CHRS, IFFSIZE_UNKNOWN)) */
309 } /* if(!PushChunk(iff, ID_FTXT, ID_FORM, IFFSIZE_UNKNOWN)) */
312 } /* if(!OpenIFF(iff,IFFF_WRITE)) */
313 CloseClipboard((struct ClipboardHandle
*)iff
->iff_Stream
);
315 } /* if((iff->iff_Stream = (IPTR)OpenClipboard(clipunit))) */
318 } /* if((iff = AllocIFF()))) */
321 /*****************************************************************************************/
323 static void readfromclipboard(struct SGWork
*sgw
)
325 struct IFFHandle
*iff
;
326 struct ContextNode
*cn
;
328 if((iff
= AllocIFF()))
330 D(bug("ConClip/conclipeditfunc: AllocIFF okay\n"));
332 if((iff
->iff_Stream
= (IPTR
)OpenClipboard(clipunit
)))
334 D(bug("ConClip/conclipeditfunc: OpenClipboard okay\n"));
337 if(!OpenIFF(iff
, IFFF_READ
))
339 D(bug("ConClip/conclipeditfunc: OpenIff okay\n"));
341 if (!(StopChunk(iff
, ID_FTXT
, ID_CHRS
)))
343 D(bug("ConClip/conclipeditfunc: StopChunk okay\n"));
345 if (!ParseIFF(iff
, IFFPARSE_SCAN
))
347 D(bug("ConClip/conclipeditfunc: ParseIFF okay\n"));
349 cn
= CurrentChunk(iff
);
350 if ((cn
->cn_Type
== ID_FTXT
) && (cn
->cn_ID
== ID_CHRS
) && (cn
->cn_Size
> 0))
354 D(bug("ConClip: readfromclipboard: Found FTXT CHRS Chunk\n"));
355 D(bug("ConClip: readfromclipboard: Old text = \"%s\"\n", sgw
->WorkBuffer
));
357 readsize
= sgw
->StringInfo
->MaxChars
- 1 - sgw
->BufferPos
;
358 if (cn
->cn_Size
< readsize
) readsize
= cn
->cn_Size
;
361 memmove(sgw
->WorkBuffer
+ sgw
->BufferPos
+ readsize
,
362 sgw
->WorkBuffer
+ sgw
->BufferPos
,
363 sgw
->StringInfo
->MaxChars
- sgw
->BufferPos
- readsize
);
364 ReadChunkBytes(iff
, sgw
->WorkBuffer
+ sgw
->BufferPos
, readsize
);
366 D(bug("ConClip: readfromclipboard: New text = \"%s\"\n", sgw
->WorkBuffer
));
368 sgw
->BufferPos
+= readsize
;
371 } /* if ((cn->cn_Type == ID_FTXT) && (cn->cn_ID == ID_CHRS) && (cn->cn_Size > 0)) */
373 } /* if (!ParseIFF(iff, IFFPARSE_SCAN)) */
375 } /* if (!(StopChunk(iff, ID_FTXT, ID_CHRS))) */
379 } /* if(!OpenIFF(iff, IFFF_READ)) */
380 CloseClipboard((struct ClipboardHandle
*)iff
->iff_Stream
);
382 } /* if((iff->iff_Stream = (IPTR)OpenClipboard(clipunit))) */
385 } /* if((iff = AllocIFF()))) */
388 /*****************************************************************************************/
390 static void handleall(void)
397 sigs
= Wait(SIGBREAKF_CTRL_C
| portmask
);
401 struct MyEditHookMsg
*msg
;
403 while((msg
= (struct MyEditHookMsg
*)GetMsg(progport
)))
408 D(bug("ConClip: Received CODE_COPY message\n"));
409 savetoclipboard(msg
->sgw
);
413 D(bug("ConClip: Received CODE_PASTE message\n"));
414 readfromclipboard(msg
->sgw
);
417 } /* switch(msg->code) */
421 } /* while((msg = (struct MyEditHookMsg *)GetMsg(progport))) */
423 } /* if (sigs & portmask) */
425 if (sigs
& SIGBREAKF_CTRL_C
) quitme
= TRUE
;
427 } /* while(!quitme) */
430 /*****************************************************************************************/
448 /*****************************************************************************************/