Navigation
Home
gpl
danovitschwebcam
1.0
display.c








































display.c
   
   /*
    *
    * display.c - part of Danovitsch Webcam
    *
    * Copyright (C) 2001 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 <Daan @ pa4dan . nl>