Beispiel #1
0
        /// <summary>
        /// Process a remote method invocation request from one display to another hosted on another surface.
        /// </summary>
        /// <param name="pDisplay">The display which called this api function.</param>
        /// <param name="pSurface">The surface which this display is hosted on.</param>
        /// <param name="sTargetSurface">The target surface which contains the display we want to call the function on.</param>
        /// <param name="sRemoteFunction">The name of the function on the active display on the target surface we want to call.</param>
        /// <param name="lArguments">A list of arguments to pass to that function.</param>
        /// <returns></returns>
        public static bool ProcessRMICall(Display pDisplay, Surface pSurface, String sTargetSurface, String sRemoteFunction, Awesomium.Core.JSValue[] lArguments)
        {
            // Check the display and surface are valid.
            if (pDisplay == null) throw new ArgumentNullException("Cannot process a display API request without a display.");
            if (pSurface == null) throw new ArgumentNullException("Cannot process a display API request without a surface.");

            // Check we have a valid request handler.
            if (sTargetSurface == null || sTargetSurface.Length == 0)
            {
                Log.Write("Cannot process a cross-surface RMI call without a target surface name.", pDisplay.ToString(), Log.Type.DisplayWarning);
                return false;
            }

            // Check for a valid remote function.
            if (sRemoteFunction == null || sRemoteFunction.Length == 0)
            {
                Log.Write("Cannot process a cross-surface RMI call without a target function name.", pDisplay.ToString(), Log.Type.DisplayWarning);
                return false;
            }

            // Attempt to find the target surface.
            var pTargetSurface = Authority.FindSurface(sTargetSurface);
            if (pTargetSurface == null)
            {
                Log.Write("Surface '"+sTargetSurface+"' not found.  Cannot process a cross-surface RMI call without a valid target surface.", pDisplay.ToString(), Log.Type.DisplayWarning);
                return false;
            }

            // Check there is a display on the surface.
            if (pTargetSurface.ActiveDisplay != null)
            {
                // Insert the calling surface name into the first argument.
                var l = new List<Awesomium.Core.JSValue>(lArguments);
                l.Insert(0, pSurface.Identifier);

                // Call the function on it and pass the data.
                pTargetSurface.ActiveDisplay.AsyncCallGlobalFunction(sRemoteFunction, l.ToArray());
                return true;
            }

            // Otherwise we didn't do it.
            Log.Write("Could not process a cross-surface RMI call because the target surface did not have an active display.", pDisplay.ToString(), Log.Type.DisplayWarning);
            return false;
        }
Beispiel #2
0
        /// <summary>
        /// Delete a display.
        /// </summary>
        /// <param name="pDisplay">The display we want to delete.</param>
        public static void DeleteDisplay(Display pDisplay)
        {
            // Check we have good data.
            if (pDisplay == null) throw new ArgumentNullException("Cannot delete a null display.");
            if (pDisplay.IsDeleted()) throw new ArgumentNullException("Cannot delete a deleted display.");

            // Remove it from its surface, if attached.
            var pSurface = pDisplay.ActiveSurface;
            if (pSurface != null)
            {
                pSurface.Authority_DetachDisplay(pDisplay);
            }

            // Release any resources created for it.
            pDisplay.Authority_Delete();

            // Remove it from the list of displays.
            Authority._ActiveDisplays.Remove(pDisplay);

            // Log the happening.  That is a weird film btw.
            Log.Write("Display '"+pDisplay.ToString()+"' deleted.", AUTHORITY_LOG_SOURCE, Log.Type.DisplayInfo);
        }
