tizen 2.3 release
[framework/uifw/xorg/lib/libhwc.git] / src / hwc.c
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Contact: Sangjin Lee <lsj119@samsung.com>
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Soft-
8  * ware"), to deal in the Software without restriction, including without
9  * limitation the rights to use, copy, modify, merge, publish, distribute,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, provided that the above copyright
12  * notice(s) and this permission notice appear in all copies of the Soft-
13  * ware and that both the above copyright notice(s) and this permission
14  * notice appear in supporting documentation.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
18  * ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY
19  * RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN
20  * THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE-
21  * QUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
22  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
23  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFOR-
24  * MANCE OF THIS SOFTWARE.
25  *
26  * Except as contained in this notice, the name of a copyright holder shall
27  * not be used in advertising or otherwise to promote the sale, use or
28  * other dealings in this Software without prior written authorization of
29  * the copyright holder.
30  *
31  * Origin Authors:
32  *   Sangjin Lee (lsj119@samsung.com)
33  */
34
35 #include <stdio.h>
36 #include <sys/types.h>
37 #include <unistd.h>
38 #include <X11/Xlibint.h>
39 #include <X11/extensions/Xext.h>
40 #include <X11/extensions/extutil.h>
41 #include <X11/extensions/hwcproto.h>
42 #include "hwc.h"
43
44 static char hwcExtensionName[] = HWC_NAME;
45 static XExtensionInfo *hwcInfo;
46
47 static int
48 HWCCloseDisplay(Display *dpy, XExtCodes *codes);
49 static int
50 HWCError(Display *display, xError *err, XExtCodes *codes, int *ret_code);
51 static Bool
52 HWCWireToCookie(Display *dpy,XGenericEventCookie *cookie, xEvent        *event);
53 static Bool
54 HWCCopyCookie(Display *dpy, XGenericEventCookie *in, XGenericEventCookie *out);
55
56 static /* const */ XExtensionHooks hwcExtensionHooks = {
57   NULL,                   /* create_gc */
58   NULL,                   /* copy_gc */
59   NULL,                   /* flush_gc */
60   NULL,                   /* free_gc */
61   NULL,                   /* create_font */
62   NULL,                   /* free_font */
63   HWCCloseDisplay,       /* close_display */
64   NULL,        /* wire_to_event */
65   NULL,        /* event_to_wire */
66   HWCError,              /* error */
67   NULL,                   /* error_string */
68 };
69
70 static XExtDisplayInfo *
71 HWCFindDisplay (Display *dpy)
72 {
73     XExtDisplayInfo *dpyinfo;
74     if (!hwcInfo)
75     {
76         if (!(hwcInfo = XextCreateExtension()))
77             return NULL;
78     }
79
80     if (!(dpyinfo = XextFindDisplay (hwcInfo, dpy)))
81     {
82         dpyinfo = XextAddDisplay (hwcInfo,dpy,hwcExtensionName,&hwcExtensionHooks,0,NULL);
83
84         if (dpyinfo->codes) /* NULL if HWC doesn't exist on the server */
85         {
86             XESetWireToEventCookie(dpy, dpyinfo->codes->major_opcode, HWCWireToCookie);
87             XESetCopyEventCookie(dpy, dpyinfo->codes->major_opcode, HWCCopyCookie);
88         }
89     }
90
91     return dpyinfo;
92 }
93
94 static int
95 HWCCloseDisplay(Display *dpy, XExtCodes *codes)
96 {
97    return XextRemoveDisplay (hwcInfo, dpy);
98 }
99
100 static int
101 HWCError(Display *display, xError *err, XExtCodes *codes, int *ret_code)
102 {
103     return False;
104 }
105
106 static Bool
107 HWCWireToCookie(Display *dpy, XGenericEventCookie *cookie, xEvent       *event)
108 {
109     XExtDisplayInfo *info = HWCFindDisplay(dpy);
110     xGenericEvent* ge = (xGenericEvent*)event;
111
112     if (ge->extension != info->codes->major_opcode)
113     {
114         fprintf(stderr, "HWCWireToCookie: wrong extension opcode %d\n",
115                 ge->extension);
116         return False;
117     }
118
119     cookie->type = ge->type;
120     cookie->serial = _XSetLastRequestRead(dpy, (xGenericReply *) event);
121     cookie->send_event = ((event->u.u.type & 0x80) != 0);
122     cookie->display = dpy;
123     cookie->extension = ge->extension;
124     cookie->evtype = ge->evtype;
125
126     /*Fill cookie data*/
127     switch(ge->evtype)
128     {
129         case HWCConfigureNotify:
130         {
131             xHWCConfigureNotify *in = (xHWCConfigureNotify*)event;
132             HWCConfigureNotifyCookie* data;
133
134             cookie->data = data = malloc(sizeof(HWCConfigureNotifyCookie));
135             data->evtype = HWCConfigureNotify;
136             data->maxLayer = in->maxLayer;
137             return True;
138         }
139         default:
140             printf("HWCWireToCookie: Unknown generic event. type %d\n", ge->evtype);
141     }
142
143     return False;
144 }
145
146 static Bool
147 HWCCopyCookie(Display *dpy, XGenericEventCookie *in, XGenericEventCookie *out)
148 {
149     XExtDisplayInfo *info = HWCFindDisplay(dpy);
150
151     if (in->extension != info->codes->major_opcode)
152     {
153         fprintf(stderr,"HWCCopyCookie: wrong extension opcode %d\n",
154                 in->extension);
155         return False;
156     }
157
158     *out = *in;
159     out->data = NULL;
160     out->cookie = 0;
161
162     switch(in->evtype) {
163         case HWCConfigureNotify:
164         {
165             HWCConfigureNotifyCookie *_in, *_out;
166
167             _in = (HWCConfigureNotifyCookie *)in->data;
168             _out = malloc(sizeof(HWCConfigureNotifyCookie));
169             *_out = *_in;
170             out->data = (void*)_out;
171             return True;
172         }
173         default:
174             fprintf(stderr, "HWCCopyCookie: Failed to copy evtype %d", in->evtype);
175             break;
176     }
177
178     return False;
179 }
180
181 Bool
182 HWCQueryVersion(Display * dpy, int *major, int *minor)
183 {
184    XExtDisplayInfo *info = HWCFindDisplay(dpy);
185    xHWCQueryVersionReply rep;
186    xHWCQueryVersionReq *req;
187
188    XextCheckExtension(dpy, info, hwcExtensionName, False);
189
190    LockDisplay(dpy);
191    GetReq(HWCQueryVersion, req);
192    req->reqType = info->codes->major_opcode;
193    req->hwcReqType = X_HWCQueryVersion;
194    req->majorVersion = HWC_MAJOR;
195    req->minorVersion = HWC_MINOR;
196    if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
197       UnlockDisplay(dpy);
198       SyncHandle();
199       return False;
200    }
201    *major = rep.majorVersion;
202    *minor = rep.minorVersion;
203    UnlockDisplay(dpy);
204    SyncHandle();
205
206    return True;
207 }
208
209 Bool
210 HWCOpen(Display * dpy, Window window, int *maxLayer)
211 {
212    XExtDisplayInfo *info = HWCFindDisplay(dpy);
213    xHWCOpenReply rep;
214    xHWCOpenReq *req;
215
216    XextCheckExtension(dpy, info, hwcExtensionName, False);
217
218    LockDisplay(dpy);
219    GetReq(HWCOpen, req);
220    req->reqType = info->codes->major_opcode;
221    req->hwcReqType = X_HWCOpen;
222    req->window = window;
223
224    if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
225       UnlockDisplay(dpy);
226       SyncHandle();
227       return False;
228    }
229
230    *maxLayer = rep.maxLayer;
231
232    UnlockDisplay(dpy);
233    SyncHandle();
234
235    return True;
236 }
237
238 void
239 HWCSetDrawables(Display * dpy, Window window, Drawable *drawables, XRectangle *srcRect, XRectangle *dstRect, int count)
240 {
241     XExtDisplayInfo *info = HWCFindDisplay(dpy);
242     xHWCSetDrawablesReq *req;
243     xHWCDrawInfo *p;
244     int i;
245
246     XextSimpleCheckExtension(dpy, info, hwcExtensionName);
247     LockDisplay(dpy);
248
249     GetReqExtra(HWCSetDrawables, count * SIZEOF(xHWCDrawInfo), req);
250
251     req->reqType = info->codes->major_opcode;
252     req->hwcReqType = X_HWCSetDrawables;
253     req->window = window;
254     req->count = count;
255     p = (xHWCDrawInfo *) & req[1];
256     for (i = 0; i < count; i++)
257     {
258         p[i].drawable = drawables[i];
259         p[i].srcX = srcRect[i].x;
260         p[i].srcY = srcRect[i].y;
261         p[i].srcWidth = srcRect[i].width;
262         p[i].srcHeight = srcRect[i].height;
263         p[i].dstX = dstRect[i].x;
264         p[i].dstY = dstRect[i].y;
265         p[i].dstWidth = dstRect[i].width;
266         p[i].dstHeight = dstRect[i].height;
267     }
268
269     UnlockDisplay(dpy);
270     SyncHandle();
271 }
272
273 void
274 HWCSelectInput(Display * dpy, Window window, int mask)
275 {
276     XExtDisplayInfo *info = HWCFindDisplay(dpy);
277     xHWCSelectInputReq *req;
278
279     XextSimpleCheckExtension(dpy, info, hwcExtensionName);
280     LockDisplay(dpy);
281
282     GetReq(HWCSelectInput, req);
283     req->reqType = info->codes->major_opcode;
284     req->hwcReqType = X_HWCSelectInput;
285     req->window = window;
286     req->eventMask = mask;
287
288     UnlockDisplay(dpy);
289     SyncHandle();
290 }
291