2 Copyright 2011-2012, The AROS Development Team.
7 #include <aros/debug.h>
9 #include <clib/alib_protos.h>
11 #include <graphics/rpattr.h>
12 #include <proto/utility.h>
13 #include <proto/intuition.h>
14 #include <proto/graphics.h>
15 #include <proto/exec.h>
18 #include <intuition/cghooks.h>
20 #include "screendecorclass.h"
21 #include "drawfuncs.h"
24 #define SETIMAGE_SCR(id) sd->di->img_##id = CreateNewImageContainerMatchingScreen(data->di->img_##id, truecolor, screen)
26 #define CHILDPADDING 1
30 struct Screen
*Screen
;
31 /* These are original images loaded from disk */
32 struct DecorImages
* di
;
33 struct DecorConfig
* dc
;
37 static void DisposeScreenSkinning(struct scrdecor_data
*data
)
41 static BOOL
InitScreenSkinning(struct scrdecor_data
*data
, struct DecorImages
* di
, struct DecorConfig
* dc
)
49 if (data
->di
->img_sdepth
) return TRUE
;
51 DisposeScreenSkinning(data
);
59 static IPTR
scrdecor_new(Class
*cl
, Object
*obj
, struct opSet
*msg
)
61 struct scrdecor_data
*data
;
64 D(bug("scrdecor_new(tags @ 0x%p)\n", msg
->ops_AttrList
));
66 obj
= (Object
*)DoSuperMethodA(cl
, obj
, (Msg
)msg
);
70 data
= INST_DATA(cl
, obj
);
72 struct DecorConfig
* dc
= (struct DecorConfig
*) GetTagData(SDA_DecorConfig
, (IPTR
) NULL
, msg
->ops_AttrList
);
73 struct DecorImages
* di
= (struct DecorImages
*) GetTagData(SDA_DecorImages
, (IPTR
) NULL
, msg
->ops_AttrList
);
75 D(bug("scrdecor_new: DecorImages @ 0x%p\n", di
));
76 D(bug("scrdecor_new: DecorConfig @ 0x%p\n", dc
));
78 data
->FirstChild
= NULL
;
80 if (!InitScreenSkinning(data
, di
, dc
))
82 CoerceMethod(cl
,obj
,OM_DISPOSE
);
87 barh
= data
->dc
->SBarHeight
;
89 if (data
->di
->img_sbarlogo
) if (data
->di
->img_sbarlogo
->h
> barh
) barh
= data
->di
->img_sbarlogo
->h
;
90 if (data
->di
->img_stitlebar
) if (data
->di
->img_stitlebar
->h
> barh
) barh
= data
->di
->img_stitlebar
->h
;
96 static IPTR
scrdecor_dispose(Class
*cl
, Object
*obj
, struct opSet
*msg
)
98 struct scrdecor_data
*data
= INST_DATA(cl
, obj
);
100 DisposeScreenSkinning(data
);
105 /**************************************************************************************************/
107 static IPTR
scrdecor_get(Class
*cl
, Object
*obj
, struct opGet
*msg
)
109 switch(msg
->opg_AttrID
)
111 case SDA_TrueColorOnly
:
112 *msg
->opg_Storage
= TRUE
;
116 return DoSuperMethodA(cl
, obj
, (Msg
)msg
);
121 /**************************************************************************************************/
123 static void scr_findtitlearea(struct scrdecor_data
*data
, struct Screen
*scr
, LONG
*left
, LONG
*right
)
127 LONG minx
= 0, maxx
= scr
->Width
- 1;
129 for (g
= scr
->FirstGadget
; g
; g
= g
->NextGadget
)
131 if (!(g
->Flags
& GFLG_RELRIGHT
))
133 if (g
->LeftEdge
+ g
->Width
> minx
) minx
= g
->LeftEdge
+ g
->Width
;
137 if (g
->LeftEdge
+ scr
->Width
- 1 - 1 < maxx
) maxx
= g
->LeftEdge
+ scr
->Width
- 1 - 1;
140 if (maxx
!= scr
->Width
- 1)
141 maxx
= maxx
- (data
->dc
->SBarGadPre_s
+ data
->dc
->SBarGadPost_s
);
147 static IPTR
scrdecor_set(Class
*cl
, Object
*obj
, struct opSet
*msg
)
149 struct scrdecor_data
*data
= INST_DATA(cl
, obj
);
150 struct TagItem
*tags
= msg
->ops_AttrList
;
151 struct TagItem
*tstate
;
155 while ((tag
= NextTagItem(&tstate
)))
162 if (!(data
->FirstChild
))
164 LONG left
, right
= 0;
165 struct GadgetInfo childgadinf
;
166 struct gpLayout childlayoutmsg
;
167 D(bug("[screendecor] SDA_TitleChild: 0x%p\n", tag
->ti_Data
));
169 if ((childgadinf
.gi_Screen
= LockPubScreen(NULL
)) != NULL
)
171 UnlockPubScreen(NULL
, childgadinf
.gi_Screen
);
172 data
->FirstChild
= (Object
*)tag
->ti_Data
;
173 ((struct Gadget
*)(data
->FirstChild
))->SpecialInfo
= childgadinf
.gi_Screen
;
175 childgadinf
.gi_RastPort
= childgadinf
.gi_Screen
->BarLayer
->rp
;
177 if ((childgadinf
.gi_DrInfo
= GetScreenDrawInfo(childgadinf
.gi_Screen
)) != NULL
)
179 childgadinf
.gi_Pens
.DetailPen
= childgadinf
.gi_DrInfo
->dri_Pens
[DETAILPEN
];
180 childgadinf
.gi_Pens
.BlockPen
= childgadinf
.gi_DrInfo
->dri_Pens
[BLOCKPEN
];
183 childlayoutmsg
.MethodID
= GM_LAYOUT
;
184 childlayoutmsg
.gpl_GInfo
= &childgadinf
;
185 childlayoutmsg
.gpl_Initial
= 0;
187 ((struct Gadget
*)(data
->FirstChild
))->TopEdge
= 0 + CHILDPADDING
;
188 ((struct Gadget
*)(data
->FirstChild
))->Height
= childgadinf
.gi_Screen
->BarHeight
- (CHILDPADDING
<< 1);
190 DoMethodA(data
->FirstChild
, &childlayoutmsg
);
192 scr_findtitlearea(data
, (childgadinf
.gi_Screen
), &left
, &right
);
194 ((struct Gadget
*)(data
->FirstChild
))->LeftEdge
= right
- (((struct Gadget
*)(data
->FirstChild
))->Width
+ data
->dc
->SBarGadPost_s
+ 1);
196 childlayoutmsg
.MethodID
= GM_GOACTIVE
;
197 DoMethodA(data
->FirstChild
, &childlayoutmsg
);
203 return DoSuperMethodA(cl
, obj
, (Msg
)msg
);
209 static IPTR
scrdecor_draw_screenbar(Class
*cl
, Object
*obj
, struct sdpDrawScreenBar
*msg
)
211 struct scrdecor_data
*data
= INST_DATA(cl
, obj
);
212 struct ScreenData
*sd
= (struct ScreenData
*) msg
->sdp_UserBuffer
;
213 struct RastPort
*rp
= msg
->sdp_RPort
;
214 struct Screen
*scr
= msg
->sdp_Screen
;
215 struct DrawInfo
*dri
= msg
->sdp_Dri
;
216 UWORD
*pens
= dri
->dri_Pens
;
217 LONG left
, right
= 0, len
, filllen
;
218 BOOL beeping
= scr
->Flags
& BEEPING
;
220 if ((data
->dc
->SBarChildPre_s
> 0) && (data
->dc
->SBarChildPre_s
< sd
->img_stitlebar
->w
))
221 filllen
= data
->dc
->SBarChildPre_o
;
222 else if ((data
->dc
->SBarGadPre_s
> 0) && (data
->dc
->SBarGadPre_s
< sd
->img_stitlebar
->w
))
223 filllen
= data
->dc
->SBarGadPre_o
;
225 filllen
= sd
->img_stitlebar
->w
;
230 scr_findtitlearea(data
, scr
, &left
, &right
);
234 SetAPen(rp
, pens
[BARDETAILPEN
]);
235 RectFill(rp
, 0, 0, scr
->Width
, sd
->img_stitlebar
->h
);
239 if (sd
->img_stitlebar
->ok
)
241 if (data
->dc
->SBarGadPre_s
> 0)
243 WriteTiledImageHorizontal(rp
, sd
->img_stitlebar
, 0,
244 data
->dc
->SBarGadPre_o
, data
->dc
->SBarGadPre_s
,
245 right
+ 1, 0, data
->dc
->SBarGadPre_o
);
247 if (data
->dc
->SBarGadFill_s
> 0)
249 WriteTiledImageHorizontal(rp
, sd
->img_stitlebar
, 0,
250 data
->dc
->SBarGadFill_o
, data
->dc
->SBarGadFill_s
,
251 right
+ data
->dc
->SBarGadPre_s
+ 1, 0, scr
->Width
- (right
+ data
->dc
->SBarGadPre_s
+ data
->dc
->SBarGadPost_s
));
253 if (data
->dc
->SBarGadPost_s
> 0)
255 WriteTiledImageHorizontal(rp
, sd
->img_stitlebar
, 0,
256 data
->dc
->SBarGadPost_o
, data
->dc
->SBarGadPost_s
,
257 scr
->Width
- data
->dc
->SBarGadPost_s
, 0, data
->dc
->SBarGadPost_s
);
261 if ((data
->FirstChild
) && (((struct Gadget
*)(data
->FirstChild
))->Width
> 2)) {
262 D(bug("[screendecor] draw_screenbar: titlechild width = %d\n", ((struct Gadget
*)(data
->FirstChild
))->Width
));
263 right
= right
- (((struct Gadget
*)(data
->FirstChild
))->Width
+ data
->dc
->SBarChildPre_s
+ data
->dc
->SBarChildPost_s
);
266 if (sd
->img_stitlebar
->ok
)
268 WriteVerticalScaledTiledImageHorizontal(rp
, sd
->img_stitlebar
, 0, 0,
269 filllen
, 0, 0, data
->dc
->SBarHeight
, right
+ 1, scr
->BarHeight
+ 1);
274 if (sd
->img_sbarlogo
->ok
)
276 WriteTiledImageHorizontal(rp
, sd
->img_sbarlogo
, 0, 0,
277 sd
->img_sbarlogo
->w
, data
->dc
->SLogoOffset
,
278 (scr
->BarHeight
+ 1 - sd
->img_sbarlogo
->h
) / 2, sd
->img_sbarlogo
->w
);
281 if (scr
->Title
!= NULL
)
283 struct TextExtent te
;
285 len
= strlen(scr
->Title
);
287 if ((len
= TextFit(rp
, scr
->Title
, len
, &te
, NULL
, 1, right
- data
->dc
->STitleOffset
, scr
->BarHeight
)) != 0)
289 UWORD tx
= data
->dc
->STitleOffset
;
290 UWORD tymax
= scr
->BarHeight
- (dri
->dri_Font
->tf_YSize
- dri
->dri_Font
->tf_Baseline
) - 1;
291 UWORD ty
= ((scr
->BarHeight
+ dri
->dri_Font
->tf_Baseline
- 1) >> 1);
292 if (ty
> tymax
) ty
= tymax
;
294 SetFont(rp
, msg
->sdp_Dri
->dri_Font
);
297 if (!(sd
->truecolor
) || ((data
->dc
->STitleOutline
== FALSE
) && (data
->dc
->STitleShadow
== FALSE
)))
299 SetAPen(rp
, pens
[beeping
? BARBLOCKPEN
: BARDETAILPEN
]);
301 Text(rp
, scr
->Title
, len
);
303 else if (data
->dc
->STitleOutline
)
305 SetSoftStyle(rp
, FSF_BOLD
, AskSoftStyle(rp
));
306 SetRPAttrs(rp
, RPTAG_PenMode
, FALSE
, RPTAG_FgColor
, data
->dc
->STitleColorShadow
, TAG_DONE
);
308 Move(rp
, tx
+ 1, ty
); Text(rp
, scr
->Title
, len
);
309 Move(rp
, tx
+ 2, ty
); Text(rp
, scr
->Title
, len
);
310 Move(rp
, tx
, ty
); Text(rp
, scr
->Title
, len
);
311 Move(rp
, tx
, ty
+ 1); Text(rp
, scr
->Title
, len
);
312 Move(rp
, tx
, ty
+ 2); Text(rp
, scr
->Title
, len
);
313 Move(rp
, tx
+ 1, ty
+ 2); Text(rp
, scr
->Title
, len
);
314 Move(rp
, tx
+ 2, ty
+ 1); Text(rp
, scr
->Title
, len
);
315 Move(rp
, tx
+ 2, ty
+ 2); Text(rp
, scr
->Title
, len
);
317 SetRPAttrs(rp
, RPTAG_PenMode
, FALSE
, RPTAG_FgColor
, data
->dc
->STitleColorText
, TAG_DONE
);
318 Move(rp
, tx
+ 1, ty
+ 1);
319 Text(rp
, scr
->Title
, len
);
320 SetSoftStyle(rp
, FS_NORMAL
, AskSoftStyle(rp
));
324 SetRPAttrs(rp
, RPTAG_PenMode
, FALSE
, RPTAG_FgColor
, data
->dc
->STitleColorShadow
, TAG_DONE
);
325 Move(rp
, tx
+ 1, ty
+ 1 );
326 Text(rp
, scr
->Title
, len
);
328 SetRPAttrs(rp
, RPTAG_PenMode
, FALSE
, RPTAG_FgColor
, data
->dc
->STitleColorText
, TAG_DONE
);
330 Text(rp
, scr
->Title
, len
);
335 if (data
->FirstChild
&& (((struct Gadget
*)(data
->FirstChild
))->Width
> 0)) {
336 struct GadgetInfo childgadinf
;
337 struct gpRender childrendermsg
=
345 if (sd
->img_stitlebar
->ok
)
347 if (data
->dc
->SBarChildPre_s
> 0)
349 WriteTiledImageHorizontal(rp
, sd
->img_stitlebar
, 0,
350 data
->dc
->SBarChildPre_o
, data
->dc
->SBarChildPre_s
,
351 right
+ 1, 0, data
->dc
->SBarChildPre_s
);
353 if (data
->dc
->SBarChildFill_s
> 0)
355 WriteTiledImageHorizontal(rp
, sd
->img_stitlebar
, 0,
356 data
->dc
->SBarChildFill_o
, data
->dc
->SBarChildFill_s
,
357 right
+ data
->dc
->SBarChildPre_s
+ 1, 0, ((struct Gadget
*)(data
->FirstChild
))->Width
);
361 WriteVerticalScaledTiledImageHorizontal(rp
, sd
->img_stitlebar
, 0,
362 0, filllen
, right
+ data
->dc
->SBarChildPre_s
+ 1, 0, data
->dc
->SBarHeight
, right
, scr
->BarHeight
+ 1);
364 if (data
->dc
->SBarChildPost_s
> 0)
366 WriteTiledImageHorizontal(rp
, sd
->img_stitlebar
, 0,
367 data
->dc
->SBarChildPost_o
, data
->dc
->SBarChildPost_s
,
368 right
+ data
->dc
->SBarChildPre_s
+ ((struct Gadget
*)(data
->FirstChild
))->Width
+ 1, 0, data
->dc
->SBarChildPost_s
);
371 childgadinf
.gi_Screen
= ((struct Gadget
*)(data
->FirstChild
))->SpecialInfo
= scr
;
372 childgadinf
.gi_RastPort
= rp
;
373 childgadinf
.gi_Pens
.DetailPen
= pens
[DETAILPEN
];
374 childgadinf
.gi_Pens
.BlockPen
= pens
[BLOCKPEN
];
375 childgadinf
.gi_DrInfo
= dri
;
376 childgadinf
.gi_Domain
.Left
= right
+ data
->dc
->SBarChildPre_s
+ 1;
377 childgadinf
.gi_Domain
.Width
= ((struct Gadget
*)(data
->FirstChild
))->Width
;
378 childgadinf
.gi_Domain
.Top
= 0 + CHILDPADDING
; // TODO: Get the real area from the theme..
379 childgadinf
.gi_Domain
.Height
= sd
->img_stitlebar
->h
- (CHILDPADDING
<< 1);
380 D(bug("[screendecor] draw_screenbar: rendering titlechild @ 0x%p, msg @ 0x%p, info @ 0x%p\n", data
->FirstChild
, &childrendermsg
, &childgadinf
));
381 DoMethodA(data
->FirstChild
, &childrendermsg
);
387 static IPTR
scrdecor_getdefsize_sysimage(Class
*cl
, Object
*obj
, struct sdpGetDefSizeSysImage
*msg
)
389 struct scrdecor_data
*data
= INST_DATA(cl
, obj
);
391 if (msg
->sdp_Which
== SDEPTHIMAGE
)
393 if (data
->di
&& data
->di
->img_sdepth
)
395 *msg
->sdp_Height
= data
->di
->img_sdepth
->h
;
396 *msg
->sdp_Width
= data
->di
->img_sdepth
->w
>> 1;
398 else return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
400 else return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
405 static IPTR
scrdecor_draw_sysimage(Class
*cl
, Object
*obj
, struct sdpDrawSysImage
*msg
)
407 struct ScreenData
*sd
= (struct ScreenData
*) msg
->sdp_UserBuffer
;
409 struct RastPort
*rp
= msg
->sdp_RPort
;
410 LONG left
= msg
->sdp_X
;
411 LONG top
= msg
->sdp_Y
;
412 LONG width
= msg
->sdp_Width
;
413 LONG height
= msg
->sdp_Height
;
414 LONG state
= msg
->sdp_State
;
416 if (msg
->sdp_Which
== SDEPTHIMAGE
)
420 DrawScaledStatefulGadgetImageToRP(rp
, sd
->img_sdepth
, state
, left
, top
, width
, height
);
422 else return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
424 else return DoSuperMethodA(cl
, obj
, (Msg
) msg
);
429 static IPTR
scrdecor_layoutscrgadgets(Class
*cl
, Object
*obj
, struct sdpLayoutScreenGadgets
*msg
)
431 struct Gadget
*gadget
= msg
->sdp_Gadgets
;
432 struct ScreenData
*sd
= (struct ScreenData
*) msg
->sdp_UserBuffer
;
434 struct scrdecor_data
*data
= INST_DATA(cl
, obj
);
438 switch(gadget
->GadgetType
& GTYP_SYSTYPEMASK
)
441 gadget
->LeftEdge
= -(gadget
->Width
+ data
->dc
->SBarGadPost_s
);
442 gadget
->TopEdge
= (data
->dc
->SBarHeight
- sd
->img_sdepth
->h
) >> 1;
443 gadget
->Flags
&= ~GFLG_RELWIDTH
;
444 gadget
->Flags
|= GFLG_RELRIGHT
;
448 if (msg
->sdp_Flags
& SDF_LSG_MULTIPLE
)
450 gadget
= gadget
->NextGadget
;
461 static IPTR
scrdecor_initscreen(Class
*cl
, Object
*obj
, struct sdpInitScreen
*msg
)
463 struct scrdecor_data
*data
= INST_DATA(cl
, obj
);
464 struct ScreenData
*sd
= (struct ScreenData
*)msg
->sdp_UserBuffer
;
465 struct Screen
*screen
= msg
->sdp_Screen
;
467 sd
->truecolor
= msg
->sdp_TrueColor
;
469 BOOL truecolor
= sd
->truecolor
;
472 * This depends on openwindow.c adding font height to w->BorderTop.
473 * It allows the window title bar to grow when font is bigger than decoration defined height
475 if ((msg
->sdp_FontHeight
+ 2) > data
->dc
->BarHeight
)
476 msg
->sdp_WBorTop
= 1;
478 msg
->sdp_WBorTop
= data
->dc
->BarHeight
- 1 - msg
->sdp_FontHeight
;
480 /* Allow scaling title bar above decoration defined height */
481 msg
->sdp_BarHeight
= msg
->sdp_FontHeight
> (data
->dc
->SBarHeight
- 1) ? msg
->sdp_FontHeight
: (data
->dc
->SBarHeight
- 1);
483 msg
->sdp_BarHBorder
= 1;
484 msg
->sdp_WBorLeft
= data
->dc
->LeftBorder
;
485 msg
->sdp_WBorRight
= data
->dc
->RightBorder
;
486 msg
->sdp_WBorBottom
= data
->dc
->BottomBorder
;
489 sd
->DeactivePen
= -1;
490 #if 0 // Omitting this gives better colours on low-color screens
492 sd
->ActivePen
= ObtainPen(screen
->ViewPort
.ColorMap
, -1, (data
->dc
->LUTBaseColors_a
<< 8) & 0xff000000, (data
->dc
->LUTBaseColors_a
<< 16) & 0xff000000, (data
->dc
->LUTBaseColors_a
<< 24) & 0xff000000, PEN_EXCLUSIVE
);
493 sd
->DeactivePen
= ObtainPen(screen
->ViewPort
.ColorMap
, -1, (data
->dc
->LUTBaseColors_d
<< 8) & 0xff000000, (data
->dc
->LUTBaseColors_d
<< 16) & 0xff000000, (data
->dc
->LUTBaseColors_d
<< 24) & 0xff000000, PEN_EXCLUSIVE
);
497 /* Convert initial images to current screen */
498 /* Make sure a structure is always generated even if there is no image
499 That was the assumption of previous code :/ */
501 sd
->di
= NewImages();
503 SETIMAGE_SCR(sdepth
);
504 SETIMAGE_SCR(sbarlogo
);
505 SETIMAGE_SCR(stitlebar
);
517 SETIMAGE_SCR(snapshot
);
518 SETIMAGE_SCR(iconify
);
520 SETIMAGE_SCR(winbar_normal
);
521 SETIMAGE_SCR(border_normal
);
522 SETIMAGE_SCR(border_deactivated
);
523 SETIMAGE_SCR(verticalcontainer
);
524 SETIMAGE_SCR(verticalknob
);
525 SETIMAGE_SCR(horizontalcontainer
);
526 SETIMAGE_SCR(horizontalknob
);
529 SETIMAGE_SCR(amigakey
);
530 SETIMAGE_SCR(menucheck
);
531 SETIMAGE_SCR(submenu
);
533 /* Set pointers to converted images */
534 sd
->img_sdepth
= sd
->di
->img_sdepth
;
535 sd
->img_sbarlogo
= sd
->di
->img_sbarlogo
;
536 sd
->img_stitlebar
= sd
->di
->img_stitlebar
;
538 sd
->img_amigakey
= sd
->di
->img_amigakey
;
539 sd
->img_menucheck
= sd
->di
->img_menucheck
;
540 sd
->img_submenu
= sd
->di
->img_submenu
;
545 static IPTR
scrdecor_exitscreen(Class
*cl
, Object
*obj
, struct sdpExitScreen
*msg
)
547 struct ScreenData
*sd
= (struct ScreenData
*)msg
->sdp_UserBuffer
;
554 /**************************************************************************************************/
556 static IPTR
scrdecor_dispatcher(struct IClass
*cl
, Object
*obj
, Msg msg
)
560 switch(msg
->MethodID
)
563 retval
= scrdecor_new(cl
, obj
, (struct opSet
*)msg
);
567 retval
= scrdecor_dispose(cl
, obj
, (struct opSet
*)msg
);
571 retval
= scrdecor_get(cl
, obj
, (struct opGet
*)msg
);
575 retval
= scrdecor_set(cl
, obj
, (struct opSet
*)msg
);
578 case SDM_GETDEFSIZE_SYSIMAGE
:
579 retval
= scrdecor_getdefsize_sysimage(cl
, obj
, (struct sdpGetDefSizeSysImage
*)msg
);
582 case SDM_DRAW_SCREENBAR
:
583 retval
= scrdecor_draw_screenbar(cl
, obj
, (struct sdpDrawScreenBar
*)msg
);
586 case SDM_DRAW_SYSIMAGE
:
587 retval
= scrdecor_draw_sysimage(cl
, obj
, (struct sdpDrawSysImage
*)msg
);
590 case SDM_LAYOUT_SCREENGADGETS
:
591 retval
= scrdecor_layoutscrgadgets(cl
, obj
, (struct sdpLayoutScreenGadgets
*)msg
);
595 retval
= scrdecor_initscreen(cl
, obj
, (struct sdpInitScreen
*)msg
);
599 retval
= scrdecor_exitscreen(cl
, obj
, (struct sdpExitScreen
*)msg
);
603 retval
= DoSuperMethodA(cl
, obj
, msg
);
610 struct IClass
* MakeScreenDecorClass()
612 struct IClass
* cl
= MakeClass(NULL
, SCRDECORCLASS
, NULL
, sizeof(struct scrdecor_data
), 0);
615 cl
->cl_Dispatcher
.h_Entry
= HookEntry
;
616 cl
->cl_Dispatcher
.h_SubEntry
= (HOOKFUNC
)scrdecor_dispatcher
;