/* * * 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 #include #include #include #include #include #include #include #include #include #include #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; Ivisualid) 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; PFIdepth) break; if (PFIdepth+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); }