Don't call InvertPixelArray with negative width and/or height.
[tangerine.git] / workbench / c / ConClip.c
blob08457cafe0c854be3c0a905996afa08664ccfdaf
1 /*
2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc:
6 Lang: English
7 */
9 /*****************************************************************************************/
11 #include <aros/asmcall.h>
12 #include <dos/dos.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>
27 #include <string.h>
28 #include <stdlib.h>
31 #undef DEBUG
32 #define DEBUG 0
33 #include <aros/debug.h>
35 /*****************************************************************************************/
37 #define ARG_TEMPLATE "CLIPUNIT=UNIT/N,OFF/S"
38 #define ARG_CLIPUNIT 0
39 #define ARG_OFF 1
40 #define NUM_ARGS 2
42 /*****************************************************************************************/
44 #define CODE_COPY 'C'
45 #define CODE_PASTE 'V'
47 struct MyEditHookMsg
49 struct Message msg;
50 struct SGWork *sgw;
51 WORD code;
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;
65 static BOOL off;
66 static UBYTE s[256];
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);
77 exit(0);
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);
98 cleanup(s);
101 if (args[ARG_CLIPUNIT]) clipunit = (ULONG)(*(IPTR *)args[ARG_CLIPUNIT]);
102 if (args[ARG_OFF]) off = args[ARG_OFF] ? TRUE : FALSE;
104 FreeArgs(myargs);
107 /*****************************************************************************************/
109 static void checkport(void)
111 Forbid();
112 progport = FindPort(CONCLIP_PORTNAME);
113 if (progport)
115 if (off) Signal(progport->mp_SigTask, SIGBREAKF_CTRL_C);
116 Permit();
117 progport = NULL;
118 cleanup(NULL);
120 progport = CreatePort(CONCLIP_PORTNAME, 1);
121 Permit();
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)
136 AROS_USERFUNC_INIT
138 struct MsgPort *port, replyport;
139 struct MyEditHookMsg msg;
140 BOOL calloldhook = TRUE;
141 ULONG retcode = 0;
143 switch (*command)
145 case SGH_KEY:
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))
154 case 'C':
155 if (!sgw->NumChars) break;
156 /* fall through */
158 case 'V':
159 D(bug("ConClip/conclipeditfunc: key = %c\n", toupper(sgw->Code)));
161 if ((port = FindPort(CONCLIP_PORTNAME)))
163 calloldhook = FALSE;
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);
178 msg.sgw = sgw;
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)
193 sgw->NumChars = len;
194 sgw->EditOp = EO_BIGCHANGE;
195 sgw->Actions = SGA_USE | SGA_REDISPLAY;
197 retcode = 1;
200 } /* if (msg.code == CODE_COPY) */
202 } /* if ((port = FindPort(CONCLIP_PORTNAME))) */
204 break;
206 } /* switch(ToUpper(sgw->Code)) */
208 } /* if (sgw->IEvent->ie_Qualifier & IEQUALIFIER_RCOMMAND) */
209 break;
211 } /* switch (*command) */
213 if (calloldhook) retcode = CallHookPkt(oldedithook, sgw, command);
215 return retcode;
217 AROS_USERFUNC_EXIT
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)))
243 InitIFFasClip(iff);
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);
252 PopChunk(iff);
254 } /* if(!PushChunk(iff, ID_FTXT, ID_CHRS, IFFSIZE_UNKNOWN)) */
255 PopChunk(iff);
257 } /* if(!PushChunk(iff, ID_FTXT, ID_FORM, IFFSIZE_UNKNOWN)) */
258 CloseIFF(iff);
260 } /* if(!OpenIFF(iff,IFFF_WRITE)) */
261 CloseClipboard((struct ClipboardHandle*)iff->iff_Stream);
263 } /* if((iff->iff_Stream = (IPTR)OpenClipboard(clipunit))) */
264 FreeIFF(iff);
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"));
284 InitIFFasClip(iff);
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))
300 WORD readsize;
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;
307 if (readsize > 0)
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))) */
325 CloseIFF(iff);
327 } /* if(!OpenIFF(iff, IFFF_READ)) */
328 CloseClipboard((struct ClipboardHandle*)iff->iff_Stream);
330 } /* if((iff->iff_Stream = (IPTR)OpenClipboard(clipunit))) */
331 FreeIFF(iff);
333 } /* if((iff = AllocIFF()))) */
336 /*****************************************************************************************/
338 static void handleall(void)
340 BOOL quitme = FALSE;
341 ULONG sigs;
343 while(!quitme)
345 sigs = Wait(SIGBREAKF_CTRL_C | portmask);
347 if (sigs & portmask)
349 struct MyEditHookMsg *msg;
351 while((msg = (struct MyEditHookMsg *)GetMsg(progport)))
353 switch(msg->code)
355 case CODE_COPY:
356 D(bug("ConClip: Received CODE_COPY message\n"));
357 savetoclipboard(msg->sgw);
358 break;
360 case CODE_PASTE:
361 D(bug("ConClip: Received CODE_PASTE message\n"));
362 readfromclipboard(msg->sgw);
363 break;
365 } /* switch(msg->code) */
367 ReplyMsg(&msg->msg);
369 } /* while((msg = (struct MyEditHookMsg *)GetMsg(progport))) */
371 } /* if (sigs & portmask) */
373 if (sigs & SIGBREAKF_CTRL_C) quitme = TRUE;
375 } /* while(!quitme) */
378 /*****************************************************************************************/
380 int main(void)
382 init();
383 getarguments();
384 checkport();
385 installedithook();
386 handleall();
387 cleanup(NULL);
388 return 0;
391 /*****************************************************************************************/