static int ephyrGetPortAttribute(KdScreenInfo * a_screen_info, Atom a_attr_name, int *a_attr_value, pointer a_port_priv) { int res = Success, host_atom = 0; EphyrPortPriv *port_priv = a_port_priv; EPHYR_RETURN_VAL_IF_FAIL(port_priv, BadMatch); EPHYR_RETURN_VAL_IF_FAIL(ValidAtom(a_attr_name), BadMatch); EPHYR_LOG("enter, portnum:%d, atomid:%d, attr_name:%s\n", port_priv->port_number, (int) a_attr_name, NameForAtom(a_attr_name)); if (!ephyrLocalAtomToHost(a_attr_name, &host_atom)) { EPHYR_LOG_ERROR("failed to convert local atom to host atom\n"); res = BadMatch; goto out; } if (!ephyrHostXVGetPortAttribute(port_priv->port_number, host_atom, a_attr_value)) { EPHYR_LOG_ERROR("failed to get port attribute\n"); res = BadMatch; goto out; } res = Success; out: EPHYR_LOG("leave\n"); return res; }
static int ephyrGLXMakeCurrentReal(__GLXclientState * a_cl, GLXDrawable write, GLXDrawable read, GLXContextTag ctx, GLXContextTag old_ctx, Bool a_do_swap) { int res = BadImplementation; xGLXMakeCurrentReply reply; DrawablePtr drawableR = NULL, drawableW = NULL; GLXContextTag new_ctx = 0; EPHYR_LOG("enter\n"); res = dixLookupDrawable(&drawableW, write, a_cl->client, 0, DixReadAccess); EPHYR_RETURN_VAL_IF_FAIL(drawableW, BadValue); EPHYR_RETURN_VAL_IF_FAIL(drawableW->pScreen, BadValue); EPHYR_LOG("screen nummber requested:%d\n", drawableW->pScreen->myNum); if (read != write) { res = dixLookupDrawable(&drawableR, read, a_cl->client, 0, DixReadAccess); EPHYR_RETURN_VAL_IF_FAIL(drawableR, BadValue); EPHYR_RETURN_VAL_IF_FAIL(drawableR->pScreen, BadValue); } else { drawableR = drawableW; } if (!ephyrHostGLXMakeCurrent(hostx_get_window(drawableW->pScreen->myNum), hostx_get_window(drawableR->pScreen->myNum), ctx, old_ctx, (int *) &new_ctx)) { EPHYR_LOG_ERROR("ephyrHostGLXMakeCurrent() failed\n"); goto out; } reply = (xGLXMakeCurrentReply) { .type = X_Reply, .sequenceNumber = a_cl->client->sequence, .length = 0, .contextTag = new_ctx }; if (a_do_swap) { __GLX_DECLARE_SWAP_VARIABLES; __GLX_SWAP_SHORT(&reply.sequenceNumber); __GLX_SWAP_INT(&reply.length); __GLX_SWAP_INT(&reply.contextTag); } WriteToClient(a_cl->client, sz_xGLXMakeCurrentReply, &reply); res = Success; out: EPHYR_LOG("leave\n"); return res; } int ephyrGLXMakeCurrent(__GLXclientState * a_cl, GLbyte * a_pc) { xGLXMakeCurrentReq *req = (xGLXMakeCurrentReq *) a_pc; return ephyrGLXMakeCurrentReal(a_cl, req->drawable, req->drawable, req->context, req->oldContextTag, FALSE); }
static int ephyrSetPortAttribute(KdScreenInfo * a_info, Atom a_attr_name, int a_attr_value, pointer a_port_priv) { int res = Success, host_atom = 0; EphyrPortPriv *port_priv = a_port_priv; Bool is_attr_valid = FALSE; EPHYR_RETURN_VAL_IF_FAIL(port_priv, BadMatch); EPHYR_RETURN_VAL_IF_FAIL(port_priv->current_adaptor, BadMatch); EPHYR_RETURN_VAL_IF_FAIL(port_priv->current_adaptor->pAttributes, BadMatch); EPHYR_RETURN_VAL_IF_FAIL(port_priv->current_adaptor->nAttributes, BadMatch); EPHYR_RETURN_VAL_IF_FAIL(ValidAtom(a_attr_name), BadMatch); EPHYR_LOG("enter, portnum:%d, atomid:%d, attr_name:%s, attr_val:%d\n", port_priv->port_number, (int) a_attr_name, NameForAtom(a_attr_name), a_attr_value); if (!ephyrLocalAtomToHost(a_attr_name, &host_atom)) { EPHYR_LOG_ERROR("failed to convert local atom to host atom\n"); res = BadMatch; goto out; } if (!ephyrXVPrivIsAttrValueValid(port_priv->current_adaptor->pAttributes, port_priv->current_adaptor->nAttributes, NameForAtom(a_attr_name), a_attr_value, &is_attr_valid)) { EPHYR_LOG_ERROR("failed to validate attribute %s\n", NameForAtom(a_attr_name)); /* res = BadMatch ; goto out ; */ } if (!is_attr_valid) { EPHYR_LOG_ERROR("attribute %s is not valid\n", NameForAtom(a_attr_name)); /* res = BadMatch ; goto out ; */ } if (!ephyrHostXVSetPortAttribute(port_priv->port_number, host_atom, a_attr_value)) { EPHYR_LOG_ERROR("failed to set port attribute\n"); res = BadMatch; goto out; } res = Success; out: EPHYR_LOG("leave\n"); return res; }
static int ephyrPutVideo(KdScreenInfo * a_info, DrawablePtr a_drawable, short a_vid_x, short a_vid_y, short a_drw_x, short a_drw_y, short a_vid_w, short a_vid_h, short a_drw_w, short a_drw_h, RegionPtr a_clipping_region, pointer a_port_priv) { EphyrPortPriv *port_priv = a_port_priv; BoxRec clipped_area, dst_box; int result = BadImplementation; int drw_x = 0, drw_y = 0, drw_w = 0, drw_h = 0; EPHYR_RETURN_VAL_IF_FAIL(a_info->pScreen, BadValue); EPHYR_RETURN_VAL_IF_FAIL(a_drawable && port_priv, BadValue); EPHYR_LOG("enter\n"); dst_box.x1 = a_drw_x; dst_box.x2 = a_drw_x + a_drw_w; dst_box.y1 = a_drw_y; dst_box.y2 = a_drw_y + a_drw_h; if (!DoSimpleClip(&dst_box, RegionExtents(a_clipping_region), &clipped_area)) { EPHYR_LOG_ERROR("failed to simple clip\n"); goto out; } drw_x = clipped_area.x1; drw_y = clipped_area.y1; drw_w = clipped_area.x2 - clipped_area.x1; drw_h = clipped_area.y2 - clipped_area.y1; if (!ephyrHostXVPutVideo(a_info->pScreen->myNum, port_priv->port_number, a_vid_x, a_vid_y, a_vid_w, a_vid_h, a_drw_x, a_drw_y, a_drw_w, a_drw_h)) { EPHYR_LOG_ERROR("ephyrHostXVPutVideo() failed\n"); goto out; } result = Success; out: EPHYR_LOG("leave\n"); return result; }
static int ephyrQueryImageAttributes(KdScreenInfo * a_info, int a_id, unsigned short *a_w, unsigned short *a_h, int *a_pitches, int *a_offsets) { int image_size = 0; EPHYR_RETURN_VAL_IF_FAIL(a_w && a_h, FALSE); EPHYR_LOG("enter: dim (%dx%d), pitches: %p, offsets: %p\n", *a_w, *a_h, a_pitches, a_offsets); if (!ephyrHostXVQueryImageAttributes(s_base_port_id, a_id, a_w, a_h, &image_size, a_pitches, a_offsets)) { EPHYR_LOG_ERROR("EphyrHostXVQueryImageAttributes() failed\n"); goto out; } EPHYR_LOG("image size: %d, dim (%dx%d)\n", image_size, *a_w, *a_h); out: EPHYR_LOG("leave\n"); return image_size; }
Bool ephyrDRIGetClientDriverName(int a_screen, int *a_ddx_driver_major_version, int *a_ddx_driver_minor_version, int *a_ddx_driver_patch_version, char **a_client_driver_name) { Display *dpy = hostx_get_display(); Bool is_ok = FALSE; EPHYR_RETURN_VAL_IF_FAIL(a_ddx_driver_major_version && a_ddx_driver_minor_version && a_ddx_driver_patch_version && a_client_driver_name, FALSE); EPHYR_LOG("enter\n"); is_ok = XF86DRIGetClientDriverName(dpy, DefaultScreen(dpy), a_ddx_driver_major_version, a_ddx_driver_minor_version, a_ddx_driver_patch_version, a_client_driver_name); EPHYR_LOG("major:%d, minor:%d, patch:%d, name:%s\n", *a_ddx_driver_major_version, *a_ddx_driver_minor_version, *a_ddx_driver_patch_version, *a_client_driver_name); EPHYR_LOG("leave:%d\n", is_ok); return is_ok; }
Bool ephyrDRIGetDrawableInfo(int a_screen, int a_drawable, unsigned int *a_index, unsigned int *a_stamp, int *a_x, int *a_y, int *a_w, int *a_h, int *a_num_clip_rects, drm_clip_rect_t ** a_clip_rects, int *a_back_x, int *a_back_y, int *a_num_back_clip_rects, drm_clip_rect_t ** a_back_clip_rects) { Bool is_ok = FALSE; Display *dpy = hostx_get_display(); EphyrHostWindowAttributes attrs; EPHYR_RETURN_VAL_IF_FAIL(a_x && a_y && a_w && a_h && a_num_clip_rects, FALSE); EPHYR_LOG("enter\n"); memset(&attrs, 0, sizeof(attrs)); if (!hostx_get_window_attributes(a_drawable, &attrs)) { EPHYR_LOG_ERROR("failed to query host window attributes\n"); goto out; } if (!XF86DRIGetDrawableInfo(dpy, DefaultScreen(dpy), a_drawable, a_index, a_stamp, a_x, a_y, a_w, a_h, a_num_clip_rects, a_clip_rects, a_back_x, a_back_y, a_num_back_clip_rects, a_back_clip_rects)) { EPHYR_LOG_ERROR("XF86DRIGetDrawableInfo ()\n"); goto out; } EPHYR_LOG("host x,y,w,h: (%d,%d,%d,%d)\n", *a_x, *a_y, *a_w, *a_h); if (*a_num_clip_rects) { free(*a_back_clip_rects); *a_back_clip_rects = calloc(*a_num_clip_rects, sizeof(drm_clip_rect_t)); memmove(*a_back_clip_rects, *a_clip_rects, *a_num_clip_rects * sizeof(drm_clip_rect_t)); *a_num_back_clip_rects = *a_num_clip_rects; } EPHYR_LOG("num back clip rects:%d, num clip rects:%d\n", *a_num_clip_rects, *a_num_back_clip_rects); *a_back_x = *a_x; *a_back_y = *a_y; *a_w = attrs.width; *a_h = attrs.height; is_ok = TRUE; out: EPHYR_LOG("leave. index:%d, stamp:%d, x,y:(%d,%d), w,y:(%d,%d)\n", *a_index, *a_stamp, *a_x, *a_y, *a_w, *a_h); return is_ok; }
static int ephyrGLXIsDirectReal (__GLXclientState *a_cl, GLbyte *a_pc, Bool a_do_swap) { int res=BadImplementation; ClientPtr client = a_cl->client; xGLXIsDirectReq *req = (xGLXIsDirectReq *) a_pc; xGLXIsDirectReply reply; int is_direct=0 ; EPHYR_RETURN_VAL_IF_FAIL (a_cl && a_pc, FALSE) ; EPHYR_LOG ("enter\n") ; memset (&reply, 0, sizeof (reply)) ; if (!ephyrHostIsContextDirect (req->context, (int*)&is_direct)) { EPHYR_LOG_ERROR ("ephyrHostIsContextDirect() failed\n") ; goto out ; } reply.isDirect = is_direct ; reply.length = 0; reply.type = X_Reply; reply.sequenceNumber = client->sequence; WriteToClient(client, sz_xGLXIsDirectReply, (char *)&reply); res = Success ; out: EPHYR_LOG ("leave\n") ; return res ; }
static Bool ephyrXVPrivIsAttrValueValid(KdAttributePtr a_attrs, int a_attrs_len, const char *a_attr_name, int a_attr_value, Bool *a_is_valid) { int i = 0; EPHYR_RETURN_VAL_IF_FAIL(a_attrs && a_attr_name && a_is_valid, FALSE); for (i = 0; i < a_attrs_len; i++) { if (a_attrs[i].name && strcmp(a_attrs[i].name, a_attr_name)) continue; if (a_attrs[i].min_value > a_attr_value || a_attrs[i].max_value < a_attr_value) { *a_is_valid = FALSE; EPHYR_LOG_ERROR("attribute was not valid\n" "value:%d. min:%d. max:%d\n", a_attr_value, a_attrs[i].min_value, a_attrs[i].max_value); } else { *a_is_valid = TRUE; } return TRUE; } return FALSE; }
static int ephyrGLXMakeCurrentReal (__GLXclientState *a_cl, GLbyte *a_pc, Bool a_do_swap) { int res=BadImplementation; xGLXMakeCurrentReq *req = (xGLXMakeCurrentReq *) a_pc; xGLXMakeCurrentReply reply ; DrawablePtr drawable=NULL; int rc=0; EPHYR_LOG ("enter\n") ; rc = dixLookupDrawable (&drawable, req->drawable, a_cl->client, 0, DixReadAccess); EPHYR_RETURN_VAL_IF_FAIL (drawable, BadValue) ; EPHYR_RETURN_VAL_IF_FAIL (drawable->pScreen, BadValue) ; EPHYR_LOG ("screen nummber requested:%d\n", drawable->pScreen->myNum) ; memset (&reply, 0, sizeof (reply)) ; if (!ephyrHostGLXMakeCurrent (hostx_get_window (drawable->pScreen->myNum), req->context, req->oldContextTag, (int*)&reply.contextTag)) { EPHYR_LOG_ERROR ("ephyrHostGLXMakeCurrent() failed\n") ; goto out; } reply.length = 0; reply.type = X_Reply; reply.sequenceNumber = a_cl->client->sequence; if (a_do_swap) { __GLX_DECLARE_SWAP_VARIABLES; __GLX_SWAP_SHORT(&reply.sequenceNumber); __GLX_SWAP_INT(&reply.length); __GLX_SWAP_INT(&reply.contextTag); } WriteToClient(a_cl->client, sz_xGLXMakeCurrentReply, (char *)&reply); res = Success ; out: EPHYR_LOG ("leave\n") ; return res ; }
static int ephyrReputImage(KdScreenInfo * a_info, DrawablePtr a_drawable, short a_drw_x, short a_drw_y, RegionPtr a_clipping_region, pointer a_port_priv) { EphyrPortPriv *port_priv = a_port_priv; int result = BadImplementation; EPHYR_RETURN_VAL_IF_FAIL(a_info->pScreen, FALSE); EPHYR_RETURN_VAL_IF_FAIL(a_drawable && port_priv, BadValue); EPHYR_LOG("enter\n"); if (!port_priv->image_buf_size || !port_priv->image_buf) { EPHYR_LOG_ERROR("has null image buf in cache\n"); goto out; } if (!ephyrHostXVPutImage(a_info->pScreen->myNum, port_priv->port_number, port_priv->image_id, a_drw_x, a_drw_y, port_priv->drw_w, port_priv->drw_h, port_priv->src_x, port_priv->src_y, port_priv->src_w, port_priv->src_h, port_priv->image_width, port_priv->image_height, port_priv->image_buf, (EphyrHostBox *) RegionRects(a_clipping_region), RegionNumRects(a_clipping_region))) { EPHYR_LOG_ERROR("ephyrHostXVPutImage() failed\n"); goto out; } result = Success; out: EPHYR_LOG("leave\n"); return result; }
/* * Xephyr - A kdrive X server thats runs in a host X window. * Authored by Matthew Allum <*****@*****.**> * * Copyright © 2007 OpenedHand Ltd * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of OpenedHand Ltd not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. OpenedHand Ltd makes no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. * * Authors: * Dodji Seketeli <*****@*****.**> */ #ifdef HAVE_CONFIG_H #include <kdrive-config.h> #endif #include <X11/Xutil.h> #include <X11/Xlibint.h> #include <GL/glx.h> #include "xf86dri.h" #include "hostx.h" #include "ephyrdri.h" #define _HAVE_XALLOC_DECLS #include "ephyrlog.h" #include "dixstruct.h" #include "pixmapstr.h" #ifndef TRUE #define TRUE 1 #endif /*TRUE*/ #ifndef FALSE #define FALSE 0 #endif /*FALSE*/ Bool ephyrDRIQueryDirectRenderingCapable(int a_screen, Bool *a_is_capable) { Display *dpy = hostx_get_display(); Bool is_ok = FALSE; EPHYR_RETURN_VAL_IF_FAIL(a_is_capable, FALSE); EPHYR_LOG("enter\n"); is_ok = XF86DRIQueryDirectRenderingCapable(dpy, DefaultScreen(dpy), a_is_capable); EPHYR_LOG("leave. is_capable:%d, is_ok=%d\n", *a_is_capable, is_ok); return is_ok; }
static int ephyrGLXGetStringReal (__GLXclientState *a_cl, GLbyte *a_pc, Bool a_do_swap) { ClientPtr client=NULL ; int context_tag=0, name=0, res=BadImplementation, length=0 ; char *string=NULL; __GLX_DECLARE_SWAP_VARIABLES; EPHYR_RETURN_VAL_IF_FAIL (a_cl && a_pc, BadValue) ; EPHYR_LOG ("enter\n") ; client = a_cl->client ; if (a_do_swap) { __GLX_SWAP_INT (a_pc + 4); __GLX_SWAP_INT (a_pc + __GLX_SINGLE_HDR_SIZE); } context_tag = __GLX_GET_SINGLE_CONTEXT_TAG (a_pc) ; a_pc += __GLX_SINGLE_HDR_SIZE; name = *(GLenum*)(a_pc + 0); EPHYR_LOG ("context_tag:%d, name:%d\n", context_tag, name) ; if (!ephyrHostGLXGetStringFromServer (context_tag, name, EPHYR_HOST_GLX_GetString, &string)) { EPHYR_LOG_ERROR ("failed to get string from server\n") ; goto out ; } if (string) { length = strlen (string) + 1; EPHYR_LOG ("got string:'%s', size:%d\n", string, length) ; } else { EPHYR_LOG ("got string: string (null)\n") ; } __GLX_BEGIN_REPLY (length); __GLX_PUT_SIZE (length); __GLX_SEND_HEADER (); if (a_do_swap) { __GLX_SWAP_REPLY_SIZE (); __GLX_SWAP_REPLY_HEADER (); } WriteToClient (client, length, (char *)string); res = Success ; out: EPHYR_LOG ("leave\n") ; return res ; }
static int ephyrGLXCreateContextReal(xGLXCreateContextReq * a_req, Bool a_do_swap) { int res = BadImplementation; EphyrHostWindowAttributes host_w_attrs; __GLX_DECLARE_SWAP_VARIABLES; EPHYR_RETURN_VAL_IF_FAIL(a_req, BadValue); EPHYR_LOG("enter\n"); if (a_do_swap) { __GLX_SWAP_SHORT(&a_req->length); __GLX_SWAP_INT(&a_req->context); __GLX_SWAP_INT(&a_req->visual); __GLX_SWAP_INT(&a_req->screen); __GLX_SWAP_INT(&a_req->shareList); } EPHYR_LOG("context creation requested. localid:%d, " "screen:%d, visual:%d, direct:%d\n", (int) a_req->context, (int) a_req->screen, (int) a_req->visual, (int) a_req->isDirect); memset(&host_w_attrs, 0, sizeof(host_w_attrs)); if (!hostx_get_window_attributes(hostx_get_window(a_req->screen), &host_w_attrs)) { EPHYR_LOG_ERROR("failed to get host window attrs\n"); goto out; } EPHYR_LOG("host window visual id: %d\n", host_w_attrs.visualid); if (!ephyrHostGLXCreateContext(a_req->screen, host_w_attrs.visualid, a_req->context, a_req->shareList, 0, a_req->isDirect, X_GLXCreateContext)) { EPHYR_LOG_ERROR("ephyrHostGLXCreateContext() failed\n"); goto out; } res = Success; out: EPHYR_LOG("leave\n"); return res; }
Bool ephyrHostGLXQueryVersion(int *a_major, int *a_minor) { Bool is_ok = FALSE; Display *dpy = hostx_get_display(); int major_opcode = 0; xGLXQueryVersionReq *req = NULL; xGLXQueryVersionReply reply; EPHYR_RETURN_VAL_IF_FAIL(a_major && a_minor, FALSE); EPHYR_LOG("enter\n"); if (glx_major) { *a_major = glx_major; *a_minor = glx_minor; return TRUE; } if (!ephyrHostGLXGetMajorOpcode(&major_opcode)) { EPHYR_LOG_ERROR("failed to get major opcode\n"); goto out; } EPHYR_LOG("major opcode: %d\n", major_opcode); /* Send the glXQueryVersion request */ memset(&reply, 0, sizeof(reply)); LockDisplay(dpy); GetReq(GLXQueryVersion, req); req->reqType = major_opcode; req->glxCode = X_GLXQueryVersion; req->majorVersion = 2; req->minorVersion = 1; _XReply(dpy, (xReply *) &reply, 0, False); UnlockDisplay(dpy); SyncHandle(); *a_major = glx_major = reply.majorVersion; *a_minor = glx_minor = reply.minorVersion; EPHYR_LOG("major:%d, minor:%d\n", *a_major, *a_minor); is_ok = TRUE; out: EPHYR_LOG("leave\n"); return is_ok; }
static Bool ephyrXVPrivRegisterAdaptors(EphyrXVPriv * a_this, ScreenPtr a_screen) { KdScreenPriv(a_screen); KdScreenInfo *screen = pScreenPriv->screen; Bool is_ok = FALSE; KdVideoAdaptorPtr *adaptors = NULL, *registered_adaptors = NULL; int num_registered_adaptors = 0, i = 0, num_adaptors = 0; EPHYR_RETURN_VAL_IF_FAIL(a_this && a_screen, FALSE); EPHYR_LOG("enter\n"); if (!a_this->num_adaptors) goto out; num_registered_adaptors = KdXVListGenericAdaptors(screen, ®istered_adaptors); num_adaptors = num_registered_adaptors + a_this->num_adaptors; adaptors = calloc(num_adaptors, sizeof(KdVideoAdaptorPtr)); if (!adaptors) { EPHYR_LOG_ERROR("failed to allocate adaptors tab\n"); goto out; } memmove(adaptors, registered_adaptors, num_registered_adaptors); for (i = 0; i < a_this->num_adaptors; i++) { *(adaptors + num_registered_adaptors + i) = &a_this->adaptors[i]; } if (!KdXVScreenInit(a_screen, adaptors, num_adaptors)) { EPHYR_LOG_ERROR("failed to register adaptors\n"); goto out; } EPHYR_LOG("there are %d registered adaptors\n", num_adaptors); is_ok = TRUE; out: free(registered_adaptors); registered_adaptors = NULL; free(adaptors); adaptors = NULL; EPHYR_LOG("leave\n"); return is_ok; }
static KdVideoEncodingPtr videoEncodingDup(EphyrHostEncoding * a_encodings, int a_num_encodings) { KdVideoEncodingPtr result = NULL; int i = 0; EPHYR_RETURN_VAL_IF_FAIL(a_encodings && a_num_encodings, NULL); result = calloc(a_num_encodings, sizeof(KdVideoEncodingRec)); for (i = 0; i < a_num_encodings; i++) { result[i].id = a_encodings[i].id; result[i].name = strdup(a_encodings[i].name); result[i].width = a_encodings[i].width; result[i].height = a_encodings[i].height; result[i].rate.numerator = a_encodings[i].rate.numerator; result[i].rate.denominator = a_encodings[i].rate.denominator; } return result; }
Bool ephyrDRIGetDeviceInfo(int a_screen, drm_handle_t * a_frame_buffer, int *a_fb_origin, int *a_fb_size, int *a_fb_stride, int *a_dev_private_size, void **a_dev_private) { Bool is_ok = FALSE; Display *dpy = hostx_get_display(); EPHYR_RETURN_VAL_IF_FAIL(dpy, FALSE); EPHYR_LOG("enter\n"); is_ok = XF86DRIGetDeviceInfo(dpy, DefaultScreen(dpy), a_frame_buffer, a_fb_origin, a_fb_size, a_fb_stride, a_dev_private_size, a_dev_private); EPHYR_LOG("leave:%d\n", is_ok); return is_ok; }
static Bool DoSimpleClip(BoxPtr a_dst_box, BoxPtr a_clipper, BoxPtr a_result) { BoxRec dstClippedBox; EPHYR_RETURN_VAL_IF_FAIL(a_dst_box && a_clipper && a_result, FALSE); /* * setup the clipbox inside the destination. */ dstClippedBox.x1 = a_dst_box->x1; dstClippedBox.x2 = a_dst_box->x2; dstClippedBox.y1 = a_dst_box->y1; dstClippedBox.y2 = a_dst_box->y2; /* * if the cliper leftmost edge is inside * the destination area then the leftmost edge of the resulting * clipped box is the leftmost edge of the cliper. */ if (a_clipper->x1 > dstClippedBox.x1) dstClippedBox.x1 = a_clipper->x1; /* * if the cliper top edge is inside the destination area * then the bottom horizontal edge of the resulting clipped box * is the bottom edge of the cliper */ if (a_clipper->y1 > dstClippedBox.y1) dstClippedBox.y1 = a_clipper->y1; /*ditto for right edge */ if (a_clipper->x2 < dstClippedBox.x2) dstClippedBox.x2 = a_clipper->x2; /*ditto for bottom edge */ if (a_clipper->y2 < dstClippedBox.y2) dstClippedBox.y2 = a_clipper->y2; memcpy(a_result, &dstClippedBox, sizeof(dstClippedBox)); return TRUE; }
Bool ephyrDRIOpenConnection(int a_screen, drm_handle_t * a_sarea, char **a_bus_id_string) { Display *dpy = hostx_get_display(); Bool is_ok = FALSE; EPHYR_RETURN_VAL_IF_FAIL(a_bus_id_string, FALSE); EPHYR_LOG("enter. screen:%d\n", a_screen); is_ok = XF86DRIOpenConnection(dpy, DefaultScreen(dpy), a_sarea, a_bus_id_string); if (*a_bus_id_string) { EPHYR_LOG("leave. bus_id_string:%s, is_ok:%d\n", *a_bus_id_string, is_ok); } else { EPHYR_LOG("leave. bus_id_string:null, is_ok:%d\n", is_ok); } return is_ok; }
Bool ephyrHostGetIntegerValue(int a_current_context_tag, int a_int, int *a_val) { Bool is_ok = FALSE; Display *dpy = hostx_get_display(); int major_opcode = 0, size = 0; xGLXSingleReq *req = NULL; xGLXSingleReply reply; unsigned char *pc = NULL; EPHYR_RETURN_VAL_IF_FAIL(a_val, FALSE); EPHYR_LOG("enter\n"); if (!ephyrHostGLXGetMajorOpcode(&major_opcode)) { EPHYR_LOG_ERROR("failed to get major opcode\n"); goto out; } LockDisplay(dpy); GetReqExtra(GLXSingle, 4, req); req->reqType = major_opcode; req->glxCode = X_GLsop_GetIntegerv; req->contextTag = a_current_context_tag; pc = ((unsigned char *) (req) + sz_xGLXSingleReq); EPHYR_GLX_SINGLE_PUT_LONG(0, a_int); EPHYR_GLX_SINGLE_READ_XREPLY(); EPHYR_GLX_SINGLE_GET_SIZE(size); if (!size) { UnlockDisplay(dpy); SyncHandle(); EPHYR_LOG_ERROR("X_GLsop_GetIngerv failed\n"); goto out; } EPHYR_GLX_SINGLE_GET_LONG(a_val); UnlockDisplay(dpy); SyncHandle(); is_ok = TRUE; out: EPHYR_LOG("leave\n"); return is_ok; }
static KdAttributePtr portAttributesDup(EphyrHostAttribute * a_encodings, int a_num_encodings) { int i = 0; KdAttributePtr result = NULL; EPHYR_RETURN_VAL_IF_FAIL(a_encodings && a_num_encodings, NULL); result = calloc(a_num_encodings, sizeof(KdAttributeRec)); if (!result) { EPHYR_LOG_ERROR("failed to allocate attributes\n"); return NULL; } for (i = 0; i < a_num_encodings; i++) { result[i].flags = a_encodings[i].flags; result[i].min_value = a_encodings[i].min_value; result[i].max_value = a_encodings[i].max_value; result[i].name = strdup(a_encodings[i].name); } return result; }
Bool ephyrHostGLXSendClientInfo(int32_t a_major, int32_t a_minor, const char *a_extension_list) { Bool is_ok = FALSE; Display *dpy = hostx_get_display(); xGLXClientInfoReq *req; int size; int32_t major_opcode = 0; EPHYR_RETURN_VAL_IF_FAIL(dpy && a_extension_list, FALSE); if (!ephyrHostGLXGetMajorOpcode(&major_opcode)) { EPHYR_LOG_ERROR("failed to get major opcode\n"); goto out; } LockDisplay(dpy); GetReq(GLXClientInfo, req); req->reqType = major_opcode; req->glxCode = X_GLXClientInfo; req->major = a_major; req->minor = a_minor; size = strlen(a_extension_list) + 1; req->length += bytes_to_int32(size); req->numbytes = size; Data(dpy, a_extension_list, size); UnlockDisplay(dpy); SyncHandle(); is_ok = TRUE; out: return is_ok; }
static int ephyrGLXCreateNewContextReal(xGLXCreateNewContextReq * a_req, Bool a_do_swap) { int res = BadImplementation; __GLX_DECLARE_SWAP_VARIABLES; EPHYR_RETURN_VAL_IF_FAIL(a_req, BadValue); EPHYR_LOG("enter\n"); if (a_do_swap) { __GLX_SWAP_SHORT(&a_req->length); __GLX_SWAP_INT(&a_req->context); __GLX_SWAP_INT(&a_req->fbconfig); __GLX_SWAP_INT(&a_req->screen); __GLX_SWAP_INT(&a_req->renderType); __GLX_SWAP_INT(&a_req->shareList); } EPHYR_LOG("context creation requested. localid:%d, " "screen:%d, fbconfig:%d, renderType:%d, direct:%d\n", (int) a_req->context, (int) a_req->screen, (int) a_req->fbconfig, (int) a_req->renderType, (int) a_req->isDirect); if (!ephyrHostGLXCreateContext(a_req->screen, a_req->fbconfig, a_req->context, a_req->shareList, a_req->renderType, a_req->isDirect, X_GLXCreateNewContext)) { EPHYR_LOG_ERROR("ephyrHostGLXCreateNewContext() failed\n"); goto out; } res = Success; out: EPHYR_LOG("leave\n"); return res; }
Bool ephyrHostGLXGetMajorOpcode(int *a_opcode) { Bool is_ok = FALSE; Display *dpy = hostx_get_display(); static int opcode; int first_event_return = 0, first_error_return = 0; EPHYR_RETURN_VAL_IF_FAIL(dpy, FALSE); EPHYR_LOG("enter\n"); if (!opcode) { if (!XQueryExtension(dpy, GLX_EXTENSION_NAME, &opcode, &first_event_return, &first_error_return)) { EPHYR_LOG_ERROR("XQueryExtension() failed\n"); goto out; } } *a_opcode = opcode; is_ok = TRUE; out: EPHYR_LOG("release\n"); return is_ok; }
static Bool ephyrLocalAtomToHost(int a_local_atom, int *a_host_atom) { const char *atom_name = NULL; int host_atom = None; EPHYR_RETURN_VAL_IF_FAIL(a_host_atom, FALSE); if (!ValidAtom(a_local_atom)) return FALSE; atom_name = NameForAtom(a_local_atom); if (!atom_name) return FALSE; if (!ephyrHostGetAtom(atom_name, FALSE, &host_atom) || host_atom == None) { EPHYR_LOG_ERROR("no atom for string %s defined in host X\n", atom_name); return FALSE; } *a_host_atom = host_atom; return TRUE; }
static Bool ephyrXVPrivGetImageBufSize(int a_port_id, int a_image_id, unsigned short a_width, unsigned short a_height, int *a_size) { Bool is_ok = FALSE; unsigned short width = a_width, height = a_height; EPHYR_RETURN_VAL_IF_FAIL(a_size, FALSE); EPHYR_LOG("enter\n"); if (!ephyrHostXVQueryImageAttributes(a_port_id, a_image_id, &width, &height, a_size, NULL, NULL)) { EPHYR_LOG_ERROR("failed to get image attributes\n"); goto out; } is_ok = TRUE; out: EPHYR_LOG("leave\n"); return is_ok; }
Bool ephyrHostGLXMakeCurrent(int a_drawable, int a_readable, int a_glx_ctxt_id, int a_old_ctxt_tag, int *a_ctxt_tag) { Bool is_ok = FALSE; Display *dpy = hostx_get_display(); int32_t major_opcode = 0; int remote_glx_ctxt_id = 0; xGLXMakeCurrentReply reply; EPHYR_RETURN_VAL_IF_FAIL(a_ctxt_tag, FALSE); EPHYR_LOG("enter. drawable:%d, read:%d, context:%d, oldtag:%d\n", a_drawable, a_readable, a_glx_ctxt_id, a_old_ctxt_tag); if (!ephyrHostGLXGetMajorOpcode(&major_opcode)) { EPHYR_LOG_ERROR("failed to get major opcode\n"); goto out; } if (!hostx_get_resource_id_peer(a_glx_ctxt_id, &remote_glx_ctxt_id)) { EPHYR_LOG_ERROR("failed to get remote glx ctxt id\n"); goto out; } LockDisplay(dpy); /* If both drawables are the same, use the old MakeCurrent request. * Otherwise, if we have GLX 1.3 or higher, use the MakeContextCurrent * request which supports separate read and draw targets. Failing that, * try the SGI MakeCurrentRead extension. Logic cribbed from Mesa. */ if (a_drawable == a_readable) { xGLXMakeCurrentReq *req; GetReq(GLXMakeCurrent, req); req->reqType = major_opcode; req->glxCode = X_GLXMakeCurrent; req->drawable = a_drawable; req->context = remote_glx_ctxt_id; req->oldContextTag = a_old_ctxt_tag; } else if (glx_major > 1 || glx_minor >= 3) { xGLXMakeContextCurrentReq *req; GetReq(GLXMakeContextCurrent, req); req->reqType = major_opcode; req->glxCode = X_GLXMakeContextCurrent; req->drawable = a_drawable; req->readdrawable = a_readable; req->context = remote_glx_ctxt_id; req->oldContextTag = a_old_ctxt_tag; } else { xGLXVendorPrivateWithReplyReq *vpreq; xGLXMakeCurrentReadSGIReq *req; GetReqExtra(GLXVendorPrivateWithReply, (sz_xGLXMakeCurrentReadSGIReq - sz_xGLXVendorPrivateWithReplyReq), vpreq); req = (xGLXMakeCurrentReadSGIReq *) vpreq; req->reqType = major_opcode; req->glxCode = X_GLXVendorPrivateWithReply; req->vendorCode = X_GLXvop_MakeCurrentReadSGI; req->drawable = a_drawable; req->readable = a_readable; req->context = remote_glx_ctxt_id; req->oldContextTag = a_old_ctxt_tag; } memset(&reply, 0, sizeof(reply)); if (!_XReply(dpy, (xReply *) &reply, 0, False)) { EPHYR_LOG_ERROR("failed to get reply from host\n"); UnlockDisplay(dpy); SyncHandle(); goto out; } UnlockDisplay(dpy); SyncHandle(); *a_ctxt_tag = reply.contextTag; EPHYR_LOG("context tag:%d\n", *a_ctxt_tag); is_ok = TRUE; out: EPHYR_LOG("leave\n"); return is_ok; }
static Bool ephyrHostGLXGetVisualConfigsInternal(enum VisualConfRequestType a_type, int32_t a_screen, int32_t * a_num_visuals, int32_t * a_num_props, int32_t * a_props_buf_size, int32_t ** a_props_buf) { Bool is_ok = FALSE; Display *dpy = hostx_get_display(); xGLXGetVisualConfigsReq *req; xGLXGetFBConfigsReq *fb_req; xGLXVendorPrivateWithReplyReq *vpreq; xGLXGetFBConfigsSGIXReq *sgi_req; xGLXGetVisualConfigsReply reply; char *server_glx_version = NULL, *server_glx_extensions = NULL; int j = 0, screens = 0, major_opcode = 0, num_props = 0, num_visuals = 0, props_buf_size = 0, props_per_visual_size = 0; int32_t *props_buf = NULL; EPHYR_RETURN_VAL_IF_FAIL(dpy, FALSE); screens = ScreenCount(dpy); if (!ephyrHostGLXGetMajorOpcode(&major_opcode)) { EPHYR_LOG_ERROR("failed to get opcode\n"); goto out; } LockDisplay(dpy); switch (a_type) { case EPHYR_GET_FB_CONFIG: GetReq(GLXGetFBConfigs, fb_req); fb_req->reqType = major_opcode; fb_req->glxCode = X_GLXGetFBConfigs; fb_req->screen = DefaultScreen(dpy); break; case EPHYR_VENDOR_PRIV_GET_FB_CONFIG_SGIX: GetReqExtra(GLXVendorPrivateWithReply, sz_xGLXGetFBConfigsSGIXReq - sz_xGLXVendorPrivateWithReplyReq, vpreq); sgi_req = (xGLXGetFBConfigsSGIXReq *) vpreq; sgi_req->reqType = major_opcode; sgi_req->glxCode = X_GLXVendorPrivateWithReply; sgi_req->vendorCode = X_GLXvop_GetFBConfigsSGIX; sgi_req->screen = DefaultScreen(dpy); break; case EPHYR_GET_VISUAL_CONFIGS: GetReq(GLXGetVisualConfigs, req); req->reqType = major_opcode; req->glxCode = X_GLXGetVisualConfigs; req->screen = DefaultScreen(dpy); break; } if (!_XReply(dpy, (xReply *) &reply, 0, False)) { EPHYR_LOG_ERROR("unknown error\n"); UnlockDisplay(dpy); goto out; } if (!reply.numVisuals) { EPHYR_LOG_ERROR("screen does not support GL rendering\n"); UnlockDisplay(dpy); goto out; } num_visuals = reply.numVisuals; /* FIXME: Is the __GLX_MIN_CONFIG_PROPS test correct for * FIXME: FBconfigs? */ /* Check number of properties */ num_props = reply.numProps; if ((num_props < __GLX_MIN_CONFIG_PROPS) || (num_props > __GLX_MAX_CONFIG_PROPS)) { /* Huh? Not in protocol defined limits. Punt */ EPHYR_LOG_ERROR("got a bad reply to request\n"); UnlockDisplay(dpy); goto out; } if (a_type != EPHYR_GET_VISUAL_CONFIGS) { num_props *= 2; } props_per_visual_size = num_props * __GLX_SIZE_INT32; props_buf_size = props_per_visual_size * reply.numVisuals; props_buf = malloc(props_buf_size); for (j = 0; j < reply.numVisuals; j++) { if (_XRead(dpy, &((char *) props_buf)[j * props_per_visual_size], props_per_visual_size) != Success) { EPHYR_LOG_ERROR("read failed\n"); } } UnlockDisplay(dpy); *a_num_visuals = num_visuals; *a_num_props = reply.numProps; *a_props_buf_size = props_buf_size; *a_props_buf = props_buf; is_ok = TRUE; out: if (server_glx_version) { XFree(server_glx_version); server_glx_version = NULL; } if (server_glx_extensions) { XFree(server_glx_extensions); server_glx_extensions = NULL; } SyncHandle(); return is_ok; }
Bool ephyrHostGLXGetStringFromServer(int a_screen_number, int a_string_name, enum EphyrHostGLXGetStringOps a_op, char **a_string) { Bool is_ok = FALSE; Display *dpy = hostx_get_display(); int default_screen = DefaultScreen(dpy); xGLXGenericGetStringReq *req = NULL; xGLXSingleReply reply; unsigned long length = 0, numbytes = 0; int major_opcode = 0, get_string_op = 0; EPHYR_RETURN_VAL_IF_FAIL(dpy && a_string, FALSE); EPHYR_LOG("enter\n"); switch (a_op) { case EPHYR_HOST_GLX_QueryServerString: get_string_op = X_GLXQueryServerString; break; case EPHYR_HOST_GLX_GetString: get_string_op = X_GLsop_GetString; EPHYR_LOG("Going to glXGetString. strname:%#x, ctxttag:%d\n", a_string_name, a_screen_number); break; default: EPHYR_LOG_ERROR("unknown EphyrHostGLXGetStringOp:%d\n", a_op); goto out; } if (!ephyrHostGLXGetMajorOpcode(&major_opcode)) { EPHYR_LOG_ERROR("failed to get major opcode\n"); goto out; } EPHYR_LOG("major opcode: %d\n", major_opcode); LockDisplay(dpy); /* All of the GLX protocol requests for getting a string from the server * look the same. The exact meaning of the a_for_whom field is usually * either the screen number (for glXQueryServerString) or the context tag * (for GLXSingle). */ GetReq(GLXGenericGetString, req); req->reqType = major_opcode; req->glxCode = get_string_op; req->for_whom = default_screen; req->name = a_string_name; _XReply(dpy, (xReply *) &reply, 0, False); #if UINT32_MAX >= (ULONG_MAX / 4) if (reply.length >= (ULONG_MAX / 4)) { _XEatDataWords(dpy, reply.length); goto eat_out; } #endif if (reply.length > 0) { length = (unsigned long) reply.length * 4; numbytes = reply.size; if (numbytes > length) { EPHYR_LOG_ERROR("string length %d longer than reply length %d\n", numbytes, length); goto eat_out; } } EPHYR_LOG("going to get a string of size:%d\n", numbytes); if (numbytes < INT_MAX) *a_string = Xcalloc(numbytes + 1, 1); else *a_string = NULL; if (*a_string == NULL) { EPHYR_LOG_ERROR("allocation failed\n"); goto eat_out; } if (_XRead(dpy, *a_string, numbytes)) { EPHYR_LOG_ERROR("read failed\n"); length = 0; /* if read failed, no idea how much to eat */ } else { length -= numbytes; EPHYR_LOG("strname:%#x, strvalue:'%s', strlen:%d\n", a_string_name, *a_string, numbytes); is_ok = TRUE; } eat_out: _XEatData(dpy, length); UnlockDisplay(dpy); SyncHandle(); out: EPHYR_LOG("leave\n"); return is_ok; }