ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/rxvt-unicode/src/main.C
(Generate patch)

Comparing rxvt-unicode/src/main.C (file contents):
Revision 1.108 by root, Wed Aug 25 05:03:33 2004 UTC vs.
Revision 1.132 by root, Thu Feb 3 07:18:30 2005 UTC

32 32
33#include "../config.h" /* NECESSARY */ 33#include "../config.h" /* NECESSARY */
34#include "rxvt.h" /* NECESSARY */ 34#include "rxvt.h" /* NECESSARY */
35#include "main.intpro" /* PROTOS for internal routines */ 35#include "main.intpro" /* PROTOS for internal routines */
36 36
37#include <signal.h> 37#include <csignal>
38#include <cstring>
38 39
39#ifdef TTY_GID_SUPPORT 40#ifdef TTY_GID_SUPPORT
40# include <grp.h> 41# include <grp.h>
41#endif 42#endif
42 43
43#ifdef HAVE_TERMIOS_H 44#ifdef HAVE_TERMIOS_H
44# include <termios.h> 45# include <termios.h>
45#endif 46#endif
46 47
47#include <cstring> 48#ifdef KEYSYM_RESOURCE
49# include "keyboard.h"
50#endif
48 51
49vector<rxvt_term *> rxvt_term::termlist; 52vector<rxvt_term *> rxvt_term::termlist;
50 53
51static char curlocale[128]; 54static char curlocale[128];
52 55
155 pointer_ev (this, &rxvt_term::pointer_cb), 158 pointer_ev (this, &rxvt_term::pointer_cb),
156#endif 159#endif
157#ifdef USE_XIM 160#ifdef USE_XIM
158 im_ev (this, &rxvt_term::im_cb), 161 im_ev (this, &rxvt_term::im_cb),
159#endif 162#endif
163 sw_term (this, &rxvt_term::sig_term),
164 sw_int (this, &rxvt_term::sig_term),
165 sw_chld (this, &rxvt_term::sig_chld),
160 termwin_ev (this, &rxvt_term::x_cb), 166 termwin_ev (this, &rxvt_term::x_cb),
161 vt_ev (this, &rxvt_term::x_cb), 167 vt_ev (this, &rxvt_term::x_cb),
162 check_ev (this, &rxvt_term::check_cb), 168 check_ev (this, &rxvt_term::check_cb),
163 flush_ev (this, &rxvt_term::flush_cb), 169 flush_ev (this, &rxvt_term::flush_cb),
164 destroy_ev (this, &rxvt_term::destroy_cb), 170 destroy_ev (this, &rxvt_term::destroy_cb),
166 incr_ev (this, &rxvt_term::incr_cb) 172 incr_ev (this, &rxvt_term::incr_cb)
167{ 173{
168 cmdbuf_ptr = cmdbuf_endp = cmdbuf_base; 174 cmdbuf_ptr = cmdbuf_endp = cmdbuf_base;
169 175
170 termlist.push_back (this); 176 termlist.push_back (this);
177
178#ifdef KEYSYM_RESOURCE
179 keyboard = new keyboard_manager;
180
181 if (!keyboard)
182 rxvt_fatal ("out of memory, aborting.\n");
183#endif
171} 184}
172 185
173rxvt_term::~rxvt_term () 186rxvt_term::~rxvt_term ()
174{ 187{
175 termlist.erase (find (termlist.begin (), termlist.end(), this)); 188 termlist.erase (find (termlist.begin (), termlist.end(), this));
176 189
177 if (cmd_pid) 190 if (cmd_pid)
178 kill (-cmd_pid, SIGHUP); 191 kill (-cmd_pid, SIGHUP);
179 192
180 pty.put ();
181
182#ifdef UTMP_SUPPORT 193#ifdef UTMP_SUPPORT
183 privileged_utmp (RESTORE); 194 privileged_utmp (RESTORE);
184#endif 195#endif
196
197 pty.put ();
185 198
186#if ENABLE_STYLES 199#if ENABLE_STYLES
187 for (int i = RS_styleCount; --i; ) 200 for (int i = RS_styleCount; --i; )
188 if (TermWin.fontset[i] != TermWin.fontset[0]) 201 if (TermWin.fontset[i] != TermWin.fontset[0])
189 delete TermWin.fontset[i]; 202 delete TermWin.fontset[i];
257 free (env_windowid); 270 free (env_windowid);
258 free (env_display); 271 free (env_display);
259 free (env_term); 272 free (env_term);
260 free (env_colorfgbg); 273 free (env_colorfgbg);
261 free (locale); 274 free (locale);
262#if 0 275 free (v_buffer);
263 free (codeset); 276 free (incr_buf);
264#endif
265 277
266 delete envv; 278 delete envv;
267 delete argv; 279 delete argv;
280
281#ifdef KEYSYM_RESOURCE
282 delete keyboard;
283#endif
268} 284}
269 285
270void 286void
271rxvt_term::destroy () 287rxvt_term::destroy ()
272{ 288{
330bool 346bool
331rxvt_term::init (int argc, const char *const *argv) 347rxvt_term::init (int argc, const char *const *argv)
332{ 348{
333 SET_R (this); 349 SET_R (this);
334 350
351 set_locale ("");
352
335 if (!init_vars ()) 353 if (!init_vars ())
336 return false; 354 return false;
337 355
338 init_secondary (); 356 init_secondary ();
339 357
340 const char **cmd_argv = init_resources (argc, argv); 358 const char **cmd_argv = init_resources (argc, argv);
341 359
342 set_locale (""); 360#ifdef KEYSYM_RESOURCE
361 keyboard->register_done ();
362#endif
343 363
344#if MENUBAR_MAX 364#if MENUBAR_MAX
345 menubar_read (rs[Rs_menu]); 365 menubar_read (rs[Rs_menu]);
346#endif 366#endif
347#ifdef HAVE_SCROLLBARS 367#ifdef HAVE_SCROLLBARS
381 401
382 set_colorfgbg (); 402 set_colorfgbg ();
383 403
384 init_command (cmd_argv); 404 init_command (cmd_argv);
385 405
406 free (cmd_argv);
407
386 pty_ev.start (pty.pty, EVENT_READ); 408 pty_ev.start (pty.pty, EVENT_READ);
387 409
388 check_ev.start (); 410 check_ev.start ();
389 411
390 return true; 412 return true;
393static int (*old_xerror_handler) (Display *dpy, XErrorEvent *event); 415static int (*old_xerror_handler) (Display *dpy, XErrorEvent *event);
394 416
395void 417void
396rxvt_init () 418rxvt_init ()
397{ 419{
398 /* install exit handler for cleanup */
399#if 0
400#ifdef HAVE_ATEXIT
401 atexit (rxvt_clean_exit);
402#else
403#endif
404#endif
405 /* 420 /*
406 * Save and then give up any super-user privileges 421 * Save and then give up any super-user privileges
407 * If we need privileges in any area then we must specifically request it. 422 * If we need privileges in any area then we must specifically request it.
408 * We should only need to be root in these cases: 423 * We should only need to be root in these cases:
409 * 1. write utmp entries on some systems 424 * 1. write utmp entries on some systems
410 * 2. chown tty on some systems 425 * 2. chown tty on some systems
411 */ 426 */
412 rxvt_privileges (SAVE); 427 rxvt_privileges (SAVE);
413 rxvt_privileges (IGNORE); 428 rxvt_privileges (IGNORE);
414 429
415 struct sigaction sa; 430 signal (SIGHUP, SIG_IGN);
416 431 signal (SIGPIPE, SIG_IGN);
417 sigfillset (&sa.sa_mask);
418 sa.sa_flags = SA_NOCLDSTOP | SA_RESTART;
419 sa.sa_handler = SIG_IGN; sigaction (SIGHUP , &sa, 0);
420 sa.sa_handler = SIG_IGN; sigaction (SIGPIPE, &sa, 0);
421 sa.sa_handler = rxvt_Exit_signal; sigaction (SIGINT , &sa, 0);
422 sa.sa_handler = rxvt_Exit_signal; sigaction (SIGQUIT, &sa, 0);
423 sa.sa_handler = rxvt_Exit_signal; sigaction (SIGTERM, &sa, 0);
424 sa.sa_handler = rxvt_Child_signal; sigaction (SIGCHLD, &sa, 0);
425 432
426 /* need to trap SIGURG for SVR4 (Unixware) rlogin */ 433 /* need to trap SIGURG for SVR4 (Unixware) rlogin */
427 /* signal (SIGURG, SIG_DFL); */ 434 /* signal (SIGURG, SIG_DFL); */
428 435
429 old_xerror_handler = XSetErrorHandler ((XErrorHandler) rxvt_xerror_handler); 436 old_xerror_handler = XSetErrorHandler ((XErrorHandler) rxvt_xerror_handler);
437 // TODO: handle this with exceptions and tolerate the memory loss
430 //XSetIOErrorHandler ((XErrorHandler) rxvt_xioerror_handler); 438 //XSetIOErrorHandler ((XErrorHandler) rxvt_xioerror_handler);
431} 439}
432 440
433/* ------------------------------------------------------------------------- * 441/* ------------------------------------------------------------------------- *
434 * SIGNAL HANDLING & EXIT HANDLER * 442 * SIGNAL HANDLING & EXIT HANDLER *
435 * ------------------------------------------------------------------------- */ 443 * ------------------------------------------------------------------------- */
436/* 444/*
437 * Catch a SIGCHLD signal and exit if the direct child has died 445 * Catch a SIGCHLD signal and exit if the direct child has died
438 */ 446 */
439 447
440void rxvt_term::child_exited (int pid) 448void
449rxvt_term::sig_chld (sig_watcher &w)
441{ 450{
442 for (rxvt_term **t = termlist.begin (); t < termlist.end (); t++) 451 // we are being called for every SIGCHLD, not just ours
443 if (pid == (*t)->cmd_pid) 452 int pid;
444 {
445 (*t)->destroy ();
446 break;
447 }
448}
449
450/* ARGSUSED */
451/* INTPROTO */
452RETSIGTYPE
453rxvt_Child_signal (int sig __attribute__ ((unused)))
454{
455 int pid, save_errno = errno;
456 453
457 while ((pid = waitpid (-1, NULL, WNOHANG)) > 0) 454 while ((pid = waitpid (-1, NULL, WNOHANG)) > 0)
458 rxvt_term::child_exited (pid); 455 for (rxvt_term **t = termlist.begin (); t < termlist.end (); t++)
459 456 if (pid == (*t)->cmd_pid)
460 errno = save_errno; 457 {
461} 458 (*t)->destroy ();
462 459 break;
463/* 460 }
464 * Catch a fatal signal and tidy up before quitting
465 */
466/* INTPROTO */
467RETSIGTYPE
468rxvt_Exit_signal (int sig)
469{
470 signal (sig, SIG_DFL);
471#ifdef DEBUG_CMD
472 rxvt_warn ("caught signal %d, exiting.\n", sig);
473#endif
474 rxvt_clean_exit ();
475 kill (getpid (), sig);
476}
477
478/* INTPROTO */
479int
480rxvt_xerror_handler (Display *display, XErrorEvent *event)
481{
482 if (GET_R->allowedxerror == -1)
483 GET_R->allowedxerror = event->error_code;
484 else
485 {
486 old_xerror_handler (display, event);
487 GET_R->destroy ();
488 }
489
490 return 0;
491} 461}
492 462
493/*----------------------------------------------------------------------*/ 463/*----------------------------------------------------------------------*/
494/* 464/*
495 * Exit gracefully, clearing the utmp entry and restoring tty attributes 465 * Exit gracefully, clearing the utmp entry and restoring tty attributes
496 * TODO: if debugging, this should free up any known resources if we can 466 * TODO: if debugging, this should free up any known resources if we can
497 */ 467 */
468void
469rxvt_destroy_all ()
470{
471 // TODO: rxvtd should clean up all ressources
472 for (rxvt_term **t = rxvt_term::termlist.begin (); t < rxvt_term::termlist.end (); t++)
473 (*t)->destroy ();
474}
475
476/*
477 * Catch a fatal signal and tidy up before quitting
478 */
479void
480rxvt_term::sig_term (sig_watcher &w)
481{
482#ifdef DEBUG_CMD
483 rxvt_warn ("caught signal %d, exiting.\n", w.signum);
484#endif
485 rxvt_destroy_all ();
486 signal (w.signum, SIG_DFL);
487 kill (getpid (), w.signum);
488}
489
498/* INTPROTO */ 490/* INTPROTO */
499void 491int
500rxvt_clean_exit () 492rxvt_xerror_handler (Display *display, XErrorEvent *event)
501{ 493{
502 // TODO: rxvtd should clean up all ressources 494 if (GET_R->allowedxerror == -1)
503 if (GET_R) 495 GET_R->allowedxerror = event->error_code;
496 else
497 {
498 old_xerror_handler (display, event);
504 GET_R->destroy (); 499 GET_R->destroy ();
500 }
501
502 return 0;
505} 503}
506 504
507/* ------------------------------------------------------------------------- * 505/* ------------------------------------------------------------------------- *
508 * MEMORY ALLOCATION WRAPPERS * 506 * MEMORY ALLOCATION WRAPPERS *
509 * ------------------------------------------------------------------------- */ 507 * ------------------------------------------------------------------------- */
510/* INTPROTO */ 508void *
511void *
512rxvt_malloc (size_t size) 509rxvt_malloc (size_t size)
513{ 510{
514 void *p;
515
516 p = malloc (size); 511 void *p = malloc (size);
512
517 if (p) 513 if (!p)
518 return p;
519
520 rxvt_fatal ("memory allocation failure. aborting.\n"); 514 rxvt_fatal ("memory allocation failure. aborting.\n");
521 /* NOTREACHED */ 515
516 return p;
522} 517}
523 518
524/* INTPROTO */ 519/* INTPROTO */
525void * 520void *
526rxvt_calloc (size_t number, size_t size) 521rxvt_calloc (size_t number, size_t size)
527{ 522{
528 void *p;
529
530 p = calloc (number, size); 523 void *p = calloc (number, size);
524
531 if (p) 525 if (!p)
532 return p;
533
534 rxvt_fatal ("memory allocation failure. aborting.\n"); 526 rxvt_fatal ("memory allocation failure. aborting.\n");
535 /* NOTREACHED */ 527
528 return p;
536} 529}
537 530
538/* INTPROTO */ 531/* INTPROTO */
539void * 532void *
540rxvt_realloc (void *ptr, size_t size) 533rxvt_realloc (void *ptr, size_t size)
541{ 534{
542 void *p;
543
544 if (ptr)
545 p = realloc (ptr, size); 535 void *p = realloc (ptr, size);
546 else
547 p = malloc (size);
548 536
549 if (p) 537 if (!p)
550 return p;
551
552 rxvt_fatal ("memory allocation failure. aborting.\n"); 538 rxvt_fatal ("memory allocation failure. aborting.\n");
553 /* NOTREACHED */ 539
540 return p;
554} 541}
555 542
556/* ------------------------------------------------------------------------- * 543/* ------------------------------------------------------------------------- *
557 * PRIVILEGED OPERATIONS * 544 * PRIVILEGED OPERATIONS *
558 * ------------------------------------------------------------------------- */ 545 * ------------------------------------------------------------------------- */
798rxvt_term::set_fonts () 785rxvt_term::set_fonts ()
799{ 786{
800 rxvt_fontset *fs = new rxvt_fontset (this); 787 rxvt_fontset *fs = new rxvt_fontset (this);
801 rxvt_fontprop prop; 788 rxvt_fontprop prop;
802 789
803 prop.width = prop.height = prop.weight = prop.slant
804 = rxvt_fontprop::unset;
805
806 if (!fs 790 if (!fs
807 || !fs->populate (rs[Rs_font] ? rs[Rs_font] : "fixed", prop) 791 || !fs->populate (rs[Rs_font] ? rs[Rs_font] : "fixed")
808 || !fs->realize_font (1)) 792 || !fs->realize_font (1))
809 { 793 {
810 delete fs; 794 delete fs;
811 return false; 795 return false;
812 } 796 }
818#endif 802#endif
819 803
820 delete TermWin.fontset[0]; 804 delete TermWin.fontset[0];
821 TermWin.fontset[0] = fs; 805 TermWin.fontset[0] = fs;
822 806
823 fs->prop = prop = (*fs)[1]->properties (); 807 prop = (*fs)[1]->properties ();
808 prop.height += TermWin.lineSpace;
809 fs->set_prop (prop);
824 810
825 TermWin.fwidth = prop.width; 811 TermWin.fwidth = prop.width;
826 TermWin.fheight = prop.height; 812 TermWin.fheight = prop.height;
827 TermWin.fweight = prop.weight; 813 TermWin.fweight = prop.weight;
828 TermWin.fslant = prop.slant; 814 TermWin.fslant = prop.slant;
848 834
849 if (SET_STYLE (0, style) & RS_Bold) prop2.weight = rxvt_fontprop::bold; 835 if (SET_STYLE (0, style) & RS_Bold) prop2.weight = rxvt_fontprop::bold;
850 if (SET_STYLE (0, style) & RS_Italic) prop2.slant = rxvt_fontprop::italic; 836 if (SET_STYLE (0, style) & RS_Italic) prop2.slant = rxvt_fontprop::italic;
851 } 837 }
852 838
853 fs->populate (res, prop2); 839 fs->populate (res);
840 fs->set_prop (prop2);
854 } 841 }
855#else 842#else
856 TermWin.fontset[style] = TermWin.fontset[0]; 843 TermWin.fontset[style] = TermWin.fontset[0];
857#endif 844#endif
858 } 845 }
865 } 852 }
866 853
867 return true; 854 return true;
868} 855}
869 856
857void rxvt_term::set_string_property (Atom prop, const char *str, int len)
858{
859 // TODO: SMART_WINDOW_TITLE
860 XChangeProperty (display->display, TermWin.parent[0],
861 prop, XA_STRING, 8, PropModeReplace,
862 (const unsigned char *)str, len >= 0 ? len : strlen (str));
863}
864
865void rxvt_term::set_utf8_property (Atom prop, const char *str, int len)
866{
867 // TODO: SMART_WINDOW_TITLE
868 wchar_t *ws = rxvt_mbstowcs (str, len);
869 char *s = rxvt_wcstoutf8 (ws);
870
871 XChangeProperty (display->display, TermWin.parent[0],
872 prop, xa[XA_UTF8_STRING], 8, PropModeReplace,
873 (const unsigned char *)s, strlen (s));
874
875 free (s);
876 free (ws);
877}
878
870/*----------------------------------------------------------------------*/ 879/*----------------------------------------------------------------------*/
871/*----------------------------------------------------------------------*/ 880/*----------------------------------------------------------------------*/
872/* xterm sequences - title, iconName, color (exptl) */ 881/* xterm sequences - title, iconName, color (exptl) */
873void 882void
874rxvt_term::set_title (const char *str) 883rxvt_term::set_title (const char *str)
875{ 884{
876#ifdef SMART_WINDOW_TITLE 885 set_string_property (XA_WM_NAME, str);
877 char *name; 886#if ENABLE_FRILLS
878 887 set_utf8_property (xa[XA_NET_WM_NAME], str);
879 if (!XFetchName (display->display, TermWin.parent[0], &name))
880 name = NULL;
881
882 if (name == NULL || strcmp (name, str))
883#endif
884 XStoreName (display->display, TermWin.parent[0], str);
885
886#ifdef SMART_WINDOW_TITLE
887 if (name)
888 XFree (name);
889#endif 888#endif
890} 889}
891 890
892void 891void
893rxvt_term::set_icon_name (const char *str) 892rxvt_term::set_icon_name (const char *str)
894{ 893{
895#ifdef SMART_WINDOW_TITLE 894 set_string_property (XA_WM_ICON_NAME, str);
896 char *name; 895#if ENABLE_FRILLS
897 896 set_utf8_property (xa[XA_NET_WM_ICON_NAME], str);
898 if (!XGetIconName (display->display, TermWin.parent[0], &name))
899 name = NULL;
900
901 if (name == NULL || strcmp (name, str))
902#endif
903 XSetIconName (display->display, TermWin.parent[0], str);
904
905#ifdef SMART_WINDOW_TITLE
906 if (name)
907 XFree (name);
908#endif 897#endif
909} 898}
910 899
911#ifdef XTERM_COLOR_CHANGE 900#ifdef XTERM_COLOR_CHANGE
912void 901void
1031 1020
1032 sprintf (env_colorfgbg, "COLORFGBG=%s;%s%s", fstr, xpmb, bstr); 1021 sprintf (env_colorfgbg, "COLORFGBG=%s;%s%s", fstr, xpmb, bstr);
1033} 1022}
1034 1023
1035/*----------------------------------------------------------------------*/ 1024/*----------------------------------------------------------------------*/
1036/*
1037 * Colour determination for low colour displays, routine from
1038 * Hans de Goede <hans@highrise.nl>
1039 */
1040 1025
1041int 1026int
1042rxvt_term::rXParseAllocColor (rxvt_color *screen_in_out, const char *colour) 1027rxvt_term::rXParseAllocColor (rxvt_color *screen_in_out, const char *colour)
1043{ 1028{
1044 if (!screen_in_out->set (display, colour)) 1029 if (!screen_in_out->set (display, colour))
1131 TermWin_TotalWidth (), menuBar_TotalHeight ()); 1116 TermWin_TotalWidth (), menuBar_TotalHeight ());
1132 1117
1133 XMoveResizeWindow (display->display, TermWin.vt, 1118 XMoveResizeWindow (display->display, TermWin.vt,
1134 window_vt_x, window_vt_y, 1119 window_vt_x, window_vt_y,
1135 TermWin_TotalWidth (), TermWin_TotalHeight ()); 1120 TermWin_TotalWidth (), TermWin_TotalHeight ());
1121
1136 scr_clear (); 1122 scr_clear ();
1137#ifdef XPM_BACKGROUND 1123#ifdef XPM_BACKGROUND
1138 resize_pixmap (); 1124 resize_pixmap ();
1139#endif 1125#endif
1140 } 1126 }
1163 } 1149 }
1164 1150
1165 old_width = szHint.width; 1151 old_width = szHint.width;
1166 old_height = szHint.height; 1152 old_height = szHint.height;
1167 1153
1154#ifdef XPM_BACKGROUND
1155 if (TermWin.pixmap)
1156 scr_touch (false);
1157#endif
1158
1168#ifdef USE_XIM 1159#ifdef USE_XIM
1169 IMSetStatusPosition (); 1160 IMSetStatusPosition ();
1170#endif 1161#endif
1171} 1162}
1172 1163
1263} 1254}
1264 1255
1265void 1256void
1266rxvt_term::IMSendSpot () 1257rxvt_term::IMSendSpot ()
1267{ 1258{
1268 XPoint spot; 1259 XPoint nspot;
1269 XVaNestedList preedit_attr; 1260 XVaNestedList preedit_attr;
1270 1261
1271 if (!Input_Context 1262 if (!Input_Context
1272 || !TermWin.focus 1263 || !TermWin.focus
1273 || !(input_style & XIMPreeditPosition) 1264 || !(input_style & XIMPreeditPosition))
1274#if 0
1275 || !(event_type == KeyPress
1276 || event_type == Expose
1277 || event_type == NoExpose
1278 || event_type == SelectionNotify
1279 || event_type == ButtonRelease || event_type == FocusIn)
1280#endif
1281 || !IMisRunning ())
1282 return; 1265 return;
1283 1266
1284 im_set_position (spot); 1267 im_set_position (nspot);
1268
1269 if (nspot.x == spot.x && nspot.y == spot.y)
1270 return;
1271
1272 spot = nspot;
1285 1273
1286 preedit_attr = XVaCreateNestedList (0, XNSpotLocation, &spot, NULL); 1274 preedit_attr = XVaCreateNestedList (0, XNSpotLocation, &spot, NULL);
1287 XSetICValues (Input_Context, XNPreeditAttributes, preedit_attr, NULL); 1275 XSetICValues (Input_Context, XNPreeditAttributes, preedit_attr, NULL);
1288 XFree (preedit_attr); 1276 XFree (preedit_attr);
1289} 1277}
1290 1278
1291void 1279void
1292rxvt_term::im_destroy () 1280rxvt_term::im_destroy ()
1293{ 1281{
1294 if (Input_Context)
1295 {
1296 XDestroyIC (Input_Context);
1297 Input_Context = 0;
1298 }
1299
1300 if (input_method) 1282 if (input_method)
1301 { 1283 {
1284 if (Input_Context && input_method->xim)
1285 XDestroyIC (Input_Context);
1286
1302 display->put_xim (input_method); 1287 display->put_xim (input_method);
1303 input_method = 0; 1288 input_method = 0;
1304 } 1289 }
1290
1291 Input_Context = 0;
1305} 1292}
1306 1293
1307/* 1294/*
1308 * Try to open a XIM with the current modifiers, then see if we can 1295 * Try to open a XIM with the current modifiers, then see if we can
1309 * open a suitable preedit type 1296 * open a suitable preedit type
1327 input_method = display->get_xim (locale, modifiers); 1314 input_method = display->get_xim (locale, modifiers);
1328 if (input_method == NULL) 1315 if (input_method == NULL)
1329 return false; 1316 return false;
1330 1317
1331 xim = input_method->xim; 1318 xim = input_method->xim;
1319 spot.x = spot.y = -1;
1332 1320
1333 xim_styles = NULL; 1321 xim_styles = NULL;
1334 if (XGetIMValues (xim, XNQueryInputStyle, &xim_styles, NULL) 1322 if (XGetIMValues (xim, XNQueryInputStyle, &xim_styles, NULL)
1335 || !xim_styles || !xim_styles->count_styles) 1323 || !xim_styles || !xim_styles->count_styles)
1336 { 1324 {
1337 im_destroy (); 1325 im_destroy ();
1338 return false; 1326 return false;
1339 } 1327 }
1340 1328
1341 p = rs[Rs_preeditType] ? rs[Rs_preeditType] : "OverTheSpot,OffTheSpot,Root"; 1329 const char *pet[] = { rs[Rs_preeditType], "OverTheSpot,OffTheSpot,Root,None" };
1330
1331 for (int pi = 0; pi < 2; pi++)
1332 {
1333 p = pet[pi];
1334
1335 if (!p)
1336 continue;
1337
1342 s = rxvt_splitcommastring (p); 1338 s = rxvt_splitcommastring (p);
1343 1339
1344 for (i = found = 0; !found && s[i]; i++) 1340 for (i = found = 0; !found && s[i]; i++)
1345 { 1341 {
1346 if (!strcmp (s[i], "OverTheSpot")) 1342 if (!strcmp (s[i], "OverTheSpot"))
1347 input_style = (XIMPreeditPosition | XIMStatusNothing); 1343 input_style = (XIMPreeditPosition | XIMStatusNothing);
1348 else if (!strcmp (s[i], "OffTheSpot")) 1344 else if (!strcmp (s[i], "OffTheSpot"))
1349 input_style = (XIMPreeditArea | XIMStatusArea); 1345 input_style = (XIMPreeditArea | XIMStatusArea);
1350 else if (!strcmp (s[i], "Root")) 1346 else if (!strcmp (s[i], "Root"))
1351 input_style = (XIMPreeditNothing | XIMStatusNothing); 1347 input_style = (XIMPreeditNothing | XIMStatusNothing);
1348 else if (!strcmp (s[i], "None"))
1349 input_style = (XIMPreeditNone | XIMStatusNone);
1352 1350
1353 for (j = 0; j < xim_styles->count_styles; j++) 1351 for (j = 0; j < xim_styles->count_styles; j++)
1354 if (input_style == xim_styles->supported_styles[j]) 1352 if (input_style == xim_styles->supported_styles[j])
1355 { 1353 {
1354 rxvt_freecommastring (s);
1355
1356 found = 1; 1356 found = 1;
1357 break; 1357 goto foundpet;
1358 }
1359
1358 } 1360 }
1359 }
1360 1361
1361 for (i = 0; s[i]; i++) 1362 rxvt_freecommastring (s);
1362 free (s[i]); 1363 }
1363 1364
1364 free (s); 1365foundpet:
1366
1365 XFree (xim_styles); 1367 XFree (xim_styles);
1366 1368
1367 if (!found) 1369 if (!found)
1368 { 1370 {
1369 im_destroy (); 1371 im_destroy ();
1390 "*", 1392 "*",
1391 TermWin.fheight, 1393 TermWin.fheight,
1392 TermWin.fheight + 1, TermWin.fheight - 1, 1394 TermWin.fheight + 1, TermWin.fheight - 1,
1393 TermWin.fheight - 2, TermWin.fheight + 2); 1395 TermWin.fheight - 2, TermWin.fheight + 2);
1394 1396
1395 fs = XCreateFontSet (display->display, pat, 1397 fs = XCreateFontSet (display->display, rs[Rs_imFont] ? rs[Rs_imFont] : pat,
1396 &missing_charset_list, &missing_charset_count, &def_string); 1398 &missing_charset_list, &missing_charset_count, &def_string);
1397 1399
1398 if (missing_charset_list) 1400 if (missing_charset_list)
1399 XFreeStringList (missing_charset_list); 1401 XFreeStringList (missing_charset_list);
1400 1402
1494 if (p && *p) 1496 if (p && *p)
1495 { 1497 {
1496 bool found = false; 1498 bool found = false;
1497 1499
1498 s = rxvt_splitcommastring (p); 1500 s = rxvt_splitcommastring (p);
1501
1499 for (i = 0; s[i]; i++) 1502 for (i = 0; s[i]; i++)
1500 { 1503 {
1501 if (*s[i]) 1504 if (*s[i])
1502 { 1505 {
1503 strcpy (buf, "@im="); 1506 strcpy (buf, "@im=");
1507 found = true; 1510 found = true;
1508 break; 1511 break;
1509 } 1512 }
1510 } 1513 }
1511 } 1514 }
1512 for (i = 0; s[i]; i++) 1515
1513 free (s[i]); 1516 rxvt_freecommastring (s);
1514 free (s);
1515 1517
1516 if (found) 1518 if (found)
1517 goto done; 1519 goto done;
1518 } 1520 }
1519 1521

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines