2 Copyright © 1995-2011, 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.1 (19.2.2015)\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 replyport
.mp_Node
.ln_Type
= NT_MSGPORT
;
219 replyport
.mp_Node
.ln_Name
= NULL
;
220 replyport
.mp_Node
.ln_Pri
= 0;
221 replyport
.mp_Flags
= PA_SIGNAL
;
222 replyport
.mp_SigBit
= SIGB_SINGLE
;
223 replyport
.mp_SigTask
= FindTask(NULL
);
224 NewList(&replyport
.mp_MsgList
);
226 msg
.msg
.mn_Node
.ln_Type
= NT_MESSAGE
;
227 msg
.msg
.mn_ReplyPort
= &replyport
;
228 msg
.msg
.mn_Length
= sizeof(msg
);
230 msg
.code
= ToUpper(sgw
->Code
);
233 if ((msg
.code
== CODE_COPY
) || (sgw
->NumChars
< sgw
->StringInfo
->MaxChars
- 1))
235 SetSignal(0, SIGF_SINGLE
);
236 PutMsg(port
, &msg
.msg
);
237 WaitPort(&replyport
);
240 if (msg
.code
== CODE_PASTE
)
242 WORD len
= strlen(sgw
->WorkBuffer
);
244 if (len
!= sgw
->NumChars
)
247 sgw
->EditOp
= EO_BIGCHANGE
;
248 sgw
->Actions
= SGA_USE
| SGA_REDISPLAY
;
253 } /* if (msg.code == CODE_COPY) */
255 } /* if ((port = FindPort(CONCLIP_PORTNAME))) */
259 } /* switch(ToUpper(sgw->Code)) */
261 } /* if (sgw->IEvent->ie_Qualifier & IEQUALIFIER_RCOMMAND) */
264 } /* switch (*command) */
266 if (calloldhook
) retcode
= CallHookPkt(oldedithook
, sgw
, command
);
273 /*****************************************************************************************/
275 static void installedithook(void)
277 edithook
.h_Entry
= (HOOKFUNC
)AROS_ASMSYMNAME(conclipeditfunc
);
278 edithook
.h_SubEntry
= NULL
;
279 edithook
.h_Data
= NULL
;
281 oldedithook
= SetEditHook(&edithook
);
284 /*****************************************************************************************/
285 /*****************************************************************************************/
286 /*****************************************************************************************/
288 static void savetoclipboard(struct SGWork
*sgw
)
290 struct IFFHandle
*iff
;
292 if((iff
= AllocIFF()))
294 if((iff
->iff_Stream
= (IPTR
)OpenClipboard(clipunit
)))
297 if(!OpenIFF(iff
,IFFF_WRITE
))
299 if(!PushChunk(iff
, ID_FTXT
, ID_FORM
, IFFSIZE_UNKNOWN
))
301 if(!PushChunk(iff
, ID_FTXT
, ID_CHRS
, IFFSIZE_UNKNOWN
))
303 WriteChunkBytes(iff
, sgw
->WorkBuffer
, sgw
->NumChars
);
307 } /* if(!PushChunk(iff, ID_FTXT, ID_CHRS, IFFSIZE_UNKNOWN)) */
310 } /* if(!PushChunk(iff, ID_FTXT, ID_FORM, IFFSIZE_UNKNOWN)) */
313 } /* if(!OpenIFF(iff,IFFF_WRITE)) */
314 CloseClipboard((struct ClipboardHandle
*)iff
->iff_Stream
);
316 } /* if((iff->iff_Stream = (IPTR)OpenClipboard(clipunit))) */
319 } /* if((iff = AllocIFF()))) */
322 /*****************************************************************************************/
324 static void readfromclipboard(struct SGWork
*sgw
)
326 struct IFFHandle
*iff
;
327 struct ContextNode
*cn
;
329 if((iff
= AllocIFF()))
331 D(bug("ConClip/conclipeditfunc: AllocIFF okay\n"));
333 if((iff
->iff_Stream
= (IPTR
)OpenClipboard(clipunit
)))
335 D(bug("ConClip/conclipeditfunc: OpenClipboard okay\n"));
338 if(!OpenIFF(iff
, IFFF_READ
))
340 D(bug("ConClip/conclipeditfunc: OpenIff okay\n"));
342 if (!(StopChunk(iff
, ID_FTXT
, ID_CHRS
)))
344 D(bug("ConClip/conclipeditfunc: StopChunk okay\n"));
346 if (!ParseIFF(iff
, IFFPARSE_SCAN
))
348 D(bug("ConClip/conclipeditfunc: ParseIFF okay\n"));
350 cn
= CurrentChunk(iff
);
351 if ((cn
->cn_Type
== ID_FTXT
) && (cn
->cn_ID
== ID_CHRS
) && (cn
->cn_Size
> 0))
355 D(bug("ConClip: readfromclipboard: Found FTXT CHRS Chunk\n"));
356 D(bug("ConClip: readfromclipboard: Old text = \"%s\"\n", sgw
->WorkBuffer
));
358 readsize
= sgw
->StringInfo
->MaxChars
- 1 - sgw
->BufferPos
;
359 if (cn
->cn_Size
< readsize
) readsize
= cn
->cn_Size
;
362 memmove(sgw
->WorkBuffer
+ sgw
->BufferPos
+ readsize
,
363 sgw
->WorkBuffer
+ sgw
->BufferPos
,
364 sgw
->StringInfo
->MaxChars
- sgw
->BufferPos
- readsize
);
365 ReadChunkBytes(iff
, sgw
->WorkBuffer
+ sgw
->BufferPos
, readsize
);
367 D(bug("ConClip: readfromclipboard: New text = \"%s\"\n", sgw
->WorkBuffer
));
369 sgw
->BufferPos
+= readsize
;
372 } /* if ((cn->cn_Type == ID_FTXT) && (cn->cn_ID == ID_CHRS) && (cn->cn_Size > 0)) */
374 } /* if (!ParseIFF(iff, IFFPARSE_SCAN)) */
376 } /* if (!(StopChunk(iff, ID_FTXT, ID_CHRS))) */
380 } /* if(!OpenIFF(iff, IFFF_READ)) */
381 CloseClipboard((struct ClipboardHandle
*)iff
->iff_Stream
);
383 } /* if((iff->iff_Stream = (IPTR)OpenClipboard(clipunit))) */
386 } /* if((iff = AllocIFF()))) */
389 /*****************************************************************************************/
391 static void handleall(void)
398 sigs
= Wait(SIGBREAKF_CTRL_C
| portmask
);
402 struct MyEditHookMsg
*msg
;
404 while((msg
= (struct MyEditHookMsg
*)GetMsg(progport
)))
409 D(bug("ConClip: Received CODE_COPY message\n"));
410 savetoclipboard(msg
->sgw
);
414 D(bug("ConClip: Received CODE_PASTE message\n"));
415 readfromclipboard(msg
->sgw
);
418 } /* switch(msg->code) */
422 } /* while((msg = (struct MyEditHookMsg *)GetMsg(progport))) */
424 } /* if (sigs & portmask) */
426 if (sigs
& SIGBREAKF_CTRL_C
) quitme
= TRUE
;
428 } /* while(!quitme) */
431 /*****************************************************************************************/
449 /*****************************************************************************************/