2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
9 /*****************************************************************************************/
11 #include <aros/asmcall.h>
13 #include <intuition/intuition.h>
14 #include <intuition/sghooks.h>
15 #include <intuition/classusr.h>
16 #include <libraries/iffparse.h>
17 #include <devices/inputevent.h>
18 #include <datatypes/textclass.h>
19 #include <utility/hooks.h>
20 #include <proto/exec.h>
21 #include <proto/dos.h>
22 #include <proto/intuition.h>
23 #include <proto/iffparse.h>
24 #include <proto/alib.h>
25 #include <proto/utility.h>
33 #include <aros/debug.h>
35 /*****************************************************************************************/
37 #define ARG_TEMPLATE "CLIPUNIT=UNIT/N,OFF/S"
38 #define ARG_CLIPUNIT 0
42 /*****************************************************************************************/
45 #define CODE_PASTE 'V'
54 /*****************************************************************************************/
56 const STRPTR CONCLIP_TASKNAME
= "« ConClip »";
57 const STRPTR CONCLIP_PORTNAME
= "ConClip.rendezvous";
59 /*****************************************************************************************/
61 static struct MsgPort
*progport
;
62 static struct Hook edithook
, *oldedithook
;
63 static struct Task
*progtask
;
64 static ULONG clipunit
, portmask
;
68 /*****************************************************************************************/
70 static void cleanup(STRPTR msg
)
72 if (msg
) Printf("ConClip: %s\n", msg
);
74 if (oldedithook
) SetEditHook(oldedithook
);
75 if (progport
) DeletePort(progport
);
80 /*****************************************************************************************/
82 static void init(void)
84 progtask
= FindTask(NULL
);
85 ((struct Process
*)progtask
)->pr_WindowPtr
= (APTR
)-1;
88 /*****************************************************************************************/
90 static void getarguments(void)
92 struct RDArgs
*myargs
;
93 IPTR args
[NUM_ARGS
] = {0, 0};
95 if (!(myargs
= ReadArgs(ARG_TEMPLATE
, args
, NULL
)))
97 Fault(IoErr(), 0, s
, 255);
101 if (args
[ARG_CLIPUNIT
]) clipunit
= (ULONG
)(*(IPTR
*)args
[ARG_CLIPUNIT
]);
102 if (args
[ARG_OFF
]) off
= args
[ARG_OFF
] ? TRUE
: FALSE
;
107 /*****************************************************************************************/
109 static void checkport(void)
112 progport
= FindPort(CONCLIP_PORTNAME
);
115 if (off
) Signal(progport
->mp_SigTask
, SIGBREAKF_CTRL_C
);
120 progport
= CreatePort(CONCLIP_PORTNAME
, 1);
123 if (!progport
) cleanup("Could not create MsgPort!");
125 portmask
= 1L << progport
->mp_SigBit
;
128 /*****************************************************************************************/
130 AROS_UFH3(ULONG
, conclipeditfunc
,
131 AROS_UFHA(struct Hook
*, hook
, A0
),
132 AROS_UFHA(struct SGWork
*, sgw
, A2
),
133 AROS_UFHA(ULONG
*, command
, A1
)
138 struct MsgPort
*port
, replyport
;
139 struct MyEditHookMsg msg
;
140 BOOL calloldhook
= TRUE
;
146 D(bug("ConClip/conclipeditfunc: is SGH_KEY\n"));
148 if (sgw
->IEvent
->ie_Qualifier
& IEQUALIFIER_RCOMMAND
)
150 D(bug("ConClip/conclipeditfunc: qualifier RCOMMAND okay\n"));
152 switch(ToUpper(sgw
->Code
))
155 if (!sgw
->NumChars
) break;
159 D(bug("ConClip/conclipeditfunc: key = %c\n", toupper(sgw
->Code
)));
161 if ((port
= FindPort(CONCLIP_PORTNAME
)))
165 replyport
.mp_Node
.ln_Type
= NT_MSGPORT
;
166 replyport
.mp_Node
.ln_Name
= NULL
;
167 replyport
.mp_Node
.ln_Pri
= 0;
168 replyport
.mp_Flags
= PA_SIGNAL
;
169 replyport
.mp_SigBit
= SIGB_SINGLE
;
170 replyport
.mp_SigTask
= FindTask(NULL
);
171 NewList(&replyport
.mp_MsgList
);
173 msg
.msg
.mn_Node
.ln_Type
= NT_MESSAGE
;
174 msg
.msg
.mn_ReplyPort
= &replyport
;
175 msg
.msg
.mn_Length
= sizeof(msg
);
177 msg
.code
= ToUpper(sgw
->Code
);
180 if ((msg
.code
== CODE_COPY
) || (sgw
->NumChars
< sgw
->StringInfo
->MaxChars
- 1))
182 SetSignal(0, SIGF_SINGLE
);
183 PutMsg(port
, &msg
.msg
);
184 WaitPort(&replyport
);
187 if (msg
.code
== CODE_PASTE
)
189 WORD len
= strlen(sgw
->WorkBuffer
);
191 if (len
!= sgw
->NumChars
)
194 sgw
->EditOp
= EO_BIGCHANGE
;
195 sgw
->Actions
= SGA_USE
| SGA_REDISPLAY
;
200 } /* if (msg.code == CODE_COPY) */
202 } /* if ((port = FindPort(CONCLIP_PORTNAME))) */
206 } /* switch(ToUpper(sgw->Code)) */
208 } /* if (sgw->IEvent->ie_Qualifier & IEQUALIFIER_RCOMMAND) */
211 } /* switch (*command) */
213 if (calloldhook
) retcode
= CallHookPkt(oldedithook
, sgw
, command
);
220 /*****************************************************************************************/
222 static void installedithook(void)
224 edithook
.h_Entry
= (HOOKFUNC
)AROS_ASMSYMNAME(conclipeditfunc
);
225 edithook
.h_SubEntry
= NULL
;
226 edithook
.h_Data
= NULL
;
228 oldedithook
= SetEditHook(&edithook
);
231 /*****************************************************************************************/
232 /*****************************************************************************************/
233 /*****************************************************************************************/
235 static void savetoclipboard(struct SGWork
*sgw
)
237 struct IFFHandle
*iff
;
239 if((iff
= AllocIFF()))
241 if((iff
->iff_Stream
= (IPTR
)OpenClipboard(clipunit
)))
244 if(!OpenIFF(iff
,IFFF_WRITE
))
246 if(!PushChunk(iff
, ID_FTXT
, ID_FORM
, IFFSIZE_UNKNOWN
))
248 if(!PushChunk(iff
, ID_FTXT
, ID_CHRS
, IFFSIZE_UNKNOWN
))
250 WriteChunkBytes(iff
, sgw
->WorkBuffer
, sgw
->NumChars
);
254 } /* if(!PushChunk(iff, ID_FTXT, ID_CHRS, IFFSIZE_UNKNOWN)) */
257 } /* if(!PushChunk(iff, ID_FTXT, ID_FORM, IFFSIZE_UNKNOWN)) */
260 } /* if(!OpenIFF(iff,IFFF_WRITE)) */
261 CloseClipboard((struct ClipboardHandle
*)iff
->iff_Stream
);
263 } /* if((iff->iff_Stream = (IPTR)OpenClipboard(clipunit))) */
266 } /* if((iff = AllocIFF()))) */
269 /*****************************************************************************************/
271 static void readfromclipboard(struct SGWork
*sgw
)
273 struct IFFHandle
*iff
;
274 struct ContextNode
*cn
;
276 if((iff
= AllocIFF()))
278 D(bug("ConClip/conclipeditfunc: AllocIFF okay\n"));
280 if((iff
->iff_Stream
= (IPTR
)OpenClipboard(clipunit
)))
282 D(bug("ConClip/conclipeditfunc: OpenClipboard okay\n"));
285 if(!OpenIFF(iff
, IFFF_READ
))
287 D(bug("ConClip/conclipeditfunc: OpenIff okay\n"));
289 if (!(StopChunk(iff
, ID_FTXT
, ID_CHRS
)))
291 D(bug("ConClip/conclipeditfunc: StopChunk okay\n"));
293 if (!ParseIFF(iff
, IFFPARSE_SCAN
))
295 D(bug("ConClip/conclipeditfunc: ParseIFF okay\n"));
297 cn
= CurrentChunk(iff
);
298 if ((cn
->cn_Type
== ID_FTXT
) && (cn
->cn_ID
== ID_CHRS
) && (cn
->cn_Size
> 0))
302 D(bug("ConClip: readfromclipboard: Found FTXT CHRS Chunk\n"));
303 D(bug("ConClip: readfromclipboard: Old text = \"%s\"\n", sgw
->WorkBuffer
));
305 readsize
= sgw
->StringInfo
->MaxChars
- 1 - sgw
->BufferPos
;
306 if (cn
->cn_Size
< readsize
) readsize
= cn
->cn_Size
;
309 memmove(sgw
->WorkBuffer
+ sgw
->BufferPos
+ readsize
,
310 sgw
->WorkBuffer
+ sgw
->BufferPos
,
311 sgw
->StringInfo
->MaxChars
- sgw
->BufferPos
- readsize
);
312 ReadChunkBytes(iff
, sgw
->WorkBuffer
+ sgw
->BufferPos
, readsize
);
314 D(bug("ConClip: readfromclipboard: New text = \"%s\"\n", sgw
->WorkBuffer
));
316 sgw
->BufferPos
+= readsize
;
319 } /* if ((cn->cn_Type == ID_FTXT) && (cn->cn_ID == ID_CHRS) && (cn->cn_Size > 0)) */
321 } /* if (!ParseIFF(iff, IFFPARSE_SCAN)) */
323 } /* if (!(StopChunk(iff, ID_FTXT, ID_CHRS))) */
327 } /* if(!OpenIFF(iff, IFFF_READ)) */
328 CloseClipboard((struct ClipboardHandle
*)iff
->iff_Stream
);
330 } /* if((iff->iff_Stream = (IPTR)OpenClipboard(clipunit))) */
333 } /* if((iff = AllocIFF()))) */
336 /*****************************************************************************************/
338 static void handleall(void)
345 sigs
= Wait(SIGBREAKF_CTRL_C
| portmask
);
349 struct MyEditHookMsg
*msg
;
351 while((msg
= (struct MyEditHookMsg
*)GetMsg(progport
)))
356 D(bug("ConClip: Received CODE_COPY message\n"));
357 savetoclipboard(msg
->sgw
);
361 D(bug("ConClip: Received CODE_PASTE message\n"));
362 readfromclipboard(msg
->sgw
);
365 } /* switch(msg->code) */
369 } /* while((msg = (struct MyEditHookMsg *)GetMsg(progport))) */
371 } /* if (sigs & portmask) */
373 if (sigs
& SIGBREAKF_CTRL_C
) quitme
= TRUE
;
375 } /* while(!quitme) */
378 /*****************************************************************************************/
391 /*****************************************************************************************/