summaryrefslogtreecommitdiffstats
path: root/src
Commit message (Collapse)AuthorAgeFilesLines
* NEWT WindowsWindow.c: UpdateInsets: Fix determiniation of isUndecorated - ↵Sven Gothel2012-12-301-1/+1
| | | | WS_SYSMENU is _not_ an indication!
* Bug632: Test NEWT Child Window Translucency (X11/Windows) ..Sven Gothel2012-12-306-15/+180
| | | | | | | | | | | | | - Windows: Child window is not translucent at all - X11: Child window is translucent to parent's background, however - parents content is _not_ 'composed in'. - TODO: Find whether there is a solution or not. - Note: The child window does not change it's rel. position if parent moves! This is a feature, since we don't have impl. a layout.
* SharedResourceRunner: Always dump Exception if catched @ creation, not just ↵Sven Gothel2012-12-301-3/+1
| | | | | | in DEBUG case. This seems to be crucial, since otherwise user is left in the dark w/o enabling debug flags.
* setGLFunctionAvailability(..): Unify GLInt and GLString version validation; ↵Sven Gothel2012-12-301-50/+102
| | | | | | | | | | | | | | | | | Refines commit b6ae4e4dcbd740dd57de9dc3280d943e98cdaa76 - Limit getGLIntVersion() w/ non ARB ctx to 3.0 - similar to getGLVersionNumber(.., String). - GLInt only proceeds w/ valid version - Always test GLInt version before GLString version, cont. w/ GLString version if GLInt failed. - Fail if strictMode and GLInt failed, but GLString reports GL >= 3.0 - Fail is strictMode and neither GLInt nor GLString could validate version - Clear glError before succeeding (could be tainted by GLInt version test)
* Cleanup / Simplify: setGLFunctionAvailability(..) / ↵Sven Gothel2012-12-302-50/+117
| | | | | | | | | | createContextARBVersions(..) GL Version Validation String or integer based GL version validation now happens in setGLFunctionAvailability(..) depending on the requested profile. Due to the 'strictMatch' argument the method fails early when unsatisfied also allowing to simplify createContextARBVersions(..) implementation.
* Fix Bug 658 (Mesa 9.0 3.1 Intel compat quirk, 3.1 core only) ; No ↵Sven Gothel2012-12-294-43/+306
| | | | | | | | | | | | | | | | | | | PROFILE_ALIASING compat -> core ; Fix setGLFunctionAvailability(..) failure path @ profile query - Add GLRendererQuirks.GLNonCompliant, marking a GL context/profile non compliant. Currently: 'Mesa DRI Intel(R) Sandybridge Desktop' && 3.1 compat profile - Fix Bug 658 (Mesa 9.0 3.1 Intel compat quirk, 3.1 core only) Detect case using new GLRendererQuirks.GLNonCompliant in setGLFunctionAvailability() and return 'false'. - No PROFILE_ALIASING compat -> core Use true core GL profiles / context if available to ensure proper API behavior across platforms due to different functionality. E.g. don't use GL3bc if GL3 is requested. - Fix setGLFunctionAvailability(..) failure path @ profile query Destroy temp context & zero result to cont. iterating through GL versions. This missing cleanup lead to returning the faulty GL context handle and it's mapping/usage.
* Adapt change of commit d93c5d23e304ea20e868595748f92a5bef4f5703 to unit test ↵Sven Gothel2012-12-291-26/+76
| | | | (GLCanvas realization point)
* AWT GLCanvas: More strict GLDrawable realization [on AWT-EDT], skip if ↵Sven Gothel2012-12-282-7/+8
| | | | | | | | | | | | | | | | | | | | creation is not possible on AWT-EDT. The Intel HD3000 OpenGL driver on Windows will deadlock @ SwapBuffers in case the drawable is created on a thread other than the window owner thread. We are aware of such possibilities, nevertheless the AWTEDTExecutor.singleton.invoke(..) allowed to execute the runnable in case it cannot be invoked on AWT-EDT. The latter is the case if the current thread is not the AWT-EDT _and_ is holding the AWT tree-lock. With GlueGen commit 0b43b43f889ad7fc220942b0076e2001ca3cf13f, the invoke method now consumes an argument allowing to restrict the execution to AWT-EDT only. In such case, the drawable will be realized at a later time from the AWT-EDT. Such a situation could be triggered if a Frame's setVisible(true) is not issued from the AWT-EDT, as it should be! However, to relax such use cases - we better recognize such possible dealock and avoid it.
* NEWT/Android: Fix NewtBaseActivity.getWindow() recursion if used w/o ↵Sven Gothel2012-12-251-1/+1
| | | | delegated Activity, i.e. our ActivityLauncher (Completes commit a35beb22d712b6da85a794115b19d484a12c8643)
* Test*NewtEventModifiers*: Clear 'clearing' events on thread - @Before/@After ↵Sven Gothel2012-12-251-42/+32
| | | | | | -> execOffThreadWithOnThreadEventDispatch Remaining 'clearing' events from _releaseModifiers() and escape() broke test case.
* Misc OSX/SWT: OSXUtil.RunOnMainThread(..) refinement; Fix ↵Sven Gothel2012-12-256-91/+205
| | | | | | | | | | | | | | | | | Test*NewtEventModifiers for SWT (TestNewtEventModifiersNewtCanvasSWT) - Misc OSX/SWT: OSXUtil.RunOnMainThread(..) refinement - 'waitUntilDone' is implemented on Java site via lock/wait on RunnableTask to not freeze OSX main thread. - Fix Test*NewtEventModifiers for SWT (TestNewtEventModifiersNewtCanvasSWT) - Deal with SWT's requirement to run the SWT event dispatch on the TK thread, which must be the main thread on OSX. We spawn off the actual test-action into another thread, while dispatching the events until the test-action is completed. - AWTRobot: Add 'void requestFocus(Robot robot, Object obj, int x, int y)' - Use waitForIdle() only if programmed in Robot (Deadlock w/ OSX SWT) - Required for SWT usage (see above)
* NEWT/Android: Fix NewtBaseActivity.getWindow() recursion if used w/o ↵Sven Gothel2012-12-241-2/+6
| | | | delegated Activity, i.e. our ActivityLauncher
* WT-NEWT Modifier mapping and test: part-4 (Fix unit tests): ↵Sven Gothel2012-12-242-75/+117
| | | | BaseNewtEventModifiers ignore more events (clicked, wheel, entered, exited); Fix TestNewtEventModifiersNewtCanvasSWT SWT-Display thread.
* NEWT peserve 'mouseButtonModMask' to be sent for all mouse- and key events. ↵Sven Gothel2012-12-241-30/+43
| | | | | | | | | | | | | | | | TODO: NEWT Event Factories. Misc: Cleaned up spacing. On some native OS, the accumulation of pressed button modifier-mask is not available, e.g. OS X. NEWT WindowImpl.doMouseEvent(..), invoked by native NEWT events, will track the pressed mouse button modifier-mask, similar to mouseButtonPressed to synthesize the DRAGGED event. Added NEWT WindowImpl.doKeyEvent(..) to honor the pressed mouse button modifier-mask, i.e. pass it w/ key events as well. TODO: Unify synthesization of NEWT event artifacts as described by the above, allowing NEWT event translation to benefit from same code to gain same semantics. Notable: AWTNewtEventFactory and SWTNewtEventFactory
* AWT-NEWT Modifier mapping and test: part-3 (Fix unit tests)Sven Gothel2012-12-245-167/+208
| | | | | | | | | | | | | | | | | | | | | | | - Finetune delay - Wait for eventCount - Fix Listener concurrency - Manually tested (enabled in our unit tests now) - Tool Combinations - NEWT GLWindow - AWT GLCanvas - NewtCanvasAWT - NewtCanvasSWT - On - Linux/X11 - Windows - OSX(+) (+): Failure NEWT: When multiple buttons are pressed, only the last one is visible via modifier MASK. "expected:[button1, button2], have: [button2]"
* AWT-NEWT Modifier mapping and test: part-3 (NEWT BUTTON MASK always, ..)Sven Gothel2012-12-246-125/+135
| | | | | | | | | | | | | | | | - AWTNewtEventFactory's awtModifiers2Newt: - always include NEWT BUTTON_MASK (press, release, ..) where AWT doesn't include them at release (it's only a DOWN_MASK). - Test BaseNewtEventModifiers, .. - No need to call super class Before, BeforeClass, .. manually - Use RedSquareES2 as GL demo - Adapt to AWTNewtEventFactory's modifier change above (NEWT BUTTON MASK even at release) - More descriptive error/log text - Added _mandatory_ TestNewtEventModifiersNEWTWindowAWT to test native NEWT behavior. This shall be the golden behavior all translated events shall compare w/.
* Move pre-existing NEWT event test to new dedicated package package: ↵Sven Gothel2012-12-236-12/+5
| | | | com.jogamp.opengl.test.junit.newt.event
* Fix 13168c99ff9e8bf71c83f1be7afee270a3db4074 / ↵Sven Gothel2012-12-237-173/+164
| | | | | | | | | | | | | | | | | 811e3791b98fea0dfa3b7d301cb532c54df8dc82: AWT-NEWT Modifier mapping - part-2 AWTNewtEventFactory: - getAWTButtonMask() -> getAWTButtonDownMask() - using proper _DOWN_MASK values (regression of commit 13168c99ff9e8bf71c83f1be7afee270a3db4074) - com.jogamp.newt.event.MouseEvent.BUTTON_NUMBER buttons - adding 'ModifierMappings.txt' to API doc header - remove obsolete 'int awtModifiers2Newt(int awtMods, boolean mouseHint)' - 'int awtButton2Newt(int awtButton)' 1:1 button name mapping Tests: - rename TestNewtEventModifiers -> BaseNewtEventModifiers to avoid being picked up by our junit testing framework. The latter tests all classes starting w/ 'Test*'
* Fix commit 811e3791b98fea0dfa3b7d301cb532c54df8dc82: Make AWT usage Java6 ↵Sven Gothel2012-12-232-63/+66
| | | | clean (was using Java7 stuff); Note: Need to test!
* Merge pull request #54 from rhatcher/masterSven Gothel2012-12-236-2/+1258
|\ | | | | Fix For Bug 629, Plus First Crack At Associated Unit Tests
| * Merge branch 'master' of https://github.com/sgothel/joglrhatcher2012-12-0621-484/+1632
| |\
| * | Fix for JOGL bug 629, and added new unit tests.rhatcher2012-11-296-2/+1258
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The change to AWTNewtEventFactory appears to fix the original issue for AWTCanvas instances, and the TestNewtEventModifiersAWTCanvas appears to work ok too. However, there are still issues with NewtCanvasAWT and NewtCanvasSWT instances. These might be problems in the test code, but there's also a good chance there are still issues in the NEWT event delivery infrastructure. For the time being I recommend that only TestNewtEventModifiersAWTCanvas be included in routine unit tests. The tests are defined in TestNewtEventModifiers, and the remaining test classes extend it to define how the window and associated GL drawing surface are created. File ModifierMappings.txt is simply informational, and shows how the modifier bits are laid out between AWT and NEWT. This possibly should have been a spreadsheet.
* | | Bug 642 / Refine 1ae0737f34143a5ed655bd9c4d5fe9b0437c7774: ↵Sven Gothel2012-12-221-2/+2
| | | | | | | | | | | | | | | | | | | | | GLCanvas.displayOnEDT: Also check null!=drawable As for 1ae0737f34143a5ed655bd9c4d5fe9b0437c7774, an animator may inject a display Runnable on the EDT before AWT destruction. In case this Runnable is executed after destruction on the EDT - it would fail.
* | | Fix regression of commit b8a8fc24a3afb0cb06a31504bdea1a98b8f00ef4: Cache ↵Sven Gothel2012-12-221-4/+5
| | | | | | | | | | | | ShaderState for share ctor.
* | | Bug 642 / Refine 1ae0737f34143a5ed655bd9c4d5fe9b0437c7774: ↵Sven Gothel2012-12-221-48/+42
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | GLContextImpl.makeCurrent() - Handle !drawable.isRealized() early, don't catch 'create' Exception Catching the createImpl() exception could be confusing, since it shall succeed. Such exception is required to hint a platform bug and to debug it. Hence testing drawable.isRealized() upfront is preferrable, i.e. catching a well known case for returning CONTEXT_NOT_CURRENT.
* | | Bug 642: Refine test case, adding Hw/Lw mix intermediate Container test to ↵Sven Gothel2012-12-222-8/+24
| | | | | | | | | | | | avoid remove/add of GL component on Window when moving splitter.
* | | Fix Bug 642 TestJSplitPaneMixHwLw01AWT (AWT-GLCanvas); Robustness ↵Sven Gothel2012-12-226-27/+144
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | GLContext/GLDrawable - Fix Bug 642 TestJSplitPaneMixHwLw01AWT On Windows platform when mixing hw/lw JSplitPanel, the GLCanvas is removed and added when splitter is moved. The lack of robustness (see below) lead to an exception. Note: Only w/ GLJPanel (no hw/lw mixing) the splitter can be moved in both direction. Only here it is guaranteed that the GL component will survive the action. - Fix AWT-GLCanvas EDT Runnable: swapBuffer().. / display(..) - Check drawable.isRealized() within the lock on the performing thread. This is not possible before issuing the EDT Runnable action since we cannot hold the lock beforehand. - Robustness GLDrawableImpl - boolean realized -> volatile boolean realized - remove 'synchronized' on isRealized() and setRealized(..) - Use dbl-checked locking on 'realized' test for swapBuffers() and setRealized(..) - Robustness GLContextImpl - Catch createImpl(..) exception and properly return CONTEXT_NOT_CURRENT
* | | *Drawable impl. DEBUG: Add getThreadName() to debug out.Sven Gothel2012-12-228-13/+16
| | |
* | | FBObject, minor edit: GL2GL3.GL_MAX_COLOR_ATTACHMENTS -> ↵Sven Gothel2012-12-211-1/+2
| | | | | | | | | | | | GL2ES2.GL_MAX_COLOR_ATTACHMENTS
* | | GLContextImpl: Make createContextARBImpl/setGLFunctionAvailability more ↵Sven Gothel2012-12-219-23/+32
| | | | | | | | | | | | robost while detecting erroneous queried GL version
* | | Bug 651: Mesa3D: GL_INVALID_ENUM in ↵Sven Gothel2012-12-202-2/+212
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | glGetIntegerv(pname=GL_MAX_TEXTURE_IMAGE_UNITS) ; Add unit test / bisect Mesa3D This bug lies within Mesa3D (any renderer) and is fixed in commit 8dc79ae7d73cf6711c2182ff9a5d37ef6c989d23. Mesa3D Version 9.0 still exposes this bug, where 9.0.1 has it fixed w/ above commit.
* | | Bug642: Add test case for Swing JSplit Pane w/ GLCanvas and GLJPanelSven Gothel2012-12-161-0/+179
| | |
* | | MacOSXCGLContext: Use new setLocation(gl, shader-program); Minor edits..Sven Gothel2012-12-163-3/+3
| | |
* | | GLJPanel: Impl. is GLProfile agnostic; Use ↵Sven Gothel2012-12-166-427/+463
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | GLDrawableFactory.createOffscreenDrawable(..) for common OffscreenBackend (dropping pbuffer/software); Flip FBO w/ GLSL texture renderer. - Implementation is GLProfile agnostic - Shall work on ES2, GL2, .. etc - Use GLDrawableFactory.createOffscreenDrawable(..) for common OffscreenBackend (dropping pbuffer/software) - Leave offscreen selection to common factory code, favoring FBO - Flip FBO w/ GLSL texture renderer - Faster on low CPU machines - Enabled if GL2ES2 and FBO offscreen
* | | GLArrayData/ImmModeSink: Remove implicit dependency on ShaderState - allow ↵Sven Gothel2012-12-1621-327/+1283
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | operating w/o it; ShaderState: Remove notion of GL context attachment, use pass-through or object association; GLArrayData/GLUniformData: Add basic GLSL location methods - GLArrayData/GLUniformData: Add basic GLSL location methods - GLArrayData - add: setLocation(..) for attribute location/index retrieval (post link) and binding (pre link) - GLUniformData - add: setLocation(..) for attribute location/index retrieval (post link) - GLArrayData/ImmModeSink: Remove implicit dependency on ShaderState - allow operating w/o it - GLArrayData - add: 'public void associate(Object obj, boolean enable)', allows setting ShaderState usage - ShaderState: Remove notion of GL context attachment, use pass-through or object association - ownsAttribute(..) associates the attribute w/ ShaderState - removed GL context ShaderState attachment Tested: - ImmModeSink w/ GLSL/ES2 w/ and w/o ShaderState - GLArrayData* w/ and w/o ShaderState
* | | Cleanup GLContext special entries: getOffscreenContextPixelDataType(), ↵Sven Gothel2012-12-1516-107/+158
| |/ |/| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | getOffscreenContextReadBuffer(), .. ; Add GLFBODrawable API entries for multi buffering (no impl. yet); GLJPanel 1st simplification using offscreen drawable - Cleanup GLContext special entries: getOffscreenContextPixelDataType(), getOffscreenContextReadBuffer(), .. ; - add: getDefaultReadBuffer() (-> exposed via GLBase as well) - add: isGLOrientationFlippedVertical() - add: getDefaultPixelDataType() - removed impl: getOffscreenContextPixelDataType() - removed impl: getOffscreenContextReadBuffer() - removed impl: offscreenImageNeedsVerticalFlip() - Add GLFBODrawable API entries for multi buffering (no impl. yet); - TODO: Add implementation code in GLFBODrawableImpl - GLJPanel 1st simplification using FBO - Use above new GL/GLContext entries - Fix: getNativeSurface() and getHandle() - TODO: - Remove distinction of 'pbuffer' and 'software', - Use GLDrawableFactory.createOffscreenDrawable(..) - Use GL for FBO swapping
* | SWT GLCanvas: Fix sporadic drop of redraw on X11 _and_ allow using custom ↵Sven Gothel2012-12-0411-298/+912
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | GLCapabilities on X11 (feature complete) To allow custom GLCapabilities, we had to use native parenting on X11 w/ a new child window. The desired visualID chosen by the users GLCapabilities is passed to the new child window. The redraw drops must be caused by the original GDK or the new child GDK window. Now we use a plain X11 child window similar to NEWT's X11 window and NewtCanvasSWT, which doesn't expose this bug. (Note: SWTAccessor/GLCanvas still contains the uncommented GDK code path for further inspection, if desired) Also added SWTNewtEventFactory to test event handling on the SWT GLCanvas w/ GearsES2. TestSWTJOGLGLCanvas01GLn tests custom GLCapabilities now. SWTEDTUtil has been moved to private: com.jogamp.newt.swt -> jogamp.newt.swt.
* | Fix GLDrawableHelper invokeGLImpl(..): Only attempt to release context after ↵Sven Gothel2012-12-021-25/+28
| | | | | | | | successfull claim; Also fix intendations of block.
* | SWT GLCanvas/NewtCanvasSWT: Check isVisible() @ validation; NewtCanvasSWT ↵Sven Gothel2012-12-024-60/+113
| | | | | | | | | | | | | | | | | | | | remove just introduced setVisible(false) and adapt to setEDTUtil() changes. ; Enhance Bug 643 unit test: Also test NEWT EDT and pre-visible GLWindow. - SWT GLCanvas/NewtCanvasSWT: Check isVisible() @ validation - NewtCanvasSWT remove just introduced setVisible(false) and adapt to setEDTUtil() changes - Enhance Bug 643 unit test: Also test NEWT EDT and pre-visible GLWindow.
* | NEWT EDTUtil: Simplify running state (default is running @ setEDTUtil()); ↵Sven Gothel2012-12-027-80/+81
| | | | | | | | Simplify DefaultEDTUtil impl. and fix concurrency leak w/ 'shouldStop'
* | Fix Bug 643: SWT 'display.asyncExec(Runnable runnable)' runnable not ↵Sven Gothel2012-12-021-10/+9
| | | | | | | | | | | | | | | | | | | | | | | | executed on Windows Turns out that the NEWT Windows impl. didn't properly validated the client region @ WM_PAINT and hence 'exhausted' the message pipeline, i.e. never reached an IDLE state. The latter caused SWT to never reach a point where deferred asyncExec(..) Runnables got processed. Besides this SWT effect, this also caused a NEWT window on Windows to always repaint itself (?).
* | NEWT WindowImpl fixes: surfaceLockCount-- if native lock fails; ↵Sven Gothel2012-12-022-28/+36
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | waitForVisible(.., fastFail:=false); waitForSize(..) @ setSize; reparent definePosition(..); - surfaceLockCount-- if native lock fails In case native lock fails, not only remove the windowLock but also decr. surfaceLockCount (proper roll back) - was a BUG! - waitForVisible(.., fastFail:=false) Don't fail fast if visibility wasn't reached. - waitForSize(..) @ setSize Wait for size change - otherwise an SWT child won't reach desired size. - reparent definePosition(..); Position might not get updated by WM events (SWT parent apparently) - Windows WindowDriver: Cleanup code a bit.
* | NEWT WindowImpl: Don't issue native resize if invisible, simply use ↵Sven Gothel2012-11-301-18/+13
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | defineSize(..); Don't set persitent undecorated flag if child window at creation; Use local 'screen' directly. - Don't issue native resize if invisible, simply use defineSize(..) Invisible windows may not promote size change natively, hence simply setting the size via defineSize(..) is appropriate. Latter setVisible(true) will take size into account. - Don't set persitent undecorated flag if child window at creation Even if a window is a child at creation, it maybe reparented to top-level where the default behavior is to be expected. Undecorated top-level window shall require explicit setUndecorated(true). - Use local 'screen' directly. No need to make code more complicate ..
* | Fix NewtCanvasSWT's newtChild usage: Only use set newtChild if it's ready, ↵Sven Gothel2012-11-301-6/+15
| | | | | | | | i.e. SWTEDTUtil set and parented; Recognize pending resize.
* | Simplify NEWT EDTUtil invoke: To start EDT Runnable maybe null - start EDT ↵Sven Gothel2012-11-305-62/+54
| | | | | | | | | | | | even if on EDT thread. DEBUG: Name EDTUtil impl, e.g. Default, AWT and SWT
* | Bug628: Adding unit-test 'TestNewtCanvasSWTBug628ResizeDeadlock' exposing ↵Sven Gothel2012-11-292-7/+288
| | | | | | | | | | | | | | | | | | | | | | NewtCanvasSWT asyncExec(..) bug w/ native parenting The unit test shows, that while using JOGL's SWT GLCanvas Display's asyncExec(..) works properly, but w/ NewtCanvasSWT on Windows does not. NewtCanvasSWT differs w/: - Using native parenting [Newt GLWindow to SWT Canvas] - Processing native events in own NEWT EDT, w/ own Windows dispatch hook [For the child GLWindow only]
* | NewtCanvasSWT: Add DisposeListenerSven Gothel2012-11-291-3/+18
| |
* | SWT GLCanvas: Fix dispose bug, check for isDisposed() and add ↵Sven Gothel2012-11-291-17/+52
| | | | | | | | | | | | | | | | | | | | | | | | | | | | DisposeListener; Run GL tasks on current thread w/o restrictions Fix dispose bug, check for isDisposed() and add DisposeListener - Don't issue SWTAccessor.setRealized(..), since it's called implicit via super.dispose() - Check isDisposed() .. - add DisposeListener to act on parent's disposal (Shell, Composition, ..) Run GL tasks on current thread w/o restrictions + * The current thread seems to be valid for all platforms, + * since no SWT lifecycle tasks are being performed w/ this call. + * Only GL task, which are independent from the SWT threading model.
* | TestSWTJOGLGLCanvas01GLn: Use display.syncExec(..) where possible, add AnimatorSven Gothel2012-11-291-5/+24
| |
* | SWTAccessor: Add SWT 4.3's X11-GTK version adaption (2.14, 2.24, 3.0)Sven Gothel2012-11-291-46/+170
| |