rename the directory
[AROS.git] / arch / all-android / hidd / androidgfx / agfx.c
blob76fffcb37b023d92d0f62c07a66a20d2a13094b2
1 /*
2 Copyright © 1995-2015, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Android-hosted graphics driver class.
6 Lang: English.
7 */
9 #define DEBUG 1
11 #define __OOP_NOATTRBASES__
13 #include <sys/types.h>
14 #include <android/configuration.h>
15 #include <fcntl.h>
17 #include <aros/debug.h>
18 #include <aros/symbolsets.h>
19 #include <graphics/displayinfo.h>
20 #include <hidd/hidd.h>
21 #include <hidd/graphics.h>
22 #include <hidd/keyboard.h>
23 #include <hidd/mouse.h>
24 #include <hidd/unixio.h>
25 #include <oop/oop.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 "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 },
60 { TAG_DONE , 0 }
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"},
68 { TAG_DONE , 0UL }
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"},
76 { TAG_DONE , 0UL }
79 struct TagItem mode_tags[] =
81 { aHidd_Gfx_PixFmtTags , (IPTR)pftags },
82 #ifdef ENABLE_SCROLL
83 { aHidd_Sync_HMax , 16384 },
84 { aHidd_Sync_VMax , 16384 },
85 #endif
86 { aHidd_Gfx_SyncTags , (IPTR)p_sync_tags },
87 { aHidd_Gfx_SyncTags , (IPTR)l_sync_tags },
88 { TAG_DONE , 0UL }
91 struct TagItem mytags[] =
93 { aHidd_Gfx_ModeTags , (IPTR)mode_tags },
94 { aHidd_Name , (IPTR)"android.monitor"},
95 { aHidd_HardwareName , (IPTR)"Android OS" },
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;
105 query.req.len = 1;
106 query.id = 0;
107 DoRequest(&query.req, XSD(cl));
109 if (query.req.status != STATUS_ACK)
111 D(bug("[AGFX] Display server communication error\n"));
112 return NULL;
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;
124 else
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);
134 if (o)
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)
154 BOOL displayable;
155 struct pHidd_Gfx_CreateObject p;
156 struct TagItem tags[] =
158 {TAG_IGNORE, 0 },
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);
165 if (displayable)
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;
171 else
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 */
185 p.mID = msg->mID;
186 p.cl = msg->cl;
187 p.attrList = tags;
189 object = (OOP_Object *)OOP_DoSuperMethod(cl, o, &p.mID);
191 else
192 object = (OOP_Object *)OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
194 return object;
197 /****************************************************************************************/
199 VOID AGFXCl__Root__Get(OOP_Class *cl, OOP_Object *o, struct pRoot_Get *msg)
201 ULONG idx;
203 if (IS_GFX_ATTR(msg->attrID, idx))
205 switch (idx)
207 case aoHidd_Gfx_IsWindowed:
208 case aoHidd_Gfx_NoFrameBuffer:
209 *msg->storage = TRUE;
210 return;
212 case aoHidd_Gfx_DriverName:
213 *msg->storage = (IPTR)"Android";
214 return;
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));
228 if (data->bitmap)
229 OOP_SetAttrsTags(data->bitmap, aHidd_BitMap_Visible, FALSE, TAG_DONE);
231 if (msg->bitMap)
232 OOP_SetAttrsTags(msg->bitMap, aHidd_BitMap_Visible, TRUE, TAG_DONE);
233 else
235 /* addr == NULL will clear the screen. Offset and size are ignored. */
236 struct ShowRequest show;
238 show.req.cmd = cmd_Show;
239 show.req.len = 8;
240 show.displayid = 0;
241 show.orientation = ACONFIGURATION_ORIENTATION_ANY; /* Do not change the orientation */
242 show.addr = 0;
244 DoRequest(&show.req, XSD(cl));
247 data->bitmap = msg->bitMap;
248 return 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)
256 ULONG i;
258 for (i = 0; iftable[i]; i++)
260 if (bases[i])
261 OOP_ReleaseAttrBase(iftable[i]);
264 FreeVec(bases);
267 static OOP_AttrBase *AllocAttrBases(const STRPTR *iftable)
269 ULONG cnt, i;
270 OOP_AttrBase *ret;
272 for (cnt = 0; iftable[cnt]; cnt++);
274 ret = AllocVec(cnt * sizeof(OOP_AttrBase), MEMF_CLEAR);
275 if (ret)
277 for (i = 0; i < cnt; i++)
279 ret[i] = OOP_ObtainAttrBase(iftable[i]);
280 if (!ret[i])
282 FreeAttrBases(iftable, ret);
283 return NULL;
288 return ret;
291 static const STRPTR interfaces[] =
293 IID_Hidd_ChunkyBM,
294 IID_Hidd_BitMap,
295 IID_Hidd_Sync,
296 IID_Hidd_PixFmt,
297 IID_Hidd_Gfx,
298 IID_Hidd_Kbd,
299 IID_Hidd_Mouse,
300 IID_Hidd,
301 NULL
304 static int GetPipe(const char *name, APTR lib, APTR HostLibBase)
306 int *ptr = HostLib_GetPointer(lib, name, NULL);
308 if (!ptr)
310 D(bug("[AGFX] Failed to locate symbol %s\n", name));
311 return -1;
314 return *ptr;
317 #undef XSD
318 #define XSD(cl) (&agfxBase->xsd)
320 static int agfx_init(struct AGFXBase *agfxBase)
322 APTR HostLibBase;
323 APTR HostLibHandle;
324 int res;
325 struct HelloRequest hello;
327 HostLibBase = OpenResource("hostlib.resource");
328 if (!HostLibBase)
329 return FALSE;
331 HostLibHandle = HostLib_Open("libAROSBootstrap.so", NULL);
332 if (!HostLibHandle)
333 return FALSE;
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))
343 return FALSE;
345 agfxBase->xsd.AttrBases = AllocAttrBases(interfaces);
346 if (!agfxBase->xsd.AttrBases)
347 return FALSE;
349 agfxBase->xsd.unixio = OOP_NewObject(NULL, CLID_Hidd_UnixIO, NULL);
350 if (!agfxBase->xsd.unixio)
351 return FALSE;
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);
361 if (res)
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;
368 return FALSE;
371 /* Say hello to our display server */
372 hello.req.cmd = cmd_Hello;
373 hello.req.len = 1;
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"));
380 return FALSE;
383 D(bug("[AGFX] Init OK\n"));
385 return TRUE;
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);
408 return TRUE;
411 /****************************************************************************************/
413 ADD2INITLIB(agfx_init, 0);
414 ADD2EXPUNGELIB(agfx_expunge, 0);
415 ADD2LIBS("unixio.hidd", 42, static struct Library *, unixioBase);