/* 
    KDE Xv interface

    Copyright (C) 2001 George Staikos (staikos@kde.org)

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program 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 General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/


#ifndef __KXV_H
#define __KXV_H

#include <X11/X.h>
#include <X11/Xlib.h>
#include <qstring.h>
#include <qstringlist.h>
#include <qlist.h>
#include <qpixmap.h>

class QWidget;

class KXvPrivate;
class KXvDevice;
class KXvDevicePrivate;

typedef QList<KXvDevice> KXvDeviceList;


class KXv {
public:
  ~KXv();

  /*
   *   To get access to the Xv extension, you call this method.  It will return
   *   a KXv* object on success, or NULL if it can't connect.
   *
   *   d is typically the Window ID
   */
  static KXv *connect(Drawable d);

  /*
   *   True if we can connect to the Xv extension.
   */
  static bool haveXv();

  /*
   *   Return the list of Xv devices
   */
  KXvDeviceList& devices();

protected:
  KXv();
  bool init(Drawable d);

  /***   XV info   ***/
  unsigned int xv_version, xv_release, xv_request, xv_event, xv_error;
  unsigned int xv_adaptors;
  void *xv_adaptor_info;


  KXvDeviceList _devs;


private:
  KXvPrivate *d;
};



class KXvDeviceAttribute {
public:
  QString name;
  int min;
  int max;
  int flags;

  Atom atom();
};

typedef QList<KXvDeviceAttribute> KXvDeviceAttributes;



class KXvDevice {
friend class KXv;
public:

  KXvDevice();
  ~KXvDevice();

  /*
   *   return the list of known attributes
   */
  const KXvDeviceAttributes& attributes();

  /*
   *   return the range for a given attribute
   */
  bool getAttributeRange(QString attribute, int *min, int *max);

  /*
   *   get the current value of a given attribute
   */
  bool getAttribute(QString attribute, int *val);

  /*
   *   set the current value of a given attribute
   */
  bool setAttribute(QString attribute, int val);

  bool grabStill(QPixmap *pix, int dw, int dh);

  /*
   *   True if this device can operate on the given widget
   */
  bool supportsWidget(QWidget *w);

  /*
   *   Display the given image with Xv.
   */
  int displayImage(QWidget *widget, const unsigned char *const data, int w, int h, int dw, int dh);
  int displayImage(Window win, const unsigned char *const data, int w, int h, int dw, int dh);

  /*
   *   Start a video stream in widget w, width dw, height dh
   */
  bool startVideo(QWidget *w, int dw, int dh);
  bool startVideo(Window w, int dw, int dh);

  /*
   *   Is the video playing
   */
  bool videoPlaying() const;

  /*
   *   Stop video stream
   */
  bool stopVideo();

  /*
   *   True if this is an image output backend (video card)
   */
  bool isImageBackend();

  /*
   *   True if this is a video source
   */
  bool isVideoSource();

  /*
   *   Name of the device
   */
  const QString& name() const;

  /*
   *   The Xv port for this device
   */
  int port() const;

  /*
   *   The list of encodings/norms available
   */
  const QStringList& encodings() const;

  /*
   *   Set the encoding to the given one.  This should be taken from the list.
   */
  bool setEncoding(const QString& e);

  /*
   *   Set the image format. (ex YUV)
   */
  int setImageFormat(int format);

  /*
   *   Get the current image format
   */
  int imageFormat() const;

  /*
   *   Use SHM for PutImage if available
   */
  bool useShm(bool on);

  /*
   *   Is SHM being used?
   */
  bool usingShm() const;

protected:

  bool init();

  bool _shm;
  KXvDeviceAttributes _attrs;

  int xv_type, xv_adaptor;
  QString xv_name;
  int xv_port;
  unsigned int xv_encodings;
  int xv_encoding;
  void *xv_encoding_info;
  int xv_encoding_attributes;
  void *xv_attr;
  GC xv_gc;
  Window xv_last_win;

  QStringList _encodingList;

  int xv_formats;
  void *xv_formatvalues;

  int xv_nvisualformats;
  void *xv_visualformats;  // XvFormat*

  bool videoStarted;
  Window videoWindow;

  long xv_imageformat;

  void *xv_shminfo;
  void *xv_image;
  int xv_image_w;
  int xv_image_h;
  bool _haveShm;

private:

  KXvDevicePrivate *d;

  void rebuildImage(int w, int h, bool shm);
  void destroyImage();
};


#endif

