sqInt ioSetCursorWithMask(sqInt cursorBitsIndex, sqInt cursorMaskIndex, sqInt offsetX, sqInt offsetY) { uchar* cursorBits = (uchar*)pointerForOop(cursorBitsIndex); uchar* maskBits = (uchar*)pointerForOop(cursorMaskIndex); int i; Cursor c; c.offset.x = offsetX; c.offset.y = offsetY; for (i = 0; i < 16; i++) { c.clr[i*2] = (~cursorBits[i*4+3] & maskBits[i*4+3]); c.clr[i*2+1] = (~cursorBits[i*4+2] & maskBits[i*4+2]); c.set[i*2] = cursorBits[i*4+3]; c.set[i*2+1] = cursorBits[i*4+2]; } setcursor(mousectl, &c); return 0; }
static sqInt display_ioShowDisplay(sqInt dispBitsIndex, sqInt width, sqInt height, sqInt depth, sqInt affectedL, sqInt affectedR, sqInt affectedT, sqInt affectedB) { if ((depth != fb_depth(fb)) || (width != fb_width(fb)) || (height != fb_height(fb)) || (affectedR < affectedL) || (affectedB < affectedT)) return 0; fb->copyBits(fb, pointerForOop(dispBitsIndex), affectedL, affectedR, affectedT, affectedB); return 1; }
/* ioLoadExternalFunctionOfLengthFromModuleOfLength Entry point for functions looked up through the VM. */ void *ioLoadExternalFunctionOfLengthFromModuleOfLength(sqInt functionNameIndex, sqInt functionNameLength, sqInt moduleNameIndex, sqInt moduleNameLength) { char *functionNamePointer= pointerForOop(functionNameIndex); char *moduleNamePointer= pointerForOop(moduleNameIndex); char functionName[256]; char moduleName[256]; int i; if(functionNameLength > 255 || moduleNameLength > 255) return 0; /* can't cope with those */ for(i=0; i< functionNameLength; i++) functionName[i] = functionNamePointer[i]; functionName[functionNameLength] = 0; for(i=0; i< moduleNameLength; i++) moduleName[i] = moduleNamePointer[i]; moduleName[moduleNameLength] = 0; return ioLoadFunctionFrom(functionName, moduleName); }
/* ioUnloadModuleOfLength: Entry point for the interpreter. */ sqInt ioUnloadModuleOfLength(sqInt moduleNameIndex, sqInt moduleNameLength) { char *moduleNamePointer= pointerForOop(moduleNameIndex); char moduleName[256]; int i; if(moduleNameLength > 255) return 0; /* can't cope with those */ for(i=0; i< moduleNameLength; i++) moduleName[i] = moduleNamePointer[i]; moduleName[moduleNameLength] = 0; return ioUnloadModule(moduleName); }
sqInt vmPathGetLength(sqInt sqVMPathIndex, sqInt length) { char *stVMPath= pointerForOop(sqVMPathIndex); int count, i; count= strlen(vmPath); count= (length < count) ? length : count; /* copy the file name into the Squeak string */ for (i= 0; i < count; i++) stVMPath[i]= vmPath[i]; return count; }
sqInt imageNameGetLength(sqInt sqImageNameIndex, sqInt length) { char *sqImageName= pointerForOop(sqImageNameIndex); int count, i; count= strlen(imageName); count= (length < count) ? length : count; /* copy the file name into the Squeak string */ for (i= 0; i < count; i++) sqImageName[i]= imageName[i]; return count; }
EXPORT(sqInt) primitiveAsyncFileWriteStart(void) { AsyncFile * f; sqInt count; sqInt startIndex; sqInt bufferSize; char * bufferPtr; sqInt fHandle; sqInt fPosition; sqInt buffer; sqInt start; sqInt num; fHandle = interpreterProxy->stackValue(4); fPosition = interpreterProxy->stackIntegerValue(3); buffer = interpreterProxy->stackValue(2); start = interpreterProxy->stackIntegerValue(1); num = interpreterProxy->stackIntegerValue(0); if (interpreterProxy->failed()) { return null; } f = asyncFileValueOf(fHandle); if (interpreterProxy->failed()) { return null; } count = num; startIndex = start; /* in bytes or words */ bufferSize = interpreterProxy->slotSizeOf(buffer); if (interpreterProxy->isWords(buffer)) { /* convert word counts to byte counts */ count = count * ( 4); startIndex = ((startIndex - 1) * ( 4)) + 1; bufferSize = bufferSize * ( 4); } interpreterProxy->success((startIndex >= 1) && (((startIndex + count) - 1) <= bufferSize)); bufferPtr = (((pointerForOop(buffer)) + ( 4)) + startIndex) - 1; if (!(interpreterProxy->failed())) { asyncFileWriteStart(f, fPosition, bufferPtr, count); } if (interpreterProxy->failed()) { return null; } interpreterProxy->pop(5); return null; }
/* ioLoadModuleOfLength This entry point is exclusively for the FFI. It does *NOT* call any of the initializers nor does it attempt to lookup stuff internally. */ void *ioLoadModuleOfLength(sqInt moduleNameIndex, sqInt moduleNameLength) { ModuleEntry *module; char *moduleNamePointer= pointerForOop(moduleNameIndex); char moduleName[256]; int i; if(moduleNameLength > 255) return 0; /* can't cope with those */ for(i=0; i< moduleNameLength; i++) moduleName[i] = moduleNamePointer[i]; moduleName[moduleNameLength] = 0; module = findOrLoadModule(moduleName, 1); if(module) return module->handle; return 0; }
/* ioLoadSymbolOfLengthFromModule This entry point is exclusively for the FFI. */ void *ioLoadSymbolOfLengthFromModule(sqInt functionNameIndex, sqInt functionNameLength, void *moduleHandle) { char *functionNamePointer= pointerForOop(functionNameIndex); char functionName[256]; int i; if(functionNameLength > 255) return 0; /* can't cope with those */ for(i=0; i< functionNameLength; i++) functionName[i] = functionNamePointer[i]; functionName[functionNameLength] = 0; if(moduleHandle) return ioFindExternalFunctionIn(functionName, moduleHandle); else return 0; }
sqInt imageNamePutLength(sqInt sqImageNameIndex, sqInt length) { char *sqImageName= pointerForOop(sqImageNameIndex); int count, i; count= (IMAGE_NAME_SIZE < length) ? IMAGE_NAME_SIZE : length; /* copy the file name into a null-terminated C string */ for (i= 0; i < count; i++) imageName[i]= sqImageName[i]; imageName[count]= 0; dpy->winSetName(imageName); return count; }
EXPORT(sqInt) primitiveAsyncFileReadResult(void) { AsyncFile * f; sqInt count; sqInt startIndex; sqInt bufferSize; sqInt r; char * bufferPtr; sqInt fhandle; sqInt buffer; sqInt start; sqInt num; sqInt _return_value; fhandle = interpreterProxy->stackValue(3); buffer = interpreterProxy->stackValue(2); start = interpreterProxy->stackIntegerValue(1); num = interpreterProxy->stackIntegerValue(0); if (interpreterProxy->failed()) { return null; } f = asyncFileValueOf(fhandle); count = num; startIndex = start; /* in bytes or words */ bufferSize = interpreterProxy->slotSizeOf(buffer); if (interpreterProxy->isWords(buffer)) { /* covert word counts to byte counts */ count = count * 4; startIndex = ((startIndex - 1) * 4) + 1; bufferSize = bufferSize * 4; } interpreterProxy->success((startIndex >= 1) && (((startIndex + count) - 1) <= bufferSize)); bufferPtr = (((pointerForOop(buffer)) + ( 4)) + startIndex) - 1; if (!(interpreterProxy->failed())) { r = asyncFileReadResult(f, bufferPtr, count); } _return_value = interpreterProxy->integerObjectOf(r); if (interpreterProxy->failed()) { return null; } interpreterProxy->popthenPush(5, _return_value); return null; }
// play (exactly) frameCount of samples (and no less, since the result is // ignored). // static sqInt sound_PlaySamplesFromAtLength(sqInt frameCount, sqInt arrayIndex, sqInt startIndex) { if (output) { int byteCount= frameCount * SqueakFrameSize; if (Buffer_free(output->buffer) >= byteCount) { Buffer_write(output->buffer, pointerForOop(arrayIndex) + (startIndex * SqueakFrameSize), byteCount); return frameCount; } return 0; } success(false); return 8192; }
static sqInt sound_RecordSamplesIntoAtLength(sqInt buf, sqInt startSliceIndex, sqInt bufferSizeInBytes) { if (input) { if (Buffer_avail(input->buffer) >= (512 * DeviceFrameSize)) { int start= startSliceIndex * SqueakFrameSize / 2; UInt32 count= min(input->cvtBufSize, bufferSizeInBytes - start); if (kAudioHardwareNoError == AudioConverterFillBuffer(input->converter, bufferDataProc, input, &count, pointerForOop(buf) + start)) return count / (SqueakFrameSize / 2) / input->channels; } return 0; } success(false); return 0; }
static sqInt display_ioShowDisplay(sqInt dispBitsIndex, sqInt width, sqInt height, sqInt depth, sqInt affectedL, sqInt affectedR, sqInt affectedT, sqInt affectedB) { uint32_t *dispBits= pointerForOop(dispBitsIndex); uint32_t *pixels; int i, j; if (toQuit) { pthread_exit(NULL); } pthread_mutex_lock(&image_mutex); if (isContextValid()) { pixels = image_data_->Map(image); for (j = 0; j < screenHeight; j++) { for (i = 0; i < screenWidth; i++) { pixels[j*(screenStride/4)+i] = dispBits[j*width+i]; } } image_data_->Unmap(image); } pthread_mutex_unlock(&image_mutex); flush_display_requested = 1; return 0; }
sqInt ioShowDisplay(sqInt dispBitsIndex, sqInt width, sqInt height, sqInt depth, sqInt affectedL, sqInt affectedR, sqInt affectedT, sqInt affectedB) { Rectangle r; r.min.x = affectedL; r.max.x = affectedR; r.min.y = affectedT; r.max.y = affectedB; ulong chan; uchar* dispBits = (uchar*)pointerForOop(dispBitsIndex); size_t region_w = affectedR-affectedL, region_h = affectedB-affectedT; uchar* buf = (uchar*)malloc(region_w*region_h*3); if (buf == NULL) return 0; sqToP9Bits(dispBits, buf, width, height, affectedL, affectedR, affectedT, affectedB); switch (depth) { case 1: chan = GREY1; break; case 2: chan = GREY2; break; case 4: chan = CMAP8; break; case 8: chan = CMAP8; break; case 16: chan = RGB16; break; case 32: chan = RGB24; break; default: return -1; } Image* s = allocimage(display, r, chan, 0, DNofill); if (s == 0) { return -1; } Image* mask = allocimage(display, r, chan, 0, DOpaque); if (mask == 0) { freeimage(s); return -1; } loadimage(s, r, buf, region_w*region_h*3); Point e; e.x = 0; e.y = 0; draw(screen, screen->r, s, mask, e); freeimage(mask); freeimage(s); free(buf); return 0; }
static char * bufferPointerstartIndex(sqInt buffer, sqInt startIndex) { return (((pointerForOop(buffer)) + ( 4)) + startIndex) - 1; }
static sqInt display_ioSetCursorWithMask(sqInt cursorBitsIndex, sqInt cursorMaskIndex, sqInt offsetX, sqInt offsetY) { fb_setCursor(fb, pointerForOop(cursorBitsIndex), pointerForOop(cursorMaskIndex), offsetX, offsetY); return 1; }
static char * bufferPointerstartIndex(sqInt buffer, sqInt startIndex) { return (((pointerForOop(buffer)) + (BASE_HEADER_SIZE)) + startIndex) - 1; }
sqInt getAttributeIntoLength(sqInt id, sqInt byteArrayIndex, sqInt length) { if (length > 0) strncpy(pointerForOop(byteArrayIndex), getAttribute(id), length); return 0; }
// insert up to frameCount (and no less than frameCount/2 -- see SoundPlayer // class>>startPlayingImmediately: for the [bogus] reasons why) frames into // the front and back buffers, leaving some number of framesOfLeadTime // intact before starging the insertion. (this last parameter is // meaningless for us and could be reduced to zero, but ignoring it causes // strange things to happen. time to rething the image code, methinks.) // // Note: this is only used when the "sound quick start" preference is // enabled in the image. // static sqInt sound_InsertSamplesFromLeadTime(sqInt frameCount, sqInt srcBufPtr, sqInt framesOfLeadTime) { Stream *s= output; debugf("snd_InsertSamples %d From %p LeadTime %d\n", frameCount, srcBufPtr, framesOfLeadTime); if (s) { // data already sent to the device is lost forever, although latency // is only a few hundred frames (and is certainly much lower than the // standard value of `framesOfLeadTime'). instead of putzing around // why not just mix the samples in right away, leaving one h/w // buffer's worth of lead time in case we're interrupted in the // middle? char *frontData= 0, *backData= 0; int frontFrames= 0, backFrames= 0; int framesDone= 0; int leadBytes; # if (OBEY_LEAD_TIME) { AudioTimeStamp timeStamp; u_int64_t then, now; timeStamp.mFlags= kAudioTimeStampHostTimeValid; checkError(AudioDeviceGetCurrentTime(s->id, &timeStamp), "AudioDeviceGetCurrentTime", ""); now= AudioConvertHostTimeToNanos(timeStamp.mHostTime) / 1000ull; then= s->timestamp; leadBytes= ( ((now - then) * (u_int64_t)s->sampleRate) / 1000000ull + framesOfLeadTime ) * SqueakFrameSize; } # else { leadBytes= s->devBufSize; // quantum shipped to the hardware } # endif { int availBytes; int byteCount= frameCount * SqueakFrameSize; Buffer_getOutputPointers(s->buffer, &frontData, &frontFrames, // bytes! &backData, &backFrames); // bytes! availBytes= frontFrames + backFrames; // don't consume more than frameCount - 1 frames leadBytes= max(leadBytes, availBytes - byteCount + SqueakFrameSize); assert((availBytes - leadBytes) < (byteCount)); if (leadBytes < frontFrames) // skip leadBytes into first fragment { frontData += leadBytes; frontFrames -= leadBytes; } else // omit the first fragment { leadBytes -= frontFrames; // lead in second fragment frontFrames= 0; backData += leadBytes; // skip leadBytes into second fragment backFrames -= leadBytes; } frontFrames /= SqueakFrameSize; backFrames /= SqueakFrameSize; } assert((frontFrames + backFrames) < frameCount); // avoid bug in image if ((frontFrames + backFrames) >= (frameCount / 2)) { mixFrames((short *)frontData, (short *)pointerForOop(srcBufPtr), frontFrames); srcBufPtr += frontFrames * SqueakFrameSize; mixFrames((short *)backData, (short *)pointerForOop(srcBufPtr), backFrames); framesDone= frontFrames + backFrames; } return framesDone; } success(false); return frameCount; }
sqInt sqShrinkMemoryBy(sqInt oldLimit, sqInt delta) { return oopForPointer(uxShrinkMemoryBy(pointerForOop(oldLimit), delta)); }