2 Copyright © 1995-2017, The AROS Development Team. All rights reserved.
5 Desc: Android-hosted graphics driver class.
11 #define __OOP_NOATTRBASES__
13 #include <sys/types.h>
14 #include <android/configuration.h>
17 #include <aros/debug.h>
18 #include <aros/symbolsets.h>
19 #include <graphics/displayinfo.h>
20 #include <hidd/hidd.h>
22 #include <hidd/keyboard.h>
23 #include <hidd/mouse.h>
24 #include <hidd/unixio.h>
26 #include <proto/exec.h>
27 #include <proto/hostlib.h>
28 #include <proto/oop.h>
29 #include <proto/utility.h>
31 #include LC_LIBDEFS_FILE
33 #include "android_server.h"
35 OOP_Object
*AGFXCl__Root__New(OOP_Class
*cl
, OOP_Object
*o
, struct pRoot_New
*msg
)
37 struct QueryRequest query
;
39 struct TagItem pftags
[] =
42 * Shifts are non-obviously calculated from the MSB, not from the LSB.
43 * I. e. color value is placed in the most significant byte of the ULONG
44 * before shifting (cc000000, not 000000cc)
46 { aHidd_PixFmt_RedShift
, 24 },
47 { aHidd_PixFmt_GreenShift
, 16 },
48 { aHidd_PixFmt_BlueShift
, 8 },
49 { aHidd_PixFmt_AlphaShift
, 0 },
50 { aHidd_PixFmt_RedMask
, 0x000000FF },
51 { aHidd_PixFmt_GreenMask
, 0x0000FF00 },
52 { aHidd_PixFmt_BlueMask
, 0x00FF0000 },
53 { aHidd_PixFmt_AlphaMask
, 0x00000000 },
54 { aHidd_PixFmt_ColorModel
, vHidd_ColorModel_TrueColor
},
55 { aHidd_PixFmt_Depth
, 24 },
56 { aHidd_PixFmt_BytesPerPixel
, 4 },
57 { aHidd_PixFmt_BitsPerPixel
, 24 },
58 { aHidd_PixFmt_StdPixFmt
, vHidd_StdPixFmt_Native
},
59 { aHidd_PixFmt_BitMapType
, vHidd_BitMapType_Chunky
},
63 struct TagItem p_sync_tags
[] =
65 { aHidd_Sync_HDisp
, 160 },
66 { aHidd_Sync_VDisp
, 160 },
67 { aHidd_Sync_Description
, (IPTR
)"Android: %hx%v Portrait"},
71 struct TagItem l_sync_tags
[] =
73 { aHidd_Sync_HDisp
, 160 },
74 { aHidd_Sync_VDisp
, 160 },
75 { aHidd_Sync_Description
, (IPTR
)"Android: %hx%v Landscape"},
79 struct TagItem mode_tags
[] =
81 { aHidd_Gfx_PixFmtTags
, (IPTR
)pftags
},
83 { aHidd_Sync_HMax
, 16384 },
84 { aHidd_Sync_VMax
, 16384 },
86 { aHidd_Gfx_SyncTags
, (IPTR
)p_sync_tags
},
87 { aHidd_Gfx_SyncTags
, (IPTR
)l_sync_tags
},
91 struct TagItem mytags
[] =
93 { aHidd_Gfx_ModeTags
, (IPTR
)mode_tags
},
94 { aHidd_Name
, (IPTR
)"androidgfx"},
95 { aHidd_HardwareName
, (IPTR
)"Android OS Gfx Host" },
96 { aHidd_ProducerName
, (IPTR
)"Google inc." },
97 { TAG_MORE
, (IPTR
)msg
->attrList
}
99 struct pRoot_New mymsg
= { msg
->mID
, mytags
};
101 EnterFunc(bug("AGFX::New()\n"));
103 /* Get display size */
104 query
.req
.cmd
= cmd_Query
;
107 DoRequest(&query
.req
, XSD(cl
));
109 if (query
.req
.status
!= STATUS_ACK
)
111 D(bug("[AGFX] Display server communication error\n"));
115 D(bug("[AGFX] Display size: %ux%u, Titlebar size: %u, Orientation: %u\n", query
.width
, query
.height
, query
.titlebar
, query
.orientation
));
117 if (query
.orientation
== ACONFIGURATION_ORIENTATION_PORT
)
119 p_sync_tags
[0].ti_Data
= query
.width
;
120 p_sync_tags
[1].ti_Data
= query
.height
- query
.titlebar
;
121 l_sync_tags
[0].ti_Data
= query
.height
;
122 l_sync_tags
[1].ti_Data
= query
.width
- query
.titlebar
;
126 l_sync_tags
[0].ti_Data
= query
.width
;
127 l_sync_tags
[1].ti_Data
= query
.height
- query
.titlebar
;
128 p_sync_tags
[0].ti_Data
= query
.height
;
129 p_sync_tags
[1].ti_Data
= query
.width
- query
.titlebar
;
132 /* Register gfxmodes */
133 o
= (OOP_Object
*)OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)&mymsg
);
136 struct gfx_data
*data
= OOP_INST_DATA(cl
, o
);
138 D(bug("AGFX::New(): Got object from super\n"));
140 data
->width
= query
.width
;
141 data
->height
= query
.height
;
143 ReturnPtr("AGFXGfx::New", OOP_Object
*, o
);
146 /****************************************************************************************/
148 OOP_Object
*AGFXCl__Hidd_Gfx__CreateObject(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_CreateObject
*msg
)
150 OOP_Object
*object
= NULL
;
152 if (msg
->cl
== XSD(cl
)->basebm
)
155 struct pHidd_Gfx_CreateObject p
;
156 struct TagItem tags
[] =
159 {TAG_MORE
, (IPTR
)msg
->attrList
}
162 /* Here we select a class for the bitmap to create */
164 displayable
= GetTagData(aHidd_BitMap_Displayable
, FALSE
, msg
->attrList
);
167 /* Displayable bitmaps are bitmaps of our class */
168 tags
[0].ti_Tag
= aHidd_BitMap_ClassPtr
;
169 tags
[0].ti_Data
= (IPTR
)XSD(cl
)->bmclass
;
173 /* Non-displayable friends of our bitmaps are plain chunky bitmaps */
174 OOP_Object
*friend = (OOP_Object
*)GetTagData(aHidd_BitMap_Friend
, 0, msg
->attrList
);
176 if (friend && (OOP_OCLASS(friend) == XSD(cl
)->bmclass
))
178 tags
[0].ti_Tag
= aHidd_BitMap_ClassID
;
179 tags
[0].ti_Data
= (IPTR
)CLID_Hidd_ChunkyBM
;
183 /* The base class will take care about other cases */
189 object
= (OOP_Object
*)OOP_DoSuperMethod(cl
, o
, &p
.mID
);
192 object
= (OOP_Object
*)OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
197 /****************************************************************************************/
199 VOID
AGFXCl__Root__Get(OOP_Class
*cl
, OOP_Object
*o
, struct pRoot_Get
*msg
)
203 if (IS_GFX_ATTR(msg
->attrID
, idx
))
207 case aoHidd_Gfx_IsWindowed
:
208 case aoHidd_Gfx_NoFrameBuffer
:
209 *msg
->storage
= TRUE
;
212 case aoHidd_Gfx_DriverName
:
213 *msg
->storage
= (IPTR
)"Android";
217 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
220 /****************************************************************************************/
222 OOP_Object
*AGFXCl__Hidd_Gfx__Show(OOP_Class
*cl
, OOP_Object
*o
, struct pHidd_Gfx_Show
*msg
)
224 struct gfx_data
*data
= OOP_INST_DATA(cl
, o
);
226 D(bug("[AGFX] Show(0x%p)\n", msg
->bitMap
));
229 OOP_SetAttrsTags(data
->bitmap
, aHidd_BitMap_Visible
, FALSE
, TAG_DONE
);
232 OOP_SetAttrsTags(msg
->bitMap
, aHidd_BitMap_Visible
, TRUE
, TAG_DONE
);
235 /* addr == NULL will clear the screen. Offset and size are ignored. */
236 struct ShowRequest show
;
238 show
.req
.cmd
= cmd_Show
;
241 show
.orientation
= ACONFIGURATION_ORIENTATION_ANY
; /* Do not change the orientation */
244 DoRequest(&show
.req
, XSD(cl
));
247 data
->bitmap
= msg
->bitMap
;
251 /****************************************************************************************/
253 /* The following two functions are candidates for inclusion into oop.library */
254 static void FreeAttrBases(const STRPTR
*iftable
, OOP_AttrBase
*bases
)
258 for (i
= 0; iftable
[i
]; i
++)
261 OOP_ReleaseAttrBase(iftable
[i
]);
267 static OOP_AttrBase
*AllocAttrBases(const STRPTR
*iftable
)
272 for (cnt
= 0; iftable
[cnt
]; cnt
++);
274 ret
= AllocVec(cnt
* sizeof(OOP_AttrBase
), MEMF_CLEAR
);
277 for (i
= 0; i
< cnt
; i
++)
279 ret
[i
] = OOP_ObtainAttrBase(iftable
[i
]);
282 FreeAttrBases(iftable
, ret
);
291 static const STRPTR interfaces
[] =
304 static int GetPipe(const char *name
, APTR lib
, APTR HostLibBase
)
306 int *ptr
= HostLib_GetPointer(lib
, name
, NULL
);
310 D(bug("[AGFX] Failed to locate symbol %s\n", name
));
318 #define XSD(cl) (&agfxBase->xsd)
320 static int agfx_init(struct AGFXBase
*agfxBase
)
325 struct HelloRequest hello
;
327 HostLibBase
= OpenResource("hostlib.resource");
331 HostLibHandle
= HostLib_Open("libAROSBootstrap.so", NULL
);
335 agfxBase
->xsd
.DisplayPipe
= GetPipe("DisplayPipe", HostLibHandle
, HostLibBase
);
336 agfxBase
->xsd
.InputPipe
= GetPipe("InputPipe", HostLibHandle
, HostLibBase
);
338 D(bug("[AGFX] DisplayPipe %d InputPipe %d\n", agfxBase
->xsd
.DisplayPipe
, agfxBase
->xsd
.InputPipe
));
340 HostLib_Close(HostLibHandle
, NULL
);
342 if ((agfxBase
->xsd
.DisplayPipe
== -1) || (agfxBase
->xsd
.InputPipe
== -1))
345 agfxBase
->xsd
.AttrBases
= AllocAttrBases(interfaces
);
346 if (!agfxBase
->xsd
.AttrBases
)
349 agfxBase
->xsd
.unixio
= OOP_NewObject(NULL
, CLID_Hidd_UnixIO
, NULL
);
350 if (!agfxBase
->xsd
.unixio
)
353 NEWLIST(&agfxBase
->xsd
.waitQueue
);
355 agfxBase
->xsd
.serverInt
.fd
= agfxBase
->xsd
.InputPipe
;
356 agfxBase
->xsd
.serverInt
.mode
= vHidd_UnixIO_Read
;
357 agfxBase
->xsd
.serverInt
.handler
= agfxInt
;
358 agfxBase
->xsd
.serverInt
.handlerData
= &agfxBase
->xsd
;
360 res
= Hidd_UnixIO_AddInterrupt(agfxBase
->xsd
.unixio
, &agfxBase
->xsd
.serverInt
);
363 Hidd_UnixIO_CloseFile(agfxBase
->xsd
.unixio
, agfxBase
->xsd
.DisplayPipe
, NULL
);
364 Hidd_UnixIO_CloseFile(agfxBase
->xsd
.unixio
, agfxBase
->xsd
.InputPipe
, NULL
);
366 /* We don't need to dispose a unixio v42 object, it's a singletone. */
367 agfxBase
->xsd
.unixio
= NULL
;
371 /* Say hello to our display server */
372 hello
.req
.cmd
= cmd_Hello
;
374 hello
.version
= PROTOCOL_VERSION
;
375 DoRequest(&hello
.req
, &agfxBase
->xsd
);
377 if (hello
.req
.status
!= STATUS_ACK
)
379 D(bug("[AGFX] Display server version mismatch\n"));
383 D(bug("[AGFX] Init OK\n"));
388 /****************************************************************************************/
390 static int agfx_expunge(struct AGFXBase
*agfxBase
)
392 D(bug("[AGFX] Expunge\n"));
394 if (agfxBase
->xsd
.unixio
)
396 Hidd_UnixIO_RemInterrupt(agfxBase
->xsd
.unixio
, &agfxBase
->xsd
.serverInt
);
398 if (agfxBase
->xsd
.DisplayPipe
!= -1)
399 Hidd_UnixIO_CloseFile(agfxBase
->xsd
.unixio
, agfxBase
->xsd
.DisplayPipe
, NULL
);
401 if (agfxBase
->xsd
.InputPipe
!= -1)
402 Hidd_UnixIO_CloseFile(agfxBase
->xsd
.unixio
, agfxBase
->xsd
.InputPipe
, NULL
);
405 if (agfxBase
->xsd
.AttrBases
)
406 FreeAttrBases(interfaces
, agfxBase
->xsd
.AttrBases
);
411 /****************************************************************************************/
413 ADD2INITLIB(agfx_init
, 0);
414 ADD2EXPUNGELIB(agfx_expunge
, 0);
415 ADD2LIBS("unixio.hidd", 42, static struct Library
*, unixioBase
);