<Compile Include="src\Mono.Cairo\EGLDevice.cs" />
<Compile Include="src\Mono.Cairo\DRMDevice.cs" />
<Compile Include="src\Mono.Cairo\DRMSurface.cs" />
+ <Compile Include="src\CrowMonitor.cs" />
</ItemGroup>
<ItemGroup>
<Reference Include="System" />
--- /dev/null
+//
+// CrowMonitor.cs
+//
+// Author:
+// Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+// Copyright (c) 2013-2017 Jean-Philippe Bruyère
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+using System;
+using System.Threading;
+using System.Diagnostics;
+
+namespace Crow
+{
+ public class NamedMutex {
+ public string Name;
+ public NamedMutex (string name){
+ Name = name;
+ }
+ }
+ public static class CrowMonitor
+ {
+ public static Stopwatch timer = Stopwatch.StartNew();
+
+ public static bool TryEnter (NamedMutex mutex, string ctxName = "?"){
+ Console.WriteLine("{3}:TRY LCK:{0} => {1} ({2})", Thread.CurrentThread.Name, mutex.Name, ctxName, timer.ElapsedTicks);
+ bool locking = Monitor.TryEnter (mutex);
+ if (locking)
+ Console.WriteLine("{2}:\tLOCKED :{0} => {1} mutex", Thread.CurrentThread.Name, mutex.Name, timer.ElapsedTicks);
+ return locking;
+
+ }
+ public static void Enter (NamedMutex mutex, string ctxName = "?") {
+ Console.WriteLine("{3}:WAIT :{0} => {1} ({2})", Thread.CurrentThread.Name, mutex.Name, ctxName, timer.ElapsedTicks);
+ Monitor.Enter (mutex);
+ Console.WriteLine("{3}:\tLOCKED :{0} => {1} mutex ({2})", Thread.CurrentThread.Name, mutex.Name, ctxName, timer.ElapsedTicks);
+ }
+ public static void Exit (NamedMutex mutex) {
+ Monitor.Exit (mutex);
+ Console.WriteLine("{2}:\tRELEASE:{0} => {1} mutex", Thread.CurrentThread.Name, mutex.Name, timer.ElapsedTicks);
+ }
+ }
+}
+
/// Thread monitored by current interface with Finished event when state==Stopped
/// </summary>
public class CrowThread {
- Thread thread;
+ internal Thread thread;
public event EventHandler Finished;
public GraphicObject Host;
public CrowThread (GraphicObject host, ThreadStart start){
{
public class GraphicObject : ILayoutable, IValueChange
{
+ internal NamedMutex mutex = new NamedMutex("GRAPHIC OBJECT");
internal static ulong currentUid = 0;
internal ulong uid = 0;
if (parent == value)
return;
DataSourceChangeEventArgs e = new DataSourceChangeEventArgs (parent, value);
- lock (this)
- parent = value;
+ CrowMonitor.Enter (mutex, "set parent of object");
+ parent = value;
+ CrowMonitor.Exit (mutex);
onParentChanged (this, e);
}
public virtual void RegisterForLayouting(LayoutingType layoutType){
if (Parent == null)
return;
- lock (CurrentInterface.LayoutMutex) {
- //prevent queueing same LayoutingType for this
- layoutType &= (~RegisteredLayoutings);
+ CrowMonitor.Enter (CurrentInterface.LayoutMutex, "register for layouting");
+ //prevent queueing same LayoutingType for this
+ layoutType &= (~RegisteredLayoutings);
- if (layoutType == LayoutingType.None)
- return;
+ if (layoutType != LayoutingType.None) {
+
//dont set position for stretched item
if (Width == Measure.Stretched)
layoutType &= (~LayoutingType.X);
// //prevent queueing same LayoutingType for this
// layoutType &= (~RegisteredLayoutings);
- if (layoutType == LayoutingType.None)
- return;
-
- //enqueue LQI LayoutingTypes separately
- if (layoutType.HasFlag (LayoutingType.Width))
- CurrentInterface.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.Width, this));
- if (layoutType.HasFlag (LayoutingType.Height))
- CurrentInterface.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.Height, this));
- if (layoutType.HasFlag (LayoutingType.X))
- CurrentInterface.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.X, this));
- if (layoutType.HasFlag (LayoutingType.Y))
- CurrentInterface.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.Y, this));
- if (layoutType.HasFlag (LayoutingType.ArrangeChildren))
- CurrentInterface.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.ArrangeChildren, this));
+ if (layoutType != LayoutingType.None) {
+ //enqueue LQI LayoutingTypes separately
+ if (layoutType.HasFlag (LayoutingType.Width))
+ CurrentInterface.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.Width, this));
+ if (layoutType.HasFlag (LayoutingType.Height))
+ CurrentInterface.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.Height, this));
+ if (layoutType.HasFlag (LayoutingType.X))
+ CurrentInterface.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.X, this));
+ if (layoutType.HasFlag (LayoutingType.Y))
+ CurrentInterface.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.Y, this));
+ if (layoutType.HasFlag (LayoutingType.ArrangeChildren))
+ CurrentInterface.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.ArrangeChildren, this));
+ }
}
+ CrowMonitor.Exit (CurrentInterface.LayoutMutex);
}
/// <summary> trigger dependant sizing component update </summary>
//TODO:this test should not be necessary
if (Slot.Height < 0 || Slot.Width < 0 || parent == null)
return;
- lock (this) {
- if (cacheEnabled) {
- if (Slot.Width > Interface.MaxCacheSize || Slot.Height > Interface.MaxCacheSize)
- cacheEnabled = false;
- }
+
+ CrowMonitor.Enter (mutex, "Paint");
- if (cacheEnabled) {
- if (IsDirty)
- RecreateCache ();
+ if (cacheEnabled) {
+ if (Slot.Width > Interface.MaxCacheSize || Slot.Height > Interface.MaxCacheSize)
+ cacheEnabled = false;
+ }
- UpdateCache (ctx);
- if (!isEnabled)
- paintDisabled (ctx, Slot + Parent.ClientRectangle.Position);
- } else {
- Rectangle rb = Slot + Parent.ClientRectangle.Position;
- ctx.Save ();
+ if (cacheEnabled) {
+ if (IsDirty)
+ RecreateCache ();
- ctx.Translate (rb.X, rb.Y);
+ UpdateCache (ctx);
+ if (!isEnabled)
+ paintDisabled (ctx, Slot + Parent.ClientRectangle.Position);
+ } else {
+ Rectangle rb = Slot + Parent.ClientRectangle.Position;
+ ctx.Save ();
- onDraw (ctx);
- if (!isEnabled)
- paintDisabled (ctx, Slot);
+ ctx.Translate (rb.X, rb.Y);
- ctx.Restore ();
- }
- LastPaintedSlot = Slot;
+ onDraw (ctx);
+ if (!isEnabled)
+ paintDisabled (ctx, Slot);
+
+ ctx.Restore ();
}
+ LastPaintedSlot = Slot;
+
+ CrowMonitor.Exit (mutex);
}
void paintDisabled(Context gr, Rectangle rb){
gr.Operator = Operator.Xor;
if (string.IsNullOrEmpty(value))
Picture = null;
else {
- lock(CurrentInterface.LayoutMutex){
- LoadImage (value);
- }
+ CrowMonitor.Enter(CurrentInterface.LayoutMutex, "load image");
+ LoadImage (value);
+ CrowMonitor.Exit(CurrentInterface.LayoutMutex);
}
} catch (Exception ex) {
Debug.WriteLine (ex.Message);
close ();
}
public static MessageBox Show (Type msgBoxType, string message, string okMsg = "", string cancelMsg = ""){
- lock (Interface.CurrentInterface.UpdateMutex) {
- MessageBox mb = new MessageBox ();
- mb.Initialize ();
- mb.CurrentInterface.AddWidget (mb);
- mb.MsgType = msgBoxType;
- mb.Message = message;
- if (!string.IsNullOrEmpty(okMsg))
- mb.OkMessage = okMsg;
- if (!string.IsNullOrEmpty(cancelMsg))
- mb.CancelMessage = cancelMsg;
- return mb;
- }
+ MessageBox mb = null;
+ CrowMonitor.Enter (Interface.CurrentInterface.UpdateMutex, "message box show");
+ mb = new MessageBox ();
+ mb.Initialize ();
+ mb.CurrentInterface.AddWidget (mb);
+ mb.MsgType = msgBoxType;
+ mb.Message = message;
+ if (!string.IsNullOrEmpty(okMsg))
+ mb.OkMessage = okMsg;
+ if (!string.IsNullOrEmpty(cancelMsg))
+ mb.CancelMessage = cancelMsg;
+ CrowMonitor.Exit (Interface.CurrentInterface.UpdateMutex);
+ return mb;
+
}
}
}
NotifyValueChanged ("Data", data);
- lock (CurrentInterface.LayoutMutex)
- ClearItems ();
+ CrowMonitor.Enter (CurrentInterface.LayoutMutex, "templated group enclosing clearItems");
+ ClearItems ();
+ CrowMonitor.Exit (CurrentInterface.LayoutMutex);
if (data == null)
return;
loadingThread = new CrowThread (this, loading);
+ loadingThread.thread.Name = "list loading thread";
loadingThread.Finished += (object sender, EventArgs e) => (sender as TemplatedGroup).Loaded.Raise (sender, e);
loadingThread.Start ();
if (page == items)
return;
- lock (CurrentInterface.LayoutMutex)
- items.AddChild (page);
+ CrowMonitor.Enter (CurrentInterface.LayoutMutex, "templeted group add chile (page)");
+ items.AddChild (page);
+ CrowMonitor.Exit (CurrentInterface.LayoutMutex);
#if DEBUG_LOAD
loadingTime.Stop ();
iTemp = ItemTemplates ["default"];
}
- lock (CurrentInterface.LayoutMutex) {
- g = iTemp.CreateInstance(CurrentInterface);
- page.AddChild (g);
- //g.LogicalParent = this;
- registerItemClick (g);
- }
+ CrowMonitor.Enter (CurrentInterface.LayoutMutex, "templeted group add item to page");
+ g = iTemp.CreateInstance(CurrentInterface);
+ page.AddChild (g);
+ //g.LogicalParent = this;
+ registerItemClick (g);
+ CrowMonitor.Exit (CurrentInterface.LayoutMutex);
+
if (iTemp.Expand != null && g is Expandable) {
(g as Expandable).Expand += iTemp.Expand;
/// <summary>Coordinate of the dirty bmp on the original bmp</summary>
public Rectangle DirtyRect;
/// <summary>Locked for each layouting operation</summary>
- public object LayoutMutex = new object();
+ public NamedMutex LayoutMutex = new NamedMutex("LAYOUTING");
/// <summary>Sync mutex between host and Crow for rendering operations (bmp, dirtyBmp,...)</summary>
- public object RenderMutex = new object();
+ public NamedMutex DrawingQueueMutex = new NamedMutex("DRAWING QUEUE");
+ /// <summary>Sync mutex between host and Crow for rendering operations (bmp, dirtyBmp,...)</summary>
+ public NamedMutex RenderMutex = new NamedMutex("RENDERING");
/// <summary>Global lock of the update cycle</summary>
- public object UpdateMutex = new object();
+ public NamedMutex UpdateMutex = new NamedMutex("UPDATE");
//TODO:share resource instances
/// <summary>
/// Store loaded resources instances shared among controls to reduce memory footprint
/// of this Interface</summary>
public GraphicObject LoadInterface (string path)
{
- lock (UpdateMutex) {
- GraphicObject tmp = Load (path);
- AddWidget (tmp);
-
- return tmp;
- }
+ CrowMonitor.Enter (UpdateMutex, "load interface");
+ GraphicObject tmp = Load (path);
+ AddWidget (tmp);
+ CrowMonitor.Exit (UpdateMutex);
+ return tmp;
}
/// <summary>Create an instance of a GraphicObject linked to this interface but
/// not added to the GraphicTree</summary>
/// GraphObj's property Set methods could trigger an update from another thread</summary>
public void EnqueueForRepaint(GraphicObject g)
{
- lock (DrawingQueue) {
- if (g.IsQueueForRedraw)
- return;
+ CrowMonitor.Enter (DrawingQueueMutex, "engueue for repaint");
+ if (!g.IsQueueForRedraw){
DrawingQueue.Enqueue (g);
g.IsQueueForRedraw = true;
}
+ CrowMonitor.Exit (DrawingQueueMutex);
}
/// <summary>Main Update loop, executed in this interface thread, lock the UpdateMutex
/// Steps:
for (int i = 0; i < tmpThreads.Length; i++)
tmpThreads [i].CheckState ();
- if (!Monitor.TryEnter (UpdateMutex))
+ if (!CrowMonitor.TryEnter (UpdateMutex, "main update loop"))
return;
+
#if MEASURE_TIME
updateMeasure.StartCycle();
updateMeasure.StopCycle();
#endif
- Monitor.Exit (UpdateMutex);
+ CrowMonitor.Exit (UpdateMutex);
}
/// <summary>Layouting loop, this is the first step of the udpate and process registered
/// Layouting queue items. Failing LQI's are requeued in this cycle until MaxTry is reached which
layoutingMeasure.StartCycle();
#endif
- if (Monitor.TryEnter (LayoutMutex)) {
+ if (CrowMonitor.TryEnter (LayoutMutex, "main layouting loop")) {
DiscardQueue = new Queue<LayoutingQueueItem> ();
//Debug.WriteLine ("======= Layouting queue start =======");
LayoutingQueueItem lqi;
lqi.ProcessLayouting ();
}
LayoutingQueue = DiscardQueue;
- Monitor.Exit (LayoutMutex);
+ CrowMonitor.Exit (LayoutMutex);
DiscardQueue = null;
}
#endif
GraphicObject g = null;
while (DrawingQueue.Count > 0) {
- lock (DrawingQueue)
- g = DrawingQueue.Dequeue ();
- lock (g)
- g.ClippingRegistration ();
+ CrowMonitor.Enter (DrawingQueueMutex, "clipping registration");
+ g = DrawingQueue.Dequeue ();
+ CrowMonitor.Exit (DrawingQueueMutex);
+ CrowMonitor.Enter (g.mutex, "after dequeue, before entering clipping registration");
+ g.ClippingRegistration ();
+ CrowMonitor.Exit (g.mutex);
}
#if MEASURE_TIME
#if DEBUG_CLIP_RECTANGLE
clipping.stroke (ctx, Color.Red.AdjustAlpha(0.5));
#endif
- lock (RenderMutex) {
+ CrowMonitor.Enter (RenderMutex, "creating dirty rect");
// Array.Copy (bmp, dirtyBmp, bmp.Length);
IsDirty = true;
if (IsDirty)
} else
IsDirty = false;
- }
+ CrowMonitor.Exit (RenderMutex);
clipping.Reset ();
}
//surf.WriteToPng (@"/mnt/data/test.png");
}
}
- lock (UpdateMutex)
- GraphicTree.Insert (ptr, g);
+ CrowMonitor.Enter (UpdateMutex, "interface add widget");
+ GraphicTree.Insert (ptr, g);
+ CrowMonitor.Exit (UpdateMutex);
g.RegisteredLayoutings = LayoutingType.None;
g.RegisterForLayouting (LayoutingType.Sizing | LayoutingType.ArrangeChildren);
if (g.Contains (_hoverWidget))
HoverWidget = null;
}
- lock (UpdateMutex) {
- g.DataSource = null;
- g.Visible = false;
- GraphicTree.Remove (g);
- }
+ CrowMonitor.Enter (UpdateMutex, "interface delete widget");
+ g.DataSource = null;
+ g.Visible = false;
+ GraphicTree.Remove (g);
+ CrowMonitor.Exit (UpdateMutex);
}
/// <summary> Put widget on top of other root widgets</summary>
public void PutOnTop(GraphicObject g, bool isOverlay = false)
}
if (GraphicTree.IndexOf(g) > ptr)
{
- lock (UpdateMutex) {
+ CrowMonitor.Enter (UpdateMutex, "interface put on top");
+
GraphicTree.Remove (g);
GraphicTree.Insert (ptr, g);
- }
+ CrowMonitor.Exit (UpdateMutex);
+
EnqueueForRepaint (g);
}
}
/// <summary> Remove all Graphic objects from top container </summary>
public void ClearInterface()
{
- lock (UpdateMutex) {
+ CrowMonitor.Enter (UpdateMutex, "clear interface");
+
while (GraphicTree.Count > 0) {
//TODO:parent is not reset to null because object will be added
//to ObjectToRedraw list, and without parent, it fails
g.Visible = false;
GraphicTree.RemoveAt (0);
}
- }
+ CrowMonitor.Exit (UpdateMutex);
+
#if DEBUG_LAYOUTING
LQIsTries = new List<LQIList>();
curLQIsTries = new LQIList();
#endregion
public void ProcessResize(Rectangle bounds){
- lock (UpdateMutex) {
+ CrowMonitor.Enter (UpdateMutex, "process resize");
+
clientRectangle = bounds;
int stride = 4 * ClientRectangle.Width;
int bmpSize = Math.Abs (stride) * ClientRectangle.Height;
g.RegisterForLayouting (LayoutingType.All);
clipping.AddRectangle (clientRectangle);
- }
+ CrowMonitor.Exit (UpdateMutex);
+
}
#region Mouse and Keyboard Handling
}
//top level graphic obj's parsing
- lock (GraphicTree) {
- for (int i = 0; i < GraphicTree.Count; i++) {
- GraphicObject g = GraphicTree [i];
- if (g.MouseIsIn (e.Position)) {
- g.checkHoverWidget (e);
- if (g is Window)
- PutOnTop (g);
- return true;
- }
+ for (int i = 0; i < GraphicTree.Count; i++) {
+ GraphicObject g = GraphicTree [i];
+ if (g.MouseIsIn (e.Position)) {
+ g.checkHoverWidget (e);
+ if (g is Window)
+ PutOnTop (g);
+ return true;
}
}
+
HoverWidget = null;
return false;
}
using Cairo;
using Crow.Linux;
using Crow;
+using System.Reflection;
+using System.Linq;
namespace testDrm
{
public class TestApp : Application, IValueChange
{
+ [STAThread]
static void Main ()
{
+ System.Threading.Thread.CurrentThread.Name = "Main";
try {
using (TestApp crowApp = new TestApp ()) {
crowApp.Run ();
} catch (Exception ex) {
Console.WriteLine (ex.ToString ());
}
+ Console.WriteLine ("terminating");
}
#region IValueChange implementation
}
#endregion
- public bool Running = true;
+
public TestApp () : base () {
}
+
int frTime = 0;
int frMin = int.MaxValue;
int frMax = 0;
+ #region Test values for Binding
+// public int intValue = 500;
+// DirectoryInfo curDir = new DirectoryInfo (System.IO.Path.GetDirectoryName(Assembly.GetEntryAssembly().Location));
+// public FileSystemInfo[] CurDirectory {
+// get { return curDir.GetFileSystemInfos (); }
+// }
+// public int IntValue {
+// get {
+// return intValue;
+// }
+// set {
+// intValue = value;
+// NotifyValueChanged ("IntValue", intValue);
+// }
+// }
+// void onSpinnerValueChange(object sender, ValueChangeEventArgs e){
+// if (e.MemberName != "Value")
+// return;
+// intValue = Convert.ToInt32(e.NewValue);
+// }
+// void change_alignment(object sender, EventArgs e){
+// RadioButton rb = sender as RadioButton;
+// if (rb == null)
+// return;
+// NotifyValueChanged ("alignment", Enum.Parse(typeof(Alignment), rb.Caption));
+// }
+// public IList<String> List2 = new List<string>(new string[]
+// {
+// "string1",
+// "string2",
+// "string3",
+// }
+// );
+// public IList<String> TestList2 {
+// set{
+// List2 = value;
+// NotifyValueChanged ("TestList2", testList);
+// }
+// get { return List2; }
+// }
+ IList<Crow.Color> testList = Crow.Color.ColorDic;
+ public IList<Crow.Color> TestList {
+ set{
+ testList = value;
+ NotifyValueChanged ("TestList", testList);
+ }
+ get { return testList; }
+ }
+// string curSources = "";
+// public string CurSources {
+// get { return curSources; }
+// set {
+// if (value == curSources)
+// return;
+// curSources = value;
+// NotifyValueChanged ("CurSources", curSources);
+// }
+// }
+// bool boolVal = true;
+// public bool BoolVal {
+// get { return boolVal; }
+// set {
+// if (boolVal == value)
+// return;
+// boolVal = value;
+// NotifyValueChanged ("BoolVal", boolVal);
+// }
+// }
+
+ #endregion
public override void Run ()
- {
+ {
Stopwatch frame = new Stopwatch ();
- Load ("#testDrm.ui.menu.crow").DataSource = this;
- Load ("#testDrm.ui.0.crow").DataSource = this;
- Load ("#testDrm.ui.0.crow").DataSource = this;
- Load ("#testDrm.ui.0.crow").DataSource = this;
- Load ("#testDrm.ui.0.crow").DataSource = this;
+// Load ("#testDrm.ui.menu.crow").DataSource = this;
+// Load ("#testDrm.ui.0.crow").DataSource = this;
+// Load ("#testDrm.ui.0.crow").DataSource = this;
+// Load ("#testDrm.ui.0.crow").DataSource = this;
+ //System.Threading.Thread.Sleep (100);
+ int i = 0;
while(Running){
try {
frame.Restart();
+ i++;
+
base.Run ();
+//
+ if (i == 1000){
+ Load ("#testDrm.ui.menu.crow").DataSource = this;
+ }
+
frame.Stop();
frTime = (int)frame.ElapsedTicks;
NotifyValueChanged("frameTime", frTime);
{
Running = false;
}
+ void onLoadClick(object send, Crow.MouseButtonEventArgs e)
+ {
+ Console.WriteLine ("********** LOADING ui item ******************");
+ GraphicObject go = Load ("#testDrm.ui.2.crow");
+ Console.WriteLine ("********** SETTING DATASOURCE ON ITEM ******************");
+ go.DataSource = this;
+ Console.WriteLine ("********** LOADING FINISHED ******************");
+ }
}
}
namespace Crow
{
public class Application : IDisposable
- {
+ {
+ public bool Running = true;
DRI.GPUControler gpu;
Cairo.GLSurface cairoSurf;
//
Crow.XCursor cursor;
int previousVT = -1, appVT = -1;
-//
- public Application(){
+ public Application(){
if (Kernel.signal (Signal.SIGUSR1, switch_request_handle) < 0)
throw new Exception ("signal handler registation failed");
if (Kernel.signal (Signal.SIGINT, sigint_handler) < 0)
gpu = new DRI.GPUControler();
cairoSurf = gpu.CairoSurf;
- cursor = Crow.XCursorFile.Load("#Crow.Images.Icons.Cursors.arrow").Cursors[0];
-
CrowInterface = new Interface ();
Thread t = new Thread (interfaceThread);
+ t.Name = "Interface";
t.IsBackground = true;
t.Start ();
initInput ();
CrowInterface.ProcessResize (new Size (gpu.Width, gpu.Height));
+ cursor = Crow.XCursorFile.Load("#Crow.Images.Icons.Cursors.arrow").Cursors[0];
gpu.updateCursor (cursor);
//CrowInterface.MouseCursorChanged += CrowInterface_MouseCursorChanged;
}
}
}
void sigint_handler (Signal s){
- Console.WriteLine ("SIGINT catched");
- //Running = false;
+ Console.WriteLine ("{0}: SIGINT catched", CrowMonitor.timer.ElapsedTicks);
+ Running = false;
}
// void CrowInterface_MouseCursorChanged (object sender, MouseCursorChangedEventArgs e)
// {
// using (Cairo.Context ctx = new Cairo.Context (cairoSurf)) {
// ctx.Rectangle (0, 0, gpu.Width, gpu.Height);
-// ctx.SetSourceRGB (0, 0, 0.1);
+// ctx.SetSourceRGB (0, 0, 1);
+// ctx.Fill ();
+// ctx.Rectangle (5, 5, 50, 50);
+// ctx.SetSourceRGB (1, 0, 0);
+// ctx.Fill ();
+// ctx.Rectangle (1550, 850, 50, 50);
+// ctx.SetSourceRGB (0, 1, 0);
// ctx.Fill ();
// }
- if (Monitor.TryEnter (CrowInterface.RenderMutex)) {
+ if (CrowMonitor.TryEnter (CrowInterface.RenderMutex, "cairo paint dirty rect on backend surf")) {
if (CrowInterface.IsDirty) {
CrowInterface.IsDirty = false;
update = true;
}
}
}
- Monitor.Exit (CrowInterface.RenderMutex);
+ CrowMonitor.Exit (CrowInterface.RenderMutex);
}
-
+//
// if (!update)
// return;
// update = false;
cairoSurf.SwapBuffers ();
gpu.Update ();
+ //Thread.Sleep (1);
+ //gpu.MarkFBDirty ();
}
void initInput (){
Semaphore ready = new Semaphore(0, 1);
input_thread = new Thread (InputThreadLoop);
+ input_thread.Name = "input_thread";
input_thread.IsBackground = true;
input_thread.Start(ready);
}
[DllImportAttribute("libEGL.dll", EntryPoint = "eglWaitNative")]
[return: MarshalAsAttribute(UnmanagedType.I1)]
public static extern bool WaitNative(int engine);
- [DllImportAttribute("libEGL.dll", EntryPoint = "eglSwapBuffers")]
- [return: MarshalAsAttribute(UnmanagedType.I1)]
- public static extern bool SwapBuffers(EGLDisplay dpy, EGLSurface surface);
[DllImportAttribute("libEGL.dll", EntryPoint = "eglCopyBuffers")]
[return: MarshalAsAttribute(UnmanagedType.I1)]
public static extern bool CopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target);
{
#region pinvoke
[DllImportAttribute("libEGL.dll")]
- public static extern EGLSurface eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, IntPtr win, IntPtr attrib_list);
+ internal static extern EGLSurface eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, IntPtr win, IntPtr attrib_list);
[DllImportAttribute("libEGL.dll")]
- public static extern EGLSurface eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, int[] attrib_list);
+ internal static extern EGLSurface eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, int[] attrib_list);
[DllImportAttribute("libEGL.dll")]
- public static extern EGLSurface eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, int[] attrib_list);
+ internal static extern EGLSurface eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, int[] attrib_list);
[DllImportAttribute("libEGL.dll")][return: MarshalAsAttribute(UnmanagedType.I1)]
- public static extern bool eglDestroySurface(EGLDisplay dpy, EGLSurface surface);
+ internal static extern bool eglDestroySurface(EGLDisplay dpy, EGLSurface surface);
[DllImportAttribute("libEGL.dll")][return: MarshalAsAttribute(UnmanagedType.I1)]
- public static extern bool eglQuerySurface(EGLDisplay dpy, EGLSurface surface, int attribute, out int value);
+ internal static extern bool eglQuerySurface(EGLDisplay dpy, EGLSurface surface, int attribute, out int value);
[DllImportAttribute("libEGL.dll")]
- public static extern EGLSurface eglCreatePbufferFromClientBuffer(EGLDisplay dpy, int buftype, EGLClientBuffer buffer, EGLConfig config, int[] attrib_list);
+ internal static extern EGLSurface eglCreatePbufferFromClientBuffer(EGLDisplay dpy, int buftype, EGLClientBuffer buffer, EGLConfig config, int[] attrib_list);
[DllImportAttribute("libEGL.dll")][return: MarshalAsAttribute(UnmanagedType.I1)]
- public static extern bool eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, int attribute, int value);
+ internal static extern bool eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, int attribute, int value);
[DllImportAttribute("libEGL.dll")][return: MarshalAsAttribute(UnmanagedType.I1)]
- public static extern bool eglBindTexImage(EGLDisplay dpy, EGLSurface surface, int buffer);
+ internal static extern bool eglBindTexImage(EGLDisplay dpy, EGLSurface surface, int buffer);
[DllImportAttribute("libEGL.dll")][return: MarshalAsAttribute(UnmanagedType.I1)]
- public static extern bool eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, int buffer);
+ internal static extern bool eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, int buffer);
+ [DllImportAttribute("libEGL.dll")][return: MarshalAsAttribute(UnmanagedType.I1)]
+ internal static extern bool eglSwapBuffers(EGLDisplay dpy, EGLSurface surface);
+
#endregion
Context ctx;
if (!Context.MakeCurrent(ctx.dpy, handle, handle, ctx.ctx))
throw new NotSupportedException(string.Format("eglMakeCurrent on surface Failed: {0}",Context.GetError()));
}
+ public void SwapBuffers () {
+ if (!eglSwapBuffers (ctx.dpy, handle))
+ throw new NotSupportedException(string.Format("eglSwapBuffers Failed: {0}",Context.GetError()));
+ }
#region IDisposable implementation
~Surface(){
using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.Diagnostics;
+using System.Threading;
namespace Linux.DRI {
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
Resources resources = null;
Connector connector = null;
Crtc currentCrtc = null;
- ModeInfo currentMode;
+ ModeInfo currentMode, originalMode;
+ uint originalFB;
public GPUControler(string gpu_path = "/dev/dri/card0"){
fd_gpu = Libc.open(gpu_path, OpenFlags.ReadWrite | OpenFlags.CloseOnExec);
public int Width { get { return (int)currentMode.hdisplay; }}
public int Height { get { return (int)currentMode.vdisplay; }}
+ ModeInfo getNewMode(){
+ ModeInfo mode = currentCrtc.CurrentMode;
+ mode.clock = 118250;
+ mode.hdisplay = 1600;
+ mode.hsync_start = 1696;
+ mode.hsync_end = 1856;
+ mode.htotal = 2112;
+ mode.vdisplay = 900;
+ mode.vsync_start = 903;
+ mode.vsync_end = 908;
+ mode.vtotal = 934;
+ mode.flags |= (uint)VideoMode.NHSYNC;
+ mode.flags |= (uint)VideoMode.PVSYNC;
+ return mode;
+ }
+ unsafe void setNewMode(){
+
+ //currentCrtc.handle->mode = currentMode;
+// ModeInfo* mode = (ModeInfo*)Marshal.AllocHGlobal (sizeof(ModeInfo));// pConnector->modes;
+// *mode = currentMode;
+
+ uint fb;
+ GBM.gbm_bo* bo = GBM.BufferObject.gbm_bo_create (gbmDev.handle, (uint)Width, (uint)Height, GBM.SurfaceFormat.ARGB8888, GBM.SurfaceFlags.Scanout);
+ int ret = drmModeAddFB (fd_gpu, (uint)Width, (uint)Height, (byte)depth, (byte)bpp, bo->Stride, (uint)bo->Handle32, out fb);
+ if (ret != 0)
+ Console.WriteLine ("addFb failed: {0}", ret);
+ bo->SetUserData ((IntPtr)fb, handleDestroyFB);
+
+ uint connId = connector.Id;
+ ret = drmModeSetCrtc (fd_gpu, currentCrtc.Id, fb, 0, 0, &connId, 1, ref currentMode);
+ if (ret != 0)
+ Console.WriteLine ("set new mode setCrtc failed: {0}", ret);
+ //GBM.BufferObject.gbm_bo_destroy (bo);
+
+ //Console.WriteLine ("new mode set to {0} x {1}", Width, Height);
+ }
bool defaultConfiguration (){
//select the first connected connector
foreach (Connector c in resources.Connectors) {
return false;
currentCrtc = connector.CurrentEncoder.CurrentCrtc;
- currentMode = currentCrtc.CurrentMode;
-
+ originalMode = currentCrtc.CurrentMode;
+ originalFB = currentCrtc.CurrentFbId;
+ currentMode = getNewMode();
+
+
//configure a rendering stack
gbmSurf = new GBM.Surface (gbmDev, Width, Height,
GBM.SurfaceFlags.Rendering | GBM.SurfaceFlags.Scanout);
+ setNewMode ();
+
eglSurf = new EGL.Surface (eglctx, gbmSurf);
eglSurf.MakeCurrent ();
if (cairoDev.Acquire () != Cairo.Status.Success)
Console.WriteLine ("[Cairo]: Failed to acquire egl device.");
-
+
+// using (Cairo.Context ctx = new Cairo.Context (CairoSurf)) {
+// ctx.Rectangle (0, 0, Width, Height);
+// ctx.SetSourceRGB (0, 0, 1);
+// ctx.Fill ();
+// }
+// CairoSurf.Flush ();
+// CairoSurf.SwapBuffers ();
+// Update ();
+
+ //Thread.Sleep (1);
return true;
}
void handleDestroyFB(ref GBM.gbm_bo bo, IntPtr data)
GBM.gbm_bo* bo;
uint fb;
-// PollFD fds = new PollFD();
-// fds.fd = fd_gpu;
-// fds.events = PollFlags.In;
-//
-// EventContext evctx = new EventContext();
-// evctx.version = EventContext.Version;
-// evctx.page_flip_handler = PageFlipPtr;
-
-// int timeout = -1;//block ? -1 : 0;
-//
-
if (!gbmSurf.HasFreeBuffers)
throw new NotSupportedException("[GBM] Out of free buffer");
bo = gbmSurf.Lock ();
- //fb = getFbFromBo (bo);
- //unsafe {
- //Console.WriteLine ("current fb: {0}", currentCrtc.CurrentFbId);
- //if (currentCrtc.CurrentFbId == 0)
- int ret = drmModeAddFB (fd_gpu, currentMode.hdisplay, currentMode.vdisplay, (byte)depth, (byte)bpp, bo->Stride, (uint)bo->Handle32, out fb);
- if (ret != 0)
- Console.WriteLine ("addFb failed: {0}", ret);
- //else
- // fb = currentCrtc.CurrentFbId;
- bo->SetUserData ((IntPtr)fb, handleDestroyFB);
+ int ret = drmModeAddFB (fd_gpu, currentMode.hdisplay, currentMode.vdisplay, (byte)depth, (byte)bpp, bo->Stride, (uint)bo->Handle32, out fb);
+ if (ret != 0)
+ Console.WriteLine ("addFb failed: {0}", ret);
+ bo->SetUserData ((IntPtr)fb, handleDestroyFB);
- uint connId = connector.Id;
- ret = drmModeSetCrtc (fd_gpu, currentCrtc.Id, fb, 0, 0, &connId, 1, ref currentMode);
- if (ret != 0)
- Console.WriteLine ("setCrtc failed: {0}", ret);
- //}
- gbmSurf.Release (bo);
+ uint connId = connector.Id;
+ ret = drmModeSetCrtc (fd_gpu, currentCrtc.Id, fb, 0, 0, &connId, 1, ref currentMode);
+ if (ret != 0)
+ Console.WriteLine ("setCrtc failed: {0}", ret);
- //bo.Dispose ();
-//
-// SetScanoutRegion (fb);
-// drmTimeOut.Restart();
-//
-// while (run && drmTimeOut.ElapsedMilliseconds < 10000){
-// BufferObject next_bo;
-// bool update = false;
-//
-// if (updateMousePos) {
-// lock (Sync) {
-// updateMousePos = false;
-// unsafe {
-// Drm.MoveCursor (fd_gpu, pEncoder->crtc_id, MouseX-8, MouseY-4);
-// }
-// }
-// }
-//
-// if (Monitor.TryEnter (CrowInterface.RenderMutex)) {
-// if (CrowInterface.IsDirty) {
-// CrowInterface.IsDirty = false;
-// update = true;
-// using (Cairo.Context ctx = new Cairo.Context (cairoSurf)) {
-// using (Cairo.Surface d = new Cairo.ImageSurface (CrowInterface.dirtyBmp, Cairo.Format.Argb32,
-// width, height, width * 4)) {
-// ctx.SetSourceSurface (d, 0, 0);
-// ctx.Operator = Cairo.Operator.Source;
-// ctx.Paint ();
-// }
-// }
-// }
-// Monitor.Exit (CrowInterface.RenderMutex);
-// }
-//
-// if (!update)
-// continue;
-// update = false;
-//
-// cairoSurf.Flush ();
-// cairoSurf.SwapBuffers ();
-//
-// if (Gbm.HasFreeBuffers (gbm_surface) == 0)
-// throw new Exception ("[GBM]: Out of free buffers.");
-//
-// next_bo = Gbm.LockFrontBuffer (gbm_surface);
-// if (next_bo == BufferObject.Zero)
-// throw new Exception ("[GBM]: Failed to lock front buffer.");
-//
-// fb = getFbFromBo (next_bo);
-//
-// unsafe{
-// int is_flip_queued = 1;
-//
-// while (Drm.ModePageFlip (fd_gpu, pEncoder->crtc_id, fb, PageFlipFlags.FlipEvent, ref is_flip_queued) < 0) {
-// //Console.WriteLine ("[DRM] Failed to enqueue framebuffer flip.");
-// continue;
-// }
-//
-// while (is_flip_queued != 0)
-// {
-// fds.revents = 0;
-// if (Libc.poll (ref fds, 1, timeout) < 0)
-// break;
-//
-// if ((fds.revents & (PollFlags.Hup | PollFlags.Error)) != 0)
-// break;
-//
-// if ((fds.revents & PollFlags.In) != 0)
-// Drm.HandleEvent (fd_gpu, ref evctx);
-// else
-// break;
-// Thread.Sleep (1);
-// }
-// if (is_flip_queued != 0)
-// Console.WriteLine ("flip canceled");
-//
-// Gbm.ReleaseBuffer (gbm_surface, bo);
-// //Drm.ModeRmFB(fd_gpu, fb);
-//
-// bo = next_bo;
-// next_bo = BufferObject.Zero;
-//
-// }
-// }
+ gbmSurf.Release (bo);
+ }
+ [StructLayout(LayoutKind.Sequential)]
+ struct drmClip {
+ public ushort x1;
+ public ushort y1;
+ public ushort x2;
+ public ushort y2;
+ }
+ unsafe public void MarkFBDirty(){
+ IntPtr pClip = Marshal.AllocHGlobal (sizeof(drmClip));
+ drmClip dc = new drmClip () { x1 = 0, y1 = 0, x2 = 500, y2 = 500 };
+ Marshal.StructureToPtr (dc, pClip,false);
+ int ret = drmModeDirtyFB (fd_gpu, currentCrtc.CurrentFbId, IntPtr.Zero, 0);
+ if (ret < 0)
+ Console.WriteLine ("set FB dirty failed: {0}", ret);
}
-
#region cursor
GBM.BufferObject boMouseCursor;
drmModeMoveCursor (fd_gpu, currentCrtc.Id, x, y);
}
#endregion
-// void initGbm (){
-// gbm_surface = Gbm.CreateSurface(gbm_device, mode.hdisplay, mode.vdisplay, SurfaceFormat.ARGB8888, SurfaceFlags.Rendering | SurfaceFlags.Scanout);
-// if (gbm_surface == IntPtr.Zero)
-// throw new NotSupportedException("[GBM] Failed to create GBM surface for rendering");
-//
-// unsafe {
-// gbm_bo* bo = Gbm.CreateBO (gbm_device, mode.hdisplay, mode.vdisplay, SurfaceFormat.ARGB8888, SurfaceFlags.Scanout);
-// if (bo == null)
-// Console.WriteLine ("failed to create a BufferObject for screen 0");
-// else {
-// uint fb_id = screens [0].BindBuffer (bo);
-// // if (paint (bo))
-// // Console.WriteLine ("[DRI] bo paint succeed");
-// // ModeDirtyFB (fd_gpu, fb_id, IntPtr.Zero, 0);
-// }
-// // //Gbm.DestroyBuffer (bo);
-// ModeAddFB (fd_gpu, bo->Width, bo->Height,(byte)depth, (byte)bpp, bo->Stride, bo->Handle32, out fb_id);
-// bo->SetUserData ((IntPtr)fb_id, IntPtr.Zero);
-//
-// int ret = ModeSetCrtc(fd_gpu, crtc_id, fb_id, x, y, &connector_id, 1, ref mode);
-// }
-// }
+
// unsafe public drmPlane GetPlane (uint id) {
// drmPlane p = new drmPlane();
// drmPlane* pPlane = ModeGetPlane (fd_gpu, id);
CairoSurf = null;
}
+ uint connId = connector.Id;
+ unsafe{
+ int ret = drmModeSetCrtc (fd_gpu, currentCrtc.Id, originalFB, 0, 0, &connId, 1, ref originalMode);
+ if (ret != 0)
+ Console.WriteLine ("restore Crtc failed: {0}", ret);
+ }
+
if (boMouseCursor != null)
boMouseCursor.Dispose ();
boMouseCursor = null;
byte bpp, uint stride, uint bo_handle, out uint buf_id);
[DllImport(lib, CallingConvention = CallingConvention.Cdecl)]
public static extern int drmModeRmFB(int fd, int bufferId);
- [DllImport(lib, EntryPoint = "drmModeDirtyFB", CallingConvention = CallingConvention.Cdecl)]
- public static extern int ModeDirtyFB(int fd, uint bufferId, IntPtr clips, uint num_clips);
-
+ [DllImport(lib, CallingConvention = CallingConvention.Cdecl)]
+ public static extern int drmModeDirtyFB(int fd, uint bufferId, IntPtr clips, uint num_clips);
[DllImport(lib, EntryPoint = "drmModeGetFB", CallingConvention = CallingConvention.Cdecl)]
unsafe internal static extern drmFrameBuffer* ModeGetFB(int fd, uint fb_id);
[DllImport(lib, CallingConvention = CallingConvention.Cdecl)]
unsafe static extern int drmModeSetCrtc(int fd, uint crtcId, uint bufferId, uint x, uint y, uint* connectors, int count, ref ModeInfo mode);
+ [DllImport(lib, EntryPoint = "drmModeSetCrtc", CallingConvention = CallingConvention.Cdecl)]
+ unsafe static extern int ModeSetCrtc(int fd, uint crtcId, uint bufferId, uint x, uint y, uint* connectors, int count, ModeInfo* mode);
+
[DllImport(lib, CallingConvention = CallingConvention.Cdecl)]
internal static extern int drmModeSetCursor2(int fd, uint crtcId, uint bo_handle, uint width, uint height, int hot_x, int hot_y);
#endregion
int fd_gpu;
- drmConnector* handle;
+ internal drmConnector* handle;
#region ctor
public Connector (int _fd_gpu, uint _id)
#endregion
int fd_gpu;
- drmEncoder* handle;
+ internal drmEncoder* handle;
#region ctor
unsafe internal Encoder (int _fd_gpu, uint _id)
{
#region pinvoke
[DllImport("gbm", CallingConvention = CallingConvention.Cdecl)]
- static extern gbm_bo* gbm_bo_create (IntPtr gbm, uint width, uint height, SurfaceFormat format, SurfaceFlags flags);
+ internal static extern gbm_bo* gbm_bo_create (IntPtr gbm, uint width, uint height, SurfaceFormat format, SurfaceFlags flags);
[DllImport("gbm", CallingConvention = CallingConvention.Cdecl)]
internal static extern void gbm_bo_destroy (gbm_bo* bo);
[DllImport("gbm", CallingConvention = CallingConvention.Cdecl)]
<DefineConstants>DEBUG;</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
- <ConsolePause>false</ConsolePause>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<IntermediateOutputPath>$(SolutionDir)build\obj\$(Configuration)</IntermediateOutputPath>
- <OutputPath>$(SolutionDir)build\$(Configuration)</OutputPath>
+ <OutputPath>$(SolutionDir)build\Debug</OutputPath>
+ <Externalconsole>true</Externalconsole>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>full</DebugType>
<ConsolePause>false</ConsolePause>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<IntermediateOutputPath>$(SolutionDir)build\obj\$(Configuration)</IntermediateOutputPath>
- <OutputPath>$(SolutionDir)build\$(Configuration)</OutputPath>
+ <OutputPath>$(SolutionDir)build\Release</OutputPath>
</PropertyGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>
<Compile Include="src\Linux\GBM\Device.cs" />
<Compile Include="src\Application.cs" />
<Compile Include="Main.cs" />
+ <Compile Include="testThreadMonitor.cs" />
</ItemGroup>
<ItemGroup>
<Reference Include="System" />
<ItemGroup>
<EmbeddedResource Include="ui\menu.crow" />
<EmbeddedResource Include="ui\0.crow" />
+ <EmbeddedResource Include="ui\1.crow" />
+ <EmbeddedResource Include="ui\2.crow" />
+ <EmbeddedResource Include="ui\colorItem.crow" />
</ItemGroup>
<ItemGroup>
<None Include="src\DRMContext.cs" />
--- /dev/null
+//
+// Main.cs
+//
+// Author:
+// Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+// Copyright (c) 2013-2017 Jean-Philippe Bruyère
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+using System;
+using System.Diagnostics;
+using System.IO;
+using System.Collections.Generic;
+using System.Threading;
+
+namespace testMonitor
+{
+
+ public class testMonitor
+ {
+ static object _obj = new object();
+ static object mutex1
+ {
+ get
+ {
+ System.Diagnostics.StackFrame frame = new System.Diagnostics.StackFrame(1);
+ System.Diagnostics.Debug.WriteLine(String.Format("Lock acquired by: {0} on thread {1}", frame.GetMethod().Name, System.Threading.Thread.CurrentThread.ManagedThreadId));
+ return _obj;
+ }
+ }
+
+ [STAThread]
+ static void Main ()
+ {
+
+ Thread t1 = new Thread (thread1);
+ t1.Start ();
+ Thread t2 = new Thread (thread2);
+ t2.Start ();
+
+ while (true) {
+ continue;
+ Monitor.Enter (mutex1);
+ //Console.WriteLine ("Main thread entered mutex1 lock");
+ Thread.Sleep (1000);
+// Console.WriteLine ("Main Thread wait state mutex1 lock");
+// Monitor.Wait (Mutex1);
+// Console.WriteLine ("Main Thread wait finished mutex1 lock");
+ Monitor.Exit (mutex1);
+ Thread.Sleep (1);
+ //Console.WriteLine ("Thread 1 state: {0}", t1.ThreadState.ToString ());
+ }
+
+
+ }
+
+ static void thread1(){
+ while (true) {
+ Monitor.Enter (mutex1);
+ Thread.Sleep (1000);
+ Monitor.Exit (mutex1);
+ Thread.Sleep (1);
+ }
+ }
+ static void thread2(){
+ while (true) {
+ Monitor.Enter (mutex1);
+ Thread.Sleep (1000);
+ Monitor.Exit (mutex1);
+ Thread.Sleep (1);
+ }
+ }
+ }
+}
\ No newline at end of file
<DirectoryView Name="dv" CurrentDirectory="/" Margin="1"/>
</Border>
<Splitter/>-->
- <ListBox Name="colorList" Data="{TestList}" Margin="5"
- ItemTemplate="#Tests.Interfaces.colorItem.crow"
- Template="#Crow.Templates.ScrollingListBox.goml"
- />
+<!-- <ListBox Name="colorList" Data="{TestList}" Margin="5"/>-->
+<!-- ItemTemplate="#testDrm.ui.colorItem.crow"
+ Template="#Crow.Templates.ScrollingListBox.goml"-->
</VerticalStack>
</HorizontalStack>
</Window>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0"?>
+<GraphicObject Width="100" Height="100" Background="Teal"/>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0"?>
+<Window Caption="Showcase" Height="90%" Width="90%">
+ <HorizontalStack >
+ <VerticalStack Width="30%" Margin="5">
+ <Label Width="Stretched" Margin="3" Background="Onyx"/>
+ <TextBox Text="TextBox" Multiline="true" Margin="3"/>
+ <HorizontalStack Height="Fit" Margin="5" Background="Onyx" CornerRadius="10">
+ <VerticalStack Spacing="5" Width="50%">
+ <CheckBox Fit="true" Caption="test"/>
+ <CheckBox Fit="true"/>
+ <CheckBox Fit="true"/>
+ <CheckBox Fit="true" IsChecked="true"/>
+ </VerticalStack>
+ <VerticalStack Spacing="5" Width="50%">
+ <RadioButton Fit="true"/>
+ <RadioButton Fit="true" IsChecked="true"/>
+ <RadioButton Fit="true"/>
+ <RadioButton Fit="true"/>
+ </VerticalStack>
+ </HorizontalStack>
+ <HorizontalStack Height="Fit" Margin="5">
+ <Label Text="MouseEvents" Width="50%" Margin="3"
+ Background="Onyx"
+ Foreground="DimGray"
+ TextAlignment="Center"
+ MouseEnter="{Foreground=White}"
+ MouseLeave="{Foreground=DimGray}"
+ MouseDown="{Background=DarkRed}"
+ MouseUp="{Background=Onyx}"/>
+ <Label Text="MouseEvents" Width="50%" Margin="3"
+ Background="Onyx"
+ Foreground="DimGray"
+ TextAlignment="Center"
+ MouseEnter="{Foreground=White}"
+ MouseLeave="{Foreground=DimGray}"
+ MouseDown="{Background=Mantis}"
+ MouseUp="{Background=Onyx}"/>
+ </HorizontalStack>
+ <GroupBox Caption="Templated controls" Height="Fit" Margin="5">
+ <HorizontalStack Height="Fit">
+ <VerticalStack Width="50%">
+ <CheckBox IsChecked="true" Style="CheckBox2"/>
+ <CheckBox Style="CheckBox2"/>
+ <CheckBox Style="CheckBox2"/>
+ <CheckBox Style="CheckBox2"/>
+ </VerticalStack>
+ <Splitter/>
+ <VerticalStack Width="50%">
+ <RadioButton Style="RadioButton2"/>
+ <RadioButton Style="RadioButton2"/>
+ <RadioButton Style="RadioButton2"/>
+ <RadioButton Style="RadioButton2"/>
+ </VerticalStack>
+ </HorizontalStack>
+ </GroupBox>
+ <HorizontalStack Height="Fit">
+ <Label Text="Spinner"/>
+ <Spinner Fit="true"/>
+ </HorizontalStack>
+ <HorizontalStack Height="Fit">
+ <Button Caption="Button"/>
+ <Button Caption="Button" IsEnabled="false"/>
+ </HorizontalStack>
+ </VerticalStack>
+ <Splitter/>
+ <VerticalStack Width="40%" Margin="5" Spacing="5">
+ <Expandable Background="DimGray">
+ <Image Path="#Crow.Images.Icons.crow.svg"/>
+ </Expandable>
+ <Popper Background="DimGray" >
+ <Border Fit="True" Background="DimGray" CornerRadius="0" BorderWidth="1">
+ <Image Path="#Crow.Images.Icons.crow.svg" Width="100" Height="100" Margin="10"
+ MouseEnter="{Background=LightGray}"
+ MouseLeave="{Background=Transparent}"/>
+ </Border>
+ </Popper>
+ <Slider Height="10" Width="90%"/>
+ <Container Height="Fit" Width="200" Background="Onyx" Margin="2" CornerRadius="5">
+ <ProgressBar Background="DimGray" Height="10" Value="50"/>
+ </Container>
+ <Image Path="#Crow.Images.Icons.crow.svg" Width="60" Height="60" Background="LightGray" />
+ <MessageBox Movable="false"/>
+ <ColorPicker SelectedColor="{²../go.Background}" Name="colorPicker" Background="Onyx" Margin="5" Fit="True" />
+ <GraphicObject Name="go" Width="100" Height="60" Background="{../../colorList.SelectedItem}"/>
+ <Label Text="{../../colorPicker.SelectedRawColor}"/>
+ </VerticalStack>
+ <Splitter/>
+ <VerticalStack Width="30%" Margin="5">
+ <ListBox Name="colorList" Data="{TestList}" Margin="5"
+ ItemTemplate="#testDrm.ui.colorItem.crow"
+ Template="#Crow.Templates.ScrollingListBox.goml"
+ />
+ </VerticalStack>
+ </HorizontalStack>
+</Window>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0"?>
+<Border Foreground="Transparent" Focusable="true" HorizontalAlignment="Left" Height="Fit" Width="200">
+ <HorizontalStack Margin="0"
+ MouseEnter="{Background=hgradient|0:DarkRed|1:Transparent}"
+ MouseLeave="{Background=Transparent}">
+ <GraphicObject Height="12" Width="20" Background="{}" Margin="0" CornerRadius="3"/>
+ <Label Text="{}" Margin="0" Width="Stretched"/>
+ </HorizontalStack>
+</Border>
+
<?xml version="1.0"?>
<Menu>
<MenuItem Caption="File" Width="Fit">
- <MenuItem Caption="New" />
+ <MenuItem Caption="New" MouseClick="onLoadClick"/>
<MenuItem Caption="Open"/>
<MenuItem Caption="Save"/>
<MenuItem Caption="Quit" MouseClick="onQuitClick"/>