static int datadropper_init(bContext *C, wmOperator *op)
{
	DataDropper *ddr;
	int index_dummy;
	StructRNA *type;

	SpaceType *st;
	ARegionType *art;

	st = BKE_spacetype_from_id(SPACE_VIEW3D);
	art = BKE_regiontype_from_id(st, RGN_TYPE_WINDOW);

	op->customdata = ddr = MEM_callocN(sizeof(DataDropper), "DataDropper");

	uiContextActiveProperty(C, &ddr->ptr, &ddr->prop, &index_dummy);

	if ((ddr->ptr.data == NULL) ||
	    (ddr->prop == NULL) ||
	    (RNA_property_editable(&ddr->ptr, ddr->prop) == false) ||
	    (RNA_property_type(ddr->prop) != PROP_POINTER))
	{
		return false;
	}

	ddr->art = art;
	ddr->draw_handle_pixel = ED_region_draw_cb_activate(art, datadropper_draw_cb, ddr, REGION_DRAW_POST_PIXEL);

	type = RNA_property_pointer_type(&ddr->ptr, ddr->prop);
	ddr->idcode = RNA_type_to_ID_code(type);
	BLI_assert(ddr->idcode != 0);
	ddr->idcode_name = BKE_idcode_to_name(ddr->idcode);

	return true;
}
static int datadropper_init(bContext *C, wmOperator *op)
{
  int index_dummy;
  StructRNA *type;

  SpaceType *st;
  ARegionType *art;

  st = BKE_spacetype_from_id(SPACE_VIEW3D);
  art = BKE_regiontype_from_id(st, RGN_TYPE_WINDOW);

  DataDropper *ddr = MEM_callocN(sizeof(DataDropper), __func__);

  uiBut *but = UI_context_active_but_prop_get(C, &ddr->ptr, &ddr->prop, &index_dummy);

  if ((ddr->ptr.data == NULL) || (ddr->prop == NULL) ||
      (RNA_property_editable(&ddr->ptr, ddr->prop) == false) ||
      (RNA_property_type(ddr->prop) != PROP_POINTER)) {
    MEM_freeN(ddr);
    return false;
  }
  op->customdata = ddr;

  ddr->is_undo = UI_but_flag_is_set(but, UI_BUT_UNDO);

  ddr->art = art;
  ddr->draw_handle_pixel = ED_region_draw_cb_activate(
      art, datadropper_draw_cb, ddr, REGION_DRAW_POST_PIXEL);

  type = RNA_property_pointer_type(&ddr->ptr, ddr->prop);
  ddr->idcode = RNA_type_to_ID_code(type);
  BLI_assert(ddr->idcode != 0);
  /* Note we can translate here (instead of on draw time),
   * because this struct has very short lifetime. */
  ddr->idcode_name = TIP_(BKE_idcode_to_name(ddr->idcode));

  PointerRNA ptr = RNA_property_pointer_get(&ddr->ptr, ddr->prop);
  ddr->init_id = ptr.id.data;

  return true;
}
static bool datadropper_poll(bContext *C)
{
  PointerRNA ptr;
  PropertyRNA *prop;
  int index_dummy;
  uiBut *but;

  /* data dropper only supports object data */
  if ((CTX_wm_window(C) != NULL) &&
      (but = UI_context_active_but_prop_get(C, &ptr, &prop, &index_dummy)) &&
      (but->type == UI_BTYPE_SEARCH_MENU) && (but->flag & UI_BUT_VALUE_CLEAR)) {
    if (prop && RNA_property_type(prop) == PROP_POINTER) {
      StructRNA *type = RNA_property_pointer_type(&ptr, prop);
      const short idcode = RNA_type_to_ID_code(type);
      if ((idcode == ID_OB) || OB_DATA_SUPPORT_ID(idcode)) {
        return 1;
      }
    }
  }

  return 0;
}