static void Add_File_Events(REBGOB *gob, REBINT flags, HDROP drop) { REBEVT evt; REBINT num; REBINT len; REBINT i; REBCHR* buf; POINT xy; //Get the mouse position DragQueryPoint(drop, &xy); evt.type = EVT_DROP_FILE; evt.flags = (u8) (flags | (1<<EVF_HAS_XY)); evt.info = 0; evt.data = xy.x | xy.y<<16; num = DragQueryFile(drop, -1, NULL, 0); for (i = 0; i < num; i++){ len = DragQueryFile(drop, i, NULL, 0); buf = OS_Make(len+1); DragQueryFile(drop, i, buf, len+1); //Reb_Print("DROP: %s", buf); buf[len] = 0; // ?! convert to REBOL format? E.g.: evt.ser = OS_To_REBOL_File(buf, &len); OS_Free(buf); if (!Reb_Event(&evt)) break; // queue is full } }
*/ REBOOL As_OS_Str(REBSER *series, REBCHR **string) /* ** If necessary, convert a string series to Win32 wide-chars. ** (Handy for GOB/TEXT handling). ** If the string series is empty the resulting string is set to NULL ** ** Function returns: ** TRUE - if the resulting string needs to be deallocated by the caller code ** FALSE - if REBOL string is used (no dealloc needed) ** ** Note: REBOL strings are allowed to contain nulls. ** ***********************************************************************/ { int len, n; void *str; wchar_t *wstr; if ((len = RL_Get_String(series, 0, &str)) < 0) { // Latin1 byte string - convert to wide chars len = -len; wstr = OS_Make((len + 1) * sizeof(wchar_t)); for (n = 0; n < len; n++) wstr[n] = (wchar_t)((unsigned char*)str)[n]; wstr[len] = 0; //note: following string needs be deallocated in the code that uses this function *string = (REBCHR*)wstr; return TRUE; } *string = (len == 0) ? NULL : str; //empty string check return FALSE; }
*/ DEVICE_CMD Read_DNS(REBREQ *sock) /* ** Initiate the GetHost request and return immediately. ** Note the temporary results buffer (must be freed later). ** ***********************************************************************/ { void *host; #ifdef HAS_ASYNC_DNS HANDLE handle; #else HOSTENT *he; #endif host = OS_Make(MAXGETHOSTSTRUCT); // be sure to free it #ifdef HAS_ASYNC_DNS if (!GET_FLAG(sock->modes, RST_REVERSE)) // hostname lookup handle = WSAAsyncGetHostByName(Event_Handle, WM_DNS, sock->data, host, MAXGETHOSTSTRUCT); else handle = WSAAsyncGetHostByAddr(Event_Handle, WM_DNS, (char*)&(sock->net.remote_ip), 4, AF_INET, host, MAXGETHOSTSTRUCT); if (handle != 0) { sock->net.host_info = host; sock->handle = handle; return DR_PEND; // keep it on pending list } #else // Use old-style blocking DNS (mainly for testing purposes): if (GET_FLAG(sock->modes, RST_REVERSE)) { he = gethostbyaddr((char*)&sock->net.remote_ip, 4, AF_INET); if (he) { sock->net.host_info = host; //??? sock->data = he->h_name; SET_FLAG(sock->flags, RRF_DONE); return DR_DONE; } } else { he = gethostbyname(sock->data); if (he) { sock->net.host_info = host; // ?? who deallocs? COPY_MEM((char*)&(sock->net.remote_ip), (char *)(*he->h_addr_list), 4); //he->h_length); SET_FLAG(sock->flags, RRF_DONE); return DR_DONE; } } #endif OS_Free(host); sock->net.host_info = 0; sock->error = GET_ERROR; //Signal_Device(sock, EVT_ERROR); return DR_ERROR; // Remove it from pending list }
*/ DEVICE_CMD Read_Clipboard(REBREQ *req) /* ***********************************************************************/ { HANDLE data; REBUNI *cp; REBUNI *bin; REBINT len; req->actual = 0; // If there is no clipboard data: if (!IsClipboardFormatAvailable(CF_UNICODETEXT)) { req->error = 10; return DR_ERROR; } if (!OpenClipboard(NULL)) { req->error = 20; return DR_ERROR; } // Read the UTF-8 data: if ((data = GetClipboardData(CF_UNICODETEXT)) == NULL) { CloseClipboard(); req->error = 30; return DR_ERROR; } cp = GlobalLock(data); if (!cp) { GlobalUnlock(data); CloseClipboard(); req->error = 40; return DR_ERROR; } len = LEN_STR(cp); // wide chars bin = OS_Make((len+1) * sizeof(REBCHR)); COPY_STR(bin, cp, len); GlobalUnlock(data); CloseClipboard(); SET_FLAG(req->flags, RRF_WIDE); req->data = (REBYTE *)bin; req->actual = len * sizeof(REBCHR); return DR_DONE; }
*/ void* rebcmp_create(REBGOB* rootGob, REBGOB* gob) /* ** Create new Compositor instance. ** ***********************************************************************/ { //new compositor struct REBCMP_CTX *ctx = (REBCMP_CTX*)OS_Make(sizeof(REBCMP_CTX)); //shortcuts ctx->Root_Gob = rootGob; ctx->Win_Gob = gob; //------------------------------ //Put backend specific code here //------------------------------ //call resize to init buffer rebcmp_resize_buffer(ctx, gob); return ctx; }
*/ void Open_StdIO(void) /* ** Open REBOL's standard IO device. This same device is used ** by both the host code and the R3 DLL itself. ** ** This must be done before any other initialization is done ** in order to output banners or errors. ** ***********************************************************************/ { CLEARS(&Std_IO_Req); Std_IO_Req.clen = sizeof(Std_IO_Req); Std_IO_Req.device = RDI_STDIO; OS_Do_Device(&Std_IO_Req, RDC_OPEN); if (Std_IO_Req.error) Host_Crash("stdio open"); inbuf = OS_Make(inbuf_len); inbuf[0] = 0; }
*/ REBREQ *OS_Make_Devreq(int device) /* ***********************************************************************/ { REBDEV *dev; REBREQ *req; int size; // Validate device: if (device >= RDI_MAX || !(dev = Devices[device])) return 0; size = dev->req_size ? dev->req_size : sizeof(REBREQ); req = OS_Make(size); CLEARS(req); SET_FLAG(req->flags, RRF_ALLOC); req->clen = size; req->device = device; return req; }
*/ REBCHR *OS_List_Env(void) /* ***********************************************************************/ { REBCHR *env = GetEnvironmentStrings(); REBCNT n, len = 0; REBCHR *str; str = env; while (n = (REBCNT)LEN_STR(str)) { len += n + 1; str = env + len; // next } len++; str = OS_Make(len * sizeof(REBCHR)); MOVE_MEM(str, env, len * sizeof(REBCHR)); FreeEnvironmentStrings(env); return str; }
static REBYTE *Get_Next_Line() { REBYTE *bp = inbuf; REBYTE *out; REBCNT len; // Scan for line terminator or end: for (bp = inbuf; *bp != CR && *bp != LF && *bp != 0; bp++); // If found, copy the line and remove it from buffer: if (*bp) { if (*bp == CR && bp[1] == LF) bp++; len = bp - inbuf; out = OS_Make(len + 2); COPY_BYTES(out, inbuf, len+1); out[len+1] = 0; MOVE_MEM(inbuf, bp+1, 1+strlen(bp+1)); return out; } return 0; // more input needed }
*/ void* rebcmp_create(REBGOB* rootGob, REBGOB* gob) /* ** Create new Compositor instance. ** ***********************************************************************/ { //new compositor struct REBCMP_CTX *ctx = (REBCMP_CTX*)OS_Make(sizeof(REBCMP_CTX)); memset(ctx, 0, sizeof(REBCMP_CTX)); //shortcuts ctx->Root_Gob = rootGob; ctx->Win_Gob = gob; //initialize clipping regions ctx->Win_Clip.x = 0; ctx->Win_Clip.y = 0; ctx->Win_Clip.width = GOB_LOG_W_INT(gob); ctx->Win_Clip.height = GOB_LOG_H_INT(gob); host_window_t *hw = GOB_HWIN(gob); if (hw != NULL) { ctx->host_window = hw; ctx->x_gc = XCreateGC(global_x_info->display, ctx->host_window->x_id, 0, 0); int screen_num = DefaultScreen(global_x_info->display); unsigned long black = BlackPixel(global_x_info->display, screen_num); unsigned long white = WhitePixel(global_x_info->display, screen_num); XSetBackground(global_x_info->display, ctx->x_gc, white); XSetForeground(global_x_info->display, ctx->x_gc, black); } //call resize to init buffer rebcmp_resize_buffer(ctx, gob); return ctx; }
*/ REBOOL rebcmp_resize_buffer(REBCMP_CTX* ctx, REBGOB* winGob) /* ** Resize the window compositing buffer. ** ** Returns TRUE if buffer size was really changed, otherwise FALSE. ** ***********************************************************************/ { //check if window size really changed if ((GOB_LOG_W(winGob) != GOB_WO(winGob)) || (GOB_LOG_H(winGob) != GOB_HO(winGob)) || ctx->pixbuf == NULL) {//ctx might haven't been initialized yet REBINT w = GOB_LOG_W_INT(winGob); REBINT h = GOB_LOG_H_INT(winGob); if (ctx->x_image) { XDestroyImage(ctx->x_image); //frees ctx->pixbuf as well } #ifdef USE_XSHM if (ctx->x_image_back) { XDestroyImage(ctx->x_image_back); //frees ctx->pixbuf as well } if (global_x_info->has_xshm && global_x_info->sys_pixmap_format == pix_format_bgra32) { if (ctx->x_shminfo.shmaddr != NULL) { XShmDetach(global_x_info->display, &ctx->x_shminfo); shmdt(ctx->x_shminfo.shmaddr); //RL_Print("Removing SHM %x\n", ctx->x_shminfo.shmid); shmctl(ctx->x_shminfo.shmid, IPC_RMID, NULL); } ctx->x_image = XShmCreateImage(global_x_info->display, global_x_info->default_visual, global_x_info->default_depth, ZPixmap, 0, &ctx->x_shminfo, w, h); if (ctx->x_image == NULL) { global_x_info->has_xshm = 0; } else { ctx->pixbuf_len = ctx->x_image->bytes_per_line * ctx->x_image->height; ctx->x_shminfo.shmid = shmget(IPC_PRIVATE, ctx->pixbuf_len, IPC_CREAT | 0644 ); //RL_Print("Allocated SHM %x\n", ctx->x_shminfo.shmid); if (ctx->x_shminfo.shmid < 0) { //RL_Print("shmget failed, fallback to non-shm\n"); global_x_info->has_xshm = 0; } else { ctx->pixbuf = ctx->x_shminfo.shmaddr = ctx->x_image->data = (char *)shmat(ctx->x_shminfo.shmid, 0, 0); } if (ctx->pixbuf == NULL) { //RL_Print("shmat failed, fallback to non-shm\n"); global_x_info->has_xshm = 0; //RL_Print("Removing SHM %x\n", ctx->x_shminfo.shmid); shmctl(ctx->x_shminfo.shmid, IPC_RMID, NULL); } else { memset(ctx->pixbuf, 0, ctx->pixbuf_len); ctx->x_shminfo.readOnly = False; XSync(global_x_info->display, False); orig_error_handler = XSetErrorHandler(shm_error_handler); XShmAttach(global_x_info->display, &ctx->x_shminfo); //Bad Access error when talking to a remote X server XSync(global_x_info->display, False); XSetErrorHandler(orig_error_handler); if (!global_x_info->has_xshm) { //RL_Print("XShmAttach failed, fallback to non-shm\n"); XDestroyImage(ctx->x_image); shmdt(ctx->x_shminfo.shmaddr); //RL_Print("Removing SHM %x\n", ctx->x_shminfo.shmid); shmctl(ctx->x_shminfo.shmid, IPC_RMID, NULL); }; } } if (global_x_info->has_xshm) { if (ctx->x_shminfo_back.shmaddr != NULL) { XShmDetach(global_x_info->display, &ctx->x_shminfo_back); shmdt(ctx->x_shminfo_back.shmaddr); //RL_Print("Removing SHM %x\n", ctx->x_shminfo_back.shmid); shmctl(ctx->x_shminfo_back.shmid, IPC_RMID, NULL); } ctx->x_image_back = XShmCreateImage(global_x_info->display, global_x_info->default_visual, global_x_info->default_depth, ZPixmap, 0, &ctx->x_shminfo_back, w, h); assert(ctx->x_image_back != NULL); ctx->x_shminfo_back.shmid = shmget(IPC_PRIVATE, ctx->x_image_back->bytes_per_line * ctx->x_image->height, IPC_CREAT | 0644 ); ctx->x_shminfo_back.shmaddr = ctx->x_image_back->data = (char *)shmat(ctx->x_shminfo_back.shmid, 0, 0); XShmAttach(global_x_info->display, &ctx->x_shminfo_back); //Bad Access error when talking to a remote X server XSync(global_x_info->display, False); } } if (!global_x_info->has_xshm || global_x_info->sys_pixmap_format != pix_format_bgra32) {//fall back to non-xshm version global_x_info->has_xshm = 0; #endif //RL_Print("Non-shm version\n"); ctx->pixbuf_len = w * h * BYTE_PER_PIXEL; //BGRA32; ctx->pixbuf = OS_Make(ctx->pixbuf_len); if (ctx->pixbuf == NULL){ //RL_Print("Allocation of %d bytes memory failed\n", ctx->pixbuf_len); Host_Crash("Not enough memory\n"); } memset(ctx->pixbuf, 0, ctx->pixbuf_len); if (global_x_info->display != NULL) { ctx->x_image = XCreateImage(global_x_info->display, global_x_info->default_visual, global_x_info->default_depth, ZPixmap, 0, ctx->pixbuf, w, h, global_x_info->bpp, w * global_x_info->bpp / 8); } #ifdef USE_XSHM } #endif if (ctx->x_image != NULL) { #ifdef ENDIAN_BIG ctx->x_image->byte_order = MSBFirst; #else ctx->x_image->byte_order = LSBFirst; #endif } //update the buffer size values ctx->winBufSize.x = w; ctx->winBufSize.y = h; //update old gob area GOB_XO(winGob) = GOB_LOG_X(winGob); GOB_YO(winGob) = GOB_LOG_Y(winGob); GOB_WO(winGob) = GOB_LOG_W(winGob); GOB_HO(winGob) = GOB_LOG_H(winGob); return TRUE; } return FALSE; }
*/ RXIEXT int RXD_Text(int cmd, RXIFRM *frm, REBCEC *ctx) /* ** DRAW command dispatcher. ** ***********************************************************************/ { switch (cmd) { case CMD_TEXT_INIT_WORDS: //temp hack - will be removed later text_ext_words = RL_MAP_WORDS(RXA_SERIES(frm,1)); break; case CMD_TEXT_ANTI_ALIAS: rt_anti_alias(ctx->envr, RXA_LOGIC(frm, 1)); break; case CMD_TEXT_BOLD: rt_bold(ctx->envr, RXA_LOGIC(frm, 1)); break; case CMD_TEXT_CARET: { RXIARG val; u32 *words, *w; REBSER *obj; REBCNT type; REBXYF caret, highlightStart, highlightEnd; REBXYF *pcaret = 0, *phighlightStart = 0; obj = RXA_OBJECT(frm, 1); //Reb_Print("RXI_WORDS_OF_OBJECT() called\n"); words = RL_WORDS_OF_OBJECT(obj); //Reb_Print("RXI_WORDS_OF_OBJECT() OK\n"); w = words; while (type = RL_GET_FIELD(obj, w[0], &val)) { // RL_Print("word: %d %d %d\n", w[0],w[1], (REBYTE)w[1]); switch(RL_FIND_WORD(text_ext_words,w[0])) { case W_TEXT_CARET: if (type == RXT_BLOCK){ REBSER* block = val.series; REBINT len = RL_SERIES(block, RXI_SER_TAIL); if (len > 1){ RXIARG pos, elem; if ( RL_GET_VALUE(block, 0, &pos) == RXT_BLOCK && RL_GET_VALUE(block, 1, &elem) == RXT_STRING ){ caret.x = 1 + pos.index; caret.y = 1 + elem.index; pcaret = ⁁ } } } break; case W_TEXT_HIGHLIGHT_START: if (type == RXT_BLOCK){ REBSER* block = val.series; REBINT len = RL_SERIES(block, RXI_SER_TAIL); if (len > 1){ RXIARG pos, elem; if ( RL_GET_VALUE(block, 0, &pos) == RXT_BLOCK && RL_GET_VALUE(block, 1, &elem) == RXT_STRING ){ highlightStart.x = 1 + pos.index; highlightStart.y = 1 + elem.index; phighlightStart = &highlightStart; } } } break; case W_TEXT_HIGHLIGHT_END: if (type == RXT_BLOCK){ REBSER* block = val.series; REBINT len = RL_SERIES(block, RXI_SER_TAIL); if (len > 1){ RXIARG pos, elem; if ( RL_GET_VALUE(block, 0, &pos) == RXT_BLOCK && RL_GET_VALUE(block, 1, &elem) == RXT_STRING ){ highlightEnd.x = 1 + pos.index; highlightEnd.y = 1 + elem.index; } } } break; } w++; } OS_Free(words); rt_caret(ctx->envr, pcaret, phighlightStart, highlightEnd); } break; case CMD_TEXT_CENTER: rt_center(ctx->envr); break; case CMD_TEXT_COLOR: rt_color(ctx->envr, RXA_TUPLE(frm,1) + 1); break; case CMD_TEXT_DROP: rt_drop(ctx->envr, RXA_INT32(frm,1)); break; case CMD_TEXT_FONT: { RXIARG val; u32 *words,*w; REBSER *obj; REBCNT type; REBFNT *font = rt_get_font(ctx->envr); obj = RXA_OBJECT(frm, 1); words = RL_WORDS_OF_OBJECT(obj); w = words; while (type = RL_GET_FIELD(obj, w[0], &val)) { switch(RL_FIND_WORD(text_ext_words,w[0])) { case W_TEXT_NAME: if (type == RXT_STRING){ wchar_t* str; REBCNT gc = TRUE; if (RL_GET_STRING(val.series, 0 , (void*)&str) < 0){ size_t newSize = mbstowcs(NULL, (char*)str, 0) + 1; size_t origsize = strlen((char*)str) + 1; //note: following string will be deallocated by the rich text module wchar_t* wstr = OS_Make(newSize * sizeof( wchar_t )); mbstowcs(wstr, (char*)str, newSize); str = wstr; gc = FALSE; } font->name = str; font->name_gc = gc; } break; case W_TEXT_STYLE: switch(type) { case RXT_WORD: { u32 styleWord = RL_FIND_WORD(text_ext_words,val.int32a); if (styleWord) rt_set_font_styles(font, styleWord); } break; case RXT_BLOCK: { RXIARG styleVal; REBCNT styleType; REBCNT n; u32 styleWord; for (n = 0; styleType = RL_GET_VALUE(val.series, n, &styleVal); n++) { if (styleType == RXT_WORD) { styleWord = RL_FIND_WORD(text_ext_words,styleVal.int32a); if (styleWord) rt_set_font_styles(font, styleWord); } } } break; } break; case W_TEXT_SIZE: if (type == RXT_INTEGER) font->size = val.int64; break; case W_TEXT_COLOR: if (type == RXT_TUPLE) memcpy(font->color,val.bytes + 1 , 4); break; case W_TEXT_OFFSET: if (type == RXT_PAIR) { font->offset_x = val.pair.x; font->offset_y = val.pair.y; } break; case W_TEXT_SPACE: if (type == RXT_PAIR) { font->space_x = val.pair.x; font->space_y = val.pair.y; } break; case W_TEXT_SHADOW: switch(type) { case RXT_PAIR: { font->shadow_x = val.pair.x; font->shadow_y = val.pair.y; } break; case RXT_BLOCK: { RXIARG shadowVal; REBCNT shadowType; REBCNT n; for (n = 0; shadowType = RL_GET_VALUE(val.series, n, &shadowVal); n++) { switch (shadowType) { case RXT_PAIR: font->shadow_x = shadowVal.pair.x; font->shadow_y = shadowVal.pair.y; break; case RXT_TUPLE: memcpy(font->shadow_color,shadowVal.bytes + 1 , 4); break; case RXT_INTEGER: font->shadow_blur = shadowVal.int64; break; } } } break; } break; } w++; } OS_Free(words); rt_font(ctx->envr, font); } break; case CMD_TEXT_ITALIC: rt_italic(ctx->envr, RXA_LOGIC(frm, 1)); break; case CMD_TEXT_LEFT: rt_left(ctx->envr); break; case CMD_TEXT_NEWLINE: rt_newline(ctx->envr, ctx->index + 1); break; case CMD_TEXT_PARA: { RXIARG val; u32 *words,*w; REBSER *obj; REBCNT type; REBPRA *para = rt_get_para(ctx->envr); obj = RXA_OBJECT(frm, 1); words = RL_WORDS_OF_OBJECT(obj); w = words; while (type = RL_GET_FIELD(obj, w[0], &val)) { switch(RL_FIND_WORD(text_ext_words,w[0])) { case W_TEXT_ORIGIN: if (type == RXT_PAIR) { para->origin_x = val.pair.x; para->origin_y = val.pair.y; } break; case W_TEXT_MARGIN: if (type == RXT_PAIR) { para->margin_x = val.pair.x; para->margin_y = val.pair.y; } break; case W_TEXT_INDENT: if (type == RXT_PAIR) { para->indent_x = val.pair.x; para->indent_y = val.pair.y; } break; case W_TEXT_TABS: if (type == RXT_INTEGER) { para->tabs = val.int64; } break; case W_TEXT_WRAPQ: if (type == RXT_LOGIC) { para->wrap = val.int32a; } break; case W_TEXT_SCROLL: if (type == RXT_PAIR) { para->scroll_x = val.pair.x; para->scroll_y = val.pair.y; } break; case W_TEXT_ALIGN: if (type == RXT_WORD) { para->align = RL_FIND_WORD(text_ext_words,val.int32a); } break; case W_TEXT_VALIGN: if (type == RXT_WORD) { para->valign = RL_FIND_WORD(text_ext_words,val.int32a); } break; } w++; } OS_Free(words); rt_para(ctx->envr, para); } break; case CMD_TEXT_RIGHT: rt_right(ctx->envr); break; case CMD_TEXT_SCROLL: rt_scroll(ctx->envr, RXA_PAIR(frm, 1)); break; case CMD_TEXT_SHADOW: rt_shadow(ctx->envr, RXA_PAIR(frm, 1), RXA_TUPLE(frm,2) + 1, RXA_INT32(frm,3)); break; case CMD_TEXT_SIZE: rt_font_size(ctx->envr, RXA_INT32(frm,1)); break; case CMD_TEXT_TEXT: { REBCHR* str; REBCNT gc = TRUE; if (RL_GET_STRING(RXA_SERIES(frm, 1), 0 , (void*)&str) < 0){ size_t newSize = mbstowcs(NULL, (char*)str, 0) + 1; size_t origsize = strlen((char*)str) + 1; //note: following string will be deallocated by the rich text module wchar_t* wstr = OS_Make(newSize * sizeof( wchar_t )); mbstowcs(wstr, (char*)str, newSize); str = (REBCHR*)wstr; gc = FALSE; } rt_text(ctx->envr, str, ctx->index + 2, gc); } break; case CMD_TEXT_UNDERLINE: rt_underline(ctx->envr, RXA_LOGIC(frm, 1)); break; default: return RXR_NO_COMMAND; } return RXR_UNSET; }
*/ DEVICE_CMD Lookup_Socket(REBREQ *sock) /* ** Initiate the GetHost request and return immediately. ** This is very similar to the DNS device. ** The request will pend until the main event handler gets WM_DNS. ** Note the temporary results buffer (must be freed later). ** Note we use the sock->handle for the DNS handle. During use, ** we store the TCP socket in the length field. ** ***********************************************************************/ { #ifdef TO_WIN32 HANDLE handle; #endif HOSTENT *host; #ifdef HAS_ASYNC_DNS // Check if we are polling for completion: if (host = (HOSTENT*)(sock->net.host_info)) { // The windows main event handler will change this when it gets WM_DNS event: if (!GET_FLAG(sock->flags, RRF_DONE)) return DR_PEND; // still waiting CLR_FLAG(sock->flags, RRF_DONE); if (!sock->error) { // Success! host = (HOSTENT*)sock->net.host_info; COPY_MEM((char*)&(sock->net.remote_ip), (char *)(*host->h_addr_list), 4); //he->h_length); Signal_Device(sock, EVT_LOOKUP); } else Signal_Device(sock, EVT_ERROR); OS_Free(host); // free what we allocated earlier sock->socket = sock->length; // Restore TCP socket saved below sock->net.host_info = 0; return DR_DONE; } // Else, make the lookup request: host = OS_Make(MAXGETHOSTSTRUCT); // be sure to free it handle = WSAAsyncGetHostByName(Event_Handle, WM_DNS, sock->data, (char*)host, MAXGETHOSTSTRUCT); if (handle != 0) { sock->net.host_info = host; sock->length = sock->socket; // save TCP socket temporarily sock->handle = handle; return DR_PEND; // keep it on pending list } OS_Free(host); #else // Use old-style blocking DNS (mainly for testing purposes): host = gethostbyname(sock->data); sock->net.host_info = 0; // no allocated data if (host) { COPY_MEM((char*)&(sock->net.remote_ip), (char *)(*host->h_addr_list), 4); //he->h_length); CLR_FLAG(sock->flags, RRF_DONE); Signal_Device(sock, EVT_LOOKUP); return DR_DONE; } #endif sock->error = GET_ERROR; //Signal_Device(sock, EVT_ERROR); return DR_ERROR; // Remove it from pending list }
*/ DEVICE_CMD Open_IO(REBREQ *req) /* ***********************************************************************/ { REBDEV *dev; REBCHR *title = TEXT("REBOL 3 Alpha"); HANDLE win; dev = Devices[req->device]; // Avoid opening the console twice (compare dev and req flags): if (GET_FLAG(dev->flags, RDF_OPEN)) { // Device was opened earlier as null, so req must have that flag: if (GET_FLAG(dev->flags, SF_DEV_NULL)) SET_FLAG(req->modes, RDM_NULL); SET_FLAG(req->flags, RRF_OPEN); return DR_DONE; // Do not do it again } if (!GET_FLAG(req->modes, RDM_NULL)) { // Get the raw stdio handles: Std_Out = GetStdHandle(STD_OUTPUT_HANDLE); Std_Inp = GetStdHandle(STD_INPUT_HANDLE); //Std_Err = GetStdHandle(STD_ERROR_HANDLE); Std_Echo = 0; Redir_Out = (GetFileType(Std_Out) != 0); Redir_Inp = (GetFileType(Std_Inp) != 0); // attach_console(); // merges streams, not good // If output not redirected, open a console: if (!Redir_Out) { if (!AllocConsole()) { req->error = GetLastError(); return DR_ERROR; } SetConsoleTitle(title); // The goof-balls at MS seem to require this: // See: http://support.microsoft.com/kb/124103 Sleep(40); win = FindWindow(NULL, title); // What if more than one open ?! if (win) { SetForegroundWindow(win); BringWindowToTop(win); } // Get the new stdio handles: Std_Out = GetStdHandle(STD_OUTPUT_HANDLE); if (!Redir_Inp) { Std_Inp = GetStdHandle(STD_INPUT_HANDLE); // Make the Win32 console a bit smarter by default: SetConsoleMode(Std_Inp, CONSOLE_MODES); } } Std_Buf = OS_Make(BUF_SIZE * sizeof(REBCHR)); // Handle stdio CTRL-C interrupt: SetConsoleCtrlHandler(Handle_Break, TRUE); } else SET_FLAG(dev->flags, SF_DEV_NULL); SET_FLAG(req->flags, RRF_OPEN); SET_FLAG(dev->flags, RDF_OPEN); return DR_DONE; }