9fans.net/go@v0.0.5/draw/drawfcall/msg.go (about) 1 package drawfcall 2 3 import ( 4 "fmt" 5 "image" 6 "io" 7 ) 8 9 const ( 10 _ = iota 11 Rerror 12 Trdmouse 13 Rrdmouse 14 Tmoveto 15 Rmoveto 16 Tcursor 17 Rcursor 18 Tbouncemouse 19 Rbouncemouse 20 Trdkbd 21 Rrdkbd 22 Tlabel 23 Rlabel 24 Tinit 25 Rinit 26 Trdsnarf 27 Rrdsnarf 28 Twrsnarf 29 Rwrsnarf 30 Trddraw 31 Rrddraw 32 Twrdraw 33 Rwrdraw 34 Ttop 35 Rtop 36 Tresize 37 Rresize 38 Tcursor2 39 Rcursor2 40 Tctxt 41 Rctxt 42 Trdkbd4 43 Rrdkbd4 44 Tmax 45 ) 46 47 const MAXMSG = 4 << 20 48 49 type Msg struct { 50 Type uint8 51 Tag uint8 52 Mouse Mouse 53 Resized bool 54 Cursor Cursor 55 Cursor2 Cursor2 56 Arrow bool 57 Rune rune 58 Winsize string 59 Label string 60 Snarf []byte 61 Error string 62 ID string 63 Data []byte 64 Count int 65 Rect image.Rectangle 66 } 67 68 type Mouse struct { 69 image.Point 70 Buttons int 71 Msec uint32 72 } 73 74 type Cursor struct { 75 image.Point 76 White [32]byte 77 Black [32]byte 78 } 79 80 type Cursor2 struct { 81 image.Point 82 White [128]byte 83 Black [128]byte 84 } 85 86 func stringsize(s string) int { 87 return 4 + len(s) 88 } 89 90 func bytesize(b []byte) int { 91 return 4 + len(b) 92 } 93 94 func (m *Msg) Size() int { 95 switch m.Type { 96 case Trdmouse, 97 Rbouncemouse, 98 Rmoveto, 99 Rcursor, 100 Rcursor2, 101 Trdkbd, 102 Trdkbd4, 103 Rlabel, 104 Rctxt, 105 Rinit, 106 Trdsnarf, 107 Rwrsnarf, 108 Ttop, 109 Rtop, 110 Rresize: 111 return 4 + 1 + 1 112 case Rrdmouse: 113 return 4 + 1 + 1 + 4 + 4 + 4 + 4 + 1 114 case Tbouncemouse: 115 return 4 + 1 + 1 + 4 + 4 + 4 116 case Tmoveto: 117 return 4 + 1 + 1 + 4 + 4 118 case Tcursor: 119 return 4 + 1 + 1 + 4 + 4 + 2*16 + 2*16 + 1 120 case Tcursor2: 121 return 4 + 1 + 1 + 4 + 4 + 2*16 + 2*16 + 4 + 4 + 4*32 + 4*32 + 1 122 case Rerror: 123 return 4 + 1 + 1 + stringsize(m.Error) 124 case Rrdkbd: 125 return 4 + 1 + 1 + 2 126 case Rrdkbd4: 127 return 4 + 1 + 1 + 4 128 case Tlabel: 129 return 4 + 1 + 1 + stringsize(m.Label) 130 case Tctxt: 131 return 4 + 1 + 1 + stringsize(m.ID) 132 case Tinit: 133 return 4 + 1 + 1 + stringsize(m.Winsize) + stringsize(m.Label) 134 case Rrdsnarf, 135 Twrsnarf: 136 return 4 + 1 + 1 + bytesize(m.Snarf) 137 case Rrddraw, 138 Twrdraw: 139 return 4 + 1 + 1 + bytesize(m.Data) 140 case Trddraw, 141 Rwrdraw: 142 return 4 + 1 + 1 + 4 143 case Tresize: 144 return 4 + 1 + 1 + 4*4 145 } 146 return 0 147 } 148 149 func (m *Msg) Marshal() []byte { 150 n := m.Size() 151 if n < 6 { 152 return nil 153 } 154 b := make([]byte, 0, n) 155 b = pbit32(b, n) 156 b = pbit8(b, m.Tag) 157 b = pbit8(b, m.Type) 158 159 switch m.Type { 160 case Rerror: 161 b = pstring(b, m.Error) 162 case Rrdmouse: 163 b = pbit32(b, m.Mouse.X) 164 b = pbit32(b, m.Mouse.Y) 165 b = pbit32(b, m.Mouse.Buttons) 166 b = pbit32(b, int(m.Mouse.Msec)) 167 b = append(b, boolbyte(m.Resized)) 168 b[19], b[22] = b[22], b[19] 169 case Tbouncemouse: 170 b = pbit32(b, m.Mouse.X) 171 b = pbit32(b, m.Mouse.Y) 172 b = pbit32(b, m.Mouse.Buttons) 173 case Tmoveto: 174 b = pbit32(b, m.Mouse.X) 175 b = pbit32(b, m.Mouse.Y) 176 case Tcursor: 177 b = pbit32(b, m.Cursor.X) 178 b = pbit32(b, m.Cursor.Y) 179 b = append(b, m.Cursor.White[:]...) 180 b = append(b, m.Cursor.Black[:]...) 181 b = append(b, boolbyte(m.Arrow)) 182 case Tcursor2: 183 b = pbit32(b, m.Cursor.X) 184 b = pbit32(b, m.Cursor.Y) 185 b = append(b, m.Cursor.White[:]...) 186 b = append(b, m.Cursor.Black[:]...) 187 b = pbit32(b, m.Cursor2.X) 188 b = pbit32(b, m.Cursor2.Y) 189 b = append(b, m.Cursor2.White[:]...) 190 b = append(b, m.Cursor2.Black[:]...) 191 b = append(b, boolbyte(m.Arrow)) 192 case Rrdkbd: 193 b = pbit16(b, uint16(m.Rune)) 194 case Rrdkbd4: 195 b = pbit32(b, int(m.Rune)) 196 case Tlabel: 197 b = pstring(b, m.Label) 198 case Tctxt: 199 b = pstring(b, m.ID) 200 case Tinit: 201 b = pstring(b, m.Winsize) 202 b = pstring(b, m.Label) 203 case Rrdsnarf, Twrsnarf: 204 b = pbytes(b, m.Snarf) 205 case Rrddraw, Twrdraw: 206 b = pbit32(b, len(m.Data)) 207 b = append(b, m.Data...) 208 case Trddraw, Rwrdraw: 209 b = pbit32(b, m.Count) 210 case Tresize: 211 b = pbit32(b, m.Rect.Min.X) 212 b = pbit32(b, m.Rect.Min.Y) 213 b = pbit32(b, m.Rect.Max.X) 214 b = pbit32(b, m.Rect.Max.Y) 215 } 216 if len(b) != n { 217 println(len(b), n, m.String()) 218 panic("size mismatch") 219 } 220 return b 221 } 222 223 func boolbyte(b bool) byte { 224 if b { 225 return 1 226 } 227 return 0 228 } 229 230 func ReadMsg(r io.Reader) ([]byte, error) { 231 size := make([]byte, 4) 232 _, err := io.ReadFull(r, size) 233 if err != nil { 234 return nil, err 235 } 236 n, _ := gbit32(size[:]) 237 buf := make([]byte, n) 238 copy(buf, size) 239 _, err = io.ReadFull(r, buf[4:]) 240 if err != nil { 241 if err == io.EOF { 242 err = io.ErrUnexpectedEOF 243 } 244 return nil, err 245 } 246 return buf, nil 247 } 248 249 func (m *Msg) Unmarshal(b []byte) error { 250 if len(b) < 6 { 251 return fmt.Errorf("short packet") 252 } 253 254 nn, b := gbit32(b) 255 if nn != 4+len(b) { 256 return fmt.Errorf("invalid size") 257 } 258 259 m.Tag, b = gbit8(b) 260 m.Type, b = gbit8(b) 261 switch m.Type { 262 default: 263 return fmt.Errorf("invalid type %d", int(m.Type)) 264 case Trdmouse, 265 Rbouncemouse, 266 Rmoveto, 267 Rcursor, 268 Rcursor2, 269 Trdkbd, 270 Trdkbd4, 271 Rlabel, 272 Rctxt, 273 Rinit, 274 Trdsnarf, 275 Rwrsnarf, 276 Ttop, 277 Rtop, 278 Rresize: 279 // nothing 280 case Rerror: 281 m.Error, b = gstring(b) 282 case Rrdmouse: 283 m.Mouse.X, b = gbit32(b) 284 m.Mouse.Y, b = gbit32(b) 285 m.Mouse.Buttons, b = gbit32(b) 286 b[1], b[4] = b[4], b[1] 287 var msec int 288 msec, b = gbit32(b) 289 m.Mouse.Msec = uint32(msec) 290 m.Resized = b[0] != 0 291 b = b[1:] 292 case Tbouncemouse: 293 m.Mouse.X, b = gbit32(b) 294 m.Mouse.Y, b = gbit32(b) 295 m.Mouse.Buttons, b = gbit32(b) 296 case Tmoveto: 297 m.Mouse.X, b = gbit32(b) 298 m.Mouse.Y, b = gbit32(b) 299 case Tcursor: 300 m.Cursor.X, b = gbit32(b) 301 m.Cursor.Y, b = gbit32(b) 302 copy(m.Cursor.White[:], b[:]) 303 copy(m.Cursor.Black[:], b[32:]) 304 b = b[64:] 305 var n byte 306 n, b = gbit8(b) 307 m.Arrow = n != 0 308 case Tcursor2: 309 m.Cursor.X, b = gbit32(b) 310 m.Cursor.Y, b = gbit32(b) 311 copy(m.Cursor.White[:], b[:]) 312 copy(m.Cursor.Black[:], b[32:]) 313 b = b[64:] 314 m.Cursor2.X, b = gbit32(b) 315 m.Cursor2.Y, b = gbit32(b) 316 copy(m.Cursor2.White[:], b[:]) 317 copy(m.Cursor2.Black[:], b[128:]) 318 b = b[256:] 319 var n byte 320 n, b = gbit8(b) 321 m.Arrow = n != 0 322 case Rrdkbd: 323 var r uint16 324 r, b = gbit16(b) 325 m.Rune = rune(r) 326 case Rrdkbd4: 327 var r int 328 r, b = gbit32(b) 329 m.Rune = rune(r) 330 case Tlabel: 331 m.Label, b = gstring(b) 332 case Tctxt: 333 m.ID, b = gstring(b) 334 case Tinit: 335 m.Winsize, b = gstring(b) 336 m.Label, b = gstring(b) 337 case Rrdsnarf, 338 Twrsnarf: 339 m.Snarf, b = gbytes(b) 340 case Rrddraw, 341 Twrdraw: 342 var n int 343 n, b = gbit32(b) 344 m.Data = b[:n] 345 b = b[n:] 346 case Trddraw, 347 Rwrdraw: 348 m.Count, b = gbit32(b) 349 case Tresize: 350 m.Rect.Min.X, b = gbit32(b) 351 m.Rect.Min.Y, b = gbit32(b) 352 m.Rect.Max.X, b = gbit32(b) 353 m.Rect.Max.Y, b = gbit32(b) 354 } 355 356 if len(b) != 0 { 357 return fmt.Errorf("junk at end of packet %d %s", len(b), m) 358 } 359 return nil 360 } 361 362 func (m *Msg) String() string { 363 s := fmt.Sprintf("tag=%d ", m.Tag) 364 switch m.Type { 365 default: 366 s += fmt.Sprintf("unknown msg type=%d", m.Type) 367 case Rerror: 368 s += fmt.Sprintf("Rerror error='%s'", m.Error) 369 case Trdmouse: 370 s += fmt.Sprintf("Trdmouse") 371 case Rrdmouse: 372 s += fmt.Sprintf("Rrdmouse x=%d y=%d buttons=%d msec=%d resized=%v", 373 m.Mouse.X, m.Mouse.Y, 374 m.Mouse.Buttons, m.Mouse.Msec, m.Resized) 375 case Tbouncemouse: 376 s += fmt.Sprintf("Tbouncemouse x=%d y=%d buttons=%d", 377 m.Mouse.X, m.Mouse.Y, m.Mouse.Buttons) 378 case Rbouncemouse: 379 s += fmt.Sprintf("Rbouncemouse") 380 case Tmoveto: 381 s += fmt.Sprintf("Tmoveto x=%d y=%d", m.Mouse.X, m.Mouse.Y) 382 case Rmoveto: 383 s += fmt.Sprintf("Rmoveto") 384 case Tcursor: 385 s += fmt.Sprintf("Tcursor arrow=%v", m.Arrow) 386 case Rcursor: 387 s += fmt.Sprintf("Rcursor") 388 case Tcursor2: 389 s += fmt.Sprintf("Tcursor2 arrow=%v", m.Arrow) 390 case Rcursor2: 391 s += fmt.Sprintf("Rcursor2") 392 case Trdkbd: 393 s += fmt.Sprintf("Trdkbd") 394 case Rrdkbd: 395 s += fmt.Sprintf("Rrdkbd rune=%c", m.Rune) 396 case Trdkbd4: 397 s += fmt.Sprintf("Trdkbd4") 398 case Rrdkbd4: 399 s += fmt.Sprintf("Rrdkbd4 rune=%c", m.Rune) 400 case Tlabel: 401 s += fmt.Sprintf("Tlabel label='%s'", m.Label) 402 case Rlabel: 403 s += fmt.Sprintf("Rlabel") 404 case Tctxt: 405 s += fmt.Sprintf("Tctxt id='%s'", m.ID) 406 case Rctxt: 407 s += fmt.Sprintf("Rctxt") 408 case Tinit: 409 s += fmt.Sprintf("Tinit label='%s' winsize='%s'", m.Label, m.Winsize) 410 case Rinit: 411 s += fmt.Sprintf("Rinit") 412 case Trdsnarf: 413 s += fmt.Sprintf("Trdsnarf") 414 case Rrdsnarf: 415 s += fmt.Sprintf("Rrdsnarf snarf='%s'", m.Snarf) 416 case Twrsnarf: 417 s += fmt.Sprintf("Twrsnarf snarf='%s'", m.Snarf) 418 case Rwrsnarf: 419 s += fmt.Sprintf("Rwrsnarf") 420 case Trddraw: 421 s += fmt.Sprintf("Trddraw %d", m.Count) 422 case Rrddraw: 423 s += fmt.Sprintf("Rrddraw %d %x", len(m.Data), m.Data) 424 case Twrdraw: 425 s += fmt.Sprintf("Twrdraw %d %x", len(m.Data), m.Data) 426 case Rwrdraw: 427 s += fmt.Sprintf("Rwrdraw %d", m.Count) 428 case Ttop: 429 s += fmt.Sprintf("Ttop") 430 case Rtop: 431 s += fmt.Sprintf("Rtop") 432 case Tresize: 433 s += fmt.Sprintf("Tresize %v", m.Rect) 434 case Rresize: 435 s += fmt.Sprintf("Rresize") 436 } 437 return s 438 }