Prevent partitions from extending beyond end of container partition.
[AROS.git] / workbench / c / ConClip.c
blobd59eb67fa207bbabe33be0730cd046ec8b193bd2
1 /*
2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Conclip CLI command
6 Lang: English
7 */
8 /******************************************************************************
10 NAME
12 Conclip
14 FORMAT
16 CONCLIP [ [UNIT | CLIPUNIT] <unitnumber>] [OFF]
18 SYNOPSIS
20 CLIPUNIT=UNIT/N, ON/S, OFF/S
22 LOCATION
26 FUNCTION
28 Enable clipboard cut/copy/paste functionality in console windows
29 and string gadgets. This enables the use of a system global clipboard.
31 INPUTS
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
37 RESULT
39 NOTES
41 EXAMPLE
43 Conclip CLIPUNIT=1
45 This will set the global clipboard unit to 1. The available clipboards
46 can be checked in clips: dirDir Clips:
48 BUGS
50 SEE ALSO
52 INTERNALS
54 HISTORY
56 ******************************************************************************//*****************************************************************************************/
58 #include <aros/asmcall.h>
59 #include <dos/dos.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>
74 #include <string.h>
75 #include <stdlib.h>
78 #undef DEBUG
79 #define DEBUG 0
80 #include <aros/debug.h>
82 /*****************************************************************************************/
84 #define ARG_TEMPLATE "CLIPUNIT=UNIT/N,OFF/S"
85 #define ARG_CLIPUNIT 0
86 #define ARG_OFF 1
87 #define NUM_ARGS 2
89 /*****************************************************************************************/
91 #define CODE_COPY 'C'
92 #define CODE_PASTE 'V'
94 struct MyEditHookMsg
96 struct Message msg;
97 struct SGWork *sgw;
98 WORD code;
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;
112 static BOOL off;
113 static UBYTE s[256];
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);
124 exit(0);
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);
145 cleanup(s);
148 if (args[ARG_CLIPUNIT]) clipunit = (ULONG)(*(IPTR *)args[ARG_CLIPUNIT]);
149 if (args[ARG_OFF]) off = args[ARG_OFF] ? TRUE : FALSE;
151 FreeArgs(myargs);
154 /*****************************************************************************************/
156 static void checkport(void)
158 Forbid();
159 progport = FindPort(CONCLIP_PORTNAME);
160 if (progport)
162 if (off) Signal(progport->mp_SigTask, SIGBREAKF_CTRL_C);
163 Permit();
164 progport = NULL;
165 cleanup(NULL);
167 progport = CreatePort(CONCLIP_PORTNAME, 1);
168 Permit();
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)
183 AROS_USERFUNC_INIT
185 struct MsgPort *port, replyport;
186 struct MyEditHookMsg msg;
187 BOOL calloldhook = TRUE;
188 ULONG retcode = 0;
190 switch (*command)
192 case SGH_KEY:
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))
201 case 'C':
202 if (!sgw->NumChars) break;
203 /* fall through */
205 case 'V':
206 D(bug("ConClip/conclipeditfunc: key = %c\n", toupper(sgw->Code)));
208 if ((port = FindPort(CONCLIP_PORTNAME)))
210 calloldhook = FALSE;
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);
225 msg.sgw = sgw;
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)
240 sgw->NumChars = len;
241 sgw->EditOp = EO_BIGCHANGE;
242 sgw->Actions = SGA_USE | SGA_REDISPLAY;
244 retcode = 1;
247 } /* if (msg.code == CODE_COPY) */
249 } /* if ((port = FindPort(CONCLIP_PORTNAME))) */
251 break;
253 } /* switch(ToUpper(sgw->Code)) */
255 } /* if (sgw->IEvent->ie_Qualifier & IEQUALIFIER_RCOMMAND) */
256 break;
258 } /* switch (*command) */
260 if (calloldhook) retcode = CallHookPkt(oldedithook, sgw, command);
262 return retcode;
264 AROS_USERFUNC_EXIT
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)))
290 InitIFFasClip(iff);
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);
299 PopChunk(iff);
301 } /* if(!PushChunk(iff, ID_FTXT, ID_CHRS, IFFSIZE_UNKNOWN)) */
302 PopChunk(iff);
304 } /* if(!PushChunk(iff, ID_FTXT, ID_FORM, IFFSIZE_UNKNOWN)) */
305 CloseIFF(iff);
307 } /* if(!OpenIFF(iff,IFFF_WRITE)) */
308 CloseClipboard((struct ClipboardHandle*)iff->iff_Stream);
310 } /* if((iff->iff_Stream = (IPTR)OpenClipboard(clipunit))) */
311 FreeIFF(iff);
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"));
331 InitIFFasClip(iff);
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))
347 WORD readsize;
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;
354 if (readsize > 0)
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))) */
372 CloseIFF(iff);
374 } /* if(!OpenIFF(iff, IFFF_READ)) */
375 CloseClipboard((struct ClipboardHandle*)iff->iff_Stream);
377 } /* if((iff->iff_Stream = (IPTR)OpenClipboard(clipunit))) */
378 FreeIFF(iff);
380 } /* if((iff = AllocIFF()))) */
383 /*****************************************************************************************/
385 static void handleall(void)
387 BOOL quitme = FALSE;
388 ULONG sigs;
390 while(!quitme)
392 sigs = Wait(SIGBREAKF_CTRL_C | portmask);
394 if (sigs & portmask)
396 struct MyEditHookMsg *msg;
398 while((msg = (struct MyEditHookMsg *)GetMsg(progport)))
400 switch(msg->code)
402 case CODE_COPY:
403 D(bug("ConClip: Received CODE_COPY message\n"));
404 savetoclipboard(msg->sgw);
405 break;
407 case CODE_PASTE:
408 D(bug("ConClip: Received CODE_PASTE message\n"));
409 readfromclipboard(msg->sgw);
410 break;
412 } /* switch(msg->code) */
414 ReplyMsg(&msg->msg);
416 } /* while((msg = (struct MyEditHookMsg *)GetMsg(progport))) */
418 } /* if (sigs & portmask) */
420 if (sigs & SIGBREAKF_CTRL_C) quitme = TRUE;
422 } /* while(!quitme) */
425 /*****************************************************************************************/
427 int main(void)
429 init();
430 getarguments();
431 checkport();
432 installedithook();
433 handleall();
434 cleanup(NULL);
435 return 0;
438 /*****************************************************************************************/