REBOOL Host_Start_Exiting(int *exit_status, int argc, REBCHR **argv) { REBYTE vers[8]; REBINT startup_rc; REBYTE *embedded_script = NULL; REBI64 embedded_size = 0; Host_Lib = &Host_Lib_Init; embedded_script = OS_Read_Embedded(&embedded_size); // !!! Note we may have to free Main_Args.home_dir below after this Parse_Args(argc, argv, &Main_Args); vers[0] = 5; // len RL_Version(&vers[0]); // Must be done before an console I/O can occur. Does not use reb-lib, // so this device should open even if there are other problems. Open_StdIO(); // also sets up interrupt handler // Initialize the REBOL library (reb-lib): if (!CHECK_STRUCT_ALIGN) Host_Crash("Incompatible struct alignment"); if (!Host_Lib) Host_Crash("Missing host lib"); // !!! Second part will become vers[2] < RL_REV on release!!! if (vers[1] != RL_VER || vers[2] != RL_REV) Host_Crash("Incompatible reb-lib DLL"); startup_rc = RL_Init(&Main_Args, Host_Lib); // !!! Not a good abstraction layer here, but Parse_Args may have put // an OS_ALLOC'd string into home_dir, via OS_Get_Current_Dir if (Main_Args.home_dir) OS_FREE(Main_Args.home_dir); if (startup_rc == 1) Host_Crash("Host-lib wrong size"); if (startup_rc == 2) Host_Crash("Host-lib wrong version/checksum"); //Initialize core extension commands Init_Core_Ext(); #ifdef TEST_EXTENSIONS Init_Ext_Test(); #endif #ifdef TO_WINDOWS // no console, we must be the child process if (GetStdHandle(STD_OUTPUT_HANDLE) == 0) { App_Instance = GetModuleHandle(NULL); } #ifdef REB_CORE else //use always the console for R3/core { // GetWindowsLongPtr support 32 & 64 bit windows App_Instance = (HINSTANCE)GetWindowLongPtr(GetConsoleWindow(), GWLP_HINSTANCE); } #else //followinng R3/view code behaviors when compiled as: //-"console app" mode: stdio redirection works but blinking console window during start //-"GUI app" mode stdio redirection doesn't work properly, no blinking console window during start else if (argc > 1) // we have command line args
*/ void Put_Str(REBYTE *buf) /* ** Outputs a null terminated UTF-8 string. ** If buf is larger than StdIO Device allows, error out. ** OS dependent line termination must be done prior to call. ** ** !!! A request should ideally have a way to enforce that it is not ** going to modify the data. We currently require the caller to ** pass us data that could be written to, but "promise not to" ** since it is a RDC_WRITE operation. To stay on the right side ** of the compiler, use a strdup()/free() instead of an m_cast. ** ***********************************************************************/ { /* This function could be called by signal handler and inside of Fetch_Buf */ REBREQ req; memcpy(&req, &Std_IO_Req, sizeof(req)); req.length = LEN_BYTES(buf); req.common.data = buf; req.actual = 0; OS_Do_Device(&req, RDC_WRITE); if (req.error) Host_Crash("stdio write"); }
*/ void Put_Str(REBYTE *buf) /* ** Outputs a null terminated UTF-8 string. ** If buf is larger than StdIO Device allows, error out. ** OS dependent line termination must be done prior to call. ** ***********************************************************************/ { Std_IO_Req.length = strlen(buf); Std_IO_Req.data = (REBYTE*)buf; Std_IO_Req.actual = 0; OS_Do_Device(&Std_IO_Req, RDC_WRITE); if (Std_IO_Req.error) Host_Crash("stdio write"); }
*/ 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_ALLOC_ARRAY(REBYTE, inbuf_len); inbuf[0] = 0; }
*/ 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; }
int main(int argc, char **argv) #endif { REBYTE vers[8]; REBYTE *line; REBINT n; const char *env_always_malloc = NULL; REBYTE *embedded_script = NULL; REBI64 embedded_size = 0; #ifdef TO_WIN32 // In Win32 get args manually: // Fetch the win32 unicoded program arguments: argv = (char **)CommandLineToArgvW(GetCommandLineW(), &argc); #endif Host_Lib = &Host_Lib_Init; env_always_malloc = getenv("R3_ALWAYS_MALLOC"); if (env_always_malloc != NULL) { always_malloc = atoi(env_always_malloc); } embedded_script = OS_Read_Embedded(&embedded_size); Parse_Args(argc, (REBCHR **)argv, &Main_Args); vers[0] = 5; // len RL_Version(&vers[0]); // Must be done before an console I/O can occur. Does not use reb-lib, // so this device should open even if there are other problems. Open_StdIO(); // also sets up interrupt handler // Initialize the REBOL library (reb-lib): if (!CHECK_STRUCT_ALIGN) Host_Crash("Incompatible struct alignment"); if (!Host_Lib) Host_Crash("Missing host lib"); // !!! Second part will become vers[2] < RL_REV on release!!! if (vers[1] != RL_VER || vers[2] != RL_REV) Host_Crash("Incompatible reb-lib DLL"); n = RL_Init(&Main_Args, Host_Lib); if (n == 1) Host_Crash("Host-lib wrong size"); if (n == 2) Host_Crash("Host-lib wrong version/checksum"); //Initialize core extension commands Init_Core_Ext(); #ifdef EXT_LICENSING Init_Licensing_Ext(); #endif //EXT_LICENSING #ifdef TEST_EXTENSIONS Init_Ext_Test(); #endif #ifdef TO_WIN32 // no console, we must be the child process if (GetStdHandle(STD_OUTPUT_HANDLE) == 0) { App_Instance = GetModuleHandle(NULL); } #ifdef REB_CORE else //use always the console for R3/core { // GetWindowsLongPtr support 32 & 64 bit windows App_Instance = (HINSTANCE)GetWindowLongPtr(GetConsoleWindow(), GWLP_HINSTANCE); } #else //followinng R3/view code behaviors when compiled as: //-"console app" mode: stdio redirection works but blinking console window during start //-"GUI app" mode stdio redirection doesn't work properly, no blinking console window during start else if (argc > 1) // we have command line args