Beispiel #3
0
        /// <summary>
        /// Process a display request.  For example the calling JS would look like: Authority.request(handlername, somedata).
        /// </summary>
        /// <param name="pDisplay">The display which called this api function.</param>
        /// <param name="pSurface">The surface which this display is hosted on.</param>
        /// <param name="sRequestHandler">The name of the request handler.</param>
        /// <param name="dArguments">The table of arguments which were given in the data parameter.</param>
        /// <returns>True if the request was sucessfully handled.  False if not.</returns>
        public static bool ProcessRequest(Display pDisplay, Surface pSurface, String sRequestHandler, Awesomium.Core.JSObject dArguments)
        {
            // Check the display and surface are valid.
            if (pDisplay == null) throw new ArgumentNullException("Cannot process a display API request without a display.");
            if (pSurface == null) throw new ArgumentNullException("Cannot process a display API request without a surface.");

            // Check we have a valid request handler.
            if (sRequestHandler == null || sRequestHandler.Length == 0)
            {
                Log.Write("Cannot process a display API request without a handler name.", pDisplay.ToString(), Log.Type.DisplayWarning);
                return false;
            }

            // Make the request handler lower case.
            sRequestHandler = sRequestHandler.ToLower();

            // Search the bound request handlers.
            DisplayAPI.IRequest pHandler = null;
            if (dRequestHandlers.TryGetValue(sRequestHandler, out pHandler))
            {
                // If one is found, process the request and return the success condition.
                return pHandler.ProcessRequest(pDisplay, pSurface, dArguments);
            }

            // No handler for request.
            Log.Write("Authority could not find handler for request '" + sRequestHandler + "'.", pDisplay.ToString(), Log.Type.DisplayWarning);
            return false;
        }
Beispiel #4
0
        /// <summary>
        /// Remove a display from its current surface. Use with care.
        /// </summary>
        /// <remarks>N.B You must call 'pDisplay.Delete()' when you are finished with it if you don't put it back on a surface.</remarks>
        /// <param name="pDisplay">The display we want to remove from its surface.</param>
        public static void RemoveDisplay(Display pDisplay)
        {
            // Check we have good data.
            if (pDisplay == null) throw new ArgumentNullException("Cannot remove a null display.");
            if (pDisplay.IsDeleted()) throw new ArgumentNullException("Cannot remove a deleted display.");

            // Remove the view from the current surface.
            var pOldSurface = pDisplay.ActiveSurface;
            if (pOldSurface != null)
                pDisplay.ActiveSurface.Authority_DetachDisplay(pDisplay);

            // Remove it from the list of displays.
            Authority._ActiveDisplays.Remove(pDisplay);

            // Write a log message.
            Log.Write("Display '"+pDisplay.ToString()+"' removed.", AUTHORITY_LOG_SOURCE, Log.Type.DisplayInfo);
        }
Beispiel #5
0
        /// <summary>
        /// Move a display from one surface to another.
        /// </summary>
        /// <param name="pDisplay">The display we want to move.</param>
        /// <param name="pNewSurface">The surface we want to move it too.</param>
        public static void MoveDisplay(Display pDisplay, Surface pNewSurface)
        {
            // Check we have good data.
            if (pDisplay == null) throw new ArgumentNullException("Cannot move a null display.");
            if (pNewSurface == null) throw new ArgumentNullException("Cannot move display to a null surface.");
            if (pDisplay.IsDeleted()) throw new ArgumentNullException("Cannot move a deleted display.");
            if (pNewSurface.IsDeleted()) throw new ArgumentNullException("Cannot move display to a deleted surface.");

            // Drop if the new and old are the same.
            if (pDisplay.ActiveSurface == pNewSurface)
                return;
            
            // Check we can move to the new surface.
            if (pNewSurface.ActiveDisplay != null)
                throw new Exception("Cannot move a display to the new surface because it is currently occupied.");

            // Remove the view from the current surface.
            var pOldSurface = pDisplay.ActiveSurface;
            if (pOldSurface != null)
                pDisplay.ActiveSurface.Authority_DetachDisplay(pDisplay);

            // Attach it to the new one.
            pNewSurface.Authority_AttachDisplay(pDisplay);

            // Write a log message.
            Log.Write("Display moved from '" + pOldSurface.ToString()+ "' to '"+pNewSurface.ToString()+"'.", AUTHORITY_LOG_SOURCE, Log.Type.DisplayInfo);
        }
