📄 ipcsocket.c
字号:
/* Copyright (C) 2004-2005 Li Yudong*//*** This program is free software; you can redistribute it and/or modify** it under the terms of the GNU General Public License as published by** the Free Software Foundation; either version 2 of the License, or** (at your option) any later version.**** This program is distributed in the hope that it will be useful,** but WITHOUT ANY WARRANTY; without even the implied warranty of** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the** GNU General Public License for more details.**** You should have received a copy of the GNU General Public License** along with this program; if not, write to the Free Software** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA*/#include "../include/common.h"#include "../include/socketio.h"#include "../include/blockheap.h"#include "../include/rect.h"#include "../include/invalidregion.h"#include "../include/clipregion.h"#include "../include/message.h"#include "../include/hdc.h"#include "../include/caret.h"#include "../include/winnc.h"#include "../include/winbase.h"#include "../include/window.h"#include "../include/lguiapp.h"#include "../include/socketio.h"#include "../include/ipcsocket.h"#include "../include/mouse.h"extern PWindowsTree _lGUI_pActiveWin;extern PWindowsTree _lGUI_pFocus;extern PlGUIAppStat _lGUI_pAppStat;extern PWindowsTree _lGUI_pWindowsTree;extern WndCaptureMouse _lGUI_wndCaptureMouse;extern PlGUIAppStat _lGUI_pAppStat;extern PWindowsTree _lGUI_pImeWindow;extern PWindowsTree _lGUI_pSkbWindow;//two global variable//listen thread for server//connect thread for clientpthread_t thread_ipcmsg;//identify of listen socket for server//identify of connect socket for clientint _lGUI_fdSocket;void TerminateIpcSocket(){ pthread_cancel(thread_ipcmsg); pthread_join(thread_ipcmsg,NULL);}//thread cleanup function//register to do cleanup work while thread exitvoid cleanup_after_malloc( void* allocated_memory){ if(allocated_memory) free(allocated_memory);}void cleanup_after_opensock( void* fd){ int t; t=*((int*)fd); close(t);}//===============================================================================//****************************Server*********************************************//===============================================================================//Initial listen socket and create thread for serverBOOLInitIpcSocketServer(){ _lGUI_fdSocket=serv_listen(CS_PATH); if(_lGUI_fdSocket<0){ printerror("server socket listen return error!"); return false; } pthread_create(&thread_ipcmsg,NULL,IpcSocketMainLoopServer,(void*)&_lGUI_fdSocket); return true;}//main loop for listen threadvoid* IpcSocketMainLoopServer( void* para){ PlGUIAppStat pStat; int clifd; int fd; fd=*((int*)para); while(1){ pthread_testcancel(); clifd=serv_accept(fd); if(clifd!=-1){ pStat=(PlGUIAppStat)malloc(sizeof(lGUIAppStat)); if(!pStat) continue; memset(pStat,0,sizeof(lGUIAppStat)); pStat->fdSocket = clifd; if(!_lGUI_pAppStat) _lGUI_pAppStat=pStat; else{ pStat->pNext=_lGUI_pAppStat; _lGUI_pAppStat=pStat; } //create socket thread. A thread for a application pthread_create(&(_lGUI_pAppStat->tdSocket),NULL,(void*)ReadMainLoopServer,(void*)&clifd); } }}//Main loop for socket readvoid* ReadMainLoopServer( void* clifd){ void* pData; int iSize; int iRet; int fd; int old_cancel_type; int iMsg; fd=*((int*)clifd); pData=malloc(SIZE_IPC_MSG); if(!pData) pthread_exit(0); //register thread cleanup function pthread_cleanup_push(cleanup_after_malloc,pData); while(1){ //read value of message at first; iRet = sock_read(fd,(void*)&iMsg,sizeof(int)); if(iRet==SOCKERR_CLOSED || iRet==SOCKERR_IO){ //printerror("socket error while reading type of message!"); ProcessIpcMessageServer(fd,LMSG_IPC_DESTROYAPP,NULL,0); pthread_exit(0); } //read the size of added data iRet=sock_read(fd,(void*)&iSize,sizeof(int)); if(iRet==SOCKERR_CLOSED || iRet==SOCKERR_IO){ //printerror("socket error while reading size of message!"); ProcessIpcMessageServer(fd,LMSG_IPC_DESTROYAPP,NULL,0); pthread_exit(0); } //read added data iRet=sock_read(fd,pData,iSize); if(iRet==SOCKERR_CLOSED || iRet==SOCKERR_IO){ //printerror("socket error while reading message!"); ProcessIpcMessageServer(fd,LMSG_IPC_DESTROYAPP,NULL,0); pthread_exit(0); } //process the readed message ProcessIpcMessageServer(fd,iMsg,pData,iSize); } pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED,&old_cancel_type); pthread_cleanup_pop(1); pthread_setcanceltype(old_cancel_type,NULL);}//Process ipc message for sersverBOOL ProcessIpcMessageServer( int fd, int iMsg, void* pAttachData, int iAttachSize){ switch (iMsg){ case LMSG_IPC_CREATEAPP: //create application CreateApplicationServer(fd, pAttachData, iAttachSize); break; case LMSG_IPC_DESTROYAPP: //if two thread a and b are siblings.thread a can not // wait on any processes forked by thread b // so i have to send a notify message to main thread //Destroy application SendNotifyMessage((HWND)_lGUI_pWindowsTree,LMSG_IPC_DESTROYAPP,(WPARAM)fd,(LPARAM)NULL); //DestroyApplicationServer(fd, pAttachData, iAttachSize); break; case LMSG_IPC_SHOWMAINWIN: //Show Main Window ShowMainWinServer(fd, pAttachData, iAttachSize); break; case LMSG_IPC_HIDEMAINWIN: //Hide Main Window HideMainWinServer(fd, pAttachData, iAttachSize); break; } return true;}BOOL CreateApplicationServer( int fd, void* pAttachData, int iAttachSize){ PlGUIAppStat pStat; PlGUIAppStat pCurStat; pStat = _lGUI_pAppStat; if(!pStat) return false; while(pStat){ if(pStat->fdSocket == fd) break; pStat = pStat->pNext; } if(!pStat) return false; pCurStat = (PlGUIAppStat)pAttachData; if(!pCurStat) return false; strcpy(pStat->pAppName,pCurStat->pAppName); CopyRect(&(pStat->rc),&(pCurStat->rc)); pStat->bVisible=false;//it's invisible before show operate //init clip area pStat->pClipRgn=(PClipRegion)malloc(sizeof(ClipRegion)); if(!(pStat->pClipRgn)) return false; memset(pStat->pClipRgn,0,sizeof(ClipRegion)); InitClipRegion(pStat->pClipRgn); return true;}//Destroy an application//socket id// pAttachData iAttachSize no used BOOL DestroyApplicationServer( int fd, void* pAttachData, int iAttachSize){ PWindowsTree pControl; PlGUIAppStat pStat,pCurStat,pPrevStat=NULL; int status; BOOL bTop=false; pStat = _lGUI_pAppStat; if(!pStat) return false; while(pStat){ if(pStat->fdSocket==fd){ break; } pPrevStat=pStat; pStat=pStat->pNext; } if(!pStat){ return false; } if(pStat == _lGUI_pAppStat){ bTop = true; _lGUI_pAppStat = _lGUI_pAppStat->pNext; } else pPrevStat->pNext = pStat->pNext; //wait to clean the child process image in kernal //otherwise the child process will become to be a defunct process //pthread_cancel(pStat->tdSocket); //pthread_join(pStat->tdSocket,NULL); waitpid((pid_t)((atoi)(pStat->pAppName)),&status,0); if(pStat->bVisible){//only if this application is visible if(pStat->pNext){ //recalculate clip region of mainwindow under the current RecalClipRgnUnderThis(pStat->pNext); //send clip region change message to application pCurStat=pStat->pNext; while(pCurStat){ SendClipRgnChangeMsg(pCurStat); pCurStat=pCurStat->pNext; } //if this application is at top layer // then we should active the nearest application under it if(bTop){ SendMsgByServer(_lGUI_pAppStat,LMSG_IPC_ACTIVEAPP,NULL,0); } //send redraw message to application pCurStat=pStat->pNext; while(pCurStat){ SendMsgByServer(pCurStat,LMSG_IPC_REDRAW,(void*)&(pStat->rc),sizeof(RECT)); pCurStat=pCurStat->pNext; } } //recalculate clip region of desktop ReCalClipRegion(_lGUI_pWindowsTree); //recalculate clip region of desktop control pControl=_lGUI_pWindowsTree->pControlHead; while(pControl){ ReCalClipRegion(pControl); pControl=pControl->pNext; } //redraw desktop scrInvalidateRect((HWND)_lGUI_pWindowsTree,&(pStat->rc),true); //redraw desktop control pControl=_lGUI_pWindowsTree->pControlHead; while(pControl){ if(IsVisible(pControl)) scrInvalidateRect((HWND)pControl,&(pStat->rc),true); pControl=pControl->pNext; } //if all of application have been destroyed,we should active desktop. if(!_lGUI_pAppStat){ ActiveWindow(_lGUI_pWindowsTree); } } //destroy the application EmptyClipRegion(pStat->pClipRgn); free(pStat->pClipRgn); free(pStat); return true;}//Show Main Window//para:// socket id// pAttachData iAttachSize no used BOOL ShowMainWinServer( int fd, void* pAttachData, int iAttachSize){ PlGUIAppStat pStat,pCurStat,pPrevStat,pThisStat,pActiveStat; PWindowsTree pControl; RECT rect; if(IsActive((HWND)_lGUI_pWindowsTree)){//if desktop is active pActiveStat = NULL; } else{ pStat=_lGUI_pAppStat; while(pStat){ if(pStat->bVisible) break; pStat = pStat->pNext; } pActiveStat = pStat; } pStat = _lGUI_pAppStat; pPrevStat = _lGUI_pAppStat; while(pStat){ if(pStat->fdSocket==fd) break; pPrevStat = pStat; pStat=pStat->pNext; } if(!pStat) return false; //Move this main window node to top if(pStat!=_lGUI_pAppStat){ pThisStat = pStat->pNext; pPrevStat->pNext = pStat->pNext; pStat->pNext = _lGUI_pAppStat; _lGUI_pAppStat = pStat; } else pThisStat = NULL; pStat->bVisible=true; //clipped by desktop rect GetWindowRect((HWND)_lGUI_pWindowsTree,&rect); IntersectRect(&(pStat->rc),&(pStat->rc),&rect); //Initial the clip region SetInitRectClipRegion (pStat->pClipRgn, &(pStat->rc)); //clipped by imewin and skbwin to generate initial clip region if(IsVisible((HWND)_lGUI_pImeWindow)) SubtractClipRegion(pStat->pClipRgn,&_lGUI_pImeWindow->rect); if(IsVisible((HWND)_lGUI_pSkbWindow)) SubtractClipRegion(pStat->pClipRgn,&_lGUI_pSkbWindow->rect); //clip region of all main window under this will change. pCurStat=_lGUI_pAppStat->pNext; while(pCurStat!= pThisStat){ if(IsIntersect(&(pCurStat->pClipRgn->rcBound),&(pStat->rc))){ SubtractClipRegion (pCurStat->pClipRgn, &(pStat->rc)); //send clipregion change message to application if(pCurStat->bVisible) SendClipRgnChangeMsg(pCurStat); } pCurStat = pCurStat->pNext; } //send disactive message to the top application before. if(pActiveStat){ SendMsgByServer(pActiveStat,LMSG_IPC_DISACTIVEAPP,NULL,0); } //calculate clipregion of desktop SubtractClipRegion(_lGUI_pWindowsTree->pClipRgn,&(pStat->rc)); //calculate clip region of desktop control pControl=_lGUI_pWindowsTree->pControlHead; while(pControl){ SubtractClipRegion(pControl->pClipRgn,&(pStat->rc)); pControl=pControl->pNext; } //send confirm message to the new generated application SendShowMainWinAnsToClient(_lGUI_pAppStat); return true;}//send new generaged clip region to confirm the client waitting process//the content sent by this message is same like send clip change messagevoid SendShowMainWinAnsToClient( PlGUIAppStat pStat){ PClipRect pHead,pTail; char* pAttachData; int iAttachSize; char* pCurPointer; int iCount; pHead=pStat->pClipRgn->pHead; pTail=pStat->pClipRgn->pTail; if(!pHead) iCount=0; else{ iCount=1; while(pHead!=pTail){ iCount++; pHead=pHead->pNext; } } if(iCount){ iAttachSize=iCount*sizeof(RECT); pAttachData=malloc(iAttachSize); pCurPointer=pAttachData; pHead=pStat->pClipRgn->pHead; while(pHead){ memcpy((void*)pCurPointer,&(pHead->rect),sizeof(RECT)); pCurPointer+=sizeof(RECT); pHead=pHead->pNext; } SendMsgByServer(pStat,LMSG_IPC_SHOWMAINWIN_ANS,pAttachData,iAttachSize); free(pAttachData); }}//Hide main window//Param// socket id// pAttachData iAttachSize no used BOOL HideMainWinServer( int fd, void* pAttachData, int iAttachSize){ PlGUIAppStat pStat,pCurStat; PWindowsTree pControl; pStat=_lGUI_pAppStat; while(pStat){ if(pStat->fdSocket==fd) break; pStat=pStat->pNext; } if(!pStat) return false; pStat->bVisible=false; ReCalClipRegion(_lGUI_pWindowsTree); InvalidateRect((HWND)_lGUI_pWindowsTree,NULL,true); pControl=_lGUI_pWindowsTree->pControlHead; while(pControl){ ReCalClipRegion(pControl); pControl=pControl->pNext; } pControl=_lGUI_pWindowsTree->pControlHead; while(pControl){ scrInvalidateRect((HWND)pControl,NULL,true); pControl=pControl->pNext; } RecalClipRgnUnderThis(pStat->pNext); pCurStat=pStat->pNext; while(pCurStat){ SendClipRgnChangeMsg(pCurStat); pCurStat=pCurStat->pNext; } pCurStat=pStat->pNext; while(pCurStat){ SendMsgByServer(pCurStat,LMSG_IPC_REDRAW,(void*)&(pStat->rc),sizeof(RECT)); pCurStat=pCurStat->pNext; } return true;}//send message to client//parameter://1. application description pointer//2. message type//3. message added data//4. size of added message dataBOOL SendMsgByServer( PlGUIAppStat pStat, int iMsg, void* pAttachData, int iAttachSize){ if(!pStat->fdSocket) return false; //send message value sock_write(pStat->fdSocket,(void*)&iMsg,sizeof(int)); //send size of added data sock_write(pStat->fdSocket,(void*)&iAttachSize,sizeof(int)); if(pAttachData && iAttachSize) //send added data sock_write(pStat->fdSocket,pAttachData,iAttachSize); return true;}//send clip region change message void SendClipRgnChangeMsg( PlGUIAppStat pStat){ PClipRect pHead,pTail; char* pAttachData; int iAttachSize; char* pCurPointer; int iCount; pHead=pStat->pClipRgn->pHead; pTail=pStat->pClipRgn->pTail; if(!pHead) iCount=0; else{ iCount=1; while(pHead!=pTail){ iCount++; pHead=pHead->pNext; } } if(iCount){ iAttachSize=iCount*sizeof(RECT); pAttachData=malloc(iAttachSize); pCurPointer=pAttachData; pHead=pStat->pClipRgn->pHead; while(pHead){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -