iohandler.cc
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:5k
源码类别:

通讯编程

开发平台:

Visual C++

  1. /*
  2.  * Copyright (c) 1993-1994 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *      This product includes software developed by the University of
  16.  *      California, Berkeley and the Network Research Group at
  17.  *      Lawrence Berkeley Laboratory.
  18.  * 4. Neither the name of the University nor of the Laboratory may be used
  19.  *    to endorse or promote products derived from this software without
  20.  *    specific prior written permission.
  21.  *
  22.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  23.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  24.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  25.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  26.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  27.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  28.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  29.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  30.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  31.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  32.  * SUCH DAMAGE.
  33.  */
  34. static const char rcsid[] =
  35.     "@(#) $Header: /cvsroot/otcl-tclcl/tclcl/iohandler.cc,v 1.8 1997/12/25 04:21:40 tecklee Exp $ (LBL)";
  36. #include "tclcl.h"
  37. #include "iohandler.h"
  38. #ifdef WIN32
  39. #include "tk.h"
  40. #include <stdlib.h>
  41. #include <winsock.h>
  42. #endif
  43. #ifdef WIN32
  44. #if TK_MAJOR_VERSION >= 8
  45. extern "C" HINSTANCE Tk_GetHINSTANCE();
  46. #else
  47. extern "C" HINSTANCE TkWinGetAppInstance();
  48. #define Tk_GetHINSTANCE() TkWinGetAppInstance()
  49. #endif
  50. LRESULT CALLBACK
  51. IOHandler::WSocketHandler(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  52. {
  53. IOHandler* p;
  54. switch (message) {
  55. case WM_CREATE:{
  56. CREATESTRUCT *info = (CREATESTRUCT *) lParam;
  57. SetWindowLong(hwnd, GWL_USERDATA, (DWORD)info->lpCreateParams);
  58. return 0;
  59. }
  60. case WM_DESTROY:
  61. return 0;
  62. case WM_WSOCK_READY:
  63. p = (IOHandler *) GetWindowLong(hwnd, GWL_USERDATA);
  64. if (p == NULL) {
  65. fprintf(stderr, "IOHandler: no GWL_USERDATAn");
  66. }
  67. else {
  68. p->dispatch(TK_READABLE);
  69. return 0;
  70. }
  71. break;
  72. }
  73. return DefWindowProc(hwnd, message, wParam, lParam);
  74. }
  75. #endif
  76. #ifdef WIN32
  77. ATOM IOHandler::classAtom_ = 0;
  78. #endif
  79. IOHandler::IOHandler() : fd_(-1)
  80. #ifdef WIN32
  81.     , hwnd_(0)
  82. #endif
  83. {
  84. #ifdef WIN32
  85.         if (0==classAtom_) {    
  86.                 WNDCLASS cl;
  87.                 /*
  88.                  * Register the Message window class.
  89.                  */                
  90.                 cl.style = CS_HREDRAW | CS_VREDRAW;
  91.                 cl.lpfnWndProc = IOHandler::WSocketHandler;
  92.                 cl.cbClsExtra = 0;
  93.                 cl.cbWndExtra = 0;
  94.                 cl.hInstance = Tk_GetHINSTANCE();
  95.                 cl.hIcon = NULL;
  96.                 cl.hCursor = NULL;
  97.                 cl.hbrBackground = NULL;
  98.                 cl.lpszMenuName = NULL;
  99.                 cl.lpszClassName = "TclCLWSocket";
  100.                 classAtom_ = RegisterClass(&cl);
  101.                 if (0==classAtom_) {
  102.                         displayErr("register class WSocket");
  103.                 }                
  104.         }
  105. #endif
  106. }
  107. IOHandler::~IOHandler()
  108. {
  109. if (fd_ >= 0)
  110. unlink();
  111. }
  112. void IOHandler::link(int fd, int mask)
  113. {
  114. fd_ = fd;
  115. #ifdef WIN32
  116. int status;
  117. int flags = 0;
  118. if (TK_READABLE & mask)
  119.   flags |= FD_READ;
  120. if (TK_WRITABLE & mask)
  121.   flags |= FD_WRITE;
  122. hwnd_ = CreateWindow("TclCLWSocket", "",
  123.      WS_POPUP | WS_CLIPCHILDREN,
  124.      CW_USEDEFAULT, CW_USEDEFAULT, 0, 0,
  125.      NULL,
  126.      NULL, Tk_GetHINSTANCE(), this);
  127.         if (hwnd_ == NULL) {
  128.                 displayErr("IOHandler::link() CreateWindow");
  129.                 exit(1);
  130.         }
  131. // ShowWindow(hwnd_, SW_HIDE);
  132.         if ((status = WSAAsyncSelect(fd, hwnd_, WM_WSOCK_READY,
  133.      flags)) > 0) {
  134.                 displayErr("IOHandler::link() WSAAsyncSelect");
  135.                 exit(1);
  136.         }
  137. #elif TCL_MAJOR_VERSION >= 8
  138. Tcl_CreateFileHandler(fd,
  139.       mask, callback, (ClientData)this);
  140. #else
  141. Tcl_CreateFileHandler(Tcl_GetFile((ClientData)fd, TCL_UNIX_FD),
  142.       mask, callback, (ClientData)this);
  143. #endif
  144. }
  145. void IOHandler::unlink()
  146. {
  147. #ifdef WIN32
  148. if (fd_ >= 0 && hwnd_ != 0) {
  149. /* cancel callback */
  150. (void) WSAAsyncSelect(fd_, hwnd_, 0, 0);     
  151. if (hwnd_) {
  152. (void) DestroyWindow(hwnd_);
  153. hwnd_ = 0;
  154. fd_ = -1;
  155. }
  156. }
  157. #else
  158. if (fd_ >= 0) {
  159. #if TCL_MAJOR_VERSION < 8
  160. Tcl_DeleteFileHandler(Tcl_GetFile((ClientData)fd_,
  161.   TCL_UNIX_FD));
  162. #else 
  163. Tcl_DeleteFileHandler(fd_);  
  164. #endif
  165. fd_ = -1;
  166. }
  167. #endif
  168. }
  169. #ifndef WIN32
  170. void IOHandler::callback(ClientData cd, int mask)
  171. {
  172. IOHandler* p = (IOHandler*)cd;
  173. p->dispatch(mask);
  174. }
  175. #endif