/* * ZlibAlloc * * Allocates an array in memory. * * Arguments: * opaque - Not used. * items - Number of items to allocate. * size - Size of each element, in bytes. * * Return Value: * If the function succeeds, the return value is a pointer to the allocated * memory block. If the function fails, the return value is NULL. * * Remarks: * This function provides Zlib access to Tcl's memory allocation system. */ static voidpf ZlibAlloc( voidpf opaque, uInt items, uInt size ) { return (voidpf)attemptckalloc((int)(items * size)); }
/*++ BzipAlloc Allocates an array in memory. Arguments: opaque - Not used. items - Number of items to allocate. size - Size of each element, in bytes. Return Value: If the function succeeds, the return value is a pointer to the allocated memory block. If the function fails, the return value is NULL. Remarks: This function provides Bzip access to Tcl's memory allocation system. --*/ static void * BzipAlloc( void *opaque, int items, int size ) { return (void *)attemptckalloc(items * size); }
DBusHandlerResult DBus_Message(DBusConnection *conn, DBusMessage *msg, void *data) { Tcl_HashTable *members; Tcl_HashEntry *memberPtr; Tcl_HashSearch search; Tcl_DBusEvent *evPtr; Tcl_DBusMethodData *mPtr = NULL; Tcl_DBusSignalData *sPtr; DBusMessage *err; int i, len; char buffer[DBUS_MAXIMUM_NAME_LENGTH + 1], *errbuf; const char *path, *name, *intf, *str[2]; Tcl_DBusHandlerData* dataPtr = data; path = dbus_message_get_path(msg); intf = dbus_message_get_interface(msg); name = dbus_message_get_member(msg); if (intf != NULL) { intf = strncpy(buffer, intf, DBUS_MAXIMUM_NAME_LENGTH); buffer[DBUS_MAXIMUM_NAME_LENGTH] = '\0'; len = strlen(intf); buffer[len++] = '.'; name = strncpy(buffer + len, name, DBUS_MAXIMUM_NAME_LENGTH - len); } switch (dbus_message_get_type(msg)) { case DBUS_MESSAGE_TYPE_METHOD_CALL: if (intf != NULL) { mPtr = DBus_FindListeners(dataPtr->dbus, path, intf, TRUE); if (mPtr == NULL) { /* Check if a method was defined without a path */ mPtr = DBus_FindListeners(dataPtr->dbus, "", intf, TRUE); } } if (intf == NULL || mPtr == NULL) { /* TODO: Method calls are not required to specify an interface */ /* So should really also check for *.name if intf == NULL */ /* Check if a method was defined without an interface */ mPtr = DBus_FindListeners(dataPtr->dbus, path, name, TRUE); if (mPtr == NULL) { /* Check if a method was defined with no path and no interface */ mPtr = DBus_FindListeners(dataPtr->dbus, "", name, TRUE); } } if (mPtr == NULL) { /* Check if an unknown handler was defined for the path */ mPtr = DBus_FindListeners(dataPtr->dbus, path, "", TRUE); if (mPtr == NULL) { /* Check if a global unknown handler was defined */ mPtr = DBus_FindListeners(dataPtr->dbus, "", "", TRUE); } } if (mPtr == NULL) { /* There is no script-level handler for this method call */ if (dbus_message_get_no_reply(msg)) /* The caller is not interested in succes or failure */ break; /* Allocate space and construct the error message */ /* Each of name, interface, and signature can only be 255 chars */ /* long, but path is unlimited. So base the amount of space */ /* to request on the length of the path string */ if ((errbuf = attemptckalloc(strlen(path) + 1024)) != NULL) { sprintf(errbuf, "No such method '%s' in interface '%s' " "at object path '%s' (signature '%s')", name, dbus_message_get_interface(msg), path, dbus_message_get_signature(msg)); } /* Send the error back to the caller */ err = dbus_message_new_error(msg, DBUS_ERROR_UNKNOWN_METHOD, errbuf); if (dbus_connection_send(conn, err, NULL)) { dbus_connection_flush(conn); } /* Free up the used resources */ dbus_message_unref(err); if (errbuf != NULL) ckfree(errbuf); break; } evPtr = (Tcl_DBusEvent *) ckalloc(sizeof(Tcl_DBusEvent)); evPtr->event.proc = DBus_EventHandler; evPtr->interp = mPtr->interp; evPtr->script = mPtr->script; Tcl_IncrRefCount(evPtr->script); evPtr->conn = mPtr->conn; evPtr->msg = msg; evPtr->flags = mPtr->flags; dbus_message_ref(msg); if (dbus_message_get_no_reply(msg)) /* Don't report the result of the event handler */ evPtr->flags |= DBUSFLAG_NOREPLY; Tcl_QueueEvent((Tcl_Event *) evPtr, TCL_QUEUE_TAIL); break; case DBUS_MESSAGE_TYPE_METHOD_RETURN: break; case DBUS_MESSAGE_TYPE_ERROR: break; case DBUS_MESSAGE_TYPE_SIGNAL: str[0] = intf; str[1] = name; for (i = 0; i < 2; i++) { if (str[i] == NULL) continue; members = DBus_FindListeners(dataPtr->dbus, path, str[i], FALSE); if (members == NULL) { members = DBus_FindListeners(dataPtr->dbus, "", str[i], FALSE); if (members == NULL) continue; } /* Queue execution of listeners for this signal in all interpreters */ for (memberPtr = Tcl_FirstHashEntry(members, &search); memberPtr != NULL; memberPtr = Tcl_NextHashEntry(&search)) { evPtr = (Tcl_DBusEvent *) ckalloc(sizeof(Tcl_DBusEvent)); sPtr = (Tcl_DBusSignalData *) Tcl_GetHashValue(memberPtr); evPtr->event.proc = DBus_EventHandler; evPtr->interp = (Tcl_Interp *) Tcl_GetHashKey(members, memberPtr); evPtr->script = sPtr->script; Tcl_IncrRefCount(evPtr->script); evPtr->conn = conn; evPtr->msg = msg; /* Never report the result of a signal handler */ evPtr->flags = sPtr->flags | DBUSFLAG_NOREPLY; dbus_message_ref(msg); Tcl_QueueEvent((Tcl_Event *) evPtr, TCL_QUEUE_TAIL); } } break; } return DBUS_HANDLER_RESULT_HANDLED; }
static int RasterizeSVG( Tcl_Interp *interp, Tk_PhotoHandle imageHandle, NSVGimage *nsvgImage, int destX, int destY, int width, int height, int srcX, int srcY, RastOpts *ropts) { int w, h, c; NSVGrasterizer *rast; unsigned char *imgData; Tk_PhotoImageBlock svgblock; w = (int) ceil(nsvgImage->width * ropts->scale); h = (int) ceil(nsvgImage->height * ropts->scale); rast = nsvgCreateRasterizer(); if (rast == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj("cannot initialize rasterizer", -1)); Tcl_SetErrorCode(interp, "TK", "IMAGE", "SVG", "RASTERIZER_ERROR", NULL); goto cleanAST; } imgData = attemptckalloc(w * h *4); if (imgData == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj("cannot alloc image buffer", -1)); Tcl_SetErrorCode(interp, "TK", "IMAGE", "SVG", "OUT_OF_MEMORY", NULL); goto cleanRAST; } nsvgRasterize(rast, nsvgImage, (float) ropts->x, (float) ropts->y, (float) ropts->scale, imgData, w, h, w * 4); /* transfer the data to a photo block */ svgblock.pixelPtr = imgData; svgblock.width = w; svgblock.height = h; svgblock.pitch = w * 4; svgblock.pixelSize = 4; for (c = 0; c <= 3; c++) { svgblock.offset[c] = c; } if (Tk_PhotoExpand(interp, imageHandle, destX + width, destY + height) != TCL_OK) { goto cleanRAST; } if (Tk_PhotoPutBlock(interp, imageHandle, &svgblock, destX, destY, width, height, TK_PHOTO_COMPOSITE_SET) != TCL_OK) { goto cleanimg; } ckfree(imgData); nsvgDeleteRasterizer(rast); nsvgDelete(nsvgImage); return TCL_OK; cleanimg: ckfree(imgData); cleanRAST: nsvgDeleteRasterizer(rast); cleanAST: nsvgDelete(nsvgImage); return TCL_ERROR; }
static NSVGimage * ParseSVGWithOptions( Tcl_Interp *interp, const char *input, int length, Tcl_Obj *formatObj, RastOpts *ropts) { Tcl_Obj **objv = NULL; int objc = 0; double dpi = 96.0; char unit[3], *p; char *inputCopy = NULL; NSVGimage *nsvgImage; static const char *const fmtOptions[] = { "-dpi", "-scale", "-unit", NULL }; enum fmtOptions { OPT_DPI, OPT_SCALE, OPT_UNIT }; /* * The parser destroys the original input string, * therefore first duplicate. */ inputCopy = attemptckalloc(length+1); if (inputCopy == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj("cannot alloc data buffer", -1)); Tcl_SetErrorCode(interp, "TK", "IMAGE", "SVG", "OUT_OF_MEMORY", NULL); goto error; } memcpy(inputCopy, input, length); inputCopy[length] = '\0'; /* * Process elements of format specification as a list. */ strcpy(unit, "px"); ropts->x = ropts->y = 0.0; ropts->scale = 1.0; if ((formatObj != NULL) && Tcl_ListObjGetElements(interp, formatObj, &objc, &objv) != TCL_OK) { goto error; } for (; objc > 0 ; objc--, objv++) { int optIndex; /* * Ignore the "svg" part of the format specification. */ if (!strcasecmp(Tcl_GetString(objv[0]), "svg")) { continue; } if (Tcl_GetIndexFromObjStruct(interp, objv[0], fmtOptions, sizeof(char *), "option", 0, &optIndex) == TCL_ERROR) { goto error; } if (objc < 2) { ckfree(inputCopy); inputCopy = NULL; Tcl_WrongNumArgs(interp, 1, objv, "value"); goto error; } objc--; objv++; switch ((enum fmtOptions) optIndex) { case OPT_DPI: if (Tcl_GetDoubleFromObj(interp, objv[0], &dpi) == TCL_ERROR) { goto error; } if (dpi < 0.0) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "-dpi value must be positive", -1)); Tcl_SetErrorCode(interp, "TK", "IMAGE", "SVG", "BAD_DPI", NULL); goto error; } break; case OPT_SCALE: if (Tcl_GetDoubleFromObj(interp, objv[0], &ropts->scale) == TCL_ERROR) { goto error; } if (ropts->scale <= 0.0) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "-scale value must be positive", -1)); Tcl_SetErrorCode(interp, "TK", "IMAGE", "SVG", "BAD_SCALE", NULL); goto error; } break; case OPT_UNIT: p = Tcl_GetString(objv[0]); if ((p != NULL) && (p[0])) { strncpy(unit, p, 3); unit[2] = '\0'; } break; } } nsvgImage = nsvgParse(inputCopy, unit, (float) dpi); if (nsvgImage == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj("cannot parse SVG image", -1)); Tcl_SetErrorCode(interp, "TK", "IMAGE", "SVG", "PARSE_ERROR", NULL); goto error; } ckfree(inputCopy); return nsvgImage; error: if (inputCopy != NULL) { ckfree(inputCopy); } return NULL; }