// USER int emulator::run(char const *prg_name, char const *args, int *ret_ptr, int stack_size) { DEBUG(3) dprintf("emulator::run() called. this=%p, prg_name='%s', args='%s', ret_ptr=%p, stack_size=%d\n", this, prg_name, args, ret_ptr, stack_size); int retc; context *ctx = getContext(); if(!ctx) return ENOMEM; retc = ctx->init_run(prg_name, args, stack_size); if(retc) { deleteContext(ctx); return retc; } message *msg = new message(ctx); if(!msg) { deleteContext(ctx); return ENOMEM; } msg->setCmd(message::RUN_CMD); msg->sendToEmulator(); doEvents(ctx); delete msg; retc = ctx->getRetVal(); deleteContext(ctx); return retc; }
/* If this function is NULL, polling is not needed */ static int GSDLLCALL gsdll_poll(void *handle) { EventRecord eventStructure; while (WaitNextEvent(everyEvent, &eventStructure, 0, NULL)) doEvents(&eventStructure); return (gDone ? e_Fatal : 0); }
void MinecraftDynmapProto::EventsLoop(void *) { ScopedLock s(events_loop_lock_); time_t tim = ::time(NULL); debugLogA(">>>>> Entering %s[%d]", __FUNCTION__, tim); while (doEvents()) { if (!isOnline()) break; if (WaitForSingleObjectEx(events_loop_event_, m_updateRate, true) != WAIT_TIMEOUT) // FIXME: correct timeout break; debugLogA("***** %s[%d] refreshing...", __FUNCTION__, tim); } ResetEvent(events_loop_event_); ResetEvent(events_loop_lock_); debugLogA("<<<<< Exiting %s[%d]", __FUNCTION__, tim); }
int main ( int argc, char *argv[] ) { struct RDArgs *rda = NULL; ULONG sigs; globalEvents = -1; globalCurrentTool = LUNA_TOOL_BRUSH; // Init brush brushTool.antialias = TRUE; // TODO: load from config set toolbox cycle! brushTool.width = 1; brushTool.height = 1; brushTool.feather = TRUE; // TODO: load from config and set toolbox cycle! // Set the colors prevColor = 0; currColor = 0; globalColor = 0; BOOL keyIsDown = FALSE; keyboardEnabled = TRUE; // Starts up the application #ifdef __amigaos4__ MUIMasterBase = OpenLibrary("muimaster.library", 0); if (!MUIMasterBase) { printf("Error opening muimaster library\n"); exit(0); }; IMUIMaster = (struct MUIMasterIFace *) GetInterface(MUIMasterBase, "main", 1, NULL); if (!MUIMasterBase && !IMUIMaster) { printf("Error opening muimaster library\n"); exit(0); }; CyberGfxBase = OpenLibrary("cybergraphics.library", 0); if (!CyberGfxBase) { printf("Error opening cybergraphics library\n"); exit(0); }; ICyberGfx = (struct CyberGfxIFace *) GetInterface(CyberGfxBase, "main", 1, NULL); if (!CyberGfxBase && !ICyberGfx) { printf("Error opening muimaster library\n"); exit(0); }; #endif struct MsgPort *port; Forbid(); port = FindPort("LUNAPAINT"); Permit(); if ( port == NULL) { Locale_Initialize(); Init_Application ( ); } else { // Double Start // TODO: open projects when clicking on icons from there goto quit; } if (argc) { IPTR args[ ARG_CNT ] = {0}; rda = ReadArgs ( ARG_TEMPLATE, args, NULL ); if ( ! rda ) { PrintFault( IoErr ( ), argv[0] ); goto exit; } if ( args[ARG_FILE] ) { STRPTR *file = (STRPTR *)args[ARG_FILE]; while ( *file ) { LoadProject ( *file, FALSE ); file++; } } } // Main loop while ( getSignals ( &sigs ) ) { // Check for signals from GUI if ( checkSignalBreak ( &sigs ) ) break; if ( keyboardEnabled ) { // Execute keyboard events on key press if ( evalRawKey >= IECODE_ASCII_FIRST && evalRawKey < IECODE_ASCII_LAST ) { if ( !keyIsDown ) { keyIsDown = TRUE; checkKeyboardShortcuts ( evalRawKey ); } } } // We always register keyup strokes if ( evalRawKey & IECODE_UP_PREFIX ) keyIsDown = FALSE; // Execute pending events if ( globalActiveWindow && globalActiveCanvas ) doEvents ( ); // Reset events globalEvents = -1; // Mouse clicks if ( mouseClickCount > 0 ) mouseClickCount--; // Delayed canvas redraw if ( redrawTimes == 1 ) { if ( globalActiveWindow ) DoMethod ( globalActiveWindow->area, MUIM_Draw ); redrawTimes--; } if ( redrawTimes > 0 ) redrawTimes--; } // Exists the application and cleans up reserved resources exit: Exit_Application ( ); Locale_Deinitialize(); #ifdef __amigaos4__ if(MUIMasterBase && IMUIMaster) DropInterface((struct Interface *)IMUIMaster); if (MUIMasterBase) CloseLibrary(MUIMasterBase); if(CyberGfxBase && ICyberGfx) DropInterface((struct Interface *)ICyberGfx); if(CyberGfxBase) CloseLibrary(CyberGfxBase); #endif if (rda) FreeArgs(rda); quit: return 0; }
int __stdcall EnumMutex2(_CollectionPtr *pColl, void* doEventsCallback){ int cnt=0; char buf[600]; NTSTATUS rv; vbCallback doEvents = (vbCallback)doEventsCallback; if(pColl==0 || *pColl == 0) return -4; EnablePrivilege(SE_DEBUG_NAME); HMODULE hNtDll = LoadLibrary(TEXT("ntdll.dll")); if (!hNtDll) return -1; PZWQUERYSYSTEMINFORMATION ZwQuerySystemInformation = (PZWQUERYSYSTEMINFORMATION)GetProcAddress(hNtDll, "ZwQuerySystemInformation"); PZWDUPLICATEOBJECT ZwDuplicateObject = (PZWDUPLICATEOBJECT)GetProcAddress(hNtDll, "ZwDuplicateObject"); PZWQUERYOBJECT ZwQueryObject = (PZWQUERYOBJECT)GetProcAddress(hNtDll, "ZwQueryObject"); if( (int)ZwQuerySystemInformation == 0 || (int)ZwDuplicateObject == 0 || (int)ZwQueryObject == 0) return -2; ULONG n = 0x1000; PULONG p = new ULONG[n]; while (ZwQuerySystemInformation(SystemHandleInformation, p, n * sizeof *p, 0) == STATUS_INFO_LENGTH_MISMATCH){ delete [] p; p = new ULONG[n *= 2]; } PSYSTEM_HANDLE_INFORMATION h = PSYSTEM_HANDLE_INFORMATION(p + 1); for (ULONG i = 0; i < *p; i++){ HANDLE hObject = 0; OBJECT_BASIC_INFORMATION obi; HANDLE hProcess = OpenProcess(PROCESS_DUP_HANDLE, FALSE, h[i].ProcessId); if(hProcess == 0) continue; //kept getting NtClose was called on a handle that was protected from close via NtSetInformationObject. //also this is much faster by eliminating the DUPLICATE_SAME_ATTRIBUTES flag..no need to use the doevents callback? if (ZwDuplicateObject(hProcess, HANDLE(h[i].Handle), NtCurrentProcess(), &hObject, 0, 0, /*DUPLICATE_SAME_ATTRIBUTES*/ NULL)!= STATUS_SUCCESS) continue; rv = ZwQueryObject(hObject, ObjectBasicInformation, &obi, sizeof obi, &n); if(!NT_SUCCESS(rv)) continue; n = obi.TypeInformationLength + 2; POBJECT_TYPE_INFORMATION oti = POBJECT_TYPE_INFORMATION(new CHAR[n]); rv = ZwQueryObject(hObject, ObjectTypeInformation, oti, n, &n); if(!NT_SUCCESS(rv)) continue; if(oti[0].Name.Length > 0 && wcscmp(oti[0].Name.Buffer,L"Mutant")==0){ n = obi.NameInformationLength == 0 ? MAX_PATH * sizeof (WCHAR) : obi.NameInformationLength; POBJECT_NAME_INFORMATION oni = POBJECT_NAME_INFORMATION(new CHAR[n]); rv = ZwQueryObject(hObject, ObjectNameInformation, oni, n, &n); if (NT_SUCCESS(rv)){ if(oni[0].Name.Length > 0){ _snprintf(buf, sizeof(buf)-1, "%ld %ls", h[i].ProcessId, oni[0].Name.Buffer); addStr(*pColl,buf); cnt++; } } } //_snprintf(buf, sizeof(buf), "i=%d hObject=%x hProcess=%x\r\n",i,hObject,hProcess); //OutputDebugString(buf); if( (int)doEvents != 0 && i > 0 && i%5 == 0 ) doEvents(""); if(hObject !=0) CloseHandle(hObject); if(hProcess!=0) CloseHandle(hProcess); } delete [] p; return cnt; }
int main() { // creates a window and GLES context if (makeContext() != 0) exit(-1); // all the shaders have at least texture unit 0 active so // activate it now and leave it active glActiveTexture(GL_TEXTURE0); flareTex = loadPNG("resources/textures/cloud.png"); width = getDisplayWidth(); height = getDisplayHeight(); glViewport(0, 0, getDisplayWidth(), getDisplayHeight()); // initialises glprint's matrix, shader and texture initGlPrint(getDisplayWidth(), getDisplayHeight()); font1=createFont("resources/textures/font.png",0,256,16,16,16); initSprite(getDisplayWidth(), getDisplayHeight()); fileid = 0; loadfile(); for (int i=0; i<max_flares; i++) { flares[i].x=rand_range(0,getDisplayWidth()); flares[i].y=rand_range(0,getDisplayHeight()); flares[i].vx=rand_range(0,10)-5; flares[i].vy=rand_range(0,10)-5; } /*for (int i=0; i<max_targets; i++) { targets[i].x=rand_range(0,getDisplayWidth()); targets[i].y=rand_range(0,getDisplayHeight()); targets[i].flares = 0; }*/ /*for (int i=0; i<max_flares; i++) { flares[i].x=rand_range(0,getDisplayWidth()); flares[i].y=rand_range(0,getDisplayHeight()); flares[i].vx=rand_range(0,10)-5; flares[i].vy=rand_range(0,10)-5; flares[i].target = (int)rand_range(0,max_targets); targets[flares[i].target].flares ++; }*/ // we don't want to draw the back of triangles // the blending is set up for glprint but disabled // while not in use glCullFace(GL_BACK); glEnable(GL_CULL_FACE); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); glDisable(GL_DEPTH_TEST); glClearColor(0, 0.5, 1, 1); // count each frame int num_frames = 0; // set to true to leave main loop bool quit = false; // get a pointer to the key down array keys = getKeys(); int* mouse = getMouse(); while (!quit) { // the main loop doEvents(); // update mouse and key arrays if (keys[KEY_ESC]) quit = true; // exit if escape key pressed if (keys[KEY_SPACE]) relocate_targets(); // exit if escape key pressed if (keys[KEY_RETURN]) reassign_flares(); // exit if escape key pressed if (keys[KEY_S] && !lastkeys[KEY_S]) save(); // exit if escape key pressed if (keys[KEY_CURSL] && !lastkeys[KEY_CURSL]){ fileid--; if (fileid <0) fileid = 0; loadfile(); // exit if escape key pressed } if (keys[KEY_CURSR] && !lastkeys[KEY_CURSR]){ fileid++; loadfile(); // exit if escape key pressed } if (keys[KEY_C]){ max_targets = 1; // exit if escape key pressed reassign_flares(); } lastkeys[KEY_S] = keys[KEY_S]; lastkeys[KEY_CURSL] = keys[KEY_CURSL]; lastkeys[KEY_CURSR] = keys[KEY_CURSR]; mx = mouse[0]; my = mouse[1]; if(mouse[2] != 0){ spawn_target(mx,my); } for (int i=0; i<RE_MULTIPLY; i++){ random_events(); } think(); render(); // the render loop usleep(1600); // no need to run cpu/gpu full tilt } closeContext(); // tidy up return 0; }
int main() { lightDir.x=0.5; lightDir.y=.7; lightDir.z=-0.5; kmVec3Normalize(&lightDir,&lightDir); // creates a window and GLES context if (makeContext() != 0) exit(-1); // all the shaders have at least texture unit 0 active so // activate it now and leave it active glActiveTexture(GL_TEXTURE0); // The obj shapes and their textures are loaded cubeTex = loadPNG("resources/textures/dice.png"); loadObj(&cubeObj, "resources/models/cube.gbo", "resources/shaders/textured.vert", "resources/shaders/textured.frag"); shipTex = loadPNG("resources/textures/shipv2.png"); loadObjCopyShader(&shipObj,"resources/models/ship.gbo",&cubeObj); alienTex = loadPNG("resources/textures/alien.png"); loadObjCopyShader(&alienObj, "resources/models/alien.gbo", &cubeObj); shotTex = loadPNG("resources/textures/shot.png"); loadObjCopyShader(&shotObj, "resources/models/shot.gbo", &cubeObj); expTex = loadPNG("resources/textures/explosion.png"); playerPos.x = 0; playerPos.y = 0; playerPos.z = 0; kmMat4Identity(&view); pEye.x = 0; pEye.y = 2; pEye.z = 4; pCenter.x = 0; pCenter.y = 0; pCenter.z = -5; pUp.x = 0; pUp.y = 1; pUp.z = 0; kmMat4LookAt(&view, &pEye, &pCenter, &pUp); // projection matrix, as distance increases // the way the model is drawn is effected kmMat4Identity(&projection); kmMat4PerspectiveProjection(&projection, 45, (float)getDisplayWidth() / getDisplayHeight(), 0.1, 100); glViewport(0, 0, getDisplayWidth(), getDisplayHeight()); // these two matrices are pre combined for use with each model render kmMat4Assign(&vp, &projection); kmMat4Multiply(&vp, &vp, &view); // initialises glprint's matrix shader and texture initGlPrint(getDisplayWidth(), getDisplayHeight()); font1=createFont("resources/textures/font.png",0,256,16,16,16); font2=createFont("resources/textures/bigfont.png",32,512,9.5,32,48); glCullFace(GL_BACK); glEnable(GL_CULL_FACE); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDisable(GL_BLEND); // only used by glprintf glEnable(GL_DEPTH_TEST); struct timeval t, ta, t1, t2; // fps stuff gettimeofday(&t1, NULL); int num_frames = 0; bool quit = false; mouse = getMouse(); keys = getKeys(); resetAliens(); for (int n = 0; n < MAX_PLAYER_SHOTS; n++) { playerShots[n].alive = false; } initPointClouds("resources/shaders/particle.vert", "resources/shaders/particle.frag",(float)getDisplayWidth()/24.0); for (int n = 0; n < MAX_ALIENS; n++) { aliens[n].explosion=createPointCloud(40); resetExposion(aliens[n].explosion); // sets initials positions } while (!quit) { // the main loop doEvents(); // update mouse and key arrays // mask of 4 is right mouse if (keys[KEY_ESC]) quit = true; glClearColor(0, .5, 1, 1); // render between two gettimeofday calls so // we can sleep long enough to roughly sync // to ~60fps but not on the pi! // TODO find something a tad more elegent long i; gettimeofday(&t, NULL); i = t.tv_sec * 1e6 + t.tv_usec; // render(); float rad; // radians rotation based on frame counter glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); frame++; rad = frame * (0.0175f * 2); kmMat4Identity(&model); kmMat4Translation(&model, playerPos.x, playerPos.y, playerPos.z); playerCroll += (PIDcal(playerRoll, playerCroll, &playerPre_error, &playerIntegral) / 2); kmMat4RotationPitchYawRoll(&model, 0, 3.1416, playerCroll * 3); // kmMat4Assign(&mvp, &vp); kmMat4Multiply(&mvp, &mvp, &model); kmMat4Assign(&mv, &view); kmMat4Multiply(&mv, &mv, &model); glBindTexture(GL_TEXTURE_2D, shipTex); drawObj(&shipObj, &mvp, &mv, lightDir, viewDir); glPrintf(50 + sinf(rad) * 16, 240 + cosf(rad) * 16, font2,"frame=%i fps=%3.2f", frame, lfps); kmVec3 tmp; playerFireCount--; if (keys[KEY_LCTRL] && playerFireCount < 0) { struct playerShot_t *freeShot; freeShot = getFreeShot(); if (freeShot != 0) { playerFireCount = 15; freeShot->alive = true; kmVec3Assign(&freeShot->pos, &playerPos); } } for (int n = 0; n < MAX_PLAYER_SHOTS; n++) { if (playerShots[n].alive) { playerShots[n].pos.z -= .08; if (playerShots[n].pos.z < -10) playerShots[n].alive = false; kmMat4Identity(&model); kmMat4Translation(&model, playerShots[n].pos.x, playerShots[n].pos.y, playerShots[n].pos.z); kmMat4RotationPitchYawRoll(&model, rad * 4, 0, -rad * 4); kmMat4Assign(&mvp, &vp); kmMat4Multiply(&mvp, &mvp, &model); kmMat4Assign(&mv, &view); kmMat4Multiply(&mv, &mv, &model); glBindTexture(GL_TEXTURE_2D, shotTex); drawObj(&shotObj, &mvp, &mv, lightDir, viewDir); } } playerRoll = 0; if (keys[KEY_CURSL] && playerPos.x > -10) { playerPos.x -= 0.1; playerRoll = .2; } if (keys[KEY_CURSR] && playerPos.x < 10) { playerPos.x += 0.1; playerRoll = -.2; } pEye.x = playerPos.x * 1.25; pCenter.x = playerPos.x; pCenter.y = playerPos.y + 1; pCenter.z = playerPos.z; int deadAliens; deadAliens = 0; for (int n = 0; n < MAX_ALIENS; n++) { if (aliens[n].alive == true) { kmMat4Identity(&model); kmMat4Translation(&model, aliens[n].pos.x, aliens[n].pos.y, aliens[n].pos.z); kmMat4RotationPitchYawRoll(&model, -.4, 0, 0); kmMat4Assign(&mvp, &vp); kmMat4Multiply(&mvp, &mvp, &model); kmMat4Assign(&mv, &view); kmMat4Multiply(&mv, &mv, &model); glBindTexture(GL_TEXTURE_2D, alienTex); drawObj(&alienObj, &mvp, &mv, lightDir, viewDir); kmVec3 d; for (int i = 0; i < MAX_PLAYER_SHOTS; i++) { kmVec3Subtract(&d, &aliens[n].pos, &playerShots[i].pos); if (kmVec3Length(&d) < .7 && playerShots[i].alive) { aliens[n].alive = false; playerShots[i].alive = false; aliens[n].exploding = true; resetExposion(aliens[n].explosion); } } } if (aliens[n].alive != true && aliens[n].exploding != true) { deadAliens++; } } if (deadAliens == MAX_ALIENS) { resetAliens(); } // draw explosions after ALL aliens for (int n = 0; n < MAX_ALIENS; n++) { if (aliens[n].exploding==true) { kmMat4Identity(&model); kmMat4Translation(&model, aliens[n].pos.x, aliens[n].pos.y, aliens[n].pos.z); kmMat4Assign(&mvp, &vp); kmMat4Multiply(&mvp, &mvp, &model); glBindTexture(GL_TEXTURE_2D, expTex); drawPointCloud(aliens[n].explosion, &mvp); aliens[n].explosion->tick=aliens[n].explosion->tick+0.05; if (aliens[n].explosion->tick>1.25) { aliens[n].exploding=false; } else { // update the explosion for (int i=0; i<aliens[n].explosion->totalPoints; i++) { float t; t=aliens[n].explosion->tick; if (i>aliens[n].explosion->totalPoints/2) t=t/2.0; aliens[n].explosion->pos[i*3]=aliens[n].explosion->vel[i*3] * t; aliens[n].explosion->pos[i*3+1]=aliens[n].explosion->vel[i*3+1] * t; aliens[n].explosion->pos[i*3+2]=aliens[n].explosion->vel[i*3+2] * t; } } } } // move camera kmMat4LookAt(&view, &pEye, &pCenter, &pUp); kmMat4Assign(&vp, &projection); kmMat4Multiply(&vp, &vp, &view); kmVec3Subtract(&viewDir,&pEye,&pCenter); kmVec3Normalize(&viewDir,&viewDir); // dump values glPrintf(100, 280, font1,"eye %3.2f %3.2f %3.2f ", pEye.x, pEye.y, pEye.z); glPrintf(100, 296, font1,"centre %3.2f %3.2f %3.2f ", pCenter.x, pCenter.y, pCenter.z); glPrintf(100, 320, font1,"mouse %i,%i %i ", mouse[0], mouse[1], mouse[2]); glPrintf(100, 340, font1,"frame %i %i ", frame, frame % 20); swapBuffers(); gettimeofday(&ta, NULL); long j = (ta.tv_sec * 1e6 + ta.tv_usec); i = j - i; if (i < 0) i = 1000000; // pass through - slower that 60fps if (i < 16000) usleep(16000 - i); // every 10 frames average the time taken and store // fps value for later printing with glprintf if (++num_frames % 10 == 0) { gettimeofday(&t2, NULL); float dtf = t2.tv_sec - t1.tv_sec + (t2.tv_usec - t1.tv_usec) * 1e-6; lfps = num_frames / dtf; num_frames = 0; t1 = t2; } } closeContext(); return 0; }
void main(void) { int code; int exit_code; int argc; char **argv; char dformat[64], ddevice[32]; SInt32 response; /* Initialize operating environment */ #if TARGET_API_MAC_CARBON MoreMasterPointers(224); #else MoreMasters(); #endif InitCursor(); FlushEvents(everyEvent,0); if (AEInstallEventHandler(kCoreEventClass,kAEQuitApplication, NewAEEventHandlerUPP((AEEventHandlerProcPtr) quitAppEventHandler), 0L,false) != noErr) ExitToShell(); gActionFunctionScrollUPP = NewControlActionUPP(&actionFunctionScroll); Gestalt(gestaltMenuMgrAttr,&response); if(response & gestaltMenuMgrAquaLayoutMask) gRunningOnX = true; /* Initialize SIOUX */ SIOUXSettings.initializeTB = false; SIOUXSettings.standalone = false; SIOUXSettings.asktosaveonclose = false; SIOUXSettings.sleep = GetCaretTime(); SIOUXSettings.userwindowtitle = "\pGhostscript"; /* Get arguments from user */ argc = ccommand(&argv); /* Show command line window */ if (InstallConsole(0)) ExitToShell(); /* Part of fudge to make SIOUX accept characters without becoming modal */ SelectWindow(SIOUXTextWindow->window); PostEvent(keyDown, 0x4c00); // Enter ReadCharsFromConsole(dformat, 0x7FFF); clrscr(); /* Add in the display format as the first command line argument */ if (argc >= MAX_ARGS - 1) { printf("Too many command line arguments\n"); return; } memmove(&argv[3], &argv[1], (argc-1) * sizeof(char**)); argc += 2; argv[1] = ddevice; argv[2] = dformat; gs_sprintf(ddevice, "-sDEVICE=display"); gs_sprintf(dformat, "-dDisplayFormat=%d", display_format); /* Run Ghostscript */ if (gsapi_new_instance(&instance, NULL) < 0) { printf("Can't create Ghostscript instance\n"); return; } #ifdef DEBUG visual_tracer_init(); set_visual_tracer(&visual_tracer); #endif gsapi_set_stdio(instance, gsdll_stdin, gsdll_stdout, gsdll_stderr); gsapi_set_poll(instance, gsdll_poll); gsapi_set_display_callback(instance, &display); code = gsapi_init_with_args(instance, argc, argv); if (code == 0) code = gsapi_run_string(instance, start_string, 0, &exit_code); else { printf("Failed to initialize. Error %d.\n", code); fflush(stdout); } code = gsapi_exit(instance); if (code != 0) { printf("Failed to terminate. Error %d.\n", code); fflush(stdout); } gsapi_delete_instance(instance); #ifdef DEBUG visual_tracer_close(); #endif /* Ghostscript has finished - let user see output before quitting */ WriteCharsToConsole("\r[Finished - hit any key to quit]", 33); fflush(stdout); /* Process events until a key is hit or user quits from menu */ while(!gDone) { EventRecord eventStructure; if(WaitNextEvent(everyEvent,&eventStructure,SIOUXSettings.sleep,NULL)) { if (eventStructure.what == keyDown) gDone = true; doEvents(&eventStructure); } else SIOUXHandleOneEvent(&eventStructure); } }
/* This function is a fudge which allows the SIOUX window to be waiting for input and not be modal at the same time. (Why didn't MetroWerks think of that?) It is based on the SIOUX function ReadCharsFromConsole(), and contains an event loop which allows other windows to be active. It collects characters up to when the user presses ENTER, stores the complete buffer and gives as much to the calling function as it wants until it runs out, at which point it gets another line (or set of lines if pasting from the clipboard) from the user. */ static size_t get_input(void *ptr, size_t size) { EventRecord eventStructure; long charswaiting, old_charswaiting = 0; char *text; #if SIOUX_USE_WASTE Handle textHandle; #endif /* If needing more input, set edit start position */ if (!stdin_buf) #if SIOUX_USE_WASTE SIOUXselstart = WEGetTextLength(SIOUXTextWindow->edit); #else SIOUXselstart = (*SIOUXTextWindow->edit)->teLength; #endif /* Wait until user presses exit (or quits) */ while(!gDone && !stdin_buf) { #if SIOUX_USE_WASTE charswaiting = WEGetTextLength(SIOUXTextWindow->edit) - SIOUXselstart; #else if ((*SIOUXTextWindow->edit)->teLength > 0) charswaiting = (*SIOUXTextWindow->edit)->teLength - SIOUXselstart; else charswaiting = ((unsigned short) (*SIOUXTextWindow->edit)->teLength) - SIOUXselstart; #endif /* If something has happened, see if we need to do anything */ if (charswaiting != old_charswaiting) { #if SIOUX_USE_WASTE textHandle = WEGetText(SIOUXTextWindow->edit); HLock(textHandle); text = *textHandle + SIOUXselstart; #else text = (*(*SIOUXTextWindow->edit)->hText) + SIOUXselstart; #endif /* If user has pressed enter, gather up the buffer ready for returning */ if (text[charswaiting-1] == '\r') { stdin_buf = malloc(charswaiting); if (!stdin_buf) return -1; stdin_bufsize = charswaiting; memcpy(stdin_buf, text, stdin_bufsize); SIOUXselstart += charswaiting; text = stdin_buf; while (text = memchr(text, '\r', charswaiting - (text - stdin_buf))) *text = '\n'; } #if SIOUX_USE_WASTE HUnlock(textHandle); #endif old_charswaiting = charswaiting; if (stdin_buf) break; } /* Wait for next event and process it */ SIOUXState = SCANFING; if(WaitNextEvent(everyEvent, &eventStructure, SIOUXSettings.sleep ,NULL)) doEvents(&eventStructure); else SIOUXHandleOneEvent(&eventStructure); SIOUXState = IDLE; } /* If data has been entered, return as much as has been requested */ if (stdin_buf && !gDone) { if (size >= stdin_bufsize - stdin_bufpos) { size = stdin_bufsize - stdin_bufpos; memcpy (ptr, stdin_buf + stdin_bufpos, size); free(stdin_buf); stdin_buf = NULL; stdin_bufpos = 0; stdin_bufsize = 0; } else { memcpy (ptr, stdin_buf + stdin_bufpos, size); stdin_bufpos += size; } return size; } else if (stdin_buf) { free(stdin_buf); stdin_buf = NULL; stdin_bufpos = 0; stdin_bufsize = 0; } return 0; }