/* GStreamer
 * Copyright (C) <2005> Julien Moutte <julien@moutte.net>
 *               <2009>,<2010> Stefan Kost <stefan.kost@nokia.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

/* for developers: there are two useful tools : xvinfo and xvattr */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

/* Object header */
#include "xvcontext.h"

/* Debugging category */
#include <gst/gstinfo.h>

/* for XkbKeycodeToKeysym */
#include <X11/XKBlib.h>

GST_DEBUG_CATEGORY_EXTERN (gst_debug_xv_context);
GST_DEBUG_CATEGORY_EXTERN (GST_CAT_PERFORMANCE);
#define GST_CAT_DEFAULT gst_debug_xv_context

void
gst_xvcontext_config_clear (GstXvContextConfig * config)
{
  if (config->display_name) {
    g_free (config->display_name);
    config->display_name = NULL;
  }
  config->adaptor_nr = -1;
}

GST_DEFINE_MINI_OBJECT_TYPE (GstXvContext, gst_xvcontext);

typedef struct
{
  unsigned long flags;
  unsigned long functions;
  unsigned long decorations;
  long input_mode;
  unsigned long status;
}
MotifWmHints, MwmHints;

#define MWM_HINTS_DECORATIONS   (1L << 1)


static void
gst_lookup_xv_port_from_adaptor (GstXvContext * context,
    XvAdaptorInfo * adaptors, guint adaptor_nr)
{
  gint j;
  gint res;

  /* Do we support XvImageMask ? */
  if (!(adaptors[adaptor_nr].type & XvImageMask)) {
    GST_DEBUG ("XV Adaptor %s has no support for XvImageMask",
        adaptors[adaptor_nr].name);
    return;
  }

  /* We found such an adaptor, looking for an available port */
  for (j = 0; j < adaptors[adaptor_nr].num_ports && !context->xv_port_id; j++) {
    /* We try to grab the port */
    res = XvGrabPort (context->disp, adaptors[adaptor_nr].base_id + j, 0);
    if (Success == res) {
      context->xv_port_id = adaptors[adaptor_nr].base_id + j;
      GST_DEBUG ("XV Adaptor %s with %ld ports", adaptors[adaptor_nr].name,
          adaptors[adaptor_nr].num_ports);
    } else {
      GST_DEBUG ("GrabPort %d for XV Adaptor %s failed: %d", j,
          adaptors[adaptor_nr].name, res);
    }
  }
}

/* This function generates a caps with all supported format by the first
   Xv grabable port we find. We store each one of the supported formats in a
   format list and append the format to a newly created caps that we return
   If this function does not return NULL because of an error, it also grabs
   the port via XvGrabPort */
