![]() |
![]() |
||||||
![]() |
|||||||
|
/*
*
* display.c - part of Danovitsch Webcam
*
* Copyright (C) 2001, 2003 by Daan Vreeken
*
* Published under the terms of the GNU Public License 2.0
* (or any later version)
*
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <unistd.h>
#include <time.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include "general.h"
#include "webcam.h"
#include "io.h"
#include "display.h"
/**@BEGINFUNC**************************************************************
Prototype : void XUTILGetVisualBpp(
Display *display,
XVisualInfo *vi,
TV_INT32 *Bpp_pixmap,
TV_INT32 *Bpp_fbuffer )
Purpose : Returns the number of bytes per pixel for the specified
visual.
NOTE: This is not always (depth+7)/8, which is the reason
for the existance of this convenience function. And even
then this function will sometimes get it wrong because
Pixmap pixel geometry doesn't necessarily equate to Frame
buffer pixel geometry.
BACKGROUND: Some X servers define 4 Bpp 24bpp modes as
depth 32 bpp (-bpp 32), while others define them as depth
24 bpp (-bpp 24). Others use implement both 24bpp and 32bpp
in a 3Bpp mode (e.g. 3.3.1 S3V server). So we can't use
visual depth alone as a determining value.
Alternatively we probe the pixmap formats that are
supported by the display to help determine the true Bpp.
For both cases, the pixmap bits_per_pixel for the
corresponding depth (24 or 32) is 32, usually reflecting
the true depth of the frame buffer, but not always.
Because without probing hardware we can't really tell
for sure what the frame buffer Bpp is, we allow the
user to tell us (for 24bpp and 32bpp anyway) using the
Bpp24bit and Bpp32bit settings
Programmer : 29-Mar-97 Randall Hopper
Parameters : display - I: display that visual is on
vi - I: info struct for a visual
Bpp_pixmap - O: pixmap Bpp
Bpp_fbuffer - O: frame buffer Bpp
Returns : Bytes per pixel for the visual
Globals : None.
**@ENDFUNC*****************************************************************/
void GetBpp(Display *Display, XVisualInfo *VI, int *BppPtr)
{
static struct
{
VisualID VisualID;
long BppPixmap;
long BppFBuffer;
} *VList = NULL;
static int VListLen = 0;
int I;
int Bpp = 0;
/* Look up cached value */
for (I=0; I<VListLen; I++)
if (VList[I].VisualID==VI->visualid)
break;
/* Didn't have a cached value? Go figure it out. */
if (I>=VListLen)
{
XPixmapFormatValues *PF;
int NumPF;
int PFI;
/* Try to grab Bpp from pixmap formats first */
PF=XListPixmapFormats(Display,&NumPF);
if (PF!=NULL)
{
for (PFI=0; PFI<NumPF; PFI++)
if (PF[PFI].depth==VI->depth)
break;
if (PFI<NumPF)
Bpp=(PF[PFI].bits_per_pixel+7)/8;
XFree(PF);
}
/* Or fallback to using depth */
if (Bpp==0)
Bpp=(VI->depth+7)/8;
/* And finally, add to Bpp cache */
VListLen++;
VList=realloc(VList,sizeof(VList[0])*VListLen);
if (VList==NULL)
{
printf("EEEK ! Out of memory!\n");
exit(0);
}
I=VListLen-1;
VList[I].VisualID=VI->visualid;
VList[I].BppPixmap=Bpp;
VList[I].BppFBuffer=Bpp;
}
if (BppPtr)
*BppPtr=VList[I].BppPixmap;
}
int Display_MakeGC(XWnd *W)
{
XGCValues GCVals;
GC NewGC;
NewGC=XCreateGC(W->Dsp,W->Wnd,0,&GCVals);
if (NewGC)
{
XSetForeground(W->Dsp,NewGC,W->White);
XSetBackground(W->Dsp,NewGC,W->Black);
W->MyGC=NewGC;
return 1;
}
else
return 0;
}
XWnd *Display_CreateWindow(void)
{
char DisplayName[100];
XWnd *W = malloc(sizeof(*W));
XWnd **Ptr;
XVisualInfo Pref;
int Visuals;
long Nop;
//sanity check
if (W==NULL)
ExitFatal("Could not allocate memory for Display_Wnd structure!");
//get display name (or guess it)
if (getenv("DISPLAY"))
strcpy(DisplayName,(char *)getenv("DISPLAY"));
else
strcpy(DisplayName,":0.0");
//open display
W->Dsp=XOpenDisplay(DisplayName);
if (W->Dsp==NULL)
ExitFatal("Could not open display!");
W->Scr=DefaultScreen(W->Dsp);
W->Black=BlackPixel(W->Dsp,W->Scr);
W->White=WhitePixel(W->Dsp,W->Scr);
W->Vis=DefaultVisual(W->Dsp,W->Scr);
W->MyDepth=DefaultDepth(W->Dsp,W->Scr);
Pref.screen=W->Scr;
W->VisInfo=XGetVisualInfo(W->Dsp,VisualScreenMask,&Pref,&Visuals);
GetBpp(W->Dsp,W->VisInfo,&W->Bpp);
printf("MyDepth: %d\n",W->MyDepth);
//create window
W->Wnd=XCreateSimpleWindow(W->Dsp,RootWindow(W->Dsp,W->Scr),10,10,20,20,5,W->Black,W->Black);
if (!Display_MakeGC(W))
{
XDestroyWindow(W->Dsp,W->Wnd);
ExitFatal("Could not make GC!");
}
XMapWindow(W->Dsp,W->Wnd);
XmbSetWMProperties(W->Dsp,W->Wnd,Server_String,"dv",NULL,0,NULL,NULL,NULL);
return W;
}
void Display_CreateImage(XWnd *W, int Width, int Height)
{
W->Buffer=malloc(Width*Height*4);
if (W->Buffer==NULL)
ExitFatal("Could not allocate memory for image backbuffer!");
W->XImg=XCreateImage(W->Dsp,W->Vis,W->MyDepth,ZPixmap,0,W->Buffer,Width,Height,32,0);
W->ImgWidth=Width;
W->ImgHeight=Height;
XMapWindow(W->Dsp,W->Wnd);
XFlush(W->Dsp);
}
void Display_DestroyImage(XWnd *W)
{
XDestroyImage(W->XImg);
}
void Display_UpdateImage(XWnd *W)
{
XPutImage(W->Dsp,W->Wnd,W->MyGC,W->XImg,0,0,5,5,W->ImgWidth,W->ImgHeight);
XFlush(W->Dsp);
}
void Display_ResizeWindow(XWnd *W, int Width, int Height)
{
XResizeWindow(W->Dsp,W->Wnd,Width,Height);
}
void Display_Init(void)
{
}
void Display_Kill(XWnd *W)
{
//Destroy the window and close the display
XDestroyWindow(W->Dsp,W->Wnd);
XCloseDisplay(W->Dsp);
}
syntax highlighted by Code2HTML, v. 0.9.1 Email me with questions/comments : Daan <Danovitsch @ Vitsch . net> |