Boolean MCScreenDC::wait(real8 duration, Boolean dispatch, Boolean anyevent) { MCwaitdepth++; real8 curtime = MCS_time(); if (duration < 0.0) duration = 0.0; real8 exittime = curtime + duration; Boolean abort = False; Boolean reset = False; modalclosed = False; Boolean done = False; Boolean donepending = False; do { real8 eventtime = exittime; donepending = handlepending(curtime, eventtime, dispatch); siguser(); real8 waittime = donepending ? 0.0 : eventtime - curtime; MCModeQueueEvents(); if (MCquit) { abort = True; break; } if (MCnsockets > 0) waittime = waittime < 0.025 ? waittime: 0.025; //calls handle() in macdcmac.cpp if (modalclosed || (dispatch && MCEventQueueDispatch() || handle(waittime, dispatch, anyevent, abort, reset) || donepending) && anyevent || abort) break; if (MCquit) { abort = True; break; } // MW-2012-09-19: [[ Bug 10218 ]] Make sure we update the screen in case // any engine event handling methods need us to. MCRedrawUpdateScreen(); curtime = MCS_time(); } while (curtime < exittime); MCwaitdepth--; // MW-2012-09-19: [[ Bug 10218 ]] Make sure we update the screen in case // any engine event handling methods need us to. MCRedrawUpdateScreen(); return abort; }
bool MCSessionExpireCookie() { MCAutoStringRef t_session_name; /* UNCHECKED */ MCS_get_session_name(&t_session_name); return MCServerSetCookie(*t_session_name, MCSTR("EXPIRE"), MCS_time() - 60 * 60 * 24, nil, nil, false, true); }
// MW-2008-06-12: [[ Bug 6396 ]] Make sure r_abort is set to False if // the first two checks against 'button' fail. Also update the code // to use GetCurrentButtonState Boolean MCScreenDC::getmouse(uint2 button, Boolean& r_abort) { // Make the check interval what it always has been - 9! static real8 lasttime; real8 newtime = MCS_time(); real8 sr = (real8)9.0 / 1000.0; if ((newtime - lasttime) < sr) { r_abort = MCscreen->wait(sr, False, False); if (r_abort) return False; } r_abort = False; lasttime = newtime; UInt32 t_state; t_state = GetCurrentButtonState(); if (button == 0) return t_state != 0; if (button == 1) return (t_state & (1 << 0)) != 0; if (button == 2) return (t_state & (1 << 2)) != 0; if (button == 3) return (t_state & (1 << 1)) != 0 || ((t_state & (1 << 0)) != 0 && (querymods() & MS_MOD2) != 0); return False; }
Boolean IO_findsocket(const char *name, uint2 &i) { IO_cleansockets(MCS_time()); for (i = 0 ; i < MCnsockets ; i++) if (strequal(MCsockets[i]->name, name)) return True; return False; }
bool MCSystemPickDate(MCDateTime *p_current, MCDateTime *p_min, MCDateTime *p_max, bool p_use_cancel, bool p_use_done, MCDateTime *r_result, bool &r_canceled, MCRectangle p_button_rect) { if (s_in_popup_dialog) return false; int32_t t_current, t_min, t_max; bool t_use_min, t_use_max; t_use_min = p_min != nil; t_use_max = p_max != nil; MCExecPoint ep(nil, nil, nil); if (p_current != nil) { MCD_convert_from_datetime(ep, CF_SECONDS, CF_UNDEFINED, *p_current); t_current = ep.getint4(); } else t_current = MCS_time(); if (t_use_min) { MCD_convert_from_datetime(ep, CF_SECONDS, CF_UNDEFINED, *p_min); t_min = ep.getint4(); } if (t_use_max) { MCD_convert_from_datetime(ep, CF_SECONDS, CF_UNDEFINED, *p_max); t_max = ep.getint4(); } s_in_popup_dialog = true; s_dialog_result = kMCDialogResultUnknown; // IM-2012-10-31 [[ BZ 10483 ]] - make sure we have the timezone bias for the date MCS_getlocaldatetime(s_selected_date); MCAndroidEngineRemoteCall("showDatePicker", "vbbiii", nil, t_use_min, t_use_max, t_min, t_max, t_current); while(s_in_popup_dialog) MCscreen -> wait(60.0, True, True); if (s_dialog_result == kMCDialogResultError) return false; r_canceled = s_dialog_result == kMCDialogResultCanceled; if (!r_canceled) { // IM-2012-10-31 [[ BZ 10483 ]] - convert the return value back to UTC MCS_datetimetouniversal(s_selected_date); *r_result = s_selected_date; } return true; }
bool MCSystemPickTime(MCDateTime *p_current, MCDateTime *p_min, MCDateTime *p_max, int32_t p_step, bool p_use_cancel, bool p_use_done, MCDateTime *r_result, bool &r_canceled, MCRectangle p_button_rect) { if (s_in_popup_dialog) return false; int32_t t_hour, t_minute; MCExecPoint ep(nil, nil, nil); MCDateTime t_current; if (p_current != nil) t_current = *p_current; else { ep.setnvalue(MCS_time()); MCD_convert_to_datetime(ep, CF_SECONDS, CF_UNDEFINED, t_current); } // IM-2012-05-09 - make sure we show the correct local hour + minute values MCS_datetimetolocal(t_current); t_hour = t_current.hour; t_minute = t_current.minute; s_in_popup_dialog = true; s_dialog_result = kMCDialogResultUnknown; // IM-2012-10-31 [[ BZ 10483 ]] - make sure we have the timezone bias for the date s_selected_date = t_current; MCAndroidEngineRemoteCall("showTimePicker", "vii", nil, t_hour, t_minute); while (s_in_popup_dialog) MCscreen->wait(60.0, True, True); if (s_dialog_result == kMCDialogResultError) return false; r_canceled = s_dialog_result == kMCDialogResultCanceled; if (!r_canceled) { // IM-2012-10-31 [[ BZ 10483 ]] - convert the return value back to UTC MCS_datetimetouniversal(s_selected_date); *r_result = s_selected_date; } return true; }
bool MCSessionExpireSession(MCStringRef p_id) { bool t_success = true; MCSession *t_session = NULL; MCSessionIndexRef t_index = NULL; t_success = MCSessionOpenIndex(t_index); if (t_success) { if (MCSessionFindMatchingSession(t_index, p_id, t_session)) t_session->expires = MCS_time() - 60 * 60 * 24; } if (t_index) t_success &= MCSessionCloseIndex(t_index, t_success); return t_success; }
bool MCSessionOpenSession(MCSessionIndexRef p_index, MCSession *p_session) { bool t_success = true; MCAutoStringRef t_path_string; t_success = MCStringFormat(&t_path_string, "%@/%s", p_index->save_path, p_session->filename); if (t_success) t_success = NULL != (p_session->filehandle = MCsystem->OpenFile(*t_path_string, kMCOpenFileModeUpdate, false)); if (t_success) t_success = MCSystemLockFile(p_session->filehandle, false, true); if (t_success && p_session->filehandle->GetFileSize() > 0 && p_session->expires > MCS_time()) t_success = MCSessionReadSession(p_session); return t_success; }
bool MCSessionCleanup(void) { bool t_success = true; MCSessionIndexRef t_index = NULL; t_success = MCSessionOpenIndex(t_index); real8 t_time; t_time = MCS_time(); for (uint32_t i = 0; t_success && i < t_index->session_count; i++) { if (t_index->session[i]->expires <= t_time) { bool t_deleted = false; // check file not locked MCSystemFileHandle *t_file; MCAutoStringRef t_full_path_string; if (MCStringFormat(&t_full_path_string, "%@/%s", t_index->save_path, t_index->session[i]->filename) && MCS_exists(*t_full_path_string, True)) { t_file = MCsystem->OpenFile(*t_full_path_string, kMCOpenFileModeRead, false); if (t_file != NULL) { bool t_locked = false; t_locked = MCSystemLockFile(t_file, false, false); t_file->Close(); if (t_locked) t_deleted = MCsystem->DeleteFile(*t_full_path_string); } } else t_deleted = true; if (t_deleted) MCSessionIndexRemoveSession(t_index, t_index->session[i]); } } if (t_index != NULL) t_success &= MCSessionCloseIndex(t_index, t_success); return t_success; }
void IO_freeobject(MCObject *o) { IO_cleansockets(MCS_time()); uint2 i = 0; while (i < MCnsockets) #if 1 { if (MCsockets[i]->object == o) MCsockets[i]->doclose(); i++; } #else if (MCsockets[i]->object == o) { delete MCsockets[i]; uint2 j = i; while (++j < MCnsockets) MCsockets[j - 1] = MCsockets[j]; MCnsockets--; } else i++; #endif }
void MCInternalObjectListenerMessagePendingListeners(void) { if (MCobjectpropertieschanged) { MCobjectpropertieschanged = False; MCObjectListener *t_prev_listener; t_prev_listener = nil; MCObjectListener *t_listener; t_listener = s_object_listeners; while(t_listener != nil) { // MW-2013-08-27: [[ Bug 11126 ]] This static is updated by the remove_* functions // to ensure we don't get any dangling pointers. s_next_listener_to_process = t_listener -> next; if (!t_listener -> object -> Exists()) remove_object_listener_from_list(t_listener, t_prev_listener); else { uint8_t t_properties_changed; t_properties_changed = t_listener -> object -> Get() -> propertieschanged(); if (t_properties_changed != kMCPropertyChangedMessageTypeNone) { MCExecPoint ep(nil, nil, nil); t_listener -> object -> Get() -> getprop(0, P_LONG_ID, ep, False); MCObjectListenerTarget *t_target; t_target = nil; MCObjectListenerTarget *t_prev_target; t_prev_target = nil; double t_new_time; t_new_time = MCS_time(); if (t_listener -> last_update_time + MCpropertylistenerthrottletime / 1000.0 < t_new_time) { t_listener -> last_update_time = t_new_time; t_target = t_listener->targets; while (t_target != nil) { // MW-2013-08-27: [[ Bug 11126 ]] This static is updated by the remove_* functions // to ensure we don't get any dangling pointers. s_next_listener_target_to_process = t_target -> next; if (!t_target -> target -> Exists()) remove_object_listener_target_from_list(t_target, t_prev_target, t_listener, t_prev_listener); else { // MM-2012-11-06: Added resizeControl(Started/Ended) and gradientEdit(Started/Ended) messages. if (t_properties_changed & kMCPropertyChangedMessageTypePropertyChanged) t_target -> target -> Get() -> message_with_args(MCM_property_changed, ep . getsvalue()); if (t_properties_changed & kMCPropertyChangedMessageTypeResizeControlStarted) t_target -> target -> Get() -> message_with_args(MCM_resize_control_started, ep . getsvalue()); if (t_properties_changed & kMCPropertyChangedMessageTypeResizeControlEnded) t_target -> target -> Get() -> message_with_args(MCM_resize_control_ended, ep . getsvalue()); if (t_properties_changed & kMCPropertyChangedMessageTypeGradientEditStarted) t_target -> target -> Get() -> message_with_args(MCM_gradient_edit_started, ep . getsvalue()); if (t_properties_changed & kMCPropertyChangedMessageTypeGradientEditEnded) t_target -> target -> Get() -> message_with_args(MCM_gradient_edit_ended, ep . getsvalue()); t_prev_target = t_target; } t_target = s_next_listener_target_to_process; } } else t_listener -> object -> Get() -> signallistenerswithmessage(t_properties_changed); } t_prev_listener = t_listener; } // MW-2013-08-27: [[ Bug 11126 ]] Use the static as the next in the chain. t_listener = s_next_listener_to_process; } } }
void MCSessionRefreshExpireTime(MCSession *p_session) { p_session->expires = MCS_time() + MCS_get_session_lifetime(); }
void MCStack::effectrect(const MCRectangle& p_area, Boolean& r_abort) { // Get the list of effects. MCEffectList *t_effects = MCcur_effects; MCcur_effects = NULL; // If the window isn't opened or hasn't been attached (plugin) or if we have no // snapshot to use, this is a no-op. if (!opened || !haswindow() || m_snapshot == nil) { while(t_effects != NULL) { MCEffectList *t_effect; t_effect = t_effects; t_effects = t_effects -> next; delete t_effect; } return; } // Mark the stack as being in an effect. state |= CS_EFFECT; // Lock messages while the effect is happening. Boolean t_old_lockmessages; t_old_lockmessages = MClockmessages; MClockmessages = True; // Calculate the area of interest. MCRectangle t_effect_area; t_effect_area = curcard -> getrect(); t_effect_area . y = getscroll(); t_effect_area . height -= t_effect_area . y; t_effect_area = MCU_intersect_rect(t_effect_area, p_area); // IM-2013-08-21: [[ ResIndependence ]] Scale effect area to device coords // Align snapshot rect to device pixels // IM-2013-09-30: [[ FullscreenMode ]] Use stack transform to get device coords MCGAffineTransform t_transform; t_transform = getdevicetransform(); // MW-2013-10-29: [[ Bug 11330 ]] Make sure the effect area is cropped to the visible // area. t_effect_area = MCRectangleGetTransformedBounds(t_effect_area, getviewtransform()); t_effect_area = MCU_intersect_rect(t_effect_area, MCU_make_rect(0, 0, view_getrect() . width, view_getrect() . height)); // IM-2014-01-24: [[ HiDPI ]] scale effect region to backing surface coords MCGFloat t_scale; t_scale = view_getbackingscale(); MCRectangle t_device_rect, t_user_rect; t_device_rect = MCRectangleGetScaledBounds(t_effect_area, t_scale); t_user_rect = MCRectangleGetTransformedBounds(t_device_rect, MCGAffineTransformInvert(t_transform)); // IM-2013-08-29: [[ RefactorGraphics ]] get device height for CoreImage effects // IM-2013-09-30: [[ FullscreenMode ]] Use view rect to get device height uint32_t t_device_height; t_device_height = floor(view_getrect().height * t_scale); // Make a region of the effect area // IM-2013-08-29: [[ ResIndependence ]] scale effect region to device coords MCRegionRef t_effect_region; t_effect_region = nil; /* UNCHECKED */ MCRegionCreate(t_effect_region); /* UNCHECKED */ MCRegionSetRect(t_effect_region, t_effect_area); #ifndef FEATURE_PLATFORM_PLAYER #if defined(FEATURE_QUICKTIME) // MW-2010-07-07: Make sure QT is only loaded if we actually are doing an effect if (t_effects != nil) if (!MCdontuseQTeffects) if (!MCtemplateplayer -> isQTinitted()) MCtemplateplayer -> initqt(); #endif #endif // Lock the screen to prevent any updates occuring until we want them. MCRedrawLockScreen(); // By default, we have not aborted. r_abort = False; MCGImageRef t_initial_image; t_initial_image = MCGImageRetain(m_snapshot); while(t_effects != nil) { uint32_t t_duration; t_duration = MCU_max(1, MCeffectrate / (t_effects -> speed - VE_VERY)); if (t_effects -> type == VE_DISSOLVE) t_duration *= 2; uint32_t t_delta; t_delta = 0; // Create surface at effect_area size. // Render into surface based on t_effects -> image MCGImageRef t_final_image = nil; // If this isn't a plain effect, then we must fetch first and last images. if (t_effects -> type != VE_PLAIN) { // Render the final image. MCGContextRef t_context = nil; // IM-2014-05-20: [[ GraphicsPerformance ]] Create opaque context for snapshot /* UNCHECKED */ MCGContextCreate(t_device_rect.width, t_device_rect.height, false, t_context); MCGContextTranslateCTM(t_context, -t_device_rect.x, -t_device_rect.y); // IM-2013-10-03: [[ FullscreenMode ]] Apply device transform to context MCGContextConcatCTM(t_context, t_transform); // Configure the context. MCGContextClipToRect(t_context, MCRectangleToMCGRectangle(t_user_rect)); // Render an appropriate image switch(t_effects -> image) { case VE_INVERSE: { MCContext *t_old_context = nil; /* UNCHECKED */ t_old_context = new MCGraphicsContext(t_context); curcard->draw(t_old_context, t_user_rect, false); delete t_old_context; MCGContextSetFillRGBAColor(t_context, 1.0, 1.0, 1.0, 1.0); MCGContextSetBlendMode(t_context, kMCGBlendModeDifference); MCGContextAddRectangle(t_context, MCRectangleToMCGRectangle(t_user_rect)); MCGContextFill(t_context); } break; case VE_BLACK: MCGContextSetFillRGBAColor(t_context, 0.0, 0.0, 0.0, 1.0); MCGContextAddRectangle(t_context, MCRectangleToMCGRectangle(t_user_rect)); MCGContextFill(t_context); break; case VE_WHITE: MCGContextSetFillRGBAColor(t_context, 1.0, 1.0, 1.0, 1.0); MCGContextAddRectangle(t_context, MCRectangleToMCGRectangle(t_user_rect)); MCGContextFill(t_context); break; case VE_GRAY: MCGContextSetFillRGBAColor(t_context, 0.5, 0.5, 0.5, 1.0); MCGContextAddRectangle(t_context, MCRectangleToMCGRectangle(t_user_rect)); MCGContextFill(t_context); break; default: { MCContext *t_old_context = nil; /* UNCHECKED */ t_old_context = new MCGraphicsContext(t_context); curcard->draw(t_old_context, t_user_rect, false); delete t_old_context; } } /* UNCHECKED */ MCGContextCopyImage(t_context, t_final_image); MCGContextRelease(t_context); } MCStackEffectContext t_context; t_context.delta = t_delta; t_context.duration = t_duration; t_context.effect = t_effects; t_context.effect_area = t_device_rect; t_context.initial_image = t_initial_image; t_context.final_image = t_final_image; // MW-2011-10-20: [[ Bug 9824 ]] Make sure dst point is correct. // Initialize the destination with the start image. view_platform_updatewindowwithcallback(t_effect_region, MCStackRenderInitial, &t_context); // If there is a sound, then start playing it. if (t_effects -> sound != NULL) { MCAudioClip *acptr; MCNewAutoNameRef t_sound; /* UNCHECKED */ MCNameCreate(t_effects->sound, &t_sound); if ((acptr = (MCAudioClip *)getobjname(CT_AUDIO_CLIP, *t_sound)) == NULL) { IO_handle stream; if ((stream = MCS_open(t_effects->sound, kMCOpenFileModeRead, True, False, 0)) != NULL) { acptr = new MCAudioClip; acptr->setdisposable(); if (!acptr->import(t_effects->sound, stream)) { delete acptr; acptr = NULL; } MCS_close(stream); } } if (acptr != NULL) { MCU_play_stop(); MCacptr = acptr; MCU_play(); #ifndef FEATURE_PLATFORM_AUDIO if (MCacptr != NULL) MCscreen->addtimer(MCacptr, MCM_internal, PLAY_RATE); #endif } if (MCscreen->wait((real8)MCsyncrate / 1000.0, False, True)) { r_abort = True; break; } } // Initialize CoreImage of QTEffects if needed. if (t_effects -> type != VE_PLAIN) { MCAutoPointer<char> t_name; /* UNCHECKED */ MCStringConvertToCString(t_effects -> name, &t_name); #ifdef _MAC_DESKTOP // IM-2013-08-29: [[ ResIndependence ]] use scaled effect rect for CI effects if (t_effects -> type == VE_UNDEFINED && MCCoreImageEffectBegin(*t_name, t_initial_image, t_final_image, t_device_rect, t_device_height, t_effects -> arguments)) t_effects -> type = VE_CIEFFECT; else #endif #ifdef FEATURE_QUICKTIME_EFFECTS // IM-2013-08-29: [[ ResIndependence ]] use scaled effect rect for QT effects if (t_effects -> type == VE_UNDEFINED && MCQTEffectBegin(t_effects -> type, *t_name, t_effects -> direction, t_initial_image, t_final_image, t_device_rect)) t_effects -> type = VE_QTEFFECT; #else ; #endif } // Run effect // Now perform the effect loop, but only if there is something to do. if (t_effects -> type != VE_PLAIN || old_blendlevel != blendlevel) { // Calculate timing parameters. double t_start_time; t_start_time = 0.0; for(;;) { t_context.delta = t_delta; Boolean t_drawn = False; view_platform_updatewindowwithcallback(t_effect_region, MCStackRenderEffect, &t_context); // Now redraw the window with the new image. // if (t_drawn) { MCscreen -> sync(getw()); } // Update the window's blendlevel (if needed) if (old_blendlevel != blendlevel) { float t_fraction = float(t_delta) / t_duration; setopacity(uint1((old_blendlevel * 255 + (float(blendlevel) - old_blendlevel) * 255 * t_fraction) / 100)); } // If the start time is zero, then start counting from here. if (t_start_time == 0.0) t_start_time = MCS_time(); // If we've reached the end of the transition, we are done. if (t_delta == t_duration) { #ifdef _ANDROID_MOBILE // MW-2011-12-12: [[ Bug 9907 ]] Make sure we let the screen sync at this point MCscreen -> wait(0.01, False, False); #endif break; } // Get the time now. double t_now; t_now = MCS_time(); // Compute the new delta value. uint32_t t_new_delta; t_new_delta = (uint32_t)ceil((t_now - t_start_time) * 1000.0); // If the new value is same as the old, then advance one step. if (t_new_delta == t_delta) t_delta = t_new_delta + 1; else t_delta = t_new_delta; // If the new delta is beyond the end point, set it to the end. if (t_delta > t_duration) t_delta = t_duration; // Wait until the next boundary, making sure we break for no reason // other than abort. if (MCscreen -> wait((t_start_time + (t_delta / 1000.0)) - t_now, False, False)) r_abort = True; // If we aborted, we render the final step and are thus done. if (r_abort) t_delta = t_duration; } } #ifdef _MAC_DESKTOP if (t_effects -> type == VE_CIEFFECT) MCCoreImageEffectEnd(); else #endif #ifdef FEATURE_QUICKTIME_EFFECTS if (t_effects -> type == VE_QTEFFECT) MCQTEffectEnd(); #endif // Free initial surface. MCGImageRelease(t_initial_image); // initial surface becomes final surface. t_initial_image = t_final_image; t_final_image = nil; // Move to the next effect. MCEffectList *t_current_effect; t_current_effect = t_effects; t_effects = t_effects -> next; delete t_current_effect; } // Make sure the pixmaps are freed and any dangling effects // are cleaned up. if (t_effects != NULL) { /* OVERHAUL - REVISIT: error cleanup needs revised */ MCGImageRelease(t_initial_image); // MCGSurfaceRelease(t_final_image); while(t_effects != NULL) { MCEffectList *t_current_effect; t_current_effect = t_effects; t_effects = t_effects -> next; delete t_current_effect; } } MCRegionDestroy(t_effect_region); MCGImageRelease(m_snapshot); m_snapshot = nil; m_snapshot = t_initial_image; // Unlock the screen. MCRedrawUnlockScreen(); // Unlock messages. MClockmessages = t_old_lockmessages; // Turn off effect mode. state &= ~CS_EFFECT; // The stack's blendlevel is now the new one. old_blendlevel = blendlevel; // Finally, mark the affected area of the stack for a redraw. dirtyrect(p_area); }