2 Copyright © 1995-2001, 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>
80 #include <aros/debug.h>
82 /*****************************************************************************************/
84 #define ARG_TEMPLATE "CLIPUNIT=UNIT/N,OFF/S"
85 #define ARG_CLIPUNIT 0
89 /*****************************************************************************************/
92 #define CODE_PASTE 'V'
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
);
127 /*****************************************************************************************/
129 static void init(void)
131 progtask
= FindTask(NULL
);
132 ((struct Process
*)progtask
)->pr_WindowPtr
= (APTR
)-1;
135 /*****************************************************************************************/
137 static void getarguments(void)
139 struct RDArgs
*myargs
;
140 IPTR args
[NUM_ARGS
] = {0, 0};
142 if (!(myargs
= ReadArgs(ARG_TEMPLATE
, args
, NULL
)))
144 Fault(IoErr(), 0, s
, 255);
148 if (args
[ARG_CLIPUNIT
]) clipunit
= (ULONG
)(*(IPTR
*)args
[ARG_CLIPUNIT
]);
149 if (args
[ARG_OFF
]) off
= args
[ARG_OFF
] ? TRUE
: FALSE
;
154 /*****************************************************************************************/
156 static void checkport(void)
159 progport
= FindPort(CONCLIP_PORTNAME
);
162 if (off
) Signal(progport
->mp_SigTask
, SIGBREAKF_CTRL_C
);
167 progport
= CreatePort(CONCLIP_PORTNAME
, 1);
170 if (!progport
) cleanup("Could not create MsgPort!");
172 portmask
= 1L << progport
->mp_SigBit
;
175 /*****************************************************************************************/
177 AROS_UFH3(ULONG
, conclipeditfunc
,
178 AROS_UFHA(struct Hook
*, hook
, A0
),
179 AROS_UFHA(struct SGWork
*, sgw
, A2
),
180 AROS_UFHA(ULONG
*, command
, A1
)
185 struct MsgPort
*port
, replyport
;
186 struct MyEditHookMsg msg
;
187 BOOL calloldhook
= TRUE
;
193 D(bug("ConClip/conclipeditfunc: is SGH_KEY\n"));
195 if (sgw
->IEvent
->ie_Qualifier
& IEQUALIFIER_RCOMMAND
)
197 D(bug("ConClip/conclipeditfunc: qualifier RCOMMAND okay\n"));
199 switch(ToUpper(sgw
->Code
))
202 if (!sgw
->NumChars
) break;
206 D(bug("ConClip/conclipeditfunc: key = %c\n", toupper(sgw
->Code
)));
208 if ((port
= FindPort(CONCLIP_PORTNAME
)))
212 replyport
.mp_Node
.ln_Type
= NT_MSGPORT
;
213 replyport
.mp_Node
.ln_Name
= NULL
;
214 replyport
.mp_Node
.ln_Pri
= 0;
215 replyport
.mp_Flags
= PA_SIGNAL
;
216 replyport
.mp_SigBit
= SIGB_SINGLE
;
217 replyport
.mp_SigTask
= FindTask(NULL
);
218 NewList(&replyport
.mp_MsgList
);
220 msg
.msg
.mn_Node
.ln_Type
= NT_MESSAGE
;
221 msg
.msg
.mn_ReplyPort
= &replyport
;
222 msg
.msg
.mn_Length
= sizeof(msg
);
224 msg
.code
= ToUpper(sgw
->Code
);
227 if ((msg
.code
== CODE_COPY
) || (sgw
->NumChars
< sgw
->StringInfo
->MaxChars
- 1))
229 SetSignal(0, SIGF_SINGLE
);
230 PutMsg(port
, &msg
.msg
);
231 WaitPort(&replyport
);
234 if (msg
.code
== CODE_PASTE
)
236 WORD len
= strlen(sgw
->WorkBuffer
);
238 if (len
!= sgw
->NumChars
)
241 sgw
->EditOp
= EO_BIGCHANGE
;
242 sgw
->Actions
= SGA_USE
| SGA_REDISPLAY
;
247 } /* if (msg.code == CODE_COPY) */
249 } /* if ((port = FindPort(CONCLIP_PORTNAME))) */
253 } /* switch(ToUpper(sgw->Code)) */
255 } /* if (sgw->IEvent->ie_Qualifier & IEQUALIFIER_RCOMMAND) */
258 } /* switch (*command) */
260 if (calloldhook
) retcode
= CallHookPkt(oldedithook
, sgw
, command
);
267 /*****************************************************************************************/
269 static void installedithook(void)
271 edithook
.h_Entry
= (HOOKFUNC
)AROS_ASMSYMNAME(conclipeditfunc
);
272 edithook
.h_SubEntry
= NULL
;
273 edithook
.h_Data
= NULL
;
275 oldedithook
= SetEditHook(&edithook
);
278 /*****************************************************************************************/
279 /*****************************************************************************************/
280 /*****************************************************************************************/
282 static void savetoclipboard(struct SGWork
*sgw
)
284 struct IFFHandle
*iff
;
286 if((iff
= AllocIFF()))
288 if((iff
->iff_Stream
= (IPTR
)OpenClipboard(clipunit
)))
291 if(!OpenIFF(iff
,IFFF_WRITE
))
293 if(!PushChunk(iff
, ID_FTXT
, ID_FORM
, IFFSIZE_UNKNOWN
))
295 if(!PushChunk(iff
, ID_FTXT
, ID_CHRS
, IFFSIZE_UNKNOWN
))
297 WriteChunkBytes(iff
, sgw
->WorkBuffer
, sgw
->NumChars
);
301 } /* if(!PushChunk(iff, ID_FTXT, ID_CHRS, IFFSIZE_UNKNOWN)) */
304 } /* if(!PushChunk(iff, ID_FTXT, ID_FORM, IFFSIZE_UNKNOWN)) */
307 } /* if(!OpenIFF(iff,IFFF_WRITE)) */
308 CloseClipboard((struct ClipboardHandle
*)iff
->iff_Stream
);
310 } /* if((iff->iff_Stream = (IPTR)OpenClipboard(clipunit))) */
313 } /* if((iff = AllocIFF()))) */
316 /*****************************************************************************************/
318 static void readfromclipboard(struct SGWork
*sgw
)
320 struct IFFHandle
*iff
;
321 struct ContextNode
*cn
;
323 if((iff
= AllocIFF()))
325 D(bug("ConClip/conclipeditfunc: AllocIFF okay\n"));
327 if((iff
->iff_Stream
= (IPTR
)OpenClipboard(clipunit
)))
329 D(bug("ConClip/conclipeditfunc: OpenClipboard okay\n"));
332 if(!OpenIFF(iff
, IFFF_READ
))
334 D(bug("ConClip/conclipeditfunc: OpenIff okay\n"));
336 if (!(StopChunk(iff
, ID_FTXT
, ID_CHRS
)))
338 D(bug("ConClip/conclipeditfunc: StopChunk okay\n"));
340 if (!ParseIFF(iff
, IFFPARSE_SCAN
))
342 D(bug("ConClip/conclipeditfunc: ParseIFF okay\n"));
344 cn
= CurrentChunk(iff
);
345 if ((cn
->cn_Type
== ID_FTXT
) && (cn
->cn_ID
== ID_CHRS
) && (cn
->cn_Size
> 0))
349 D(bug("ConClip: readfromclipboard: Found FTXT CHRS Chunk\n"));
350 D(bug("ConClip: readfromclipboard: Old text = \"%s\"\n", sgw
->WorkBuffer
));
352 readsize
= sgw
->StringInfo
->MaxChars
- 1 - sgw
->BufferPos
;
353 if (cn
->cn_Size
< readsize
) readsize
= cn
->cn_Size
;
356 memmove(sgw
->WorkBuffer
+ sgw
->BufferPos
+ readsize
,
357 sgw
->WorkBuffer
+ sgw
->BufferPos
,
358 sgw
->StringInfo
->MaxChars
- sgw
->BufferPos
- readsize
);
359 ReadChunkBytes(iff
, sgw
->WorkBuffer
+ sgw
->BufferPos
, readsize
);
361 D(bug("ConClip: readfromclipboard: New text = \"%s\"\n", sgw
->WorkBuffer
));
363 sgw
->BufferPos
+= readsize
;
366 } /* if ((cn->cn_Type == ID_FTXT) && (cn->cn_ID == ID_CHRS) && (cn->cn_Size > 0)) */
368 } /* if (!ParseIFF(iff, IFFPARSE_SCAN)) */
370 } /* if (!(StopChunk(iff, ID_FTXT, ID_CHRS))) */
374 } /* if(!OpenIFF(iff, IFFF_READ)) */
375 CloseClipboard((struct ClipboardHandle
*)iff
->iff_Stream
);
377 } /* if((iff->iff_Stream = (IPTR)OpenClipboard(clipunit))) */
380 } /* if((iff = AllocIFF()))) */
383 /*****************************************************************************************/
385 static void handleall(void)
392 sigs
= Wait(SIGBREAKF_CTRL_C
| portmask
);
396 struct MyEditHookMsg
*msg
;
398 while((msg
= (struct MyEditHookMsg
*)GetMsg(progport
)))
403 D(bug("ConClip: Received CODE_COPY message\n"));
404 savetoclipboard(msg
->sgw
);
408 D(bug("ConClip: Received CODE_PASTE message\n"));
409 readfromclipboard(msg
->sgw
);
412 } /* switch(msg->code) */
416 } /* while((msg = (struct MyEditHookMsg *)GetMsg(progport))) */
418 } /* if (sigs & portmask) */
420 if (sigs
& SIGBREAKF_CTRL_C
) quitme
= TRUE
;
422 } /* while(!quitme) */
425 /*****************************************************************************************/
438 /*****************************************************************************************/