diff options
author | Daniel Genrich <daniel.genrich@gmx.net> | 2008-09-18 18:59:44 +0400 |
---|---|---|
committer | Daniel Genrich <daniel.genrich@gmx.net> | 2008-09-18 18:59:44 +0400 |
commit | fc312fae98f54b56d00812fee64aa9e9e1ee74ff (patch) | |
tree | bdb691f07cacd5c18bf318e024469400551d8476 /intern | |
parent | 190aae27ae7149945f2bf802d7cfd7691f61c45f (diff) | |
parent | 423b05390434c310c0f0e59ef62fce79287c581b (diff) |
svn merge -r 16454:16593 https://svn.blender.org/svnroot/bf-blender/trunk/blender
Diffstat (limited to 'intern')
-rw-r--r-- | intern/SoundSystem/SoundDefines.h | 2 | ||||
-rw-r--r-- | intern/SoundSystem/openal/SND_OpenALDevice.cpp | 4 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_SystemX11.cpp | 47 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_SystemX11.h | 22 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_WindowX11.cpp | 397 | ||||
-rw-r--r-- | intern/ghost/intern/GHOST_WindowX11.h | 21 | ||||
-rw-r--r-- | intern/iksolver/CMakeLists.txt | 2 | ||||
-rw-r--r-- | intern/iksolver/SConscript | 3 |
8 files changed, 426 insertions, 72 deletions
diff --git a/intern/SoundSystem/SoundDefines.h b/intern/SoundSystem/SoundDefines.h index 5d425a8dc94..450fde187b5 100644 --- a/intern/SoundSystem/SoundDefines.h +++ b/intern/SoundSystem/SoundDefines.h @@ -44,7 +44,7 @@ enum /* general stuff */ #define NUM_BUFFERS 128 -#define NUM_SOURCES 16 +#define NUM_SOURCES 24 /* 24 is the limit for openal on windows, was 16 in 2.47 and previous */ /* openal related stuff */ #define AL_LOOPING 0x1007 diff --git a/intern/SoundSystem/openal/SND_OpenALDevice.cpp b/intern/SoundSystem/openal/SND_OpenALDevice.cpp index 82ed1c8a808..c660e9aecba 100644 --- a/intern/SoundSystem/openal/SND_OpenALDevice.cpp +++ b/intern/SoundSystem/openal/SND_OpenALDevice.cpp @@ -294,6 +294,10 @@ SND_OpenALDevice::SND_OpenALDevice() // let openal generate its sources if (alc_error == ALC_NO_ERROR) { + int i; + + for (i=0;i<NUM_SOURCES;i++) + m_sources[i] = 0; alGenSources(NUM_SOURCES, m_sources); m_sourcesinitialized = true; } diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp index 1b90831986d..047bc654559 100644 --- a/intern/ghost/intern/GHOST_SystemX11.cpp +++ b/intern/ghost/intern/GHOST_SystemX11.cpp @@ -96,15 +96,26 @@ GHOST_SystemX11( if (!m_display) return; #ifdef __sgi - m_delete_window_atom - = XSGIFastInternAtom(m_display, + m_delete_window_atom = XSGIFastInternAtom(m_display, "WM_DELETE_WINDOW", SGI_XA_WM_DELETE_WINDOW, False); #else - m_delete_window_atom - = XInternAtom(m_display, "WM_DELETE_WINDOW", True); + m_delete_window_atom = XInternAtom(m_display, "WM_DELETE_WINDOW", False); #endif + m_wm_protocols= XInternAtom(m_display, "WM_PROTOCOLS", False); + m_wm_take_focus= XInternAtom(m_display, "WM_TAKE_FOCUS", False); + m_wm_state= XInternAtom(m_display, "WM_STATE", False); + m_wm_change_state= XInternAtom(m_display, "WM_CHANGE_STATE", False); + m_net_state= XInternAtom(m_display, "_NET_WM_STATE", False); + m_net_max_horz= XInternAtom(m_display, + "_NET_WM_STATE_MAXIMIZED_HORZ", False); + m_net_max_vert= XInternAtom(m_display, + "_NET_WM_STATE_MAXIMIZED_VERT", False); + m_net_fullscreen= XInternAtom(m_display, + "_NET_WM_STATE_FULLSCREEN", False); + m_motif= XInternAtom(m_display, "_MOTIF_WM_HINTS", False); + // compute the initial time timeval tv; if (gettimeofday(&tv,NULL) == -1) { @@ -477,7 +488,7 @@ GHOST_SystemX11::processEvent(XEvent *xe) XClientMessageEvent & xcme = xe->xclient; #ifndef __sgi - if (xcme.data.l[0] == m_delete_window_atom) { + if (((Atom)xcme.data.l[0]) == m_delete_window_atom) { g_event = new GHOST_Event( getMilliSeconds(), @@ -511,6 +522,14 @@ GHOST_SystemX11::processEvent(XEvent *xe) GHOST_kEventNDOFButton, window, data); } + } + else if (((Atom)xcme.data.l[0]) == m_wm_take_focus) { + /* as ICCCM say, we need reply this event + * with a SetInputFocus, the data[1] have + * the valid timestamp (send by the window + * manager). + */ + XSetInputFocus(m_display, xcme.window, RevertToParent, xcme.data.l[1]); } else { /* Unknown client message, ignore */ } @@ -528,6 +547,24 @@ GHOST_SystemX11::processEvent(XEvent *xe) // XCrossingEvents pointer leave enter window. break; case MapNotify: + /* + * From ICCCM: + * [ Clients can select for StructureNotify on their + * top-level windows to track transition between + * Normal and Iconic states. Receipt of a MapNotify + * event will indicate a transition to the Normal + * state, and receipt of an UnmapNotify event will + * indicate a transition to the Iconic state. ] + */ + if (window->m_post_init == True) { + /* + * Now we are sure that the window is + * mapped, so only need change the state. + */ + window->setState(window->m_post_state); + window->m_post_init= False; + } + break; case UnmapNotify: break; case MappingNotify: diff --git a/intern/ghost/intern/GHOST_SystemX11.h b/intern/ghost/intern/GHOST_SystemX11.h index c67f7d81e60..683337b47e1 100644 --- a/intern/ghost/intern/GHOST_SystemX11.h +++ b/intern/ghost/intern/GHOST_SystemX11.h @@ -215,15 +215,27 @@ public: */ virtual void putClipboard(GHOST_TInt8 *buffer, int flag) const; -private : - - Display * m_display; - /** - * Atom used to detect window close events + * Atom used for ICCCM, WM-spec and Motif. + * We only need get this atom at the start, it's relative + * to the display not the window and are public for every + * window that need it. */ + Atom m_wm_protocols; + Atom m_wm_take_focus; + Atom m_wm_state; + Atom m_wm_change_state; + Atom m_net_state; + Atom m_net_max_horz; + Atom m_net_max_vert; + Atom m_net_fullscreen; + Atom m_motif; Atom m_delete_window_atom; +private : + + Display * m_display; + /// The vector of windows that need to be updated. std::vector<GHOST_WindowX11 *> m_dirty_windows; diff --git a/intern/ghost/intern/GHOST_WindowX11.cpp b/intern/ghost/intern/GHOST_WindowX11.cpp index 7b0606c40b7..2f7aee95b82 100644 --- a/intern/ghost/intern/GHOST_WindowX11.cpp +++ b/intern/ghost/intern/GHOST_WindowX11.cpp @@ -55,6 +55,16 @@ typedef struct { #define MWM_HINTS_DECORATIONS (1L << 1) /* + * A client can't change the window property, that is the + * work of the window manager. We send a ClientMessage + * event to the Root window with the property + * and the Action (WM-spec define this): + */ +#define _NET_WM_STATE_REMOVE 0 +#define _NET_WM_STATE_ADD 1 +#define _NET_WM_STATE_TOGGLE 2 + +/* import bpy I = bpy.data.images['blender.png'] # the 48x48 icon @@ -154,7 +164,8 @@ GHOST_WindowX11( // Set up the minimum atrributes that we require and see if // X can find us a visual matching those requirements. - + Atom atoms[2]; + int natom; int attributes[40], i = 0; @@ -228,7 +239,6 @@ GHOST_WindowX11( Window root_return; int x_return,y_return; unsigned int w_return,h_return,border_w_return,depth_return; - GHOST_TInt32 screen_x, screen_y; XGetGeometry(m_display, parentWindow, &root_return, &x_return, &y_return, &w_return, &h_return, &border_w_return, &depth_return ); @@ -262,46 +272,26 @@ GHOST_WindowX11( // Are we in fullscreen mode - then include // some obscure blut code to remove decorations. - if (state == GHOST_kWindowStateFullScreen) { + /* + * One of the problem with WM_spec is that can't set a property + * to a window that isn't mapped. That is why we can't "just + * call setState" here. + * + * To fix this, we first need know that the window is really + * mapped waiting for the MapNotify event. + * + * So, m_post_init indicate that we need wait for the MapNotify + * event and then set the window state to the m_post_state. + */ + if ((state != GHOST_kWindowStateNormal) && (state != GHOST_kWindowStateMinimized)) { + m_post_init = True; + m_post_state = state; + } + else { + m_post_init = False; + m_post_state = GHOST_kWindowStateNormal; + } - MotifWmHints hints; - Atom atom; - - atom = XInternAtom(m_display, "_MOTIF_WM_HINTS", False); - - if (atom == None) { - GHOST_PRINT("Could not intern X atom for _MOTIF_WM_HINTS.\n"); - } else { - hints.flags = MWM_HINTS_DECORATIONS; - hints.decorations = 0; /* Absolutely no decorations. */ - // other hints.decorations make no sense - // you can't select individual decorations - - XChangeProperty(m_display, m_window, - atom, atom, 32, - PropModeReplace, (unsigned char *) &hints, 4); - } - } else if (state == GHOST_kWindowStateMaximized) { - // With this, xprop should report the following just after launch - // _NET_WM_STATE(ATOM) = _NET_WM_STATE_MAXIMIZED_VERT, _NET_WM_STATE_MAXIMIZED_HORZ - // After demaximization the right side is empty, though (maybe not the most correct then?) - Atom state, atomh, atomv; - - state = XInternAtom(m_display, "_NET_WM_STATE", False); - atomh = XInternAtom(m_display, "_NET_WM_STATE_MAXIMIZED_HORZ", False); - atomv = XInternAtom(m_display, "_NET_WM_STATE_MAXIMIZED_VERT", False); - if (state == None ) { - GHOST_PRINT("Atom _NET_WM_STATE requested but not avaliable nor created.\n"); - } else { - XChangeProperty(m_display, m_window, - state, XA_ATOM, 32, - PropModeAppend, (unsigned char *) &atomh, 1); - XChangeProperty(m_display, m_window, - state, XA_ATOM, 32, - PropModeAppend, (unsigned char *) &atomv, 1); - } - } - // Create some hints for the window manager on how // we want this window treated. @@ -324,6 +314,25 @@ GHOST_WindowX11( free(wmclass); XFree(xclasshint); + /* The basic for a good ICCCM "work" */ + if (m_system->m_wm_protocols) { + natom= 0; + + if (m_system->m_delete_window_atom) { + atoms[natom]= m_system->m_delete_window_atom; + natom++; + } + + if (m_system->m_wm_take_focus) { + atoms[natom]= m_system->m_wm_take_focus; + natom++; + } + + if (natom) { + /* printf("Register atoms: %d\n", natom); */ + XSetWMProtocols(m_display, m_window, atoms, natom); + } + } // Set the window icon XWMHints *xwmhints = XAllocWMHints(); @@ -645,28 +654,298 @@ clientToScreen( outY = ay; } +void GHOST_WindowX11::icccmSetState(int state) +{ + XEvent xev; - GHOST_TWindowState -GHOST_WindowX11:: -getState( -) const { - //FIXME - return GHOST_kWindowStateNormal; + if (state != IconicState) + return; + + xev.xclient.type = ClientMessage; + xev.xclient.serial = 0; + xev.xclient.send_event = True; + xev.xclient.display = m_display; + xev.xclient.window = m_window; + xev.xclient.format = 32; + xev.xclient.message_type = m_system->m_wm_change_state; + xev.xclient.data.l[0] = state; + XSendEvent (m_display, RootWindow(m_display, DefaultScreen(m_display)), + False, SubstructureNotifyMask | SubstructureRedirectMask, &xev); } - GHOST_TSuccess -GHOST_WindowX11:: -setState( - GHOST_TWindowState state -){ - //TODO +int GHOST_WindowX11::icccmGetState(void) const +{ + unsigned char *prop_ret; + unsigned long bytes_after, num_ret; + Atom type_ret; + int format_ret, st; + + prop_ret = NULL; + st = XGetWindowProperty(m_display, m_window, m_system->m_wm_state, 0, + 0x7fffffff, False, m_system->m_wm_state, &type_ret, + &format_ret, &num_ret, &bytes_after, &prop_ret); + + if ((st == Success) && (prop_ret) && (num_ret == 2)) + st = prop_ret[0]; + else + st = NormalState; + + if (prop_ret) + XFree(prop_ret); + return (st); +} + +void GHOST_WindowX11::netwmMaximized(bool set) +{ + XEvent xev; + + xev.xclient.type= ClientMessage; + xev.xclient.serial = 0; + xev.xclient.send_event = True; + xev.xclient.window = m_window; + xev.xclient.message_type = m_system->m_net_state; + xev.xclient.format = 32; + + if (set == True) + xev.xclient.data.l[0] = _NET_WM_STATE_ADD; + else + xev.xclient.data.l[0] = _NET_WM_STATE_REMOVE; + + xev.xclient.data.l[1] = m_system->m_net_max_horz; + xev.xclient.data.l[2] = m_system->m_net_max_vert; + xev.xclient.data.l[3] = 0; + xev.xclient.data.l[4] = 0; + XSendEvent (m_display, RootWindow(m_display, DefaultScreen(m_display)), + False, SubstructureRedirectMask | SubstructureNotifyMask, &xev); +} + +bool GHOST_WindowX11::netwmIsMaximized(void) const +{ + unsigned char *prop_ret; + unsigned long bytes_after, num_ret, i; + Atom type_ret; + bool st; + int format_ret, count; + + prop_ret = NULL; + st = False; + i = XGetWindowProperty(m_display, m_window, m_system->m_net_state, 0, + 0x7fffffff, False, XA_ATOM, &type_ret, &format_ret, + &num_ret, &bytes_after, &prop_ret); + if ((i == Success) && (prop_ret) && (format_ret == 32)) { + count = 0; + for (i = 0; i < num_ret; i++) { + if (((unsigned long *) prop_ret)[i] == m_system->m_net_max_horz) + count++; + if (((unsigned long *) prop_ret)[i] == m_system->m_net_max_vert) + count++; + if (count == 2) { + st = True; + break; + } + } + } + + if (prop_ret) + XFree(prop_ret); + return (st); +} + +void GHOST_WindowX11::netwmFullScreen(bool set) +{ + XEvent xev; + + xev.xclient.type = ClientMessage; + xev.xclient.serial = 0; + xev.xclient.send_event = True; + xev.xclient.window = m_window; + xev.xclient.message_type = m_system->m_net_state; + xev.xclient.format = 32; + + if (set == True) + xev.xclient.data.l[0] = _NET_WM_STATE_ADD; + else + xev.xclient.data.l[0] = _NET_WM_STATE_REMOVE; + + xev.xclient.data.l[1] = m_system->m_net_fullscreen; + xev.xclient.data.l[2] = 0; + xev.xclient.data.l[3] = 0; + xev.xclient.data.l[4] = 0; + XSendEvent (m_display, RootWindow(m_display, DefaultScreen(m_display)), + False, SubstructureRedirectMask | SubstructureNotifyMask, &xev); +} + +bool GHOST_WindowX11::netwmIsFullScreen(void) const +{ + unsigned char *prop_ret; + unsigned long bytes_after, num_ret, i; + Atom type_ret; + bool st; + int format_ret; + + prop_ret = NULL; + st = False; + i = XGetWindowProperty(m_display, m_window, m_system->m_net_state, 0, + 0x7fffffff, False, XA_ATOM, &type_ret, &format_ret, + &num_ret, &bytes_after, &prop_ret); + if ((i == Success) && (prop_ret) && (format_ret == 32)) { + for (i = 0; i < num_ret; i++) { + if (((unsigned long *)prop_ret)[i] == m_system->m_net_fullscreen) { + st = True; + break; + } + } + } + + if (prop_ret) + XFree(prop_ret); + return (st); +} + +void GHOST_WindowX11::motifFullScreen(bool set) +{ + MotifWmHints hints; + + hints.flags = MWM_HINTS_DECORATIONS; + if (set == True) + hints.decorations = 0; + else + hints.decorations = 1; + + XChangeProperty(m_display, m_window, m_system->m_motif, + m_system->m_motif, 32, PropModeReplace, + (unsigned char *)&hints, 4); +} + +bool GHOST_WindowX11::motifIsFullScreen(void) const +{ + unsigned char *prop_ret; + unsigned long bytes_after, num_ret; + MotifWmHints *hints; + Atom type_ret; + bool state; + int format_ret, st; + + prop_ret = NULL; + state = False; + st = XGetWindowProperty(m_display, m_window, m_system->m_motif, 0, + 0x7fffffff, False, m_system->m_motif, + &type_ret, &format_ret, &num_ret, + &bytes_after, &prop_ret); + if ((st == Success) && (prop_ret)) { + hints = (MotifWmHints *)prop_ret; + if (hints->flags & MWM_HINTS_DECORATIONS) { + if (!hints->decorations) + state = True; + } + } - if (state == (int)getState()) { + if (prop_ret) + XFree(prop_ret); + return (state); +} + +GHOST_TWindowState GHOST_WindowX11::getState() const +{ + GHOST_TWindowState state_ret; + int state; + + state_ret = GHOST_kWindowStateNormal; + state = icccmGetState(); + /* + * In the Iconic and Withdrawn state, the window is + * unmaped, so only need return a Minimized state. + */ + if ((state == IconicState) || (state == WithdrawnState)) + state_ret = GHOST_kWindowStateMinimized; + else if (netwmIsMaximized() == True) + state_ret = GHOST_kWindowStateMaximized; + else if (netwmIsFullScreen() == True) + state_ret = GHOST_kWindowStateFullScreen; + else if (motifIsFullScreen() == True) + state_ret = GHOST_kWindowStateFullScreen; + return (state_ret); +} + +GHOST_TSuccess GHOST_WindowX11::setState(GHOST_TWindowState state) +{ + GHOST_TWindowState cur_state; + bool is_max, is_full, is_motif_full; + + cur_state = getState(); + if (state == (int)cur_state) return GHOST_kSuccess; - } else { - return GHOST_kFailure; + + if (cur_state != GHOST_kWindowStateMinimized) { + /* + * The window don't have this property's + * if it's not mapped. + */ + is_max = netwmIsMaximized(); + is_full = netwmIsFullScreen(); + } + else { + is_max = False; + is_full = False; + } + + is_motif_full = motifIsFullScreen(); + + if (state == GHOST_kWindowStateNormal) { + if (is_max == True) + netwmMaximized(False); + if (is_full == True) + netwmFullScreen(False); + if (is_motif_full == True) + motifFullScreen(False); + icccmSetState(NormalState); + return (GHOST_kSuccess); + } + + if (state == GHOST_kWindowStateFullScreen) { + /* + * We can't change to full screen if the window + * isn't mapped. + */ + if (cur_state == GHOST_kWindowStateMinimized) + return (GHOST_kFailure); + + if (is_max == True) + netwmMaximized(False); + if (is_full == False) + netwmFullScreen(True); + if (is_motif_full == False) + motifFullScreen(True); + return (GHOST_kSuccess); + } + + if (state == GHOST_kWindowStateMaximized) { + /* + * We can't change to Maximized if the window + * isn't mapped. + */ + if (cur_state == GHOST_kWindowStateMinimized) + return (GHOST_kFailure); + + if (is_full == True) + netwmFullScreen(False); + if (is_motif_full == True) + motifFullScreen(False); + if (is_max == False) + netwmMaximized(True); + return (GHOST_kSuccess); + } + + if (state == GHOST_kWindowStateMinimized) { + /* + * The window manager need save the current state of + * the window (maximized, full screen, etc). + */ + icccmSetState(IconicState); + return (GHOST_kSuccess); } + return (GHOST_kFailure); } #include <iostream> @@ -701,9 +980,9 @@ setOrder( xev.xclient.message_type = atom; xev.xclient.format = 32; - xev.xclient.data.l[0] = 0; - xev.xclient.data.l[1] = 0; - xev.xclient.data.l[2] = 0; + xev.xclient.data.l[0] = 1; + xev.xclient.data.l[1] = CurrentTime; + xev.xclient.data.l[2] = m_window; xev.xclient.data.l[3] = 0; xev.xclient.data.l[4] = 0; diff --git a/intern/ghost/intern/GHOST_WindowX11.h b/intern/ghost/intern/GHOST_WindowX11.h index abb5c131cb7..1d73faaf3f6 100644 --- a/intern/ghost/intern/GHOST_WindowX11.h +++ b/intern/ghost/intern/GHOST_WindowX11.h @@ -212,6 +212,15 @@ public: const GHOST_TabletData* GetTabletData() { return &m_xtablet.CommonData; } + + /* + * Need this in case that we want start the window + * in FullScreen or Maximized state. + * Check GHOST_WindowX11.cpp + */ + bool m_post_init; + GHOST_TWindowState m_post_state; + protected: /** * Tries to install a rendering context in this window. @@ -327,6 +336,18 @@ private : /* Tablet devices */ XTablet m_xtablet; + + void icccmSetState(int state); + int icccmGetState() const; + + void netwmMaximized(bool set); + bool netwmIsMaximized() const; + + void netwmFullScreen(bool set); + bool netwmIsFullScreen() const; + + void motifFullScreen(bool set); + bool motifIsFullScreen() const; }; diff --git a/intern/iksolver/CMakeLists.txt b/intern/iksolver/CMakeLists.txt index da69f2a3332..736a2a78bb2 100644 --- a/intern/iksolver/CMakeLists.txt +++ b/intern/iksolver/CMakeLists.txt @@ -28,5 +28,5 @@ SET(INC intern ../moto/include ../memutil) FILE(GLOB SRC intern/*.cpp) -BLENDERLIB_NOLIST(blender_IK "${SRC}" "${INC}") +BLENDERLIB(bf_IK "${SRC}" "${INC}") #, libtype=['blender'], priority = [10] ) diff --git a/intern/iksolver/SConscript b/intern/iksolver/SConscript index 81bf61dfcd8..543ee46487c 100644 --- a/intern/iksolver/SConscript +++ b/intern/iksolver/SConscript @@ -5,4 +5,5 @@ sources = env.Glob('intern/*.cpp') incs = 'intern ../moto/include ../memutil' -env.BlenderLib ('blender_IK', sources, Split(incs), [], libtype='blender', priority=10 ) +env.BlenderLib ('bf_IK', sources, Split(incs), [], libtype=['intern','player'], priority=[20,100] ) + |