Beispiel #6
0
        /// <summary>
        /// Show a display on a given surface.
        /// </summary>
        /// <remarks>This will throw exceptions if this is not possible.  Ensure neither the display is already open or the surface is occupied.</remarks>
        /// <param name="pDisplay">The display to show.</param>
        /// <param name="pSurface">The surface to show it on.</param>
        public static void ShowDisplay(Display pDisplay, Surface pSurface)
        {
            // Check we have good data.
            if (pDisplay == null) throw new ArgumentNullException("Cannot show null display.");
            if (pSurface == null) throw new ArgumentNullException("Cannot show display on a null surface.");
            if (pDisplay.IsDeleted()) throw new ArgumentNullException("Cannot show a deleted display.");
            if (pSurface.IsDeleted()) throw new ArgumentNullException("Cannot show display on a deleted surface.");

            // Check neither the display or surface are occupied.
            if (pDisplay.ActiveSurface != null) throw new Exception("Cannot show this display because it is already active somewhere else.");
            if (pSurface.ActiveDisplay != null) throw new Exception("Cannot show a display on this surface because it is currently occupied.");

            // Attach it to the surface.
            pSurface.Authority_AttachDisplay(pDisplay);
            Authority._ActiveDisplays.Add(pDisplay);

            // Write a log message.
            Log.Write("Attached display '"+pDisplay.ToString()+"' to surface '"+pSurface.Identifier+"'", AUTHORITY_LOG_SOURCE, Log.Type.DisplayInfo);
        }
        /// <summary>
        /// Attempt to load calibration data from a file.
        /// </summary>
        /// <param name="bCalibration">Do we want to load hardware and calibration settings.</param>
        /// <param name="bSurfaces">Do we want to load surface data.</param>
        /// <param name="bDisplays">Do we want to load displays.</param>
        /// <param name="sFile">The file we want to load the data from.</param>
        private void Load(bool bCalibration, bool bSurfaces, bool bDisplays, String sFile)
        {
            // Open the XML file and parse out the data we are interested in.
            var pDocument = XDocument.Load(sFile);

            #region Load Calibration Data
            if (bCalibration)
            {
                // Parse the surfaces from the file.
                var dCalibration = (from item in pDocument.Root.Elements("calibration")
                                    select new
                                    {
                                        MonitorDevice = item.Element("monitor").Value,
                                        KinectDevice = item.Element("kinect").Value,

                                        KinectImage = (from pt in item.Element("kinectimage").Elements("point") select PointFromString(pt.Value)).ToArray(),
                                        ProjectedImage = (from pt in item.Element("projectedimage").Elements("point") select PointFromString(pt.Value)).ToArray(),
                                    }).FirstOrDefault();

                // Check we have calibration data.
                if (dCalibration != null)
                {
                    #region Load Screen
                    // If we already have a monitor selected.
                    if (SelectedScreen != null)
                    {
                        // If the device names are the same, all is well.
                        if (SelectedScreen.DeviceName != dCalibration.MonitorDevice)
                        {
                            // We have one selected already, log and bail.
                            Log.Write("Screen already selected.  Ignoring '" + dCalibration.MonitorDevice + "'.", "Application", Log.Type.AppWarning);
                        }

                        // See if we can complete step 1.
                        TryCompleteStep1(false);
                    }

                    // If we don't have a montior selected.
                    else
                    {
                        // Attempt to find a montor with a matching device name.
                        var lAvailable = Utilities.MonitorDetection.QueryDisplays();
                        foreach (var pMonitor in lAvailable)
                        {
                            if (pMonitor.DeviceName == dCalibration.MonitorDevice)
                            {
                                SelectedScreen = pMonitor;
                                TryCompleteStep1(false);
                                break;
                            }
                        }

                        // If we didn't manage to select a screen, make a note in the log.
                        if (SelectedScreen == null)
                        {
                            Log.Write("Could not find screen that matches the one in the file. You will need to choose another one.", "Application", Log.Type.AppWarning);
                        }
                    }
                    #endregion

                    #region Load Kinect
                    // If we already have a kinect selected.
                    if (SelectedKinect != null)
                    {
                        // If the device names are the same, all is well.
                        if (SelectedKinect.DeviceConnectionId != dCalibration.KinectDevice)
                        {
                            // We have one selected already, log and bail.
                            Log.Write("Kinect already selected.  Ignoring '" + dCalibration.KinectDevice + "'.", "Application", Log.Type.AppWarning);
                        }

                        // See if we can complete step 1.
                        TryCompleteStep1(false);
                    }

                    // If we don't have a kinect selected.
                    else
                    {
                        // Attempt to find a montor with a matching device name.
                        var lAvailable = KinectSensor.KinectSensors;
                        foreach (var pKinect in lAvailable)
                        {
                            if (pKinect.DeviceConnectionId == dCalibration.KinectDevice)
                            {
                                SelectedKinect = pKinect;
                                TryCompleteStep1(false);
                                break;
                            }
                        }

                        // If we didn't manage to select a screen, make a note in the log.
                        if (SelectedKinect == null)
                        {
                            Log.Write("Could not find kinect that matches the one in the file. You will need to choose another one.", "Application", Log.Type.AppWarning);
                        }
                    }
                    #endregion

                    #region Load Calibration Settings
                    // If we are NOT calibrated but are ready to be used.
                    if (bCalibrated == false && SelectedKinect != null && SelectedScreen != null)
                    {
                        Calibrate(dCalibration.ProjectedImage, dCalibration.KinectImage);
                    }

                    // If we ARE calibrated and are ready to be used.
                    else if (bCalibrated == true && SelectedKinect != null && SelectedScreen != null)
                    {
                        // Do we want to overwrite the existing calibration.
                        var hResult = MessageBox.Show("Do you want to overwrite current calibration with imported one?", "Ubi Displays", MessageBoxButton.YesNo, MessageBoxImage.Question);
                        if (hResult == MessageBoxResult.Yes)
                        {
                            Calibrate(dCalibration.ProjectedImage, dCalibration.KinectImage);
                        }
                    }

                    // Otherwise we are not ready!
                    else
                    {
                        Log.Write("Cannot import calibration because hardware is not selected.", "Application", Log.Type.AppWarning);
                    }
                    #endregion
                }
            }
            #endregion

            // Only import these if we are calibrated.
            if (!bCalibrated && (bSurfaces || bDisplays))
            {
                Log.Write("Cannot import surfaces and displays.  Please calibrate and try again.", "Application", Log.Type.AppWarning);
                return;
            }

            #region Load Surfaces
            if (bSurfaces)
            {
                // Parse the surfaces from the file.
                var lSurfaces = from item in pDocument.Root.Elements("surface")
                                select new
                                {
                                    Identifier = item.Element("name").Value,
                                    InjectMT = (item.Element("inject_multitouch").Value.ToLower() == "true") ? true : false,

                                    Projector = (from pt in item.Element("projector").Elements("point") select PointFromString(pt.Value)).ToArray(),
                                    Sensor = (from pt in item.Element("sensorspace").Elements("point") select Vector3FromString(pt.Value)).ToArray(),
                                    KinectImage = (from pt in item.Element("image").Elements("point") select PointFromString(pt.Value)).ToArray(),
                                };

                // For each surface, register one with the authority.
                foreach (var dSurfaceData in lSurfaces)
                {
                    // Check the surface name is good.
                    if (dSurfaceData.Identifier == null || dSurfaceData.Identifier == "")
                    {
                        Log.Write("Cannot import surface.  Surface is missing a name.", "Application", Log.Type.AppWarning);
                        continue;
                    }

                    // If the name is already taken, bail.
                    if (Authority.FindSurface(dSurfaceData.Identifier) != null)
                    {
                        Log.Write("Cannot import surface '" + dSurfaceData.Identifier + "'.  Surface with the same name already exists.", "Application", Log.Type.AppWarning);
                        continue;
                    }

                    // Check we have valid data.
                    if ((dSurfaceData.Projector == null || dSurfaceData.Projector.Length != 4) ||
                        (dSurfaceData.Sensor == null || dSurfaceData.Sensor.Length != 4) ||
                        (dSurfaceData.KinectImage == null || dSurfaceData.KinectImage.Length != 4))
                    {
                        Log.Write("Cannot import surface '" + dSurfaceData.Identifier + "'.  It does not contain valid data.", "Application", Log.Type.AppWarning);
                        continue;
                    }

                    // Create the surface.
                    var pSurface = new Model.Surface(dSurfaceData.Identifier);
                    pSurface.AttemptMultiTouchInject = dSurfaceData.InjectMT;
                    pSurface.SetSpatialProperties(dSurfaceData.Projector, dSurfaceData.Sensor, dSurfaceData.KinectImage);
                    Authority.RegisterSurface(pSurface);
                }
            }
            #endregion

            #region Load Displays
            if (bDisplays)
            {
                // For each display in the surface file, attach it to the surface.
                var lDisplays = from item in pDocument.Root.Elements("display")
                                select new
                                {
                                    SurfaceName = item.Element("surfacename").Value,
                                    LoadInstruction = item.Element("loadinstruction").Value,
                                    Resolution = PointFromString(item.Element("resolution").Value),
                                };

                // Create the displays.
                foreach (var dDisplayData in lDisplays)
                {
                    // Find the surface to place it on.
                    var pSurface = Authority.FindSurface(dDisplayData.SurfaceName);
                    if (pSurface == null)
                    {
                        Log.Write("Cannot import display '" + dDisplayData.LoadInstruction + "'.  Could not find host surface '" + dDisplayData.SurfaceName + "'.", "Application", Log.Type.AppWarning);
                        continue;
                    }

                    // Create the display.
                    var pDisplay = new Display(dDisplayData.LoadInstruction, dDisplayData.Resolution);

                    // Disable debug mode on the surface.
                    pSurface.ShowDebug = false;

                    // Show the display.
                    Authority.ShowDisplay(pDisplay, pSurface);
                }
            }
            #endregion
        }
        /// <summary>
        /// Called to handle something being dropped on the image.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void HandleDisplay_Drop(object sender, DragEventArgs e)
        {
            // Not dragging anymore.
            bDraggingFile = false;

            // Bail if not a file.
            var sFile = "http://google.com";

            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                // Select the file to load.
                string[] tFilePaths = (string[])(e.Data.GetData(DataFormats.FileDrop));
                if (tFilePaths.Length != 1)
                    return;
                sFile = tFilePaths[0];
            }
            else if (e.Data.GetDataPresent(DataFormats.StringFormat))
            {
                sFile = e.Data.GetData(DataFormats.StringFormat) as String;
                if (sFile == null || (!sFile.StartsWith("http") && !sFile.StartsWith("file")))
                    return;
            }

            // Find which polygon we have dropped on.
            var pClick = e.GetPosition(_vidManage);

            // Check to see if our point is contained by any of our surfaces.
            UbiDisplays.Model.Surface pSurface = null;
            foreach (var s in Authority.Surfaces)
            {
                List<Point> lPoints = new List<Point>();
                lPoints.Add(new Point(s.KinectSpace[0].X, s.KinectSpace[0].Y));
                lPoints.Add(new Point(s.KinectSpace[1].X, s.KinectSpace[1].Y));
                lPoints.Add(new Point(s.KinectSpace[2].X, s.KinectSpace[2].Y));
                lPoints.Add(new Point(s.KinectSpace[3].X, s.KinectSpace[3].Y));

                // If we have dropped it into this polygon.
                if (Utilities.Polygon.IsPointInPolygon(pClick.X, pClick.Y, lPoints))
                {
                    pSurface = s;
                    break;
                }
            }

            // If we have missed all the surfaces.
            if (pSurface == null)
                return;

            // If there is already something on the surface, remove it.
            if (pSurface.ActiveDisplay != null)
            {
                Authority.DeleteDisplay(pSurface.ActiveDisplay);
            }

            // Create a new display.
            var pDisplay = new Display(sFile);
            Authority.ShowDisplay(pDisplay, pSurface);
            pSurface.ShowDebug = false;

            // Ensure debug mode is turned off.
            // TODO
            //pSurface.DebugMode = false;

            // Remove the polygons.
            foreach (var pPoly in lDragPolygons)
                _pzManage.Children.Remove(pPoly);
            lDragPolygons.Clear();
        }