/* * * webcam.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 "general.h" #include "io.h" #include "display.h" #include "capture.h" #include "overlay.h" #include "compress.h" #include "server.h" #include "http.h" #include "webcam.h" int PleaseDie = 0; int WantX; int TooOld(struct timeval *Object, long Sec, long USec) { struct timeval Temp = *Object; struct timeval Now; Temp.tv_sec+=Sec; Temp.tv_usec+=USec; while (Temp.tv_usec>=1000*1000) { Temp.tv_usec-=1000*1000; Temp.tv_sec++; } gettimeofday(&Now,NULL); if (Temp.tv_secClose=1; return; } else Error("EEEK! Fixme!! Received SIGPIPE!!"); PleaseDie=1; } void Translate(unsigned char *Dst, unsigned char *Src, int Bpp) { int X,Y; unsigned char *A = Dst; unsigned char *B = Src; long C; int Diff; int Plus; unsigned char Cnt; unsigned char Cnt2; for (Y=0; Y0) { Readed=fread(Buf,1,sizeof(Buf),OverlayTxt); for (Cnt=0; CntID!=NoID) { Capture_Set(Arr,NULL,Arr->NumValue,Arr->OrgValue); Arr++; } sprintf(ListenAddr,Server_ListenAddr); memset(&(Addr.sin_zero),0,8); Addr.sin_family=AF_INET; Addr.sin_port=htons(Server_Port); Addr.sin_addr.s_addr=inet_addr(ListenAddr); Len=sizeof(Addr); AcceptSock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); Cnt=1; setsockopt(AcceptSock,SOL_SOCKET,SO_REUSEADDR,(char *)&Cnt,sizeof(Cnt)); if (bind(AcceptSock,(struct sockaddr *)&Addr,Len)==-1) ExitFatal("Could not bind socket!"); if (listen(AcceptSock,5)==-1) ExitFatal("Socket error!"); while (!PleaseDie) { /// Check age of frame buffer // if (TooOld(&FrameTime,FrameTimeout)) Capture_Single(); /// Dump dead connections // for (Cnt=0; Cnt=0; Cnt--) if (Client[Cnt].Close) Server_CloseConnection(Cnt); FD_ZERO(&ReadMask); FD_ZERO(&WriteMask); FD_SET(AcceptSock,&ReadMask); FD_SET(Capture_Fifo[1],&ReadMask); FDMax=AcceptSock; if (Capture_Fifo[1]>FDMax) FDMax=Capture_Fifo[1]; for (Cnt=0; CntFDMax) FDMax=Client[Cnt].FD; } if (State==Response) { FD_SET(Client[Cnt].FD,&WriteMask); if (Client[Cnt].FD>FDMax) FDMax=Client[Cnt].FD; } } /// Wait for data to get available (anywhere) // if (select(FDMax+1,&ReadMask,&WriteMask,NULL,&MaxWait)<=0) { continue; } /// New connection? // if (FD_ISSET(AcceptSock,&ReadMask)) { NewConn=accept(AcceptSock,NULL,NULL); if (NewConn==-1) ExitFatal("Hugh? accept returned an error!"); //fcntl(NewConn,F_SETFD,O_NONBLOCK); if (ClientsFD=NewConn; C->Close=0; C->State=GetRequest; C->Mode=LineMode; C->Line=NULL; C->Length=0; C->Request=NULL; C->PostData=NULL; C->PostLength=0; C->ContentLength=0; C->Error=0; gettimeofday(&C->ConnectTime,NULL); Clients++; } else { Debug(80,"Server full... (dropping new connection)"); close(NewConn); } } /// Check client connections for activity... // for (Cnt=0; Cnttm_hour,Time->tm_min,Time->tm_sec,Time->tm_zone); if (WantX) { Translate((unsigned char *)Wnd->Buffer,(unsigned char *)FrameBuffer,Wnd->Bpp); //memcpy(Wnd->Buffer,FrameBuffer,4*ImageWidth*ImageHeight); Display_UpdateImage(Wnd); } NewFrame=0; } } Output("\n\nSomeone wants us to die!"); Server_Shutdown(); Capture_Shutdown(); if (WantX) { Display_DestroyImage(Wnd); Display_Kill(Wnd); } Output("\nMoo,\n]:8)"); return 0; }