let the screen be queried for its compositing flags
[aros:aros.git] / AROS / rom / intuition / screenclass.c
1 /*
2     Copyright © 2013, The AROS Development Team. All rights reserved.
3     $Id$
4 */
5
6 #include <aros/debug.h>
7 #include <cybergraphx/cybergraphics.h>
8 #include <hidd/graphics.h>
9 #include <hidd/hidd.h>
10 #include <graphics/driver.h>
11 #include <graphics/sprite.h>
12 #include <intuition/intuition.h>
13 #include <intuition/intuitionbase.h>
14 #include <intuition/classes.h>
15 #include <intuition/classusr.h>
16 #include <intuition/monitorclass.h>
17 #include <proto/alib.h>
18 #include <proto/exec.h>
19 #include <proto/intuition.h>
20 #include <proto/oop.h>
21 #include <proto/utility.h>
22
23 #include "intuition_intern.h"
24 #include "intuition_customize.h"
25 #include "monitorclass_private.h"
26
27 /*i***************************************************************************************
28
29     NAME
30         --background_screenclass--
31
32     LOCATION
33         screenclass
34
35     NOTES
36         In AROS screens are BOOPSI objects. It is possible to modify certain properties
37         of the screen by using SetAttrs() and GetAttr() functions.
38
39         screenclass by itself is private to the system and does not have a public ID.
40         The user can't create objects of this class manually. Screens are created and
41         destroyed as usually, using OpenScreen() and CloseScreen() functions.
42
43         This class is fully compatible with MorphOS starting from v2.x.
44
45 *****************************************************************************************/
46
47 IPTR ScreenClass__OM_DISPOSE(Class *cl, Object *o, Msg msg)
48 {
49     struct IntuitionBase *IntuitionBase = (struct IntuitionBase *)cl->cl_UserData;
50     struct IntScreen *screen = INST_DATA(cl, o);
51
52     /* Free decoration objects */
53     DisposeObject(screen->WinDecorObj);
54     DisposeObject(screen->MenuDecorObj);
55     DisposeObject(screen->ScrDecorObj);
56
57     /* Free decoration buffer */
58     FreeMem((APTR)screen->DecorUserBuffer, screen->DecorUserBufferSize);
59
60     if ((screen->Decorator != ((struct IntIntuitionBase *)(IntuitionBase))->Decorator) &&
61         (screen->Decorator != NULL))
62     {
63         struct NewDecorator *nd = screen->Decorator;
64
65         ObtainSemaphore(&((struct IntIntuitionBase *)(IntuitionBase))->ScrDecorSem);
66
67         nd->nd_cnt--;
68         if (nd->nd_IntPattern == NULL)
69         {
70             /*
71              * If no pattern is defined, we assume it was old default decorator
72              * which fell out of use. Unload it.
73              */
74             int_UnloadDecorator(nd, IntuitionBase);
75         }
76
77         ReleaseSemaphore(&((struct IntIntuitionBase *)(IntuitionBase))->ScrDecorSem);
78     }
79
80     return DoSuperMethodA(cl, o, msg);
81 }
82
83 static IPTR GetScreen(ULONG attrID, struct IntScreen *screen, struct IntuitionBase *IntuitionBase)
84 {
85     Object *mon;
86
87     GetAttr(attrID, screen->IMonitorNode, (IPTR *)&mon);
88
89     if (mon)
90     {
91         ULONG lock = LockIBase(0);
92         struct Screen *ret = FindFirstScreen(mon, IntuitionBase);
93
94         if (ret && ((ret->Flags & SCREENTYPE) == CUSTOMSCREEN))
95         {
96             /* We want only public screens */
97             ret = NULL;
98         }
99
100         UnlockIBase(lock);
101
102         return (IPTR)ret;
103     }
104
105     return 0;
106 }
107
108 /*i***************************************************************************************
109
110     NAME
111         SA_Left
112
113     SYNOPSIS
114         [ISG], LONG
115
116     LOCATION
117         screenclass
118
119     FUNCTION
120         Position of left edge of the screen relative to top-left physical display corner.
121
122     NOTES
123
124     EXAMPLE
125
126     BUGS
127
128     SEE ALSO
129
130     INTERNALS
131
132 *****************************************************************************************/
133 /*i***************************************************************************************
134
135     NAME
136         SA_Top
137
138     SYNOPSIS
139         [ISG], LONG
140
141     LOCATION
142         screenclass
143
144     FUNCTION
145         Position of top edge of the screen relative to top-left physical display corner.
146
147     NOTES
148
149     EXAMPLE
150
151     BUGS
152
153     SEE ALSO
154
155     INTERNALS
156
157 *****************************************************************************************/
158 /*i***************************************************************************************
159
160     NAME
161         SA_Width
162
163     SYNOPSIS
164         [I.G], LONG
165
166     LOCATION
167         screenclass
168
169     FUNCTION
170         Width of the screen (not display) in pixels.
171
172     NOTES
173
174     EXAMPLE
175
176     BUGS
177
178     SEE ALSO
179
180     INTERNALS
181
182 *****************************************************************************************/
183 /*i***************************************************************************************
184
185     NAME
186         SA_Height
187
188     SYNOPSIS
189         [I.G], LONG
190
191     LOCATION
192         screenclass
193
194     FUNCTION
195         Height of the screen (not display) in pixels.
196
197     NOTES
198
199     EXAMPLE
200
201     BUGS
202
203     SEE ALSO
204
205     INTERNALS
206
207 *****************************************************************************************/
208 /*i***************************************************************************************
209
210     NAME
211         SA_Depth
212
213     SYNOPSIS
214         [I.G], LONG
215
216     LOCATION
217         screenclass
218
219     FUNCTION
220         Depth of the screen.
221
222     NOTES
223         This attribute returns real depth, however old structure fields, for example
224         screen->RastPort.BitMap->bm_Depth, in case of direct-color screens will
225         contain 8 for purposes of backwards compatibility. 
226
227     EXAMPLE
228
229     BUGS
230
231     SEE ALSO
232
233     INTERNALS
234
235 *****************************************************************************************/
236 /*i***************************************************************************************
237
238     NAME
239         SA_PubName
240
241     SYNOPSIS
242         [I.G], STRPTR
243
244     LOCATION
245         screenclass
246
247     FUNCTION
248         Public screen name (system name, not human-readable title).
249
250     NOTES
251
252     EXAMPLE
253
254     BUGS
255
256     SEE ALSO
257
258     INTERNALS
259
260 *****************************************************************************************/
261 /*i***************************************************************************************
262
263     NAME
264         SA_DisplayID
265
266     SYNOPSIS
267         [I.G], LONG
268
269     LOCATION
270         screenclass
271
272     FUNCTION
273         Display mode ID of the screen.
274
275     NOTES
276
277     EXAMPLE
278
279     BUGS
280
281     SEE ALSO
282
283     INTERNALS
284
285 *****************************************************************************************/
286 /*i***************************************************************************************
287
288     NAME
289         SA_Behind
290
291     SYNOPSIS
292         [I.G], LONG
293
294     LOCATION
295         screenclass
296
297     FUNCTION
298         Supplying this attribute during screen creation (to OpenScreen() or
299         OpenScreenTagList() functions) causes this screen to be created and
300         opened behind all other screens.
301
302         Querying this attribute returns its initial value.
303
304     NOTES
305
306     EXAMPLE
307
308     BUGS
309
310     SEE ALSO
311
312     INTERNALS
313
314 *****************************************************************************************/
315 /*i***************************************************************************************
316
317     NAME
318         SA_MonitorName
319
320     SYNOPSIS
321         [I.G], LONG
322
323     LOCATION
324         screenclass
325
326     FUNCTION
327         Name of the monitorclass object (AKA display device name) to which this screen
328         belongs.
329
330     NOTES
331
332     EXAMPLE
333
334     BUGS
335
336     SEE ALSO
337         SA_MonitorObject
338
339     INTERNALS
340
341 *****************************************************************************************/
342 /*i***************************************************************************************
343
344     NAME
345         SA_MonitorObject
346
347     SYNOPSIS
348         [..G], Object *
349
350     LOCATION
351         screenclass
352
353     FUNCTION
354         Returns display device (monitorclass) object to which this screen belongs
355
356     NOTES
357
358     EXAMPLE
359
360     BUGS
361
362     SEE ALSO
363         SA_MonitorName
364
365     INTERNALS
366
367 *****************************************************************************************/
368 /*i***************************************************************************************
369
370     NAME
371         SA_TopLeftScreen
372
373     SYNOPSIS
374         [..G], struct Screen *
375
376     LOCATION
377         screenclass
378
379     FUNCTION
380         Get a pointer to a public screen displayed on a monitor placed in top-left diagonal
381         direction relative to this screen's one. If the frontmost screen on the given
382         monitor is not public, NULL will be returned.
383
384     NOTES
385         AROS supports screen composition, so more than one screen is actually displayed
386         at any given time. In order to match MorphOS semantics this attribute takes into
387         account only the frontmost screen on the given monitor.
388
389     EXAMPLE
390
391     BUGS
392
393     SEE ALSO
394         monitorclass/MA_TopLeftMonitor
395
396     INTERNALS
397
398 *****************************************************************************************/
399 /*i***************************************************************************************
400
401     NAME
402         SA_TopMiddleScreen
403
404     SYNOPSIS
405         [..G], struct Screen *
406
407     LOCATION
408         screenclass
409
410     FUNCTION
411         Get a pointer to a public screen displayed on a monitor placed in top direction
412         relative to this screen's one. If the frontmost screen on the given monitor is
413         not public, NULL will be returned.
414
415     NOTES
416         AROS supports screen composition, so more than one screen is actually displayed
417         at any given time. In order to match MorphOS semantics this attribute takes into
418         account only the frontmost screen on the given monitor.
419
420     EXAMPLE
421
422     BUGS
423
424     SEE ALSO
425         monitorclass/MA_TopMiddleMonitor
426
427     INTERNALS
428
429 *****************************************************************************************/
430 /*i***************************************************************************************
431
432     NAME
433         SA_TopRightScreen
434
435     SYNOPSIS
436         [..G], struct Screen *
437
438     LOCATION
439         screenclass
440
441     FUNCTION
442         Get a pointer to a screen displayed on a monitor placed in top-right diagonal
443         direction relative to this screen's one. If the frontmost screen on the given
444         monitor is not public, NULL will be returned.
445
446     NOTES
447         AROS supports screen composition, so more than one screen is actually displayed
448         at any given time. In order to match MorphOS semantics this attribute takes into
449         account only the frontmost screen on the given monitor.
450
451     EXAMPLE
452
453     BUGS
454
455     SEE ALSO
456         monitorclass/MA_TopRightMonitor
457
458     INTERNALS
459
460 *****************************************************************************************/
461 /*i***************************************************************************************
462
463     NAME
464         SA_MiddleLeftScreen
465
466     SYNOPSIS
467         [..G], struct Screen *
468
469     LOCATION
470         screenclass
471
472     FUNCTION
473         Get a pointer to a public screen displayed on a monitor placed in left direction
474         relative to this screen's one. If the frontmost screen on the given monitor is
475         not public, NULL will be returned.
476
477     NOTES
478         AROS supports screen composition, so more than one screen is actually displayed
479         at any given time. In order to match MorphOS semantics this attribute takes into
480         account only the frontmost screen on the given monitor.
481
482     EXAMPLE
483
484     BUGS
485
486     SEE ALSO
487         monitorclass/MA_MiddleLeftMonitor
488
489     INTERNALS
490
491 *****************************************************************************************/
492 /*i***************************************************************************************
493
494     NAME
495         SA_MiddleRightScreen
496
497     SYNOPSIS
498         [..G], struct Screen *
499
500     LOCATION
501         screenclass
502
503     FUNCTION
504         Get a pointer to a public screen displayed on a monitor placed in left direction
505         relative to this screen's one. If the frontmost screen on the given monitor is
506         not public, NULL will be returned.
507
508     NOTES
509         AROS supports screen composition, so more than one screen is actually displayed
510         at any given time. In order to match MorphOS semantics this attribute takes into
511         account only the frontmost screen on the given monitor.
512
513     EXAMPLE
514
515     BUGS
516
517     SEE ALSO
518         monitorclass/MA_MiddleRightMonitor
519
520     INTERNALS
521
522 *****************************************************************************************/
523 /*i***************************************************************************************
524
525     NAME
526         SA_BottomLeftScreen
527
528     SYNOPSIS
529         [..G], struct Screen *
530
531     LOCATION
532         screenclass
533
534     FUNCTION
535         Get a pointer to a public screen displayed on a monitor placed in bottom-left
536         diagonal direction relative to this screen's one. If the frontmost screen on
537         the given monitor is not public, NULL will be returned.
538
539     NOTES
540         AROS supports screen composition, so more than one screen is actually displayed
541         at any given time. In order to match MorphOS semantics this attribute takes into
542         account only the frontmost screen on the given monitor.
543
544     EXAMPLE
545
546     BUGS
547
548     SEE ALSO
549         monitorclass/MA_BottomLeftMonitor
550
551     INTERNALS
552
553 *****************************************************************************************/
554 /*i***************************************************************************************
555
556     NAME
557         SA_BottomMiddleScreen
558
559     SYNOPSIS
560         [..G], struct Screen *
561
562     LOCATION
563         screenclass
564
565     FUNCTION
566         Get a pointer to a public screen displayed on a monitor placed in bottom direction
567         relative to this screen's one. If the frontmost screen on the given monitor is
568         not public, NULL will be returned.
569
570     NOTES
571         AROS supports screen composition, so more than one screen is actually displayed
572         at any given time. In order to match MorphOS semantics this attribute takes into
573         account only the frontmost screen on the given monitor.
574
575     EXAMPLE
576
577     BUGS
578
579     SEE ALSO
580         monitorclass/MA_BottomMiddleMonitor
581
582     INTERNALS
583
584 *****************************************************************************************/
585 /*i***************************************************************************************
586
587     NAME
588         SA_BottomRightScreen
589
590     SYNOPSIS
591         [..G], struct Screen *
592
593     LOCATION
594         screenclass
595
596     FUNCTION
597         Get a pointer to a screen displayed on a monitor placed in bottom-right diagonal
598         direction relative to this screen's one. If the frontmost screen on the given
599         monitor is not public, NULL will be returned.
600
601     NOTES
602         AROS supports screen composition, so more than one screen is actually displayed
603         at any given time. In order to match MorphOS semantics this attribute takes into
604         account only the frontmost screen on the given monitor.
605
606     EXAMPLE
607
608     BUGS
609
610     SEE ALSO
611         monitorclass/MA_BottomRightMonitor
612
613     INTERNALS
614
615 *****************************************************************************************/
616 /*i***************************************************************************************
617
618     NAME
619         SA_StopBlanker
620
621     SYNOPSIS
622         [S..], BOOL
623
624     LOCATION
625         screenclass
626
627     FUNCTION
628         This attribute is currently reserved and exists only for source compatibility with
629         MorphOS.
630
631     NOTES
632
633     EXAMPLE
634
635     BUGS
636
637     SEE ALSO
638
639     INTERNALS
640
641 *****************************************************************************************/
642 /*i***************************************************************************************
643
644     NAME
645         SA_ShowPointer
646
647     SYNOPSIS
648         [ISG], BOOL
649
650     LOCATION
651         screenclass
652
653     FUNCTION
654         Setting this attribute to FALSE makes mouse pointer invisible on your custom screen.
655         Default value is TRUE. Setting this attribute on public screens is ignore.
656
657     NOTES
658
659     EXAMPLE
660
661     BUGS
662
663     SEE ALSO
664
665     INTERNALS
666
667 *****************************************************************************************/
668 /*i***************************************************************************************
669
670     NAME
671         SA_GammaControl
672
673     SYNOPSIS
674         [I..], BOOL
675
676     LOCATION
677         screenclass
678
679     FUNCTION
680         Setting this attribute to TRUE enables to use SA_GammaRed, SA_GammaBlue and
681         SA_GammaGreen attributes to supply custom gamma correction table for your
682         screen.
683
684     NOTES
685         Since in AROS more than one screen can be visible simultaneously, current
686         display gamma correction table is determined by the frontmost screen on
687         that display.
688
689     EXAMPLE
690
691     BUGS
692
693     SEE ALSO
694
695     INTERNALS
696
697 *****************************************************************************************/
698
699 IPTR ScreenClass__OM_GET(Class *cl, Object *o, struct opGet *msg)
700 {
701     struct IntuitionBase *IntuitionBase = (struct IntuitionBase *)cl->cl_UserData;
702     struct Library *OOPBase = GetPrivIBase(IntuitionBase)->OOPBase;
703     OOP_AttrBase HiddBitMapAttrBase = GetPrivIBase(IntuitionBase)->HiddAttrBase;
704     OOP_AttrBase HiddPixFmtAttrBase = GetPrivIBase(IntuitionBase)->HiddPixFmtAttrBase;
705     struct IntScreen *screen = INST_DATA(cl, o);
706
707     switch (msg->opg_AttrID)
708     {
709     case SA_Left:
710         *msg->opg_Storage = screen->Screen.LeftEdge;
711         break;
712
713     case SA_Top:
714         *msg->opg_Storage = screen->Screen.TopEdge;
715         break;
716
717     case SA_Width:
718         *msg->opg_Storage = screen->Screen.Width;
719         break;
720
721     case SA_Height:
722         *msg->opg_Storage = screen->Screen.Height;
723         break;
724
725     case SA_Depth:
726         *msg->opg_Storage = screen->realdepth;
727         break;
728
729     case SA_PubName:
730         *msg->opg_Storage = (IPTR)screen->pubScrNode->psn_Node.ln_Name;
731         break;
732
733     case SA_DisplayID:
734         *msg->opg_Storage = screen->ModeID;
735         break;
736
737     case SA_Behind:
738         *msg->opg_Storage = (screen->Screen.Flags & SCREENBEHIND) ? TRUE : FALSE;
739         break;
740
741     case SA_Displayed:
742         *msg->opg_Storage = screen->GammaControl.Active;
743         break;
744
745     case SA_MonitorName:
746         return GetAttr(MA_MonitorName, screen->IMonitorNode, msg->opg_Storage);
747
748     case SA_MonitorObject:
749         *msg->opg_Storage = (IPTR)screen->IMonitorNode;
750         break;
751
752     case SA_TopLeftScreen:
753         *msg->opg_Storage = GetScreen(MA_TopLeftMonitor, screen, IntuitionBase);
754         break;
755
756     case SA_TopMiddleScreen:
757         *msg->opg_Storage = GetScreen(MA_TopMiddleMonitor, screen, IntuitionBase);
758         break;
759
760     case SA_TopRightScreen:
761         *msg->opg_Storage = GetScreen(MA_TopRightMonitor, screen, IntuitionBase);
762         break;
763
764     case SA_MiddleLeftScreen:
765         *msg->opg_Storage = GetScreen(MA_MiddleLeftMonitor, screen, IntuitionBase);
766         break;
767
768     case SA_MiddleRightScreen:
769         *msg->opg_Storage = GetScreen(MA_MiddleRightMonitor, screen, IntuitionBase);
770         break;
771
772     case SA_BottomLeftScreen:
773         *msg->opg_Storage = GetScreen(MA_BottomLeftMonitor, screen, IntuitionBase);
774         break;
775
776     case SA_BottomMiddleScreen:
777         *msg->opg_Storage = GetScreen(MA_BottomMiddleMonitor, screen, IntuitionBase);
778         break;
779
780     case SA_BottomRightScreen:
781         *msg->opg_Storage = GetScreen(MA_BottomRightMonitor, screen, IntuitionBase);
782         break;
783
784     case SA_ShowPointer:
785         *msg->opg_Storage = screen->ShowPointer;
786         break;
787
788     case SA_GammaRed:
789         *msg->opg_Storage = (IPTR)screen->GammaControl.GammaTableR;
790         break;
791
792     case SA_GammaBlue:
793         *msg->opg_Storage = (IPTR)screen->GammaControl.GammaTableB;
794         break;
795
796     case SA_GammaGreen:
797         *msg->opg_Storage = (IPTR)screen->GammaControl.GammaTableG;
798         break;
799
800     case SA_DisplayWidth:
801         *msg->opg_Storage = screen->Screen.ViewPort.DWidth;
802         break;
803
804     case SA_DisplayHeight:
805         *msg->opg_Storage = screen->Screen.ViewPort.DHeight;
806         break;
807
808     case SA_PixelFormat:
809         if (IS_HIDD_BM(screen->Screen.RastPort.BitMap))
810         {
811             OOP_Object *pixfmt;
812
813             OOP_GetAttr(HIDD_BM_OBJ(screen->Screen.RastPort.BitMap), aHidd_BitMap_PixFmt, (IPTR *)&pixfmt);
814             OOP_GetAttr(pixfmt, aHidd_PixFmt_CgxPixFmt, msg->opg_Storage);
815         }
816         else
817         {
818             *msg->opg_Storage = -1;
819         }
820         break;
821
822     case SA_ScreenbarTextYPos:
823         *msg->opg_Storage = screen->Screen.BarVBorder + screen->Screen.BarLayer->rp->TxBaseline;
824         break;
825
826     case SA_ScreenbarTextPen:
827         *msg->opg_Storage = screen->Pens[BARDETAILPEN];
828         break;
829
830     case SA_ScreenbarTextFont:
831         *msg->opg_Storage = (IPTR)screen->Screen.BarLayer->rp->Font;
832         break;
833
834     case SA_CompositingFlags:
835         *msg->opg_Storage = (IPTR)(screen->SpecialFlags >> 8);
836         break;
837
838     case SA_OpacitySupport:    /* These are reserved in AROS */
839     case SA_SourceAlphaSupport:
840     case SA_ScreenbarSignal:
841     case SA_CompositingLayers:
842         *msg->opg_Storage = 0;
843         break;
844
845     default:
846         return FALSE;
847     }
848
849     return TRUE;
850 }
851
852 IPTR ScreenClass__OM_SET(Class *cl, Object *o, struct opSet *msg)
853 {
854     struct IntuitionBase *IntuitionBase = (struct IntuitionBase *)cl->cl_UserData;
855     struct Library *UtilityBase = GetPrivIBase(IntuitionBase)->UtilityBase;
856     struct IntScreen *screen = INST_DATA(cl, o);
857     struct TagItem *tstate = msg->ops_AttrList;
858     struct TagItem *tag;
859     BOOL showpointer = screen->ShowPointer;
860     BOOL movescreen = FALSE;
861     BOOL gammaset = FALSE;
862
863     while((tag = NextTagItem(&tstate)))
864     {
865         switch (tag->ti_Tag)
866         {
867         case SA_Left:
868             if (screen->SpecialFlags & SF_Draggable)
869             {
870                 screen->Screen.LeftEdge = tag->ti_Data;
871                 movescreen = TRUE;
872             }
873             break;
874
875         case SA_Top:
876             if (screen->SpecialFlags & SF_Draggable)
877             {
878                 screen->Screen.TopEdge = tag->ti_Data;
879                 movescreen = TRUE;
880             }
881             break;
882
883         case SA_ShowPointer:
884             showpointer = tag->ti_Data;
885             break;
886
887         case SA_GammaRed:
888             if (screen->GammaControl.UseGammaControl)
889             {
890                 screen->GammaControl.GammaTableR = (UBYTE *)tag->ti_Data;
891                 gammaset = TRUE;
892             }
893             break;
894
895         case SA_GammaBlue:
896             if (screen->GammaControl.UseGammaControl)
897             {
898                 screen->GammaControl.GammaTableB = (UBYTE *)tag->ti_Data;
899                 gammaset = TRUE;
900             }
901             break;
902
903         case SA_GammaGreen:
904             if (screen->GammaControl.UseGammaControl)
905             {
906                 screen->GammaControl.GammaTableG = (UBYTE *)tag->ti_Data;
907                 gammaset = TRUE;
908             }
909             break;
910         }
911     }
912
913     if (movescreen)
914     {
915         /*
916          * Move the screen to (0, 0) relative of current position.
917          * LeftEdge/TopEdge have been already updated.
918          */
919         ScreenPosition(&screen->Screen, SPOS_RELATIVE, 0, 0, 0, 0);
920     }
921
922     if (showpointer != screen->ShowPointer)
923     {
924         screen->ShowPointer = showpointer;
925         /* TODO: Actually implement this */
926     }
927
928     if (gammaset)
929     {
930         /*
931          * Update gamma table on the monitor.
932          * The monitorclass takes care itself about whether this screen
933          * currently controlls gamma table.
934          */
935         DoMethod((Object *)screen->IMonitorNode, MM_SetScreenGamma, &GetPrivScreen(screen)->GammaControl, FALSE);
936     }
937
938     return 0;
939 }