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.model = EVM_GUI; 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 (!RL_Event(&evt)) break; // queue is full } }
// // RL_Update_Event: C // // Updates an application event (e.g. GUI) to the event port. // // Returns: // Returns 1 if updated, or 0 if event appended, and -1 if full. // Arguments: // evt - A properly initialized event structure. The // model and type of the event are used to address // the unhandled event in the queue, when it is found, // it will be replaced with this one // RL_API int RL_Update_Event(REBEVT *evt) { REBVAL *event = Find_Last_Event(evt->model, evt->type); if (event) { event->payload.event = *evt; return 1; } return RL_Event(evt) - 1; }
static void Add_Event_XY(REBGOB *gob, REBINT id, REBINT xy, REBINT flags) { REBEVT evt; evt.type = id; evt.flags = (u8) (flags | (1<<EVF_HAS_XY)); evt.model = EVM_GUI; evt.data = xy; evt.ser = (void*)gob; RL_Event(&evt); // returns 0 if queue is full }
static void Add_Event_Key(REBGOB *gob, REBINT id, REBINT key, REBINT flags) { REBEVT evt; evt.type = id; evt.flags = flags; evt.model = EVM_GUI; evt.data = key; evt.ser = (void*)gob; RL_Event(&evt); // returns 0 if queue is full }
*/ void Signal_Device(REBREQ *req, REBINT type) /* ** Generate a device event to awake a port on REBOL. ** ***********************************************************************/ { REBEVT evt; CLEARS(&evt); evt.type = (REBYTE)type; evt.model = EVM_DEVICE; evt.req = req; if (type == EVT_ERROR) evt.data = req->error; RL_Event(&evt); // (returns 0 if queue is full, ignored) }
*/ RL_API int RL_Callback(RXICBI *cbi) /* ** Evaluate a REBOL callback function, either synchronous or asynchronous. ** ** Returns: ** Sync callback: type of the result; async callback: true if queued ** Arguments: ** cbi - callback information including special option flags, ** object pointer (where function is located), function name ** as global word identifier (within above object), argument list ** passed to callback (see notes below), and result value. ** Notes: ** The flag value will determine the type of callback. It can be either ** synchronous, where the code will re-enter the interpreter environment ** and call the specified function, or asynchronous where an EVT_CALLBACK ** event is queued, and the callback will be evaluated later when events ** are processed within the interpreter's environment. ** For asynchronous callbacks, the cbi and the args array must be managed ** because the data isn't processed until the callback event is ** handled. Therefore, these cannot be allocated locally on ** the C stack; they should be dynamic (or global if so desired.) ** See c:extensions-callbacks ** ***********************************************************************/ { REBEVT evt; // Synchronous callback? if (!GET_FLAG(cbi->flags, RXC_ASYNC)) { return Do_Callback(cbi->obj, cbi->word, cbi->args, &(cbi->result)); } CLEARS(&evt); evt.type = EVT_CALLBACK; evt.model = EVM_CALLBACK; evt.eventee.ser = cbi; SET_FLAG(cbi->flags, RXC_QUEUED); return RL_Event(&evt); // (returns 0 if queue is full, ignored) }
*/ RL_API int RL_Update_Event(REBEVT *evt) /* ** Updates an application event (e.g. GUI) to the event port. ** ** Returns: ** Returns 1 if updated, or 0 if event appended, and -1 if full. ** Arguments: ** evt - A properly initialized event structure. The ** model and type of the event are used to address ** the unhandled event in the queue, when it is found, ** it will be replaced with this one ** ***********************************************************************/ { REBVAL *event = Find_Last_Event(evt->model, evt->type); if (event) { event->data.event = *evt; return 1; } return RL_Event(evt) - 1; }