/* 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_xvcontext);
GST_DEBUG_CATEGORY_EXTERN (GST_CAT_PERFORMANCE);
#define GST_CAT_DEFAULT gst_debug_xvcontext

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;
  }
}
