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'
99 /*****************************************************************************************/
101 const STRPTR CONCLIP_TASKNAME
= "ConClip >>";
102 const STRPTR CONCLIP_PORTNAME
= "ConClip.rendezvous";
104 /*****************************************************************************************/
106 static struct MsgPort
*progport
;
107 static struct Hook edithook
, *oldedithook
;
108 static struct Task
*progtask
;
109 static ULONG clipunit
, portmask
;
113 /*****************************************************************************************/
115 static void cleanup(STRPTR msg
)
117 if (msg
) Printf("ConClip: %s\n", msg
);
119 if (oldedithook
) SetEditHook(oldedithook
);
120 if (progport
) DeletePort(progport
);
123 /*****************************************************************************************/
125 static void init(void)
127 progtask
= FindTask(NULL
);
128 ((struct Process
*)progtask
)->pr_WindowPtr
= (APTR
)-1;
131 /*****************************************************************************************/
133 static BOOL
getarguments(void)
135 struct RDArgs
*myargs
;
136 IPTR args
[NUM_ARGS
] = {0, 0};
138 if (!(myargs
= ReadArgs(ARG_TEMPLATE
, args
, NULL
)))
140 Fault(IoErr(), 0, s
, 255);
145 if (args
[ARG_CLIPUNIT
]) clipunit
= (ULONG
)(*(IPTR
*)args
[ARG_CLIPUNIT
]);
146 if (args
[ARG_OFF
]) off
= args
[ARG_OFF
] ? TRUE
: FALSE
;
152 /*****************************************************************************************/
154 static BOOL
checkport(void)
157 progport
= FindPort(CONCLIP_PORTNAME
);
160 if (off
) Signal(progport
->mp_SigTask
, SIGBREAKF_CTRL_C
);
166 progport
= CreatePort(CONCLIP_PORTNAME
, 1);
171 cleanup("Could not create MsgPort!");
175 portmask
= 1L << progport
->mp_SigBit
;
179 /*****************************************************************************************/
181 AROS_UFH3(ULONG
, conclipeditfunc
,
182 AROS_UFHA(struct Hook
*, hook
, A0
),
183 AROS_UFHA(struct SGWork
*, sgw
, A2
),
184 AROS_UFHA(ULONG
*, command
, A1
)
189 struct MsgPort
*port
, replyport
;
190 struct MyEditHookMsg msg
;
191 BOOL calloldhook
= TRUE
;
197 D(bug("ConClip/conclipeditfunc: is SGH_KEY\n"));
199 if (sgw
->IEvent
->ie_Qualifier
& IEQUALIFIER_RCOMMAND
)
201 D(bug("ConClip/conclipeditfunc: qualifier RCOMMAND okay\n"));
203 switch(ToUpper(sgw
->Code
))
206 if (!sgw
->NumChars
) break;
210 D(bug("ConClip/conclipeditfunc: key = %c\n", toupper(sgw
->Code
)));
212 if ((port
= FindPort(CONCLIP_PORTNAME
)))
216 replyport
.mp_Node
.ln_Type
= NT_MSGPORT
;
217 replyport
.mp_Node
.ln_Name
= NULL
;
218 replyport
.mp_Node
.ln_Pri
= 0;
219 replyport
.mp_Flags
= PA_SIGNAL
;
220 replyport
.mp_SigBit
= SIGB_SINGLE
;
221 replyport
.mp_SigTask
= FindTask(NULL
);
222 NewList(&replyport
.mp_MsgList
);
224 msg
.msg
.mn_Node
.ln_Type
= NT_MESSAGE
;
225 msg
.msg
.mn_ReplyPort
= &replyport
;
226 msg
.msg
.mn_Length
= sizeof(msg
);
228 msg
.code
= ToUpper(sgw
->Code
);
231 if ((msg
.code
== CODE_COPY
) || (sgw
->NumChars
< sgw
->StringInfo
->MaxChars
- 1))
233 SetSignal(0, SIGF_SINGLE
);
234 PutMsg(port
, &msg
.msg
);
235 WaitPort(&replyport
);
238 if (msg
.code
== CODE_PASTE
)
240 WORD len
= strlen(sgw
->WorkBuffer
);
242 if (len
!= sgw
->NumChars
)
245 sgw
->EditOp
= EO_BIGCHANGE
;
246 sgw
->Actions
= SGA_USE
| SGA_REDISPLAY
;
251 } /* if (msg.code == CODE_COPY) */
253 } /* if ((port = FindPort(CONCLIP_PORTNAME))) */
257 } /* switch(ToUpper(sgw->Code)) */
259 } /* if (sgw->IEvent->ie_Qualifier & IEQUALIFIER_RCOMMAND) */
262 } /* switch (*command) */
264 if (calloldhook
) retcode
= CallHookPkt(oldedithook
, sgw
, command
);
271 /*****************************************************************************************/
273 static void installedithook(void)
275 edithook
.h_Entry
= (HOOKFUNC
)AROS_ASMSYMNAME(conclipeditfunc
);
276 edithook
.h_SubEntry
= NULL
;
277 edithook
.h_Data
= NULL
;
279 oldedithook
= SetEditHook(&edithook
);
282 /*****************************************************************************************/
283 /*****************************************************************************************/
284 /*****************************************************************************************/
286 static void savetoclipboard(struct SGWork
*sgw
)
288 struct IFFHandle
*iff
;
290 if((iff
= AllocIFF()))
292 if((iff
->iff_Stream
= (IPTR
)OpenClipboard(clipunit
)))
295 if(!OpenIFF(iff
,IFFF_WRITE
))
297 if(!PushChunk(iff
, ID_FTXT
, ID_FORM
, IFFSIZE_UNKNOWN
))
299 if(!PushChunk(iff
, ID_FTXT
, ID_CHRS
, IFFSIZE_UNKNOWN
))
301 WriteChunkBytes(iff
, sgw
->WorkBuffer
, sgw
->NumChars
);
305 } /* if(!PushChunk(iff, ID_FTXT, ID_CHRS, IFFSIZE_UNKNOWN)) */
308 } /* if(!PushChunk(iff, ID_FTXT, ID_FORM, IFFSIZE_UNKNOWN)) */
311 } /* if(!OpenIFF(iff,IFFF_WRITE)) */
312 CloseClipboard((struct ClipboardHandle
*)iff
->iff_Stream
);
314 } /* if((iff->iff_Stream = (IPTR)OpenClipboard(clipunit))) */
317 } /* if((iff = AllocIFF()))) */
320 /*****************************************************************************************/
322 static void readfromclipboard(struct SGWork
*sgw
)
324 struct IFFHandle
*iff
;
325 struct ContextNode
*cn
;
327 if((iff
= AllocIFF()))
329 D(bug("ConClip/conclipeditfunc: AllocIFF okay\n"));
331 if((iff
->iff_Stream
= (IPTR
)OpenClipboard(clipunit
)))
333 D(bug("ConClip/conclipeditfunc: OpenClipboard okay\n"));
336 if(!OpenIFF(iff
, IFFF_READ
))
338 D(bug("ConClip/conclipeditfunc: OpenIff okay\n"));
340 if (!(StopChunk(iff
, ID_FTXT
, ID_CHRS
)))
342 D(bug("ConClip/conclipeditfunc: StopChunk okay\n"));
344 if (!ParseIFF(iff
, IFFPARSE_SCAN
))
346 D(bug("ConClip/conclipeditfunc: ParseIFF okay\n"));
348 cn
= CurrentChunk(iff
);
349 if ((cn
->cn_Type
== ID_FTXT
) && (cn
->cn_ID
== ID_CHRS
) && (cn
->cn_Size
> 0))
353 D(bug("ConClip: readfromclipboard: Found FTXT CHRS Chunk\n"));
354 D(bug("ConClip: readfromclipboard: Old text = \"%s\"\n", sgw
->WorkBuffer
));
356 readsize
= sgw
->StringInfo
->MaxChars
- 1 - sgw
->BufferPos
;
357 if (cn
->cn_Size
< readsize
) readsize
= cn
->cn_Size
;
360 memmove(sgw
->WorkBuffer
+ sgw
->BufferPos
+ readsize
,
361 sgw
->WorkBuffer
+ sgw
->BufferPos
,
362 sgw
->StringInfo
->MaxChars
- sgw
->BufferPos
- readsize
);
363 ReadChunkBytes(iff
, sgw
->WorkBuffer
+ sgw
->BufferPos
, readsize
);
365 D(bug("ConClip: readfromclipboard: New text = \"%s\"\n", sgw
->WorkBuffer
));
367 sgw
->BufferPos
+= readsize
;
370 } /* if ((cn->cn_Type == ID_FTXT) && (cn->cn_ID == ID_CHRS) && (cn->cn_Size > 0)) */
372 } /* if (!ParseIFF(iff, IFFPARSE_SCAN)) */
374 } /* if (!(StopChunk(iff, ID_FTXT, ID_CHRS))) */
378 } /* if(!OpenIFF(iff, IFFF_READ)) */
379 CloseClipboard((struct ClipboardHandle
*)iff
->iff_Stream
);
381 } /* if((iff->iff_Stream = (IPTR)OpenClipboard(clipunit))) */
384 } /* if((iff = AllocIFF()))) */
387 /*****************************************************************************************/
389 static void handleall(void)
396 sigs
= Wait(SIGBREAKF_CTRL_C
| portmask
);
400 struct MyEditHookMsg
*msg
;
402 while((msg
= (struct MyEditHookMsg
*)GetMsg(progport
)))
407 D(bug("ConClip: Received CODE_COPY message\n"));
408 savetoclipboard(msg
->sgw
);
412 D(bug("ConClip: Received CODE_PASTE message\n"));
413 readfromclipboard(msg
->sgw
);
416 } /* switch(msg->code) */
420 } /* while((msg = (struct MyEditHookMsg *)GetMsg(progport))) */
422 } /* if (sigs & portmask) */
424 if (sigs
& SIGBREAKF_CTRL_C
) quitme
= TRUE
;
426 } /* while(!quitme) */
429 /*****************************************************************************************/
447 /*****************************************************************************************/