Cleanup: remove all strcpy calls in source/blender/editors/

Replace with STRNCPY or BLI_strncpy, while many cases were safe,
translated source strings could cause buffer overflows, see: #108917.
This commit is contained in:
Campbell Barton
2023-06-19 11:37:05 +10:00
parent fde76c8b4d
commit cf29e011be
39 changed files with 208 additions and 197 deletions

View File

@@ -32,6 +32,9 @@
int getname_anim_fcurve(char *name, ID *id, FCurve *fcu)
{
/* Could make an argument, it's a documented limit at the moment. */
const size_t name_maxncpy = 256;
int icon = 0;
/* sanity checks */
@@ -41,13 +44,13 @@ int getname_anim_fcurve(char *name, ID *id, FCurve *fcu)
if (ELEM(NULL, id, fcu, fcu->rna_path)) {
if (fcu == NULL) {
strcpy(name, TIP_("<invalid>"));
BLI_strncpy(name, TIP_("<invalid>"), name_maxncpy);
}
else if (fcu->rna_path == NULL) {
strcpy(name, TIP_("<no path>"));
BLI_strncpy(name, TIP_("<no path>"), name_maxncpy);
}
else { /* id == NULL */
BLI_snprintf(name, 256, "%s[%d]", fcu->rna_path, fcu->array_index);
BLI_snprintf(name, name_maxncpy, "%s[%d]", fcu->rna_path, fcu->array_index);
}
}
else {
@@ -171,10 +174,10 @@ int getname_anim_fcurve(char *name, ID *id, FCurve *fcu)
/* XXX we need to check for invalid names...
* XXX the name length limit needs to be passed in or as some define */
if (structname) {
BLI_snprintf(name, 256, "%s%s (%s)", arrayname, propname, structname);
BLI_snprintf(name, name_maxncpy, "%s%s (%s)", arrayname, propname, structname);
}
else {
BLI_snprintf(name, 256, "%s%s", arrayname, propname);
BLI_snprintf(name, name_maxncpy, "%s%s", arrayname, propname);
}
/* free temp name if nameprop is set */
@@ -193,7 +196,7 @@ int getname_anim_fcurve(char *name, ID *id, FCurve *fcu)
}
else {
/* invalid path */
BLI_snprintf(name, 256, "\"%s[%d]\"", fcu->rna_path, fcu->array_index);
BLI_snprintf(name, name_maxncpy, "\"%s[%d]\"", fcu->rna_path, fcu->array_index);
/* icon for this should be the icon for the base ID */
/* TODO: or should we just use the error icon? */

View File

@@ -497,10 +497,10 @@ static int poselib_blend_modal(bContext *C, wmOperator *op, const wmEvent *event
ED_slider_status_string_get(pbd->slider, slider_string, sizeof(slider_string));
if (pbd->state == POSE_BLEND_BLENDING) {
strcpy(tab_string, TIP_("[Tab] - Show original pose"));
STRNCPY(tab_string, TIP_("[Tab] - Show original pose"));
}
else {
strcpy(tab_string, TIP_("[Tab] - Show blended pose"));
STRNCPY(tab_string, TIP_("[Tab] - Show blended pose"));
}
SNPRINTF(status_string, "%s | %s | [Ctrl] - Flip Pose", tab_string, slider_string);

View File

@@ -941,21 +941,21 @@ static void pose_slide_draw_status(bContext *C, tPoseSlideOp *pso)
switch (pso->mode) {
case POSESLIDE_PUSH:
strcpy(mode_str, TIP_("Push Pose"));
STRNCPY(mode_str, TIP_("Push Pose"));
break;
case POSESLIDE_RELAX:
strcpy(mode_str, TIP_("Relax Pose"));
STRNCPY(mode_str, TIP_("Relax Pose"));
break;
case POSESLIDE_BREAKDOWN:
strcpy(mode_str, TIP_("Breakdown"));
STRNCPY(mode_str, TIP_("Breakdown"));
break;
case POSESLIDE_BLEND:
strcpy(mode_str, TIP_("Blend to Neighbor"));
STRNCPY(mode_str, TIP_("Blend to Neighbor"));
break;
default:
/* Unknown. */
strcpy(mode_str, TIP_("Sliding-Tool"));
STRNCPY(mode_str, TIP_("Sliding-Tool"));
break;
}

View File

@@ -1273,7 +1273,6 @@ void ED_curve_editnurb_make(Object *obedit)
actkey = BKE_keyblock_from_object(obedit);
if (actkey) {
// XXX strcpy(G.editModeTitleExtra, "(Key) ");
/* TODO(@ideasman42): undo_system: investigate why this was needed. */
#if 0
undo_editmode_clear();

View File

@@ -231,7 +231,7 @@ static int gpencil_layer_add_exec(bContext *C, wmOperator *op)
RNA_property_string_get(op->ptr, prop, name);
}
else {
strcpy(name, "GP_Layer");
STRNCPY(name, "GP_Layer");
}
bGPDlayer *gpl = BKE_gpencil_layer_addnew(gpd, name, true, false);

View File

@@ -1853,7 +1853,7 @@ static int gpencil_move_to_layer_exec(bContext *C, wmOperator *op)
RNA_property_string_get(op->ptr, prop, name);
}
else {
strcpy(name, "GP_Layer");
STRNCPY(name, "GP_Layer");
}
target_layer = BKE_gpencil_layer_addnew(gpd, name, true, false);
}

View File

@@ -735,24 +735,25 @@ typedef struct GPMatArray {
static uint get_material_type(MaterialGPencilStyle *gp_style,
bool use_stroke,
bool use_fill,
char *name)
char *name,
size_t name_maxncpy)
{
uint r_i = 0;
if ((use_stroke) && (use_fill)) {
switch (gp_style->mode) {
case GP_MATERIAL_MODE_LINE: {
r_i = 1;
strcpy(name, "Line Stroke-Fill");
BLI_strncpy(name, "Line Stroke-Fill", name_maxncpy);
break;
}
case GP_MATERIAL_MODE_DOT: {
r_i = 2;
strcpy(name, "Dots Stroke-Fill");
BLI_strncpy(name, "Dots Stroke-Fill", name_maxncpy);
break;
}
case GP_MATERIAL_MODE_SQUARE: {
r_i = 3;
strcpy(name, "Squares Stroke-Fill");
BLI_strncpy(name, "Squares Stroke-Fill", name_maxncpy);
break;
}
default:
@@ -763,17 +764,17 @@ static uint get_material_type(MaterialGPencilStyle *gp_style,
switch (gp_style->mode) {
case GP_MATERIAL_MODE_LINE: {
r_i = 4;
strcpy(name, "Line Stroke");
BLI_strncpy(name, "Line Stroke", name_maxncpy);
break;
}
case GP_MATERIAL_MODE_DOT: {
r_i = 5;
strcpy(name, "Dots Stroke");
BLI_strncpy(name, "Dots Stroke", name_maxncpy);
break;
}
case GP_MATERIAL_MODE_SQUARE: {
r_i = 6;
strcpy(name, "Squares Stroke");
BLI_strncpy(name, "Squares Stroke", name_maxncpy);
break;
}
default:
@@ -782,7 +783,7 @@ static uint get_material_type(MaterialGPencilStyle *gp_style,
}
else {
r_i = 7;
strcpy(name, "Solid Fill");
BLI_strncpy(name, "Solid Fill", name_maxncpy);
}
/* Create key TSSSSFFFF (T: Type S: Stroke Alpha F: Fill Alpha) */
@@ -878,7 +879,7 @@ static int gpencil_material_to_vertex_exec(bContext *C, wmOperator *op)
/* Only for no Stencil materials. */
if (!is_stencil) {
/* Create material type unique key by type and alpha. */
uint key = get_material_type(gp_style, use_stroke, use_fill, name);
uint key = get_material_type(gp_style, use_stroke, use_fill, name, sizeof(name));
/* Check if material exist. */
bool found = false;

View File

@@ -51,6 +51,9 @@ void ED_node_cursor_location_get(const struct SpaceNode *snode, float value[2]);
void ED_node_cursor_location_set(struct SpaceNode *snode, const float value[2]);
int ED_node_tree_path_length(struct SpaceNode *snode);
/**
* \param value: The path output at least the size of `ED_node_tree_path_length(snode) + 1`.
*/
void ED_node_tree_path_get(struct SpaceNode *snode, char *value);
void ED_node_tree_start(struct SpaceNode *snode,

View File

@@ -1026,8 +1026,8 @@ static void override_idtemplate_menu()
MenuType *mt;
mt = MEM_cnew<MenuType>(__func__);
strcpy(mt->idname, "UI_MT_idtemplate_liboverride");
strcpy(mt->label, N_("Library Override"));
STRNCPY(mt->idname, "UI_MT_idtemplate_liboverride");
STRNCPY(mt->label, N_("Library Override"));
mt->poll = override_idtemplate_menu_poll;
mt->draw = override_idtemplate_menu_draw;
WM_menutype_add(mt);

View File

@@ -214,9 +214,8 @@ static void ui_update_color_picker_buts_rgb(uiBut *from_but,
}
rgb_float_to_uchar(rgb_hex_uchar, rgb_hex);
SNPRINTF(col, "%02X%02X%02X", UNPACK3_EX((uint), rgb_hex_uchar, ));
strcpy(bt->poin, col);
const int col_len = SNPRINTF_RLEN(col, "%02X%02X%02X", UNPACK3_EX((uint), rgb_hex_uchar, ));
memcpy(bt->poin, col, col_len + 1);
}
else if (bt->str[1] == ' ') {
if (bt->str[0] == 'R') {

View File

@@ -123,9 +123,9 @@ static void hud_panel_operator_redo_draw(const bContext *C, Panel *panel)
static void hud_panels_register(ARegionType *art, int space_type, int region_type)
{
PanelType *pt = MEM_cnew<PanelType>(__func__);
strcpy(pt->idname, "OPERATOR_PT_redo");
strcpy(pt->label, N_("Redo"));
strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
STRNCPY(pt->idname, "OPERATOR_PT_redo");
STRNCPY(pt->label, N_("Redo"));
STRNCPY(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
pt->draw_header = hud_panel_operator_redo_draw_header;
pt->draw = hud_panel_operator_redo_draw;
pt->poll = hud_panel_operator_redo_poll;

View File

@@ -490,8 +490,9 @@ static bool add_collection_search_item(CollItemSearch *cis,
* removed). */
BKE_id_full_name_ui_prefix_get(
name_buf, static_cast<const ID *>(cis->data), false, UI_SEP_CHAR, &name_prefix_offset);
BLI_assert(strlen(name_buf) <= MEM_allocN_len(cis->name));
strcpy(cis->name, name_buf);
const int name_buf_len = strlen(name_buf);
BLI_assert(name_buf_len <= strlen(cis->name));
memcpy(cis->name, name_buf, name_buf_len + 1);
}
return UI_search_item_add(items,

View File

@@ -1571,7 +1571,7 @@ float UI_text_clip_middle_ex(const uiFontStyle *fstyle,
const float parts_strwidth = (okwidth - sep_strwidth) / 2.0f;
if (rpart) {
strcpy(rpart_buf, rpart);
STRNCPY(rpart_buf, rpart);
*rpart = '\0';
rpart = rpart_buf;
}

View File

@@ -737,7 +737,7 @@ static void *undomesh_from_editmesh(UndoMesh *um, BMEditMesh *em, Key *key, Undo
/* Copy the ID name characters to the mesh so code that depends on accessing the ID type can work
* on it. Necessary to use the attribute API. */
strcpy(um->me.id.name, "MEundomesh_from_editmesh");
STRNCPY(um->me.id.name, "MEundomesh_from_editmesh");
/* Runtime data is necessary for some asserts in other code, and the overhead of creating it for
* undo meshes should be low. */

View File

@@ -1449,7 +1449,7 @@ static int object_gpencil_add_exec(bContext *C, wmOperator *op)
md->source_type = LRT_SOURCE_SCENE;
}
/* Only created one layer and one material. */
strcpy(md->target_layer, ((bGPDlayer *)gpd->layers.first)->info);
STRNCPY(md->target_layer, ((bGPDlayer *)gpd->layers.first)->info);
md->target_material = BKE_gpencil_material(ob, 1);
if (md->target_material) {
id_us_plus(&md->target_material->id);

View File

@@ -1452,7 +1452,7 @@ static int constraint_delete_exec(bContext *C, wmOperator *op)
/* Store name temporarily for report. */
char name[MAX_NAME];
strcpy(name, con->name);
STRNCPY(name, con->name);
/* free the constraint */
if (BKE_constraint_remove_ex(lb, ob, con, true)) {
@@ -1525,7 +1525,7 @@ static int constraint_apply_exec(bContext *C, wmOperator *op)
/* Store name temporarily for report. */
char name[MAX_NAME];
strcpy(name, con->name);
STRNCPY(name, con->name);
const bool is_first_constraint = con != constraints->first;
/* Copy the constraint. */
@@ -1622,7 +1622,7 @@ static int constraint_copy_exec(bContext *C, wmOperator *op)
/* Store name temporarily for report. */
char name[MAX_NAME];
strcpy(name, con->name);
STRNCPY(name, con->name);
/* Copy the constraint. */
bConstraint *copy_con;

View File

@@ -20,6 +20,7 @@
#include "DNA_scene_types.h"
#include "BLI_listbase.h"
#include "BLI_string.h"
#include "BLI_string_utf8.h"
#include "BLI_string_utils.h"
#include "BLI_utildefines.h"
@@ -552,7 +553,7 @@ static int gpencil_modifier_remove_exec(bContext *C, wmOperator *op)
/* Store name temporarily for report. */
char name[MAX_NAME];
strcpy(name, md->name);
STRNCPY(name, md->name);
if (!ED_object_gpencil_modifier_remove(op->reports, bmain, ob, md)) {
return OPERATOR_CANCELLED;
@@ -735,7 +736,7 @@ static int gpencil_modifier_apply_exec(bContext *C, wmOperator *op)
char name[MAX_NAME];
if (do_report) {
reports_len = BLI_listbase_count(&op->reports->list);
strcpy(name, md->name); /* Store name temporarily since the modifier is removed. */
STRNCPY(name, md->name); /* Store name temporarily since the modifier is removed. */
}
if (!ED_object_gpencil_modifier_apply(bmain, op->reports, depsgraph, ob, md, apply_as)) {

View File

@@ -1517,7 +1517,7 @@ static int modifier_remove_exec(bContext *C, wmOperator *op)
/* Store name temporarily for report. */
char name[MAX_NAME];
strcpy(name, md->name);
STRNCPY(name, md->name);
if (!ED_object_modifier_remove(op->reports, bmain, scene, ob, md)) {
return OPERATOR_CANCELLED;
@@ -1769,7 +1769,7 @@ static int modifier_apply_exec_ex(bContext *C, wmOperator *op, int apply_as, boo
char name[MAX_NAME];
if (do_report) {
reports_len = BLI_listbase_count(&op->reports->list);
strcpy(name, md->name); /* Store name temporarily since the modifier is removed. */
STRNCPY(name, md->name); /* Store name temporarily since the modifier is removed. */
}
if (!ED_object_modifier_apply(

View File

@@ -488,7 +488,7 @@ static int shaderfx_remove_exec(bContext *C, wmOperator *op)
/* Store name temporarily for report. */
char name[MAX_NAME];
strcpy(name, fx->name);
STRNCPY(name, fx->name);
if (!ED_object_shaderfx_remove(op->reports, bmain, ob, fx)) {
return OPERATOR_CANCELLED;

View File

@@ -328,9 +328,9 @@ static void screen_user_menu_draw(const bContext *C, Menu *menu)
void ED_screen_user_menu_register(void)
{
MenuType *mt = MEM_callocN(sizeof(MenuType), __func__);
strcpy(mt->idname, "SCREEN_MT_user_menu");
strcpy(mt->label, N_("Quick Favorites"));
strcpy(mt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
STRNCPY(mt->idname, "SCREEN_MT_user_menu");
STRNCPY(mt->label, N_("Quick Favorites"));
STRNCPY(mt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
mt->draw = screen_user_menu_draw;
WM_menutype_add(mt);
}

View File

@@ -30,25 +30,25 @@ void action_buttons_register(ARegionType * /*art*/)
/* TODO: AnimData / Actions List */
pt = MEM_cnew<PanelType>("spacetype action panel properties");
strcpy(pt->idname, "ACTION_PT_properties");
strcpy(pt->label, N_("Active F-Curve"));
strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
STRNCPY(pt->idname, "ACTION_PT_properties");
STRNCPY(pt->label, N_("Active F-Curve"));
STRNCPY(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
pt->draw = action_anim_panel_properties;
pt->poll = action_anim_panel_poll;
BLI_addtail(&art->paneltypes, pt);
pt = MEM_cnew<PanelType>("spacetype action panel properties");
strcpy(pt->idname, "ACTION_PT_key_properties");
strcpy(pt->label, N_("Active Keyframe"));
strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
STRNCPY(pt->idname, "ACTION_PT_key_properties");
STRNCPY(pt->label, N_("Active Keyframe"));
STRNCPY(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
pt->draw = action_anim_panel_key_properties;
pt->poll = action_anim_panel_poll;
BLI_addtail(&art->paneltypes, pt);
pt = MEM_callocN(sizeof(PanelType), "spacetype action panel modifiers");
strcpy(pt->idname, "ACTION_PT_modifiers");
strcpy(pt->label, N_("Modifiers"));
strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
STRNCPY(pt->idname, "ACTION_PT_modifiers");
STRNCPY(pt->label, N_("Modifiers"));
STRNCPY(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
pt->draw = action_anim_panel_modifiers;
pt->poll = action_anim_panel_poll;
BLI_addtail(&art->paneltypes, pt);

View File

@@ -12,6 +12,7 @@
#include "MEM_guardedalloc.h"
#include "BLI_listbase.h"
#include "BLI_string.h"
#include "BLI_utildefines.h"
#include "BLT_translation.h"
@@ -1254,9 +1255,9 @@ static void buttons_panel_context_draw(const bContext *C, Panel *panel)
void buttons_context_register(ARegionType *art)
{
PanelType *pt = MEM_callocN(sizeof(PanelType), "spacetype buttons panel context");
strcpy(pt->idname, "PROPERTIES_PT_context");
strcpy(pt->label, N_("Context")); /* XXX C panels unavailable through RNA bpy.types! */
strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
STRNCPY(pt->idname, "PROPERTIES_PT_context");
STRNCPY(pt->label, N_("Context")); /* XXX C panels unavailable through RNA bpy.types! */
STRNCPY(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
pt->poll = buttons_panel_context_poll;
pt->draw = buttons_panel_context_draw;
pt->flag = PANEL_TYPE_NO_HEADER | PANEL_TYPE_NO_SEARCH;

View File

@@ -73,10 +73,10 @@ void ED_clip_buttons_register(ARegionType *art)
PanelType *pt;
pt = MEM_cnew<PanelType>("spacetype clip panel metadata");
strcpy(pt->idname, "CLIP_PT_metadata");
strcpy(pt->label, N_("Metadata"));
strcpy(pt->category, "Footage");
strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
STRNCPY(pt->idname, "CLIP_PT_metadata");
STRNCPY(pt->label, N_("Metadata"));
STRNCPY(pt->category, "Footage");
STRNCPY(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
pt->poll = metadata_panel_context_poll;
pt->draw = metadata_panel_context_draw;
pt->flag |= PANEL_TYPE_DEFAULT_CLOSED;

View File

@@ -273,7 +273,7 @@ static void draw_movieclip_notes(SpaceClip *sc, ARegion *region)
}
else {
if (sc->flag & SC_LOCK_SELECTION) {
strcpy(str, "Locked");
STRNCPY(str, "Locked");
}
}
@@ -1082,16 +1082,16 @@ static void draw_marker_texts(SpaceClip *sc,
pos[1] = pos[1] * zoomy - fontsize;
if (marker->flag & MARKER_DISABLED) {
strcpy(state, "disabled");
STRNCPY(state, "disabled");
}
else if (marker->framenr != ED_space_clip_get_clip_frame_number(sc)) {
strcpy(state, "estimated");
STRNCPY(state, "estimated");
}
else if (marker->flag & MARKER_TRACKED) {
strcpy(state, "tracked");
STRNCPY(state, "tracked");
}
else {
strcpy(state, "keyframed");
STRNCPY(state, "keyframed");
}
if (state[0]) {

View File

@@ -2023,9 +2023,9 @@ void file_external_operations_menu_register(void)
MenuType *mt;
mt = MEM_callocN(sizeof(MenuType), "spacetype file menu file operations");
strcpy(mt->idname, "FILEBROWSER_MT_operations_menu");
strcpy(mt->label, N_("External"));
strcpy(mt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
STRNCPY(mt->idname, "FILEBROWSER_MT_operations_menu");
STRNCPY(mt->label, N_("External"));
STRNCPY(mt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
mt->draw = file_os_operations_menu_draw;
mt->poll = file_os_operations_menu_poll;
WM_menutype_add(mt);

View File

@@ -94,9 +94,9 @@ void file_tool_props_region_panels_register(ARegionType *art)
PanelType *pt;
pt = MEM_callocN(sizeof(PanelType), "spacetype file operator properties");
strcpy(pt->idname, "FILE_PT_operator");
strcpy(pt->label, N_("Operator"));
strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
STRNCPY(pt->idname, "FILE_PT_operator");
STRNCPY(pt->label, N_("Operator"));
STRNCPY(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
pt->flag = PANEL_TYPE_NO_HEADER;
pt->poll = file_panel_operator_poll;
pt->draw_header = file_panel_operator_header;
@@ -208,9 +208,9 @@ void file_execute_region_panels_register(ARegionType *art)
PanelType *pt;
pt = MEM_callocN(sizeof(PanelType), "spacetype file execution buttons");
strcpy(pt->idname, "FILE_PT_execution_buttons");
strcpy(pt->label, N_("Execute Buttons"));
strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
STRNCPY(pt->idname, "FILE_PT_execution_buttons");
STRNCPY(pt->label, N_("Execute Buttons"));
STRNCPY(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
pt->flag = PANEL_TYPE_NO_HEADER;
pt->poll = file_panel_operator_poll;
pt->draw = file_panel_execution_buttons_draw;
@@ -260,9 +260,9 @@ void file_tools_region_panels_register(ARegionType *art)
PanelType *pt;
pt = MEM_callocN(sizeof(PanelType), "spacetype file asset catalog buttons");
strcpy(pt->idname, "FILE_PT_asset_catalog_buttons");
strcpy(pt->label, N_("Asset Catalogs"));
strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
STRNCPY(pt->idname, "FILE_PT_asset_catalog_buttons");
STRNCPY(pt->label, N_("Asset Catalogs"));
STRNCPY(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
pt->flag = PANEL_TYPE_NO_HEADER;
pt->poll = file_panel_asset_browsing_poll;
pt->draw = file_panel_asset_catalog_buttons_draw;

View File

@@ -1345,7 +1345,7 @@ static void parent_dir_until_exists_or_default_root(char *dir)
#ifdef WIN32
BLI_windows_get_default_root_dir(dir);
#else
strcpy(dir, "/");
ARRAY_SET_ITEMS(dir, '/', '\0');
#endif
}
}

View File

@@ -205,7 +205,7 @@ static void graph_panel_properties(const bContext *C, Panel *panel)
acf->name(ale, name);
}
else {
strcpy(name, IFACE_("<invalid>"));
STRNCPY(name, IFACE_("<invalid>"));
icon = ICON_ERROR;
}
@@ -1469,47 +1469,47 @@ void graph_buttons_register(ARegionType *art)
PanelType *pt;
pt = MEM_callocN(sizeof(PanelType), "spacetype graph panel properties");
strcpy(pt->idname, "GRAPH_PT_properties");
strcpy(pt->label, N_("Active F-Curve"));
strcpy(pt->category, "F-Curve");
strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
STRNCPY(pt->idname, "GRAPH_PT_properties");
STRNCPY(pt->label, N_("Active F-Curve"));
STRNCPY(pt->category, "F-Curve");
STRNCPY(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
pt->draw = graph_panel_properties;
pt->poll = graph_panel_poll;
BLI_addtail(&art->paneltypes, pt);
pt = MEM_callocN(sizeof(PanelType), "spacetype graph panel properties");
strcpy(pt->idname, "GRAPH_PT_key_properties");
strcpy(pt->label, N_("Active Keyframe"));
strcpy(pt->category, "F-Curve");
strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
STRNCPY(pt->idname, "GRAPH_PT_key_properties");
STRNCPY(pt->label, N_("Active Keyframe"));
STRNCPY(pt->category, "F-Curve");
STRNCPY(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
pt->draw = graph_panel_key_properties;
pt->poll = graph_panel_poll;
BLI_addtail(&art->paneltypes, pt);
pt = MEM_callocN(sizeof(PanelType), "spacetype graph panel drivers driven");
strcpy(pt->idname, "GRAPH_PT_driven_property");
strcpy(pt->label, N_("Driven Property"));
strcpy(pt->category, "Drivers");
strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
STRNCPY(pt->idname, "GRAPH_PT_driven_property");
STRNCPY(pt->label, N_("Driven Property"));
STRNCPY(pt->category, "Drivers");
STRNCPY(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
pt->draw = graph_panel_driven_property;
pt->poll = graph_panel_drivers_poll;
BLI_addtail(&art->paneltypes, pt);
pt = MEM_callocN(sizeof(PanelType), "spacetype graph panel drivers");
strcpy(pt->idname, "GRAPH_PT_drivers");
strcpy(pt->label, N_("Driver"));
strcpy(pt->category, "Drivers");
strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
STRNCPY(pt->idname, "GRAPH_PT_drivers");
STRNCPY(pt->label, N_("Driver"));
STRNCPY(pt->category, "Drivers");
STRNCPY(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
pt->draw = graph_panel_drivers;
pt->draw_header = graph_panel_drivers_header;
pt->poll = graph_panel_drivers_poll;
BLI_addtail(&art->paneltypes, pt);
pt = MEM_callocN(sizeof(PanelType), "spacetype graph panel drivers popover");
strcpy(pt->idname, "GRAPH_PT_drivers_popover");
strcpy(pt->label, N_("Add/Edit Driver"));
strcpy(pt->category, "Drivers");
strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
STRNCPY(pt->idname, "GRAPH_PT_drivers_popover");
STRNCPY(pt->label, N_("Add/Edit Driver"));
STRNCPY(pt->category, "Drivers");
STRNCPY(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
pt->draw = graph_panel_drivers_popover;
pt->poll = graph_panel_drivers_popover_poll;
BLI_addtail(&art->paneltypes, pt);
@@ -1518,10 +1518,10 @@ void graph_buttons_register(ARegionType *art)
WM_paneltype_add(pt);
pt = MEM_callocN(sizeof(PanelType), "spacetype graph panel modifiers");
strcpy(pt->idname, "GRAPH_PT_modifiers");
strcpy(pt->label, N_("Modifiers"));
strcpy(pt->category, "Modifiers");
strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
STRNCPY(pt->idname, "GRAPH_PT_modifiers");
STRNCPY(pt->label, N_("Modifiers"));
STRNCPY(pt->category, "Modifiers");
STRNCPY(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
pt->flag = PANEL_TYPE_NO_HEADER;
pt->draw = graph_panel_modifiers;
pt->poll = graph_panel_poll;
@@ -1531,10 +1531,10 @@ void graph_buttons_register(ARegionType *art)
ANIM_modifier_panels_register_graph_only(art, GRAPH_FMODIFIER_PANEL_PREFIX, graph_panel_poll);
pt = MEM_callocN(sizeof(PanelType), "spacetype graph panel view");
strcpy(pt->idname, "GRAPH_PT_view");
strcpy(pt->label, N_("Show Cursor"));
strcpy(pt->category, "View");
strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
STRNCPY(pt->idname, "GRAPH_PT_view");
STRNCPY(pt->label, N_("Show Cursor"));
STRNCPY(pt->category, "View");
STRNCPY(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
pt->draw = graph_panel_cursor;
pt->draw_header = graph_panel_cursor_header;
BLI_addtail(&art->paneltypes, pt);

View File

@@ -125,7 +125,7 @@ static void common_draw_status_header(bContext *C, tGraphSliderOp *gso, const ch
ED_slider_status_string_get(gso->slider, slider_string, UI_MAX_DRAW_STR);
strcpy(mode_str, TIP_(operator_name));
STRNCPY(mode_str, TIP_(operator_name));
if (hasNumInput(&gso->num)) {
char str_ofs[NUM_STR_REP_LEN];
@@ -424,7 +424,7 @@ static void decimate_draw_status(bContext *C, tGraphSliderOp *gso)
ED_slider_status_string_get(gso->slider, slider_string, UI_MAX_DRAW_STR);
strcpy(mode_str, TIP_("Decimate Keyframes"));
STRNCPY(mode_str, TIP_("Decimate Keyframes"));
if (hasNumInput(&gso->num)) {
char str_ofs[NUM_STR_REP_LEN];

View File

@@ -1296,10 +1296,10 @@ void image_buttons_register(ARegionType *art)
PanelType *pt;
pt = MEM_callocN(sizeof(PanelType), "spacetype image panel metadata");
strcpy(pt->idname, "IMAGE_PT_metadata");
strcpy(pt->label, N_("Metadata"));
strcpy(pt->category, "Image");
strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
STRNCPY(pt->idname, "IMAGE_PT_metadata");
STRNCPY(pt->label, N_("Metadata"));
STRNCPY(pt->category, "Image");
STRNCPY(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
pt->order = 10;
pt->poll = metadata_panel_context_poll;
pt->draw = metadata_panel_context_draw;

View File

@@ -610,50 +610,50 @@ void nla_buttons_register(ARegionType *art)
PanelType *pt;
pt = MEM_cnew<PanelType>("spacetype nla panel animdata");
strcpy(pt->idname, "NLA_PT_animdata");
strcpy(pt->label, N_("Animation Data"));
strcpy(pt->category, "Edited Action");
strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
STRNCPY(pt->idname, "NLA_PT_animdata");
STRNCPY(pt->label, N_("Animation Data"));
STRNCPY(pt->category, "Edited Action");
STRNCPY(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
pt->flag = PANEL_TYPE_NO_HEADER;
pt->draw = nla_panel_animdata;
pt->poll = nla_animdata_panel_poll;
BLI_addtail(&art->paneltypes, pt);
pt = MEM_cnew<PanelType>("spacetype nla panel properties");
strcpy(pt->idname, "NLA_PT_stripname");
strcpy(pt->label, N_("Active Strip Name"));
strcpy(pt->category, "Strip");
strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
STRNCPY(pt->idname, "NLA_PT_stripname");
STRNCPY(pt->label, N_("Active Strip Name"));
STRNCPY(pt->category, "Strip");
STRNCPY(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
pt->flag = PANEL_TYPE_NO_HEADER;
pt->draw = nla_panel_stripname;
pt->poll = nla_strip_panel_poll;
BLI_addtail(&art->paneltypes, pt);
PanelType *pt_properties = pt = MEM_cnew<PanelType>("spacetype nla panel properties");
strcpy(pt->idname, "NLA_PT_properties");
strcpy(pt->label, N_("Active Strip"));
strcpy(pt->category, "Strip");
strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
STRNCPY(pt->idname, "NLA_PT_properties");
STRNCPY(pt->label, N_("Active Strip"));
STRNCPY(pt->category, "Strip");
STRNCPY(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
pt->draw = nla_panel_properties;
pt->poll = nla_strip_panel_poll;
BLI_addtail(&art->paneltypes, pt);
pt = MEM_cnew<PanelType>("spacetype nla panel properties");
strcpy(pt->idname, "NLA_PT_actionclip");
strcpy(pt->label, N_("Action Clip"));
strcpy(pt->category, "Strip");
strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
STRNCPY(pt->idname, "NLA_PT_actionclip");
STRNCPY(pt->label, N_("Action Clip"));
STRNCPY(pt->category, "Strip");
STRNCPY(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
pt->draw = nla_panel_actclip;
pt->flag = PANEL_TYPE_DEFAULT_CLOSED;
pt->poll = nla_strip_actclip_panel_poll;
BLI_addtail(&art->paneltypes, pt);
pt = MEM_cnew<PanelType>("spacetype nla panel evaluation");
strcpy(pt->idname, "NLA_PT_evaluation");
strcpy(pt->parent_id, "NLA_PT_properties");
strcpy(pt->label, N_("Animated Influence"));
strcpy(pt->category, "Strip");
strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
STRNCPY(pt->idname, "NLA_PT_evaluation");
STRNCPY(pt->parent_id, "NLA_PT_properties");
STRNCPY(pt->label, N_("Animated Influence"));
STRNCPY(pt->category, "Strip");
STRNCPY(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
pt->draw = nla_panel_evaluation;
pt->draw_header = nla_panel_animated_influence_header;
pt->parent = pt_properties;
@@ -663,11 +663,11 @@ void nla_buttons_register(ARegionType *art)
BLI_addtail(&art->paneltypes, pt);
pt = MEM_cnew<PanelType>("spacetype nla panel animated strip time");
strcpy(pt->idname, "NLA_PT_animated_strip_time");
strcpy(pt->parent_id, "NLA_PT_properties");
strcpy(pt->label, N_("Animated Strip Time"));
strcpy(pt->category, "Strip");
strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
STRNCPY(pt->idname, "NLA_PT_animated_strip_time");
STRNCPY(pt->parent_id, "NLA_PT_properties");
STRNCPY(pt->label, N_("Animated Strip Time"));
STRNCPY(pt->category, "Strip");
STRNCPY(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
pt->draw = nla_panel_animated_strip_time;
pt->draw_header = nla_panel_animated_strip_time_header;
pt->parent = pt_properties;
@@ -677,10 +677,10 @@ void nla_buttons_register(ARegionType *art)
BLI_addtail(&art->paneltypes, pt);
pt = MEM_cnew<PanelType>("spacetype nla panel modifiers");
strcpy(pt->idname, "NLA_PT_modifiers");
strcpy(pt->label, N_("Modifiers"));
strcpy(pt->category, "Modifiers");
strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
STRNCPY(pt->idname, "NLA_PT_modifiers");
STRNCPY(pt->label, N_("Modifiers"));
STRNCPY(pt->category, "Modifiers");
STRNCPY(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
pt->draw = nla_panel_modifiers;
pt->poll = nla_strip_eval_panel_poll;
pt->flag = PANEL_TYPE_NO_HEADER;

View File

@@ -178,18 +178,20 @@ int ED_node_tree_path_length(SpaceNode *snode)
void ED_node_tree_path_get(SpaceNode *snode, char *value)
{
int i = 0;
value[0] = '\0';
#ifndef NDEBUG
const char *value_orig = value;
#endif
/* Note that the caller ensures there is enough space available. */
LISTBASE_FOREACH_INDEX (bNodeTreePath *, path, &snode->treepath, i) {
if (i == 0) {
strcpy(value, path->display_name);
value += strlen(path->display_name);
}
else {
BLI_sprintf(value, "/%s", path->display_name);
value += strlen(path->display_name) + 1;
const int len = strlen(path->display_name);
if (i != 0) {
*value++ = '/';
}
memcpy(value, path->display_name, len);
value += len;
}
*value = '\0';
BLI_assert(ptrdiff_t(ED_node_tree_path_length(snode)) == ptrdiff_t(value - value_orig));
}
void ED_node_set_active_viewer_key(SpaceNode *snode)
@@ -247,7 +249,7 @@ static SpaceLink *node_create(const ScrArea * /*area*/, const Scene * /*scene*/)
/* select the first tree type for valid type */
NODE_TREE_TYPES_BEGIN (treetype) {
strcpy(snode->tree_idname, treetype->idname);
STRNCPY(snode->tree_idname, treetype->idname);
break;
}
NODE_TREE_TYPES_END;

View File

@@ -85,9 +85,9 @@ void sequencer_buttons_register(ARegionType *art)
#if 0
pt = MEM_callocN(sizeof(PanelType), "spacetype sequencer panel gpencil");
strcpy(pt->idname, "SEQUENCER_PT_gpencil");
strcpy(pt->label, N_("Grease Pencil"));
strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
STRNCPY(pt->idname, "SEQUENCER_PT_gpencil");
STRNCPY(pt->label, N_("Grease Pencil"));
STRNCPY(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
pt->draw_header = ED_gpencil_panel_standard_header;
pt->draw = ED_gpencil_panel_standard;
pt->poll = sequencer_grease_pencil_panel_poll;
@@ -95,10 +95,10 @@ void sequencer_buttons_register(ARegionType *art)
#endif
pt = MEM_cnew<PanelType>("spacetype sequencer panel metadata");
strcpy(pt->idname, "SEQUENCER_PT_metadata");
strcpy(pt->label, N_("Metadata"));
strcpy(pt->category, "Metadata");
strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
STRNCPY(pt->idname, "SEQUENCER_PT_metadata");
STRNCPY(pt->label, N_("Metadata"));
STRNCPY(pt->category, "Metadata");
STRNCPY(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
pt->poll = metadata_panel_context_poll;
pt->draw = metadata_panel_context_draw;
pt->order = 10;

View File

@@ -14,6 +14,7 @@
#include "BLI_blenlib.h"
#include "BLI_math.h"
#include "BLI_string.h"
#include "BLI_timecode.h"
#include "BLI_utildefines.h"
@@ -2016,7 +2017,7 @@ static int sequencer_meta_make_exec(bContext *C, wmOperator *op)
}
seqm->machine = active_seq ? active_seq->machine : channel_max;
strcpy(seqm->name + 2, "MetaStrip");
BLI_strncpy(seqm->name + 2, "MetaStrip", sizeof(seqm->name) - 2);
SEQ_sequence_base_unique_name_recursive(scene, &ed->seqbase, seqm);
seqm->start = meta_start_frame;
seqm->len = meta_end_frame - meta_start_frame;

View File

@@ -14,9 +14,9 @@ namespace blender::ed::spreadsheet {
void spreadsheet_data_set_region_panels_register(ARegionType &region_type)
{
PanelType *panel_type = MEM_cnew<PanelType>(__func__);
strcpy(panel_type->idname, "SPREADSHEET_PT_data_set");
strcpy(panel_type->label, N_("Data Set"));
strcpy(panel_type->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
STRNCPY(panel_type->idname, "SPREADSHEET_PT_data_set");
STRNCPY(panel_type->label, N_("Data Set"));
STRNCPY(panel_type->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
panel_type->flag = PANEL_TYPE_NO_HEADER;
panel_type->draw = spreadsheet_data_set_panel_draw;
BLI_addtail(&region_type.paneltypes, panel_type);

View File

@@ -341,10 +341,10 @@ void register_row_filter_panels(ARegionType &region_type)
{
{
PanelType *panel_type = MEM_cnew<PanelType>(__func__);
strcpy(panel_type->idname, "SPREADSHEET_PT_row_filters");
strcpy(panel_type->label, N_("Filters"));
strcpy(panel_type->category, "Filters");
strcpy(panel_type->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
STRNCPY(panel_type->idname, "SPREADSHEET_PT_row_filters");
STRNCPY(panel_type->label, N_("Filters"));
STRNCPY(panel_type->category, "Filters");
STRNCPY(panel_type->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
panel_type->flag = PANEL_TYPE_NO_HEADER;
panel_type->draw = spreadsheet_row_filters_layout;
BLI_addtail(&region_type.paneltypes, panel_type);
@@ -352,10 +352,10 @@ void register_row_filter_panels(ARegionType &region_type)
{
PanelType *panel_type = MEM_cnew<PanelType>(__func__);
strcpy(panel_type->idname, "SPREADSHEET_PT_filter");
strcpy(panel_type->label, "");
strcpy(panel_type->category, "Filters");
strcpy(panel_type->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
STRNCPY(panel_type->idname, "SPREADSHEET_PT_filter");
STRNCPY(panel_type->label, "");
STRNCPY(panel_type->category, "Filters");
STRNCPY(panel_type->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
panel_type->flag = PANEL_TYPE_INSTANCED | PANEL_TYPE_HEADER_EXPAND;
panel_type->draw_header = spreadsheet_filter_panel_draw_header;
panel_type->draw = spreadsheet_filter_panel_draw;

View File

@@ -212,9 +212,9 @@ static void recent_files_menu_register(void)
MenuType *mt;
mt = MEM_callocN(sizeof(MenuType), "spacetype info menu recent files");
strcpy(mt->idname, "TOPBAR_MT_file_open_recent");
strcpy(mt->label, N_("Open Recent"));
strcpy(mt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
STRNCPY(mt->idname, "TOPBAR_MT_file_open_recent");
STRNCPY(mt->label, N_("Open Recent"));
STRNCPY(mt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
mt->draw = recent_files_menu_draw;
WM_menutype_add(mt);
}
@@ -270,9 +270,9 @@ static void undo_history_menu_register(void)
MenuType *mt;
mt = MEM_callocN(sizeof(MenuType), __func__);
strcpy(mt->idname, "TOPBAR_MT_undo_history");
strcpy(mt->label, N_("Undo History"));
strcpy(mt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
STRNCPY(mt->idname, "TOPBAR_MT_undo_history");
STRNCPY(mt->label, N_("Undo History"));
STRNCPY(mt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
mt->draw = undo_history_draw_menu;
WM_menutype_add(mt);
}

View File

@@ -1799,19 +1799,19 @@ void view3d_buttons_register(ARegionType *art)
PanelType *pt;
pt = MEM_callocN(sizeof(PanelType), "spacetype view3d panel object");
strcpy(pt->idname, "VIEW3D_PT_transform");
strcpy(pt->label, N_("Transform")); /* XXX C panels unavailable through RNA bpy.types! */
strcpy(pt->category, "Item");
strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
STRNCPY(pt->idname, "VIEW3D_PT_transform");
STRNCPY(pt->label, N_("Transform")); /* XXX C panels unavailable through RNA bpy.types! */
STRNCPY(pt->category, "Item");
STRNCPY(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
pt->draw = view3d_panel_transform;
pt->poll = view3d_panel_transform_poll;
BLI_addtail(&art->paneltypes, pt);
pt = MEM_callocN(sizeof(PanelType), "spacetype view3d panel vgroup");
strcpy(pt->idname, "VIEW3D_PT_vgroup");
strcpy(pt->label, N_("Vertex Weights")); /* XXX C panels unavailable through RNA bpy.types! */
strcpy(pt->category, "Item");
strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
STRNCPY(pt->idname, "VIEW3D_PT_vgroup");
STRNCPY(pt->label, N_("Vertex Weights")); /* XXX C panels unavailable through RNA bpy.types! */
STRNCPY(pt->category, "Item");
STRNCPY(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
pt->draw = view3d_panel_vgroup;
pt->poll = view3d_panel_vgroup_poll;
BLI_addtail(&art->paneltypes, pt);
@@ -1819,9 +1819,9 @@ void view3d_buttons_register(ARegionType *art)
MenuType *mt;
mt = MEM_callocN(sizeof(MenuType), "spacetype view3d menu collections");
strcpy(mt->idname, "VIEW3D_MT_collection");
strcpy(mt->label, N_("Collection"));
strcpy(mt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
STRNCPY(mt->idname, "VIEW3D_MT_collection");
STRNCPY(mt->label, N_("Collection"));
STRNCPY(mt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
mt->draw = hide_collections_menu_draw;
WM_menutype_add(mt);
}

View File

@@ -263,10 +263,10 @@ void ED_uvedit_buttons_register(ARegionType *art)
{
PanelType *pt = MEM_cnew<PanelType>(__func__);
strcpy(pt->idname, "IMAGE_PT_uv");
strcpy(pt->label, N_("UV Vertex")); /* XXX C panels unavailable through RNA bpy.types! */
STRNCPY(pt->idname, "IMAGE_PT_uv");
STRNCPY(pt->label, N_("UV Vertex")); /* XXX C panels unavailable through RNA bpy.types! */
/* Could be 'Item' matching 3D view, avoid new tab for two buttons. */
strcpy(pt->category, "Image");
STRNCPY(pt->category, "Image");
pt->draw = image_panel_uv;
pt->poll = image_panel_uv_poll;
BLI_addtail(&art->paneltypes, pt);