The Pedigree Project  0.1
protocol.cc
1 /*
2  * Copyright (c) 2008-2014, Pedigree Developers
3  *
4  * Please see the CONTRIB file in the root of the source tree for a full
5  * list of contributors.
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #include "protocol.h"
21 
23 #include <string.h>
24 
25 using namespace PedigreeIpc;
26 using namespace LibUiProtocol;
27 
28 static IpcEndpoint *g_pWinmanEndpoint = 0;
29 
30 bool LibUiProtocol::sendMessage(void *pMessage, size_t messageLength)
31 {
32  // Grab the endpoint for the window manager.
33  if (!g_pWinmanEndpoint)
34  {
35  g_pWinmanEndpoint = getEndpoint("pedigree-winman");
36  }
37 
38  IpcEndpoint *pEndpoint = g_pWinmanEndpoint;
39  if (!pEndpoint)
40  {
42  return false;
43  }
44 
45  // Create an initial message. This will be used for a handshake if the
46  // actual message is longer than 4 KB in size, and for the actual message if
47  // not.
48  if (messageLength > 0x1000)
49  {
51  return false;
52  }
53  IpcMessage *pIpcMessage = new IpcMessage();
54  if (!pIpcMessage->initialise())
55  {
56  return false;
57  }
58 
59  // Fill the message with the data to transmit. Callers should have the
60  // proper window manager message structures in the buffer already.
61  void *pDest = pIpcMessage->getBuffer();
62  if (!pDest)
63  {
64  delete pIpcMessage;
65  return false;
66  }
67  memcpy(pDest, pMessage, messageLength);
68 
69  // Transmit the message.
70  send(pEndpoint, pIpcMessage, false);
71 
72  return true;
73 }
74 
75 bool LibUiProtocol::recvMessage(
76  IpcEndpoint *pEndpoint, void *pBuffer, size_t maxSize)
77 {
79  if (maxSize > 0x1000)
80  return false;
81 
82  // Grab the endpoint for the window manager.
83  if (!pEndpoint)
84  {
86  return false;
87  }
88 
89  // Block and wait for a message to appear on the endpoint.
90  IpcMessage *pRecv = 0;
91  recv(pEndpoint, &pRecv, false);
92 
93  // Verify.
94  if ((!pRecv) || (!pRecv->getBuffer()))
95  {
96  return false;
97  }
98 
99  // Copy the message across.
101  memcpy(pBuffer, pRecv->getBuffer(), maxSize);
102 
103  // Clean up.
104  delete pRecv;
105 
106  return true;
107 }
108 
109 bool LibUiProtocol::recvMessageAsync(
110  IpcEndpoint *pEndpoint, void *pBuffer, size_t maxSize)
111 {
113  if (maxSize > 0x1000)
114  return false;
115 
116  // Grab the endpoint for the window manager.
117  if (!pEndpoint)
118  {
120  return false;
121  }
122 
123  // Check for a message on the endpoint.
124  IpcMessage *pRecv = 0;
125  recv(pEndpoint, &pRecv, true);
126 
127  // Verify.
128  if ((!pRecv) || (!pRecv->getBuffer()))
129  {
130  return false;
131  }
132 
133  // Copy the message across.
135  memcpy(pBuffer, pRecv->getBuffer(), maxSize);
136 
137  // Clean up.
138  delete pRecv;
139 
140  return true;
141 }
A standard IPC message that is less than 4 KB in size.