Merge branch 'master' into blender2.8
This commit is contained in:
commit
5ae6a3b6b6
|
@ -155,15 +155,7 @@ void GHOST_ContextGLX::initContextGLXEW()
|
|||
|
||||
GHOST_TSuccess GHOST_ContextGLX::initializeDrawingContext()
|
||||
{
|
||||
#ifdef WITH_X11_XINPUT
|
||||
/* use our own event handlers to avoid exiting blender,
|
||||
* this would happen for eg:
|
||||
* if you open blender, unplug a tablet, then open a new window. */
|
||||
XErrorHandler old_handler = XSetErrorHandler (GHOST_X11_ApplicationErrorHandler );
|
||||
XIOErrorHandler old_handler_io = XSetIOErrorHandler(GHOST_X11_ApplicationIOErrorHandler);
|
||||
#endif
|
||||
|
||||
|
||||
GHOST_X11_ERROR_HANDLERS_OVERRIDE(handler_store);
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* Begin Inline Glew */
|
||||
|
@ -350,11 +342,8 @@ const bool GLXEW_ARB_create_context_robustness =
|
|||
success = GHOST_kFailure;
|
||||
}
|
||||
|
||||
#ifdef WITH_X11_XINPUT
|
||||
/* Restore handler */
|
||||
XSetErrorHandler (old_handler);
|
||||
XSetIOErrorHandler(old_handler_io);
|
||||
#endif
|
||||
|
||||
GHOST_X11_ERROR_HANDLERS_RESTORE(handler_store);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
|
|
@ -73,6 +73,10 @@
|
|||
/* for debugging - so we can breakpoint X11 errors */
|
||||
// #define USE_X11_ERROR_HANDLERS
|
||||
|
||||
#ifdef WITH_X11_XINPUT
|
||||
# define USE_XINPUT_HOTPLUG
|
||||
#endif
|
||||
|
||||
/* see [#34039] Fix Alt key glitch on Unity desktop */
|
||||
#define USE_UNITY_WORKAROUND
|
||||
|
||||
|
@ -169,11 +173,36 @@ GHOST_SystemX11(
|
|||
}
|
||||
|
||||
#ifdef WITH_X11_XINPUT
|
||||
/* detect if we have xinput (for reuse) */
|
||||
{
|
||||
memset(&m_xinput_version, 0, sizeof(m_xinput_version));
|
||||
XExtensionVersion *version = XGetExtensionVersion(m_display, INAME);
|
||||
if (version && (version != (XExtensionVersion *)NoSuchExtension)) {
|
||||
if (version->present) {
|
||||
m_xinput_version = *version;
|
||||
}
|
||||
XFree(version);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_XINPUT_HOTPLUG
|
||||
if (m_xinput_version.present) {
|
||||
XEventClass class_presence;
|
||||
int xi_presence;
|
||||
DevicePresence(m_display, xi_presence, class_presence);
|
||||
XSelectExtensionEvent(
|
||||
m_display,
|
||||
RootWindow(m_display, DefaultScreen(m_display)),
|
||||
&class_presence, 1);
|
||||
(void)xi_presence;
|
||||
}
|
||||
#endif /* USE_XINPUT_HOTPLUG */
|
||||
|
||||
/* initialize incase X11 fails to load */
|
||||
memset(&m_xtablet, 0, sizeof(m_xtablet));
|
||||
|
||||
initXInputDevices();
|
||||
#endif
|
||||
refreshXInputDevices();
|
||||
#endif /* WITH_X11_XINPUT */
|
||||
}
|
||||
|
||||
GHOST_SystemX11::
|
||||
|
@ -627,8 +656,13 @@ static bool checkTabletProximity(Display *display, XDevice *device)
|
|||
return false;
|
||||
}
|
||||
|
||||
/* needed since unplugging will abort() without this */
|
||||
GHOST_X11_ERROR_HANDLERS_OVERRIDE(handler_store);
|
||||
|
||||
state = XQueryDeviceState(display, device);
|
||||
|
||||
GHOST_X11_ERROR_HANDLERS_RESTORE(handler_store);
|
||||
|
||||
if (state) {
|
||||
XInputClass *cls = state->data;
|
||||
// printf("%d class%s :\n", state->num_classes,
|
||||
|
@ -661,6 +695,41 @@ GHOST_SystemX11::processEvent(XEvent *xe)
|
|||
GHOST_WindowX11 *window = findGhostWindow(xe->xany.window);
|
||||
GHOST_Event *g_event = NULL;
|
||||
|
||||
#ifdef USE_XINPUT_HOTPLUG
|
||||
/* Hot-Plug support */
|
||||
if (m_xinput_version.present) {
|
||||
XEventClass class_presence;
|
||||
int xi_presence;
|
||||
|
||||
DevicePresence(m_display, xi_presence, class_presence);
|
||||
(void)class_presence;
|
||||
|
||||
if (xe->type == xi_presence) {
|
||||
XDevicePresenceNotifyEvent *notify_event = (XDevicePresenceNotifyEvent *)xe;
|
||||
if ((notify_event->devchange == DeviceEnabled) ||
|
||||
(notify_event->devchange == DeviceDisabled) ||
|
||||
(notify_event->devchange == DeviceAdded) ||
|
||||
(notify_event->devchange == DeviceRemoved))
|
||||
{
|
||||
refreshXInputDevices();
|
||||
|
||||
/* update all window events */
|
||||
{
|
||||
vector<GHOST_IWindow *> & win_vec = m_windowManager->getWindows();
|
||||
vector<GHOST_IWindow *>::iterator win_it = win_vec.begin();
|
||||
vector<GHOST_IWindow *>::const_iterator win_end = win_vec.end();
|
||||
|
||||
for (; win_it != win_end; ++win_it) {
|
||||
GHOST_WindowX11 *window = static_cast<GHOST_WindowX11 *>(*win_it);
|
||||
window->refreshXInputDevices();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* USE_XINPUT_HOTPLUG */
|
||||
|
||||
|
||||
if (!window) {
|
||||
return;
|
||||
}
|
||||
|
@ -680,7 +749,6 @@ GHOST_SystemX11::processEvent(XEvent *xe)
|
|||
}
|
||||
}
|
||||
#endif /* WITH_X11_XINPUT */
|
||||
|
||||
switch (xe->type) {
|
||||
case Expose:
|
||||
{
|
||||
|
@ -1917,8 +1985,6 @@ GHOST_TSuccess GHOST_SystemX11::pushDragDropEvent(GHOST_TEventType eventType,
|
|||
);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(USE_X11_ERROR_HANDLERS) || defined(WITH_X11_XINPUT)
|
||||
/*
|
||||
* These callbacks can be used for debugging, so we can breakpoint on an X11 error.
|
||||
|
||||
|
@ -1952,7 +2018,6 @@ int GHOST_X11_ApplicationIOErrorHandler(Display * /*display*/)
|
|||
/* No exit! - but keep lint happy */
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WITH_X11_XINPUT
|
||||
/* These C functions are copied from Wine 1.1.13's wintab.c */
|
||||
|
@ -2049,23 +2114,27 @@ static BOOL is_eraser(const char *name, const char *type)
|
|||
#undef FALSE
|
||||
/* end code copied from wine */
|
||||
|
||||
void GHOST_SystemX11::initXInputDevices()
|
||||
void GHOST_SystemX11::refreshXInputDevices()
|
||||
{
|
||||
static XErrorHandler old_handler = (XErrorHandler) 0;
|
||||
static XIOErrorHandler old_handler_io = (XIOErrorHandler) 0;
|
||||
if (m_xinput_version.present) {
|
||||
|
||||
XExtensionVersion *version = XGetExtensionVersion(m_display, INAME);
|
||||
if (m_xtablet.StylusDevice) {
|
||||
XCloseDevice(m_display, m_xtablet.StylusDevice);
|
||||
m_xtablet.StylusDevice = NULL;
|
||||
}
|
||||
|
||||
if (version && (version != (XExtensionVersion *)NoSuchExtension)) {
|
||||
if (version->present) {
|
||||
if (m_xtablet.EraserDevice) {
|
||||
XCloseDevice(m_display, m_xtablet.EraserDevice);
|
||||
m_xtablet.EraserDevice = NULL;
|
||||
}
|
||||
|
||||
/* Install our error handler to override Xlib's termination behavior */
|
||||
GHOST_X11_ERROR_HANDLERS_OVERRIDE(handler_store);
|
||||
|
||||
{
|
||||
int device_count;
|
||||
XDeviceInfo *device_info = XListInputDevices(m_display, &device_count);
|
||||
m_xtablet.StylusDevice = NULL;
|
||||
m_xtablet.EraserDevice = NULL;
|
||||
|
||||
/* Install our error handler to override Xlib's termination behavior */
|
||||
old_handler = XSetErrorHandler(GHOST_X11_ApplicationErrorHandler);
|
||||
old_handler_io = XSetIOErrorHandler(GHOST_X11_ApplicationIOErrorHandler);
|
||||
|
||||
for (int i = 0; i < device_count; ++i) {
|
||||
char *device_type = device_info[i].type ? XGetAtomName(m_display, device_info[i].type) : NULL;
|
||||
|
@ -2124,13 +2193,10 @@ void GHOST_SystemX11::initXInputDevices()
|
|||
}
|
||||
}
|
||||
|
||||
/* Restore handler */
|
||||
(void) XSetErrorHandler(old_handler);
|
||||
(void) XSetIOErrorHandler(old_handler_io);
|
||||
|
||||
XFreeDeviceList(device_info);
|
||||
}
|
||||
XFree(version);
|
||||
|
||||
GHOST_X11_ERROR_HANDLERS_RESTORE(handler_store);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -52,6 +52,20 @@
|
|||
int GHOST_X11_ApplicationErrorHandler(Display *display, XErrorEvent *theEvent);
|
||||
int GHOST_X11_ApplicationIOErrorHandler(Display *display);
|
||||
|
||||
#define GHOST_X11_ERROR_HANDLERS_OVERRIDE(var) \
|
||||
struct { \
|
||||
XErrorHandler handler; \
|
||||
XIOErrorHandler handler_io; \
|
||||
} var = { \
|
||||
XSetErrorHandler(GHOST_X11_ApplicationErrorHandler), \
|
||||
XSetIOErrorHandler(GHOST_X11_ApplicationIOErrorHandler), \
|
||||
}
|
||||
|
||||
#define GHOST_X11_ERROR_HANDLERS_RESTORE(var) \
|
||||
{ \
|
||||
(void)XSetErrorHandler(var.handler); \
|
||||
(void)XSetIOErrorHandler(var.handler_io); \
|
||||
} ((void)0)
|
||||
|
||||
class GHOST_WindowX11;
|
||||
|
||||
|
@ -328,6 +342,10 @@ public:
|
|||
#endif
|
||||
} m_atom;
|
||||
|
||||
#ifdef WITH_X11_XINPUT
|
||||
XExtensionVersion m_xinput_version;
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
||||
Display *m_display;
|
||||
|
@ -367,7 +385,7 @@ private:
|
|||
#endif
|
||||
|
||||
#ifdef WITH_X11_XINPUT
|
||||
void initXInputDevices();
|
||||
void refreshXInputDevices();
|
||||
#endif
|
||||
|
||||
GHOST_WindowX11 *
|
||||
|
|
|
@ -566,7 +566,7 @@ GHOST_WindowX11(GHOST_SystemX11 *system,
|
|||
}
|
||||
|
||||
#ifdef WITH_X11_XINPUT
|
||||
initXInputDevices();
|
||||
refreshXInputDevices();
|
||||
|
||||
m_tabletData.Active = GHOST_kTabletModeNone;
|
||||
#endif
|
||||
|
@ -633,45 +633,40 @@ bool GHOST_WindowX11::createX11_XIC()
|
|||
#endif
|
||||
|
||||
#ifdef WITH_X11_XINPUT
|
||||
void GHOST_WindowX11::initXInputDevices()
|
||||
void GHOST_WindowX11::refreshXInputDevices()
|
||||
{
|
||||
XExtensionVersion *version = XGetExtensionVersion(m_display, INAME);
|
||||
if (m_system->m_xinput_version.present) {
|
||||
GHOST_SystemX11::GHOST_TabletX11 &xtablet = m_system->GetXTablet();
|
||||
XEventClass xevents[8], ev;
|
||||
int dcount = 0;
|
||||
|
||||
if (version && (version != (XExtensionVersion *)NoSuchExtension)) {
|
||||
if (version->present) {
|
||||
GHOST_SystemX11::GHOST_TabletX11 &xtablet = m_system->GetXTablet();
|
||||
XEventClass xevents[8], ev;
|
||||
int dcount = 0;
|
||||
/* With modern XInput (xlib 1.6.2 at least and/or evdev 2.9.0) and some 'no-name' tablets
|
||||
* like 'UC-LOGIC Tablet WP5540U', we also need to 'select' ButtonPress for motion event,
|
||||
* otherwise we do not get any tablet motion event once pen is pressed... See T43367.
|
||||
*/
|
||||
|
||||
/* With modern XInput (xlib 1.6.2 at least and/or evdev 2.9.0) and some 'no-name' tablets
|
||||
* like 'UC-LOGIC Tablet WP5540U', we also need to 'select' ButtonPress for motion event,
|
||||
* otherwise we do not get any tablet motion event once pen is pressed... See T43367.
|
||||
*/
|
||||
|
||||
if (xtablet.StylusDevice) {
|
||||
DeviceMotionNotify(xtablet.StylusDevice, xtablet.MotionEvent, ev);
|
||||
if (ev) xevents[dcount++] = ev;
|
||||
DeviceButtonPress(xtablet.StylusDevice, xtablet.PressEvent, ev);
|
||||
if (ev) xevents[dcount++] = ev;
|
||||
ProximityIn(xtablet.StylusDevice, xtablet.ProxInEvent, ev);
|
||||
if (ev) xevents[dcount++] = ev;
|
||||
ProximityOut(xtablet.StylusDevice, xtablet.ProxOutEvent, ev);
|
||||
if (ev) xevents[dcount++] = ev;
|
||||
}
|
||||
if (xtablet.EraserDevice) {
|
||||
DeviceMotionNotify(xtablet.EraserDevice, xtablet.MotionEventEraser, ev);
|
||||
if (ev) xevents[dcount++] = ev;
|
||||
DeviceButtonPress(xtablet.EraserDevice, xtablet.PressEventEraser, ev);
|
||||
if (ev) xevents[dcount++] = ev;
|
||||
ProximityIn(xtablet.EraserDevice, xtablet.ProxInEventEraser, ev);
|
||||
if (ev) xevents[dcount++] = ev;
|
||||
ProximityOut(xtablet.EraserDevice, xtablet.ProxOutEventEraser, ev);
|
||||
if (ev) xevents[dcount++] = ev;
|
||||
}
|
||||
|
||||
XSelectExtensionEvent(m_display, m_window, xevents, dcount);
|
||||
if (xtablet.StylusDevice) {
|
||||
DeviceMotionNotify(xtablet.StylusDevice, xtablet.MotionEvent, ev);
|
||||
if (ev) xevents[dcount++] = ev;
|
||||
DeviceButtonPress(xtablet.StylusDevice, xtablet.PressEvent, ev);
|
||||
if (ev) xevents[dcount++] = ev;
|
||||
ProximityIn(xtablet.StylusDevice, xtablet.ProxInEvent, ev);
|
||||
if (ev) xevents[dcount++] = ev;
|
||||
ProximityOut(xtablet.StylusDevice, xtablet.ProxOutEvent, ev);
|
||||
if (ev) xevents[dcount++] = ev;
|
||||
}
|
||||
XFree(version);
|
||||
if (xtablet.EraserDevice) {
|
||||
DeviceMotionNotify(xtablet.EraserDevice, xtablet.MotionEventEraser, ev);
|
||||
if (ev) xevents[dcount++] = ev;
|
||||
DeviceButtonPress(xtablet.EraserDevice, xtablet.PressEventEraser, ev);
|
||||
if (ev) xevents[dcount++] = ev;
|
||||
ProximityIn(xtablet.EraserDevice, xtablet.ProxInEventEraser, ev);
|
||||
if (ev) xevents[dcount++] = ev;
|
||||
ProximityOut(xtablet.EraserDevice, xtablet.ProxOutEventEraser, ev);
|
||||
if (ev) xevents[dcount++] = ev;
|
||||
}
|
||||
|
||||
XSelectExtensionEvent(m_display, m_window, xevents, dcount);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -212,6 +212,10 @@ public:
|
|||
bool createX11_XIC();
|
||||
#endif
|
||||
|
||||
#ifdef WITH_X11_XINPUT
|
||||
void refreshXInputDevices();
|
||||
#endif
|
||||
|
||||
#ifdef WITH_XDND
|
||||
GHOST_DropTargetX11 *getDropTarget()
|
||||
{
|
||||
|
@ -315,10 +319,6 @@ private:
|
|||
Cursor
|
||||
getEmptyCursor(
|
||||
);
|
||||
|
||||
#ifdef WITH_X11_XINPUT
|
||||
void initXInputDevices();
|
||||
#endif
|
||||
|
||||
Window m_window;
|
||||
Display *m_display;
|
||||
|
|
|
@ -52,15 +52,15 @@ __all__ = (
|
|||
)
|
||||
|
||||
from _bpy import (
|
||||
_utils_units as units,
|
||||
blend_paths,
|
||||
escape_identifier,
|
||||
register_class,
|
||||
unregister_class,
|
||||
blend_paths,
|
||||
resource_path,
|
||||
script_paths as _bpy_script_paths,
|
||||
unregister_class,
|
||||
user_resource as _user_resource,
|
||||
)
|
||||
from _bpy import script_paths as _bpy_script_paths
|
||||
from _bpy import user_resource as _user_resource
|
||||
from _bpy import _utils_units as units
|
||||
|
||||
import bpy as _bpy
|
||||
import os as _os
|
||||
|
@ -641,11 +641,10 @@ def unregister_module(module, verbose=False):
|
|||
|
||||
# we start with the built-in default mapping
|
||||
def _blender_default_map():
|
||||
import sys
|
||||
import rna_manual_reference as ref_mod
|
||||
ret = (ref_mod.url_manual_prefix, ref_mod.url_manual_mapping)
|
||||
# avoid storing in memory
|
||||
del sys.modules["rna_manual_reference"]
|
||||
del _sys.modules["rna_manual_reference"]
|
||||
return ret
|
||||
|
||||
# hooks for doc lookups
|
||||
|
|
|
@ -635,6 +635,7 @@ void b_bone_spline_setup(bPoseChannel *pchan, int rest, Mat4 result_array[MAX_BB
|
|||
|
||||
{
|
||||
const float circle_factor = length * (cubic_tangent_factor_circle_v3(h1, h2) / 0.75f);
|
||||
|
||||
const float hlength1 = bone->ease1 * circle_factor;
|
||||
const float hlength2 = bone->ease2 * circle_factor;
|
||||
|
||||
|
|
|
@ -5002,7 +5002,9 @@ float cubic_tangent_factor_circle_v3(const float tan_l[3], const float tan_r[3])
|
|||
BLI_ASSERT_UNIT_V3(tan_l);
|
||||
BLI_ASSERT_UNIT_V3(tan_r);
|
||||
|
||||
const float eps = 1e-7f;
|
||||
/* -7f causes instability/glitches with Bendy Bones + Custom Refs */
|
||||
const float eps = 1e-5f;
|
||||
|
||||
const float tan_dot = dot_v3v3(tan_l, tan_r);
|
||||
if (tan_dot > 1.0f - eps) {
|
||||
/* no angle difference (use fallback, length wont make any difference) */
|
||||
|
|
|
@ -417,6 +417,11 @@ void uiStyleInit(void)
|
|||
blf_mono_font = -1;
|
||||
}
|
||||
|
||||
if (blf_mono_font_render != -1) {
|
||||
BLF_unload_id(blf_mono_font_render);
|
||||
blf_mono_font_render = -1;
|
||||
}
|
||||
|
||||
font = U.uifonts.first;
|
||||
|
||||
/* default builtin */
|
||||
|
@ -516,7 +521,12 @@ void uiStyleInit(void)
|
|||
|
||||
BLF_size(blf_mono_font, 12 * U.pixelsize, 72);
|
||||
|
||||
/* second for rendering else we get threading problems */
|
||||
/**
|
||||
* Second for rendering else we get threading problems,
|
||||
*
|
||||
* \note This isn't good that the render font depends on the preferences,
|
||||
* keep for now though, since without this there is no way to display many unicode chars.
|
||||
*/
|
||||
if (blf_mono_font_render == -1)
|
||||
blf_mono_font_render = BLF_load_mem_unique("monospace", monofont_ttf, monofont_size);
|
||||
|
||||
|
|
|
@ -567,7 +567,7 @@ static void text_id_remap(ScrArea *UNUSED(sa), SpaceLink *slink, ID *old_id, ID
|
|||
{
|
||||
SpaceText *stext = (SpaceText *)slink;
|
||||
|
||||
if (!ELEM(GS(old_id->name), ID_GD)) {
|
||||
if (!ELEM(GS(old_id->name), ID_TXT)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -227,6 +227,10 @@ static const char *rna_safe_id(const char *id)
|
|||
return "operator_value";
|
||||
else if (STREQ(id, "new"))
|
||||
return "create";
|
||||
else if (STREQ(id, "co_return")) {
|
||||
/* MSVC2015, C++ uses for coroutines */
|
||||
return "coord_return";
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
|
|
|
@ -94,6 +94,11 @@ EnumPropertyItem rna_enum_navigation_mode_items[] = {
|
|||
{0, NULL, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
static EnumPropertyItem rna_enum_language_default_items[] = {
|
||||
{0, "DEFAULT", 0, "Default (Default)", ""},
|
||||
{0, NULL, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
#ifdef RNA_RUNTIME
|
||||
|
||||
#include "DNA_object_types.h"
|
||||
|
@ -642,7 +647,11 @@ static EnumPropertyItem *rna_userdef_audio_device_itemf(bContext *UNUSED(C), Poi
|
|||
static EnumPropertyItem *rna_lang_enum_properties_itemf(bContext *UNUSED(C), PointerRNA *UNUSED(ptr),
|
||||
PropertyRNA *UNUSED(prop), bool *UNUSED(r_free))
|
||||
{
|
||||
return BLT_lang_RNA_enum_properties();
|
||||
EnumPropertyItem *items = BLT_lang_RNA_enum_properties();
|
||||
if (items == NULL) {
|
||||
items = rna_enum_language_default_items;
|
||||
}
|
||||
return items;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -3967,11 +3976,6 @@ static void rna_def_userdef_system(BlenderRNA *brna)
|
|||
{USER_MULTISAMPLE_16, "16", 0, "MultiSample: 16", "Use 16x OpenGL MultiSample (requires restart)"},
|
||||
{0, NULL, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
static EnumPropertyItem language_items[] = {
|
||||
{0, "DEFAULT", 0, "Default (Default)", ""},
|
||||
{0, NULL, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
#ifdef WITH_CYCLES
|
||||
static EnumPropertyItem compute_device_items[] = {
|
||||
|
@ -4054,7 +4058,7 @@ static void rna_def_userdef_system(BlenderRNA *brna)
|
|||
/* Language Selection */
|
||||
|
||||
prop = RNA_def_property(srna, "language", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_items(prop, language_items);
|
||||
RNA_def_property_enum_items(prop, rna_enum_language_default_items);
|
||||
#ifdef WITH_INTERNATIONAL
|
||||
RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_lang_enum_properties_itemf");
|
||||
#endif
|
||||
|
|
|
@ -469,13 +469,15 @@ EnumPropertyItem rna_enum_wm_report_items[] = {
|
|||
static wmOperator *rna_OperatorProperties_find_operator(PointerRNA *ptr)
|
||||
{
|
||||
wmWindowManager *wm = ptr->id.data;
|
||||
IDProperty *properties = (IDProperty *)ptr->data;
|
||||
wmOperator *op;
|
||||
|
||||
if (wm)
|
||||
for (op = wm->operators.first; op; op = op->next)
|
||||
if (op->properties == properties)
|
||||
if (wm) {
|
||||
IDProperty *properties = (IDProperty *)ptr->data;
|
||||
for (wmOperator *op = wm->operators.last; op; op = op->prev) {
|
||||
if (op->properties == properties) {
|
||||
return op;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue