/* * This file is part of MiniGUI, a mature cross-platform windowing * and Graphics User Interface (GUI) support system for embedded systems * and smart IoT devices. * * Copyright (C) 2002~2018, Beijing FMSoft Technologies Co., Ltd. * Copyright (C) 1998~2002, WEI Yongming * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * Or, * * As this program is a library, any link to this program must follow * GNU General Public License version 3 (GPLv3). If you cannot accept * GPLv3, you need to be licensed from FMSoft. * * If you have got a commercial license of this program, please use it * under the terms and conditions of the commercial license. * * For more information about the commercial license, please refer to * . */ /* ** object.c: The implemenation of mObject class for the new textedit module. */ #include #include #include #include #include #include #include "common.h" #include "minigui.h" #include "object.h" #if defined(_MGCTRL_TEXTEDIT_USE_NEW_IMPL) || defined(__MGNCS_TEXTEDITOR) static void mObject_construct(mObject* self, DWORD addData) { //do nothing //to avoid NULL pointer } static void mObject_destroy(mObject* self) { /* ncsRemoveObjectBindProps(self); ncsRemoveEventSource(self); ncsRemoveEventListener(self); */ } static DWORD mObject_hash(mObject *self) { return (DWORD)self; } static const char* mObject_toString(mObject *self, char* str, int max) { if(!str) return NULL; snprintf(str, max, "NCS Object %s[@%p]", TYPENAME(self),self); return str; } static mObjectClass* mObjectClassConstructor(mObjectClass* _class) { _class->super = NULL; _class->typeName = "mObject"; _class->objSize = sizeof(mObject); CLASS_METHOD_MAP(mObject, construct) CLASS_METHOD_MAP(mObject, destroy) CLASS_METHOD_MAP(mObject, hash) CLASS_METHOD_MAP(mObject, toString) return _class; } mObjectClass Class(mObject) = { (PClassConstructor)mObjectClassConstructor }; mObject * mg_newObject(mObjectClass *_class) { mObject * obj; if(_class == NULL) return NULL; obj = (mObject*)calloc(1, _class->objSize); if(!obj) return NULL; return initObject(obj, _class); } mObject * mgNewObject(mObjectClass *_class,DWORD addData){ mObject * obj = newObject(_class); if(!obj) return NULL; _class->construct(obj, addData); return obj; } mObject * mgNewObjectArgs(mObjectClass* _class, ...) { va_list va; mObject * obj; va_start(va, _class); obj = newObject(_class); if(obj) ((PCONSTRUCT_VALIST)(_class->construct))(obj, va); va_end(va); return obj; } void mgDeleteObject(mObject *obj) { if(obj == NULL || obj->_class == NULL) return; _c(obj)->destroy(obj); free(obj); } mObject* mgInitObject(mObject* pobj, mObjectClass* _class) { IInterface* piobj; IInterfaceVTable* _ivtable; int next_intf_offset ; pobj->_class = _class; next_intf_offset = _class->intfOffset; while(next_intf_offset > 0) { _ivtable = (IInterfaceVTable*)((unsigned char*)_class + next_intf_offset); piobj = (IInterface*)((unsigned char*)pobj + _ivtable->_obj_offset); piobj->_vtable = _ivtable; next_intf_offset = _ivtable->_next_offset; } return pobj; } mObject* mg_initObject(mObject* pobj, mObjectClass* _class,DWORD param) { memset(pobj, 0, _class->objSize); initObject(pobj, _class); _class->construct(pobj, param); return pobj; } mObject* mgInitObjectArgs(mObject* pobj, mObjectClass* _class, ...) { va_list va; va_start(va, _class); memset(pobj, 0, _class->objSize); initObject(pobj, _class); ((PCONSTRUCT_VALIST)(_class->construct))(pobj, va); va_end(va); return pobj; } ///////////////////////////////////////////////////// // // mObjectClass *ncsSafeCastClass(mObjectClass* clss, mObjectClass* castCls) { mObjectClass * clssSuper; if(clss == castCls) return NULL; clssSuper = clss; while(clssSuper && clssSuper != castCls) clssSuper = clssSuper->super; return clssSuper?clss:NULL; } mObject* ncsSafeCast(mObject* obj, mObjectClass *clss) { mObjectClass * objClass; if(obj == NULL || clss == NULL) return NULL; objClass = _c(obj); while(objClass && objClass != clss) objClass = objClass->super; return objClass?obj:NULL; } BOOL ncsInstanceOf(mObject *object, mObjectClass* clss) { mObjectClass* objClss; if(object == NULL || clss == NULL) return FALSE; objClss = _c(object); while(objClss && clss != objClss){ objClss = objClss->super; } return objClss != NULL; } static inline int _va_check (va_list va) { #if 0 union { va_list va; DWORD dva; } _va; if (va == 0) return 0; va_copy (_va.va, va); if(_va.dva == 0) return 0; return 1; #else intptr_t zero = 0; size_t n = sizeof (intptr_t); if (sizeof (va_list) < n) { n = sizeof (va_list); } return memcmp (&zero, &va, n); #endif } int ncsParseConstructParams(va_list args, const char* signature, ...) { va_list params; int argc; int i; /* ** the implementation of GET_ARG_COUNT is bad, because some systems ** define va_list as a pointer, and others define it as an array of ** pointers (of length 1). if(GET_ARG_COUNT(args) <= 0) return 0; */ if (_va_check (args) == 0) return 0; argc = va_arg(args, int); if(argc <= 0) return 0; va_start(params, signature); i = 0; while(i < argc) { switch(signature[i]) { case 'd': //double *(va_arg(params, double*)) = va_arg(args, double); break; case 'f': //float /* FIXME gcc says: ** warning: 'float' is promoted to 'double' when passed through '...' ** warning: (so you should pass 'double' not 'float' to 'va_arg') ** note: if this code is reached, the program will abort. */ *(va_arg(params, float*)) = va_arg(args, double); break; case 'i': //integer *(va_arg(params, int*)) = va_arg(args, int); break; case 's': //const char* *(va_arg(params, const char**)) = va_arg(args, const char*); break; case 'u': //unsigned int *(va_arg(params, unsigned int*)) = va_arg(args, unsigned int); break; case 'p': //void * *(va_arg(params, void**)) = va_arg(args, void*); break; default: *(va_arg(params, void**)) = va_arg(args, void*); } i ++; } va_end(params); return i; } #endif /* defined(_MGCTRL_TEXTEDIT_USE_NEW_IMPL) || defined(__MGNCS_TEXTEDITOR) */