static GstCaps *
gst_xvcontext_get_xv_support (GstXvContext * context,
    const GstXvContextConfig * config, GError ** error)
{
  gint i;
  XvAdaptorInfo *adaptors;
  gint nb_formats;
  XvImageFormatValues *formats = NULL;
  guint nb_encodings;
  XvEncodingInfo *encodings = NULL;
  gulong max_w = G_MAXINT, max_h = G_MAXINT;
  GstCaps *caps = NULL;
  GstCaps *rgb_caps = NULL;

  g_return_val_if_fail (context != NULL, NULL);

  /* First let's check that XVideo extension is available */
  if (!XQueryExtension (context->disp, "XVideo", &i, &i, &i))
    goto no_xv;

  /* Then we get adaptors list */
  if (Success != XvQueryAdaptors (context->disp, context->root,
          &context->nb_adaptors, &adaptors))
    goto no_adaptors;

  context->xv_port_id = 0;

  GST_DEBUG ("Found %u XV adaptor(s)", context->nb_adaptors);

  context->adaptors =
      (gchar **) g_malloc0 (context->nb_adaptors * sizeof (gchar *));

  /* Now fill up our adaptor name array */
  for (i = 0; i < context->nb_adaptors; i++) {
    context->adaptors[i] = g_strdup (adaptors[i].name);
  }

  if (config->adaptor_nr != -1 && config->adaptor_nr < context->nb_adaptors) {
    /* Find xv port from user defined adaptor */
    gst_lookup_xv_port_from_adaptor (context, adaptors, config->adaptor_nr);
  }

  if (!context->xv_port_id) {
    /* Now search for an adaptor that supports XvImageMask */
    for (i = 0; i < context->nb_adaptors && !context->xv_port_id; i++) {
      gst_lookup_xv_port_from_adaptor (context, adaptors, i);
      context->adaptor_nr = i;
    }
  }

  XvFreeAdaptorInfo (adaptors);

  if (!context->xv_port_id)
    goto no_ports;

  /* Set XV_AUTOPAINT_COLORKEY and XV_DOUBLE_BUFFER and XV_COLORKEY */
  {
    int count, todo = 4;
    XvAttribute *const attr = XvQueryPortAttributes (context->disp,
        context->xv_port_id, &count);
    static const char autopaint[] = "XV_AUTOPAINT_COLORKEY";
    static const char dbl_buffer[] = "XV_DOUBLE_BUFFER";
    static const char colorkey[] = "XV_COLORKEY";
    static const char iturbt709[] = "XV_ITURBT_709";

    GST_DEBUG ("Checking %d Xv port attributes", count);

    context->have_autopaint_colorkey = FALSE;
    context->have_double_buffer = FALSE;
    context->have_colorkey = FALSE;
    context->have_iturbt709 = FALSE;

    for (i = 0; ((i < count) && todo); i++) {
      GST_DEBUG ("Got attribute %s", attr[i].name);

      if (!strcmp (attr[i].name, autopaint)) {
        const Atom atom = XInternAtom (context->disp, autopaint, False);

        /* turn on autopaint colorkey */
        XvSetPortAttribute (context->disp, context->xv_port_id, atom,
            (config->autopaint_colorkey ? 1 : 0));
        todo--;
        context->have_autopaint_colorkey = TRUE;
      } else if (!strcmp (attr[i].name, dbl_buffer)) {
        const Atom atom = XInternAtom (context->disp, dbl_buffer, False);

        XvSetPortAttribute (context->disp, context->xv_port_id, atom,
            (config->double_buffer ? 1 : 0));
        todo--;
        context->have_double_buffer = TRUE;
      } else if (!strcmp (attr[i].name, colorkey)) {
        /* Set the colorkey, default is something that is dark but hopefully
         * won't randomly appear on the screen elsewhere (ie not black or greys)
         * can be overridden by setting "colorkey" property
         */
        const Atom atom = XInternAtom (context->disp, colorkey, False);
        guint32 ckey = 0;
        gboolean set_attr = TRUE;
        guint cr, cg, cb;

        /* set a colorkey in the right format RGB565/RGB888
         * We only handle these 2 cases, because they're the only types of
         * devices we've encountered. If we don't recognise it, leave it alone
         */
        cr = (config->colorkey >> 16);
        cg = (config->colorkey >> 8) & 0xFF;
        cb = (config->colorkey) & 0xFF;
        switch (context->depth) {
          case 16:             /* RGB 565 */
            cr >>= 3;
            cg >>= 2;
            cb >>= 3;
            ckey = (cr << 11) | (cg << 5) | cb;
            break;
          case 24:
          case 32:             /* RGB 888 / ARGB 8888 */
            ckey = (cr << 16) | (cg << 8) | cb;
            break;
          default:
            GST_DEBUG ("Unknown bit depth %d for Xv Colorkey - not adjusting",
                context->depth);
            set_attr = FALSE;
            break;
        }

        if (set_attr) {
          ckey = CLAMP (ckey, (guint32) attr[i].min_value,
              (guint32) attr[i].max_value);
          GST_LOG ("Setting color key for display depth %d to 0x%x",
              context->depth, ckey);

          XvSetPortAttribute (context->disp, context->xv_port_id, atom,
              (gint) ckey);
        }
        todo--;
        context->have_colorkey = TRUE;
      } else if (!strcmp (attr[i].name, iturbt709)) {
        todo--;
        context->have_iturbt709 = TRUE;
      }
    }

    XFree (attr);
  }

  /* Get the list of encodings supported by the adapter and look for the
   * XV_IMAGE encoding so we can determine the maximum width and height
   * supported */
  XvQueryEncodings (context->disp, context->xv_port_id, &nb_encodings,
      &encodings);

  for (i = 0; i < nb_encodings; i++) {
    GST_LOG ("Encoding %d, name %s, max wxh %lux%lu rate %d/%d",
        i, encodings[i].name, encodings[i].width, encodings[i].height,
        encodings[i].rate.numerator, encodings[i].rate.denominator);
    if (strcmp (encodings[i].name, "XV_IMAGE") == 0) {
      max_w = encodings[i].width;
      max_h = encodings[i].height;
    }
  }

  XvFreeEncodingInfo (encodings);

  /* We get all image formats supported by our port */
  formats = XvListImageFormats (context->disp,
      context->xv_port_id, &nb_formats);
  caps = gst_caps_new_empty ();
  for (i = 0; i < nb_formats; i++) {
    GstCaps *format_caps = NULL;
    gboolean is_rgb_format = FALSE;
    GstVideoFormat vformat;

    /* We set the image format of the context to an existing one. This
       is just some valid image format for making our xshm calls check before
       caps negotiation really happens. */
    context->im_format = formats[i].id;

    switch (formats[i].type) {
      case XvRGB:
      {
        XvImageFormatValues *fmt = &(formats[i]);
        gint endianness;

        endianness =
            (fmt->byte_order == LSBFirst ? G_LITTLE_ENDIAN : G_BIG_ENDIAN);

        vformat = gst_video_format_from_masks (fmt->depth, fmt->bits_per_pixel,
            endianness, fmt->red_mask, fmt->green_mask, fmt->blue_mask, 0);
        if (vformat == GST_VIDEO_FORMAT_UNKNOWN)
          break;

        format_caps = gst_caps_new_simple ("video/x-raw",
            "format", G_TYPE_STRING, gst_video_format_to_string (vformat),
            "width", GST_TYPE_INT_RANGE, 1, max_w,
            "height", GST_TYPE_INT_RANGE, 1, max_h,
            "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);

        is_rgb_format = TRUE;
        break;
      }
      case XvYUV:
      {
        vformat = gst_video_format_from_fourcc (formats[i].id);
        if (vformat == GST_VIDEO_FORMAT_UNKNOWN)
          break;

        format_caps = gst_caps_new_simple ("video/x-raw",
            "format", G_TYPE_STRING, gst_video_format_to_string (vformat),
            "width", GST_TYPE_INT_RANGE, 1, max_w,
            "height", GST_TYPE_INT_RANGE, 1, max_h,
            "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
        break;
      }
      default:
        vformat = GST_VIDEO_FORMAT_UNKNOWN;
        g_assert_not_reached ();
        break;
    }

    if (format_caps) {
      GstXvImageFormat *format = NULL;

      format = g_new0 (GstXvImageFormat, 1);
      if (format) {
        format->format = formats[i].id;
        format->vformat = vformat;
        format->caps = gst_caps_copy (format_caps);
        context->formats_list = g_list_append (context->formats_list, format);
      }

      if (is_rgb_format) {
        if (rgb_caps == NULL)
          rgb_caps = format_caps;
        else
          gst_caps_append (rgb_caps, format_caps);
      } else
        gst_caps_append (caps, format_caps);
    }
  }

  /* Collected all caps into either the caps or rgb_caps structures.
   * Append rgb_caps on the end of YUV, so that YUV is always preferred */
  if (rgb_caps)
    gst_caps_append (caps, rgb_caps);

  if (formats)
    XFree (formats);

  GST_DEBUG ("Generated the following caps: %" GST_PTR_FORMAT, caps);

  if (gst_caps_is_empty (caps))
    goto no_caps;

  return caps;

  /* ERRORS */
no_xv:
  {
    g_set_error (error, GST_RESOURCE_ERROR, GST_RESOURCE_ERROR_SETTINGS,
        ("XVideo extension is not available"));
    return NULL;
  }
no_adaptors:
  {
    g_set_error (error, GST_RESOURCE_ERROR, GST_RESOURCE_ERROR_SETTINGS,
        ("Failed getting XV adaptors list"));
    return NULL;
  }
no_ports:
  {
    context->adaptor_nr = -1;
    g_set_error (error, GST_RESOURCE_ERROR, GST_RESOURCE_ERROR_BUSY,
        ("No Xv Port available"));
    return NULL;
  }
no_caps:
  {
    gst_caps_unref (caps);
    g_set_error (error, GST_STREAM_ERROR, GST_STREAM_ERROR_WRONG_TYPE,
        ("No supported format found"));
    return NULL;
  }
}

/* This function calculates the pixel aspect ratio based on the properties
 * in the context structure and stores it there. */
static void
gst_xvcontext_calculate_pixel_aspect_ratio (GstXvContext * context)
{
  static const gint par[][2] = {
    {1, 1},                     /* regular screen */
    {16, 15},                   /* PAL TV */
    {11, 10},                   /* 525 line Rec.601 video */
    {54, 59},                   /* 625 line Rec.601 video */
    {64, 45},                   /* 1280x1024 on 16:9 display */
    {5, 3},                     /* 1280x1024 on 4:3 display */
    {4, 3}                      /*  800x600 on 16:9 display */
  };
  gint i;
  gint index;
  gdouble ratio;
  gdouble delta;

#define DELTA(idx) (ABS (ratio - ((gdouble) par[idx][0] / par[idx][1])))

  /* first calculate the "real" ratio based on the X values;
   * which is the "physical" w/h divided by the w/h in pixels of the display */
  ratio = (gdouble) (context->widthmm * context->height)
      / (context->heightmm * context->width);

  /* DirectFB's X in 720x576 reports the physical dimensions wrong, so
   * override here */
  if (context->width == 720 && context->height == 576) {
    ratio = 4.0 * 576 / (3.0 * 720);
  }
  GST_DEBUG ("calculated pixel aspect ratio: %f", ratio);

  /* now find the one from par[][2] with the lowest delta to the real one */
  delta = DELTA (0);
  index = 0;

  for (i = 1; i < sizeof (par) / (sizeof (gint) * 2); ++i) {
    gdouble this_delta = DELTA (i);

    if (this_delta < delta) {
      index = i;
      delta = this_delta;
    }
  }

  GST_DEBUG ("Decided on index %d (%d/%d)", index,
      par[index][0], par[index][1]);

  g_free (context->par);
  context->par = g_new0 (GValue, 1);
  g_value_init (context->par, GST_TYPE_FRACTION);
  gst_value_set_fraction (context->par, par[index][0], par[index][1]);
  GST_DEBUG ("set context PAR to %d/%d",
      gst_value_get_fraction_numerator (context->par),
      gst_value_get_fraction_denominator (context->par));
}

#ifdef HAVE_XSHM
/* X11 stuff */
static gboolean error_caught = FALSE;

static int
gst_xvimage_handle_xerror (Display * display, XErrorEvent * xevent)
{
  char error_msg[1024];

  XGetErrorText (display, xevent->error_code, error_msg, 1024);
  GST_DEBUG ("xvimage triggered an XError. error: %s", error_msg);
  error_caught = TRUE;
  return 0;
}

/* This function checks that it is actually really possible to create an image
   using XShm */
static gboolean
gst_xvcontext_check_xshm_calls (GstXvContext * context)
{
  XvImage *xvimage;
  XShmSegmentInfo SHMInfo;
  size_t size;
  int (*handler) (Display *, XErrorEvent *);
  gboolean result = FALSE;
  gboolean did_attach = FALSE;

  g_return_val_if_fail (context != NULL, FALSE);

  /* Sync to ensure any older errors are already processed */
  XSync (context->disp, FALSE);

  /* Set defaults so we don't free these later unnecessarily */
  SHMInfo.shmaddr = ((void *) -1);
  SHMInfo.shmid = -1;

  /* Setting an error handler to catch failure */
  error_caught = FALSE;
  handler = XSetErrorHandler (gst_xvimage_handle_xerror);

  /* Trying to create a 1x1 picture */
  GST_DEBUG ("XvShmCreateImage of 1x1");
  xvimage = XvShmCreateImage (context->disp, context->xv_port_id,
      context->im_format, NULL, 1, 1, &SHMInfo);

  /* Might cause an error, sync to ensure it is noticed */
  XSync (context->disp, FALSE);
  if (!xvimage || error_caught) {
    GST_WARNING ("could not XvShmCreateImage a 1x1 image");
    goto beach;
  }
  size = xvimage->data_size;
  SHMInfo.shmid = shmget (IPC_PRIVATE, size, IPC_CREAT | 0777);
  if (SHMInfo.shmid == -1) {
    GST_WARNING ("could not get shared memory of %" G_GSIZE_FORMAT " bytes",
        size);
    goto beach;
  }

  SHMInfo.shmaddr = shmat (SHMInfo.shmid, NULL, 0);
  if (SHMInfo.shmaddr == ((void *) -1)) {
    GST_WARNING ("Failed to shmat: %s", g_strerror (errno));
    /* Clean up the shared memory segment */
    shmctl (SHMInfo.shmid, IPC_RMID, NULL);
    goto beach;
  }

  xvimage->data = SHMInfo.shmaddr;
  SHMInfo.readOnly = FALSE;

  if (XShmAttach (context->disp, &SHMInfo) == 0) {
    GST_WARNING ("Failed to XShmAttach");
    /* Clean up the shared memory segment */
    shmctl (SHMInfo.shmid, IPC_RMID, NULL);
    goto beach;
  }

  /* Sync to ensure we see any errors we caused */
  XSync (context->disp, FALSE);

  /* Delete the shared memory segment as soon as everyone is attached.
   * This way, it will be deleted as soon as we detach later, and not
   * leaked if we crash. */
  shmctl (SHMInfo.shmid, IPC_RMID, NULL);

  if (!error_caught) {
    GST_DEBUG ("XServer ShmAttached to 0x%x, id 0x%lx", SHMInfo.shmid,
        SHMInfo.shmseg);

    did_attach = TRUE;
    /* store whether we succeeded in result */
    result = TRUE;
  } else {
    GST_WARNING ("MIT-SHM extension check failed at XShmAttach. "
        "Not using shared memory.");
  }

beach:
  /* Sync to ensure we swallow any errors we caused and reset error_caught */
  XSync (context->disp, FALSE);

  error_caught = FALSE;
  XSetErrorHandler (handler);

  if (did_attach) {
    GST_DEBUG ("XServer ShmDetaching from 0x%x id 0x%lx",
        SHMInfo.shmid, SHMInfo.shmseg);
    XShmDetach (context->disp, &SHMInfo);
    XSync (context->disp, FALSE);
  }
  if (SHMInfo.shmaddr != ((void *) -1))
    shmdt (SHMInfo.shmaddr);
  if (xvimage)
    XFree (xvimage);
  return result;
}
#endif /* HAVE_XSHM */

static GstXvContext *
gst_xvcontext_copy (GstXvContext * context)
{
  return NULL;
}

static void
gst_xvcontext_free (GstXvContext * context)
{
  GList *formats_list, *channels_list;
  gint i = 0;

  GST_LOG ("free %p", context);

  formats_list = context->formats_list;

  while (formats_list) {
    GstXvImageFormat *format = formats_list->data;

    gst_caps_unref (format->caps);
    g_free (format);
    formats_list = g_list_next (formats_list);
  }

  if (context->formats_list)
    g_list_free (context->formats_list);

  channels_list = context->channels_list;

  while (channels_list) {
    GstColorBalanceChannel *channel = channels_list->data;

    g_object_unref (channel);
    channels_list = g_list_next (channels_list);
  }

  if (context->channels_list)
    g_list_free (context->channels_list);

  if (context->caps)
    gst_caps_unref (context->caps);
  if (context->last_caps)
    gst_caps_unref (context->last_caps);

  for (i = 0; i < context->nb_adaptors; i++) {
    g_free (context->adaptors[i]);
  }

  g_free (context->adaptors);

  g_free (context->par);

  GST_DEBUG ("Closing display and freeing X Context");

  if (context->xv_port_id)
    XvUngrabPort (context->disp, context->xv_port_id, 0);

  if (context->disp)
    XCloseDisplay (context->disp);

  g_mutex_clear (&context->lock);

  g_slice_free1 (sizeof (GstXvContext), context);
}


/* This function gets the X Display and global info about it. Everything is
   stored in our object and will be cleaned when the object is disposed. Note
   here that caps for supported format are generated without any window or
   image creation */
GstXvContext *
gst_xvcontext_new (GstXvContextConfig * config, GError ** error)
{
  GstXvContext *context = NULL;
  XPixmapFormatValues *px_formats = NULL;
  gint nb_formats = 0, i, j, N_attr;
  XvAttribute *xv_attr;
  Atom prop_atom;
  const char *channels[4] = { "XV_HUE", "XV_SATURATION",
    "XV_BRIGHTNESS", "XV_CONTRAST"
  };

  g_return_val_if_fail (config != NULL, NULL);

  context = g_slice_new0 (GstXvContext);

  gst_mini_object_init (GST_MINI_OBJECT_CAST (context), 0,
      gst_xvcontext_get_type (),
      (GstMiniObjectCopyFunction) gst_xvcontext_copy,
      (GstMiniObjectDisposeFunction) NULL,
      (GstMiniObjectFreeFunction) gst_xvcontext_free);

  g_mutex_init (&context->lock);
  context->im_format = 0;
  context->adaptor_nr = -1;

  if (!(context->disp = XOpenDisplay (config->display_name)))
    goto no_display;

  context->screen = DefaultScreenOfDisplay (context->disp);
  context->screen_num = DefaultScreen (context->disp);
  context->visual = DefaultVisual (context->disp, context->screen_num);
  context->root = DefaultRootWindow (context->disp);
  context->white = XWhitePixel (context->disp, context->screen_num);
  context->black = XBlackPixel (context->disp, context->screen_num);
  context->depth = DefaultDepthOfScreen (context->screen);

  context->width = DisplayWidth (context->disp, context->screen_num);
  context->height = DisplayHeight (context->disp, context->screen_num);
  context->widthmm = DisplayWidthMM (context->disp, context->screen_num);
  context->heightmm = DisplayHeightMM (context->disp, context->screen_num);

  GST_DEBUG ("X reports %dx%d pixels and %d mm x %d mm",
      context->width, context->height, context->widthmm, context->heightmm);

  gst_xvcontext_calculate_pixel_aspect_ratio (context);
  /* We get supported pixmap formats at supported depth */
  px_formats = XListPixmapFormats (context->disp, &nb_formats);

  if (!px_formats)
    goto no_pixel_formats;

  /* We get bpp value corresponding to our running depth */
  for (i = 0; i < nb_formats; i++) {
    if (px_formats[i].depth == context->depth)
      context->bpp = px_formats[i].bits_per_pixel;
  }

  XFree (px_formats);

  context->endianness =
      (ImageByteOrder (context->disp) ==
      LSBFirst) ? G_LITTLE_ENDIAN : G_BIG_ENDIAN;

  /* our caps system handles 24/32bpp RGB as big-endian. */
  if ((context->bpp == 24 || context->bpp == 32) &&
      context->endianness == G_LITTLE_ENDIAN) {
    context->endianness = G_BIG_ENDIAN;
    context->visual->red_mask = GUINT32_TO_BE (context->visual->red_mask);
    context->visual->green_mask = GUINT32_TO_BE (context->visual->green_mask);
    context->visual->blue_mask = GUINT32_TO_BE (context->visual->blue_mask);
    if (context->bpp == 24) {
      context->visual->red_mask >>= 8;
      context->visual->green_mask >>= 8;
      context->visual->blue_mask >>= 8;
    }
  }

  if (!(context->caps = gst_xvcontext_get_xv_support (context, config, error)))
    goto no_caps;

  /* Search for XShm extension support */
#ifdef HAVE_XSHM
  if (XShmQueryExtension (context->disp) &&
      gst_xvcontext_check_xshm_calls (context)) {
    context->use_xshm = TRUE;
    GST_DEBUG ("xvimagesink is using XShm extension");
  } else
#endif /* HAVE_XSHM */
  {
    context->use_xshm = FALSE;
    GST_DEBUG ("xvimagesink is not using XShm extension");
  }

  xv_attr = XvQueryPortAttributes (context->disp, context->xv_port_id, &N_attr);

  /* Generate the channels list */
  for (i = 0; i < (sizeof (channels) / sizeof (char *)); i++) {
    XvAttribute *matching_attr = NULL;

    /* Retrieve the property atom if it exists. If it doesn't exist,
     * the attribute itself must not either, so we can skip */
    prop_atom = XInternAtom (context->disp, channels[i], True);
    if (prop_atom == None)
      continue;

    if (xv_attr != NULL) {
      for (j = 0; j < N_attr && matching_attr == NULL; ++j)
        if (!g_ascii_strcasecmp (channels[i], xv_attr[j].name))
          matching_attr = xv_attr + j;
    }

    if (matching_attr) {
      GstColorBalanceChannel *channel;

      channel = g_object_new (GST_TYPE_COLOR_BALANCE_CHANNEL, NULL);
      channel->label = g_strdup (channels[i]);
      channel->min_value = matching_attr->min_value;
      channel->max_value = matching_attr->max_value;

      context->channels_list = g_list_append (context->channels_list, channel);

      /* If the colorbalance settings have not been touched we get Xv values
         as defaults and update our internal variables */
      if (!config->cb_changed) {
        gint val;

        XvGetPortAttribute (context->disp, context->xv_port_id,
            prop_atom, &val);
        /* Normalize val to [-1000, 1000] */
        val = floor (0.5 + -1000 + 2000 * (val - channel->min_value) /
            (double) (channel->max_value - channel->min_value));

        if (!g_ascii_strcasecmp (channels[i], "XV_HUE"))
          config->hue = val;
        else if (!g_ascii_strcasecmp (channels[i], "XV_SATURATION"))
          config->saturation = val;
        else if (!g_ascii_strcasecmp (channels[i], "XV_BRIGHTNESS"))
          config->brightness = val;
        else if (!g_ascii_strcasecmp (channels[i], "XV_CONTRAST"))
          config->contrast = val;
      }
    }
  }

  if (xv_attr)
    XFree (xv_attr);

  return context;

  /* ERRORS */
no_display:
  {
    gst_xvcontext_unref (context);
    g_set_error (error, GST_RESOURCE_ERROR, GST_RESOURCE_ERROR_WRITE,
        "Could not open display %s", config->display_name);
    return NULL;
  }
no_pixel_formats:
  {
    gst_xvcontext_unref (context);
    g_set_error (error, GST_RESOURCE_ERROR, GST_RESOURCE_ERROR_SETTINGS,
        ("Could not get pixel formats"));
    return NULL;
  }
no_caps:
  {
    gst_xvcontext_unref (context);
    return NULL;
  }
}

void
gst_xvcontext_set_synchronous (GstXvContext * context, gboolean synchronous)
{
  /* call XSynchronize with the current value of synchronous */
  GST_DEBUG ("XSynchronize called with %s", synchronous ? "TRUE" : "FALSE");
  g_mutex_lock (&context->lock);
  XSynchronize (context->disp, synchronous);
  g_mutex_unlock (&context->lock);
}

void
gst_xvcontext_update_colorbalance (GstXvContext * context,
    GstXvContextConfig * config)
{
  GList *channels = NULL;

  /* Don't set the attributes if they haven't been changed, to avoid
   * rounding errors changing the values */
  if (!config->cb_changed)
    return;

  /* For each channel of the colorbalance we calculate the correct value
     doing range conversion and then set the Xv port attribute to match our
     values. */
  channels = context->channels_list;

  while (channels) {
    if (channels->data && GST_IS_COLOR_BALANCE_CHANNEL (channels->data)) {
      GstColorBalanceChannel *channel = NULL;
      Atom prop_atom;
      gint value = 0;
      gdouble convert_coef;

      channel = GST_COLOR_BALANCE_CHANNEL (channels->data);
      g_object_ref (channel);

      /* Our range conversion coef */
      convert_coef = (channel->max_value - channel->min_value) / 2000.0;

      if (g_ascii_strcasecmp (channel->label, "XV_HUE") == 0) {
        value = config->hue;
      } else if (g_ascii_strcasecmp (channel->label, "XV_SATURATION") == 0) {
        value = config->saturation;
      } else if (g_ascii_strcasecmp (channel->label, "XV_CONTRAST") == 0) {
        value = config->contrast;
      } else if (g_ascii_strcasecmp (channel->label, "XV_BRIGHTNESS") == 0) {
        value = config->brightness;
      } else {
        g_warning ("got an unknown channel %s", channel->label);
        g_object_unref (channel);
        return;
      }

      /* Committing to Xv port */
      g_mutex_lock (&context->lock);
      prop_atom = XInternAtom (context->disp, channel->label, True);
      if (prop_atom != None) {
        int xv_value;
        xv_value =
            floor (0.5 + (value + 1000) * convert_coef + channel->min_value);
        XvSetPortAttribute (context->disp,
            context->xv_port_id, prop_atom, xv_value);
      }
      g_mutex_unlock (&context->lock);

      g_object_unref (channel);
    }
    channels = g_list_next (channels);
  }
}

/* This function tries to get a format matching with a given caps in the
   supported list of formats we generated in gst_xvimagesink_get_xv_support */
gint
gst_xvcontext_get_format_from_info (GstXvContext * context, GstVideoInfo * info)
{
  GList *list = NULL;

  list = context->formats_list;

  while (list) {
    GstXvImageFormat *format = list->data;

    if (format && format->vformat == GST_VIDEO_INFO_FORMAT (info))
      return format->format;

    list = g_list_next (list);
  }
  return -1;
}

void
gst_xvcontext_set_colorimetry (GstXvContext * context,
    GstVideoColorimetry * colorimetry)
{
  Atom prop_atom;
  int xv_value;

  if (!context->have_iturbt709)
    return;

  switch (colorimetry->matrix) {
    case GST_VIDEO_COLOR_MATRIX_SMPTE240M:
    case GST_VIDEO_COLOR_MATRIX_BT709:
      xv_value = 1;
      break;
    default:
      xv_value = 0;
      break;
  }

  g_mutex_lock (&context->lock);
  prop_atom = XInternAtom (context->disp, "XV_ITURBT_709", True);
  if (prop_atom != None) {
    XvSetPortAttribute (context->disp,
        context->xv_port_id, prop_atom, xv_value);
  }
  g_mutex_unlock (&context->lock);
}

GstXWindow *
gst_xvcontext_create_xwindow (GstXvContext * context, gint width, gint height)
{
  GstXWindow *window;
  Atom wm_delete;
  Atom hints_atom = None;

  g_return_val_if_fail (GST_IS_XVCONTEXT (context), NULL);

  window = g_slice_new0 (GstXWindow);

  window->context = gst_xvcontext_ref (context);
  window->render_rect.x = window->render_rect.y = 0;
  window->render_rect.w = width;
  window->render_rect.h = height;
  window->have_render_rect = FALSE;

  window->width = width;
  window->height = height;
  window->internal = TRUE;

  g_mutex_lock (&context->lock);

  window->win = XCreateSimpleWindow (context->disp,
      context->root, 0, 0, width, height, 0, 0, context->black);

  /* We have to do that to prevent X from redrawing the background on
   * ConfigureNotify. This takes away flickering of video when resizing. */
  XSetWindowBackgroundPixmap (context->disp, window->win, None);

  /* Tell the window manager we'd like delete client messages instead of
   * being killed */
  wm_delete = XInternAtom (context->disp, "WM_DELETE_WINDOW", True);
  if (wm_delete != None) {
    (void) XSetWMProtocols (context->disp, window->win, &wm_delete, 1);
  }

  hints_atom = XInternAtom (context->disp, "_MOTIF_WM_HINTS", True);
  if (hints_atom != None) {
    MotifWmHints *hints;

    hints = g_malloc0 (sizeof (MotifWmHints));

    hints->flags |= MWM_HINTS_DECORATIONS;
    hints->decorations = 1 << 0;

    XChangeProperty (context->disp, window->win,
        hints_atom, hints_atom, 32, PropModeReplace,
        (guchar *) hints, sizeof (MotifWmHints) / sizeof (long));

    XSync (context->disp, FALSE);

    g_free (hints);
  }

  window->gc = XCreateGC (context->disp, window->win, 0, NULL);

  XMapRaised (context->disp, window->win);

  XSync (context->disp, FALSE);

  g_mutex_unlock (&context->lock);

  return window;
}

GstXWindow *
gst_xvcontext_create_xwindow_from_xid (GstXvContext * context, XID xid)
{
  GstXWindow *window;
  XWindowAttributes attr;

  window = g_slice_new0 (GstXWindow);
  window->win = xid;
  window->context = gst_xvcontext_ref (context);

  /* Set the event we want to receive and create a GC */
  g_mutex_lock (&context->lock);

  XGetWindowAttributes (context->disp, window->win, &attr);

  window->width = attr.width;
  window->height = attr.height;
  window->internal = FALSE;

  window->have_render_rect = FALSE;
  window->render_rect.x = window->render_rect.y = 0;
  window->render_rect.w = attr.width;
  window->render_rect.h = attr.height;

  window->gc = XCreateGC (context->disp, window->win, 0, NULL);
  g_mutex_unlock (&context->lock);

  return window;
}

void
gst_xwindow_destroy (GstXWindow * window)
{
  GstXvContext *context;

  g_return_if_fail (window != NULL);

  context = window->context;

  g_mutex_lock (&context->lock);

  /* If we did not create that window we just free the GC and let it live */
  if (window->internal)
    XDestroyWindow (context->disp, window->win);
  else
    XSelectInput (context->disp, window->win, 0);

  XFreeGC (context->disp, window->gc);

  XSync (context->disp, FALSE);

  g_mutex_unlock (&context->lock);

  gst_xvcontext_unref (context);

  g_slice_free1 (sizeof (GstXWindow), window);
}

void
gst_xwindow_set_event_handling (GstXWindow * window, gboolean handle_events)
{
  GstXvContext *context;

  g_return_if_fail (window != NULL);

  context = window->context;

  g_mutex_lock (&context->lock);
  if (handle_events) {
    if (window->internal) {
      XSelectInput (context->disp, window->win,
          ExposureMask | StructureNotifyMask | PointerMotionMask |
          KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask);
    } else {
      XSelectInput (context->disp, window->win,
          ExposureMask | StructureNotifyMask | PointerMotionMask |
          KeyPressMask | KeyReleaseMask);
    }
  } else {
    XSelectInput (context->disp, window->win, 0);
  }
  g_mutex_unlock (&context->lock);
}

void
gst_xwindow_set_title (GstXWindow * window, const gchar * title)
{
  GstXvContext *context;

  g_return_if_fail (window != NULL);

  context = window->context;

  /* we have a window */
  if (window->internal && title) {
    XTextProperty xproperty;
    XClassHint *hint = XAllocClassHint ();

    if ((XStringListToTextProperty (((char **) &title), 1, &xproperty)) != 0) {
      XSetWMName (context->disp, window->win, &xproperty);
      XFree (xproperty.value);

      if (hint) {
        hint->res_name = (char *) title;
        hint->res_class = (char *) "GStreamer";
        XSetClassHint (context->disp, window->win, hint);
      }
      XFree (hint);
    }
  }
}

void
gst_xwindow_update_geometry (GstXWindow * window)
{
  XWindowAttributes attr;
  GstXvContext *context;

  g_return_if_fail (window != NULL);

  context = window->context;

  /* Update the window geometry */
  g_mutex_lock (&context->lock);
  XGetWindowAttributes (context->disp, window->win, &attr);

  window->width = attr.width;
  window->height = attr.height;

  if (!window->have_render_rect) {
    window->render_rect.x = window->render_rect.y = 0;
    window->render_rect.w = attr.width;
    window->render_rect.h = attr.height;
  }

  g_mutex_unlock (&context->lock);
}


void
gst_xwindow_clear (GstXWindow * window)
{
  GstXvContext *context;

  g_return_if_fail (window != NULL);

  context = window->context;

  g_mutex_lock (&context->lock);

  XvStopVideo (context->disp, context->xv_port_id, window->win);

  XSync (context->disp, FALSE);

  g_mutex_unlock (&context->lock);
}

void
gst_xwindow_set_render_rectangle (GstXWindow * window,
    gint x, gint y, gint width, gint height)
{
  g_return_if_fail (window != NULL);

  if (width >= 0 && height >= 0) {
    window->render_rect.x = x;
    window->render_rect.y = y;
    window->render_rect.w = width;
    window->render_rect.h = height;
    window->have_render_rect = TRUE;
  } else {
    window->render_rect.x = 0;
    window->render_rect.y = 0;
    window->render_rect.w = window->width;
    window->render_rect.h = window->height;
    window->have_render_rect = FALSE;
  }
}
