Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals  

GlwClient.c

Go to the documentation of this file.
00001 /*
00002  *    gui - [gega user interface] the flexible solution for user interface problems
00003  *    Copyright (C) 2002  Gergely Gati
00004  *
00005  *    This program is free software; you can redistribute it and/or modify
00006  *    it under the terms of the GNU General Public License as published by
00007  *    the Free Software Foundation; version 2 of the License.
00008  *
00009  *    This program is distributed in the hope that it will be useful,
00010  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *    GNU General Public License for more details.
00013  *
00014  *    You should have received a copy of the GNU General Public License
00015  *    along with this program; if not, write to the Free Software
00016  *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017  *
00018  *    Gergely Gati
00019  *      email:           g.gati@freemail.hu
00020  *      AIM screenname:  GatiGergely
00021  *      ICQ number:      93131690
00022  *
00023  */
00024 #include <windows.h>
00025 #include <winsock2.h>
00026 
00027 #include <stdlib.h>
00028 #include <string.h>
00029 #include <time.h>
00030 
00031 #undef GLW_SERVER
00032 
00033 #include "NetCommon.h"
00034 #include "port/Glw.h"
00035 #include "Memory.h"
00036 #include "debug.h"
00037 #include "Net.h"
00038 #include "Client.h"
00039 //#include "Prefs.h"
00040 
00041 
00042 #define SOCK_CLOSE_BUFSIZE  256
00043 
00044 static char client_loopback[]="127.0.0.1";
00045 static char *client_address=client_loopback;
00046 static HWND global_window;
00047 static struct glw_Connection *global_conn;
00048 static int quit=0;
00049 static int async=0;
00050 
00051 
00052 struct glw_Connection
00053 {
00054   struct glw_ConnUser cuser;
00055   SOCKET sd;
00056   struct glw_SockMsg sockmsg;
00057   u32 completed;
00058   u8 *write_buffer;
00059   int byteorder;        // 0-azonos, 1-eltero
00060 };
00061 
00062 struct glw_Timer
00063 {
00064   u32 userdata;
00065 //  net_Window_t *nwin;
00066   u32 id;
00067 };
00068 
00069 
00070 static struct glw_Event curr_event;
00071 
00072 
00073 
00074 u32 glw_htonl(u32 value)
00075 {
00076   return(htonl(value));
00077 }
00078 
00079 u32 glw_ntohl(u32 value)
00080 {
00081   return(ntohl(value));
00082 }
00083 
00084 
00085 int glw_Recv(u32 connection, u8 *buff, int bufflen)
00086 {
00087   struct glw_Connection *conn=(struct glw_Connection *)connection;
00088   int ret=0;
00089 
00090   debug_Begin();
00091 
00092   if(conn!=NULL&&buff!=NULL&&bufflen>0)
00093   {
00094     ret=recv(conn->sd,buff,bufflen,0);
00095   }
00096 
00097   debug_End();
00098 
00099   return(ret);
00100 }
00101 
00102 
00103 int glw_Send(u32 connection, u8 *buff, int bufflen)
00104 {
00105   struct glw_Connection *conn=(struct glw_Connection *)connection;
00106   int ret=0;
00107 
00108   debug_Begin();
00109 
00110   if(conn!=NULL&&buff!=NULL&&bufflen>0)
00111   {
00112     ret=send(conn->sd,buff,bufflen,0);
00113   }
00114 
00115   debug_End();
00116 
00117   return(ret);
00118 }
00119 
00120 
00121 int glw_SendMsg(u32 connection, u8 type, u32 id, u8 *buff, int bufflen)
00122 {
00123   struct glw_Connection *conn=(struct glw_Connection *)connection;
00124   u8 header[GLW_HEADER_LENGTH];
00125   int mlen;
00126 
00127   debug_Begin();
00128 
00129   mlen=bufflen+GLW_HEADER_LENGTH;
00130 //printf("OUTGOING Message %d bytes + %d bytes header (total: %d)\n",bufflen,GLW_HEADER_LENGTH,mlen);
00131 //if(bufflen>3) printf("msg: %02x %02x %02x %02x (%c%c%c%c)\n",buff[0],buff[1],buff[2],buff[3],buff[0],buff[1],buff[2],buff[3]);
00132   header[0]='?';
00133   header[1]=type;
00134   *((u32 *)&header[2])=htonl(mlen);
00135   *((u32 *)&header[6])=htonl(id);
00136   if(mlen<NET_WRITE_BUFFER_SIZE)
00137   {
00138     memcpy(conn->write_buffer,header,GLW_HEADER_LENGTH);
00139     if(bufflen>0) memcpy(conn->write_buffer+GLW_HEADER_LENGTH,buff,bufflen);
00140     send(conn->sd,conn->write_buffer,mlen,0);
00141   }
00142   else
00143   {
00144     send(conn->sd,header,GLW_HEADER_LENGTH,0);
00145     if(bufflen>0&&buff!=NULL) send(conn->sd,buff,bufflen,0);
00146   }
00147 
00148   debug_End();
00149 
00150   return(0);
00151 }
00152 
00153 
00154 static void glw_Client(char *address, int port)
00155 {
00156   struct in_addr Address;
00157   SOCKET sd;
00158   u_long RemoteAddress;
00159   struct hostent *pHE;
00160   struct sockaddr_in sinRemote;
00161   WSADATA wsaData;
00162   struct glw_Connection *conn;
00163   int NewBytes;
00164   char ReadBuffer[SOCK_CLOSE_BUFSIZE];
00165 
00166   debug_Begin();
00167 
00168   if(WSAStartup(MAKEWORD(1,1),&wsaData)==0)
00169   {
00170     printf("Establishing the client...\n");
00171     RemoteAddress=inet_addr(address);
00172     if(RemoteAddress==INADDR_NONE)
00173     {
00174         pHE=gethostbyname(address);
00175         if(pHE!=0)
00176         {
00177           RemoteAddress=*((u_long*)pHE->h_addr_list[0]);
00178         }
00179     }
00180     if(RemoteAddress!=INADDR_NONE)
00181     {
00182       memcpy(&Address,&RemoteAddress,sizeof(u_long));
00183       sd=socket(AF_INET, SOCK_STREAM, 0);
00184       if(sd!=INVALID_SOCKET)
00185       {
00186         sinRemote.sin_family=AF_INET;
00187         sinRemote.sin_addr.s_addr=RemoteAddress;
00188         sinRemote.sin_port=htons(port);
00189         if(connect(sd,(struct sockaddr *)&sinRemote,sizeof(struct sockaddr_in))==SOCKET_ERROR)
00190         {
00191           sd=INVALID_SOCKET;
00192         }
00193       }
00194       if(INVALID_SOCKET!=sd)
00195       {
00196         if(NULL!=(conn=mem_calloc(1,sizeof(struct glw_Connection))))
00197         {
00198           if(NULL!=(conn->write_buffer=mem_malloc(NET_WRITE_BUFFER_SIZE)))
00199           {
00200             conn->sd=sd;
00201             printf("connected to server\n");
00202             client_Init((u32)conn,&conn->byteorder);
00203             mem_free(conn->write_buffer);
00204           }
00205           mem_free(conn);
00206         }
00207         if(shutdown(sd,SD_SEND)!=SOCKET_ERROR)
00208         {
00209           while(1)
00210           {
00211             NewBytes=recv(sd,ReadBuffer,SOCK_CLOSE_BUFSIZE,0);
00212             if(NewBytes==0||NewBytes==SOCKET_ERROR) break;
00213           }
00214           closesocket(sd);
00215         }
00216       }
00217     }
00218     WSACleanup();
00219   }
00220 
00221   debug_End();
00222 }
00223 
00224 
00225 static int glw_ReadMessage(struct glw_Connection *conn)
00226 {
00227   char header[GLW_HEADER_LENGTH];
00228   int rcv=0,r=0,ret=0;
00229   SYSTEMTIME stime;
00230 
00231   if(conn->completed==0)
00232   {
00233     // new message
00234     while(rcv<GLW_HEADER_LENGTH)
00235     {
00236       if((r=recv(conn->sd,header+rcv,GLW_HEADER_LENGTH-rcv,0))<=0)
00237       {
00238         if(WSAGetLastError()==WSAEWOULDBLOCK)
00239         {
00240           fd_set fdread;
00241           FD_ZERO(&fdread);
00242           FD_SET(conn->sd,&fdread);
00243           if((r=select(0,&fdread,NULL,NULL,NULL))==SOCKET_ERROR) break;
00244         }
00245         else break;
00246         if((r=recv(conn->sd,header+rcv,GLW_HEADER_LENGTH-rcv,0))<=0) break;
00247       }
00248       rcv+=r;
00249     }
00250     if(r>=0&&header[0]=='?')
00251     {
00252       conn->sockmsg.type=(int)header[1];
00253       conn->sockmsg.length=ntohl(*((u32 *)&header[2]));
00254       conn->sockmsg.id=ntohl(*((u32 *)&header[6]));
00255       conn->sockmsg.body=mem_malloc(conn->sockmsg.length-GLW_HEADER_LENGTH);
00256       conn->completed=GLW_HEADER_LENGTH;
00257 //      printf("%s() legal message header: type=0x%02x id=%ld len=%ld\n",__FUNCTION__,(u8)conn->sockmsg.type,conn->sockmsg.id,conn->sockmsg.length);
00258       if(conn->sockmsg.body==NULL)
00259       {
00260         // HIBA!!
00261         conn->completed=0;
00262       }
00263     }
00264     else
00265     {
00266       // HIBA!!
00267       ret=-1;
00268       if(r>0)
00269       {
00270         int i,j,c;
00271         printf("***BAD MESSAGE:\n  ");
00272         for(j=i=0;i<r;i++)
00273         {
00274           c=*(header+rcv-r+i);
00275           printf("%02x '%c' ",(unsigned short)c,(c>32||c<127?c:'.'));
00276           if((++j%8)==0) printf("\n  ");
00277         }
00278         printf("\n");
00279       }
00280       else
00281       {
00282         printf("***BAD MESSAGE ret=%d errcode=%d\n",r,WSAGetLastError());
00283       }
00284     }
00285   }
00286   else
00287   {
00288     // partial message
00289     r=recv( conn->sd,conn->sockmsg.body+conn->completed-GLW_HEADER_LENGTH,
00290             conn->sockmsg.length-conn->completed,0);
00291     if(r>0)
00292     {
00293       conn->completed+=r;
00294       if(conn->completed>=conn->sockmsg.length)
00295       {
00296         conn->completed=0;
00297         curr_event.event=GLWEV_SOCKET;
00298         curr_event.data=(u32)&conn->sockmsg;
00299         curr_event.second=(u32)time(NULL);
00300         GetSystemTime(&stime);
00301         curr_event.millis=stime.wMilliseconds;
00302       }
00303     }
00304   }
00305   return(ret);
00306 }
00307 
00308 
00309 int glw_MainLoopCli(u32 connection, u32 userdata)
00310 {
00311 //static int cnt=0;
00312   struct glw_Connection *conn=(struct glw_Connection *)connection;
00313   MSG Message;
00314 
00315   debug_Begin();
00316 
00317   debug_Message("ByteOrder: %d",conn->byteorder);
00318 
00319 //printf("\nMAINLOOP START %d\n",cnt++);
00320   global_conn=conn;
00321   do
00322   {
00323     if(async==0)
00324     {
00325       WSAAsyncSelect(conn->sd,global_window,WM_APP,FD_READ);
00326       async=1;
00327     }
00328     quit=0;
00329     curr_event.event=0L;
00330     curr_event.window=0L;
00331     curr_event.userdata=userdata;
00332     curr_event.mousex=curr_event.mousey=0;
00333 
00334     GetMessage(&Message,NULL,0,0);
00335     TranslateMessage(&Message);       // keycode conversion
00336     DispatchMessage(&Message);        // call StdWindowProc() (retval==StdWindowProc's retval)
00337 
00338 //    if(glw_ReadMessage(conn)<0) break;
00339 //printf(" 1: quit=%d\n",quit);
00340     if(curr_event.event!=0L&&0!=client_CliProcessMessage(connection,curr_event.userdata,(struct glw_SockMsg *)curr_event.data)) break;
00341 //printf(" 2: quit=%d\n",quit);
00342   } while(quit==0);
00343   WSAAsyncSelect(conn->sd,global_window,0,0);
00344   async=0;
00345 //printf("MAINLOOP STOP %d\n",--cnt);
00346 
00347   debug_End();
00348 
00349   return(0);
00350 }
00351 
00352 
00353 /*
00354 int main(int argc, char **argv)
00355 {
00356   if(argc>1) client_address=argv[1];
00357   prefs_Init();
00358   glw_Client(client_address, net_GetPort());
00359   prefs_CleanUp();
00360   mem_trace_report();
00361   return(0);
00362 }
00363 */
00364 
00365 
00366 LRESULT CALLBACK glw_StdWindowProc(HWND Window, UINT MessageType, WPARAM FirstParameter, LPARAM SecondParameter)
00367 {
00368   LRESULT ret=1L;
00369 
00370   debug_Begin();
00371 
00372   switch(MessageType)
00373   {
00374     case WM_TIMER:
00375     {
00376       struct glw_Timer *timer=(struct glw_Timer *)FirstParameter;
00377 //printf("TIMER!!!\n");
00378       // userdata: FirstParameter
00379       // event: GLWEV_TIMER
00380       if(timer!=NULL)
00381       {
00382 //printf("  CODE (%ld)\n",timer->userdata);
00383         client_TimerHandler((u32)timer,timer->userdata);
00384 //        timer->nwin->event_handler(timer->nwin->app,timer->nwin->window,0L,GLWEV_TIMER,timer->userdata);
00385         KillTimer(global_window,timer->id);
00386         ret=0;
00387       }
00388       break;
00389     }
00390     case WM_APP:
00391     {
00392 //      if(0>glw_ReadMessage(global_conn)) quit=1;
00393       if(0>glw_ReadMessage(global_conn)) printf("***BAD MESSAGE!!\n");
00394       ret=0;
00395       break;
00396     }
00397   }
00398 
00399   debug_End();
00400 
00401   return(ret);
00402 }
00403 
00404 
00405 int WINAPI WinMain(HINSTANCE Instance, HINSTANCE PreviousInstance, LPSTR CommandLine, int CommandShow)
00406 {
00407   WNDCLASSEX WindowClass;
00408 
00409   debug_Begin();
00410 
00411   if(strlen(CommandLine)>=7) client_address=CommandLine;
00412 
00413   WindowClass.cbSize = sizeof(WNDCLASSEX);
00414   WindowClass.style = 0;
00415   WindowClass.lpfnWndProc = glw_StdWindowProc;
00416   WindowClass.cbClsExtra = 0;
00417   WindowClass.cbWndExtra = 0;
00418   WindowClass.hInstance = Instance;
00419   WindowClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
00420   WindowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
00421   WindowClass.hbrBackground = GetStockObject(WHITE_BRUSH);
00422   WindowClass.lpszMenuName = NULL;
00423   WindowClass.lpszClassName = "glw_StdClientWC";
00424   WindowClass.hIconSm = NULL;
00425   if(RegisterClassEx(&WindowClass)!=0)
00426   {
00427     if((global_window=CreateWindowEx(
00428         WS_EX_OVERLAPPEDWINDOW,
00429         "glw_StdClientWC",
00430         NULL,
00431         WS_OVERLAPPED,
00432         1, 1, 3, 3,
00433         NULL,
00434         NULL,
00435         Instance,
00436         NULL))!=NULL)
00437     {
00438       ShowWindow(global_window,SW_HIDE);
00439 
00440 //      prefs_Init();
00441       glw_Client(client_address,net_GetPort());
00442 //      prefs_CleanUp();
00443 
00444       DestroyWindow(global_window);
00445     }
00446   }
00447 
00448   mem_trace_report();
00449 
00450   debug_End();
00451 
00452   return(0L);
00453 }
00454 
00455 
00456 u32 glw_TimerStart(u32 window, u32 millisec, u32 userdata)
00457 {
00458   struct glw_Timer *timer;
00459   u32 id;
00460 
00461   debug_Begin();
00462 
00463   if(NULL!=(timer=mem_malloc(sizeof(struct glw_Timer))))
00464   {
00465     timer->userdata=userdata;
00466 //    id=SetTimer(global_window,(u32)timer,(UINT)millisec,NULL);
00467 //printf("set timer %ld ms\n",millisec);
00468     id=SetTimer(global_window,(u32)timer,(UINT)millisec,(TIMERPROC)NULL);
00469     timer->id=id;
00470   }
00471 
00472   debug_End();
00473 
00474   return((u32)timer);
00475 }
00476 
00477 
00478 void glw_TimerCancel(u32 window, u32 id)
00479 {
00480   struct glw_Timer *timer=(struct glw_Timer *)id;
00481 
00482   debug_Begin();
00483 
00484   if(timer!=NULL)
00485   {
00486     KillTimer(global_window,timer->id);
00487     mem_free(timer);
00488   }
00489 
00490   debug_End();
00491 }
00492 
00493 
00494 void glw_CloseApp(u32 connection)
00495 {
00496   quit=1;
00497 }

Generated on Tue Jan 7 12:11:21 2003 for THEGUI by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002