From 1cc54e8adc05db40f17c1d57b910c9176d05061c Mon Sep 17 00:00:00 2001 From: Boram Park Date: Tue, 21 Aug 2012 18:04:15 +0900 Subject: [PATCH] upload tizen2.0 source --- CMakeLists.txt | 3 +- COPYING | 2 +- TC/testcase/utc_utilx_test.c | 2 +- debian/changelog | 16 ++ debian/control | 6 +- debian/copyright | 2 +- packaging/libslp-utilx.spec | 12 +- utilX.h | 228 ++++++++++++++++++- util_x11.h | 2 +- x11.c | 505 ++++++++++++++++++++++++++++++++++++++++++- 10 files changed, 766 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4574814..871a991 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,7 +14,8 @@ SET(VERSION "${VERSION_MAJOR}.1.0") INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}) INCLUDE(FindPkgConfig) -pkg_check_modules(pkgs REQUIRED x11) +pkg_check_modules(pkgs REQUIRED x11 xext xv xdamage libdrm libdrm_slp libdri2) + FOREACH(flag ${pkgs_CFLAGS}) SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") ENDFOREACH(flag) diff --git a/COPYING b/COPYING index 4a8b190..b0349bb 100644 --- a/COPYING +++ b/COPYING @@ -1,4 +1,4 @@ -Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved +Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/TC/testcase/utc_utilx_test.c b/TC/testcase/utc_utilx_test.c index c52b09d..7934c62 100644 --- a/TC/testcase/utc_utilx_test.c +++ b/TC/testcase/utc_utilx_test.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved * * Licensed under the Apache License, Version 2.0 (the License); * you may not use this file except in compliance with the License. diff --git a/debian/changelog b/debian/changelog index 60370e3..4e9af6c 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,19 @@ +libslp-utilx (0.1.7-5) unstable; urgency=low + + * Check the status and the dispmode of screen conf when setting the dispmode + * Git: slp/pkgs/l/libslp-utilx + * Tag: libslp-utilx_0.1.7-5 + + -- SooChan Lim Wed, 16 May 2012 11:21:10 +0900 + +libslp-utilx (0.1.7-4) unstable; urgency=low + + * Add screen configuration apis + * Git: slp/pkgs/l/libslp-utilx + * Tag: libslp-utilx_0.1.7-4 + + -- SooChan Lim Mon, 14 May 2012 13:44:33 +0900 + libslp-utilx (0.1.7-3) unstable; urgency=low * Change code to use internal atom for indicator according to EFL 1.0 upgrade diff --git a/debian/control b/debian/control index 679cd19..5659dc4 100644 --- a/debian/control +++ b/debian/control @@ -1,14 +1,14 @@ Source: libslp-utilx Section: libs Priority: extra -Maintainer: Doyoun Kang , Sung-Jin Park , Gwangyeong Mun -Build-Depends: debhelper (>= 5), autotools-dev, libx11-dev +Maintainer: Doyoun Kang , Sung-Jin Park , Gwangyeong Mun , SooChan Lim +Build-Depends: debhelper (>= 5), autotools-dev, libx11-dev Standards-Version: 3.7.2 Package: libslp-utilx-dev Section: libs Architecture: any -Depends: libslp-utilx-0 (= ${Source-Version}), libx11-dev +Depends: libslp-utilx-0 (= ${Source-Version}), libx11-dev Description: Utilities of Xwindow (development files) Utility functions for the XWindow diff --git a/debian/copyright b/debian/copyright index c3dc47f..7b1b86b 100755 --- a/debian/copyright +++ b/debian/copyright @@ -1,4 +1,4 @@ -Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. +Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License version 2.1. diff --git a/packaging/libslp-utilx.spec b/packaging/libslp-utilx.spec index 3945544..07cfe0a 100644 --- a/packaging/libslp-utilx.spec +++ b/packaging/libslp-utilx.spec @@ -1,6 +1,7 @@ -Name: libslp-utilx +#sbs-git:slp/pkgs/l/libslp-utilx libslp-utilx 0.1.7 5957503c84e65113399e346c7d5618e73957d6ff +Name: libslp-utilx Summary: utilX -Version: 0.1.7 +Version: 0.1.7 Release: 1.1 Group: System/Libraries License: Apache-2.0 @@ -9,7 +10,14 @@ Requires(post): /sbin/ldconfig Requires(postun): /sbin/ldconfig BuildRequires: cmake +BuildRequires: pkgconfig(libdri2) +BuildRequires: pkgconfig(dri2proto) BuildRequires: pkgconfig(x11) +BuildRequires: pkgconfig(xext) +BuildRequires: pkgconfig(xv) +BuildRequires: pkgconfig(xdamage) +BuildRequires: pkgconfig(libdrm) +BuildRequires: pkgconfig(libdrm_slp) %description Utility functions for the XWindow diff --git a/utilX.h b/utilX.h index faa26e6..473dfe2 100644 --- a/utilX.h +++ b/utilX.h @@ -1,7 +1,7 @@ /* * libslp-utilx * - Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -120,6 +120,29 @@ extern "C" { #define STR_ATOM_GRAB_EXCL_WIN "_GRAB_EXCL_WIN_KEYCODE" /**< this means that the key was grabbed by a client window in EXCLUSIVE mod */ #define STR_ATOM_GRAB_OR_EXCL_WIN "_GRAB_OR_EXCL_WIN_KEYCODE" /**< this means that the key was grabbed by a client window in OR_EXCLUSIVE mod */ +#define STR_ATOM_SCRNCONF_STATUS "_SCRNCONF_STATUS" /**< this is an XATOM for getting the status of the screen configuration through the client message */ + +/** + * @brief Enumeration of screen configuration status + */ +typedef enum _Utilx_Scrnconf_Status +{ + UTILX_SCRNCONF_STATUS_NULL, /**< screen configuration status is null */ + UTILX_SCRNCONF_STATUS_CONNECT, /**< screen configuration status is connect */ + UTILX_SCRNCONF_STATUS_ACTIVE /**< screen configuration status is active */ +} Utilx_Scrnconf_Status; + +/** + * @brief Enumeration of screen configuration display mode + */ +typedef enum _Utilx_Scrnconf_Dispmode +{ + UTILX_SCRNCONF_DISPMODE_NULL, /**< display mode of screen configuration is null */ + UTILX_SCRNCONF_DISPMODE_CLONE, /**< display mode of screen configuration is clone */ + UTILX_SCRNCONF_DISPMODE_EXTENDED /**< display mode of screen configuration is extended */ +} Utilx_Scrnconf_Dispmode; + + /** * @brief Enumeration of key status */ @@ -181,6 +204,145 @@ typedef enum _Utilx_Opaque_State UTILX_OPAQUE_STATE_ON = 1, /**< Opaque state */ } Utilx_Opaque_State; +/** + * @brief Structure of screen configuration information + */ +typedef struct _UtilxScrnConf +{ + char *str_output; /**< string value for the connector type */ + Utilx_Scrnconf_Status status; /**< status of screen configurtaion */ + char *str_resolution; /**< string value for the resolution to be active status */ + Utilx_Scrnconf_Dispmode dispmode; /**< display mode of screen configuration to be active status */ +} UtilxScrnConf; + +/** + * @fn ScrnConf *utilx_scrnconf_allocate(void) + * @brief allocate the UtilxScrnConf structure + * + * This function allocate the UtilxScrnConf structure.\n + * + * @remark This is used only application which want to know the screen configuration info. + * @pre This api does not require any pre-condition. + * @post This api does not change any condition. + * @see utilx_scrnconf_allocate + * @par Example + @code + #include + ... + + UtilxScrnConf *scrnconf = NULL; + + // Allocate the UtilxScrnConf structure + scrnconf = utilx_scrnconf_allocate(); + ... + @endcode + */ +UtilxScrnConf *utilx_scrnconf_allocate (void); + +/** + * @fn void utilx_scrnconf_free (UtilxScrnConf *scrnconf) + * @brief free the UtilxScrnConf structure + * + * This function free the UtilxScrnConf structure.\n + * + * @param[in] scrnconf Specifies the UtilxScrnConf structure + * @return instance of the UtilxScrnConf structure + * @remark This is used only application which want to know the screen configuration info. + * @pre This api does not require any pre-condition. + * @post This api does not change any condition. + * @see utilx_scrnconf_free + * @par Example + @code + #include + ... + + UtilxScrnConf *scrnconf = NULL; + + // Allocate the UtilxScrnConf structure + scrnconf = utilx_scrnconf_allocate(); + ... + + // Free the UtilxScrnConf structure + utilx_scrnconf_free(scrnconf); + ... + @endcode + */ +void utilx_scrnconf_free (UtilxScrnConf *scrnconf); + +/** + * @fn void utilx_scrnconf_get_info (Display *dpy, UtilxScrnConf *scrnconf) + * @brief get the information of the screen configuration + * + * This function get the information of the screen configuration.\n + * + * This function is a asynchronous call. + * + * @param[in] dpy Specifies the connection to the X server + * @param[in] scrnconf Specifies the information structure of the screen configuration + * @remark This is used only application which want to know the screen configuration info. + * @pre This api does not require any pre-condition. + * @post This api does not change any condition. + * @see utilx_scrnconf_get_info + * @par Example + @code + #include + #include + ... + + Display* dpy; + UtilxScrnConf *scrnconf = NULL; + + dpy = XOpenDisplay (NULL); + + // Allocate the UtilxScrnConf structure + scrnconf = utilx_scrnconf_allocate(); + ... + + // Set the display mode for the screen configuration + utilx_scrnconf_get_info (dpy, scrnconf); + ... + + // Free the UtilxScrnConf structure + utilx_scrnconf_free(scrnconf); + ... + + @endcode + */ +void utilx_scrnconf_get_info (Display *dpy, UtilxScrnConf *scrnconf); + + +/** + * @fn void utilx_scrnconf_set_dispmode (Display *dpy, Utilx_Scrnconf_Dispmode dispmode) + * @brief set the display mode for the screen configuration + * + * This function set the display mode for the screen configuration.\n + * + * This function is a asynchronous call. + * + * @param[in] dpy Specifies the connection to the X server + * @param[in] dipmode Specifies the display mode of the screen configuration + * @return 1 if setting the dispmode is succeeded, 0 if setting the dispmode is failed. + * @remark This is used only application which want to set the display mode of the screen configuration. + * @pre This api does not require any pre-condition. + * @post This api does not change any condition. + * @see utilx_scrnconf_set_dispmode + * @par Example + @code + #include + #include + ... + + Display* dpy; + + dpy = XOpenDisplay (NULL); + + // Set the display mode for the screen configuration + utilx_scrnconf_set_dispmode (dpy, UTILX_SCRNCONF_DISPMODE_CLONE); + ... + @endcode + */ +int utilx_scrnconf_set_dispmode (Display *dpy, Utilx_Scrnconf_Dispmode dispmode); + /** * @fn void utilx_set_system_notification_level (Display* dpy, Window win, Utilx_Notification_Level level) @@ -1325,6 +1487,70 @@ int utilx_get_window_cardinal_property(Display* dpy, Window win, Atom atom, unsi */ void utilx_show_capture_effect(Display *dpy, Window win ); +/** + * @fn void* utilx_create_screen_shot (Display* dpy, int width, int height) + * @brief Create a screenshot image. + * + * This function create a screenshot image.\n + * To use this function, you should get the permission first. After finishing, + * utilx_release_screen_shot should be called. + * + * @param[in] dpy Specifies the connection to the X server + * @param[in] width Specifies the root window handle + * @param[in] height Specifies the root window handle + * @remark You should get the permission to use. + * @post This api does not change any condition. + * @see utilx_release_screen_shot + * @par Example + @code + Display* dpy; + int width, height; + void *dump; + + dpy = XOpenDisplay (NULL); + width = DisplayWidth (dpy, DefaultScreen (dpy)); + height = DisplayHeight (dpy, DefaultScreen (dpy)); + + dump = utilx_create_screen_shot (dpy, width, height); + if (dump) + { + // do_something (dump); + } + + utilx_release_screen_shot (); + @endcode + */ +void* utilx_create_screen_shot (Display* dpy, int width, int height); + +/** + * @fn void utilx_release_screen_shot (void) + * @brief Release screenshot resources. + * + * This function release screenshot resources.\n + * utilx_release_screen_shot should be called after finsining screenshot. + * + * @see utilx_create_screen_shot + * @par Example + @code + Display* dpy; + int width, height; + void *dump; + + dpy = XOpenDisplay (NULL); + width = DisplayWidth (dpy, DefaultScreen (dpy)); + height = DisplayHeight (dpy, DefaultScreen (dpy)); + + dump = utilx_create_screen_shot (dpy, width, height); + if (dump) + { + // do_something (dump); + } + + utilx_release_screen_shot (); + @endcode + */ +void utilx_release_screen_shot (void); + #ifdef __cplusplus } #endif diff --git a/util_x11.h b/util_x11.h index 1e24bcb..a1a3c3f 100644 --- a/util_x11.h +++ b/util_x11.h @@ -1,7 +1,7 @@ /* * libslp-utilx * - Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/x11.c b/x11.c index 0831cb0..7367473 100644 --- a/x11.c +++ b/x11.c @@ -1,7 +1,7 @@ /* * libslp-utilx * - Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved + Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -23,11 +23,19 @@ #include #include +#include #include #include "utilX.h" #include "util_x11.h" +#include +#include +#include +#include +#include +#include + #define UTILX_DEBUG 0 #if UTILX_DEBUG @@ -1249,3 +1257,498 @@ API void utilx_show_capture_effect( Display *dpy, Window win) &xev ); XSync(dpy, 0 ); } + +API UtilxScrnConf *utilx_scrnconf_allocate (void) +{ + UtilxScrnConf *scrnconf = calloc (1, sizeof(UtilxScrnConf)); + if (!scrnconf) + { + fprintf (stderr, "fail to allocate UtilxScrnConf\n"); + return NULL; + } + + return scrnconf; +} + +API void utilx_scrnconf_free (UtilxScrnConf *scrnconf) +{ + if (!scrnconf) + return; + + if (scrnconf->str_output) + free (scrnconf->str_output); + + if (scrnconf->str_resolution) + free (scrnconf->str_resolution); + + free(scrnconf); + scrnconf = NULL; +} + +API void utilx_scrnconf_get_info (Display *dpy, UtilxScrnConf *scrnconf) +{ + Window win = DefaultRootWindow(dpy); + Atom scrnconf_atom = None; + XTextProperty xtp; + char *str = NULL; + char *ptr = NULL; + int items; + char **list = NULL; + int i = 0; + int s; + + scrnconf_atom = XInternAtom (dpy, "_SCRNCONF_INFO", False); + + /* get property */ + if (XGetTextProperty (dpy, win, &xtp, scrnconf_atom)) + { + s = XmbTextPropertyToTextList (dpy, &xtp, &list, &items); + if ((s == XLocaleNotSupported) || + (s == XNoMemory) || (s == XConverterNotFound)) + str = strdup((char *)xtp.value); + else if ((s >= Success) && (items > 0)) + str = strdup(list[0]); + + if (list) + XFreeStringList (list); + + XFree(xtp.value); + } + + ptr = strtok (str, ","); + while (ptr != NULL) + { + if (i == 0) + { + scrnconf->str_output = calloc (1, strlen(ptr)); + if (!scrnconf->str_output) + goto fail; + + strcpy (scrnconf->str_output, ptr); + } + else if (i == 1) + { + if (!strcmp(ptr, "CONNECT")) + scrnconf->status = UTILX_SCRNCONF_STATUS_CONNECT; + else if (!strcmp(ptr, "ACTIVE")) + scrnconf->status = UTILX_SCRNCONF_STATUS_ACTIVE; + else + scrnconf->status = UTILX_SCRNCONF_STATUS_NULL; + } + else if (i == 2) + { + scrnconf->str_resolution = calloc (1, strlen(ptr)); + if (!scrnconf->str_resolution) + goto fail; + + strcpy (scrnconf->str_resolution, ptr); + } + else if (i == 3) + { + if (!strcmp(ptr, "CLONE")) + scrnconf->dispmode = UTILX_SCRNCONF_DISPMODE_CLONE; + else if (!strcmp(ptr, "EXTENDED")) + scrnconf->dispmode = UTILX_SCRNCONF_DISPMODE_EXTENDED; + else + scrnconf->dispmode = UTILX_SCRNCONF_DISPMODE_NULL; + } + else + break; + + ptr = strtok (NULL, ","); + i++; + } + + free (str); + + return; +fail: + if (str) + free (str); + + if (scrnconf->str_output) + free (scrnconf->str_output); + if (scrnconf->str_resolution) + free (scrnconf->str_resolution); + if (scrnconf) + { + free (scrnconf); + scrnconf = NULL; + } + return; +} + +API int utilx_scrnconf_set_dispmode (Display *dpy, Utilx_Scrnconf_Dispmode dispmode) +{ + Window win = DefaultRootWindow(dpy); + XEvent xev; + Atom scrnconf_atom = None; + UtilxScrnConf *scrnconf = NULL; + + scrnconf = utilx_scrnconf_allocate (); + if (!scrnconf) + return 0; + + utilx_scrnconf_get_info (dpy, scrnconf); + + if (scrnconf->status == UTILX_SCRNCONF_STATUS_NULL) + { + fprintf (stderr, "[utilx_scrnconf]: the status of screen configuration is null\n"); + return 0; + } + + if (scrnconf->dispmode == dispmode) + { + fprintf (stderr, "[utilx_scrnconf]: dispmode (%d) already set\n", dispmode); + return 0; + } + + utilx_scrnconf_free (scrnconf); + + scrnconf_atom = XInternAtom (dpy, "_SCRNCONF_DISPMODE_SET", False); + + xev.xclient.window = win; + xev.xclient.type = ClientMessage; + xev.xclient.message_type = scrnconf_atom; + xev.xclient.format = 32; + xev.xclient.data.s[0] = dispmode; + + XSendEvent(dpy, win, False, StructureNotifyMask, &xev); + XSync(dpy, False); + + return 1; +} + +typedef struct _ShotInfo +{ + Display *dpy; + + int port; + unsigned int width; + unsigned int height; + Pixmap pixmap; + GC gc; + + int drm_fd; + drm_slp_bufmgr bufmgr; + void *virtual; + + DRI2Buffer* dri2_buffers; + drm_slp_bo bo; + + Damage damage; + int damage_base; +} ShotInfo; + +#define FOURCC(a,b,c,d) (((unsigned)d&0xff)<<24 | ((unsigned)c&0xff)<<16 | ((unsigned)b&0xff)<<8 | ((unsigned)a&0xff)) + +#define FOURCC_RGB32 FOURCC('R','G','B','4') + +static ShotInfo *shot_info; + +static int +_get_port (Display *dpy, unsigned int id) +{ + unsigned int ver, rev, req_base, evt_base, err_base; + unsigned int adaptors; + XvAdaptorInfo *ai = NULL; + XvImageFormatValues *fo = NULL; + int formats; + int i, j, p; + + if (XvQueryExtension (dpy, &ver, &rev, &req_base, &evt_base, &err_base) != Success) + return -1; + + if (XvQueryAdaptors (dpy, DefaultRootWindow (dpy), &adaptors, &ai) != Success) + return -1; + + if (!ai) + return -1; + + for (i = 0; i < adaptors; i++) + { + int support_format = False; + + if (!(ai[i].type & XvStillMask)) + continue; + + p = ai[i].base_id; + + fo = XvListImageFormats (dpy, p, &formats); + for (j = 0; j < formats; j++) + if (fo[j].id == (int)id) + support_format = True; + + if (fo) + XFree (fo); + + if (!support_format) + continue; + + if (XvGrabPort (dpy, p, 0) == Success) + { + XvFreeAdaptorInfo (ai); + return p; + } + + fprintf (stderr, "[UTILX] fail : grab port. \n"); + } + + XvFreeAdaptorInfo (ai); + + return -1; +} + +static void +_deinit_screen_shot (ShotInfo *info) +{ + Atom atom_stream_off; + + if (!info) + return; + + atom_stream_off = XInternAtom (info->dpy, "_USER_WM_PORT_ATTRIBUTE_STREAM_OFF", False); + if (atom_stream_off > 0) + XvSetPortAttribute (info->dpy, info->port, atom_stream_off, 1); + + if (info->dri2_buffers) + free(info->dri2_buffers); + if (info->bo) + drm_slp_bo_unref(info->bo); + if (info->bufmgr) + drm_slp_bufmgr_destroy (info->bufmgr); + if (info->gc) + XFreeGC (info->dpy, info->gc); + if (info->pixmap > 0) + XFreePixmap (info->dpy, info->pixmap); + if (info->port > 0) + XvUngrabPort (info->dpy, info->port, 0); + if (info->dpy) + XCloseDisplay (info->dpy); + + free (info); + shot_info = NULL; +} + +static ShotInfo* +_init_screen_shot (Display* dpy, unsigned int width, unsigned int height) +{ + ShotInfo *info = NULL; + int screen; + int dri2_base = 0; + int dri2_err_base = 0; + int damage_err_base = 0; + int dri2Major, dri2Minor; + char *driverName = NULL, *deviceName = NULL; + Atom atom_capture; + unsigned int attachments[1]; + int dri2_count, dri2_out_count; + int dri2_width, dri2_height, dri2_stride; + drm_magic_t magic; + + if (shot_info) + { + if (shot_info->width == width && shot_info->height == height) + return shot_info; + + _deinit_screen_shot (shot_info); + } + + info = calloc (1, sizeof (ShotInfo)); + if (!info) + goto fail_init; + + shot_info = info; + + /* dpy */ +#if 0 + info->dpy = XOpenDisplay (NULL); +#else + info->dpy = dpy; +#endif + + /* port */ + info->port = _get_port (info->dpy, FOURCC_RGB32); + if (info->port <= 0) + goto fail_init; + + /* width, height */ + atom_capture = XInternAtom (info->dpy, "_USER_WM_PORT_ATTRIBUTE_CAPTURE", False); + XvSetPortAttribute (info->dpy, info->port, atom_capture, 1); + XvQueryBestSize (info->dpy, info->port, 0, 0, 0, width, height, &width, &height); + if (width <= 0 || height <= 0) + goto fail_init; + info->width = width; + info->height = height; + + /* pixmap */ + info->pixmap = XCreatePixmap (info->dpy, + DefaultRootWindow (info->dpy), + width, height, + DefaultDepth (info->dpy, DefaultScreen (info->dpy))); + if (info->pixmap <= 0) + goto fail_init; + + /* gc */ + info->gc = XCreateGC (info->dpy, info->pixmap, 0, 0); + if (info->gc <= 0) + goto fail_init; + + XSetForeground (info->dpy, info->gc, 0xFF000000); + XFillRectangle (info->dpy, info->pixmap, info->gc, 0, 0, width, height); + + screen = DefaultScreen(info->dpy); + if (!DRI2QueryExtension (info->dpy, &dri2_base, &dri2_err_base)) + { + fprintf (stderr, "[UTILX] fail : DRI2QueryExtension !!\n"); + goto fail_init; + } + + if (!DRI2QueryVersion (info->dpy, &dri2Major, &dri2Minor)) + { + fprintf (stderr, "[UTILX] fail : DRI2QueryVersion !!\n"); + goto fail_init; + } + + if (!DRI2Connect (info->dpy, RootWindow(info->dpy, screen), &driverName, &deviceName)) + { + fprintf (stderr, "[UTILX] fail : DRI2Connect !!\n"); + goto fail_init; + } + + /* drm_fd */ + info->drm_fd = open (deviceName, O_RDWR); + if (info->drm_fd < 0) + { + fprintf (stderr, "[UTILX] fail : open drm device (%s)\n", deviceName); + goto fail_init; + } + + /* get the drm magic */ + drmGetMagic(info->drm_fd, &magic); + if (!DRI2Authenticate(info->dpy, RootWindow(info->dpy, screen), magic)) + { + fprintf (stderr, "[UTILX] fail : DRI2Authenticate (%d)\n", magic); + goto fail_init; + } + + /* bufmgr */ + info->bufmgr = drm_slp_bufmgr_init (info->drm_fd, NULL); + if (!info->bufmgr) + { + fprintf (stderr, "[UTILX] fail : init buffer manager \n"); + goto fail_init; + } + + DRI2CreateDrawable (info->dpy, info->pixmap); + + attachments[0] = DRI2BufferFrontLeft; + dri2_count = 1; + info->dri2_buffers = DRI2GetBuffers (info->dpy, info->pixmap, &dri2_width, &dri2_height, + attachments, dri2_count, &dri2_out_count); + + if (!info->dri2_buffers) + { + fprintf (stderr, "[UTILX] fail : get buffers\n"); + goto fail_init; + } + + if (!info->dri2_buffers[0].name) + { + fprintf (stderr, "[UTILX] fail : a handle of the dri2 buffer is null \n "); + goto fail_init; + } + + info->bo = drm_slp_bo_import (info->bufmgr, info->dri2_buffers[0].name); + if (!info->bo) + { + fprintf (stderr, "[UTILX] fail : import bo (key:%d)\n", info->dri2_buffers[0].name); + goto fail_init; + } + + dri2_stride = info->dri2_buffers[0].pitch; + + /* virtual */ + info->virtual = (void*)drm_slp_bo_get_handle (info->bo, DRM_SLP_DEVICE_CPU); + if (!info->virtual) + { + fprintf (stderr, "[UTILX] fail : map \n"); + goto fail_init; + } + + if (!XDamageQueryExtension(info->dpy, &info->damage_base, &damage_err_base)) + goto fail_init; + + info->damage = XDamageCreate (info->dpy, info->pixmap, XDamageReportNonEmpty); + if (info->damage <= 0) + { + fprintf (stderr, "[UTILX] fail : create damage \n"); + goto fail_init; + } + + XFlush (info->dpy); + + return info; + +fail_init: + _deinit_screen_shot (info); + return NULL; +} + +API void* +utilx_create_screen_shot (Display* dpy, int width, int height) +{ + ShotInfo *info; + XEvent ev; + + if (dpy <= 0) + { + fprintf (stderr, "[UTILX] invalid display(%p) \n", dpy); + return NULL; + } + + if (width <= 0 || height <= 0) + { + fprintf (stderr, "[UTILX] invalid size(%dx%d) \n", width, height); + return NULL; + } + + info = _init_screen_shot (dpy, width, height); + if (!info) + { + fprintf (stderr, "[UTILX] fail : initialize screenshot. \n"); + return NULL; + } + + XSync (info->dpy, 0); + + XvGetStill (info->dpy, info->port, info->pixmap, info->gc, + 0, 0, info->width, info->height, + 0, 0, info->width, info->height); + + XSync (info->dpy, 0); + + XNextEvent (info->dpy, &ev); /* wating for x event */ + + if (ev.type == (info->damage_base + XDamageNotify)) + { + XDamageNotifyEvent *damage_ev = (XDamageNotifyEvent *)&ev; + if (damage_ev->drawable == info->pixmap) + { + XDamageSubtract (info->dpy, info->damage, None, None ); + return info->virtual; + } + + XDamageSubtract (info->dpy, info->damage, None, None ); + } + + utilx_release_screen_shot (); + + return NULL; +} + +API void +utilx_release_screen_shot (void) +{ + _deinit_screen_shot (shot_info); +} -- 2.7.4