OS no longer mentioned in information window.
[tangerine.git] / workbench / tools / Edit / Gui.c
blobd386195b198d5d5588f16cf88b69455453f8aa5c
1 /**************************************************************
2 **** gui.c: main interface related procedures. ****
3 **** Free software under GNU license, written on 3/1/2000 ****
4 **** © T.Pierron, C.Guillaume. ****
5 **************************************************************/
7 #include <intuition/intuition.h>
8 #include <intuition/screens.h>
9 #include <intuition/imageclass.h>
10 #include <intuition/gadgetclass.h>
11 #include <libraries/gadtools.h>
12 #include <dos/dos.h>
13 #include <exec/memory.h>
14 #include "Jed.h"
15 #include "Prefs.h"
16 #include "IPC_Prefs.h"
17 #include "Version.h"
18 #include "Rawkey.h"
19 #include "Events.h"
20 #include "Search.h"
21 #include "ProtoTypes.h"
23 #define CATCOMP_NUMBERS
24 #define CATCOMP_STRINGS
25 #include "strings.h"
27 struct Screen *Scr = NULL;
28 void *Vi = NULL;
29 struct Window *Wnd = NULL;
30 struct Menu *Menu = NULL;
31 struct Scroll *Prop = NULL;
32 struct DrawInfo *di = NULL;
33 struct RastPort *RP, RPT;
34 ULONG sigmainwnd=0;
35 UBYTE boopsigad; /* Type of right prop gadget of window */
37 /* Colors pens */
38 struct pens pen = {0,1,3,2,2,1,2,1,3,2,3,0};
39 UWORD fginfo, bginfo; /* Information window */
41 #define TMPLINF "9999/99999"
43 struct NewMenu newmenu[] =
45 {NM_TITLE, MSG_PROJECTTITLE_STR, NULL, 0, 0L, NULL},
46 { NM_ITEM, MSG_NEWEMPTYFILE_STR, "N", 0, 0L, (APTR)101},
47 { NM_ITEM, MSG_OPENNEWFILE_STR, "O", 0, 0L, (APTR)102},
48 { NM_ITEM, MSG_LOADINPRJ_STR, "L", 0, 0L, (APTR)103},
49 { NM_ITEM, (STRPTR)NM_BARLABEL, NULL, 0, 0L, NULL},
50 { NM_ITEM, MSG_SAVEFILE_STR, "W", 0, 0L, (APTR)105},
51 { NM_ITEM, MSG_SAVEFILEAS_STR, NULL, 0, 0L, (APTR)106},
52 { NM_ITEM, MSG_SAVECHANGES_STR, "F", 0, 0L, (APTR)107},
53 { NM_ITEM, (STRPTR)NM_BARLABEL, NULL, 0, 0L, NULL},
54 { NM_ITEM, MSG_PRINTFILE_STR, "P", 0, 0L, (APTR)108},
55 { NM_ITEM, (STRPTR)NM_BARLABEL, NULL, 0, 0L, NULL},
56 { NM_ITEM, MSG_INFORMATION_STR, "?", 0, 0L, (APTR)109},
57 { NM_ITEM, (STRPTR)NM_BARLABEL, NULL, 0, 0L, NULL},
58 { NM_ITEM, MSG_CLOSE_STR, "Ctrl Q",NM_COMMANDSTRING, 0L, (APTR)111},
59 { NM_ITEM, MSG_QUIT_STR, "Q", 0, 0L, (APTR)112},
61 {NM_TITLE, MSG_EDITTITLE_STR, NULL, 0, 0L, NULL},
62 { NM_ITEM, MSG_CUT_STR, "X", 0, 0L, (APTR)201},
63 { NM_ITEM, MSG_COPY_STR, "C", 0, 0L, (APTR)202},
64 { NM_ITEM, MSG_PASTE_STR, "V", 0, 0L, (APTR)203},
65 { NM_ITEM, (STRPTR)NM_BARLABEL, NULL, 0, 0L, NULL},
66 { NM_ITEM, MSG_MARK_STR, "B", 0, 0L, (APTR)204},
67 { NM_ITEM, MSG_MARKCOLUMN_STR, NULL, 0, 0L, (APTR)205},
68 { NM_ITEM, MSG_SELECTALL_STR, "A", 0, 0L, (APTR)206},
69 { NM_ITEM, (STRPTR)NM_BARLABEL, NULL, 0, 0L, NULL},
70 { NM_ITEM, MSG_DELLINE_STR, "K", 0, 0L, (APTR)207},
71 { NM_ITEM, MSG_SUBTOOLS_STR, NULL, 0, 0L, NULL},
72 { NM_SUB, MSG_INDENT_STR, "Amiga Tab",NM_COMMANDSTRING, 0L, (APTR)2071},
73 { NM_SUB, MSG_UNINDENT_STR, NULL, 0, 0L, (APTR)2072},
74 { NM_SUB, NM_BARLABEL, NULL, 0, 0L, NULL},
75 { NM_SUB, MSG_UPPERCASE_STR, "Ctrl \\", NM_COMMANDSTRING, 0L, (APTR)2073},
76 { NM_SUB, MSG_LOWERCASE_STR, "Ctrl /", NM_COMMANDSTRING, 0L, (APTR)2074},
77 { NM_SUB, MSG_TOGGLECASE_STR, "G", 0, 0L, (APTR)2075},
78 { NM_ITEM, MSG_INSERTFILE_STR, "I", 0, 0L, (APTR)208},
79 { NM_ITEM, (STRPTR)NM_BARLABEL, NULL, 0, 0L, NULL},
80 { NM_ITEM, MSG_UNDO_STR, "U", 0, 0L, (APTR)209},
81 { NM_ITEM, MSG_REDO_STR, NULL, 0, 0L, (APTR)210},
83 {NM_TITLE, MSG_SEARCHTITLE_STR, NULL, 0, 0L, NULL},
84 { NM_ITEM, MSG_FIND_STR, "S", 0, 0L, (APTR)301},
85 { NM_ITEM, MSG_REPLACE_STR, "R", 0, 0L, (APTR)302},
86 { NM_ITEM, MSG_SUBFIND_STR, NULL, 0, 0L, NULL},
87 { NM_SUB, MSG_NEXTFIND_STR, "Ctrl N", NM_COMMANDSTRING, 0L, (APTR)3031},
88 { NM_SUB, MSG_PREVFIND_STR, "Ctrl P", NM_COMMANDSTRING, 0L, (APTR)3032},
89 { NM_SUB, MSG_NEXTREPLACE_STR, "Ctrl R", NM_COMMANDSTRING, 0L, (APTR)3033},
90 { NM_ITEM, (STRPTR)NM_BARLABEL, NULL, 0, 0L, NULL},
91 { NM_ITEM, MSG_PREVPAGE_STR, "Pg Up", NM_COMMANDSTRING, 0L, (APTR)304},
92 { NM_ITEM, MSG_NEXTPAGE_STR, "Pg Dn", NM_COMMANDSTRING, 0L, (APTR)305},
93 { NM_ITEM, MSG_GOTOLINE_STR, "J", 0, 0L, (APTR)306},
94 { NM_ITEM, MSG_FINDBRACKET_STR, "[", 0, 0L, (APTR)307},
95 { NM_ITEM, MSG_LASTMODIF_STR, "Ctrl Z", NM_COMMANDSTRING, 0L, (APTR)308},
96 { NM_ITEM, (STRPTR)NM_BARLABEL, NULL, 0, 0L, NULL},
97 { NM_ITEM, MSG_BEGOFLINE_STR, "Home", NM_COMMANDSTRING, 0L, (APTR)309},
98 { NM_ITEM, MSG_ENDOFLINE_STR, "End", NM_COMMANDSTRING, 0L, (APTR)310},
100 {NM_TITLE, MSG_MACROTITLE_STR, NULL, 0, 0L, NULL},
101 { NM_ITEM, MSG_STARTRECORD_STR, "Ctrl [", NM_COMMANDSTRING, 0L, (APTR)401},
102 { NM_ITEM, MSG_STOPRECORD_STR, "Ctrl ]", NM_COMMANDSTRING, 0L, (APTR)402},
103 { NM_ITEM, (STRPTR)NM_BARLABEL, NULL, 0, 0L, NULL},
104 { NM_ITEM, MSG_PLAYMACRO_STR, "M", 0, 0L, (APTR)403},
105 { NM_ITEM, MSG_REPEATMACRO_STR, NULL, 0, 0L, (APTR)404},
107 {NM_TITLE, MSG_ENVTITLE_STR, NULL, 0, 0L, NULL},
108 { NM_ITEM, MSG_SCRMODE_STR, "D", 0, 0L, (APTR)501},
109 { NM_ITEM, MSG_FONTS_STR, NULL, 0, 0L, (APTR)502},
110 { NM_ITEM, MSG_PREFS_STR, "T", 0, 0L, (APTR)503},
111 { NM_ITEM, (STRPTR)NM_BARLABEL, NULL, 0, 0L, NULL},
112 { NM_ITEM, MSG_LOADPREFS_STR, NULL, 0, 0L, (APTR)504},
113 { NM_ITEM, MSG_SAVEPREFS_STR, NULL, 0, 0L, (APTR)505},
114 { NM_ITEM, MSG_SAVEPREFSAS_STR, NULL, 0, 0L, (APTR)506},
116 {NM_END, 0, 0, 0, 0, 0}
119 /* Draw info pens, for giving screen a 2.0 newlook */
120 UWORD DriPens = (UWORD)~0;
122 /* Default screen and window titles */
123 UBYTE ScrTitle[] = SVERID;
124 UBYTE WinTitle[] = APPNAME " " VERSION;
126 /* NewWindow struct, when opening a window */
127 struct NewWindow Template =
129 0,0,0,0, 1,1, /* LE,TE,Wid,Hei, Pens */
130 IDCMP_MENUPICK | IDCMP_MOUSEMOVE | IDCMP_CLOSEWINDOW | IDCMP_NEWSIZE |
131 IDCMP_GADGETDOWN | IDCMP_GADGETUP | IDCMP_MOUSEBUTTONS | IDCMP_RAWKEY,
132 WFLG_SIZEGADGET | WFLG_SIZEBRIGHT | WFLG_CLOSEGADGET | WFLG_NEWLOOKMENUS |
133 WFLG_DEPTHGADGET | WFLG_ACTIVATE | WFLG_REPORTMOUSE | WFLG_SMART_REFRESH |
134 WFLG_DRAGBAR,
135 NULL, /* FirstGadget */
136 NULL, /* CheckMark */
137 WinTitle, /* Title */
138 NULL, /* Screen */
139 NULL, /* BitMap */
140 320, 60, 0xffff, 0xffff, /* Min & Max size */
141 CUSTOMSCREEN
144 /* Different values of NewWindow Flags field */
145 #define NORMAL_FLAGS \
146 WFLG_SIZEGADGET | WFLG_SIZEBRIGHT | WFLG_CLOSEGADGET | WFLG_NEWLOOKMENUS | \
147 WFLG_DEPTHGADGET | WFLG_ACTIVATE | WFLG_REPORTMOUSE | WFLG_SMART_REFRESH | \
148 WFLG_DRAGBAR
149 #define BACKDROP_FLAGS \
150 WFLG_NEWLOOKMENUS | WFLG_ACTIVATE | WFLG_REPORTMOUSE | WFLG_SMART_REFRESH | \
151 WFLG_BACKDROP | WFLG_DRAGBAR | WFLG_BORDERLESS
152 #define PROP_FLAGS \
153 AUTOKNOB | FREEVERT | PROPNEWLOOK | PROPBORDERLESS
155 /* Template used to quickly fill constant fields */
156 struct Scroll ScrollBar = {
157 { /* PropGadget */
158 NULL, 0,0, 0,0,
159 GFLG_RELRIGHT|GFLG_RELHEIGHT,
160 GACT_RIGHTBORDER|GACT_RELVERIFY|GACT_FOLLOWMOUSE,
161 GTYP_PROPGADGET,
162 NULL, NULL, NULL, 0, NULL,
163 0, NULL },
164 { /* Up-gadget */
165 NULL, 0,0, 0,0,
166 GFLG_RELRIGHT|GFLG_RELBOTTOM|GFLG_GADGHIMAGE|GFLG_GADGIMAGE,
167 GACT_RIGHTBORDER|GACT_RELVERIFY|GACT_IMMEDIATE,
168 GTYP_BOOLGADGET,
169 NULL, NULL, NULL, 0, NULL,
170 1, NULL },
171 { /* Down-Gadget */
172 NULL, 0,0, 0,0,
173 GFLG_RELRIGHT|GFLG_RELBOTTOM|GFLG_GADGHIMAGE|GFLG_GADGIMAGE,
174 GACT_RIGHTBORDER|GACT_RELVERIFY|GACT_IMMEDIATE,
175 GTYP_BOOLGADGET,
176 NULL, NULL, NULL, 0, NULL,
177 2, NULL },
178 { /* PropInfo */
179 PROP_FLAGS,
180 MAXPOT, MAXPOT,
181 MAXBODY, MAXBODY }
182 /* Other values may be NULL */
185 /* Menu color information */
186 struct TagItem MenuTags[] = {
187 {GTMN_FrontPen, 0L},
188 {TAG_DONE, 0}
191 /* Information about edit area */
192 struct gv gui;
194 void recalc_sigbits(void)
196 extern ULONG sigbits, swinsig, sigport;
197 sigmainwnd = 1 << Wnd->UserPort->mp_SigBit;
198 sigbits = SIGBREAKF_CTRL_C | sigmainwnd | swinsig | sigport;
201 /*** Search for text in the newmenu table ***/
202 CONST_STRPTR GetMenuText(ULONG MenuID)
204 struct NewMenu *nm;
205 for(nm = newmenu; nm->nm_UserData != (APTR)MenuID; nm++);
206 return nm->nm_Label;
209 /*** Adjust internal variables according to current window size ***/
210 void adjust_win(struct Window *wnd, BYTE PrjBar)
212 UWORD tmp;
214 gui.ysize = prefs.txtfont->tf_YSize; /* XSIZE */
215 gui.xsize = prefs.txtfont->tf_XSize; /* YSIZE */
216 gui.basel = prefs.txtfont->tf_Baseline; /* BASEL */
218 gui.oldtop = wnd->BorderTop+boopsigad;
219 gui.top = (PrjBar ? (gui.oldtop -= boopsigad)+prefs.scrfont->tf_YSize+6 : gui.oldtop);
220 gui.topcurs = gui.top+BASEL;
221 gui.nbline = (wnd->Height - wnd->BorderBottom - gui.top) / YSIZE;
222 tmp = gui.nbline * YSIZE;
223 gui.bottom = gui.top + tmp - 1;
224 gui.botcurs = gui.topcurs + tmp - YSIZE;
225 gui.left = wnd->BorderLeft;
226 tmp = (boopsigad ? Prop->scroller.Width : wnd->BorderRight);
227 gui.nbcol = (wnd->Width - tmp - gui.left - 2) / XSIZE;
228 gui.right = wnd->Width - tmp - 1;
229 gui.rcurs = gui.left + gui.nbcol * XSIZE;
230 gui.xstep = (gui.nbcol < 8 ? 1 : gui.nbcol >> 3);
232 gui.yinfo = Scr->RastPort.Font->tf_Baseline + 1;
233 gui.xinfo = (boopsigad ? Scr->Width : wnd->Width) - gui.depthwid*3 -
234 TextLength(&Scr->RastPort,TMPLINF,sizeof(TMPLINF)-1);
236 /* Scrolling mask */
237 gui.selmask = (pen.fg | pen.bg | pen.fgfill | pen.bgfill) ^
238 (pen.fg & pen.bg & pen.fgfill & pen.bgfill);
239 gui.txtmask = pen.fg ^ pen.bg;
242 /*** Clear the right column and bottom line where no chars can be written ***/
243 void clear_brcorner(void)
245 SetAPen(RP,pen.bg);
246 if(boopsigad || gui.top!=gui.oldtop) Move(RP,gui.left,gui.top-1),Draw(RP,gui.right,RP->cp_y);
247 RectFill(RP,gui.rcurs,gui.top,gui.right,gui.bottom);
248 RectFill(RP,gui.left,gui.bottom+1,gui.right,Wnd->Height-Wnd->BorderBottom-1);
249 SetAPen(RP,pen.fg);
252 /*** Adjust position of the prop gadget ***/
253 void prop_adj(Project p)
255 ULONG VertBody, VertPot;
257 extern UBYTE record;
258 if(record == 2) return;
260 /* If we have more lines visible than the text actually has (ie. **
261 ** there are empty lines visible) the body-size represents the **
262 ** lines visible according to the actual screen size: */
263 if(p->top_line + gui.nbline > p->max_lines)
264 VertPot = MAXPOT,
265 VertBody = ((p->max_lines - p->top_line) * MAXBODY) / p->max_lines;
266 else
267 if(p->max_lines <= gui.nbline)
268 /* There less lines than window can show */
269 VertPot = 0,
270 VertBody = MAXBODY;
271 else
272 VertPot = (p->top_line * MAXPOT) / (p->max_lines - gui.nbline),
273 /* The body-size is (number of lines for jump-scroll / all other lines) */
274 VertBody = (gui.nbline * MAXBODY) / p->max_lines;
276 /* Let's set it */
277 NewModifyProp((struct Gadget *)Prop,Wnd,NULL,ScrollBar.pinfo.Flags,MAXPOT,VertPot,MAXBODY,VertBody,1);
280 /*** Allocate and attach a prop gadget to the window ***/
281 struct Scroll *add_prop(struct Window *win)
283 struct Image *dummy;
284 struct Scroll *pg;
286 UWORD height, size_width, size_height;
288 /* If the window is a backdrop'ed one, use a simplified BOOPSI propgadget **
289 ** because the next propgadget aspect depends on window activated state */
290 if (win->Flags & WFLG_BACKDROP)
292 /* Yes this is actually a (struct Gadget *)... */
293 if ((pg = (struct Scroll *)NewObject(NULL, "propgclass",
294 GA_Top, 0,
295 GA_Left, win->Width - 10,
296 GA_Width, 10,
297 GA_Height, win->Height,
298 GA_RelVerify, TRUE,
299 GA_FollowMouse, TRUE,
300 GA_Immediate, TRUE,
301 PGA_VertPot, MAXPOT,
302 PGA_VertBody, MAXBODY,
303 PGA_Freedom, FREEVERT,
304 PGA_NewLook, TRUE, /* Use new-look prop gadget imagery */
305 TAG_END)))
307 /* To simplify adj_prop() */
308 ScrollBar.pinfo.Flags = ((struct PropInfo *)pg->scroller.SpecialInfo)->Flags;
309 /* And finally, add it to the window */
310 AddGList(win, (struct Gadget *)pg, 0, 1, NULL);
311 RefreshGList((struct Gadget *)pg, win, NULL, 1);
314 boopsigad = TRUE;
315 return pg;
317 boopsigad = FALSE;
319 /* Get memory */
320 if( ( pg = (void *) AllocMem(sizeof(*pg), MEMF_PUBLIC) ) )
322 /* Copy default flags/modes/etc. */
323 ScrollBar.pinfo.Flags = PROP_FLAGS;
324 CopyMem(&ScrollBar, pg, sizeof(*pg));
326 di = (void *) GetScreenDrawInfo(win->WScreen);
328 /* We need to get size-gadget height, to adjust properly arrows */
329 if((dummy = (struct Image *) NewObject(NULL, "sysiclass",
330 SYSIA_Which, SIZEIMAGE,
331 SYSIA_DrawInfo, (ULONG)di,
332 TAG_END) ))
334 size_width = dummy->Width; /* width of up/down-gadgets */
335 size_height = dummy->Height; /* bottom offset */
337 /* We don't need the image anymore */
338 DisposeObject(dummy);
340 /* Get the boopsi image of the up and down arrow */
341 if((pg->upimage = (struct Image *) NewObject(NULL, "sysiclass",
342 SYSIA_Which, UPIMAGE,
343 SYSIA_DrawInfo, (ULONG)di,
344 TAG_END) ))
346 pg->up.GadgetRender = pg->up.SelectRender = (APTR)pg->upimage;
347 height = pg->upimage->Height;
349 if((pg->downimage = (struct Image *) NewObject(NULL, "sysiclass",
350 SYSIA_Which, DOWNIMAGE,
351 SYSIA_DrawInfo, (ULONG)di,
352 TAG_END) ))
354 struct Gadget *G = (void *)pg;
355 WORD voffset = size_width / 4;
357 pg->down.GadgetRender = pg->down.SelectRender = (APTR)pg->downimage;
359 /* Release drawinfo */
360 FreeScreenDrawInfo (win->WScreen, di);
362 /* Now init all sizes/positions relative to window's borders */
363 G->Height = -(win->BorderTop + size_height + 2*height + 2);
364 G->TopEdge = win->BorderTop + 1;
365 G->Width = size_width - voffset * 2;
366 G->LeftEdge = -(size_width - voffset - 1); G++;
367 pg->up.LeftEdge=
368 G->LeftEdge = -(size_width - 1);
369 G->Width = pg->up.Width = size_width;
370 G->Height = pg->up.Height = height;
371 G->TopEdge = -(size_height + height - 1);
372 pg->up.TopEdge = G->TopEdge - height;
374 /* Other fields */
375 pg->scroller.GadgetRender = (APTR)&pg->simage;
376 pg->scroller.SpecialInfo = (APTR)&pg->pinfo;
378 /* Link gadgets */
379 pg->scroller.NextGadget = &pg->up;
380 pg->up.NextGadget = &pg->down;
382 /* And finally, add them to the window */
383 AddGList(win, &pg->scroller, 0, 3, NULL);
384 RefreshGList(&pg->scroller, win, NULL, 3);
386 return pg;
388 DisposeObject(pg->upimage);
391 FreeMem(pg, sizeof(*pg));
392 FreeScreenDrawInfo(win->WScreen, di);
394 return NULL;
397 /*** Free ressources allocated for scroller ***/
398 void free_prop(struct Scroll *pg)
400 if( pg )
402 if( boopsigad ) DisposeObject( pg );
403 else {
404 /* Free elements */
405 DisposeObject(pg->upimage);
406 DisposeObject(pg->downimage);
408 /* Free struct */
409 FreeMem(pg, sizeof(*pg));
414 /*** Open a screen according to a ModeID ***/
415 struct Screen *SetupScreen( ULONG ModeID )
417 return (struct Screen *) OpenScreenTags( NULL, SA_Left, 0,
418 SA_Top, 0,
419 SA_Depth, prefs.depth,
420 SA_Font, (ULONG)&prefs.attrscr,
421 SA_Type, CUSTOMSCREEN,
422 SA_DisplayID, ModeID,
423 SA_Overscan, OSCAN_TEXT,
424 SA_AutoScroll, TRUE,
425 SA_Pens, (ULONG)&DriPens,
426 SA_Title, (ULONG)ScrTitle,
427 TAG_DONE );
430 /*** Try to copy a screen ***/
431 struct Screen *clone_screen(void)
433 /* Required information is filled when pref. are loaded */
434 return (struct Screen *) OpenScreenTags( NULL, SA_Left, 0,
435 SA_Top, 0,
436 SA_Depth, prefs.scrd,
437 SA_Width, prefs.scrw,
438 SA_Height, prefs.scrh,
439 SA_Font, (ULONG)&prefs.attrscr,
440 SA_Type, CUSTOMSCREEN,
441 SA_DisplayID, prefs.vmd,
442 SA_AutoScroll, TRUE,
443 SA_Pens, (ULONG)&DriPens,
444 SA_Title, (ULONG)ScrTitle,
445 TAG_DONE );
448 /*** Be sure a window fits in a screen ***/
449 void fit_in_screen(struct NewWindow *wnd, struct Screen *scr)
451 /* Adjust left edge and width of window */
452 if(wnd->LeftEdge + wnd->Width > scr->Width)
453 wnd->LeftEdge = scr->Width - wnd->Width;
455 if(wnd->LeftEdge < 0) wnd->LeftEdge=0, wnd->Width=Scr->Width;
457 /* Adjust top edge and height */
458 if(wnd->TopEdge + wnd->Height > scr->Height)
459 wnd->TopEdge = scr->Height - wnd->Height;
461 if(wnd->TopEdge < 0) wnd->TopEdge=0, wnd->Height=Scr->Height;
464 /*** Force a window to recover the whole screen ***/
465 void maximize(struct NewWindow *wnd, struct Screen *scr)
467 wnd->LeftEdge = 0;
468 wnd->TopEdge = scr->BarHeight+1;
469 wnd->Height = scr->Height - wnd->TopEdge;
470 wnd->Width = scr->Width;
473 /*** Get correct pens number according to user preferences ***/
474 void load_pens( void )
476 /* Find out drawing information */
477 if( ( di = (void *) GetScreenDrawInfo(Scr) ) )
479 struct Image *dummy;
480 WORD *offset = (WORD *)&prefs.pen, *dst;
482 /* Get a copy of the correct pens for the screen */
483 for(dst=(UWORD *)&pen; (char *)dst < (char *)&pen+sizeof(pen); offset++)
484 *dst++ = (*offset < 0 ? -(*offset) - 1 : di->dri_Pens[ *offset ]);
486 fginfo = (prefs.use_pub ? 0 : di->dri_Pens[FILLTEXTPEN]);
487 bginfo = (prefs.use_pub ? 1 : di->dri_Pens[FILLPEN]);
488 MenuTags[0].ti_Data = di->dri_Pens[BARDETAILPEN];
490 /* This one is only available on system V39+ */
491 if(di->dri_Version>=2 && prefs.backdrop && prefs.use_pub != 0)
492 fginfo = MenuTags[0].ti_Data, bginfo = di->dri_Pens[BARBLOCKPEN];
494 /* Get screen depth-arrange image width */
495 if((dummy = (struct Image *) NewObject(NULL, "sysiclass",
496 SYSIA_Which, SDEPTHIMAGE,
497 SYSIA_DrawInfo, (ULONG)di,
498 TAG_END) ) )
499 gui.depthwid = dummy->Width,DisposeObject(dummy);
500 else
501 gui.depthwid = 15;
503 FreeScreenDrawInfo(Scr,di);
507 /*** Init main window returning 0, if all is OK ***/
508 long setup( void )
510 /* Setup pos/dim */
512 if (prefs.width && prefs.height)
514 CopyMem(&prefs.left,&Template.LeftEdge,4*sizeof(WORD));
517 /* Setup screen */
518 if(Scr == NULL)
519 switch( prefs.use_pub )
521 case 0: Scr = prefs.parent; break;
522 case 1: if((Scr = SetupScreen(prefs.modeid))) break;
523 case 2: Scr = clone_screen(); break;
525 /* Something goes wrong? */
526 if(Scr == NULL) return 1;
527 load_pens();
529 /* Get the screen's visual information data */
530 if(Vi || (Vi = (void *) GetVisualInfoA(Scr,NULL)))
532 /* Build the menu-strip and compute menu items size */
533 if(Menu || (Menu = (void *) CreateMenusA(newmenu, MenuTags)))
535 if( LayoutMenus(Menu, Vi, GTMN_TextAttr, (ULONG)&prefs.attrscr, TAG_DONE) )
537 Template.Screen = Scr;
538 /* Force to do not use a backdroped window on a pubscreen */
539 if( prefs.backdrop && prefs.use_pub != 0 )
540 maximize(&Template, Scr), Template.Flags = BACKDROP_FLAGS,
541 Template.Title = NULL;
542 else
543 fit_in_screen(&Template, Scr), Template.Flags = NORMAL_FLAGS,
544 Template.Title = WinTitle;
546 /* Open our main window */
547 if(Wnd || (Wnd = (void *) OpenWindow( &Template )))
549 /* Init temporary rastport, for font measurement */
550 CopyMem(RP = Wnd->RPort, &RPT, sizeof(RPT));
551 SetFont(&RPT, prefs.scrfont);
552 SetMenuStrip( Wnd, Menu );
553 recalc_sigbits();
555 /* Try to attach a prop gadget on right side of the window */
556 if(Prop || (Prop = add_prop(Wnd)))
558 /* Compute some often-used values */
559 adjust_win(Wnd,NbProject>1);
560 SetABPenDrMd(RP, pen.fg, pen.bg, JAM2);
561 SetFont(RP, prefs.txtfont);
562 return 0;
563 } else return 2;
565 /* Window fails to open */
566 return 3;
568 /* Error in menu layout */
569 return 4;
571 /* Error in menu allocation */
572 return 5;
574 /* Can't get VisualInfo */
575 return 6;
578 /*** Cleanup properly the ressources allocated for GUIs ***/
579 void CloseMainWnd(BOOL CloseScr)
581 send_pref(&prefs, CMD_KILL);
582 close_searchwnd(FALSE);
583 if(Wnd)
585 if( Menu ) ClearMenuStrip(Wnd);
587 CloseWindow(Wnd); Wnd=NULL;
588 if( Prop ) free_prop(Prop); Prop=NULL;
590 if(Menu) FreeMenus(Menu), Menu=NULL;
591 if(Vi) FreeVisualInfo(Vi), Vi=NULL;
592 /* If a screen has been opened, close it */
593 if(CloseScr)
595 if(prefs.use_pub && Scr)
596 CloseScreen(Scr);
597 Scr=NULL;