/* 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);
#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;
  }
}
