GtkUtils.mod 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. IMPLEMENTATION MODULE GtkUtils ;
  2. (*
  3. Implementation notes
  4. --------------------
  5. CStrToM2 uses libc strncpy(): when the source is shorter than the
  6. buffer strncpy() pads with NUL, and we force the last byte to NUL so
  7. the result is always terminated. This avoids pointer walking (gm2
  8. has no pointer arithmetic) and any CAST between integer sizes.
  9. IntToStr works on a LONGINT so that the magnitude of MIN(INTEGER)
  10. is representable, then reverses the digits into the caller buffer.
  11. *)
  12. FROM SYSTEM IMPORT ADDRESS, ADR;
  13. FROM libc IMPORT strncpy;
  14. FROM GObject IMPORT g_signal_connect_data, GConnectDefault, g_object_unref;
  15. FROM GLib IMPORT g_free;
  16. FROM GError IMPORT GError, g_error_free;
  17. FROM GtkApplication IMPORT gtk_application_set_accels_for_action;
  18. PROCEDURE CStrToM2 (src: ADDRESS; VAR dst: ARRAY OF CHAR);
  19. BEGIN
  20. IF src = NIL THEN
  21. dst[0] := 0C;
  22. RETURN
  23. END;
  24. strncpy(ADR(dst), src, HIGH(dst) + 1);
  25. dst[HIGH(dst)] := 0C
  26. END CStrToM2;
  27. PROCEDURE StrAppend (VAR dst: ARRAY OF CHAR; src: ARRAY OF CHAR);
  28. VAR
  29. i, j: CARDINAL;
  30. BEGIN
  31. (* locate the current end of dst *)
  32. i := 0;
  33. WHILE (i <= HIGH(dst)) AND (dst[i] # 0C) DO
  34. INC(i)
  35. END;
  36. (* append src, leaving room for the terminator *)
  37. j := 0;
  38. WHILE (i < HIGH(dst)) AND (j <= HIGH(src)) AND (src[j] # 0C) DO
  39. dst[i] := src[j];
  40. INC(i);
  41. INC(j)
  42. END;
  43. IF i <= HIGH(dst) THEN dst[i] := 0C ELSE dst[HIGH(dst)] := 0C END
  44. END StrAppend;
  45. PROCEDURE IntToStr (n: INTEGER; VAR dst: ARRAY OF CHAR);
  46. VAR
  47. digits: ARRAY [0..31] OF CHAR;
  48. v: INTEGER;
  49. i, j: CARDINAL;
  50. negative: BOOLEAN;
  51. BEGIN
  52. v := n;
  53. negative := v < 0;
  54. IF negative THEN v := -v END;
  55. (* collect digits least-significant first *)
  56. i := 0;
  57. REPEAT
  58. digits[i] := CHR(ORD('0') + CARDINAL(v MOD 10));
  59. v := v DIV 10;
  60. INC(i)
  61. UNTIL v = 0;
  62. IF negative THEN
  63. digits[i] := '-';
  64. INC(i)
  65. END;
  66. (* reverse into dst *)
  67. j := 0;
  68. WHILE (i > 0) AND (j <= HIGH(dst)) DO
  69. DEC(i);
  70. dst[j] := digits[i];
  71. INC(j)
  72. END;
  73. IF j <= HIGH(dst) THEN dst[j] := 0C ELSE dst[HIGH(dst)] := 0C END
  74. END IntToStr;
  75. PROCEDURE Connect (instance: ADDRESS; signal: ARRAY OF CHAR;
  76. handler: ADDRESS; data: ADDRESS) : [ LONGCARD ];
  77. BEGIN
  78. RETURN g_signal_connect_data(instance, signal, handler, data, NIL,
  79. GConnectDefault)
  80. END Connect;
  81. PROCEDURE SetAccel (application: ADDRESS; action: ARRAY OF CHAR;
  82. accel: ARRAY OF CHAR);
  83. VAR
  84. accels: ARRAY [0..1] OF ADDRESS;
  85. BEGIN
  86. accels[0] := ADR(accel);
  87. accels[1] := NIL;
  88. gtk_application_set_accels_for_action(application, action, ADR(accels))
  89. END SetAccel;
  90. PROCEDURE Unref (obj: ADDRESS);
  91. BEGIN
  92. IF obj # NIL THEN g_object_unref(obj) END
  93. END Unref;
  94. PROCEDURE Free (ptr: ADDRESS);
  95. BEGIN
  96. IF ptr # NIL THEN g_free(ptr) END
  97. END Free;
  98. PROCEDURE ErrorMessage (err: GError; VAR dst: ARRAY OF CHAR);
  99. BEGIN
  100. IF err = NIL THEN
  101. dst[0] := 0C
  102. ELSE
  103. CStrToM2(err^.message, dst)
  104. END
  105. END ErrorMessage;
  106. PROCEDURE ClearError (VAR err: GError);
  107. BEGIN
  108. IF err # NIL THEN
  109. g_error_free(err);
  110. err := NIL
  111. END
  112. END ClearError;
  113. END GtkUtils.