command.go 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833
  1. // License: GPLv3 Copyright: 2022, Kovid Goyal, <kovid at kovidgoyal.net>
  2. package graphics
  3. import (
  4. "bytes"
  5. "compress/zlib"
  6. "encoding/base64"
  7. "fmt"
  8. "io"
  9. "strconv"
  10. "strings"
  11. "kitty/tools/tty"
  12. "kitty/tools/tui/loop"
  13. "kitty/tools/utils"
  14. )
  15. var _ = fmt.Print
  16. // Enums {{{
  17. type GRT_a int // enum
  18. const (
  19. GRT_action_transmit GRT_a = iota // t
  20. GRT_action_transmit_and_display // T
  21. GRT_action_query // q
  22. GRT_action_display // p
  23. GRT_action_delete // d
  24. GRT_action_frame // f
  25. GRT_action_animate // a
  26. GRT_action_compose // c
  27. )
  28. type GRT_q int // enum
  29. const (
  30. GRT_quiet_noisy GRT_q = iota // 0
  31. GRT_quiet_only_errors // 1
  32. GRT_quiet_silent // 2
  33. )
  34. type GRT_f int // enum
  35. const (
  36. GRT_format_rgba GRT_f = iota // 32
  37. GRT_format_rgb // 24
  38. GRT_format_png // 100
  39. )
  40. type GRT_t int // enum
  41. const (
  42. GRT_transmission_direct GRT_t = iota // d
  43. GRT_transmission_file // f
  44. GRT_transmission_tempfile // t
  45. GRT_transmission_sharedmem // s
  46. )
  47. type GRT_o int // enum
  48. const (
  49. GRT_compression_none GRT_o = iota //
  50. GRT_compression_zlib // z
  51. )
  52. type GRT_m int // enum
  53. const (
  54. GRT_more_nomore GRT_m = iota // 0
  55. GRT_more_more // 1
  56. )
  57. type GRT_C int // enum
  58. const (
  59. GRT_cursor_move GRT_C = iota // 0
  60. GRT_cursor_static // 1
  61. )
  62. type GRT_U int // enum
  63. const (
  64. GRT_no_unicode_placeholder GRT_U = iota // 0
  65. GRT_create_unicode_placeholder // 1
  66. )
  67. type CompositionMode int // enum
  68. const (
  69. AlphaBlend CompositionMode = iota // 0
  70. Overwrite // 1
  71. )
  72. type GRT_d int // enum
  73. const (
  74. GRT_delete_visible GRT_d = iota // a
  75. GRT_free_visible // A
  76. GRT_delete_by_id // i
  77. GRT_free_by_id // I
  78. GRT_delete_by_number // n
  79. GRT_free_by_number // N
  80. GRT_delete_by_cursor // c
  81. GRT_free_by_cursor // C
  82. GRT_delete_by_frame // f
  83. GRT_free_by_frame // F
  84. GRT_delete_by_cell // p
  85. GRT_free_by_cell // P
  86. GRT_delete_by_cell_zindex // q
  87. GRT_free_by_cell_zindex // Q
  88. GRT_delete_by_range // r
  89. GRT_free_by_range // R
  90. GRT_delete_by_column // x
  91. GRT_free_by_column // X
  92. GRT_delete_by_row // y
  93. GRT_free_by_row // Y
  94. GRT_delete_by_zindex // z
  95. GRT_free_by_zindex // Z
  96. )
  97. // }}}
  98. type GraphicsCommand struct {
  99. a GRT_a
  100. q GRT_q
  101. f GRT_f
  102. t GRT_t
  103. o GRT_o
  104. m GRT_m
  105. C GRT_C
  106. d GRT_d
  107. U GRT_U
  108. s, v, S, O, x, y, w, h, X, Y, c, r uint64
  109. i, I, p uint32
  110. z int32
  111. DisableCompression bool
  112. WrapPrefix, WrapSuffix string
  113. EncodeSerializedDataFunc func(string) string
  114. response_message string
  115. }
  116. func (self *GraphicsCommand) serialize_non_default_fields() (ans []string) {
  117. var null GraphicsCommand
  118. ans = make([]string, 0, 16)
  119. write_key := func(k byte, val, defval any) {
  120. if val != defval {
  121. ans = append(ans, fmt.Sprintf("%c=%v", k, val))
  122. }
  123. }
  124. write_key('a', self.a, null.a)
  125. write_key('q', self.q, null.q)
  126. write_key('f', self.f, null.f)
  127. write_key('t', self.t, null.t)
  128. write_key('o', self.o, null.o)
  129. write_key('m', self.m, null.m)
  130. write_key('C', self.C, null.C)
  131. write_key('U', self.U, null.U)
  132. write_key('d', self.d, null.d)
  133. write_key('s', self.s, null.s)
  134. write_key('v', self.v, null.v)
  135. write_key('S', self.S, null.S)
  136. write_key('O', self.O, null.O)
  137. write_key('x', self.x, null.x)
  138. write_key('y', self.y, null.y)
  139. write_key('w', self.w, null.w)
  140. write_key('h', self.h, null.h)
  141. write_key('X', self.X, null.X)
  142. write_key('Y', self.Y, null.Y)
  143. write_key('c', self.c, null.c)
  144. write_key('r', self.r, null.r)
  145. write_key('i', self.i, null.i)
  146. write_key('I', self.I, null.I)
  147. write_key('p', self.p, null.p)
  148. write_key('z', self.z, null.z)
  149. return
  150. }
  151. func (self GraphicsCommand) String() string {
  152. ans := "GraphicsCommand(" + strings.Join(self.serialize_non_default_fields(), ", ")
  153. if self.response_message != "" {
  154. ans += fmt.Sprintf(", response=%#v", self.response_message)
  155. }
  156. return ans + ")"
  157. }
  158. var debugprintln = tty.DebugPrintln
  159. var _ = debugprintln
  160. func (self *GraphicsCommand) serialize_to(buf io.StringWriter, chunk string) (err error) {
  161. var ws func(string)
  162. if self.EncodeSerializedDataFunc == nil {
  163. ws = func(s string) {
  164. _, err = buf.WriteString(s)
  165. }
  166. } else {
  167. ws = func(s string) {
  168. _, err = buf.WriteString(self.EncodeSerializedDataFunc(s))
  169. }
  170. }
  171. if self.WrapPrefix != "" {
  172. _, err = buf.WriteString(self.WrapPrefix)
  173. if err != nil {
  174. return err
  175. }
  176. if self.WrapSuffix != "" {
  177. defer func() {
  178. if err == nil {
  179. _, err = buf.WriteString(self.WrapSuffix)
  180. }
  181. }()
  182. }
  183. }
  184. ws("\033_G")
  185. if err == nil {
  186. items := self.serialize_non_default_fields()
  187. ws(strings.Join(items, ","))
  188. if err == nil {
  189. if len(chunk) > 0 {
  190. ws(";")
  191. if err == nil {
  192. ws(chunk)
  193. }
  194. }
  195. if err == nil {
  196. ws("\033\\")
  197. }
  198. }
  199. }
  200. return
  201. }
  202. func compress_with_zlib(data []byte) []byte {
  203. var b bytes.Buffer
  204. b.Grow(len(data) + 128)
  205. w := zlib.NewWriter(&b)
  206. _, _ = w.Write(data)
  207. w.Close()
  208. return b.Bytes()
  209. }
  210. func (self *GraphicsCommand) AsAPC(payload []byte) string {
  211. buf := strings.Builder{}
  212. buf.Grow(1024)
  213. _ = self.WriteWithPayloadTo(&buf, payload)
  214. return buf.String()
  215. }
  216. func (self *GraphicsCommand) WriteWithPayloadTo(o io.StringWriter, payload []byte) (err error) {
  217. const compression_threshold = 2048
  218. if len(payload) == 0 {
  219. return self.serialize_to(o, "")
  220. }
  221. if len(payload) <= compression_threshold {
  222. return self.serialize_to(o, base64.RawStdEncoding.EncodeToString(payload))
  223. }
  224. gc := *self
  225. if !self.DisableCompression && self.Format() != GRT_format_png {
  226. compressed := compress_with_zlib(payload)
  227. if len(compressed) < len(payload) {
  228. gc.SetCompression(GRT_compression_zlib)
  229. payload = compressed
  230. }
  231. }
  232. const chunk_size = 128 * 1024
  233. data := base64.RawStdEncoding.EncodeToString(payload)
  234. for len(data) > 0 && err == nil {
  235. chunk := data
  236. if len(data) > chunk_size {
  237. chunk = data[:chunk_size]
  238. data = data[chunk_size:]
  239. } else {
  240. data = ""
  241. }
  242. if len(data) > 0 {
  243. gc.m = GRT_more_more
  244. } else {
  245. gc.m = GRT_more_nomore
  246. }
  247. err = gc.serialize_to(o, chunk)
  248. if err != nil {
  249. return err
  250. }
  251. gc = GraphicsCommand{
  252. q: self.q, a: self.a, WrapPrefix: self.WrapPrefix, WrapSuffix: self.WrapSuffix,
  253. EncodeSerializedDataFunc: self.EncodeSerializedDataFunc}
  254. }
  255. return
  256. }
  257. type loop_io_writer struct {
  258. lp *loop.Loop
  259. }
  260. func (self *loop_io_writer) WriteString(data string) (n int, err error) {
  261. self.lp.QueueWriteString(data)
  262. return
  263. }
  264. func (self *GraphicsCommand) WriteWithPayloadToLoop(lp *loop.Loop, payload []byte) (err error) {
  265. w := loop_io_writer{lp}
  266. return self.WriteWithPayloadTo(&w, payload)
  267. }
  268. func set_val[T any](loc *T, parser func(string) (T, error), value string) (err error) {
  269. var temp T
  270. temp, err = parser(value)
  271. if err == nil {
  272. *loc = temp
  273. }
  274. return err
  275. }
  276. func set_uval(loc *uint64, value string) (err error) {
  277. temp, err := strconv.ParseUint(value, 10, 64)
  278. if err == nil {
  279. *loc = temp
  280. }
  281. return err
  282. }
  283. func set_u32val(loc *uint32, value string) (err error) {
  284. temp, err := strconv.ParseUint(value, 10, 32)
  285. if err == nil {
  286. *loc = uint32(temp)
  287. }
  288. return err
  289. }
  290. func set_i32val(loc *int32, value string) (err error) {
  291. temp, err := strconv.ParseInt(value, 10, 32)
  292. if err == nil {
  293. *loc = int32(temp)
  294. }
  295. return err
  296. }
  297. func (self *GraphicsCommand) SetString(key byte, value string) (err error) {
  298. switch key {
  299. case 'a':
  300. err = set_val(&self.a, GRT_a_from_string, value)
  301. case 'q':
  302. err = set_val(&self.q, GRT_q_from_string, value)
  303. case 'f':
  304. err = set_val(&self.f, GRT_f_from_string, value)
  305. case 't':
  306. err = set_val(&self.t, GRT_t_from_string, value)
  307. case 'o':
  308. err = set_val(&self.o, GRT_o_from_string, value)
  309. case 'm':
  310. err = set_val(&self.m, GRT_m_from_string, value)
  311. case 'C':
  312. err = set_val(&self.C, GRT_C_from_string, value)
  313. case 'U':
  314. err = set_val(&self.U, GRT_U_from_string, value)
  315. case 'd':
  316. err = set_val(&self.d, GRT_d_from_string, value)
  317. case 's':
  318. err = set_uval(&self.s, value)
  319. case 'v':
  320. err = set_uval(&self.v, value)
  321. case 'S':
  322. err = set_uval(&self.S, value)
  323. case 'O':
  324. err = set_uval(&self.O, value)
  325. case 'x':
  326. err = set_uval(&self.x, value)
  327. case 'y':
  328. err = set_uval(&self.y, value)
  329. case 'w':
  330. err = set_uval(&self.w, value)
  331. case 'h':
  332. err = set_uval(&self.h, value)
  333. case 'X':
  334. err = set_uval(&self.X, value)
  335. case 'Y':
  336. err = set_uval(&self.Y, value)
  337. case 'c':
  338. err = set_uval(&self.c, value)
  339. case 'r':
  340. err = set_uval(&self.r, value)
  341. case 'i':
  342. err = set_u32val(&self.i, value)
  343. case 'I':
  344. err = set_u32val(&self.I, value)
  345. case 'p':
  346. err = set_u32val(&self.p, value)
  347. case 'z':
  348. err = set_i32val(&self.z, value)
  349. default:
  350. return fmt.Errorf("Unknown key: %c", key)
  351. }
  352. return
  353. }
  354. func GraphicsCommandFromAPCPayload(raw []byte) *GraphicsCommand {
  355. const (
  356. expecting_key int = iota
  357. expecting_equals
  358. expecting_value
  359. )
  360. state := expecting_key
  361. var current_key byte
  362. var value_start_at int
  363. var payload_start_at int = -1
  364. var gc GraphicsCommand
  365. add_key := func(pos int) {
  366. _ = gc.SetString(current_key, utils.UnsafeBytesToString(raw[value_start_at:pos]))
  367. }
  368. for pos, ch := range raw {
  369. if ch == ';' {
  370. if state == expecting_value {
  371. add_key(pos)
  372. }
  373. state = expecting_key
  374. payload_start_at = pos + 1
  375. break
  376. }
  377. switch state {
  378. case expecting_key:
  379. current_key = ch
  380. state = expecting_equals
  381. case expecting_equals:
  382. if ch == '=' {
  383. state = expecting_value
  384. value_start_at = pos + 1
  385. } else {
  386. state = expecting_key
  387. }
  388. case expecting_value:
  389. if ch == ',' {
  390. add_key(pos)
  391. state = expecting_key
  392. }
  393. }
  394. }
  395. if state == expecting_value {
  396. add_key(len(raw))
  397. }
  398. if payload_start_at > -1 {
  399. payload := raw[payload_start_at:]
  400. if len(payload) > 0 {
  401. gc.response_message = string(payload)
  402. }
  403. }
  404. return &gc
  405. }
  406. func GraphicsCommandFromAPC(raw []byte) *GraphicsCommand {
  407. if len(raw) < 1 || raw[0] != 'G' {
  408. return nil
  409. }
  410. return GraphicsCommandFromAPCPayload(raw[1:])
  411. }
  412. // Getters and Setters {{{
  413. func (self *GraphicsCommand) Action() GRT_a {
  414. return self.a
  415. }
  416. func (self *GraphicsCommand) SetAction(a GRT_a) *GraphicsCommand {
  417. self.a = a
  418. return self
  419. }
  420. func (self *GraphicsCommand) Delete() GRT_d {
  421. return self.d
  422. }
  423. func (self *GraphicsCommand) SetDelete(d GRT_d) *GraphicsCommand {
  424. self.d = d
  425. return self
  426. }
  427. func (self *GraphicsCommand) Quiet() GRT_q {
  428. return self.q
  429. }
  430. func (self *GraphicsCommand) SetQuiet(q GRT_q) *GraphicsCommand {
  431. self.q = q
  432. return self
  433. }
  434. func (self *GraphicsCommand) CursorMovement() GRT_C {
  435. return self.C
  436. }
  437. func (self *GraphicsCommand) SetCursorMovement(c GRT_C) *GraphicsCommand {
  438. self.C = c
  439. return self
  440. }
  441. func (self *GraphicsCommand) UnicodePlaceholder() GRT_U {
  442. return self.U
  443. }
  444. func (self *GraphicsCommand) SetUnicodePlaceholder(U GRT_U) *GraphicsCommand {
  445. self.U = U
  446. return self
  447. }
  448. func (self *GraphicsCommand) Format() GRT_f {
  449. return self.f
  450. }
  451. func (self *GraphicsCommand) SetFormat(f GRT_f) *GraphicsCommand {
  452. self.f = f
  453. return self
  454. }
  455. func (self *GraphicsCommand) Transmission() GRT_t {
  456. return self.t
  457. }
  458. func (self *GraphicsCommand) SetTransmission(t GRT_t) *GraphicsCommand {
  459. self.t = t
  460. return self
  461. }
  462. func (self *GraphicsCommand) Compression() GRT_o {
  463. return self.o
  464. }
  465. func (self *GraphicsCommand) SetCompression(o GRT_o) *GraphicsCommand {
  466. self.o = o
  467. return self
  468. }
  469. func (self *GraphicsCommand) Width() uint64 {
  470. return self.w
  471. }
  472. func (self *GraphicsCommand) SetWidth(w uint64) *GraphicsCommand {
  473. self.w = w
  474. return self
  475. }
  476. func (self *GraphicsCommand) Height() uint64 {
  477. return self.h
  478. }
  479. func (self *GraphicsCommand) SetHeight(h uint64) *GraphicsCommand {
  480. self.h = h
  481. return self
  482. }
  483. func (self *GraphicsCommand) DataWidth() uint64 {
  484. return self.s
  485. }
  486. func (self *GraphicsCommand) SetDataWidth(w uint64) *GraphicsCommand {
  487. self.s = w
  488. return self
  489. }
  490. func (self *GraphicsCommand) DataHeight() uint64 {
  491. return self.v
  492. }
  493. func (self *GraphicsCommand) SetDataHeight(h uint64) *GraphicsCommand {
  494. self.v = h
  495. return self
  496. }
  497. func (self *GraphicsCommand) NumberOfLoops() uint64 {
  498. return self.v
  499. }
  500. func (self *GraphicsCommand) SetNumberOfLoops(n uint64) *GraphicsCommand {
  501. self.v = n
  502. return self
  503. }
  504. func (self *GraphicsCommand) DataSize() uint64 {
  505. return self.S
  506. }
  507. func (self *GraphicsCommand) SetDataSize(s uint64) *GraphicsCommand {
  508. self.S = s
  509. return self
  510. }
  511. func (self *GraphicsCommand) DataOffset() uint64 {
  512. return self.O
  513. }
  514. func (self *GraphicsCommand) SetDataOffset(o uint64) *GraphicsCommand {
  515. self.O = o
  516. return self
  517. }
  518. func (self *GraphicsCommand) LeftEdge() uint64 {
  519. return self.x
  520. }
  521. func (self *GraphicsCommand) SetLeftEdge(x uint64) *GraphicsCommand {
  522. self.x = x
  523. return self
  524. }
  525. func (self *GraphicsCommand) TopEdge() uint64 {
  526. return self.y
  527. }
  528. func (self *GraphicsCommand) SetTopEdge(y uint64) *GraphicsCommand {
  529. self.y = y
  530. return self
  531. }
  532. func (self *GraphicsCommand) XOffset() uint64 {
  533. return self.X
  534. }
  535. func (self *GraphicsCommand) SetXOffset(x uint64) *GraphicsCommand {
  536. self.X = x
  537. return self
  538. }
  539. func (self *GraphicsCommand) BlendMode() CompositionMode {
  540. switch self.X {
  541. case 1:
  542. return Overwrite
  543. default:
  544. return AlphaBlend
  545. }
  546. }
  547. func (self *GraphicsCommand) SetBlendMode(x CompositionMode) *GraphicsCommand {
  548. self.X = uint64(x)
  549. return self
  550. }
  551. func (self *GraphicsCommand) CompositionMode() CompositionMode {
  552. switch self.C {
  553. case 1:
  554. return Overwrite
  555. default:
  556. return AlphaBlend
  557. }
  558. }
  559. func (self *GraphicsCommand) SetCompositionMode(x CompositionMode) *GraphicsCommand {
  560. switch x {
  561. case Overwrite:
  562. self.C = 1
  563. case AlphaBlend:
  564. self.C = 0
  565. }
  566. return self
  567. }
  568. func (self *GraphicsCommand) YOffset() uint64 {
  569. return self.Y
  570. }
  571. func (self *GraphicsCommand) SetYOffset(y uint64) *GraphicsCommand {
  572. self.Y = y
  573. return self
  574. }
  575. func (self *GraphicsCommand) SourceTopEdge() uint64 {
  576. return self.Y
  577. }
  578. func (self *GraphicsCommand) SetSourceTopEdge(y uint64) *GraphicsCommand {
  579. self.Y = y
  580. return self
  581. }
  582. func (self *GraphicsCommand) BackgroundColor() uint32 {
  583. return uint32(self.Y)
  584. }
  585. func (self *GraphicsCommand) SetBackgroundColor(y uint32) *GraphicsCommand {
  586. self.Y = uint64(y)
  587. return self
  588. }
  589. func (self *GraphicsCommand) Rows() uint64 {
  590. return self.r
  591. }
  592. func (self *GraphicsCommand) SetRows(r uint64) *GraphicsCommand {
  593. self.r = r
  594. return self
  595. }
  596. func (self *GraphicsCommand) Columns() uint64 {
  597. return self.c
  598. }
  599. func (self *GraphicsCommand) SetColumns(c uint64) *GraphicsCommand {
  600. self.c = c
  601. return self
  602. }
  603. func (self *GraphicsCommand) TargetFrame() uint64 {
  604. return self.r
  605. }
  606. func (self *GraphicsCommand) SetTargetFrame(r uint64) *GraphicsCommand {
  607. self.r = r
  608. return self
  609. }
  610. func (self *GraphicsCommand) BaseFrame() uint64 {
  611. return self.c
  612. }
  613. func (self *GraphicsCommand) SetBaseFrame(c uint64) *GraphicsCommand {
  614. self.c = c
  615. return self
  616. }
  617. func (self *GraphicsCommand) OverlaidFrame() uint64 {
  618. return self.c
  619. }
  620. func (self *GraphicsCommand) SetOverlaidFrame(c uint64) *GraphicsCommand {
  621. self.c = c
  622. return self
  623. }
  624. func (self *GraphicsCommand) FrameToMakeCurrent() uint64 {
  625. return self.c
  626. }
  627. func (self *GraphicsCommand) SetFrameToMakeCurrent(c uint64) *GraphicsCommand {
  628. self.c = c
  629. return self
  630. }
  631. func (self *GraphicsCommand) ImageId() uint32 {
  632. return self.i
  633. }
  634. func (self *GraphicsCommand) SetImageId(i uint32) *GraphicsCommand {
  635. self.i = i
  636. return self
  637. }
  638. func (self *GraphicsCommand) ImageNumber() uint32 {
  639. return self.I
  640. }
  641. func (self *GraphicsCommand) SetImageNumber(n uint32) *GraphicsCommand {
  642. self.I = n
  643. return self
  644. }
  645. func (self *GraphicsCommand) PlacementId() uint32 {
  646. return self.p
  647. }
  648. func (self *GraphicsCommand) SetPlacementId(p uint32) *GraphicsCommand {
  649. self.p = p
  650. return self
  651. }
  652. func (self *GraphicsCommand) ZIndex() int32 {
  653. return self.z
  654. }
  655. func (self *GraphicsCommand) SetZIndex(z int32) *GraphicsCommand {
  656. self.z = z
  657. return self
  658. }
  659. func (self *GraphicsCommand) Gap() int32 {
  660. return self.z
  661. }
  662. func (self *GraphicsCommand) SetGap(z int32) *GraphicsCommand {
  663. self.z = z
  664. return self
  665. }
  666. type AnimationControl uint
  667. const (
  668. NoAnimationAction AnimationControl = iota
  669. StopAnimation
  670. RunAnimationButWaitForNewFrames
  671. RunAnimation
  672. )
  673. func (self *GraphicsCommand) AnimationControl() AnimationControl {
  674. switch AnimationControl(self.s) {
  675. default:
  676. return NoAnimationAction
  677. case StopAnimation:
  678. return StopAnimation
  679. case RunAnimationButWaitForNewFrames:
  680. return RunAnimationButWaitForNewFrames
  681. case RunAnimation:
  682. return RunAnimation
  683. }
  684. }
  685. func (self *GraphicsCommand) SetAnimationControl(z uint) *GraphicsCommand {
  686. self.s = uint64(z)
  687. return self
  688. }
  689. func (self *GraphicsCommand) ResponseMessage() string {
  690. return self.response_message
  691. }
  692. // }}}